LCOV - code coverage report
Current view: top level - home/jenkins/libs/3rdparty/etl/include/etl - utility.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 9 11 81.8 %
Date: 2025-10-07 10:52:16 Functions: 73 79 92.4 %

          Line data    Source code
       1             : ///\file
       2             : 
       3             : /******************************************************************************
       4             : The MIT License(MIT)
       5             : 
       6             : Embedded Template Library.
       7             : https://github.com/ETLCPP/etl
       8             : https://www.etlcpp.com
       9             : 
      10             : Copyright(c) 2016 John Wellbelove
      11             : 
      12             : Permission is hereby granted, free of charge, to any person obtaining a copy
      13             : of this software and associated documentation files(the "Software"), to deal
      14             : in the Software without restriction, including without limitation the rights
      15             : to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
      16             : copies of the Software, and to permit persons to whom the Software is
      17             : furnished to do so, subject to the following conditions :
      18             : 
      19             : The above copyright notice and this permission notice shall be included in all
      20             : copies or substantial portions of the Software.
      21             : 
      22             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      23             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
      25             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      27             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      28             : SOFTWARE.
      29             : ******************************************************************************/
      30             : 
      31             : #ifndef ETL_UTILITY_INCLUDED
      32             : #define ETL_UTILITY_INCLUDED
      33             : 
      34             : #include "platform.h"
      35             : #include "type_traits.h"
      36             : 
      37             : #include "private/tuple_element.h"
      38             : #include "private/tuple_size.h"
      39             : 
      40             : #if defined(ETL_IN_UNIT_TEST) || ETL_USING_STL
      41             :   #if ETL_USING_CPP11
      42             :     #include <utility>
      43             :   #else
      44             :     #include <algorithm>
      45             :   #endif
      46             : #endif
      47             : 
      48             : ///\defgroup utility utility
      49             : ///\ingroup utilities
      50             : 
      51             : namespace etl
      52             : {
      53             : #if ETL_USING_CPP11
      54             :   //******************************************************************************
      55             :   template <typename T>
      56        1360 :   constexpr typename etl::remove_reference<T>::type&& move(T&& t) ETL_NOEXCEPT
      57             :   {
      58        1360 :     return static_cast<typename etl::remove_reference<T>::type&&>(t);
      59             :   }
      60             : 
      61             :   //******************************************************************************
      62             :   template <typename T>
      63        1713 :   constexpr T&& forward(typename etl::remove_reference<T>::type& t) ETL_NOEXCEPT
      64             :   {
      65        1713 :     return static_cast<T&&>(t);
      66             :   }
      67             : 
      68             :   template <typename T>
      69             :   constexpr T&& forward(typename etl::remove_reference<T>::type&& t) ETL_NOEXCEPT
      70             :   {
      71             :     ETL_STATIC_ASSERT(!etl::is_lvalue_reference<T>::value, "Invalid rvalue to lvalue conversion");
      72             :     return static_cast<T&&>(t);
      73             :   }
      74             : 
      75             :   //******************************************************************************
      76             :   /// See std::forward_like https://en.cppreference.com/w/cpp/utility/forward_like
      77             :   /// Returns a reference to x which has similar properties to T&&.
      78             :   ///\return
      79             :   /// If etl::remove_reference_t<T> is const then returns a const reference if U is an lvalue, otherwise a const rvalue reference.
      80             :   /// If etl::remove_reference_t<T> is not const then returns a reference if U is an lvalue, otherwise an rvalue reference.
      81             :   //******************************************************************************
      82             :   //***********************************
      83             :   /// T is const & lvalue.
      84             :   //***********************************
      85             :   template <typename T, typename U>
      86             :   ETL_NODISCARD
      87             :   ETL_CONSTEXPR
      88             :   etl::enable_if_t<etl::is_const<etl::remove_reference_t<T>>::value && etl::is_lvalue_reference<T>::value, const etl::remove_reference_t<U>&>
      89             :     forward_like(U&& u) ETL_NOEXCEPT
      90             :   {
      91             :     return static_cast<const etl::remove_reference_t<U>&>(u);
      92             :   }
      93             : 
      94             :   //***********************************
      95             :   /// T is const & rvalue.
      96             :   //***********************************
      97             :   template <typename T, typename U>
      98             :   ETL_NODISCARD
      99             :   ETL_CONSTEXPR
     100             :   etl::enable_if_t<etl::is_const<etl::remove_reference_t<T>>::value && !etl::is_lvalue_reference<T>::value, const etl::remove_reference_t<U>&&>
     101             :     forward_like(U&& u) ETL_NOEXCEPT
     102             :   {
     103             :     return static_cast<const etl::remove_reference_t<U>&&>(u);
     104             :   }
     105             : 
     106             :   //***********************************
     107             :   /// T is not const & lvalue.
     108             :   //***********************************
     109             :   template <typename T, typename U>
     110             :   ETL_NODISCARD
     111             :   ETL_CONSTEXPR
     112             :   etl::enable_if_t<!etl::is_const<etl::remove_reference_t<T>>::value && etl::is_lvalue_reference<T>::value, etl::remove_reference_t<U>&>
     113             :     forward_like(U&& u) ETL_NOEXCEPT
     114             :   {
     115             :     return static_cast<etl::remove_reference_t<U>&>(u);
     116             :   }
     117             : 
     118             :   //***********************************
     119             :   /// T is not const & rvalue.
     120             :   //***********************************
     121             :   template <typename T, typename U>
     122             :   ETL_NODISCARD
     123             :   ETL_CONSTEXPR
     124             :   etl::enable_if_t<!etl::is_const<etl::remove_reference_t<T>>::value && !etl::is_lvalue_reference<T>::value, etl::remove_reference_t<U>&&>
     125             :     forward_like(U&& u) ETL_NOEXCEPT
     126             :   {
     127             :     return static_cast<etl::remove_reference_t<U>&&>(u);
     128             :   }
     129             : 
     130             :   //***********************************
     131             :   // Defines the type that forward_like would cast to.
     132             :   //***********************************
     133             :   template <typename T, typename U>
     134             :   using forward_like_t = decltype(etl::forward_like<T>(etl::declval<U&>()));
     135             : #endif
     136             : 
     137             :   //***********************************
     138             :   // Gets the underlying type of an enum.
     139             :   //***********************************
     140             :   template <typename T>
     141           0 :   ETL_CONSTEXPR typename underlying_type<T>::type to_underlying(T value) ETL_NOEXCEPT
     142             :   {
     143           0 :     return static_cast<typename underlying_type<T>::type>(value);
     144             :   }
     145             : 
     146             :   // We can't have std::swap and etl::swap templates coexisting in the unit tests
     147             :   // as the compiler will be unable to decide which one to use, due to ADL.
     148             : #if ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST)
     149             :   //***************************************************************************
     150             :   // swap
     151             :   template <typename T>
     152         347 :   ETL_CONSTEXPR14 void swap(T& a, T& b) ETL_NOEXCEPT
     153             :   {
     154         347 :     T temp(ETL_MOVE(a));
     155         347 :     a = ETL_MOVE(b);
     156         347 :     b = ETL_MOVE(temp);
     157         347 :   }
     158             : 
     159             :   template< class T, size_t Size >
     160             :   ETL_CONSTEXPR14 void swap(T(&a)[Size], T(&b)[Size]) ETL_NOEXCEPT
     161             :   {
     162             :     for (size_t i = 0UL; i < Size; ++i)
     163             :     {
     164             :       swap(a[i], b[i]);
     165             :     }
     166             :   }
     167             : #endif
     168             : 
     169             :   //***************************************************************************
     170             :   ///\brief pair holds two objects of arbitrary type
     171             :   ///
     172             :   ///\tparam T1, T2 The types of the elements that the pair stores
     173             :   //***************************************************************************
     174             :   template <typename T1, typename T2>
     175             :   struct pair
     176             :   {
     177             :     typedef T1 first_type;   ///< @c first_type is the first bound type
     178             :     typedef T2 second_type;  ///< @c second_type is the second bound type
     179             : 
     180             :     T1 first;   ///< @c first is a copy of the first object
     181             :     T2 second;  ///< @c second is a copy of the second object
     182             : 
     183             :     //***************************************************************************
     184             :     ///\brief Default constructor
     185             :     ///
     186             :     /// The default constructor creates @c first and @c second using their respective default constructors.
     187             :     //***************************************************************************
     188             :     ETL_CONSTEXPR pair()
     189             :       : first(T1())
     190             :       , second(T2())
     191             :     {
     192             :     }
     193             : 
     194             :     //***************************************************************************
     195             :     ///\brief Constructor from parameters
     196             :     ///
     197             :     /// Two objects may be passed to a @c pair constructor to be copied.
     198             :     //***************************************************************************
     199             :     ETL_CONSTEXPR14 pair(const T1& a, const T2& b)
     200             :       : first(a)
     201             :       , second(b)
     202             :     {
     203             :     }
     204             : 
     205             : #if ETL_USING_CPP11
     206             :     //***************************************************************************
     207             :     ///\brief Move constructor from parameters.
     208             :     //***************************************************************************
     209             :     template <typename U1, typename U2>
     210             :     ETL_CONSTEXPR14 pair(U1&& a, U2&& b)
     211             :       : first(etl::forward<U1>(a))
     212             :       , second(etl::forward<U2>(b))
     213             :     {
     214             :     }
     215             : #endif
     216             : 
     217             :     //***************************************************************************
     218             :     ///\brief Copy constructor
     219             :     ///
     220             :     /// There is also a templated copy constructor for the @c pair class itself.
     221             :     //***************************************************************************
     222             :     template <typename U1, typename U2>
     223             :     ETL_CONSTEXPR14 pair(const pair<U1, U2>& other)
     224             :       : first(other.first)
     225             :       , second(other.second)
     226             :     {
     227             :     }
     228             : 
     229             :     /// Copy constructor
     230             :     pair(const pair<T1, T2>& other)
     231             :       : first(other.first)
     232             :       , second(other.second)
     233             :     {
     234             :     }
     235             : 
     236             : #if ETL_USING_CPP11
     237             :     /// Move constructor
     238             :     template <typename U1, typename U2>
     239             :     ETL_CONSTEXPR14 pair(pair<U1, U2>&& other)
     240             :       : first(etl::forward<U1>(other.first))
     241             :       , second(etl::forward<U2>(other.second))
     242             :     {
     243             :     }
     244             : #endif
     245             : 
     246             : #if defined(ETL_IN_UNIT_TEST) || ETL_USING_STL
     247             :     /// Converting to std::pair
     248             :     template <typename U1, typename U2>
     249             :     operator std::pair<U1, U2>()
     250             :     {
     251             :       return std::make_pair(first, second);
     252             :     }
     253             : 
     254             :     /// Constructing from std::pair
     255             :     template <typename U1, typename U2>
     256             :     pair(const std::pair<U1, U2>& other)
     257             :       : first(other.first)
     258             :       , second(other.second)
     259             :     {
     260             :     }
     261             : 
     262             : #if ETL_USING_CPP11
     263             :     /// Constructing to etl::pair
     264             :     template <typename U1, typename U2>
     265             :     pair(std::pair<U1, U2>&& other)
     266             :       : first(etl::forward<U1>(other.first))
     267             :       , second(etl::forward<U2>(other.second))
     268             :     {
     269             :     }
     270             : #endif
     271             : #endif
     272             : 
     273             :     void swap(pair<T1, T2>& other)
     274             :     {
     275             :       using ETL_OR_STD::swap;
     276             : 
     277             :       swap(first, other.first);
     278             :       swap(second, other.second);
     279             :     }
     280             : 
     281             :     pair<T1, T2>& operator =(const pair<T1, T2>& other)
     282             :     {
     283             :       first = other.first;
     284             :       second = other.second;
     285             : 
     286             :       return *this;
     287             :     }
     288             : 
     289             :     template <typename U1, typename U2>
     290             :     pair<U1, U2>& operator =(const pair<U1, U2>& other)
     291             :     {
     292             :       first = other.first;
     293             :       second = other.second;
     294             : 
     295             :       return *this;
     296             :     }
     297             : 
     298             : #if ETL_USING_CPP11
     299             :     pair<T1, T2>& operator =(pair<T1, T2>&& other)
     300             :     {
     301             :       first = etl::forward<T1>(other.first);
     302             :       second = etl::forward<T2>(other.second);
     303             : 
     304             :       return *this;
     305             :     }
     306             : 
     307             :     template <typename U1, typename U2>
     308             :     pair<U1, U2>& operator =(pair<U1, U2>&& other)
     309             :     {
     310             :       first = etl::forward<U1>(other.first);
     311             :       second = etl::forward<U2>(other.second);
     312             : 
     313             :       return *this;
     314             :     }
     315             : #endif
     316             :   };
     317             : 
     318             :   //***************************************************************************
     319             :   ///\brief A convenience wrapper for creating a @ref pair from two objects.
     320             :   ///
     321             :   ///\param a The first object.
     322             :   ///\param b The second object.
     323             :   ///
     324             :   ///\return A newly-constructed @ref pair object of the appropriate type.
     325             :   //***************************************************************************
     326             : #if ETL_USING_CPP11
     327             :   template <typename T1, typename T2>
     328             :   inline pair<T1, T2> make_pair(T1&& a, T2&& b)
     329             :   {
     330             :     return pair<T1, T2>(etl::forward<T1>(a), etl::forward<T2>(b));
     331             :   }
     332             : #else
     333             :   template <typename T1, typename T2>
     334             :   inline pair<T1, T2> make_pair(T1 a, T2 b)
     335             :   {
     336             :     return pair<T1, T2>(a, b);
     337             :   }
     338             : #endif
     339             : 
     340             : #if ETL_USING_CPP11
     341             :   //******************************************************************************
     342             :   template <size_t Index, typename T1, typename T2>
     343             :   struct tuple_element<Index, ETL_OR_STD::pair<T1, T2> >
     344             :   {
     345             :     ETL_STATIC_ASSERT(Index < 2U, "pair has only 2 elements");
     346             :   };
     347             : 
     348             :   template <typename T1, typename T2>
     349             :   struct tuple_element<0U, ETL_OR_STD::pair<T1, T2> >
     350             :   {
     351             :     typedef T1 type;
     352             :   };
     353             : 
     354             :   template <typename T1, typename T2>
     355             :   struct tuple_element<1U, ETL_OR_STD::pair<T1, T2> >
     356             :   {
     357             :     typedef T2 type;
     358             :   };
     359             : 
     360             :   //******************************************************************************
     361             :   template <typename T1, typename T2>
     362             :   struct tuple_size<ETL_OR_STD::pair<T1, T2>> : public etl::integral_constant<size_t, 2U>
     363             :   {
     364             :   };
     365             : #endif
     366             : 
     367             :   //******************************************************************************
     368             :   template <typename T1, typename T2>
     369             :   inline void swap(pair<T1, T2>& a, pair<T1, T2>& b)
     370             :   {
     371             :     a.swap(b);
     372             :   }
     373             : 
     374             :   ///  Two pairs of the same type are equal if their members are equal.
     375             :   template <typename T1, typename T2>
     376             :   inline bool operator ==(const pair<T1, T2>& a, const pair<T1, T2>& b)
     377             :   {
     378             : #include "private/diagnostic_float_equal_push.h"
     379             :     return (a.first == b.first) && !(a.second < b.second) && !(a.second > b.second);
     380             : #include "private/diagnostic_pop.h"
     381             :   }
     382             : 
     383             :   /// Uses @c operator== to find the result.
     384             :   template <typename T1, typename T2>
     385             :   inline bool operator !=(const pair<T1, T2>& a, const pair<T1, T2>& b)
     386             :   {
     387             :     return !(a == b);
     388             :   }
     389             : 
     390             :   template <typename T1, typename T2>
     391             :   inline bool operator <(const pair<T1, T2>& a, const pair<T1, T2>& b)
     392             :   {
     393             :     return (a.first < b.first) ||
     394             :       (!(b.first < a.first) && (a.second < b.second));
     395             :   }
     396             : 
     397             :   /// Uses @c operator< to find the result.
     398             :   template <typename T1, typename T2>
     399             :   inline bool operator >(const pair<T1, T2>& a, const pair<T1, T2>& b)
     400             :   {
     401             :     return (b < a);
     402             :   }
     403             : 
     404             :   /// Uses @c operator< to find the result.
     405             :   template <typename T1, typename T2>
     406             :   inline bool operator <=(const pair<T1, T2>& a, const pair<T1, T2>& b)
     407             :   {
     408             :     return !(b < a);
     409             :   }
     410             : 
     411             :   /// Uses @c operator< to find the result.
     412             :   template <typename T1, typename T2>
     413             :   inline bool operator >=(const pair<T1, T2>& a, const pair<T1, T2>& b)
     414             :   {
     415             :     return !(a < b);
     416             :   }
     417             : 
     418             :   //***************************************************************************
     419             :   ///\brief Functor to select @ref pair::first
     420             :   ///
     421             :   ///\ref select1st is a functor object that takes a single argument, a @ref pair, and returns the @ref pair::first element.
     422             :   ///
     423             :   ///\b Example
     424             :   ///\snippet test_utility.cpp test_select1st_example
     425             :   ///
     426             :   ///\tparam TPair The function object's argument type.
     427             :   ///
     428             :   ///\see select2nd
     429             :   //***************************************************************************
     430             :   template <typename TPair>
     431             :   struct select1st
     432             :   {
     433             :     typedef typename TPair::first_type type;  ///< type of member @ref pair::first.
     434             : 
     435             :     //***************************************************************************
     436             :     ///\brief Function call that return @c p.first.
     437             :     ///\return a reference to member @ref pair::first of the @c pair `p`
     438             :     //***************************************************************************
     439             :     type& operator()(TPair& p) const
     440             :     {
     441             :       return p.first;
     442             :     }
     443             : 
     444             :     //***************************************************************************
     445             :     ///\copydoc operator()(TPair&)const
     446             :     //
     447             :     const type& operator()(const TPair& p) const
     448             :     {
     449             :       return p.first;
     450             :     }
     451             :   };
     452             : 
     453             :   //***************************************************************************
     454             :   ///\brief Functor to select @ref pair::second
     455             :   ///
     456             :   ///\ref select2nd is a functor object that takes a single argument, a @ref pair, and returns the @ref pair::second element.
     457             :   ///
     458             :   ///\b Example
     459             :   ///\snippet test_utility.cpp test_select2nd_example
     460             :   ///
     461             :   ///\tparam TPair The function object's argument type.
     462             :   ///
     463             :   ///\see select1st
     464             :   //***************************************************************************
     465             :   template <typename TPair>
     466             :   struct select2nd
     467             :   {
     468             :     typedef typename TPair::second_type type;  ///< type of member @ref pair::second.
     469             : 
     470             :     //***************************************************************************
     471             :     ///\brief Function call. The return value is `p.second`.
     472             :     ///\return a reference to member `second` of the pair `p`.
     473             :     //***************************************************************************
     474             :     type& operator()(TPair& p) const
     475             :     {
     476             :       return p.second;
     477             :     }
     478             : 
     479             :     //***************************************************************************
     480             :     ///\copydoc operator()(TPair&)const
     481             :     //***************************************************************************
     482             :     const type& operator()(const TPair& p) const
     483             :     {
     484             :       return p.second;
     485             :     }
     486             :   };
     487             : 
     488             : #if ETL_NOT_USING_STL || ETL_CPP14_NOT_SUPPORTED
     489             :   //***************************************************************************
     490             :   /// exchange (const)
     491             :   //***************************************************************************
     492             :   template <typename T>
     493             :   T exchange(T& object, const T& new_value)
     494             :   {
     495             :     T old_value = object;
     496             :     object = new_value;
     497             :     return old_value;
     498             :   }
     499             : 
     500             :   template <typename T, typename U>
     501             :   T exchange(T& object, const U& new_value)
     502             :   {
     503             :     T old_value = object;
     504             :     object = new_value;
     505             :     return old_value;
     506             :   }
     507             : #else
     508             :   //***************************************************************************
     509             :   /// exchange (const)
     510             :   //***************************************************************************
     511             :   template <typename T, typename U = T>
     512             :   T exchange(T& object, const U& new_value)
     513             :   {
     514             :     return std::exchange(object, new_value);
     515             :   }
     516             : #endif
     517             : 
     518             :   //***************************************************************************
     519             :   /// as_const
     520             :   //***************************************************************************
     521             :   template <typename T>
     522             :   typename etl::add_const<T>::type& as_const(T& t)
     523             :   {
     524             :     return t;
     525             :   }
     526             : 
     527             :   //***************************************************************************
     528             :   /// integer_sequence
     529             :   //***************************************************************************
     530             : #if ETL_USING_CPP11
     531             :   template <typename T, T... Integers>
     532             :   class integer_sequence
     533             :   {
     534             :   public:
     535             :   
     536             :     ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Integral types only");
     537             : 
     538             :     typedef T value_type;
     539             :   
     540             :     static ETL_CONSTEXPR size_t size() ETL_NOEXCEPT 
     541             :     { 
     542             :       return sizeof...(Integers);
     543             :     }
     544             :   };
     545             : 
     546             :   namespace private_integer_sequence
     547             :   {
     548             :     template <size_t Count, typename IndexSeq>
     549             :     struct make_index_sequence;
     550             : 
     551             :     template <size_t Count, size_t... Indices>
     552             :     struct make_index_sequence<Count, etl::integer_sequence<size_t, Indices...>>
     553             :     {
     554             :       using type = typename make_index_sequence<Count - 1, etl::integer_sequence<size_t, Count - 1, Indices...>>::type;
     555             :     };
     556             : 
     557             :     template <size_t... Indices>
     558             :     struct make_index_sequence<0, etl::integer_sequence<size_t, Indices...>>
     559             :     {
     560             :       using type = etl::integer_sequence<size_t, Indices...>;
     561             :     };
     562             :   }
     563             : 
     564             :   //***********************************
     565             :   template <size_t Count>
     566             :   using make_index_sequence = typename private_integer_sequence::make_index_sequence<Count, etl::integer_sequence<size_t>>::type;
     567             : 
     568             :   template <typename... TTypes>
     569             :   using make_index_sequence_for = typename private_integer_sequence::make_index_sequence<sizeof...(TTypes), etl::integer_sequence<size_t>>::type;
     570             : 
     571             :   //***********************************
     572             :   template <size_t... Indices>
     573             :   using index_sequence = etl::integer_sequence<size_t, Indices...>;
     574             : 
     575             :   template <typename... TTypes>
     576             :   using index_sequence_for = typename etl::make_index_sequence_for<TTypes...>;
     577             : #endif
     578             : 
     579             :   //***************************************************************************
     580             :   /// 2D coordinate type.
     581             :   //***************************************************************************
     582             :   template <typename T>
     583             :   struct coordinate_2d
     584             :   {
     585             :     coordinate_2d()
     586             :       : x(T(0))
     587             :       , y(T(0))
     588             :     {
     589             :     }
     590             : 
     591             :     coordinate_2d(T x_, T y_)
     592             :       : x(x_)
     593             :       , y(y_)
     594             :     {
     595             :     }
     596             : 
     597             :     friend bool operator ==(const coordinate_2d& lhs, const coordinate_2d& rhs)
     598             :     {
     599             :       return (lhs.x == rhs.x) && (lhs.y == rhs.y);
     600             :     }
     601             : 
     602             :     friend bool operator !=(const coordinate_2d& lhs, const coordinate_2d& rhs)
     603             :     {
     604             :       return !(lhs == rhs);
     605             :     }
     606             : 
     607             :     T x;
     608             :     T y;
     609             :   };
     610             : 
     611             :   //***************************************************************************
     612             :   /// in_place disambiguation tags.
     613             :   //***************************************************************************
     614             :   
     615             :   //*************************
     616             :   struct in_place_t 
     617             :   {
     618             :     explicit ETL_CONSTEXPR in_place_t() {}
     619             :   };
     620             : 
     621             : #if ETL_USING_CPP17
     622             :   inline constexpr in_place_t in_place{};
     623             : #endif
     624             :   
     625             :   //*************************
     626             :   template <typename T> struct in_place_type_t 
     627             :   {
     628             :     explicit ETL_CONSTEXPR in_place_type_t() {}
     629             :   };
     630             : 
     631             : #if ETL_USING_CPP17
     632             :   template <typename T>
     633             :   inline constexpr in_place_type_t<T> in_place_type{};
     634             : #endif
     635             : 
     636             :   //*************************
     637             :   template <size_t Index> struct in_place_index_t 
     638             :   {
     639             :     explicit ETL_CONSTEXPR in_place_index_t() {}
     640             :   };
     641             : 
     642             : #if ETL_USING_CPP17
     643             :   template <size_t Index>
     644             :   inline constexpr in_place_index_t<Index> in_place_index{};
     645             : #endif
     646             : 
     647             : #if ETL_USING_CPP11
     648             :   //*************************************************************************
     649             :   // A function wrapper for free/global functions.
     650             :   // Deprecated.
     651             :   // See etl::function_ptr_as_functor for a runtime time wrapper option.
     652             :   // See etl::function_as_functor for a compile time wrapper option.
     653             :   //*************************************************************************
     654             :   template <typename TReturn, typename... TParams>
     655             :   class ETL_DEPRECATED functor
     656             :   {
     657             :   public:
     658             : 
     659             :     //*********************************
     660             :     /// Constructor.
     661             :     //*********************************
     662             :     constexpr functor(TReturn(*ptr_)(TParams...))
     663             :       : ptr(ptr_)
     664             :     {
     665             :     }
     666             : 
     667             :     //*********************************
     668             :     /// Const function operator.
     669             :     //*********************************
     670             :     constexpr TReturn operator()(TParams... args) const
     671             :     {
     672             :       return ptr(etl::forward<TParams>(args)...);
     673             :     }
     674             : 
     675             :   private:
     676             : 
     677             :     /// The pointer to the function.
     678             :     TReturn(*ptr)(TParams...);
     679             :   };
     680             : 
     681             :   //*****************************************************************************
     682             :   // Wrap a member function with a static free function.
     683             :   // Creates a static member function that calls the specified member function.
     684             :   // Deprecated
     685             :   // See etl::member_function_as_static
     686             :   //*****************************************************************************
     687             :   template <typename T>
     688             :   class member_function_wrapper;
     689             : 
     690             :   template <typename TReturn, typename... TParams>
     691             :   class ETL_DEPRECATED member_function_wrapper<TReturn(TParams...)>
     692             :   {
     693             :   public:
     694             : 
     695             :     template <typename T, T& Instance, TReturn(T::* Method)(TParams...)>
     696             :     static constexpr TReturn function(TParams... params)
     697             :     {
     698             :       return (Instance.*Method)(etl::forward<TParams>(params)...);
     699             :     }
     700             :   };
     701             : 
     702             :   //*****************************************************************************
     703             :   // Wrap a functor with a static free function.
     704             :   // Creates a static member function that calls the specified functor.
     705             :   // Deprecated
     706             :   // See etl::functor_as_static
     707             :   //*****************************************************************************
     708             :   template <typename T>
     709             :   class functor_wrapper;
     710             : 
     711             :   template <typename TReturn, typename... TParams>
     712             :   class functor_wrapper<TReturn(TParams...)>
     713             :   {
     714             :   public:
     715             : 
     716             :     template <typename TFunctor, TFunctor& Instance>
     717             :     static constexpr TReturn function(TParams... params)
     718             :     {
     719             :       return Instance(etl::forward<TParams>(params)...);
     720             :     }
     721             :   };
     722             : #endif
     723             : 
     724             : #if ETL_USING_CPP17
     725             :   //*****************************************************************************
     726             :   // Wraps a functor with a static free function at compile time.
     727             :   // Creates a static member 'call' that calls the specified functor.
     728             :   //*****************************************************************************
     729             :   template <auto& Instance>
     730             :   struct functor_as_static 
     731             :   {
     732             :     template <typename... TArgs>
     733             :     static constexpr auto call(TArgs&&... args)
     734             :     {
     735             :       return (Instance.operator())(etl::forward<TArgs>(args)...);
     736             :     }
     737             :   };
     738             : 
     739             :   //*****************************************************************************
     740             :   // Wraps a member function with a static free function at compile time.
     741             :   // Creates a static member 'call' that calls the specified member function.
     742             :   //*****************************************************************************
     743             :   template <auto Method, auto& Instance>
     744             :   struct member_function_as_static 
     745             :   {
     746             :     template <typename... TArgs>
     747             :     static constexpr auto call(TArgs&&... args)
     748             :     {
     749             :       return (Instance.*Method)(etl::forward<TArgs>(args)...);
     750             :     }
     751             :   };
     752             : 
     753             :   //*****************************************************************************
     754             :   // Wraps a member function with a functor at compile time.
     755             :   // Creates a functor that calls the specified member function.
     756             :   //*****************************************************************************
     757             :   template <auto Method, auto& Instance>
     758             :   class member_function_as_functor
     759             :   {
     760             :   public:
     761             : 
     762             :     template <typename... TArgs>
     763             :     constexpr auto operator()(TArgs&&... args) const -> decltype((Instance.*Method)(etl::forward<TArgs>(args)...))
     764             :     {
     765             :       return (Instance.*Method)(etl::forward<TArgs>(args)...);
     766             :     }
     767             :   };
     768             : 
     769             :   //*****************************************************************************
     770             :   // Wraps a function with a functor at compile time.
     771             :   // Creates a functor that calls the specified free function.
     772             :   //*****************************************************************************
     773             :   template <auto Function>
     774             :   class function_as_functor
     775             :   {
     776             :   public:
     777             : 
     778             :     template<typename... TArgs>
     779             :     constexpr auto operator()(TArgs&&... args) const -> decltype(Function(etl::forward<TArgs>(args)...))
     780             :     {
     781             :       return Function(etl::forward<TArgs>(args)...);
     782             :     }
     783             :   };
     784             : #endif
     785             : 
     786             : #if ETL_USING_CPP11
     787             :   //*****************************************************************************
     788             :   // Wraps a function pointer with a functor at run time.
     789             :   // Creates a functor that calls the specified free function.
     790             :   //*****************************************************************************
     791             :   template <typename T>
     792             :   class function_ptr_as_functor;
     793             : 
     794             :   template <typename TReturn, typename... TArgs>
     795             :   class function_ptr_as_functor<TReturn(TArgs...)>
     796             :   {
     797             :   public:
     798             : 
     799             :     //*********************************
     800             :     /// Constructor.
     801             :     //*********************************
     802             :     constexpr function_ptr_as_functor(TReturn(*ptr_)(TArgs...))
     803             :       : ptr(ptr_)
     804             :     {
     805             :     }
     806             : 
     807             :     //*********************************
     808             :     /// Const function operator.
     809             :     //*********************************
     810             :     constexpr TReturn operator()(TArgs... args) const
     811             :     {
     812             :       return ptr(etl::forward<TArgs>(args)...);
     813             :     }
     814             : 
     815             :   private:
     816             : 
     817             :     /// The pointer to the function.
     818             :     TReturn(*ptr)(TArgs...);
     819             :   };
     820             : #endif
     821             : 
     822             : #if ETL_USING_CPP17 && !defined(ETL_FORCE_CPP11_NONTYPE)
     823             :   //*****************************************************************************
     824             :   // Wraps a non-type template parameter as a type.
     825             :   //*****************************************************************************
     826             :   template <auto Value>
     827             :   struct nontype_t
     828             :   {
     829             :     static constexpr decltype(Value) value = Value;
     830             :   };
     831             : #elif ETL_USING_CPP11
     832             :   //*****************************************************************************
     833             :   // Wraps a non-type template parameter as a type.
     834             :   //*****************************************************************************
     835             :   template <typename T, T Value>
     836             :   struct nontype_t
     837             :   {
     838             :     static constexpr T value = Value;
     839             :   };
     840             : #endif
     841             : }
     842             : 
     843             : #endif

Generated by: LCOV version 1.14