Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-02 08:28:09

0001 //
0002 // MIT License
0003 // Copyright (c) 2020 Jonathan R. Madsen
0004 // Permission is hereby granted, free of charge, to any person obtaining a copy
0005 // of this software and associated documentation files (the "Software"), to deal
0006 // in the Software without restriction, including without limitation the rights
0007 // to use, copy, modify, merge, publish, distribute, sublicense, and
0008 // copies of the Software, and to permit persons to whom the Software is
0009 // furnished to do so, subject to the following conditions:
0010 // The above copyright notice and this permission notice shall be included in
0011 // all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED
0012 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
0013 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
0014 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
0015 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
0016 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
0017 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0018 //
0019 
0020 #pragma once
0021 
0022 #include "PTL/ConsumeParameters.hh"
0023 
0024 #include <cstddef>
0025 #include <tuple>
0026 #include <type_traits>
0027 #include <utility>
0028 
0029 /// Backports of C++ language features for use with C++11 compilers
0030 
0031 namespace PTL
0032 {
0033 // Convenience wrappers
0034 template <typename T>
0035 using decay_t = typename std::decay<T>::type;
0036 
0037 template <bool B, typename T = void>
0038 using enable_if_t = typename std::enable_if<B, T>::type;
0039 
0040 /// Provision of tuple expansion to arguments
0041 namespace impl
0042 {
0043 //--------------------------------------------------------------------------------------//
0044 // Stores a tuple of indices.  Used by tuple and pair, and by bind() to
0045 // extract the elements in a tuple.
0046 template <size_t... Indexes>
0047 struct Index_tuple
0048 {};
0049 
0050 // Concatenates two Index_tuples.
0051 template <typename Itup1, typename Itup2>
0052 struct Itup_cat;
0053 
0054 template <size_t... Ind1, size_t... Ind2>
0055 struct Itup_cat<Index_tuple<Ind1...>, Index_tuple<Ind2...>>
0056 {
0057     using __type = Index_tuple<Ind1..., (Ind2 + sizeof...(Ind1))...>;
0058 };
0059 
0060 // Builds an Index_tuple<0, 1, 2, ..., NumT-1>.
0061 template <size_t NumT>
0062 struct Build_index_tuple
0063 : Itup_cat<typename Build_index_tuple<NumT / 2>::__type,
0064            typename Build_index_tuple<NumT - NumT / 2>::__type>
0065 {};
0066 
0067 template <>
0068 struct Build_index_tuple<1>
0069 {
0070     using __type = Index_tuple<0>;
0071 };
0072 
0073 template <>
0074 struct Build_index_tuple<0>
0075 {
0076     using __type = Index_tuple<>;
0077 };
0078 
0079 /// Class template integer_sequence
0080 template <typename Tp, Tp... Idx>
0081 struct integer_sequence
0082 {
0083     using value_type = Tp;
0084     static constexpr size_t size() noexcept { return sizeof...(Idx); }
0085 };
0086 
0087 template <typename Tp, Tp NumT, typename ISeq = typename Build_index_tuple<NumT>::__type>
0088 struct Make_integer_sequence;
0089 
0090 template <typename Tp, Tp NumT, size_t... Idx>
0091 struct Make_integer_sequence<Tp, NumT, Index_tuple<Idx...>>
0092 {
0093     static_assert(NumT >= 0, "Cannot make integer sequence of negative length");
0094 
0095     using __type = integer_sequence<Tp, static_cast<Tp>(Idx)...>;
0096 };
0097 
0098 /// Alias template make_integer_sequence
0099 template <typename Tp, Tp NumT>
0100 using make_integer_sequence = typename Make_integer_sequence<Tp, NumT>::__type;
0101 
0102 /// Alias template index_sequence
0103 template <size_t... Idx>
0104 using index_sequence = integer_sequence<size_t, Idx...>;
0105 
0106 /// Alias template make_index_sequence
0107 template <size_t NumT>
0108 using make_index_sequence = make_integer_sequence<size_t, NumT>;
0109 
0110 template <typename FnT, typename TupleT, size_t... Idx>
0111 static inline auto
0112 apply(FnT&& _func, TupleT _args, impl::index_sequence<Idx...>)
0113     -> decltype(std::forward<FnT>(_func)(std::get<Idx>(std::move(_args))...))
0114 {
0115     // GCC 5.3 warns about unused variable _args when the index sequence is empty
0116 #if defined(__GNUC__) && (__GNUC__ < 6)
0117     if(sizeof...(Idx) == 0)
0118     {
0119         ConsumeParameters(_args);
0120     }
0121 #endif
0122     return std::forward<FnT>(_func)(std::get<Idx>(std::move(_args))...);
0123 }
0124 
0125 //--------------------------------------------------------------------------------------//
0126 
0127 }  // namespace impl
0128 
0129 //--------------------------------------------------------------------------------------//
0130 
0131 template <typename FnT, typename TupleT>
0132 static inline void
0133 apply(FnT&& _func, TupleT&& _args)
0134 {
0135     using tuple_type = decay_t<TupleT>;
0136     constexpr auto N = std::tuple_size<tuple_type>::value;
0137     impl::apply(std::forward<FnT>(_func), std::forward<TupleT>(_args),
0138                 impl::make_index_sequence<N>{});
0139 }
0140 
0141 }  // namespace PTL