From 27abae9d0190e4a788defd33951dab7955bfec88 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Fri, 26 Oct 2012 00:59:30 -0400 Subject: [PATCH] adding tuple impl --- include/fc/function.hpp | 13 ++-- include/fc/make_fused.hpp | 26 ++++++++ include/fc/tuple.hpp | 130 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 include/fc/make_fused.hpp create mode 100644 include/fc/tuple.hpp diff --git a/include/fc/function.hpp b/include/fc/function.hpp index 190a98b..f06033a 100644 --- a/include/fc/function.hpp +++ b/include/fc/function.hpp @@ -26,7 +26,7 @@ class function { function& operator=( function&& c ) { fc::swap(func,c.func); return *this; } template - R operator()( Args2... args2) { return func->call(fc::forward(args2)...); } + R operator()( Args2... args2)const { return func->call(fc::forward(args2)...); } protected: @@ -78,9 +78,14 @@ template class function : public function { public: function(){} - template - function( U&& u ) { *this = fc::forward(u); } - //using function::operator=; +// template +// function( U&& u ) { static_assert( sizeof(U) < 0, "tesT"); *this = fc::forward(u); } + function( const function& u ):function(u){} + function( function&& u ):function(u){} + function( const function& u ):function(u.func){} + function( function&& u ):function(fc::move(u.func)){} + + using function::operator=; }; template diff --git a/include/fc/make_fused.hpp b/include/fc/make_fused.hpp new file mode 100644 index 0000000..cc82ff8 --- /dev/null +++ b/include/fc/make_fused.hpp @@ -0,0 +1,26 @@ +#pragma once +#include +#include + +namespace fc { + template + fc::function > make_fused( const fc::function& f ) { + return [=]( fc::tuple<> ){ return f(); }; + } + template + fc::function) > make_fused( const fc::function& f ) { + return [f]( fc::tuple t){ return f(t.a); }; + } + template + fc::function) > make_fused( const fc::function& f ) { + return [f]( fc::tuple t){ return f(t.a,t.b); }; + } + template + fc::function) > make_fused( const fc::function& f ) { + return [f]( fc::tuple t){ return f(t.a,t.b,t.c); }; + } + template + fc::function) > make_fused( const fc::function& f ) { + return [f]( fc::tuple t){ return f(t.a,t.b,t.c,t.d); }; + } +} diff --git a/include/fc/tuple.hpp b/include/fc/tuple.hpp new file mode 100644 index 0000000..454aa7d --- /dev/null +++ b/include/fc/tuple.hpp @@ -0,0 +1,130 @@ +#pragma once +#include + +namespace fc { + + /** + * Provides a fast-compiling tuple that doesn't use fancy meta-programming + * techniques. It is limited to 4 parameters which is sufficient for most + * methods argument lists which is the primary use case for this tuple. Methods + * that require more than 4 parameters are probably better served by defining + * a struct. + * + * The members of the tuple are easily visited with a simple visitor functor + * of the form: + * @code + * struct visitor { + * template + * void operator()( MemberType& m ); + * + * template + * void operator()( const MemberType& m ); + * }; + * @endcode + */ + template + struct tuple { + tuple(){} + enum size_enum { size = 4 }; + + template + tuple( AA&& aa, BB&& bb, CC&& cc, DD&& dd ) + :a( fc::forward(aa) ), + b( fc::forward(bb) ), + c( fc::forward(cc) ), + d( fc::forward
(dd) ) + {} + + template + void visit( V&& v ) { v(a); v(b); v(c); v(d); } + template + void visit( V&& v )const { v(a); v(b); v(c); v(d); } + + A a; + B b; + C c; + D d; + }; + + template<> + struct tuple<> { + enum size_enum { size = 0 }; + template + void visit( V&& v)const{}; + }; + + template + struct tuple { + enum size_enum { size = 1 }; + template + tuple( AA&& aa ):a( fc::forward(aa) ){} + tuple( const tuple& t ):a(t.a){} + tuple( tuple&& t ):a(t.a){} + tuple(){} + + template + void visit( V&& v ) { v(a); } + template + void visit( V&& v )const { v(a); } + + A a; + }; + + template + struct tuple { + enum size_enum { size = 2 }; + + template + tuple( AA&& aa, BB&& bb ) + :a( fc::forward(aa) ), + b( fc::forward(bb) ){} + + tuple(){} + + template + void visit( V&& v ) { v(a); v(b); } + template + void visit( V&& v )const { v(a); v(b); } + + A a; + B b; + }; + + template + struct tuple { + enum size_enum { size = 3 }; + tuple(){} + + template + tuple( AA&& aa, BB&& bb, CC&& cc ) + :a( fc::forward(aa) ), + b( fc::forward(bb) ), + c( fc::forward(cc) ) + {} + + template + void visit( V&& v ) { v(a); v(b); v(c); } + template + void visit( V&& v )const { v(a); v(b); v(c); } + + A a; + B b; + C c; + }; + + tuple<> make_tuple(); + + template + tuple make_tuple(A&& a){ return tuple( fc::forward(a) ); } + + template + tuple make_tuple(A&& a, B&& b){ return tuple( fc::forward(a), fc::forward(b) ); } + + template + tuple make_tuple(A&& a, B&& b, C&& c){ return tuple( fc::forward(a), fc::forward(b), fc::forward(c) ); } + + template + tuple make_tuple(A&& a, B&& b, C&& c, D&& d){ + return tuple( fc::forward(a), fc::forward(b), fc::forward(c), fc::forward(d) ); + } +}