utility.hpp (4342B)
1 /* 2 Copyright 2017 Adobe 3 Distributed under the Boost Software License, Version 1.0. 4 (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 */ 6 7 /**************************************************************************************************/ 8 9 #ifndef STLAB_UTILITY_HPP 10 #define STLAB_UTILITY_HPP 11 12 /**************************************************************************************************/ 13 14 #include <array> 15 #include <type_traits> 16 17 /**************************************************************************************************/ 18 19 namespace stlab { 20 21 /**************************************************************************************************/ 22 23 inline namespace v1 { 24 /**************************************************************************************************/ 25 26 namespace detail { 27 28 /**************************************************************************************************/ 29 30 template <bool, class T> 31 struct move_if_helper; 32 33 template <class T> 34 struct move_if_helper<true, T> { 35 using type = std::remove_reference_t<T>&&; 36 }; 37 38 template <class T> 39 struct move_if_helper<false, T> { 40 using type = std::remove_reference_t<T>&; 41 }; 42 43 template <bool P, class T> 44 using move_if_helper_t = typename move_if_helper<P, T>::type; 45 46 /**************************************************************************************************/ 47 48 } // namespace detail 49 50 /**************************************************************************************************/ 51 52 template <class Seq1, class Seq2> 53 struct index_sequence_cat; 54 55 template <std::size_t... N1, std::size_t... N2> 56 struct index_sequence_cat<std::index_sequence<N1...>, std::index_sequence<N2...>> { 57 using type = std::index_sequence<N1..., N2...>; 58 }; 59 60 template <class Seq1, class Seq2> 61 using index_sequence_cat_t = typename index_sequence_cat<Seq1, Seq2>::type; 62 63 /**************************************************************************************************/ 64 65 template <class Seq> 66 struct index_sequence_to_array; 67 68 template <std::size_t... N> 69 struct index_sequence_to_array<std::index_sequence<N...>> { 70 static constexpr std::array<std::size_t, sizeof...(N)> value{{N...}}; 71 }; 72 73 /**************************************************************************************************/ 74 75 template <class Seq, template <std::size_t> class F, std::size_t Index, std::size_t Count> 76 struct index_sequence_transform; 77 78 template <class Seq, 79 template <std::size_t> class F, 80 std::size_t Index = 0, 81 std::size_t Count = Seq::size()> 82 using index_sequence_transform_t = typename index_sequence_transform<Seq, F, Index, Count>::type; 83 84 template <class Seq, template <std::size_t> class F, std::size_t Index, std::size_t Count> 85 struct index_sequence_transform { 86 using type = index_sequence_cat_t< 87 index_sequence_transform_t<Seq, F, Index, Count / 2>, 88 index_sequence_transform_t<Seq, F, Index + Count / 2, Count - Count / 2>>; 89 }; 90 91 template <class Seq, template <std::size_t> class F, std::size_t Index> 92 struct index_sequence_transform<Seq, F, Index, 0> { 93 using type = std::index_sequence<>; 94 }; 95 96 template <class Seq, template <std::size_t> class F, std::size_t Index> 97 struct index_sequence_transform<Seq, F, Index, 1> { 98 using type = typename F<index_sequence_to_array<Seq>::value[Index]>::type; 99 }; 100 101 /**************************************************************************************************/ 102 103 template <bool P, class T> 104 constexpr detail::move_if_helper_t<P, T> move_if(T&& t) noexcept { 105 return static_cast<detail::move_if_helper_t<P, T>>(t); 106 } 107 108 /**************************************************************************************************/ 109 110 template <class F, class... Args> 111 void for_each_argument(F&& f, Args&&... args) { 112 return (void)std::initializer_list<int>{(std::forward<F>(f)(args), 0)...}; 113 } 114 115 /**************************************************************************************************/ 116 117 } // namespace v1 118 119 /**************************************************************************************************/ 120 121 } // namespace stlab 122 123 /**************************************************************************************************/ 124 125 #endif 126 127 /**************************************************************************************************/