#ifndef s11n_net_s11n_1_1_FUNCTIONAL_HPP_INCLUDED #define s11n_net_s11n_1_1_FUNCTIONAL_HPP_INCLUDED 1 // Experimental code for s11n, with an emphasis on the "mental" part. // Here be beg, borrow, and steal many ideas from metatemplate and // functional libraries, like Boost.MPL. #include namespace s11n { /** Holds a [const] reference to an object. For use in template metaprogramming. Don't use this type directly: it is intended to be subclassed by reference_f<> types. T must not be pointer-qualified. Const is fine. Added in 1.1.3. Note to self: what happens if it is a pointer type? */ template struct reference_base_f { typedef T type; type & value; explicit reference_base_f( type & _ref ) : value(_ref) {} /** Returns a copy of the object this one refers to. */ inline operator T() const { return this->value; } /** Returns a [const] reference to the object this one refers to. */ inline type & operator()() const { return this->value; } }; /** Holds a reference to an object. For use in template metaprogramming. Added in 1.1.3. */ template struct reference_f : reference_base_f { typedef typename reference_base_f::type type; explicit reference_f( type & _ref ) : reference_base_f(_ref) {} template inline const reference_f & operator=( const X & val ) const { this->value = val; return *this; } }; /** Holds a const reference to an object. For use in template metaprogramming. Added in 1.1.3. */ template struct reference_f : reference_base_f { typedef typename reference_base_f::type type; explicit reference_f( type & _ref ) : reference_base_f(_ref) {} }; /** Added in 1.1.3. */ template struct reference_f : reference_base_f { /** _ref must not be 0. */ typedef typename reference_base_f::type type; explicit reference_f( type * _ref ) : reference_base_f(*_ref) {} }; /** Added in 1.1.3. */ template struct reference_f : reference_base_f { /** _ref must not be 0. */ typedef typename reference_base_f::type type; explicit reference_f( type * _ref ) : reference_base_f(*_ref) {} }; /** Convenience function to return reference_f(ref). Added in 1.1.3. */ template inline reference_f ref( T & ref ) { return reference_f(ref); } /** Pointer equivalent of reference_base_f. Added in 1.1.3. T may be const or not, but should not have a pointer qualification. Specializations of pointer_f take care of getting rid of the extra const/pointer/reference qualifiers. */ template struct pointer_base_f { /** Same as T, possibly const-qualified. */ typedef T type; type * value; explicit pointer_base_f( type * _ref ) : value(_ref) {} explicit pointer_base_f( type & _ref ) : value(&_ref) {} /** Returns a [const] pointer to the object this one refers to. */ inline type * operator()() const { return this->value; } /** For convention's sake... */ inline type * get() const { return this->value; } inline type * operator->() const { return this->value; } inline bool empty() const { return 0 != this->value; } }; /** Pointer equivalent of reference_f. Added in 1.1.3. */ template struct pointer_f : pointer_base_f { typedef typename pointer_base_f::type type; explicit pointer_f( type & _ref ) : pointer_base_f(&_ref) {} explicit pointer_f( type * _ref ) : pointer_base_f(_ref) {} }; /** Pointer equivalent of reference_f. Added in 1.1.3. */ template struct pointer_f : pointer_base_f { typedef typename pointer_base_f::type type; explicit pointer_f( type & _ref ) : pointer_base_f(&_ref) {} explicit pointer_f( type * _ref ) : pointer_base_f(_ref) {} }; /** Pointer equivalent of reference_f. Added in 1.1.3. */ template struct pointer_f : pointer_base_f { typedef typename pointer_base_f::type type; explicit pointer_f( type * _ref ) : pointer_base_f(_ref) {} explicit pointer_f( type & _ref ) : pointer_base_f(&_ref) {} }; /** Pointer equivalent of reference_f. Added in 1.1.3. */ template struct pointer_f : pointer_base_f { typedef typename pointer_base_f::type type; explicit pointer_f( type * _ref ) : pointer_base_f(_ref) {} explicit pointer_f( type & _ref ) : pointer_base_f(&_ref) {} }; // /** Returns pointer_f(v). */ // template // inline pointer_f pointer( typename type_traits::type & v ) // { // return pointer_f(v); // } // template // inline pointer_f pointer( typename type_traits::type * v ) // { // return pointer_f(v); // } // template // inline pointer_f pointer( typename type_traits::type const & v ) // { // return pointer_f(v); // } // template // inline pointer_f pointer( typename type_traits::type const * v ) // { // return pointer_f(v); // } /** Holds a value. For use in template metaprogramming. Added in 1.1.3. */ template struct value_f { typedef T type; type value; value_f( type const & _ref ) : value(_ref) {} /** Returns a copy of this->value. */ inline operator T() const { return this->value; } /** Returns a copy of this->value. */ inline type operator()() const { return this->value; } }; /** Quasi-bogus specialization. */ template struct value_f : value_f {}; /** Quasi-bogus specialization. */ template struct value_f : value_f {}; /** Quasi-bogus specialization. */ template struct value_f : value_f {}; /** Returns value_f(v). */ template inline value_f val( const T & v ) { return value_f(v); } /** A functor which simply forwards its arguments to s11n::serialize(). Added in 1.1.3. */ struct serialize_f : serialize_binary_f_tag { template inline bool operator()( NT & dest, const ST & src ) const { return serialize( dest, src ); } }; /** A functor which simply forwards its arguments to s11n::deserialize(). Added in 1.1.3. */ struct deserialize_f : deserialize_binary_f_tag { template inline bool operator()( const NT & src, ST & dest ) const { return deserialize( src, dest ); } }; /** Conforms to serialize_nullary_f_tag expectations and converts a serialize_binary_f_tag type to serialize_nullary_f_tag type. BinaryFunctorT must comply to serialize_binary_f_tag's expectations. Under NO circumstances may you pass TEMPORARY as a SerializableT argument to one of the ctors. This is strictly illegal, as we hold a reference to the object. Added in 1.1.3. */ template struct serialize_nullary_f : serialize_nullary_f_tag { reference_f node; reference_f serializable; BinaryFunctorT functor; serialize_nullary_f( NodeType & n, SerializableT const & s ) : node(n), serializable(s), functor() { } serialize_nullary_f( NodeType & n, SerializableT const & s, BinaryFunctorT const & f ): node(n), serializable(s), functor(f) { } /** Returns this->functor( this->node, this->serializable ). */ inline bool operator()() const { return this->functor( this->node(), this->serializable() ); } }; /** Returns serialize_nullary_f( n, s, f ). */ template inline serialize_nullary_f ser_nullary_f( NodeType & n, SerializableT const & s, BinaryFunctorT const & f ) { return serialize_nullary_f( n, s, f ); } /** Returns serialize_nullary_f( n, s ). */ template inline serialize_nullary_f ser_nullary_f( NodeType & n, SerializableT const & s ) { return serialize_nullary_f( n, s ); } /** Converts an S-Node to a unary functor taking a Serializable argument. BinaryFunctorT must comply to serialize_binary_f_tag. */ template struct node_to_serialize_unary_f : serialize_unary_serializable_f_tag { //typedef NodeType type; reference_f node; BinaryFunctorT functor; node_to_serialize_unary_f( NodeType & n ) : node(n), functor() {} node_to_serialize_unary_f( NodeType & n, BinaryFunctorT const & f ) : node(n), functor(f) {} template inline bool operator()( const SerT & src ) const { return this->functor( this->node(), src ); } }; /** Returns node_to_serialize_unary_f(n,f). */ template node_to_serialize_unary_f node_to_ser_unary_f( NodeType & n, BinaryFunctorT f ) { return node_to_serialize_unary_f(n,f); } /** Returns node_to_serialize_unary_f(n). */ template node_to_serialize_unary_f node_to_ser_unary_f( NodeType & n ) { return node_to_serialize_unary_f(n); } /** Converts an S-Node to a unary functor taking a Serializable argument. BinaryFunctorT must comply to deserialize_binary_f_tag. */ template struct node_to_deserialize_unary_f : deserialize_unary_serializable_f_tag { //typedef NodeType type; reference_f node; BinaryFunctorT functor; node_to_deserialize_unary_f( NodeType const & n ) : node(n), functor() {} node_to_deserialize_unary_f( NodeType const & n, BinaryFunctorT const & f ) : node(n), functor(f) {} template inline bool operator()( SerT & dest ) const { return this->functor( this->node(), dest ); } }; /** Returns node_to_deserialize_unary_f(n,f). */ template node_to_deserialize_unary_f node_to_deser_unary_f( NodeType const & n, BinaryFunctorT const & f ) { return node_to_deserialize_unary_f(n,f); } /** Returns node_to_deserialize_unary_f(n). */ template inline node_to_deserialize_unary_f node_to_deser_unary_f( NodeType const & n ) { return node_to_deserialize_unary_f(n); } /** Converts a Serializable to a type compliant with serialize_unary_node_f_tag. BinaryFunctorT must comply to serialize_binary_f_tag. Added in 1.1.3. */ template struct serializable_to_serialize_unary_f : serialize_unary_node_f_tag { typedef SerT type; reference_f serializable; BinaryFunctorT functor; serializable_to_serialize_unary_f( SerT const & n ) : serializable(n), functor() {} serializable_to_serialize_unary_f( SerT const & n, BinaryFunctorT const & f ) : serializable(n), functor(f) {} template inline bool operator()( NodeT & dest ) const { return this->functor( dest, this->serializable() ); } }; /** Returns serializable_to_serialize_unary_f( s, f ). */ template inline serializable_to_serialize_unary_f ser_to_ser_unary_f( SerT const & s, BinaryFunctorT const & f ) { return serializable_to_serialize_unary_f( s, f ); } /** Returns serializable_to_serialize_unary_f( s ). */ template inline serializable_to_serialize_unary_f ser_to_ser_unary_f( SerT const & s) { return serializable_to_serialize_unary_f( s ); } /** Converts a Serializable to a type compliant with deserialize_unary_node_f_tag. BinaryFunctorT must comply to deserialize_binary_f_tag. Added in 1.1.3. */ template struct serializable_to_deserialize_unary_f : deserialize_unary_node_f_tag { typedef SerT type; reference_f serializable; BinaryFunctorT functor; serializable_to_deserialize_unary_f( SerT & n ) : serializable(n), functor() {} serializable_to_deserialize_unary_f( SerT & n, BinaryFunctorT const & f ) : serializable(n), functor(f) {} template inline bool operator()( NodeT const & src ) const { return this->functor( src, this->serializable() ); } }; /** Returns serializable_to_deserialize_unary_f( s, f ). */ template inline serializable_to_deserialize_unary_f ser_to_deser_unary_f( SerT & s, BinaryFunctorT const & f ) { return serializable_to_deserialize_unary_f( s, f ); } /** Returns serializable_to_deserialize_unary_f( s ). */ template inline serializable_to_deserialize_unary_f ser_to_deser_unary_f( SerT const & s) { return serializable_to_deserialize_unary_f( s ); } /** Conforms to deserialize_nullary_f_tag expectations and converts a deserialize_binary_f_tag type to deserialize_nullary_f_tag type. BinaryFunctorT must comply to deserialize_binary_f_tag's expectations. Under NO circumstances may you pass TEMPORARY as a NodeType argument to one of the ctors. This is strictly illegal, as we hold a reference to the object. Added in 1.1.3. */ template struct deserialize_nullary_f : deserialize_nullary_f_tag { reference_f node; reference_f serializable; BinaryFunctorT functor; deserialize_nullary_f( NodeType const & n, DeserializableT & s ) : node(n), serializable(s), functor() { } deserialize_nullary_f( NodeType const & n, DeserializableT & s, BinaryFunctorT const & f ) : node(n), serializable(s), functor(f) { } /** Returns this->functor( this->node, this->serializable ). */ inline bool operator()() const { return this->functor( this->node(), this->serializable() ); } }; /** Returns deserialize_nullary_f( n, s, f ). */ template inline deserialize_nullary_f deser_nullary_f( NodeType const & n, DeserializableT & s, BinaryFunctorT const & f ) { return deserialize_nullary_f( n, s, f ); } /** Returns deserialize_nullary_f( n, s ); */ template inline deserialize_nullary_f deser_nullary_f( NodeType const & n, DeserializableT & s ) { return deserialize_nullary_f( n, s ); } /** Experimental. Added in 1.1.3. A Serializable functor intended for some metaprogramming experimentation, to allow lazy s11n of a Serializable. BinaryFunctorT requires this signature: bool operator()( NodeType & dest, const SerializableT & src ) */ template struct serializable_f : serialize_unary_node_f_tag { typedef SerializableT const type; reference_f reference; BinaryFunctorT functor; /** Sets this->reference(_ref). */ explicit serializable_f( type & _ref ) : reference(_ref), functor() { } serializable_f( type & _ref, BinaryFunctorT f ) : reference(_ref), functor(f) { } /** Returns serialize( dest, this->ref ). Calling after this->ref has been destroyed yields undefined behaviour. */ template inline bool operator()( NodeType & dest ) const { return this->functor( dest, this->reference() ); } /** Retyurns a const reference to this object's referenced Serializable. */ inline type & operator()() const { return this->reference(); } }; /** Experimental. Added in 1.1.3. Returns serializable_f( ref ). ref must outlive the object returned by this function! */ template inline serializable_f ser_f( SerializableT const & ref ) { return serializable_f( ref ); } /** Experimental. Added in 1.1.3. Returns serializable_f( ref, f ). ref must outlive the object returned by this function! */ template inline serializable_f ser_f( SerializableT const & ref, BinaryFunctorT f ) { return serializable_f( ref, f ); } /** Experimental. Added in 1.1.3. A Serializable functor intended for some metaprogramming experimentation, to allow lazy de-s11n of a Serializable. BinaryFunctorT requires this signature: bool operator()( const NodeType & src, SerializableT & dest ) */ template struct deserializable_f : deserialize_unary_node_f_tag { //typedef deserializable_f type; typedef DeserializableT type; reference_f reference; BinaryFunctorT functor; /** Sets this->ref = _ref. */ explicit deserializable_f( type & _ref ) : reference(_ref),functor() { } deserializable_f( type & _ref, BinaryFunctorT f ) : reference(_ref),functor(f) { } /** Returns deserialize( src, this->ref ). Calling after this->ref has been destroyed yields undefined behaviour. */ template inline bool operator()( const NodeType & src ) const { return this->functor( src, this->reference() ); } /** Retyurns a reference to this object's referenced Serializable. */ inline type & operator()() const { return this->reference(); } }; /** Added in 1.1.3. Returns deserializable_f( ref ). ref must outlive the object returned by this function! */ template inline deserializable_f deser_f( DeserializableT & ref ) { return deserializable_f( ref ); } /** Added in 1.1.3. Returns deserializable_f( ref, f ). ref must outlive the object returned by this function! */ template inline deserializable_f deser_f( DeserializableT & ref, BinaryFunctorT f ) { return deserializable_f( ref, f ); } /** A functor to allow us to easily walk a list of S-Nodes and deserialize each one into a target container. The optional BinaryFunctorT defines the functor to use to deserialize each object. The default simply routes through the s11n::deserialize() API. SerializableType is unforuntately required: we can't derive it from the output iterator. SerializableType MAY NOT yet be pointer-qualified. That's on the to-fix list somewhere. It would inherently cause a leak or be very incorrect in some uses, though, like using an ostream_iterator(). It could be made to function, but would not be leak-proof. Also, we create and copy SerializableTypes here, so that type should be cheap to do that with. BinaryFunctorT must conform to the interface defined by deserialize_f. Example, assuming NTR is a node_traits type:
	   std::for_each( NTR::children(node).begin(),
		          NTR::children(node).end(),
		          deser_to_outiter_f( std::back_inserter(myvector) ) );
	   
