diff --git a/alib2std/src/extensions/common/tuple_common.hpp b/alib2std/src/extensions/common/tuple_common.hpp new file mode 100644 index 0000000000000000000000000000000000000000..428f1b3c9769858d63543a3c26817318cf00f1eb --- /dev/null +++ b/alib2std/src/extensions/common/tuple_common.hpp @@ -0,0 +1,144 @@ +/* + * tuple.hpp + * + * Created on: Apr 1, 2013 + * Author: Jan Travnicek + */ + +#ifndef __TUPLE_COMMON_HPP_ +#define __TUPLE_COMMON_HPP_ + +#include <tuple> + +namespace ext { + +template < class ... Types > +class tuple_size; + +template < class T > +class tuple_size < T & > : public std::integral_constant < std::size_t, ext::tuple_size < T >::value > { }; + +template < class T > +class tuple_size < T && > : public std::integral_constant < std::size_t, ext::tuple_size < T >::value > { }; + +template < class T > +class tuple_size < const T > : public std::integral_constant < std::size_t, ext::tuple_size < T >::value > { }; + +template < class T > +class tuple_size< volatile T > : public std::integral_constant < std::size_t, ext::tuple_size < T >::value > { }; + +template< class T > +class tuple_size < const volatile T > : public std::integral_constant < std::size_t, tuple_size < T >::value > { }; + + + +template < std::size_t I, class T > +struct tuple_element; + +template < std::size_t I, class T > +struct tuple_element < I, const T > { + typedef typename std::add_const < typename ext::tuple_element < I, T >::type >::type type; +}; + +template < std::size_t I, class T > +struct tuple_element< I, volatile T > { + typedef typename std::add_volatile < typename ext::tuple_element < I, T >::type >::type type; +}; + +template < std::size_t I, class T > +struct tuple_element < I, const volatile T > { + typedef typename std::add_cv < typename ext::tuple_element < I, T >::type >::type type; +}; + + + +template < unsigned I > +struct call_on_nth_helper { + template < class Result, class Tuple, class Callable > + static Result call_on_nth_fn ( Tuple && t, unsigned index, Callable callback ) { + if ( index == 0 ) + return callback ( std::forward < Tuple && > ( t ).template get < ext::tuple_size < Tuple >::value - I > ( ) ); + else + return call_on_nth_helper < I - 1 >::template call_on_nth_fn < Result > ( std::forward < Tuple && > ( t ), index - 1, callback ); + } +}; + +template < > +struct call_on_nth_helper < 0 > { + template < class Result, class Tuple, class Callable > + static Result call_on_nth_fn ( Tuple &&, unsigned, Callable ) { + throw std::out_of_range ( "Not enough elements in tuple." ); + } +}; + +template < class Result, class Tuple, class Callable > +Result call_on_nth ( Tuple && t, unsigned index, Callable callback ) { + return call_on_nth_helper < ext::tuple_size < Tuple >::value >::template call_on_nth_fn < Result > ( std::forward < Tuple && > ( t ), index, callback ); +} + + + +template < unsigned I > +struct foreach_helper { + template < class Tuple, class Callable > + static void foreach_fn ( Tuple && t, Callable callback ) { + foreach_helper < I - 1 >::foreach_fn ( std::forward < Tuple && > ( t ), callback ); + callback ( std::forward < Tuple && > ( t ).template get < I - 1 > ( ) ); + } +}; + +template < > +struct foreach_helper < 0 > { + template < class Tuple, class Callable > + static void foreach_fn ( Tuple &&, Callable ) { + } +}; + +template < class Tuple, class Callable > +void foreach ( Tuple && t, Callable callback ) { + return foreach_helper < ext::tuple_size < Tuple >::value >::foreach_fn ( std::forward < Tuple && > ( t ), callback ); +} + + + +template < int I > +struct compareTupleHelper { + template < class Tuple > + static int compHelp ( const Tuple & t1, const Tuple & t2 ) { + int res = compareTupleHelper < I - 1 >::compHelp ( t1, t2 ); + + if ( res != 0 ) return res; + + static compare < typename std::decay < typename ext::tuple_element < I, Tuple >::type >::type > comp; + return comp ( t1.template get < I > ( ), t2.template get < I > ( ) ); + } + +}; + +template < > +struct compareTupleHelper < 0 > { + template < class Tuple > + static int compHelp ( const Tuple & t1, const Tuple & t2 ) { + static compare < typename std::decay < typename ext::tuple_element < 0, Tuple >::type >::type > comp; + return comp ( t1.template get < 0 > ( ), t2.template get < 0 > ( ) ); + } + +}; + + + +template < class Tuple, class Callable > +bool all_of ( const Tuple & t, Callable callback ) { + bool res = true; + + auto aggregateCallback = [ & ] ( const auto & arg0 ) { + res &= callback ( arg0 ); + }; + + ext::foreach ( t, aggregateCallback ); + return res; +} + +} /* namespace ext */ + +#endif /* __TUPLE_COMMON_HPP_ */ diff --git a/alib2std/src/extensions/ptr_tuple.hpp b/alib2std/src/extensions/ptr_tuple.hpp index 0260455c1efbc0787483c5f8a0d5433f29d69acf..08cf6b5d3479ad4c1987d46c5d142bec9c1ac0df 100644 --- a/alib2std/src/extensions/ptr_tuple.hpp +++ b/alib2std/src/extensions/ptr_tuple.hpp @@ -28,11 +28,12 @@ #include <sstream> #include <string> -#include "tuple.hpp" #include "compare.hpp" #include "iterator.hpp" #include "clone.hpp" +#include "common/tuple_common.hpp" + namespace ext { /** @@ -287,7 +288,7 @@ struct compare < ext::ptr_tuple < Ts ... > > { * \return negative value of left < right, positive value if left > right, zero if left == right */ int operator ()( const ext::ptr_tuple < Ts ... > & first, const ext::ptr_tuple < Ts ... > & second ) const { - return compareTupleHelper < ext::tuple_size < ext::tuple < Ts ... > >::value - 1, ext::ptr_tuple < Ts ... > >::compHelp ( first, second ); + return compareTupleHelper < ext::tuple_size < ext::ptr_tuple < Ts ... > >::value - 1 >::compHelp ( first, second ); } }; @@ -319,9 +320,9 @@ std::string to_string ( const ext::ptr_tuple < Ts ... > & value ) { * * \return true if compared values are the same, false othervise */ -template < class T > -bool operator == ( const ptr_tuple < T > & first, const ptr_tuple < T > & second ) { - static compare < ptr_tuple < T > > comp; +template < class ... Ts > +bool operator == ( const ptr_tuple < Ts ... > & first, const ptr_tuple < Ts ... > & second ) { + static compare < ptr_tuple < Ts ... > > comp; return comp ( first, second ) == 0; } @@ -336,8 +337,8 @@ bool operator == ( const ptr_tuple < T > & first, const ptr_tuple < T > & second * * \return true if compared values are not the same, false othervise */ -template < class T > -bool operator != ( const ptr_tuple < T > & first, const ptr_tuple < T > & second ) { +template < class ... Ts > +bool operator != ( const ptr_tuple < Ts ... > & first, const ptr_tuple < Ts ... > & second ) { return ! ( first == second ); } @@ -352,9 +353,9 @@ bool operator != ( const ptr_tuple < T > & first, const ptr_tuple < T > & second * * \return true if the first value is smaller than the second, false othervise */ -template < class T > -bool operator < ( const ptr_tuple < T > & first, const ptr_tuple < T > & second ) { - static compare < ptr_tuple < T > > comp; +template < class ... Ts > +bool operator < ( const ptr_tuple < Ts ... > & first, const ptr_tuple < Ts ... > & second ) { + static compare < ptr_tuple < Ts ... > > comp; return comp ( first, second ) < 0; } @@ -369,8 +370,8 @@ bool operator < ( const ptr_tuple < T > & first, const ptr_tuple < T > & second * * \return true if the first value is bigger than the second, false othervise */ -template < class T > -bool operator > ( const ptr_tuple < T > & first, const ptr_tuple < T > & second ) { +template < class ... Ts > +bool operator > ( const ptr_tuple < Ts ... > & first, const ptr_tuple < Ts ... > & second ) { return second < first; } @@ -385,8 +386,8 @@ bool operator > ( const ptr_tuple < T > & first, const ptr_tuple < T > & second * * \return true if the first value is smaller or equal to the second, false othervise */ -template < class T > -bool operator <= ( const ptr_tuple < T > & first, const ptr_tuple < T > & second ) { +template < class ... Ts > +bool operator <= ( const ptr_tuple < Ts ... > & first, const ptr_tuple < Ts ... > & second ) { return ! ( first > second ); } @@ -401,8 +402,8 @@ bool operator <= ( const ptr_tuple < T > & first, const ptr_tuple < T > & second * * \return true if the first value is bigger or equal to the second, false othervise */ -template < class T > -bool operator >= ( const ptr_tuple < T > & first, const ptr_tuple < T > & second ) { +template < class ... Ts > +bool operator >= ( const ptr_tuple < Ts ... > & first, const ptr_tuple < Ts ... > & second ) { return ! ( first < second ); } @@ -472,7 +473,7 @@ namespace ext { * * \result pointer tuple containing values from arguments */ -template<typename... _Elements> +template < typename... _Elements > constexpr ptr_tuple < typename std::__decay_and_strip < _Elements >::__type... > make_ptr_tuple ( _Elements && ... __args ) { typedef ptr_tuple < typename std::__decay_and_strip < _Elements >::__type... > __result_type; return __result_type ( std::forward < _Elements > ( __args ) ... ); @@ -505,53 +506,6 @@ struct tuple_element < I, ext::ptr_tuple < Types... > > { typedef typename std::tuple_element < I, std::tuple < Types ... > >::type type; }; -template < class Result, unsigned I, class ... Types > -struct call_on_nth_helper < Result, I, ext::ptr_tuple < Types ... > > { - template < class Tuple, class Callable > - static Result call_on_nth_fn ( Tuple && t, unsigned index, Callable callback ) { - if ( index == 0 ) - return callback ( std::get < ext::tuple_size < Tuple >::value - I > ( std::forward < Tuple && > ( t ) ) ); - else - return call_on_nth_helper < Result, I - 1, ext::ptr_tuple < Types ... > >::call_on_nth_fn ( std::forward < Tuple && > ( t ), index - 1, callback ); - } -}; - -template < class Result, class ... Types > -struct call_on_nth_helper < Result, 0, ext::ptr_tuple < Types ... > > { - template < class Tuple, class Callable > - static Result call_on_nth_fn ( Tuple &&, unsigned, Callable ) { - throw std::out_of_range ( "Not enough elements in tuple." ); - } -}; - -template < unsigned I, class Callable, class ... Types > -struct foreach_helper < I, ext::ptr_tuple < Types ... >, Callable > { - template < class Tuple > - static void foreach_fn ( Tuple && t, Callable callback ) { - foreach_helper < I - 1, ext::ptr_tuple < Types ... >, Callable >::foreach_fn ( std::forward < Tuple && > ( t ), callback ); - callback ( std::get < I - 1 > ( t ) ); - } -}; - -template < class Callable, class ... Types > -struct foreach_helper < 0, ext::ptr_tuple < Types ... >, Callable > { - template < class Tuple > - static void foreach_fn ( Tuple &&, Callable ) { - } -}; - -template < class Type, int size, class ... Types > -struct PtrTupleBuilder; - -template < class Type, class ... Types > -struct PtrTupleBuilder < Type, 0, Types ... > { - typedef ext::ptr_tuple < Types ... > type; -}; - -template < class Type, int n, class ... Types > -struct PtrTupleBuilder : public PtrTupleBuilder < Type, n - 1, Type, Types ... > { -}; - } /* namespace ext */ #endif /* __PTR_TUPLE_HPP_ */ diff --git a/alib2std/src/extensions/tuple.hpp b/alib2std/src/extensions/tuple.hpp index 77d8fca14131013d2afdf0c43243df36f14b064c..6ba76b7d6e090fa21b92cf41667e7af46c6b102c 100644 --- a/alib2std/src/extensions/tuple.hpp +++ b/alib2std/src/extensions/tuple.hpp @@ -8,13 +8,14 @@ #ifndef __TUPLE_HPP_ #define __TUPLE_HPP_ -#include <tuple> #include <ostream> #include <sstream> #include <string> #include "compare.hpp" +#include "common/tuple_common.hpp" + namespace ext { template < typename ... Ts > @@ -33,6 +34,21 @@ public: tuple & operator = ( const tuple & other ) = default; #endif + + template < std::size_t I > + auto & get ( ) & { + return std::get < I > ( * this ); + } + + template < std::size_t I > + auto && get ( ) && { + return std::get < I > ( std::move ( * this ) ); + } + + template < std::size_t I > + const auto & get ( ) const & { + return std::get < I > ( * this ); + } }; template<typename... _Elements> @@ -46,118 +62,6 @@ constexpr tuple < _Elements & ... > tie ( _Elements & ... __args ) noexcept { return tuple < _Elements & ... > ( __args ... ); } -template < class ... Types > -class tuple_size; - -template < class ... Types > -class tuple_size < ext::tuple < Types ... > > : public std::integral_constant < std::size_t, sizeof...( Types ) > { }; - -template < class T > -class tuple_size < T & > : public std::integral_constant < std::size_t, ext::tuple_size < T >::value > { }; - -template < class T > -class tuple_size < T && > : public std::integral_constant < std::size_t, ext::tuple_size < T >::value > { }; - -template < class T > -class tuple_size < const T > : public std::integral_constant < std::size_t, ext::tuple_size < T >::value > { }; - -template < class T > -class tuple_size< volatile T > : public std::integral_constant < std::size_t, ext::tuple_size < T >::value > { }; - -template< class T > -class tuple_size < const volatile T > : public std::integral_constant < std::size_t, tuple_size < T >::value > { }; - - -template < std::size_t I, class T > -struct tuple_element; - -template < std::size_t I, class... Types > -struct tuple_element < I, ext::tuple < Types... > > { - typedef typename std::tuple_element < I, std::tuple < Types ... > >::type type; -}; - -template < std::size_t I, class T > -struct tuple_element < I, const T > { - typedef typename std::add_const < typename ext::tuple_element < I, T >::type >::type type; -}; - -template < std::size_t I, class T > -struct tuple_element< I, volatile T > { - typedef typename std::add_volatile < typename ext::tuple_element < I, T >::type >::type type; -}; - -template < std::size_t I, class T > -struct tuple_element < I, const volatile T > { - typedef typename std::add_cv < typename ext::tuple_element < I, T >::type >::type type; -}; - -template < class Result, unsigned I, class Tuple > -struct call_on_nth_helper; - -template < class Result, unsigned I, class ... Types > -struct call_on_nth_helper < Result, I, ext::tuple < Types ... > > { - template < class Tuple, class Callable > - static Result call_on_nth_fn ( Tuple && t, unsigned index, Callable callback ) { - if ( index == 0 ) - return callback ( std::get < ext::tuple_size < Tuple >::value - I > ( std::forward < Tuple && > ( t ) ) ); - else - return call_on_nth_helper < Result, I - 1, ext::tuple < Types ... > >::call_on_nth_fn ( std::forward < Tuple && > ( t ), index - 1, callback ); - } -}; - -template < class Result, class ... Types > -struct call_on_nth_helper < Result, 0, ext::tuple < Types ... > > { - template < class Tuple, class Callable > - static Result call_on_nth_fn ( Tuple &&, unsigned, Callable ) { - throw std::out_of_range ( "Not enough elements in tuple." ); - } -}; - -template < class Result, class Tuple, class Callable > -Result call_on_nth ( Tuple && t, unsigned index, Callable callback ) { - return call_on_nth_helper < Result, ext::tuple_size < Tuple >::value, typename std::decay < Tuple >::type >::call_on_nth_fn ( std::forward < Tuple && > ( t ), index, callback ); -} - - - -template < unsigned I, class Tuple, class Callable > -struct foreach_helper; - -template < unsigned I, class Callable, class ... Types > -struct foreach_helper < I, ext::tuple < Types ... >, Callable > { - template < class Tuple > - static void foreach_fn ( Tuple && t, Callable callback ) { - foreach_helper < I - 1, ext::tuple < Types ... >, Callable >::foreach_fn ( std::forward < Tuple && > ( t ), callback ); - callback ( std::get < I - 1 > ( t ) ); - } -}; - -template < class Callable, class ... Types > -struct foreach_helper < 0, ext::tuple < Types ... >, Callable > { - template < class Tuple > - static void foreach_fn ( Tuple &&, Callable ) { - } -}; - -template < class Tuple, class Callable > -void foreach ( Tuple && t, Callable callback ) { - return foreach_helper < ext::tuple_size < Tuple >::value, typename std::decay < Tuple >::type, Callable >::foreach_fn ( std::forward < Tuple && > ( t ), callback ); -} - - - -template < class Tuple, class Callable > -bool all_of ( const Tuple & t, Callable callback ) { - bool res = true; - - auto aggregateCallback = [ & ] ( const auto & arg0 ) { - res &= callback ( arg0 ); - }; - - ext::foreach ( t, aggregateCallback ); - return res; -} - template< class... Ts> std::ostream& operator<<(std::ostream& out, const ext::tuple<Ts...>& tuple) { out << "("; @@ -177,35 +81,10 @@ std::ostream& operator<<(std::ostream& out, const ext::tuple<Ts...>& tuple) { return out; } -template < int I, typename Tuple > -struct compareTupleHelper; - -template < int I, typename Tuple > -struct compareTupleHelper { - static int compHelp ( const Tuple & t1, const Tuple & t2 ) { - int res = compareTupleHelper < I - 1, Tuple >::compHelp ( t1, t2 ); - - if ( res != 0 ) return res; - - static compare < typename std::decay < typename ext::tuple_element < I, Tuple >::type >::type > comp; - return comp ( std::get < I > ( t1 ), std::get < I > ( t2 ) ); - } - -}; - -template < class Tuple > -struct compareTupleHelper < 0, Tuple > { - static int compHelp ( const Tuple & t1, const Tuple & t2 ) { - static compare < typename std::decay < typename ext::tuple_element < 0, Tuple >::type >::type > comp; - return comp ( std::get < 0 > ( t1 ), std::get < 0 > ( t2 ) ); - } - -}; - template < typename ... Ts > struct compare < ext::tuple < Ts ... > > { int operator ()( const ext::tuple < Ts ... > & first, const ext::tuple < Ts ... > & second ) const { - return compareTupleHelper < ext::tuple_size < ext::tuple < Ts ... > >::value - 1, ext::tuple < Ts ... > >::compHelp ( first, second ); + return compareTupleHelper < ext::tuple_size < ext::tuple < Ts ... > >::value - 1 >::compHelp ( first, second ); } }; @@ -217,16 +96,12 @@ std::string to_string ( const ext::tuple < Ts ... > & value ) { return ss.str(); } -template < class Type, int size, class ... Types > -struct TupleBuilder; - -template < class Type, class ... Types > -struct TupleBuilder < Type, 0, Types ... > { - typedef ext::tuple < Types ... > type; -}; +template < class ... Types > +class tuple_size < ext::tuple < Types ... > > : public std::integral_constant < std::size_t, sizeof...( Types ) > { }; -template < class Type, int n, class ... Types > -struct TupleBuilder : public TupleBuilder < Type, n - 1, Type, Types ... > { +template < std::size_t I, class... Types > +struct tuple_element < I, ext::tuple < Types... > > { + typedef typename std::tuple_element < I, std::tuple < Types ... > >::type type; }; } /* namespace ext */ diff --git a/alib2std/test-src/extensions/PtrTupleTest.cpp b/alib2std/test-src/extensions/PtrTupleTest.cpp index 593c13861f4ad88324f2f7014a9694a7bb01aeca..3b1e6ffd8e9f615e51b54166c32770c6589d76d5 100644 --- a/alib2std/test-src/extensions/PtrTupleTest.cpp +++ b/alib2std/test-src/extensions/PtrTupleTest.cpp @@ -20,5 +20,7 @@ void PtrTupleTest::testCallOnNth() { ss << t; std::cout << ss.str ( ) << std::endl; CPPUNIT_ASSERT ( ss.str ( ) == "(1, 2, 3, 4, 5)" ); + + CPPUNIT_ASSERT ( t == t ); }