From 9205bb97c3a4d6b454660124702eb8426d7f18ea Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Fri, 20 Apr 2018 14:22:34 +0200 Subject: [PATCH] update tuple std extension --- alib2std/src/extensions/tuple.hpp | 81 +++++++++++----------- alib2std/test-src/extensions/TupleTest.cpp | 6 ++ 2 files changed, 48 insertions(+), 39 deletions(-) diff --git a/alib2std/src/extensions/tuple.hpp b/alib2std/src/extensions/tuple.hpp index ee11bca9c7..dd3d748666 100644 --- a/alib2std/src/extensions/tuple.hpp +++ b/alib2std/src/extensions/tuple.hpp @@ -58,6 +58,12 @@ 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 > { }; @@ -94,26 +100,28 @@ struct tuple_element < I, const volatile T > { template < class Result, unsigned I, class Tuple, class Callable > struct call_on_nth_helper; -template < class Result, unsigned I, class Tuple, class Callable > -struct call_on_nth_helper { - static Result call_on_nth_fn ( Tuple & t, unsigned index, Callable callback ) { +template < class Result, unsigned I, class Callable, class ... Types > +struct call_on_nth_helper < Result, I, ext::tuple < Types ... >, Callable > { + template < class Tuple > + 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 > ( t ) ); + return callback ( std::get < ext::tuple_size < Tuple >::value - I > ( std::forward < Tuple && > ( t ) ) ); else - return call_on_nth_helper < Result, I - 1, Tuple, Callable >::call_on_nth_fn ( t, index - 1, callback ); + return call_on_nth_helper < Result, I - 1, ext::tuple < Types ... >, Callable >::call_on_nth_fn ( std::forward < Tuple && > ( t ), index - 1, callback ); } }; -template < class Result, class Tuple, class Callable > -struct call_on_nth_helper < Result, 0, Tuple, Callable > { - static Result call_on_nth_fn ( Tuple &, unsigned, Callable ) { +template < class Result, class Callable, class ... Types > +struct call_on_nth_helper < Result, 0, ext::tuple < Types ... >, Callable > { + template < class Tuple > + 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, Tuple, Callable >::call_on_nth_fn ( t, index, callback ); +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, Callable >::call_on_nth_fn ( std::forward < Tuple && > ( t ), index, callback ); } @@ -121,23 +129,25 @@ Result call_on_nth ( Tuple & t, unsigned index, Callable callback ) { template < unsigned I, class Tuple, class Callable > struct foreach_helper; -template < unsigned I, class Tuple, class Callable > -struct foreach_helper { - static void foreach_fn ( Tuple & t, Callable callback ) { +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 ) ); - foreach_helper < I - 1, Tuple, Callable >::foreach_fn ( t, callback ); } }; -template < class Tuple, class Callable > -struct foreach_helper < 0, Tuple, Callable > { - static void foreach_fn ( Tuple &, Callable ) { +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, Tuple, Callable >::foreach_fn ( t, callback ); +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 ); } @@ -146,7 +156,7 @@ template < class Tuple, class Callable > bool all_of ( const Tuple & t, Callable callback ) { bool res = true; - auto aggregateCallback = [ & ] ( auto & arg0 ) { + auto aggregateCallback = [ & ] ( const auto & arg0 ) { res &= callback ( arg0 ); }; @@ -154,28 +164,21 @@ bool all_of ( const Tuple & t, Callable callback ) { return res; } -template<int I, class Tuple> -struct operator_shift_left_impl; - -template<int I, class Tuple> -struct operator_shift_left_impl { - static void operator_shift_left ( std::ostream& out, const Tuple& t) { - operator_shift_left_impl < I - 1, Tuple>::operator_shift_left ( out, t ); - out << ", " << std::get < I > ( t ); - } -}; - -template<class Tuple> -struct operator_shift_left_impl<0, Tuple> { - static void operator_shift_left ( std::ostream& out, const Tuple& t) { - out << std::get < 0 > ( t ); - } -}; - template< class... Ts> std::ostream& operator<<(std::ostream& out, const ext::tuple<Ts...>& tuple) { out << "("; - ext::operator_shift_left_impl < ext::tuple_size < ext::tuple < Ts ... > >::value - 1, ext::tuple < Ts ... > >::operator_shift_left ( out, tuple ); + + bool first = true; + auto outCallback = [ & ] ( const auto & arg0 ) { + if ( ! first ) { + out << ", "; + } else { + first = false; + } + out << arg0; + }; + + ext::foreach ( tuple, outCallback ); out << ")"; return out; } diff --git a/alib2std/test-src/extensions/TupleTest.cpp b/alib2std/test-src/extensions/TupleTest.cpp index a57e76968d..89c4c83992 100644 --- a/alib2std/test-src/extensions/TupleTest.cpp +++ b/alib2std/test-src/extensions/TupleTest.cpp @@ -1,5 +1,6 @@ #include "TupleTest.h" #include <alib/tuple> +#include <sstream> CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TupleTest, "bits" ); CPPUNIT_TEST_SUITE_REGISTRATION( TupleTest ); @@ -14,5 +15,10 @@ void TupleTest::testCallOnNth() { ext::tuple < int, int, int, int, int > t = ext::make_tuple ( 1, 2, 3, 4, 5 ); CPPUNIT_ASSERT ( ext::call_on_nth < int > ( t, 1, [] ( int i ) { return i; } ) == 2 ); + + std::stringstream ss; + ss << t; + std::cout << ss.str ( ) << std::endl; + CPPUNIT_ASSERT ( ss.str ( ) == "(1, 2, 3, 4, 5)" ); } -- GitLab