*/ template struct deserialize_to_output_iter_f { // typedef deserialize_to_output_iter_f type; typedef OutIterator type; type iterator; BinaryFunctorT functor; typedef SerializableType serializable_type; // typedef typename std::iterator_traits::value_type serializable_type; // ^^^ why is this void? /** Sets this object's output iterator. */ explicit deserialize_to_output_iter_f( type target ) : iterator(target), functor() {} /** Sets this object's output iterator and copies the given functor. */ deserialize_to_output_iter_f( type target, BinaryFunctorT f ) : iterator(target), functor(f) {} /** Creates a new object of serializable_type and deserializes it. On success iterator is assigned and incremented and true is returned. On error false is returned or an exception is propagated. If src is (!src), false is returned. Note that the odd pointerness of the argument is because node children lists contain pointers and are const in a deserialize context. */ template bool operator()( NodeType * const & src ) { if( src ) { serializable_type dest; if( this->functor( *src, dest ) ) { *(iterator++) = dest; return true; } } return false; } }; /** Convenience function returning: deserialize_to_output_iter_f( target, f ) */ template inline deserialize_to_output_iter_f deser_to_outiter_f( OutIterator target, BinaryFunctorT f ) { return deserialize_to_output_iter_f( target, f ); } /** Convenience function returning: deserialize_to_output_iter_f( target ) */ template inline deserialize_to_output_iter_f deser_to_outiter_f( OutIterator target ) { return deserialize_to_output_iter_f( target ); } /** Experimental. Added in 1.1.3. BinaryFunctorT must have: bool operator()( NodeType & dest, const SerializableT & src ) */ template struct serialize_to_subnode_f : serialize_binary_f_tag { //typedef serialize_to_subnode_f type; std::string name; BinaryFunctorT functor; /** */ serialize_to_subnode_f( const std::string & subnodename, BinaryFunctorT f ) : name(subnodename),functor(f) { } /** */ explicit serialize_to_subnode_f( const std::string & subnodename ) : name(subnodename),functor() { } /** Creates a NodeType names this->name and calls this->functor( child, src ). If the functor fails, the child is deleted and dest is unmodified, else ownership of the child is transfered to dest, via node_traits::children(dest).push_back(child). Returns true on success, false on failure. */ template inline bool operator()( NodeType & dest, SerializableT const & src ) const { typedef node_traits NTR; std::auto_ptr nap( NTR::create( this->name ) ); return this->functor( *nap, src ) ? (NTR::children(dest).push_back( nap.release() ),true) : false; } }; /** Returns serialize_to_subnode_f<>( subnodename ). Added in 1.1.3. */ inline serialize_to_subnode_f<> ser_to_subnode_f( const std::string & subnodename ) { return serialize_to_subnode_f<>( subnodename ); } /** Returns serialize_to_subnode_f( subnodename, f ). Added in 1.1.3. */ template inline serialize_to_subnode_f ser_to_subnode_f( const std::string & subnodename, BinaryFunctorT f ) { return serialize_to_subnode_f( subnodename, f ); } /** Experimental. Added in 1.1.3. BinaryFunctorT must have: bool operator()( NodeType & dest, const SerializableT & src ) */ template struct serialize_to_subnode_unary_f : serialize_unary_serializable_f_tag { //typedef serialize_to_subnode_unary_f type; reference_f node; std::string name; BinaryFunctorT functor; /** */ serialize_to_subnode_unary_f( NodeType & parent, const std::string & subnodename ) : node(parent), name(subnodename),functor() { } /** */ serialize_to_subnode_unary_f( NodeType & parent, const std::string & subnodename, BinaryFunctorT f ) : node(parent), name(subnodename),functor(f) { } /** Creates a NodeType named this->name and calls this->functor( child, src ). If the functor fails, the child is deleted and dest is unmodified, else ownership of the child is transfered to dest, via node_traits::children(this->node()).push_back(child). Returns true on success, false on failure. */ template bool operator()( SerializableT const & src ) const { typedef node_traits NTR; std::auto_ptr nap( NTR::create( this->name ) ); if( this->functor( *nap, src ) ) { NTR::children(this->node()).push_back( nap.release() ); } return 0 == nap.get(); } }; /** Returns serialize_to_subnode_f( parent, subnodename ). Example:
	   std::for_each( vec.begin(),
		          vec.end(),
		          ser_to_subnode_unary_f( mynode, "child" )
		        );
	   
Added in 1.1.3. */ template inline serialize_to_subnode_unary_f ser_to_subnode_unary_f( NodeType & parent, const std::string & subnodename ) { return serialize_to_subnode_unary_f( parent, subnodename ); } /** Returns serialize_to_subnode_unary_f( parent, subnodename, f ). Example:
	   std::for_each( vec.begin(),
		       vec.end(),
		       ser_to_subnode_f( mynode, "child", my_serialize_to_subnode_unary_functor() )
		       );
	   
Added in 1.1.3. */ template inline serialize_to_subnode_unary_f ser_to_subnode_unary_f( NodeType & parent, const std::string & subnodename, BinaryFunctorT f ) { return serialize_to_subnode_unary_f( parent, subnodename, f ); } /** BinaryFunctorT requires this signature: bool operator()( const NodeType & src, const std::string & subnodename, SerializableT & dest ) Added in 1.1.3. */ template struct deserialize_from_subnode_f : deserialize_binary_f_tag { //typedef deserialize_from_subnode_f type; std::string name; BinaryFunctorT functor; deserialize_from_subnode_f( const std::string & subnodename ) : name(subnodename),functor() { } deserialize_from_subnode_f( const std::string & subnodename, BinaryFunctorT f ) : name(subnodename),functor(f) { } /** Searches for the first child in src named this->name. If it succeeds, it returns the result of this->functor( child, dest ), else it returns false. */ template inline bool operator()( NodeType const & src, SerializableT & dest ) const { const NodeType * ch = ::s11n::find_child_by_name( src, this->name ); return ch ? this->functor( *ch, dest ) : false; } }; /** Returns deserialize_from_subnode_f<>( parent, subnodename ). Added in 1.1.3. */ inline deserialize_from_subnode_f<> deser_from_subnode_f( const std::string & subnodename ) { return deserialize_from_subnode_f<>( subnodename ); } /** Returns deserialize_from_subnode_f( parent, subnodename, f ). Added in 1.1.3. */ template inline deserialize_from_subnode_f deser_from_subnode_f( const std::string & subnodename, BinaryFunctorT f ) { return deserialize_from_subnode_f( subnodename, f ); } /** BinaryFunctorT requires this signature: bool operator()( const NodeType & src, const std::string & subnodename, SerializableT & dest ) Added in 1.1.3. */ template struct deserialize_from_subnode_unary_f : deserialize_unary_serializable_f_tag { //typedef deserialize_from_subnode_unary_f type; reference_f node; std::string name; BinaryFunctorT functor; deserialize_from_subnode_unary_f( const NodeType & parent, const std::string & subnodename ) : node(parent), name(subnodename),functor() { } deserialize_from_subnode_unary_f( const NodeType & parent, const std::string & subnodename, BinaryFunctorT f ) : node(parent), name(subnodename),functor(f) { } /** Searches for the first child in this->node() named this->name. If it succeeds, it returns the result of this->functor( child, dest ), else it returns false. */ template inline bool operator()( SerializableT & dest ) const { const NodeType * ch = ::s11n::find_child_by_name( this->node(), this->name ); return ch ? this->functor( *ch, dest ) : false; } }; /** Returns deserialize_from_subnode_unary_f( parent, subnodename ). Added in 1.1.3. */ template inline deserialize_from_subnode_unary_f deser_from_subnode_unary_f( const NodeType & parent, const std::string & subnodename ) { return deserialize_from_subnode_unary_f( parent, subnodename ); } /** Experimental. Added in 1.1.3. Returns deserialize_from_subnode_unary_f( parent, subnodename, f ). */ template inline deserialize_from_subnode_unary_f deser_from_subnode_unary_f( const NodeType & parent, const std::string & subnodename, BinaryFunctorT f ) { return deserialize_from_subnode_unary_f( parent, subnodename, f ); } /** Functor implementing AND logic and between two functors, which are expected to return values convertable to bool. */ struct logical_and_binary_f { template inline bool operator()( F1 const & f1, F2 const & f2 ) const { return f1() && f2(); } }; /** Functor implementing AND logic and between two functors, which are expected to return values convertable to bool. */ template struct logical_and_unary_f { F1 functor; logical_and_unary_f( F1 const & f ) : functor(f) {} template inline bool operator()( F2 const & f2 ) const { return this->functor() && f2(); } }; /** Functor implementing AND logic and between two functors, which are expected to return values convertable to bool. */ template struct logical_and_nullary_f { F1 functor1; F2 functor2; logical_and_nullary_f( F1 const & f1, F2 const & f2 ) : functor1(f1), functor2(f2) {} inline bool operator()() const { return this->functor1() && this->functor2(); } }; /** Returns logical_and_nullary(f1,f2). */ template inline logical_and_nullary_f logical_and( F1 const & f1, F2 const & f2 ) { return logical_and_nullary_f(f1,f2); } /** Returns logical_and_unary(f1). */ template inline logical_and_unary_f logical_and( F1 const & f1 ) { return logical_and_unary_f(f1); } /** Returns logical_and_binary(). */ inline logical_and_binary_f logical_and() { return logical_and_binary_f(); } } // namespace s11n #endif // s11n_net_s11n_1_1_FUNCTIONAL_HPP_INCLUDED