// Copyright (C) 2011 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #undef DLIB_AnY_FUNCTION_ABSTRACT_H_ #ifdef DLIB_AnY_FUNCTION_ABSTRACT_H_ #include "any_abstract.h" #include "../algs.h" namespace dlib { // ---------------------------------------------------------------------------------------- template < class Storage, typename function_type > class any_function_basic { /*! REQUIREMENTS ON Storage This must be one of the storage types from dlib/any/storage.hh E.g. storage_heap, storage_stack, etc. It determines the method by which any_function_basic holds onto the function it uses. REQUIREMENTS ON function_type This type should be a function signature. Some examples are: void (int,int) // a function returning nothing and taking two ints void () // a function returning nothing and taking no arguments char (double&) // a function returning a char and taking a reference to a double The number of arguments in the function must be no greater than 10. INITIAL VALUE - is_empty() == true - for all T: contains<T>() == false WHAT THIS OBJECT REPRESENTS This object is a version of dlib::any that is restricted to containing elements which are some kind of function object with an operator() which matches the function signature defined by function_type. Here is an example: #include <iostream> #include <string> #include "dlib/any.h" void print_message(string str) { cout << str << endl; } int main() { dlib::any_function<void(string)> f; f = print_message; f("hello world"); // calls print_message("hello world") } Note that any_function_basic objects can be used to store general function objects (i.e. defined by a class with an overloaded operator()) in addition to regular global functions. !*/ public: // This is the type of object returned by function_type functions. typedef result_type_for_function_type result_type; any_function_basic( ); /*! ensures - this object is properly initialized !*/ any_function_basic ( const any_function_basic& item ); /*! ensures - copies the state of item into *this. - Note that *this and item will contain independent copies of the contents of item. That is, this function performs a deep copy and therefore does not result in *this containing any kind of reference to item. !*/ any_function_basic ( any_function_basic&& item ); /*! ensures - moves item into *this. - The exact move semantics are determined by which Storage type is used. E.g. storage_heap will result in #item.is_empty()==true but storage_view would result in #item.is_empty() == false !*/ template < typename Funct > any_function_basic ( Funct&& funct ); /*! ensures - #contains<T>() == true - #cast_to<T>() == item (i.e. calling operator() will invoke funct()) !*/ void clear ( ); /*! ensures - #*this will have its default value. I.e. #is_empty() == true !*/ template <typename T> bool contains ( ) const; /*! ensures - if (this object currently contains an object of type T) then - returns true - else - returns false !*/ bool is_empty( ) const; /*! ensures - if (this object contains any kind of object) then - returns false - else - returns true !*/ bool is_set ( ) const; /*! ensures - returns !is_empty() !*/ explicit operator bool( ) const; /*! ensures - returns is_set() !*/ result_type operator(Args... args) ( ) const; /*! requires - is_empty() == false - the signature defined by function_type takes no arguments ensures - Let F denote the function object contained within *this. Then this function performs: return F(std::forward<Args>(args)...) !*/ template <typename T> T& cast_to( ); /*! ensures - if (contains<T>() == true) then - returns a non-const reference to the object contained within *this - else - throws bad_any_cast !*/ template <typename T> const T& cast_to( ) const; /*! ensures - if (contains<T>() == true) then - returns a const reference to the object contained within *this - else - throws bad_any_cast !*/ template <typename T> T& get( ); /*! ensures - #is_empty() == false - #contains<T>() == true - if (contains<T>() == true) - returns a non-const reference to the object contained in *this. - else - Constructs an object of type T inside *this - Any previous object stored in this any_function_basic object is destructed and its state is lost. - returns a non-const reference to the newly created T object. !*/ any_function_basic& operator= ( const any_function_basic& item ); /*! ensures - copies the state of item into *this. - Note that the type of copy is determined by the Storage template argument. E.g. storage_sbo will result in a deep copy, while storage_view would result in *this and item referring to the same underlying function. !*/ void swap ( any_function_basic& item ); /*! ensures - swaps *this and item !*/ }; // ---------------------------------------------------------------------------------------- template < typename T, typename function_type > T& any_cast( any_function_basic<function_type>& a ) { return a.cast_to<T>(); } /*! ensures - returns a.cast_to<T>() !*/ // ---------------------------------------------------------------------------------------- template < typename T, typename function_type > const T& any_cast( const any_function_basic<function_type>& a ) { return a.cast_to<T>(); } /*! ensures - returns a.cast_to<T>() !*/ // ---------------------------------------------------------------------------------------- /*!A any_function A version of any_function_basic (defined above) that owns the function it contains. Uses the small buffer optimization to make working with small lambdas faster. !*/ template <class F> using any_function = any_function_basic<te::storage_sbo<16>, F>; /*!A any_function_view A version of any_function_basic (defined above) that *DOES NOT* own the function it contains. It merely holds a pointer to the function given to its constructor. !*/ template <class F> using any_function_view = any_function_basic<te::storage_view, F>; // ---------------------------------------------------------------------------------------- } #endif // DLIB_AnY_FUNCTION_ABSTRACT_H_