Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:46

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 <algorithm>  // Retrieve definitions of min/max
0023 
0024 // Include base types
0025 #include "PTL/Types.hh"
0026 
0027 // Global utility functions
0028 #include "PTL/Utility.hh"
0029 
0030 #include <initializer_list>
0031 #include <tuple>
0032 #include <type_traits>
0033 #include <utility>
0034 
0035 #if !defined(PTL_NO_SANITIZE_THREAD)
0036 // expect that sanitizer is from compiler which supports __has_attribute
0037 #    if defined(__has_attribute)
0038 #        if __has_attribute(no_sanitize)
0039 #            define PTL_NO_SANITIZE_THREAD __attribute__((no_sanitize("thread")))
0040 #        else
0041 #            define PTL_NO_SANITIZE_THREAD
0042 #        endif
0043 #    elif defined(__clang__) || defined(__GNUC__)
0044 #        define PTL_NO_SANITIZE_THREAD __attribute__((no_sanitize("thread")))
0045 #    else
0046 // otherwise, make blank
0047 #        define PTL_NO_SANITIZE_THREAD
0048 #    endif
0049 #endif
0050 
0051 namespace PTL
0052 {
0053 template <typename T>
0054 using decay_t = typename std::decay<T>::type;
0055 
0056 template <bool B, typename T = void>
0057 using enable_if_t = typename std::enable_if<B, T>::type;
0058 
0059 // for pre-C++14 tuple expansion to arguments
0060 namespace mpl
0061 {
0062 //--------------------------------------------------------------------------------------//
0063 
0064 namespace impl
0065 {
0066 //--------------------------------------------------------------------------------------//
0067 // Stores a tuple of indices.  Used by tuple and pair, and by bind() to
0068 // extract the elements in a tuple.
0069 template <size_t... Indexes>
0070 struct Index_tuple
0071 {};
0072 
0073 // Concatenates two Index_tuples.
0074 template <typename Itup1, typename Itup2>
0075 struct Itup_cat;
0076 
0077 template <size_t... Ind1, size_t... Ind2>
0078 struct Itup_cat<Index_tuple<Ind1...>, Index_tuple<Ind2...>>
0079 {
0080     using __type = Index_tuple<Ind1..., (Ind2 + sizeof...(Ind1))...>;
0081 };
0082 
0083 // Builds an Index_tuple<0, 1, 2, ..., NumT-1>.
0084 template <size_t NumT>
0085 struct Build_index_tuple
0086 : Itup_cat<typename Build_index_tuple<NumT / 2>::__type,
0087            typename Build_index_tuple<NumT - NumT / 2>::__type>
0088 {};
0089 
0090 template <>
0091 struct Build_index_tuple<1>
0092 {
0093     using __type = Index_tuple<0>;
0094 };
0095 
0096 template <>
0097 struct Build_index_tuple<0>
0098 {
0099     using __type = Index_tuple<>;
0100 };
0101 
0102 /// Class template integer_sequence
0103 template <typename Tp, Tp... Idx>
0104 struct integer_sequence
0105 {
0106     using value_type = Tp;
0107     static constexpr size_t size() noexcept { return sizeof...(Idx); }
0108 };
0109 
0110 template <typename Tp, Tp NumT, typename ISeq = typename Build_index_tuple<NumT>::__type>
0111 struct Make_integer_sequence;
0112 
0113 template <typename Tp, Tp NumT, size_t... Idx>
0114 struct Make_integer_sequence<Tp, NumT, Index_tuple<Idx...>>
0115 {
0116     static_assert(NumT >= 0, "Cannot make integer sequence of negative length");
0117 
0118     using __type = integer_sequence<Tp, static_cast<Tp>(Idx)...>;
0119 };
0120 
0121 /// Alias template make_integer_sequence
0122 template <typename Tp, Tp NumT>
0123 using make_integer_sequence = typename Make_integer_sequence<Tp, NumT>::__type;
0124 
0125 /// Alias template index_sequence
0126 template <size_t... Idx>
0127 using index_sequence = integer_sequence<size_t, Idx...>;
0128 
0129 /// Alias template make_index_sequence
0130 template <size_t NumT>
0131 using make_index_sequence = make_integer_sequence<size_t, NumT>;
0132 
0133 /// Alias template index_sequence_for
0134 template <typename... Types>
0135 using index_sequence_for = make_index_sequence<sizeof...(Types)>;
0136 
0137 template <size_t Idx, typename Tup>
0138 using index_type_t = decay_t<decltype(std::get<Idx>(std::declval<Tup>()))>;
0139 
0140 template <typename FnT, typename TupleT, size_t... Idx>
0141 static inline auto
0142 apply(FnT&& _func, TupleT _args, impl::index_sequence<Idx...>)
0143     -> decltype(std::forward<FnT>(_func)(std::get<Idx>(std::move(_args))...))
0144 {
0145     // GCC 5.3 warns about unused variable _args when the index sequence is empty
0146 #if defined(__GNUC__) && (__GNUC__ < 6)
0147     if(sizeof...(Idx) == 0)
0148     {
0149         ConsumeParameters(_args);
0150     }
0151 #endif
0152     return std::forward<FnT>(_func)(std::get<Idx>(std::move(_args))...);
0153 }
0154 
0155 //--------------------------------------------------------------------------------------//
0156 
0157 }  // namespace impl
0158 
0159 //--------------------------------------------------------------------------------------//
0160 
0161 /// Alias template index_sequence
0162 template <size_t... Idx>
0163 using index_sequence = impl::integer_sequence<size_t, Idx...>;
0164 
0165 /// Alias template make_index_sequence
0166 template <size_t NumT>
0167 using make_index_sequence = impl::make_integer_sequence<size_t, NumT>;
0168 
0169 /// Alias template index_sequence_for
0170 template <typename... Types>
0171 using index_sequence_for = impl::make_index_sequence<sizeof...(Types)>;
0172 
0173 template <typename FnT, typename TupleT>
0174 static inline void
0175 apply(FnT&& _func, TupleT&& _args)
0176 {
0177     using tuple_type = typename std::decay<TupleT>::type;
0178     constexpr auto N = std::tuple_size<tuple_type>::value;
0179     impl::apply(std::forward<FnT>(_func), std::forward<TupleT>(_args),
0180                 impl::make_index_sequence<N>{});
0181 }
0182 
0183 //--------------------------------------------------------------------------------------//
0184 
0185 }  // namespace mpl
0186 
0187 }  // namespace PTL