#pragma once // array.hpp - A simple bounds-checked array. // // Copyright © 2014 Ben Longbons // // This file is part of The Mana World (Athena server) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "fwd.hpp" #include #include #include "oops.hpp" // half the important stuff is now in fwd.hpp !!! namespace tmwa { template struct ExclusiveIndexing { using index_type = I; constexpr static size_t index_to_offset(index_type idx) { return static_cast(idx) - static_cast(be); } constexpr static index_type offset_to_index(size_t off) { return static_cast(off + static_cast(be)); } constexpr static size_t alloc_size = index_to_offset(en) - index_to_offset(be); }; template struct InclusiveIndexing { using index_type = I; constexpr static size_t index_to_offset(index_type idx) { return static_cast(idx) - static_cast(lo); } constexpr static index_type offset_to_index(size_t off) { return static_cast(off + static_cast(lo)); } constexpr static size_t alloc_size = index_to_offset(hi) - index_to_offset(lo) + 1; }; template struct EnumIndexing : ExclusiveIndexing(0), n> { }; template struct InventoryIndexing { using index_type = I; constexpr static size_t index_to_offset(index_type idx) { return idx.get0(); } constexpr static index_type offset_to_index(size_t off) { return I::from(off); } constexpr static size_t alloc_size = limit; }; template struct GenericArray { T data[I::alloc_size]; public: T *begin() { return data + 0; } T *end() { return data + I::alloc_size; } const T *begin() const { return data + 0; } const T *end() const { return data + I::alloc_size; } size_t size() const { return I::alloc_size; } T& operator [](typename I::index_type i_) { size_t i = I::index_to_offset(i_); ALLEGE ("index in bounds", i < size()); return data[i]; } const T& operator [](typename I::index_type i_) const { size_t i = I::index_to_offset(i_); ALLEGE ("index in bounds", i < size()); return data[i]; } friend bool operator == (GenericArray& lhs, GenericArray& rhs) { for (size_t i = 0; i < I::alloc_size; ++i) { if (lhs.data[i] != rhs.data[i]) return false; } return true; } friend bool operator != (GenericArray& lhs, GenericArray& rhs) { return !(lhs == rhs); } }; } // namespace tmwa