44#define INCLUDE_UTIL_MULTIVECTOR_HPP_
55#include < cstddef>
66#include < tuple>
7- #include < type_traits>
87#include < utility>
98#include < vector>
109
1110namespace util {
11+ #if __cplusplus >= 202002L
12+ template <class OutT , class ... DataT>
13+ concept OutT_check = requires (DataT... args) { OutT{args...}; };
14+ #else
15+ template <class OutT , class ... args>
16+ class OutT_check_class {
17+ template <class OutT_ , class ... args_, typename = decltype (OutT_{std::declval<args_>()...})>
18+ static std::true_type chk ();
1219
20+ template <typename , typename ...>
21+ static std::false_type chk ();
22+
23+ public:
24+ static constexpr bool value = decltype (chk<OutT, args...>())::value;
25+ };
26+ template <class OutT , class ... args>
27+ constexpr bool OutT_check = OutT_check_class<OutT, args...>::value;
28+
29+ #endif
1330template <class ... T>
14- class MlutiVector {
31+ class MultiVector {
1532 std::tuple<std::vector<T>...> data;
33+ size_t count = 0 ;
1634
17- constexpr static size_t Data_Colum_count = std::tuple_size< decltype (data)>::value ;
35+ constexpr static size_t Data_Colum_count = sizeof ...(T) ;
1836
1937public:
38+ size_t getRowCount () const noexcept {
39+ return count;
40+ }
41+
2042 void push (const T&... args) {
43+ count++;
2144 push_helper<0 >(args...);
2245 }
2346
47+ void push (const std::tuple<T...>& arg) {
48+ count++;
49+ push_helper (arg, std::make_index_sequence<Data_Colum_count>());
50+ }
51+
2452 template <size_t Index>
25- const auto & getColumn () {
53+ const auto & getColumn () const {
2654 return std::get<Index>(data);
2755 }
2856
29- void erase (size_t index) {
30- erase_helper (index, std::make_index_sequence<Data_Colum_count>());
57+ std::tuple<T...> getRow (size_t index) const {
58+ return get_As_helper<std::tuple<T...>> (index, std::make_index_sequence<Data_Colum_count>());
3159 }
3260
3361 template <class Out_t >
3462 Out_t get_As (size_t index) {
35- static_assert (std::is_aggregate_v<Out_t>, " get_As need construct by {T...}" );
36- return get_As_helper<Out_t>(index, std::make_index_sequence<Data_Colum_count>());
63+ constexpr auto is_valid = OutT_check<Out_t, T&...>;
64+ static_assert (is_valid, " get_As parameter type must need construct by {T&...}" );
65+ if constexpr (is_valid) {
66+ return get_As_helper<Out_t>(index, std::make_index_sequence<Data_Colum_count>());
67+ }
3768 }
3869
3970 template <class Out_t >
4071 const Out_t get_As (size_t index) const {
41- static_assert (std::is_aggregate_v<Out_t>, " get_As need construct by {T...}" );
42- return get_As_helper<Out_t>(index, std::make_index_sequence<Data_Colum_count>());
72+ constexpr auto is_valid = OutT_check<Out_t, const T&...>;
73+ static_assert (is_valid, " get_As parameter type must need construct by {const T&...}." );
74+ if constexpr (is_valid) {
75+ return get_As_helper<Out_t>(index, std::make_index_sequence<Data_Colum_count>());
76+ }
4377 }
4478
4579private:
@@ -48,14 +82,9 @@ class MlutiVector {
4882 return {std::get<Seq>(data)[index]...};
4983 }
5084
51- template <class VectorT >
52- static void eraseVector (std::vector<VectorT>& vec, size_t index) {
53- vec.erase (vec.begin () + index);
54- }
55-
56- template <class IndexT , IndexT... Seq>
57- void erase_helper (size_t index, std::integer_sequence<IndexT, Seq...>) {
58- (..., eraseVector (std::get<Seq>(data), index));
85+ template <class Out_t , class IndexT , IndexT... Seq>
86+ Out_t get_As_helper (size_t index, std::integer_sequence<IndexT, Seq...>) const {
87+ return {std::get<Seq>(data)[index]...};
5988 }
6089
6190 template <size_t index, class Front >
@@ -68,6 +97,11 @@ class MlutiVector {
6897 std::get<index>(data).push_back (front);
6998 push_helper<index + 1 >(tail...);
7099 }
100+
101+ template <class IndexT , IndexT... Seq>
102+ void push_helper (std::tuple<T...> arg, std::integer_sequence<IndexT, Seq...>) {
103+ (..., std::get<Seq>(data).push_back (std::get<Seq>(arg)));
104+ }
71105};
72106}
73107
0 commit comments