28 #ifndef __RTTR_ARRAY_ACCESSOR_H__
29 #define __RTTR_ARRAY_ACCESSOR_H__
36 #include <type_traits>
46 template<
typename ArrayType,
typename B>
47 struct get_size_from_array_impl;
49 template<
typename ArrayType>
50 struct get_size_from_array_impl<ArrayType, std::true_type>
52 template<
typename... Indices>
53 static std::size_t get_size(
const ArrayType& array, std::size_t index, Indices... args)
55 using sub_type =
typename array_mapper<ArrayType>::sub_type;
56 using go_one_dim_deeper =
typename std::integral_constant<bool, (
sizeof...(Indices) > 0)>::type;
57 return get_size_from_array_impl<sub_type, go_one_dim_deeper>::get_size(array_mapper<ArrayType>::get_value(array, index), args...);
61 template<
typename ArrayType>
62 struct get_size_from_array_impl<ArrayType, std::false_type>
64 static std::size_t get_size(
const ArrayType& array)
66 return array_mapper<ArrayType>::get_size(array);
71 template<
typename ArrayType,
typename... Indices>
72 std::size_t get_size_from_array(
const ArrayType& array, Indices... args)
74 using go_one_dim_deeper =
typename std::integral_constant<bool, (
sizeof...(Indices) > 0) >::type;
75 return get_size_from_array_impl<ArrayType, go_one_dim_deeper>::get_size(array, args...);
80 template<
typename ArrayType,
typename B>
81 struct set_size_to_array_impl;
83 template<
typename ArrayType>
84 struct set_size_to_array_impl<ArrayType, std::true_type>
86 template<
typename... Indices>
87 static bool set_size(ArrayType& array, std::size_t new_size, std::size_t index, Indices... args)
89 using sub_type =
typename array_mapper<ArrayType>::sub_type;
90 using go_one_dim_deeper =
typename std::integral_constant<bool, (
sizeof...(Indices) > 0)>::type;
91 return set_size_to_array_impl<sub_type, go_one_dim_deeper>::set_size(array_mapper<ArrayType>::get_value(array, index), new_size, args...);
95 template<
typename ArrayType>
96 struct set_size_to_array_impl<ArrayType, std::false_type>
98 static bool set_size(ArrayType& array, std::size_t new_size)
100 return array_mapper<ArrayType>::set_size(array, new_size);
105 template<
typename ArrayType,
typename... Indices>
106 bool set_size_to_array(ArrayType& array, std::size_t new_size, Indices... args)
108 using go_one_dim_deeper =
typename std::integral_constant<bool, (
sizeof...(Indices) > 0) >::type;
109 return set_size_to_array_impl<ArrayType, go_one_dim_deeper>::set_size(array, new_size, args...);
114 template<
typename Return_Type,
typename ArrayType,
typename B>
115 struct get_value_from_array_impl;
117 template<
typename Return_Type,
typename ArrayType>
118 struct get_value_from_array_impl<Return_Type, ArrayType, std::true_type>
120 template<
typename... Indices>
121 static const Return_Type& get_value(
const ArrayType& array, std::size_t index, Indices... args)
123 using sub_type =
typename array_mapper<ArrayType>::sub_type;
124 using arg_count_valid =
typename std::integral_constant<bool,
sizeof...(Indices) != 0>::type;
125 return get_value_from_array_impl<Return_Type, sub_type, arg_count_valid>::get_value(array_mapper<ArrayType>::get_value(array, index), args...);
129 template<
typename Return_Type,
typename T>
130 struct get_value_from_array_impl<Return_Type, T, std::false_type>
132 template<
typename... Indices>
133 static const Return_Type& get_value(
const T& value, Indices... args)
139 template<
typename ArrayType,
typename... Indices>
140 variant get_value_from_array(
const ArrayType& array, std::size_t index, Indices... args)
142 static_assert(rank<ArrayType>::value >=
sizeof...(Indices) + 1,
"Invalid return type! The number of specified indices are out of range.");
143 using return_type =
typename rank_type<ArrayType,
sizeof...(Indices) + 1>::type;
144 using sub_type =
typename array_mapper<ArrayType>::sub_type;
145 using go_one_dim_deeper =
typename std::integral_constant<bool,
sizeof...(Indices) != 0>::type;
146 return get_value_from_array_impl<return_type, sub_type, go_one_dim_deeper>::get_value(array_mapper<ArrayType>::get_value(array, index), args...);
151 template<
typename ArrayType,
typename B>
152 struct set_value_to_array_impl;
154 template<
typename ArrayType>
155 struct set_value_to_array_impl<ArrayType, std::true_type>
157 template<
typename T1,
typename... Indices>
158 static void set_value(ArrayType& array,
const T1& value, std::size_t index, Indices... args)
160 using sub_type =
typename array_mapper<ArrayType>::sub_type;
161 using arg_count_valid =
typename std::integral_constant<bool,
sizeof...(Indices) != 0>::type;
162 set_value_to_array_impl<sub_type, arg_count_valid>::set_value(array_mapper<ArrayType>::get_value(array, index), value, args...);
167 struct set_value_to_array_impl<T, std::false_type>
169 static void set_value(T& array,
const T& value)
175 template<
typename T,
size_t N>
176 struct set_value_to_array_impl<T[N], std::false_type>
178 static void set_value(T (& arr)[N],
const T (& value)[N])
180 #if RTTR_COMPILER == RTTR_COMPILER_MSVC
183 copy_array(
const_cast< T (&)[N]
>(value), arr);
185 copy_array(value, arr);
190 template<
typename ArrayType,
typename F,
typename... Indices>
191 bool set_value_to_array(ArrayType& array,
const F& value, std::size_t index, Indices... args)
194 static_assert(std::is_same<
typename rank_type<ArrayType,
sizeof...(Indices) + 1>::type, F>::value,
"invalid type!");
195 using sub_type =
typename array_mapper<ArrayType>::sub_type;
196 using go_one_dim_deeper =
typename std::integral_constant<bool,
sizeof...(Indices) != 0>::type;
197 set_value_to_array_impl<sub_type, go_one_dim_deeper>::set_value(array_mapper<ArrayType>::get_value(array, index), value, args...);
202 bool set_value_to_array(T& arg,
const T& value)
204 set_value_to_array_impl<T, std::false_type>::set_value(arg, value);
211 template<
typename ArrayType,
typename B>
212 struct insert_value_to_array_impl;
214 template<
typename ArrayType>
215 struct insert_value_to_array_impl<ArrayType, std::true_type>
217 template<
typename T,
typename... Indices>
218 static bool insert_value(ArrayType& array,
const T& value, std::size_t index, Indices... args)
220 using sub_type =
typename array_mapper<ArrayType>::sub_type;
221 using arg_count_valid =
typename std::integral_constant<bool, (
sizeof...(Indices) > 1)>::type;
222 return insert_value_to_array_impl<sub_type, arg_count_valid>::insert_value(array_mapper<ArrayType>::get_value(array, index), value, args...);
226 template<
typename ArrayType>
227 struct insert_value_to_array_impl<ArrayType, std::false_type>
230 static bool insert_value(ArrayType& array,
const T& value, std::size_t index)
232 return array_mapper<ArrayType>::insert_value(array, value, index);
237 template<
typename ArrayType,
typename F,
typename... Indices>
238 bool insert_value_to_array(ArrayType& array,
const F& value, Indices... args)
240 using go_one_dim_deeper =
typename std::integral_constant<bool, (
sizeof...(Indices) > 1) >::type;
241 return insert_value_to_array_impl<ArrayType, go_one_dim_deeper>::insert_value(array, value, args...);
247 template<
typename ArrayType,
typename B>
248 struct remove_value_from_array_impl;
250 template<
typename ArrayType>
251 struct remove_value_from_array_impl<ArrayType, std::true_type>
253 template<
typename... Indices>
254 static bool remove_value(ArrayType& array, std::size_t index, Indices... args)
256 using sub_type =
typename array_mapper<ArrayType>::sub_type;
257 using arg_count_valid =
typename std::integral_constant<bool, (
sizeof...(Indices) > 1) >::type;
258 return remove_value_from_array_impl<sub_type, arg_count_valid>::remove_value(array_mapper<ArrayType>::get_value(array, index), args...);
262 template<
typename ArrayType>
263 struct remove_value_from_array_impl<ArrayType, std::false_type>
265 static bool remove_value(ArrayType& array, std::size_t index)
267 return array_mapper<ArrayType>::remove_value(array, index);
272 template<
typename ArrayType,
typename... Indices>
273 bool remove_value_from_array(ArrayType& array, Indices... args)
275 using go_one_dim_deeper =
typename std::integral_constant<bool, (
sizeof...(Indices) > 1) >::type;
276 return remove_value_from_array_impl<ArrayType, go_one_dim_deeper>::remove_value(array, args...);
281 template<
typename ArrayType,
typename A>
282 struct array_accessor_impl;
284 template<
typename ArrayType>
285 struct array_accessor_impl<ArrayType, std::true_type>
289 template<
typename... Indices>
290 static std::size_t get_size(
const ArrayType& obj, Indices... args)
292 return get_size_from_array<ArrayType>(obj, args...);
297 template<
typename... Indices>
298 static bool set_size(ArrayType& obj, std::size_t new_size, Indices... args)
300 return set_size_to_array<ArrayType>(obj, new_size, args...);
305 template<
typename... Indices>
306 static variant get_value(
const ArrayType& obj, Indices... indices)
308 return get_value_from_array<ArrayType>(obj, indices...);
313 template<
typename... Indices>
314 static bool set_value(ArrayType& obj, argument& arg, Indices... indices)
316 using arg_type =
typename rank_type<ArrayType,
sizeof...(Indices)>::type;
317 if (arg.is_type<arg_type>())
318 return set_value_to_array<ArrayType>(obj, arg.get_value<arg_type>(), indices...);
325 template<
typename... Indices>
326 static bool insert_value(ArrayType& obj, argument& arg, Indices... indices)
328 using arg_type =
typename rank_type<ArrayType,
sizeof...(Indices)>::type;
329 if (arg.is_type<arg_type>())
330 return insert_value_to_array<ArrayType>(obj, arg.get_value<arg_type>(), indices...);
337 template<
typename... Indices>
338 static bool remove_value(ArrayType& obj, Indices... indices)
340 return remove_value_from_array<ArrayType>(obj, indices...);
347 template<
typename ArrayType>
348 struct array_accessor_impl<ArrayType, std::false_type>
352 template<
typename... Indices>
353 static std::size_t get_size(
const ArrayType& obj, Indices... args)
358 template<
typename... Indices>
359 static bool set_size(ArrayType& obj, std::size_t new_size, Indices... args)
366 template<
typename... Indices>
367 static variant get_value(
const ArrayType& obj, Indices... indices)
374 template<
typename... Indices>
375 static bool set_value(ArrayType& obj, argument& arg, Indices... indices)
382 template<
typename... Indices>
383 static bool insert_value(ArrayType& obj, argument& arg, Indices... indices)
390 template<
typename... Indices>
391 static bool remove_value(ArrayType& obj, Indices... indices)
400 template<
typename T,
typename IndexCount>
401 struct array_accessor_variadic;
403 template<
typename ArrayType, std::size_t... N>
404 struct array_accessor_variadic<ArrayType, index_sequence<N...>>
408 static std::size_t get_size(
const ArrayType& obj,
const std::vector<std::size_t>& index_list)
410 using is_rank_in_range =
typename std::integral_constant< bool, (
sizeof...(N) < rank<ArrayType>::value) >::type;
411 return array_accessor_impl<ArrayType, is_rank_in_range>::get_size(obj, index_list[N]...);
416 static bool set_size(ArrayType& obj, std::size_t new_size,
const std::vector<std::size_t>& index_list)
418 using is_rank_in_range =
typename std::integral_constant< bool, (
sizeof...(N) < rank<ArrayType>::value) >::type;
419 return array_accessor_impl<ArrayType, is_rank_in_range>::set_size(obj, new_size, index_list[N]...);
424 static variant get_value(
const ArrayType& obj,
const std::vector<std::size_t>& index_list)
426 using is_rank_in_range =
typename std::integral_constant<bool, (
sizeof...(N) <= rank<ArrayType>::value) >::type;
427 return array_accessor_impl<ArrayType, is_rank_in_range>::get_value(obj, index_list[N]...);
432 static bool set_value(ArrayType& obj, argument& arg,
const std::vector<std::size_t>& index_list)
434 using is_rank_in_range =
typename std::integral_constant<bool, (
sizeof...(N) <= rank<ArrayType>::value) >::type;
435 return array_accessor_impl<ArrayType, is_rank_in_range>::set_value(obj, arg, index_list[N]...);
440 static bool insert_value(ArrayType& obj, argument& arg,
const std::vector<std::size_t>& index_list)
442 using is_rank_in_range =
typename std::integral_constant<bool, (
sizeof...(N) < rank<ArrayType>::value) >::type;
443 return array_accessor_impl<ArrayType, is_rank_in_range>::insert_value(obj, arg, index_list[N]...);
448 static bool remove_value(ArrayType& obj,
const std::vector<std::size_t>& index_list)
450 using is_rank_in_range =
typename std::integral_constant<bool, (
sizeof...(N) < rank<ArrayType>::value) >::type;
451 return array_accessor_impl<ArrayType, is_rank_in_range>::remove_value(obj, index_list[N]...);
457 template<
typename ArrayType, std::
size_t N>
458 struct array_accessor_impl<ArrayType, std::integral_constant<std::size_t, N>>
462 static std::size_t get_size(
const ArrayType& obj,
const std::vector<std::size_t>& index_list)
464 if (index_list.size() == N)
465 return array_accessor_variadic<ArrayType, make_index_sequence<N>>::get_size(obj, index_list);
467 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, N - 1>>::get_size(obj, index_list);
472 static bool set_size(ArrayType& obj, std::size_t new_size,
const std::vector<std::size_t>& index_list)
474 if (index_list.size() == N)
475 return array_accessor_variadic<ArrayType, make_index_sequence<N>>::set_size(obj, new_size, index_list);
477 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, N - 1>>::set_size(obj, new_size, index_list);
482 static variant get_value(
const ArrayType& obj,
const std::vector<std::size_t>& index_list)
484 if (index_list.size() == N)
485 return array_accessor_variadic<ArrayType, make_index_sequence<N>>::get_value(obj, index_list);
487 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, N - 1>>::get_value(obj, index_list);
492 static bool set_value(ArrayType& obj, argument& arg,
const std::vector<std::size_t>& index_list)
494 if (index_list.size() == N)
495 return array_accessor_variadic<ArrayType, make_index_sequence<N>>::set_value(obj, arg, index_list);
497 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, N - 1>>::set_value(obj, arg, index_list);
502 static bool insert_value(ArrayType& obj, argument& arg,
const std::vector<std::size_t>& index_list)
504 if (index_list.size() == N)
505 return array_accessor_variadic<ArrayType, make_index_sequence<N>>::insert_value(obj, arg, index_list);
507 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, N - 1>>::insert_value(obj, arg, index_list);
512 static bool remove_value(ArrayType& obj,
const std::vector<std::size_t>& index_list)
514 if (index_list.size() == N)
515 return array_accessor_variadic<ArrayType, make_index_sequence<N>>::remove_value(obj, index_list);
517 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, N - 1>>::remove_value(obj, index_list);
522 static type get_ranke_type(std::size_t index)
525 return type::get<typename rank_type<ArrayType, N>::type>();
527 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, N - 1>>::get_ranke_type(index);
531 template<
typename ArrayType>
532 struct array_accessor_impl<ArrayType, std::integral_constant<std::size_t, 0>>
536 static std::size_t get_size(
const ArrayType& obj,
const std::vector<std::size_t>& index_list)
538 return array_accessor_impl<ArrayType, std::true_type>::get_size(obj);
543 static bool set_size(ArrayType& obj, std::size_t new_size,
const std::vector<std::size_t>& index_list)
545 return array_accessor_impl<ArrayType, std::true_type>::set_size(obj, new_size);
550 static variant get_value(
const ArrayType& obj,
const std::vector<std::size_t>& index_list)
557 static bool set_value(ArrayType& obj, argument& arg,
const std::vector<std::size_t>& index_list)
560 return array_accessor_impl<ArrayType, std::true_type>::set_value(obj, arg);
565 static bool insert_value(ArrayType& obj, argument& arg,
const std::vector<std::size_t>& index_list)
572 static bool remove_value(ArrayType& obj,
const std::vector<std::size_t>& index_list)
579 static type get_ranke_type(std::size_t index)
581 return type::get<typename rank_type<ArrayType, 0>::type>();
587 template<
typename ArrayType>
588 struct array_accessor
592 template<
typename... Indices>
593 static std::size_t get_size(
const ArrayType& array, Indices... args)
595 using is_rank_in_range =
typename std::integral_constant< bool, (
sizeof...(Indices) < rank<ArrayType>::value) >::type;
596 return array_accessor_impl<ArrayType, is_rank_in_range>::get_size(array, args...);
599 static std::size_t get_size(
const ArrayType& array,
const std::vector<std::size_t>& index_list)
601 if (index_list.size() < rank<ArrayType>::value)
602 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, rank<ArrayType>::value - 1>>::get_size(array, index_list);
609 template<
typename... Indices>
610 static bool set_size(ArrayType& array, std::size_t new_size, Indices... args)
612 using is_rank_in_range =
typename std::integral_constant< bool, (
sizeof...(Indices) < rank<ArrayType>::value) >::type;
613 return array_accessor_impl<ArrayType, is_rank_in_range>::set_size(array, new_size, args...);
616 static bool set_size(ArrayType& array, std::size_t new_size,
const std::vector<std::size_t>& index_list)
618 if (index_list.size() < rank<ArrayType>::value)
619 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, rank<ArrayType>::value - 1>>::set_size(array, new_size, index_list);
626 template<
typename... Indices>
627 static variant get_value(
const ArrayType& array, Indices... indices)
629 using is_rank_in_range =
typename std::integral_constant<bool, (
sizeof...(Indices) <= rank<ArrayType>::value) >::type;
630 return array_accessor_impl<ArrayType, is_rank_in_range>::get_value(array, indices...);
633 static variant get_value(
const ArrayType& array,
const std::vector<std::size_t>& index_list)
635 if (index_list.size() <= rank<ArrayType>::value)
636 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, rank<ArrayType>::value>>::get_value(array, index_list);
643 template<
typename... Indices>
644 static bool set_value(ArrayType& array, argument& arg, Indices... indices)
646 using is_rank_in_range =
typename std::integral_constant<bool, (
sizeof...(Indices) <= rank<ArrayType>::value) >::type;
647 return array_accessor_impl<ArrayType, is_rank_in_range>::set_value(array, arg, indices...);
650 static bool set_value(ArrayType& array, argument& arg,
const std::vector<std::size_t>& index_list)
652 if (index_list.size() <= rank<ArrayType>::value)
653 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, rank<ArrayType>::value>>::set_value(array, arg, index_list);
660 template<
typename... Indices>
661 static bool insert_value(ArrayType& array, argument& arg, Indices... indices)
663 using is_rank_in_range =
typename std::integral_constant<bool, (
sizeof...(Indices) <= rank<ArrayType>::value) >::type;
664 return array_accessor_impl<ArrayType, is_rank_in_range>::insert_value(array, arg, indices...);
667 static bool insert_value(ArrayType& array, argument& arg,
const std::vector<std::size_t>& index_list)
669 if (index_list.size() < rank<ArrayType>::value)
670 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, rank<ArrayType>::value - 1>>::insert_value(array, arg, index_list);
677 template<
typename... Indices>
678 static bool remove_value(ArrayType& array, Indices... indices)
680 using is_rank_in_range =
typename std::integral_constant<bool, (
sizeof...(Indices) <= rank<ArrayType>::value) >::type;
681 return array_accessor_impl<ArrayType, is_rank_in_range>::remove_value(array, indices...);
684 static bool remove_value(ArrayType& array,
const std::vector<std::size_t>& index_list)
686 if (index_list.size() < rank<ArrayType>::value)
687 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, rank<ArrayType>::value - 1>>::remove_value(array, index_list);
694 static type get_ranke_type(std::size_t index)
696 if (index <= rank<ArrayType>::value)
697 return array_accessor_impl<ArrayType, std::integral_constant<std::size_t, rank<ArrayType>::value>>::get_ranke_type(index);
699 return ::rttr::impl::get_invalid_type();
708 #endif // __RTTR_ARRAY_ACCESSOR_H__