diff --git a/include/cista/containers/nvec.h b/include/cista/containers/nvec.h index 7a8ff266..9db6adb4 100644 --- a/include/cista/containers/nvec.h +++ b/include/cista/containers/nvec.h @@ -152,7 +152,7 @@ struct basic_nvec { using reference = std::add_lvalue_reference; const_bucket(basic_nvec const* map, index_value_type const i) - : map_{map}, i_{to_idx(i)} {} + : i_{to_idx(i)}, map_{map} {} template , typename = std::enable_if_t>> @@ -236,13 +236,13 @@ struct basic_nvec { private: std::size_t bucket_begin_idx() const { return to_idx(map_->index_[0][i_]); } std::size_t bucket_end_idx() const { - return to_idx(map_->index_[0][i_ + 1]); + return to_idx(map_->index_[0][i_ + 1U]); } bool is_inside_bucket(std::size_t const i) const { return bucket_begin_idx() + i < bucket_end_idx(); } - std::size_t i_; + size_type i_; basic_nvec const* map_; }; @@ -254,6 +254,11 @@ struct basic_nvec { template void emplace_back(Container&& bucket) { + if (index_[0].size() == 0U) { + for (auto& i : index_) { + i.push_back(0U); + } + } add(bucket); } @@ -275,7 +280,7 @@ struct basic_nvec { constexpr auto const I = sizeof...(Indices); static_assert(I == N - 1); verify(to_idx(first) < index_[I].size(), "nvec::at: index out of range"); - return get_bucket(index_[I][first], rest...); + return get_bucket(index_[I][first], rest...); } template @@ -283,23 +288,33 @@ struct basic_nvec { constexpr auto const I = sizeof...(Indices); static_assert(I == N - 1); verify(to_idx(first) < index_[I].size(), "nvec::at: index out of range"); - return get_bucket(index_[I][first], rest...); + return get_bucket(index_[I][first], rest...); } auto cista_members() noexcept { return std::tie(index_, data_); } -protected: - template - BucketType get_bucket(index_value_type const bucket_start, - index_value_type const i, Rest... rest) { - return get_bucket( - index_[sizeof...(Rest)][bucket_start + i], rest...); + template + bucket get_bucket(index_value_type const bucket_start, + index_value_type const i, Rest... rest) { + return get_bucket(index_[sizeof...(Rest)][bucket_start + i], + rest...); + } + + bucket get_bucket(index_value_type const bucket_start, + index_value_type const i) { + return bucket{this, bucket_start + i}; + } + + template + const_bucket get_bucket(index_value_type const bucket_start, + index_value_type const i, Rest... rest) const { + return get_bucket(index_[sizeof...(Rest)][bucket_start + i], + rest...); } - template - BucketType get_bucket(index_value_type const bucket_start, - index_value_type const i) { - return BucketType{this, bucket_start + i}; + const_bucket get_bucket(index_value_type const bucket_start, + index_value_type const i) const { + return const_bucket{this, bucket_start + i}; } template diff --git a/include/cista/reflection/to_tuple.h b/include/cista/reflection/to_tuple.h index 1ac88255..78f7ed3e 100644 --- a/include/cista/reflection/to_tuple.h +++ b/include/cista/reflection/to_tuple.h @@ -50,11 +50,12 @@ auto to_ptrs(T&& t) { template inline constexpr auto to_tuple_works_v = - detail::has_cista_members_v || (std::is_aggregate_v && + detail::has_cista_members_v || + (std::is_aggregate_v && #if !defined(_MSC_VER) || defined(NDEBUG) - std::is_standard_layout_v && + std::is_standard_layout_v && #endif - !std::is_polymorphic_v); + !std::is_polymorphic_v && !std::is_union_v); template && std::is_const_v, diff --git a/include/cista/serialization.h b/include/cista/serialization.h index ad99e641..290b5c51 100755 --- a/include/cista/serialization.h +++ b/include/cista/serialization.h @@ -683,7 +683,7 @@ void recurse(Ctx& c, T* el, Fn&& fn) { using Type = decay_t; if constexpr (is_indexed_v) { fn(static_cast(el)); - } else if constexpr (std::is_aggregate_v && !std::is_union_v) { + } else if constexpr (to_tuple_works_v) { for_each_ptr_field(*el, [&](auto& f) { fn(f); }); } else if constexpr (is_mode_enabled(Ctx::MODE, mode::_PHASE_II) && std::is_pointer_v) { diff --git a/test/nvec_test.cc b/test/nvec_test.cc index 77e95abb..e89718cd 100644 --- a/test/nvec_test.cc +++ b/test/nvec_test.cc @@ -7,24 +7,38 @@ #include "cista.h" #else #include "cista/containers/nvec.h" +#include "cista/serialization.h" +#include "cista/targets/buf.h" #endif TEST_CASE("nvec test") { + constexpr auto const kMode = + cista::mode::WITH_INTEGRITY | cista::mode::WITH_VERSION; + struct transfer { bool operator==(transfer const& o) const { return o.i_ == i_; } int i_; }; - cista::raw::nvec v; - v.emplace_back(std::vector>{ - {transfer{1}, transfer{2}}, {transfer{3}, transfer{4}, transfer{5}}}); - v.emplace_back(std::vector>{ - {transfer{6}, transfer{7}}, - {transfer{8}, transfer{9}, transfer{10}}, - {transfer{11}}}); - v.emplace_back(std::vector>{ - {transfer{12}, transfer{13}}, - {transfer{14}, transfer{15}, transfer{16}}, - {transfer{17}}}); + + cista::byte_buf buf; + { + cista::offset::nvec v; + v.emplace_back(std::vector>{ + {transfer{1}, transfer{2}}, {transfer{3}, transfer{4}, transfer{5}}}); + v.emplace_back(std::vector>{ + {transfer{6}, transfer{7}}, + {transfer{8}, transfer{9}, transfer{10}}, + {transfer{11}}}); + v.emplace_back(std::vector>{ + {transfer{12}, transfer{13}}, + {transfer{14}, transfer{15}, transfer{16}}, + {transfer{17}}}); + buf = cista::serialize(v); + } + + auto const& v = + *cista::deserialize, kMode>( + buf); auto const all = std::vector{ transfer{1}, transfer{2}, transfer{3}, transfer{4}, transfer{5}, diff --git a/test/union_derive_test.cc b/test/union_derive_test.cc index 450403d8..8c669cac 100644 --- a/test/union_derive_test.cc +++ b/test/union_derive_test.cc @@ -15,6 +15,7 @@ TEST_CASE("union_test") { int32_t a_; float b_; }; + static_assert(!cista::to_tuple_works_v); cista::byte_buf buf;