diff --git a/Catch_color_tutorial_tests/color_container.cpp b/Catch_color_tutorial_tests/color_container.cpp index 978efb3..b0b39b6 100644 --- a/Catch_color_tutorial_tests/color_container.cpp +++ b/Catch_color_tutorial_tests/color_container.cpp @@ -19,7 +19,6 @@ float dcon::colored_thing_const_fat_id::get_blue() { return get_color().blue; } - void dcon::data_container::deserialize_rgb(std::byte const* start, std::byte const* end, load_record& record_in_out) { if(!record_in_out.colored_thing_color) { float const* found_red = nullptr; diff --git a/Catch_core_datacontainer_tests/Catch_core_datacontainer_tests.cpp b/Catch_core_datacontainer_tests/Catch_core_datacontainer_tests.cpp index a5fb272..841eb20 100644 --- a/Catch_core_datacontainer_tests/Catch_core_datacontainer_tests.cpp +++ b/Catch_core_datacontainer_tests/Catch_core_datacontainer_tests.cpp @@ -579,7 +579,6 @@ TEST_CASE("for compatactable remove in the other direction", "[core_datacontaine REQUIRE(found_car == false); } - TEST_CASE("for erasable basic relationship functions", "[core_datacontainer_tests]") { auto ptr = std::make_unique< cob3::data_container >(); diff --git a/Catch_ecs_tutorial_tests/Catch_ecs_tutorial_tests.cpp b/Catch_ecs_tutorial_tests/Catch_ecs_tutorial_tests.cpp index 8930ab1..b269a40 100644 --- a/Catch_ecs_tutorial_tests/Catch_ecs_tutorial_tests.cpp +++ b/Catch_ecs_tutorial_tests/Catch_ecs_tutorial_tests.cpp @@ -17,6 +17,7 @@ dcon::entity_id make_entity(dcon::data_container& dc) { return dc.try_create_entity(dcon::position_id(), dcon::sprite_id()); } + TEST_CASE("destructor test", "[ecs_tutorial_tests]") { auto ptr = std::make_unique(); diff --git a/Catch_serialization_tests/new_ser.hpp b/Catch_serialization_tests/new_ser.hpp index 3fc9947..4501f72 100644 --- a/Catch_serialization_tests/new_ser.hpp +++ b/Catch_serialization_tests/new_ser.hpp @@ -188,7 +188,12 @@ namespace ns { class data_container; namespace internal { + class const_object_iterator_thingy; + class object_iterator_thingy; + class alignas(64) thingy_class { + friend const_object_iterator_thingy; + friend object_iterator_thingy; private: // // storage space for i_value of type int16_t @@ -245,7 +250,12 @@ namespace ns { friend data_container; }; + class const_object_iterator_thingy2; + class object_iterator_thingy2; + class alignas(64) thingy2_class { + friend const_object_iterator_thingy2; + friend object_iterator_thingy2; private: // // storage space for some_value of type int32_t @@ -266,7 +276,18 @@ namespace ns { friend data_container; }; + class const_object_iterator_dummy_rel; + class object_iterator_dummy_rel; + class const_iterator_thingy_foreach_dummy_rel_as_left; + class iterator_thingy_foreach_dummy_rel_as_left; + struct const_iterator_thingy_foreach_dummy_rel_as_left_generator; + struct iterator_thingy_foreach_dummy_rel_as_left_generator; + class alignas(64) dummy_rel_class { + friend const_object_iterator_dummy_rel; + friend object_iterator_dummy_rel; + friend const_iterator_thingy_foreach_dummy_rel_as_left; + friend iterator_thingy_foreach_dummy_rel_as_left; private: // // storage space for left of type thingy_id @@ -358,10 +379,12 @@ namespace ns { DCON_RELEASE_INLINE void for_each_dummy_rel_as_left(T&& func) const; DCON_RELEASE_INLINE std::pair range_of_dummy_rel_as_left() const; DCON_RELEASE_INLINE void remove_all_dummy_rel_as_left() const noexcept; + DCON_RELEASE_INLINE internal::iterator_thingy_foreach_dummy_rel_as_left_generator get_dummy_rel_as_left() const; template DCON_RELEASE_INLINE void for_each_dummy_rel(T&& func) const; DCON_RELEASE_INLINE std::pair range_of_dummy_rel() const; DCON_RELEASE_INLINE void remove_all_dummy_rel() const noexcept; + DCON_RELEASE_INLINE internal::iterator_thingy_foreach_dummy_rel_as_left_generator get_dummy_rel() const; template DCON_RELEASE_INLINE void for_each_right_from_dummy_rel(T&& func) const; DCON_RELEASE_INLINE bool has_right_from_dummy_rel(thingy2_id target) const; @@ -425,9 +448,11 @@ namespace ns { template DCON_RELEASE_INLINE void for_each_dummy_rel_as_left(T&& func) const; DCON_RELEASE_INLINE std::pair range_of_dummy_rel_as_left() const; + DCON_RELEASE_INLINE internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator get_dummy_rel_as_left() const; template DCON_RELEASE_INLINE void for_each_dummy_rel(T&& func) const; DCON_RELEASE_INLINE std::pair range_of_dummy_rel() const; + DCON_RELEASE_INLINE internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator get_dummy_rel() const; template DCON_RELEASE_INLINE void for_each_right_from_dummy_rel(T&& func) const; DCON_RELEASE_INLINE bool has_right_from_dummy_rel(thingy2_id target) const; @@ -666,6 +691,440 @@ namespace ns { return dummy_rel_const_fat_id(c, id); } + namespace internal { + class object_iterator_thingy { + private: + data_container& container; + uint32_t index = 0; + public: + object_iterator_thingy(data_container& c, uint32_t i) noexcept; + DCON_RELEASE_INLINE object_iterator_thingy& operator++() noexcept; + DCON_RELEASE_INLINE object_iterator_thingy& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(object_iterator_thingy const& o) const noexcept { + return &container == &o.container && index == o.index; + } + DCON_RELEASE_INLINE bool operator!=(object_iterator_thingy const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE thingy_fat_id operator*() const noexcept { + return thingy_fat_id(container, thingy_id(thingy_id::value_base_t(index))); + } + DCON_RELEASE_INLINE object_iterator_thingy& operator+=(int32_t n) noexcept { + index = uint32_t(int32_t(index) + n); + return *this; + } + DCON_RELEASE_INLINE object_iterator_thingy& operator-=(int32_t n) noexcept { + index = uint32_t(int32_t(index) - n); + return *this; + } + DCON_RELEASE_INLINE object_iterator_thingy operator+(int32_t n) const noexcept { + return object_iterator_thingy(container, uint32_t(int32_t(index) + n)); + } + DCON_RELEASE_INLINE object_iterator_thingy operator-(int32_t n) const noexcept { + return object_iterator_thingy(container, uint32_t(int32_t(index) - n)); + } + DCON_RELEASE_INLINE int32_t operator-(object_iterator_thingy const& o) const noexcept { + return int32_t(index) - int32_t(o.index); + } + DCON_RELEASE_INLINE bool operator>(object_iterator_thingy const& o) const noexcept { + return index > o.index; + } + DCON_RELEASE_INLINE bool operator>=(object_iterator_thingy const& o) const noexcept { + return index >= o.index; + } + DCON_RELEASE_INLINE bool operator<(object_iterator_thingy const& o) const noexcept { + return index < o.index; + } + DCON_RELEASE_INLINE bool operator<=(object_iterator_thingy const& o) const noexcept { + return index <= o.index; + } + DCON_RELEASE_INLINE thingy_fat_id operator[](int32_t n) const noexcept { + return thingy_fat_id(container, thingy_id(thingy_id::value_base_t(int32_t(index) + n))); + } + }; + class const_object_iterator_thingy { + private: + data_container const& container; + uint32_t index = 0; + public: + const_object_iterator_thingy(data_container const& c, uint32_t i) noexcept; + DCON_RELEASE_INLINE const_object_iterator_thingy& operator++() noexcept; + DCON_RELEASE_INLINE const_object_iterator_thingy& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(const_object_iterator_thingy const& o) const noexcept { + return &container == &o.container && index == o.index; + } + DCON_RELEASE_INLINE bool operator!=(const_object_iterator_thingy const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE thingy_const_fat_id operator*() const noexcept { + return thingy_const_fat_id(container, thingy_id(thingy_id::value_base_t(index))); + } + DCON_RELEASE_INLINE const_object_iterator_thingy& operator+=(int32_t n) noexcept { + index = uint32_t(int32_t(index) + n); + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy& operator-=(int32_t n) noexcept { + index = uint32_t(int32_t(index) - n); + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy operator+(int32_t n) const noexcept { + return const_object_iterator_thingy(container, uint32_t(int32_t(index) + n)); + } + DCON_RELEASE_INLINE const_object_iterator_thingy operator-(int32_t n) const noexcept { + return const_object_iterator_thingy(container, uint32_t(int32_t(index) - n)); + } + DCON_RELEASE_INLINE int32_t operator-(const_object_iterator_thingy const& o) const noexcept { + return int32_t(index) - int32_t(o.index); + } + DCON_RELEASE_INLINE bool operator>(const_object_iterator_thingy const& o) const noexcept { + return index > o.index; + } + DCON_RELEASE_INLINE bool operator>=(const_object_iterator_thingy const& o) const noexcept { + return index >= o.index; + } + DCON_RELEASE_INLINE bool operator<(const_object_iterator_thingy const& o) const noexcept { + return index < o.index; + } + DCON_RELEASE_INLINE bool operator<=(const_object_iterator_thingy const& o) const noexcept { + return index <= o.index; + } + DCON_RELEASE_INLINE thingy_const_fat_id operator[](int32_t n) const noexcept { + return thingy_const_fat_id(container, thingy_id(thingy_id::value_base_t(int32_t(index) + n))); + } + }; + + class iterator_thingy_foreach_dummy_rel_as_left { + private: + data_container& container; + dummy_rel_id const* ptr = nullptr; + public: + iterator_thingy_foreach_dummy_rel_as_left(data_container& c, thingy_id fr) noexcept; + iterator_thingy_foreach_dummy_rel_as_left(data_container& c, dummy_rel_id const* r) noexcept : container(c), ptr(r) {} + iterator_thingy_foreach_dummy_rel_as_left(data_container& c, thingy_id fr, int) noexcept; + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left& operator++() noexcept; + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr == o.ptr; + } + DCON_RELEASE_INLINE bool operator!=(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE dummy_rel_fat_id operator*() const noexcept { + return dummy_rel_fat_id(container, *ptr); + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left& operator+=(ptrdiff_t n) noexcept { + ptr += n; + return *this; + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left& operator-=(ptrdiff_t n) noexcept { + ptr -= n; + return *this; + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left operator+(ptrdiff_t n) const noexcept { + return iterator_thingy_foreach_dummy_rel_as_left(container, ptr + n); + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left operator-(ptrdiff_t n) const noexcept { + return iterator_thingy_foreach_dummy_rel_as_left(container, ptr - n); + } + DCON_RELEASE_INLINE ptrdiff_t operator-(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr - o.ptr; + } + DCON_RELEASE_INLINE bool operator>(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr > o.ptr; + } + DCON_RELEASE_INLINE bool operator>=(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr >= o.ptr; + } + DCON_RELEASE_INLINE bool operator<(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr < o.ptr; + } + DCON_RELEASE_INLINE bool operator<=(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr <= o.ptr; + } + DCON_RELEASE_INLINE dummy_rel_fat_id operator[](ptrdiff_t n) const noexcept { + return dummy_rel_fat_id(container, *(ptr + n)); + } + }; + class const_iterator_thingy_foreach_dummy_rel_as_left { + private: + data_container const& container; + dummy_rel_id const* ptr = nullptr; + public: + const_iterator_thingy_foreach_dummy_rel_as_left(data_container const& c, thingy_id fr) noexcept; + const_iterator_thingy_foreach_dummy_rel_as_left(data_container const& c, dummy_rel_id const* r) noexcept : container(c), ptr(r) {} + const_iterator_thingy_foreach_dummy_rel_as_left(data_container const& c, thingy_id fr, int) noexcept; + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left& operator++() noexcept; + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr == o.ptr; + } + DCON_RELEASE_INLINE bool operator!=(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE dummy_rel_const_fat_id operator*() const noexcept { + return dummy_rel_const_fat_id(container, *ptr); + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left& operator+=(ptrdiff_t n) noexcept { + ptr += n; + return *this; + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left& operator-=(ptrdiff_t n) noexcept { + ptr -= n; + return *this; + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left operator+(ptrdiff_t n) const noexcept { + return const_iterator_thingy_foreach_dummy_rel_as_left(container, ptr + n); + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left operator-(ptrdiff_t n) const noexcept { + return const_iterator_thingy_foreach_dummy_rel_as_left(container, ptr - n); + } + DCON_RELEASE_INLINE ptrdiff_t operator-(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr - o.ptr; + } + DCON_RELEASE_INLINE bool operator>(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr > o.ptr; + } + DCON_RELEASE_INLINE bool operator>=(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr >= o.ptr; + } + DCON_RELEASE_INLINE bool operator<(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr < o.ptr; + } + DCON_RELEASE_INLINE bool operator<=(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr <= o.ptr; + } + DCON_RELEASE_INLINE dummy_rel_const_fat_id operator[](ptrdiff_t n) const noexcept { + return dummy_rel_const_fat_id(container, *(ptr + n)); + } + }; + + struct iterator_thingy_foreach_dummy_rel_as_left_generator { + data_container& container; + thingy_id ob; + iterator_thingy_foreach_dummy_rel_as_left_generator(data_container& c, thingy_id o) : container(c), ob(o) {} + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left begin() const noexcept { + return iterator_thingy_foreach_dummy_rel_as_left(container, ob); + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left end() const noexcept { + return iterator_thingy_foreach_dummy_rel_as_left(container, ob, 0); + } + }; + struct const_iterator_thingy_foreach_dummy_rel_as_left_generator { + data_container const& container; + thingy_id ob; + const_iterator_thingy_foreach_dummy_rel_as_left_generator(data_container const& c, thingy_id o) : container(c), ob(o) {} + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left begin() const noexcept { + return const_iterator_thingy_foreach_dummy_rel_as_left(container, ob); + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left end() const noexcept { + return const_iterator_thingy_foreach_dummy_rel_as_left(container, ob, 0); + } + }; + + class object_iterator_thingy2 { + private: + data_container& container; + uint32_t index = 0; + public: + object_iterator_thingy2(data_container& c, uint32_t i) noexcept; + DCON_RELEASE_INLINE object_iterator_thingy2& operator++() noexcept; + DCON_RELEASE_INLINE object_iterator_thingy2& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(object_iterator_thingy2 const& o) const noexcept { + return &container == &o.container && index == o.index; + } + DCON_RELEASE_INLINE bool operator!=(object_iterator_thingy2 const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE thingy2_fat_id operator*() const noexcept { + return thingy2_fat_id(container, thingy2_id(thingy2_id::value_base_t(index))); + } + DCON_RELEASE_INLINE object_iterator_thingy2& operator+=(int32_t n) noexcept { + index = uint32_t(int32_t(index) + n); + return *this; + } + DCON_RELEASE_INLINE object_iterator_thingy2& operator-=(int32_t n) noexcept { + index = uint32_t(int32_t(index) - n); + return *this; + } + DCON_RELEASE_INLINE object_iterator_thingy2 operator+(int32_t n) const noexcept { + return object_iterator_thingy2(container, uint32_t(int32_t(index) + n)); + } + DCON_RELEASE_INLINE object_iterator_thingy2 operator-(int32_t n) const noexcept { + return object_iterator_thingy2(container, uint32_t(int32_t(index) - n)); + } + DCON_RELEASE_INLINE int32_t operator-(object_iterator_thingy2 const& o) const noexcept { + return int32_t(index) - int32_t(o.index); + } + DCON_RELEASE_INLINE bool operator>(object_iterator_thingy2 const& o) const noexcept { + return index > o.index; + } + DCON_RELEASE_INLINE bool operator>=(object_iterator_thingy2 const& o) const noexcept { + return index >= o.index; + } + DCON_RELEASE_INLINE bool operator<(object_iterator_thingy2 const& o) const noexcept { + return index < o.index; + } + DCON_RELEASE_INLINE bool operator<=(object_iterator_thingy2 const& o) const noexcept { + return index <= o.index; + } + DCON_RELEASE_INLINE thingy2_fat_id operator[](int32_t n) const noexcept { + return thingy2_fat_id(container, thingy2_id(thingy2_id::value_base_t(int32_t(index) + n))); + } + }; + class const_object_iterator_thingy2 { + private: + data_container const& container; + uint32_t index = 0; + public: + const_object_iterator_thingy2(data_container const& c, uint32_t i) noexcept; + DCON_RELEASE_INLINE const_object_iterator_thingy2& operator++() noexcept; + DCON_RELEASE_INLINE const_object_iterator_thingy2& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(const_object_iterator_thingy2 const& o) const noexcept { + return &container == &o.container && index == o.index; + } + DCON_RELEASE_INLINE bool operator!=(const_object_iterator_thingy2 const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE thingy2_const_fat_id operator*() const noexcept { + return thingy2_const_fat_id(container, thingy2_id(thingy2_id::value_base_t(index))); + } + DCON_RELEASE_INLINE const_object_iterator_thingy2& operator+=(int32_t n) noexcept { + index = uint32_t(int32_t(index) + n); + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy2& operator-=(int32_t n) noexcept { + index = uint32_t(int32_t(index) - n); + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy2 operator+(int32_t n) const noexcept { + return const_object_iterator_thingy2(container, uint32_t(int32_t(index) + n)); + } + DCON_RELEASE_INLINE const_object_iterator_thingy2 operator-(int32_t n) const noexcept { + return const_object_iterator_thingy2(container, uint32_t(int32_t(index) - n)); + } + DCON_RELEASE_INLINE int32_t operator-(const_object_iterator_thingy2 const& o) const noexcept { + return int32_t(index) - int32_t(o.index); + } + DCON_RELEASE_INLINE bool operator>(const_object_iterator_thingy2 const& o) const noexcept { + return index > o.index; + } + DCON_RELEASE_INLINE bool operator>=(const_object_iterator_thingy2 const& o) const noexcept { + return index >= o.index; + } + DCON_RELEASE_INLINE bool operator<(const_object_iterator_thingy2 const& o) const noexcept { + return index < o.index; + } + DCON_RELEASE_INLINE bool operator<=(const_object_iterator_thingy2 const& o) const noexcept { + return index <= o.index; + } + DCON_RELEASE_INLINE thingy2_const_fat_id operator[](int32_t n) const noexcept { + return thingy2_const_fat_id(container, thingy2_id(thingy2_id::value_base_t(int32_t(index) + n))); + } + }; + + class object_iterator_dummy_rel { + private: + data_container& container; + uint32_t index = 0; + public: + object_iterator_dummy_rel(data_container& c, uint32_t i) noexcept; + DCON_RELEASE_INLINE object_iterator_dummy_rel& operator++() noexcept; + DCON_RELEASE_INLINE object_iterator_dummy_rel& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(object_iterator_dummy_rel const& o) const noexcept { + return &container == &o.container && index == o.index; + } + DCON_RELEASE_INLINE bool operator!=(object_iterator_dummy_rel const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE dummy_rel_fat_id operator*() const noexcept { + return dummy_rel_fat_id(container, dummy_rel_id(dummy_rel_id::value_base_t(index))); + } + DCON_RELEASE_INLINE object_iterator_dummy_rel& operator+=(int32_t n) noexcept { + index = uint32_t(int32_t(index) + n); + return *this; + } + DCON_RELEASE_INLINE object_iterator_dummy_rel& operator-=(int32_t n) noexcept { + index = uint32_t(int32_t(index) - n); + return *this; + } + DCON_RELEASE_INLINE object_iterator_dummy_rel operator+(int32_t n) const noexcept { + return object_iterator_dummy_rel(container, uint32_t(int32_t(index) + n)); + } + DCON_RELEASE_INLINE object_iterator_dummy_rel operator-(int32_t n) const noexcept { + return object_iterator_dummy_rel(container, uint32_t(int32_t(index) - n)); + } + DCON_RELEASE_INLINE int32_t operator-(object_iterator_dummy_rel const& o) const noexcept { + return int32_t(index) - int32_t(o.index); + } + DCON_RELEASE_INLINE bool operator>(object_iterator_dummy_rel const& o) const noexcept { + return index > o.index; + } + DCON_RELEASE_INLINE bool operator>=(object_iterator_dummy_rel const& o) const noexcept { + return index >= o.index; + } + DCON_RELEASE_INLINE bool operator<(object_iterator_dummy_rel const& o) const noexcept { + return index < o.index; + } + DCON_RELEASE_INLINE bool operator<=(object_iterator_dummy_rel const& o) const noexcept { + return index <= o.index; + } + DCON_RELEASE_INLINE dummy_rel_fat_id operator[](int32_t n) const noexcept { + return dummy_rel_fat_id(container, dummy_rel_id(dummy_rel_id::value_base_t(int32_t(index) + n))); + } + }; + class const_object_iterator_dummy_rel { + private: + data_container const& container; + uint32_t index = 0; + public: + const_object_iterator_dummy_rel(data_container const& c, uint32_t i) noexcept; + DCON_RELEASE_INLINE const_object_iterator_dummy_rel& operator++() noexcept; + DCON_RELEASE_INLINE const_object_iterator_dummy_rel& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(const_object_iterator_dummy_rel const& o) const noexcept { + return &container == &o.container && index == o.index; + } + DCON_RELEASE_INLINE bool operator!=(const_object_iterator_dummy_rel const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE dummy_rel_const_fat_id operator*() const noexcept { + return dummy_rel_const_fat_id(container, dummy_rel_id(dummy_rel_id::value_base_t(index))); + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel& operator+=(int32_t n) noexcept { + index = uint32_t(int32_t(index) + n); + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel& operator-=(int32_t n) noexcept { + index = uint32_t(int32_t(index) - n); + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel operator+(int32_t n) const noexcept { + return const_object_iterator_dummy_rel(container, uint32_t(int32_t(index) + n)); + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel operator-(int32_t n) const noexcept { + return const_object_iterator_dummy_rel(container, uint32_t(int32_t(index) - n)); + } + DCON_RELEASE_INLINE int32_t operator-(const_object_iterator_dummy_rel const& o) const noexcept { + return int32_t(index) - int32_t(o.index); + } + DCON_RELEASE_INLINE bool operator>(const_object_iterator_dummy_rel const& o) const noexcept { + return index > o.index; + } + DCON_RELEASE_INLINE bool operator>=(const_object_iterator_dummy_rel const& o) const noexcept { + return index >= o.index; + } + DCON_RELEASE_INLINE bool operator<(const_object_iterator_dummy_rel const& o) const noexcept { + return index < o.index; + } + DCON_RELEASE_INLINE bool operator<=(const_object_iterator_dummy_rel const& o) const noexcept { + return index <= o.index; + } + DCON_RELEASE_INLINE dummy_rel_const_fat_id operator[](int32_t n) const noexcept { + return dummy_rel_const_fat_id(container, dummy_rel_id(dummy_rel_id::value_base_t(int32_t(index) + n))); + } + }; + + } + class alignas(64) data_container { public: internal::thingy_class thingy; @@ -770,6 +1229,12 @@ namespace ns { DCON_RELEASE_INLINE void thingy_set_custom_struct(thingy_id id, c_struct const& value) noexcept { thingy.m_custom_struct.vptr()[id.index()] = value; } + DCON_RELEASE_INLINE internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator thingy_get_dummy_rel_as_left(thingy_id id) const { + return internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator(*this, id); + } + DCON_RELEASE_INLINE internal::iterator_thingy_foreach_dummy_rel_as_left_generator thingy_get_dummy_rel_as_left(thingy_id id) { + return internal::iterator_thingy_foreach_dummy_rel_as_left_generator(*this, id); + } template DCON_RELEASE_INLINE void thingy_for_each_dummy_rel_as_left(thingy_id id, T&& func) const { if(bool(id)) { @@ -790,6 +1255,12 @@ namespace ns { dcon::local_vector temp(rng.first, rng.second); std::for_each(temp.begin(), temp.end(), [t = this](dummy_rel_id i) { t->dummy_rel_set_left(i, thingy_id()); }); } + DCON_RELEASE_INLINE internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator thingy_get_dummy_rel(thingy_id id) const { + return internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator(*this, id); + } + DCON_RELEASE_INLINE internal::iterator_thingy_foreach_dummy_rel_as_left_generator thingy_get_dummy_rel(thingy_id id) { + return internal::iterator_thingy_foreach_dummy_rel_as_left_generator(*this, id); + } template DCON_RELEASE_INLINE void thingy_for_each_dummy_rel(thingy_id id, T&& func) const { if(bool(id)) { @@ -1257,6 +1728,26 @@ namespace ns { func(tmp); } } + friend internal::const_object_iterator_thingy; + friend internal::object_iterator_thingy; + struct { + internal::object_iterator_thingy begin() { + data_container* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy)); + return internal::object_iterator_thingy(*container, uint32_t(0)); + } + internal::object_iterator_thingy end() { + data_container* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy)); + return internal::object_iterator_thingy(*container, container->thingy_size()); + } + internal::const_object_iterator_thingy begin() const { + data_container const* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy)); + return internal::const_object_iterator_thingy(*container, uint32_t(0)); + } + internal::const_object_iterator_thingy end() const { + data_container const* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy)); + return internal::const_object_iterator_thingy(*container, container->thingy_size()); + } + } in_thingy ; template DCON_RELEASE_INLINE void for_each_thingy2(T&& func) { @@ -1265,6 +1756,26 @@ namespace ns { func(tmp); } } + friend internal::const_object_iterator_thingy2; + friend internal::object_iterator_thingy2; + struct { + internal::object_iterator_thingy2 begin() { + data_container* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy2)); + return internal::object_iterator_thingy2(*container, uint32_t(0)); + } + internal::object_iterator_thingy2 end() { + data_container* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy2)); + return internal::object_iterator_thingy2(*container, container->thingy2_size()); + } + internal::const_object_iterator_thingy2 begin() const { + data_container const* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy2)); + return internal::const_object_iterator_thingy2(*container, uint32_t(0)); + } + internal::const_object_iterator_thingy2 end() const { + data_container const* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy2)); + return internal::const_object_iterator_thingy2(*container, container->thingy2_size()); + } + } in_thingy2 ; template DCON_RELEASE_INLINE void for_each_dummy_rel(T&& func) { @@ -1273,6 +1784,26 @@ namespace ns { func(tmp); } } + friend internal::const_object_iterator_dummy_rel; + friend internal::object_iterator_dummy_rel; + struct { + internal::object_iterator_dummy_rel begin() { + data_container* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_dummy_rel)); + return internal::object_iterator_dummy_rel(*container, uint32_t(0)); + } + internal::object_iterator_dummy_rel end() { + data_container* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_dummy_rel)); + return internal::object_iterator_dummy_rel(*container, container->dummy_rel_size()); + } + internal::const_object_iterator_dummy_rel begin() const { + data_container const* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_dummy_rel)); + return internal::const_object_iterator_dummy_rel(*container, uint32_t(0)); + } + internal::const_object_iterator_dummy_rel end() const { + data_container const* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_dummy_rel)); + return internal::const_object_iterator_dummy_rel(*container, container->dummy_rel_size()); + } + } in_dummy_rel ; @@ -2089,6 +2620,9 @@ namespace ns { DCON_RELEASE_INLINE void thingy_fat_id::remove_all_dummy_rel_as_left() const noexcept { container.thingy_remove_all_dummy_rel_as_left(id); } + DCON_RELEASE_INLINE internal::iterator_thingy_foreach_dummy_rel_as_left_generator thingy_fat_id::get_dummy_rel_as_left() const { + return internal::iterator_thingy_foreach_dummy_rel_as_left_generator(container, id); + } template DCON_RELEASE_INLINE void thingy_fat_id::for_each_dummy_rel(T&& func) const { container.thingy_for_each_dummy_rel(id, [&, t = this](dummy_rel_id i){func(fatten(t->container, i));}); @@ -2099,6 +2633,9 @@ namespace ns { DCON_RELEASE_INLINE void thingy_fat_id::remove_all_dummy_rel() const noexcept { container.thingy_remove_all_dummy_rel(id); } + DCON_RELEASE_INLINE internal::iterator_thingy_foreach_dummy_rel_as_left_generator thingy_fat_id::get_dummy_rel() const { + return internal::iterator_thingy_foreach_dummy_rel_as_left_generator(container, id); + } template DCON_RELEASE_INLINE void thingy_fat_id::for_each_right_from_dummy_rel(T&& func) const { container.thingy_for_each_right_from_dummy_rel(id, [&, t = this](thingy2_id i){func(fatten(t->container, i));}); @@ -2129,6 +2666,9 @@ namespace ns { DCON_RELEASE_INLINE std::pair thingy_const_fat_id::range_of_dummy_rel_as_left() const { return container.thingy_range_of_dummy_rel_as_left(id); } + DCON_RELEASE_INLINE internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator thingy_const_fat_id::get_dummy_rel_as_left() const { + return internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator(container, id); + } template DCON_RELEASE_INLINE void thingy_const_fat_id::for_each_dummy_rel(T&& func) const { container.thingy_for_each_dummy_rel(id, [&, t = this](dummy_rel_id i){func(fatten(t->container, i));}); @@ -2136,6 +2676,9 @@ namespace ns { DCON_RELEASE_INLINE std::pair thingy_const_fat_id::range_of_dummy_rel() const { return container.thingy_range_of_dummy_rel(id); } + DCON_RELEASE_INLINE internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator thingy_const_fat_id::get_dummy_rel() const { + return internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator(container, id); + } template DCON_RELEASE_INLINE void thingy_const_fat_id::for_each_right_from_dummy_rel(T&& func) const { container.thingy_for_each_right_from_dummy_rel(id, [&, t = this](thingy2_id i){func(fatten(t->container, i));}); @@ -2225,6 +2768,100 @@ namespace ns { namespace internal { + DCON_RELEASE_INLINE object_iterator_thingy::object_iterator_thingy(data_container& c, uint32_t i) noexcept : container(c), index(i) { + } + DCON_RELEASE_INLINE const_object_iterator_thingy::const_object_iterator_thingy(data_container const& c, uint32_t i) noexcept : container(c), index(i) { + } + DCON_RELEASE_INLINE object_iterator_thingy& object_iterator_thingy::operator++() noexcept { + ++index; + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy& const_object_iterator_thingy::operator++() noexcept { + ++index; + return *this; + } + DCON_RELEASE_INLINE object_iterator_thingy& object_iterator_thingy::operator--() noexcept { + --index; + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy& const_object_iterator_thingy::operator--() noexcept { + --index; + return *this; + } + + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left::iterator_thingy_foreach_dummy_rel_as_left(data_container& c, thingy_id fr) noexcept : container(c) { + ptr = container.dummy_rel.m_array_left.vptr()[fr.index()].data(); + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left::iterator_thingy_foreach_dummy_rel_as_left(data_container& c, thingy_id fr, int) noexcept : container(c) { + auto& vref = container.dummy_rel.m_array_left.vptr()[fr.index()]; + ptr = vref.data() + vref.size(); + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left& iterator_thingy_foreach_dummy_rel_as_left::operator++() noexcept { + ++ptr; + return *this; + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left& iterator_thingy_foreach_dummy_rel_as_left::operator--() noexcept { + --ptr; + return *this; + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left::const_iterator_thingy_foreach_dummy_rel_as_left(data_container const& c, thingy_id fr) noexcept : container(c) { + ptr = container.dummy_rel.m_array_left.vptr()[fr.index()].data(); + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left::const_iterator_thingy_foreach_dummy_rel_as_left(data_container const& c, thingy_id fr, int) noexcept : container(c) { + auto& vref = container.dummy_rel.m_array_left.vptr()[fr.index()]; + ptr = vref.data() + vref.size(); + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left& const_iterator_thingy_foreach_dummy_rel_as_left::operator++() noexcept { + ++ptr; + return *this; + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left& const_iterator_thingy_foreach_dummy_rel_as_left::operator--() noexcept { + --ptr; + return *this; + } + + DCON_RELEASE_INLINE object_iterator_thingy2::object_iterator_thingy2(data_container& c, uint32_t i) noexcept : container(c), index(i) { + } + DCON_RELEASE_INLINE const_object_iterator_thingy2::const_object_iterator_thingy2(data_container const& c, uint32_t i) noexcept : container(c), index(i) { + } + DCON_RELEASE_INLINE object_iterator_thingy2& object_iterator_thingy2::operator++() noexcept { + ++index; + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy2& const_object_iterator_thingy2::operator++() noexcept { + ++index; + return *this; + } + DCON_RELEASE_INLINE object_iterator_thingy2& object_iterator_thingy2::operator--() noexcept { + --index; + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy2& const_object_iterator_thingy2::operator--() noexcept { + --index; + return *this; + } + + DCON_RELEASE_INLINE object_iterator_dummy_rel::object_iterator_dummy_rel(data_container& c, uint32_t i) noexcept : container(c), index(i) { + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel::const_object_iterator_dummy_rel(data_container const& c, uint32_t i) noexcept : container(c), index(i) { + } + DCON_RELEASE_INLINE object_iterator_dummy_rel& object_iterator_dummy_rel::operator++() noexcept { + ++index; + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel& const_object_iterator_dummy_rel::operator++() noexcept { + ++index; + return *this; + } + DCON_RELEASE_INLINE object_iterator_dummy_rel& object_iterator_dummy_rel::operator--() noexcept { + --index; + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel& const_object_iterator_dummy_rel::operator--() noexcept { + --index; + return *this; + } + }; diff --git a/Catch_serialization_tests/old_ser.hpp b/Catch_serialization_tests/old_ser.hpp index 257fa27..600bc98 100644 --- a/Catch_serialization_tests/old_ser.hpp +++ b/Catch_serialization_tests/old_ser.hpp @@ -196,7 +196,12 @@ namespace os { class data_container; namespace internal { + class const_object_iterator_thingy; + class object_iterator_thingy; + class alignas(64) thingy_class { + friend const_object_iterator_thingy; + friend object_iterator_thingy; private: // // storage space for i_value of type int16_t @@ -360,7 +365,12 @@ namespace os { friend data_container; }; + class const_object_iterator_thingy2; + class object_iterator_thingy2; + class alignas(64) thingy2_class { + friend const_object_iterator_thingy2; + friend object_iterator_thingy2; private: // // storage space for some_value of type int32_t @@ -381,7 +391,18 @@ namespace os { friend data_container; }; + class const_object_iterator_dummy_rel; + class object_iterator_dummy_rel; + class const_iterator_thingy_foreach_dummy_rel_as_left; + class iterator_thingy_foreach_dummy_rel_as_left; + struct const_iterator_thingy_foreach_dummy_rel_as_left_generator; + struct iterator_thingy_foreach_dummy_rel_as_left_generator; + class alignas(64) dummy_rel_class { + friend const_object_iterator_dummy_rel; + friend object_iterator_dummy_rel; + friend const_iterator_thingy_foreach_dummy_rel_as_left; + friend iterator_thingy_foreach_dummy_rel_as_left; private: // // storage space for left of type thingy_id @@ -484,10 +505,12 @@ namespace os { DCON_RELEASE_INLINE void for_each_dummy_rel_as_left(T&& func) const; DCON_RELEASE_INLINE std::pair range_of_dummy_rel_as_left() const; DCON_RELEASE_INLINE void remove_all_dummy_rel_as_left() const noexcept; + DCON_RELEASE_INLINE internal::iterator_thingy_foreach_dummy_rel_as_left_generator get_dummy_rel_as_left() const; template DCON_RELEASE_INLINE void for_each_dummy_rel(T&& func) const; DCON_RELEASE_INLINE std::pair range_of_dummy_rel() const; DCON_RELEASE_INLINE void remove_all_dummy_rel() const noexcept; + DCON_RELEASE_INLINE internal::iterator_thingy_foreach_dummy_rel_as_left_generator get_dummy_rel() const; template DCON_RELEASE_INLINE void for_each_right_from_dummy_rel(T&& func) const; DCON_RELEASE_INLINE bool has_right_from_dummy_rel(thingy2_id target) const; @@ -557,9 +580,11 @@ namespace os { template DCON_RELEASE_INLINE void for_each_dummy_rel_as_left(T&& func) const; DCON_RELEASE_INLINE std::pair range_of_dummy_rel_as_left() const; + DCON_RELEASE_INLINE internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator get_dummy_rel_as_left() const; template DCON_RELEASE_INLINE void for_each_dummy_rel(T&& func) const; DCON_RELEASE_INLINE std::pair range_of_dummy_rel() const; + DCON_RELEASE_INLINE internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator get_dummy_rel() const; template DCON_RELEASE_INLINE void for_each_right_from_dummy_rel(T&& func) const; DCON_RELEASE_INLINE bool has_right_from_dummy_rel(thingy2_id target) const; @@ -798,6 +823,440 @@ namespace os { return dummy_rel_const_fat_id(c, id); } + namespace internal { + class object_iterator_thingy { + private: + data_container& container; + uint32_t index = 0; + public: + object_iterator_thingy(data_container& c, uint32_t i) noexcept; + DCON_RELEASE_INLINE object_iterator_thingy& operator++() noexcept; + DCON_RELEASE_INLINE object_iterator_thingy& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(object_iterator_thingy const& o) const noexcept { + return &container == &o.container && index == o.index; + } + DCON_RELEASE_INLINE bool operator!=(object_iterator_thingy const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE thingy_fat_id operator*() const noexcept { + return thingy_fat_id(container, thingy_id(thingy_id::value_base_t(index))); + } + DCON_RELEASE_INLINE object_iterator_thingy& operator+=(int32_t n) noexcept { + index = uint32_t(int32_t(index) + n); + return *this; + } + DCON_RELEASE_INLINE object_iterator_thingy& operator-=(int32_t n) noexcept { + index = uint32_t(int32_t(index) - n); + return *this; + } + DCON_RELEASE_INLINE object_iterator_thingy operator+(int32_t n) const noexcept { + return object_iterator_thingy(container, uint32_t(int32_t(index) + n)); + } + DCON_RELEASE_INLINE object_iterator_thingy operator-(int32_t n) const noexcept { + return object_iterator_thingy(container, uint32_t(int32_t(index) - n)); + } + DCON_RELEASE_INLINE int32_t operator-(object_iterator_thingy const& o) const noexcept { + return int32_t(index) - int32_t(o.index); + } + DCON_RELEASE_INLINE bool operator>(object_iterator_thingy const& o) const noexcept { + return index > o.index; + } + DCON_RELEASE_INLINE bool operator>=(object_iterator_thingy const& o) const noexcept { + return index >= o.index; + } + DCON_RELEASE_INLINE bool operator<(object_iterator_thingy const& o) const noexcept { + return index < o.index; + } + DCON_RELEASE_INLINE bool operator<=(object_iterator_thingy const& o) const noexcept { + return index <= o.index; + } + DCON_RELEASE_INLINE thingy_fat_id operator[](int32_t n) const noexcept { + return thingy_fat_id(container, thingy_id(thingy_id::value_base_t(int32_t(index) + n))); + } + }; + class const_object_iterator_thingy { + private: + data_container const& container; + uint32_t index = 0; + public: + const_object_iterator_thingy(data_container const& c, uint32_t i) noexcept; + DCON_RELEASE_INLINE const_object_iterator_thingy& operator++() noexcept; + DCON_RELEASE_INLINE const_object_iterator_thingy& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(const_object_iterator_thingy const& o) const noexcept { + return &container == &o.container && index == o.index; + } + DCON_RELEASE_INLINE bool operator!=(const_object_iterator_thingy const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE thingy_const_fat_id operator*() const noexcept { + return thingy_const_fat_id(container, thingy_id(thingy_id::value_base_t(index))); + } + DCON_RELEASE_INLINE const_object_iterator_thingy& operator+=(int32_t n) noexcept { + index = uint32_t(int32_t(index) + n); + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy& operator-=(int32_t n) noexcept { + index = uint32_t(int32_t(index) - n); + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy operator+(int32_t n) const noexcept { + return const_object_iterator_thingy(container, uint32_t(int32_t(index) + n)); + } + DCON_RELEASE_INLINE const_object_iterator_thingy operator-(int32_t n) const noexcept { + return const_object_iterator_thingy(container, uint32_t(int32_t(index) - n)); + } + DCON_RELEASE_INLINE int32_t operator-(const_object_iterator_thingy const& o) const noexcept { + return int32_t(index) - int32_t(o.index); + } + DCON_RELEASE_INLINE bool operator>(const_object_iterator_thingy const& o) const noexcept { + return index > o.index; + } + DCON_RELEASE_INLINE bool operator>=(const_object_iterator_thingy const& o) const noexcept { + return index >= o.index; + } + DCON_RELEASE_INLINE bool operator<(const_object_iterator_thingy const& o) const noexcept { + return index < o.index; + } + DCON_RELEASE_INLINE bool operator<=(const_object_iterator_thingy const& o) const noexcept { + return index <= o.index; + } + DCON_RELEASE_INLINE thingy_const_fat_id operator[](int32_t n) const noexcept { + return thingy_const_fat_id(container, thingy_id(thingy_id::value_base_t(int32_t(index) + n))); + } + }; + + class iterator_thingy_foreach_dummy_rel_as_left { + private: + data_container& container; + dummy_rel_id const* ptr = nullptr; + public: + iterator_thingy_foreach_dummy_rel_as_left(data_container& c, thingy_id fr) noexcept; + iterator_thingy_foreach_dummy_rel_as_left(data_container& c, dummy_rel_id const* r) noexcept : container(c), ptr(r) {} + iterator_thingy_foreach_dummy_rel_as_left(data_container& c, thingy_id fr, int) noexcept; + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left& operator++() noexcept; + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr == o.ptr; + } + DCON_RELEASE_INLINE bool operator!=(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE dummy_rel_fat_id operator*() const noexcept { + return dummy_rel_fat_id(container, *ptr); + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left& operator+=(ptrdiff_t n) noexcept { + ptr += n; + return *this; + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left& operator-=(ptrdiff_t n) noexcept { + ptr -= n; + return *this; + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left operator+(ptrdiff_t n) const noexcept { + return iterator_thingy_foreach_dummy_rel_as_left(container, ptr + n); + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left operator-(ptrdiff_t n) const noexcept { + return iterator_thingy_foreach_dummy_rel_as_left(container, ptr - n); + } + DCON_RELEASE_INLINE ptrdiff_t operator-(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr - o.ptr; + } + DCON_RELEASE_INLINE bool operator>(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr > o.ptr; + } + DCON_RELEASE_INLINE bool operator>=(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr >= o.ptr; + } + DCON_RELEASE_INLINE bool operator<(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr < o.ptr; + } + DCON_RELEASE_INLINE bool operator<=(iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr <= o.ptr; + } + DCON_RELEASE_INLINE dummy_rel_fat_id operator[](ptrdiff_t n) const noexcept { + return dummy_rel_fat_id(container, *(ptr + n)); + } + }; + class const_iterator_thingy_foreach_dummy_rel_as_left { + private: + data_container const& container; + dummy_rel_id const* ptr = nullptr; + public: + const_iterator_thingy_foreach_dummy_rel_as_left(data_container const& c, thingy_id fr) noexcept; + const_iterator_thingy_foreach_dummy_rel_as_left(data_container const& c, dummy_rel_id const* r) noexcept : container(c), ptr(r) {} + const_iterator_thingy_foreach_dummy_rel_as_left(data_container const& c, thingy_id fr, int) noexcept; + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left& operator++() noexcept; + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr == o.ptr; + } + DCON_RELEASE_INLINE bool operator!=(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE dummy_rel_const_fat_id operator*() const noexcept { + return dummy_rel_const_fat_id(container, *ptr); + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left& operator+=(ptrdiff_t n) noexcept { + ptr += n; + return *this; + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left& operator-=(ptrdiff_t n) noexcept { + ptr -= n; + return *this; + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left operator+(ptrdiff_t n) const noexcept { + return const_iterator_thingy_foreach_dummy_rel_as_left(container, ptr + n); + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left operator-(ptrdiff_t n) const noexcept { + return const_iterator_thingy_foreach_dummy_rel_as_left(container, ptr - n); + } + DCON_RELEASE_INLINE ptrdiff_t operator-(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr - o.ptr; + } + DCON_RELEASE_INLINE bool operator>(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr > o.ptr; + } + DCON_RELEASE_INLINE bool operator>=(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr >= o.ptr; + } + DCON_RELEASE_INLINE bool operator<(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr < o.ptr; + } + DCON_RELEASE_INLINE bool operator<=(const_iterator_thingy_foreach_dummy_rel_as_left const& o) const noexcept { + return ptr <= o.ptr; + } + DCON_RELEASE_INLINE dummy_rel_const_fat_id operator[](ptrdiff_t n) const noexcept { + return dummy_rel_const_fat_id(container, *(ptr + n)); + } + }; + + struct iterator_thingy_foreach_dummy_rel_as_left_generator { + data_container& container; + thingy_id ob; + iterator_thingy_foreach_dummy_rel_as_left_generator(data_container& c, thingy_id o) : container(c), ob(o) {} + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left begin() const noexcept { + return iterator_thingy_foreach_dummy_rel_as_left(container, ob); + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left end() const noexcept { + return iterator_thingy_foreach_dummy_rel_as_left(container, ob, 0); + } + }; + struct const_iterator_thingy_foreach_dummy_rel_as_left_generator { + data_container const& container; + thingy_id ob; + const_iterator_thingy_foreach_dummy_rel_as_left_generator(data_container const& c, thingy_id o) : container(c), ob(o) {} + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left begin() const noexcept { + return const_iterator_thingy_foreach_dummy_rel_as_left(container, ob); + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left end() const noexcept { + return const_iterator_thingy_foreach_dummy_rel_as_left(container, ob, 0); + } + }; + + class object_iterator_thingy2 { + private: + data_container& container; + uint32_t index = 0; + public: + object_iterator_thingy2(data_container& c, uint32_t i) noexcept; + DCON_RELEASE_INLINE object_iterator_thingy2& operator++() noexcept; + DCON_RELEASE_INLINE object_iterator_thingy2& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(object_iterator_thingy2 const& o) const noexcept { + return &container == &o.container && index == o.index; + } + DCON_RELEASE_INLINE bool operator!=(object_iterator_thingy2 const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE thingy2_fat_id operator*() const noexcept { + return thingy2_fat_id(container, thingy2_id(thingy2_id::value_base_t(index))); + } + DCON_RELEASE_INLINE object_iterator_thingy2& operator+=(int32_t n) noexcept { + index = uint32_t(int32_t(index) + n); + return *this; + } + DCON_RELEASE_INLINE object_iterator_thingy2& operator-=(int32_t n) noexcept { + index = uint32_t(int32_t(index) - n); + return *this; + } + DCON_RELEASE_INLINE object_iterator_thingy2 operator+(int32_t n) const noexcept { + return object_iterator_thingy2(container, uint32_t(int32_t(index) + n)); + } + DCON_RELEASE_INLINE object_iterator_thingy2 operator-(int32_t n) const noexcept { + return object_iterator_thingy2(container, uint32_t(int32_t(index) - n)); + } + DCON_RELEASE_INLINE int32_t operator-(object_iterator_thingy2 const& o) const noexcept { + return int32_t(index) - int32_t(o.index); + } + DCON_RELEASE_INLINE bool operator>(object_iterator_thingy2 const& o) const noexcept { + return index > o.index; + } + DCON_RELEASE_INLINE bool operator>=(object_iterator_thingy2 const& o) const noexcept { + return index >= o.index; + } + DCON_RELEASE_INLINE bool operator<(object_iterator_thingy2 const& o) const noexcept { + return index < o.index; + } + DCON_RELEASE_INLINE bool operator<=(object_iterator_thingy2 const& o) const noexcept { + return index <= o.index; + } + DCON_RELEASE_INLINE thingy2_fat_id operator[](int32_t n) const noexcept { + return thingy2_fat_id(container, thingy2_id(thingy2_id::value_base_t(int32_t(index) + n))); + } + }; + class const_object_iterator_thingy2 { + private: + data_container const& container; + uint32_t index = 0; + public: + const_object_iterator_thingy2(data_container const& c, uint32_t i) noexcept; + DCON_RELEASE_INLINE const_object_iterator_thingy2& operator++() noexcept; + DCON_RELEASE_INLINE const_object_iterator_thingy2& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(const_object_iterator_thingy2 const& o) const noexcept { + return &container == &o.container && index == o.index; + } + DCON_RELEASE_INLINE bool operator!=(const_object_iterator_thingy2 const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE thingy2_const_fat_id operator*() const noexcept { + return thingy2_const_fat_id(container, thingy2_id(thingy2_id::value_base_t(index))); + } + DCON_RELEASE_INLINE const_object_iterator_thingy2& operator+=(int32_t n) noexcept { + index = uint32_t(int32_t(index) + n); + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy2& operator-=(int32_t n) noexcept { + index = uint32_t(int32_t(index) - n); + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy2 operator+(int32_t n) const noexcept { + return const_object_iterator_thingy2(container, uint32_t(int32_t(index) + n)); + } + DCON_RELEASE_INLINE const_object_iterator_thingy2 operator-(int32_t n) const noexcept { + return const_object_iterator_thingy2(container, uint32_t(int32_t(index) - n)); + } + DCON_RELEASE_INLINE int32_t operator-(const_object_iterator_thingy2 const& o) const noexcept { + return int32_t(index) - int32_t(o.index); + } + DCON_RELEASE_INLINE bool operator>(const_object_iterator_thingy2 const& o) const noexcept { + return index > o.index; + } + DCON_RELEASE_INLINE bool operator>=(const_object_iterator_thingy2 const& o) const noexcept { + return index >= o.index; + } + DCON_RELEASE_INLINE bool operator<(const_object_iterator_thingy2 const& o) const noexcept { + return index < o.index; + } + DCON_RELEASE_INLINE bool operator<=(const_object_iterator_thingy2 const& o) const noexcept { + return index <= o.index; + } + DCON_RELEASE_INLINE thingy2_const_fat_id operator[](int32_t n) const noexcept { + return thingy2_const_fat_id(container, thingy2_id(thingy2_id::value_base_t(int32_t(index) + n))); + } + }; + + class object_iterator_dummy_rel { + private: + data_container& container; + uint32_t index = 0; + public: + object_iterator_dummy_rel(data_container& c, uint32_t i) noexcept; + DCON_RELEASE_INLINE object_iterator_dummy_rel& operator++() noexcept; + DCON_RELEASE_INLINE object_iterator_dummy_rel& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(object_iterator_dummy_rel const& o) const noexcept { + return &container == &o.container && index == o.index; + } + DCON_RELEASE_INLINE bool operator!=(object_iterator_dummy_rel const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE dummy_rel_fat_id operator*() const noexcept { + return dummy_rel_fat_id(container, dummy_rel_id(dummy_rel_id::value_base_t(index))); + } + DCON_RELEASE_INLINE object_iterator_dummy_rel& operator+=(int32_t n) noexcept { + index = uint32_t(int32_t(index) + n); + return *this; + } + DCON_RELEASE_INLINE object_iterator_dummy_rel& operator-=(int32_t n) noexcept { + index = uint32_t(int32_t(index) - n); + return *this; + } + DCON_RELEASE_INLINE object_iterator_dummy_rel operator+(int32_t n) const noexcept { + return object_iterator_dummy_rel(container, uint32_t(int32_t(index) + n)); + } + DCON_RELEASE_INLINE object_iterator_dummy_rel operator-(int32_t n) const noexcept { + return object_iterator_dummy_rel(container, uint32_t(int32_t(index) - n)); + } + DCON_RELEASE_INLINE int32_t operator-(object_iterator_dummy_rel const& o) const noexcept { + return int32_t(index) - int32_t(o.index); + } + DCON_RELEASE_INLINE bool operator>(object_iterator_dummy_rel const& o) const noexcept { + return index > o.index; + } + DCON_RELEASE_INLINE bool operator>=(object_iterator_dummy_rel const& o) const noexcept { + return index >= o.index; + } + DCON_RELEASE_INLINE bool operator<(object_iterator_dummy_rel const& o) const noexcept { + return index < o.index; + } + DCON_RELEASE_INLINE bool operator<=(object_iterator_dummy_rel const& o) const noexcept { + return index <= o.index; + } + DCON_RELEASE_INLINE dummy_rel_fat_id operator[](int32_t n) const noexcept { + return dummy_rel_fat_id(container, dummy_rel_id(dummy_rel_id::value_base_t(int32_t(index) + n))); + } + }; + class const_object_iterator_dummy_rel { + private: + data_container const& container; + uint32_t index = 0; + public: + const_object_iterator_dummy_rel(data_container const& c, uint32_t i) noexcept; + DCON_RELEASE_INLINE const_object_iterator_dummy_rel& operator++() noexcept; + DCON_RELEASE_INLINE const_object_iterator_dummy_rel& operator--() noexcept; + DCON_RELEASE_INLINE bool operator==(const_object_iterator_dummy_rel const& o) const noexcept { + return &container == &o.container && index == o.index; + } + DCON_RELEASE_INLINE bool operator!=(const_object_iterator_dummy_rel const& o) const noexcept { + return !(*this == o); + } + DCON_RELEASE_INLINE dummy_rel_const_fat_id operator*() const noexcept { + return dummy_rel_const_fat_id(container, dummy_rel_id(dummy_rel_id::value_base_t(index))); + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel& operator+=(int32_t n) noexcept { + index = uint32_t(int32_t(index) + n); + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel& operator-=(int32_t n) noexcept { + index = uint32_t(int32_t(index) - n); + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel operator+(int32_t n) const noexcept { + return const_object_iterator_dummy_rel(container, uint32_t(int32_t(index) + n)); + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel operator-(int32_t n) const noexcept { + return const_object_iterator_dummy_rel(container, uint32_t(int32_t(index) - n)); + } + DCON_RELEASE_INLINE int32_t operator-(const_object_iterator_dummy_rel const& o) const noexcept { + return int32_t(index) - int32_t(o.index); + } + DCON_RELEASE_INLINE bool operator>(const_object_iterator_dummy_rel const& o) const noexcept { + return index > o.index; + } + DCON_RELEASE_INLINE bool operator>=(const_object_iterator_dummy_rel const& o) const noexcept { + return index >= o.index; + } + DCON_RELEASE_INLINE bool operator<(const_object_iterator_dummy_rel const& o) const noexcept { + return index < o.index; + } + DCON_RELEASE_INLINE bool operator<=(const_object_iterator_dummy_rel const& o) const noexcept { + return index <= o.index; + } + DCON_RELEASE_INLINE dummy_rel_const_fat_id operator[](int32_t n) const noexcept { + return dummy_rel_const_fat_id(container, dummy_rel_id(dummy_rel_id::value_base_t(int32_t(index) + n))); + } + }; + + } + class alignas(64) data_container { public: internal::thingy_class thingy; @@ -1019,6 +1478,12 @@ namespace os { DCON_RELEASE_INLINE void thingy_set_custom_struct(thingy_id id, c_struct const& value) noexcept { thingy.m_custom_struct.vptr()[id.index()] = value; } + DCON_RELEASE_INLINE internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator thingy_get_dummy_rel_as_left(thingy_id id) const { + return internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator(*this, id); + } + DCON_RELEASE_INLINE internal::iterator_thingy_foreach_dummy_rel_as_left_generator thingy_get_dummy_rel_as_left(thingy_id id) { + return internal::iterator_thingy_foreach_dummy_rel_as_left_generator(*this, id); + } template DCON_RELEASE_INLINE void thingy_for_each_dummy_rel_as_left(thingy_id id, T&& func) const { if(bool(id)) { @@ -1039,6 +1504,12 @@ namespace os { dcon::local_vector temp(rng.first, rng.second); std::for_each(temp.begin(), temp.end(), [t = this](dummy_rel_id i) { t->dummy_rel_set_left(i, thingy_id()); }); } + DCON_RELEASE_INLINE internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator thingy_get_dummy_rel(thingy_id id) const { + return internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator(*this, id); + } + DCON_RELEASE_INLINE internal::iterator_thingy_foreach_dummy_rel_as_left_generator thingy_get_dummy_rel(thingy_id id) { + return internal::iterator_thingy_foreach_dummy_rel_as_left_generator(*this, id); + } template DCON_RELEASE_INLINE void thingy_for_each_dummy_rel(thingy_id id, T&& func) const { if(bool(id)) { @@ -1534,6 +2005,26 @@ namespace os { func(tmp); } } + friend internal::const_object_iterator_thingy; + friend internal::object_iterator_thingy; + struct { + internal::object_iterator_thingy begin() { + data_container* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy)); + return internal::object_iterator_thingy(*container, uint32_t(0)); + } + internal::object_iterator_thingy end() { + data_container* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy)); + return internal::object_iterator_thingy(*container, container->thingy_size()); + } + internal::const_object_iterator_thingy begin() const { + data_container const* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy)); + return internal::const_object_iterator_thingy(*container, uint32_t(0)); + } + internal::const_object_iterator_thingy end() const { + data_container const* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy)); + return internal::const_object_iterator_thingy(*container, container->thingy_size()); + } + } in_thingy ; template DCON_RELEASE_INLINE void for_each_thingy2(T&& func) { @@ -1542,6 +2033,26 @@ namespace os { func(tmp); } } + friend internal::const_object_iterator_thingy2; + friend internal::object_iterator_thingy2; + struct { + internal::object_iterator_thingy2 begin() { + data_container* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy2)); + return internal::object_iterator_thingy2(*container, uint32_t(0)); + } + internal::object_iterator_thingy2 end() { + data_container* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy2)); + return internal::object_iterator_thingy2(*container, container->thingy2_size()); + } + internal::const_object_iterator_thingy2 begin() const { + data_container const* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy2)); + return internal::const_object_iterator_thingy2(*container, uint32_t(0)); + } + internal::const_object_iterator_thingy2 end() const { + data_container const* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_thingy2)); + return internal::const_object_iterator_thingy2(*container, container->thingy2_size()); + } + } in_thingy2 ; template DCON_RELEASE_INLINE void for_each_dummy_rel(T&& func) { @@ -1550,6 +2061,26 @@ namespace os { func(tmp); } } + friend internal::const_object_iterator_dummy_rel; + friend internal::object_iterator_dummy_rel; + struct { + internal::object_iterator_dummy_rel begin() { + data_container* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_dummy_rel)); + return internal::object_iterator_dummy_rel(*container, uint32_t(0)); + } + internal::object_iterator_dummy_rel end() { + data_container* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_dummy_rel)); + return internal::object_iterator_dummy_rel(*container, container->dummy_rel_size()); + } + internal::const_object_iterator_dummy_rel begin() const { + data_container const* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_dummy_rel)); + return internal::const_object_iterator_dummy_rel(*container, uint32_t(0)); + } + internal::const_object_iterator_dummy_rel end() const { + data_container const* container = reinterpret_cast(reinterpret_cast(this) - offsetof(data_container, in_dummy_rel)); + return internal::const_object_iterator_dummy_rel(*container, container->dummy_rel_size()); + } + } in_dummy_rel ; @@ -3164,6 +3695,9 @@ namespace os { DCON_RELEASE_INLINE void thingy_fat_id::remove_all_dummy_rel_as_left() const noexcept { container.thingy_remove_all_dummy_rel_as_left(id); } + DCON_RELEASE_INLINE internal::iterator_thingy_foreach_dummy_rel_as_left_generator thingy_fat_id::get_dummy_rel_as_left() const { + return internal::iterator_thingy_foreach_dummy_rel_as_left_generator(container, id); + } template DCON_RELEASE_INLINE void thingy_fat_id::for_each_dummy_rel(T&& func) const { container.thingy_for_each_dummy_rel(id, [&, t = this](dummy_rel_id i){func(fatten(t->container, i));}); @@ -3174,6 +3708,9 @@ namespace os { DCON_RELEASE_INLINE void thingy_fat_id::remove_all_dummy_rel() const noexcept { container.thingy_remove_all_dummy_rel(id); } + DCON_RELEASE_INLINE internal::iterator_thingy_foreach_dummy_rel_as_left_generator thingy_fat_id::get_dummy_rel() const { + return internal::iterator_thingy_foreach_dummy_rel_as_left_generator(container, id); + } template DCON_RELEASE_INLINE void thingy_fat_id::for_each_right_from_dummy_rel(T&& func) const { container.thingy_for_each_right_from_dummy_rel(id, [&, t = this](thingy2_id i){func(fatten(t->container, i));}); @@ -3222,6 +3759,9 @@ namespace os { DCON_RELEASE_INLINE std::pair thingy_const_fat_id::range_of_dummy_rel_as_left() const { return container.thingy_range_of_dummy_rel_as_left(id); } + DCON_RELEASE_INLINE internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator thingy_const_fat_id::get_dummy_rel_as_left() const { + return internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator(container, id); + } template DCON_RELEASE_INLINE void thingy_const_fat_id::for_each_dummy_rel(T&& func) const { container.thingy_for_each_dummy_rel(id, [&, t = this](dummy_rel_id i){func(fatten(t->container, i));}); @@ -3229,6 +3769,9 @@ namespace os { DCON_RELEASE_INLINE std::pair thingy_const_fat_id::range_of_dummy_rel() const { return container.thingy_range_of_dummy_rel(id); } + DCON_RELEASE_INLINE internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator thingy_const_fat_id::get_dummy_rel() const { + return internal::const_iterator_thingy_foreach_dummy_rel_as_left_generator(container, id); + } template DCON_RELEASE_INLINE void thingy_const_fat_id::for_each_right_from_dummy_rel(T&& func) const { container.thingy_for_each_right_from_dummy_rel(id, [&, t = this](thingy2_id i){func(fatten(t->container, i));}); @@ -3318,6 +3861,100 @@ namespace os { namespace internal { + DCON_RELEASE_INLINE object_iterator_thingy::object_iterator_thingy(data_container& c, uint32_t i) noexcept : container(c), index(i) { + } + DCON_RELEASE_INLINE const_object_iterator_thingy::const_object_iterator_thingy(data_container const& c, uint32_t i) noexcept : container(c), index(i) { + } + DCON_RELEASE_INLINE object_iterator_thingy& object_iterator_thingy::operator++() noexcept { + ++index; + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy& const_object_iterator_thingy::operator++() noexcept { + ++index; + return *this; + } + DCON_RELEASE_INLINE object_iterator_thingy& object_iterator_thingy::operator--() noexcept { + --index; + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy& const_object_iterator_thingy::operator--() noexcept { + --index; + return *this; + } + + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left::iterator_thingy_foreach_dummy_rel_as_left(data_container& c, thingy_id fr) noexcept : container(c) { + ptr = container.dummy_rel.m_array_left.vptr()[fr.index()].data(); + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left::iterator_thingy_foreach_dummy_rel_as_left(data_container& c, thingy_id fr, int) noexcept : container(c) { + auto& vref = container.dummy_rel.m_array_left.vptr()[fr.index()]; + ptr = vref.data() + vref.size(); + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left& iterator_thingy_foreach_dummy_rel_as_left::operator++() noexcept { + ++ptr; + return *this; + } + DCON_RELEASE_INLINE iterator_thingy_foreach_dummy_rel_as_left& iterator_thingy_foreach_dummy_rel_as_left::operator--() noexcept { + --ptr; + return *this; + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left::const_iterator_thingy_foreach_dummy_rel_as_left(data_container const& c, thingy_id fr) noexcept : container(c) { + ptr = container.dummy_rel.m_array_left.vptr()[fr.index()].data(); + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left::const_iterator_thingy_foreach_dummy_rel_as_left(data_container const& c, thingy_id fr, int) noexcept : container(c) { + auto& vref = container.dummy_rel.m_array_left.vptr()[fr.index()]; + ptr = vref.data() + vref.size(); + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left& const_iterator_thingy_foreach_dummy_rel_as_left::operator++() noexcept { + ++ptr; + return *this; + } + DCON_RELEASE_INLINE const_iterator_thingy_foreach_dummy_rel_as_left& const_iterator_thingy_foreach_dummy_rel_as_left::operator--() noexcept { + --ptr; + return *this; + } + + DCON_RELEASE_INLINE object_iterator_thingy2::object_iterator_thingy2(data_container& c, uint32_t i) noexcept : container(c), index(i) { + } + DCON_RELEASE_INLINE const_object_iterator_thingy2::const_object_iterator_thingy2(data_container const& c, uint32_t i) noexcept : container(c), index(i) { + } + DCON_RELEASE_INLINE object_iterator_thingy2& object_iterator_thingy2::operator++() noexcept { + ++index; + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy2& const_object_iterator_thingy2::operator++() noexcept { + ++index; + return *this; + } + DCON_RELEASE_INLINE object_iterator_thingy2& object_iterator_thingy2::operator--() noexcept { + --index; + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_thingy2& const_object_iterator_thingy2::operator--() noexcept { + --index; + return *this; + } + + DCON_RELEASE_INLINE object_iterator_dummy_rel::object_iterator_dummy_rel(data_container& c, uint32_t i) noexcept : container(c), index(i) { + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel::const_object_iterator_dummy_rel(data_container const& c, uint32_t i) noexcept : container(c), index(i) { + } + DCON_RELEASE_INLINE object_iterator_dummy_rel& object_iterator_dummy_rel::operator++() noexcept { + ++index; + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel& const_object_iterator_dummy_rel::operator++() noexcept { + ++index; + return *this; + } + DCON_RELEASE_INLINE object_iterator_dummy_rel& object_iterator_dummy_rel::operator--() noexcept { + --index; + return *this; + } + DCON_RELEASE_INLINE const_object_iterator_dummy_rel& const_object_iterator_dummy_rel::operator--() noexcept { + --index; + return *this; + } + }; diff --git a/CommonIncludes/unordered_dense.h b/CommonIncludes/unordered_dense.h index 07408e9..b7ea91c 100644 --- a/CommonIncludes/unordered_dense.h +++ b/CommonIncludes/unordered_dense.h @@ -1,7 +1,7 @@ ///////////////////////// ankerl::unordered_dense::{map, set} ///////////////////////// // A fast & densely stored hashmap and hashset based on robin-hood backward shift deletion. -// Version 2.0.0 +// Version 3.0.2 // https://github.com/martinus/unordered_dense // // Licensed under the MIT License . @@ -30,9 +30,9 @@ #define ANKERL_UNORDERED_DENSE_H // see https://semver.org/spec/v2.0.0.html -#define ANKERL_UNORDERED_DENSE_VERSION_MAJOR 2 // NOLINT(cppcoreguidelines-macro-usage) incompatible API changes +#define ANKERL_UNORDERED_DENSE_VERSION_MAJOR 3 // NOLINT(cppcoreguidelines-macro-usage) incompatible API changes #define ANKERL_UNORDERED_DENSE_VERSION_MINOR 0 // NOLINT(cppcoreguidelines-macro-usage) backwards compatible functionality -#define ANKERL_UNORDERED_DENSE_VERSION_PATCH 0 // NOLINT(cppcoreguidelines-macro-usage) backwards compatible bug fixes +#define ANKERL_UNORDERED_DENSE_VERSION_PATCH 2 // NOLINT(cppcoreguidelines-macro-usage) backwards compatible bug fixes // API versioning with inline namespace, see https://www.foonathan.net/2018/11/inline-namespaces/ #define ANKERL_UNORDERED_DENSE_VERSION_CONCAT1(major, minor, patch) v##major##_##minor##_##patch @@ -79,7 +79,15 @@ # if __has_include() # undef ANKERL_UNORDERED_DENSE_PMR # define ANKERL_UNORDERED_DENSE_PMR 1 // NOLINT(cppcoreguidelines-macro-usage) -# include // for polymorphic_allocator +# define ANKERL_UNORDERED_DENSE_PMR_ALLOCATOR \ + std::pmr::polymorphic_allocator // NOLINT(cppcoreguidelines-macro-usage) +# include // for polymorphic_allocator +# elif __has_include() +# undef ANKERL_UNORDERED_DENSE_PMR +# define ANKERL_UNORDERED_DENSE_PMR 1 // NOLINT(cppcoreguidelines-macro-usage) +# define ANKERL_UNORDERED_DENSE_PMR_ALLOCATOR \ + std::experimental::pmr::polymorphic_allocator // NOLINT(cppcoreguidelines-macro-usage) +# include // for polymorphic_allocator # endif # endif @@ -364,17 +372,35 @@ namespace ankerl::unordered_dense { template using detect_iterator = typename T::iterator; + template + using detect_reserve = decltype(std::declval().reserve(size_t{})); + // enable_if helpers template constexpr bool is_map_v = !std::is_void_v; + // clang-format off template constexpr bool is_transparent_v = is_detected_v && is_detected_v; + // clang-format on template constexpr bool is_neither_convertible_v = !std::is_convertible_v && !std::is_convertible_v; + template + constexpr bool has_reserve = is_detected_v; + + // base type for map has mapped_type + template + struct base_table_type_map { + using mapped_type = T; + }; + + // base type for set doesn't have mapped_type + struct base_table_type_set { + }; + // This is it, the table. Doubles as map and set, and uses `void` for T when its used as a set. template - class table { + class table : public std::conditional_t, base_table_type_map, base_table_type_set> { public: using value_container_type = std::conditional_t< is_detected_v, AllocatorOrContainer, - typename std::vector, Key, std::pair>, AllocatorOrContainer>>; + typename std::vector, std::pair, Key>, AllocatorOrContainer>>; private: using bucket_alloc = @@ -399,7 +425,6 @@ namespace ankerl::unordered_dense { public: using key_type = Key; - using mapped_type = T; using value_type = typename value_container_type::value_type; using size_type = typename value_container_type::size_type; using difference_type = typename value_container_type::difference_type; @@ -410,8 +435,8 @@ namespace ankerl::unordered_dense { using const_reference = typename value_container_type::const_reference; using pointer = typename value_container_type::pointer; using const_pointer = typename value_container_type::const_pointer; - using iterator = typename value_container_type::iterator; using const_iterator = typename value_container_type::const_iterator; + using iterator = std::conditional_t, typename value_container_type::iterator, const_iterator>; using bucket_type = Bucket; private: @@ -478,10 +503,10 @@ namespace ankerl::unordered_dense { } [[nodiscard]] static constexpr auto get_key(value_type const& vt) -> key_type const& { - if constexpr(std::is_void_v) { - return vt; - } else { + if constexpr(is_map_v) { return vt.first; + } else { + return vt; } } @@ -748,13 +773,16 @@ namespace ankerl::unordered_dense { : table(0) { } - explicit table(size_t /*bucket_count*/, + explicit table(size_t bucket_count, Hash const& hash = Hash(), KeyEqual const& equal = KeyEqual(), allocator_type const& alloc_or_container = allocator_type()) : m_values(alloc_or_container) , m_hash(hash) , m_equal(equal) { + if(0 != bucket_count) { + reserve(bucket_count); + } } table(size_t bucket_count, allocator_type const& alloc) @@ -836,8 +864,10 @@ namespace ankerl::unordered_dense { } ~table() { - auto ba = bucket_alloc(m_values.get_allocator()); - bucket_alloc_traits::deallocate(ba, m_buckets, bucket_count()); + if(nullptr != m_buckets) { + auto ba = bucket_alloc(m_values.get_allocator()); + bucket_alloc_traits::deallocate(ba, m_buckets, bucket_count()); + } } auto operator=(table const& other) -> table& { @@ -1196,6 +1226,7 @@ namespace ankerl::unordered_dense { return begin() + static_cast(value_idx_to_remove); } + template , bool> = true> auto erase(const_iterator it) -> iterator { return erase(begin() + (it - cbegin())); } @@ -1387,7 +1418,10 @@ namespace ankerl::unordered_dense { void reserve(size_t capa) { capa = std::min(capa, max_size()); - m_values.reserve(capa); + if constexpr(has_reserve) { + // std::deque doesn't have reserve(). Make sure we only call when available + m_values.reserve(capa); + } auto shifts = calc_shifts_for_size(std::max(capa, size())); if(0 == m_num_buckets || shifts < m_shifts) { m_shifts = shifts; @@ -1423,14 +1457,14 @@ namespace ankerl::unordered_dense { } for(auto const& b_entry : b) { auto it = a.find(get_key(b_entry)); - if constexpr(std::is_void_v) { - // set: only check that the key is here - if(a.end() == it) { + if constexpr(is_map_v) { + // map: check that key is here, then also check that value is the same + if(a.end() == it || !(b_entry.second == it->second)) { return false; } } else { - // map: check that key is here, then also check that value is the same - if(a.end() == it || !(b_entry.second == it->second)) { + // set: only check that the key is here + if(a.end() == it) { return false; } } @@ -1469,10 +1503,10 @@ namespace ankerl::unordered_dense { class Hash = hash, class KeyEqual = std::equal_to, class Bucket = bucket_type::standard> - using map = detail::table>, Bucket>; + using map = detail::table>, Bucket>; template , class KeyEqual = std::equal_to, class Bucket = bucket_type::standard> - using set = detail::table, Bucket>; + using set = detail::table, Bucket>; } // namespace pmr diff --git a/DataContainerGenerator/object_member_fragments.cpp b/DataContainerGenerator/object_member_fragments.cpp index d7f106f..c40796f 100644 --- a/DataContainerGenerator/object_member_fragments.cpp +++ b/DataContainerGenerator/object_member_fragments.cpp @@ -628,7 +628,7 @@ void make_property_member_declarations(basic_builder& o, file_def const& parsed_ o + "#endif"; } else { o + "DCON_RELEASE_INLINE void @namesp@set_@prop@(@index_type@ i, bool v) const" + block{ - "container.@obj@_set_@prop@(id, i, v);"; + o + "container.@obj@_set_@prop@(id, i, v);"; }; o + "DCON_RELEASE_INLINE void @namesp@resize_@prop@(uint32_t sz) const noexcept" + block{ o + "container.@obj@_resize_@prop@(sz);"; @@ -1930,6 +1930,25 @@ void join_setter_text(basic_builder& o, property_def const& ip, bool add_prefix, }; } break; + case property_type::object: + if(add_prefix) { + if(as_primary_key) { + o + "void @obj@_set_@prop@_from_@rel@(@obj@_id ref_id, @type@ const& val)" + block{ + o + "@rel@_set_@prop@(@rel@_id(@rel@_id::value_base_t(ref_id.index())), val);"; + }; + } else { + o + "void @obj@_set_@prop@_from_@rel@(@obj@_id id, @type@ const& val)" + block{ + o + "if(auto ref_id = @rel@.m_link_back_@as_name@.vptr()[id.index()]; bool(ref_id))" + block{ + o + "@rel@_set_@prop@(ref_id, val);"; + }; + }; + } + } else { + o + "DCON_RELEASE_INLINE void @namesp@set_@prop@_from_@rel@(@type@ const& v) const noexcept" + block{ + o + "container.@obj@_set_@prop@_from_@rel@(id, v);"; + }; + } + break; case property_type::other: break; case property_type::array_bitfield: @@ -1947,7 +1966,7 @@ void join_setter_text(basic_builder& o, property_def const& ip, bool add_prefix, } } else { o + "DCON_RELEASE_INLINE void @namesp@set_@prop@_from_@rel@(@i_type@ i, bool v) const noexcept" + block{ - "container.@obj@_set_@prop@_from_@rel@(id, i, v);"; + o + "container.@obj@_set_@prop@_from_@rel@(id, i, v);"; }; } break; @@ -1968,7 +1987,7 @@ void join_setter_text(basic_builder& o, property_def const& ip, bool add_prefix, } } else { o + "DCON_RELEASE_INLINE void @namesp@set_@prop@_from_@rel@(@i_type@ i, @type@ v) const noexcept" + block{ - "container.@obj@_set_@prop@_from_@rel@(id, i, v);"; + o + "container.@obj@_set_@prop@_from_@rel@(id, i, v);"; }; } break; @@ -2022,6 +2041,41 @@ void join_getter_text(basic_builder& o, property_def const& ip, bool add_prefix, }; } break; + case property_type::object: + if(add_prefix) { + if(ip.protection != protection_type::read_only && !ip.hook_set) { + if(as_primary_key) { + o + "@type@& @obj@_get_@prop@_from_@rel@(@obj@_id ref_id) const" + block{ + o + "return @rel@_get_@prop@(@rel@_id(@rel@_id::value_base_t(ref_id.index())));"; + }; + } else { + o + "@type@& @obj@_get_@prop@_from_@rel@(@obj@_id id) const" + block{ + o + "return @rel@_get_@prop@(@rel@.m_link_back_@as_name@.vptr()[id.index()]);"; + }; + } + } else { + if(as_primary_key) { + o + "@type@ const& @obj@_get_@prop@_from_@rel@(@obj@_id ref_id) const" + block{ + o + "return @rel@_get_@prop@(@rel@_id(@rel@_id::value_base_t(ref_id.index())));"; + }; + } else { + o + "@type@ const& @obj@_get_@prop@_from_@rel@(@obj@_id id) const" + block{ + o + "return @rel@_get_@prop@(@rel@.m_link_back_@as_name@.vptr()[id.index()]);"; + }; + } + } + } else { + if(ip.protection != protection_type::read_only && !ip.hook_set) { + o + "DCON_RELEASE_INLINE @type@& @namesp@get_@prop@_from_@rel@() const noexcept" + block{ + o + "return container.@obj@_get_@prop@_from_@rel@(id);"; + }; + } else { + o + "DCON_RELEASE_INLINE @type@ const& @namesp@get_@prop@_from_@rel@() const noexcept" + block{ + o + "return container.@obj@_get_@prop@_from_@rel@(id);"; + }; + } + } + break; case property_type::vectorizable: if(add_prefix) { if(as_primary_key) { diff --git a/changes.md b/changes.md index 17b447a..89e31ad 100644 --- a/changes.md +++ b/changes.md @@ -1,5 +1,10 @@ ### version 0.2.1 +- updated unordered_dense header +- Fixed a few bugs, thanks to Clang + +### version 0.2.1 + - updated unordered_dense header - added an iterator interface (supporting `for(auto i : ...)` loops) for iterating over all of the object instances in the data container and all of the relationships linked via a `many` link to an object instance.