Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <utility>
- template< typename F, typename ...types >
- struct reverter;
- template< typename F >
- struct reverter< F >
- {
- template< typename ...types >
- static
- constexpr
- decltype(auto)
- apply(F && _f, types &&... _values)
- {
- return std::forward< F >(_f)(std::forward< types >(_values)...);
- }
- };
- template< typename F, typename first, typename ...rest >
- struct reverter< F, first, rest... >
- : reverter< F, rest... >
- {
- template< typename ...types >
- static
- constexpr
- decltype(auto)
- apply(F && _f, first && _first, rest &&... _rest, types &&... _values)
- {
- return reverter< F, rest... >::apply(std::forward< F >(_f), std::forward< rest >(_rest)..., std::forward< first >(_first), std::forward< types >(_values)...);
- }
- };
- template< typename F, typename ...types >
- constexpr
- decltype(auto)
- revert(F && _f, types &&... _values)
- {
- return reverter< F, types... >::apply(std::forward< F >(_f), std::forward< types >(_values)...);
- }
- template< typename value_type, std::size_t ...extents >
- struct multiarray;
- template< typename array_type >
- struct multiarray< array_type >
- {
- using type = array_type;
- };
- template< typename type, std::size_t first, std::size_t ...rest >
- struct multiarray< type, first, rest... >
- : multiarray< type[first], rest... >
- {
- using value_type = type;
- };
- template< typename value_type, std::size_t ...extents >
- using multiarray_t = typename multiarray< value_type, extents... >::type;
- template< typename array_type >
- struct subscripter
- {
- constexpr
- subscripter(array_type & _array)
- : array_(_array)
- { ; }
- constexpr
- array_type &
- operator () () const
- {
- return array_;
- }
- template< typename first, typename ...rest >
- constexpr
- decltype(auto)
- operator () (first && _first, rest &&... _rest) const
- {
- return operator () (std::forward< rest >(_rest)...)[std::forward< first >(_first)];
- }
- private :
- array_type & array_;
- };
- template< typename array_type, typename ...indices >
- constexpr
- decltype(auto)
- subscript(array_type & _array, indices &&... _indices)
- {
- return revert(subscripter< array_type >(_array), std::forward< indices >(_indices)...);
- }
- template< std::size_t ...sizes >
- struct multicheck;
- template<>
- struct multicheck<>
- {
- template< typename F, std::size_t ...indices >
- static
- constexpr
- decltype(auto)
- all_of(F && _f)
- {
- return std::forward< F >(_f)(std::index_sequence< indices... >{});
- }
- template< typename F, std::size_t ...indices >
- static
- constexpr
- decltype(auto)
- any_of(F && _f)
- {
- return std::forward< F >(_f)(std::index_sequence< indices... >{});
- }
- template< typename F, std::size_t ...indices >
- static
- constexpr
- decltype(auto)
- none_of(F && _f)
- {
- return std::forward< F >(_f)(std::index_sequence< indices... >{});
- }
- };
- template< std::size_t first, std::size_t ...rest >
- struct multicheck< first, rest... >
- : multicheck< rest... >
- {
- using base = multicheck< rest... >;
- template< typename F, std::size_t ...indices >
- static
- constexpr
- decltype(auto)
- all_of(F && _f)
- {
- return all_of< F, indices... >(std::forward< F >(_f), std::make_index_sequence< first >{});
- }
- template< typename F, std::size_t ...indices >
- static
- constexpr
- decltype(auto)
- any_of(F && _f)
- {
- return any_of< F, indices... >(std::forward< F >(_f), std::make_index_sequence< first >{});
- }
- template< typename F, std::size_t ...indices >
- static
- constexpr
- decltype(auto)
- none_of(F && _f)
- {
- return none_of< F, indices... >(std::forward< F >(_f), std::make_index_sequence< first >{});
- }
- private :
- template< typename F, std::size_t ...head, std::size_t ...tail >
- static
- constexpr
- decltype(auto)
- all_of(F && _f, std::index_sequence< tail... >)
- {
- return (base::template all_of< F, head..., tail >(std::forward< F >(_f)) && ...);
- }
- template< typename F, std::size_t ...head, std::size_t ...tail >
- static
- constexpr
- decltype(auto)
- any_of(F && _f, std::index_sequence< tail... >)
- {
- return (base::template any_of< F, head..., tail >(std::forward< F >(_f)) || ...);
- }
- template< typename F, std::size_t ...head, std::size_t ...tail >
- static
- constexpr
- decltype(auto)
- none_of(F && _f, std::index_sequence< tail... >)
- {
- return (!base::template none_of< F, head..., tail >(std::forward< F >(_f)) && ...);
- }
- };
- #include <iostream>
- #include <type_traits>
- #include <cassert>
- #include <cstdlib>
- struct print
- {
- template< typename ...types >
- decltype(auto)
- operator () (types &&... _values) const
- {
- return (std::cout << ... << std::forward< types >(_values)) << std::endl;
- }
- };
- template< typename array_type >
- struct print_array
- {
- constexpr
- print_array(array_type & _array)
- : array_(_array)
- { ; }
- template< std::size_t ...indices >
- bool
- operator () (std::index_sequence< indices... >) const
- {
- return operator () (indices...);
- }
- template< typename ...types >
- bool
- operator () (types &&... _values) const
- {
- std::cout << subscript(array_, std::forward< types >(_values)...) << ' ';
- return true;
- }
- private :
- array_type & array_;
- };
- template< typename array_type >
- struct iota_array
- {
- constexpr
- iota_array(array_type & _array)
- : array_(_array)
- { ; }
- template< std::size_t ...indices >
- bool
- operator () (std::index_sequence< indices... >) const
- {
- return operator () (indices...);
- }
- template< typename ...types >
- bool
- operator () (types &&... _values) const
- {
- subscript(array_, std::forward< types >(_values)...) = i;
- ++i;
- return true;
- }
- private :
- mutable std::size_t i = 0;
- array_type & array_;
- };
- template< typename type, std::size_t ...indices >
- struct invert_indices;
- template< std::size_t ...counter, std::size_t ...indices >
- struct invert_indices< std::index_sequence< counter... >, indices... >
- {
- static constexpr std::size_t index[sizeof...(counter)] = {indices...};
- using type = std::index_sequence< index[sizeof...(indices) - 1 - counter]... >;
- };
- template< std::size_t ...indices >
- using make_inverted_indices_t = typename invert_indices< std::make_index_sequence< sizeof...(indices) >, indices... >::type;
- using L = make_inverted_indices_t< 10, 20, 30 >;
- using R = std::index_sequence< 30, 20, 10 >;
- static_assert(std::is_same< L, R >{});
- static_assert(std::is_assignable< L &, R >{});
- static_assert(!std::is_assignable< L &, int >{});
- constexpr
- bool
- test()
- {
- using M = multiarray_t< char, 3, 3, 3 >;
- M m{};
- subscript(m, 2, 1, 0) = 0;
- if (m[2][1][0] != 0) {
- return false;
- }
- m[2][1][0] = 1;
- if (subscript(m, 2, 1, 0) != 1) {
- return false;
- }
- subscript(m, 2, 1)[0] = 2;
- if (m[2][1][0] != 2) {
- return false;
- }
- m[2][1][0] = 3;
- if (subscript(m, 2)[1][0] != 3) {
- return false;
- }
- subscript(m, 2)[1][0] = 4;
- if (m[2][1][0] != 4) {
- return false;
- }
- m[2][1][0] = 5;
- if (subscript(m)[2][1][0] != 5) {
- return false;
- }
- return true;
- }
- static_assert(test());
- int
- main()
- {
- revert(print{}, 1, ' ', 2, ' ', 3);
- using M = multiarray_t< int, 3, 3, 3 >;
- M m;
- static_assert(std::is_same< M, int[3][3][3] >{});
- multicheck< 3, 3, 3 >::all_of(print_array< M >(m));
- std::cout << std::endl;
- multicheck< 3, 3, 3 >::all_of(iota_array< M >(m));
- multicheck< 3, 3, 3 >::all_of(print_array< M >(m));
- std::cout << std::endl;
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment