diff --git a/doc/callable_traits.qbk b/doc/callable_traits.qbk index 2891ccb..0407a59 100644 --- a/doc/callable_traits.qbk +++ b/doc/callable_traits.qbk @@ -55,7 +55,6 @@ [template concept_simple_invokable[][role green SimpleInvokable]] [template concept_callable[][role green Callable]] [template concept_invokable[][role green Invokable]] -[template concept_bind_expression[][role green BindExpression]] [template concept_signature[][role green Signature]] [template concept_constexpr_constructible[][role green ConstexprDefaultConstructible]] [template concept_cc_tag[][role green CallingConventionTag]] @@ -76,7 +75,6 @@ [template link_simple_invokable[][link callable_traits.glossary.ref_simple_invokable [concept_simple_invokable]]] [template link_callable[][link callable_traits.glossary.ref_callable [concept_callable]]] [template link_invokable[][link callable_traits.glossary.ref_invokable [concept_invokable]]] -[template link_bind_expression[][link callable_traits.glossary.ref_bind_expression [concept_bind_expression]]] [template link_signature[][link callable_traits.glossary.ref_signature [concept_signature]]] [template link_constexpr_constructible[][link callable_traits.glossary.ref_constexpr_constructible [concept_constexpr_constructible]]] [template link_cc_tag[][link callable_traits.glossary.ref_cc_tag [concept_cc_tag]]] @@ -94,7 +92,6 @@ [template link_arg_at[][link callable_traits.ref_arg_at [^arg_at]]] [template link_args[][link callable_traits.ref_args [^args]]] [template link_arity[][link callable_traits.ref_arity [^arity]]] -[template link_bind[][link callable_traits.ref_bind [^bind]]] [template link_is_invokable[][link callable_traits.ref_is_invokable [^is_invokable]]] [template link_is_invokable_constexpr[][link callable_traits.ref_is_invokable_constexpr [^is_invokable_constexpr]]] [template link_clear_args[][link callable_traits.ref_clear_args [^clear_args]]] @@ -185,7 +182,6 @@ This documentation will be most beneficial to readers who posess a basic underst * [@http://en.cppreference.com/w/cpp/language/overloaded_address taking the address of overloaded functions] * [@http://en.cppreference.com/w/c/language/variadic C-style variadics], a.k.a. varargs * [@https://en.wikipedia.org/wiki/X86_calling_conventions calling conventions] -* [@http://en.cppreference.com/w/cpp/utility/functional/bind std::bind expressions] with [@http://en.cppreference.com/w/cpp/utility/functional/placeholders std::placeholders] [endsect][/section:prereqs] @@ -262,12 +258,6 @@ See Also: [link callable_traits.faq.faq_function_types Why not update and extend [ [Windows] [MinGW GCC \[4.8, ~ 5.2.1)] [[partial_support]] [libstdc++] [-] ] ] -[template msvc_disabled_functions[] - - -* [link_bind] -] - CallableTraits has not been tested on every platform under the sun. If you find CallableTraits to work with another toolchain, [link callable_traits.contact let us know!] [section:compatibility_issues Known Issues] @@ -275,9 +265,6 @@ CallableTraits has not been tested on every platform under the sun. If you find * [link_is_constexpr] and [link_is_invokable_constexpr] always `std::false_type` on the following platforms: * MSVC * GCC < 5 -* [link_bind] trips a static_assert on the following platforms: - * MSVC - * GCC < 4.9.2 * [link_min_arity] and [link_max_arity] are equivalent to [link_arity] on the following platforms: * GCC < 4.9.2 * [link_abominable] types are not compatible with some older compilers. Attempts to create [link_abominable] types using [libname] metafunctions will have no effect on the following platforms: @@ -373,7 +360,7 @@ There are real reasons to write code like this, but they are few and far between [*6.] [link_is_constexpr] is used to check whether a [link_constexpr_constructible] type is a [link_callable] type that yields a `constexpr` result -- no arguments necessary. -[*7.] [link_bind] is used to intercept the signature information from a `std::placeholder` expression before forwarding on to `std::bind` or `boost::bind`. This gives library writers the power to create more flexible template APIs for callable types. +[*7] (TODO - fill this in) [*8.] [link_min_arity] can be used to detect the presence of default arguments on a [link_simple_fn_obj] @@ -678,11 +665,6 @@ In order to avoid significant standardese in the reference sections, we need to [endsect] -[section:ref_bind_expression [concept_bind_expression]] -* The return type of a call to [namespace_scoped]`bind` - -[endsect] - [section:ref_constexpr_constructible [concept_constexpr_constructible]] * Any [@http://en.cppreference.com/w/cpp/concept/LiteralType LiteralType] that is also default-constructible @@ -783,7 +765,6 @@ The [libname] interface is also broken down by trait into individual header file * [include_header [link_is_invokable]] * [include_header [link_is_invokable_constexpr]] * [include_header [link_function_type]] -* [include_header [link_bind]] [endsect] @@ -1169,16 +1150,12 @@ For `add_calling_convention` to work as-intended, you must: * `T` must be one of the following: * [link_signature] * [link_simple_fn_obj] - * [link_bind_expression] * When `T` is a [link_signature], then: * Let `ArgCount` represent the number of arguments in the signature of `T` * `Index` must be less than `ArgCount` and greater than zero * Otherwise, when `T` is a [link_simple_fn_obj], then: * Let `ArgCount` represent the number of arguments in `decltype(&std::decay_t::operator())` * `Index` must be less than `ArgCount` and greater than zero -* Otherwise, when `T` is a [link_bind_expression], then: - * Let `MaxPlaceholder` represent the type of the largest `std::placeholders` object in the bind expression tree - * `Index` must be less than `std::is_placeholder::value` and greater than zero [heading Behavior] * If any constraints are violated, a substitution failure occurs @@ -1214,7 +1191,6 @@ For `add_calling_convention` to work as-intended, you must: `T` must be one of the following: * [link_signature] * [link_simple_fn_obj] -* [link_bind_expression] [heading Behavior] * When the constraints are violated, a substitution failure occurs @@ -1224,12 +1200,6 @@ For `add_calling_convention` to work as-intended, you must: * Otherwise, when `T` is a [link_simple_fn_obj], then: * Let `Args...` represent the parameter types in the signature of `decltype(&std::decay_t::operator())` * `args` aliases `std::tuple` -* Otherwise, when `T` is a [link_bind_expression], then: - * Let `bind_args...` represent the argument values that were passed to [namespace]`bind` which returned an instance of `T` - * Let `bind_result` represent the return value of `std::bind(bind_args...)` - * Let `Args...` represent the "valid argument types" to `bind_result`'s `operator()` - * Note: the "valid argument types" are implied by the position of the `std::placeholders` objects - * `args` aliases `std::tuple` [heading Example] [import ../example/args.cpp] @@ -1276,51 +1246,6 @@ For `add_calling_convention` to work as-intended, you must: [arity] [endsect] -[section:ref_bind bind] - -[note [namespace_scoped]`bind` [msvc_incompatible]] - - namespace ``[lib_namespace]`` { - - template - inline ``[^[link_bind_expression]]`` bind(Ts&&... ts); - - } - -[namespace_scoped]`bind` is used to parse type information from potentially complex `std::placeholders` expressions. The type information in [namespace_scoped]`bind` cannot legally/portably be extracted from `std::bind`, because `std::bind`'s implementation is opaque. - -[heading Constraints] -* The arguments to [namespace_scoped]`bind` must be legal arguments to `std::bind`, substituting `std::bind` for [namespace_scoped]`bind` in nested sub-expressions where necessary to meet this constraint -* All nested sub-expressions must be a call to [namespace_scoped]`bind` instead of `std::bind` -* If a call to [namespace_scoped]`bind` passes an [link_overloaded_fn_obj] instance as its first argument, then: - * any placeholder objects passed in this call must be re-used somewhere else in the expression tree, bing passed in another call to [namespace_scoped]`bind` where a [link_simple_callable] as its first argument (otherwise, no inference could be made about the parameter type being "place-held") - -[heading Behavior] -* If any constraints are violated, the result is undefined -* The return type of [namespace_scoped]`bind` can be passed to any of the following: - * [namespace_scoped][^[link_args]] - * [namespace_scoped][^[link_arg_at]] - * [namespace_scoped][^[function_type]] - * [namespace_scoped][^[result_of]] -* For convenience, the object returned by [namespace_scoped]`bind` serves as a wrapper around `std::bind`, forwarding from its `operator()` to a private member object constructed from `std::bind` in the original [namespace_scoped]`bind` - -[heading Notes] -* [namespace_scoped]`bind` is the only feature of [libname] with non-constexpr behavior. However, the runtime behavior is only provided for convenience -- [namespace_scoped]`bind` is designed to be a metaprogramming tool, and may be used in unevaluated contexts. -[heading Example 1] -[import ../example/bind_1.cpp] -[bind_1] -[heading Example 2] -[import ../example/bind_2.cpp] -[bind_2] - -[heading See Also] - * [link_args] - * [link_arg_at] - * [function_type] - * [result_of] - -[endsect] - [section:ref_is_invokable is_invokable] namespace ``[lib_namespace]`` { @@ -1497,7 +1422,6 @@ For `add_calling_convention` to work as-intended, you must: # `T` must be one of the following: * [link_signature] * [link_simple_fn_obj] - * [link_bind_expression] # Let `std::tuple` represent [namespace_scoped][link_args]`` * `Container` must be a legal template instantiation. @@ -1559,12 +1483,6 @@ For `add_calling_convention` to work as-intended, you must: * Let `Args...` represent the parameter types in the signature of `decltype(&std::decay_t::operator())` * Let `Return` represent the return type of `decltype(&std::decay_t::operator())` * `function_type` aliases `Return(Args...)` -*Otherwise, when `T` is a [link_bind_expression], then: - * Let `std::tuple` represent [namespace_scoped][^[link_args]]`` - * Let `bind_args...` represent the argument values that were passed to [namespace]`bind` which returned an instance of `T` - * Let `bind_result` represent the return value of `std::bind(bind_args...)` - * Let `Return` represent `decltype(bind_result(std::declval()...))` - * `function_type` aliases `Return(Args...)` [heading Example] [import ../example/function_type.cpp] @@ -1851,7 +1769,6 @@ TODO [result_of] [endsect] -[include make_function_example.qbk] [include interface_example.qbk] [/*********************************************************************] diff --git a/doc/html/callable_traits/compatibility.html b/doc/html/callable_traits/compatibility.html index 0a35e76..09e5601 100644 --- a/doc/html/callable_traits/compatibility.html +++ b/doc/html/callable_traits/compatibility.html @@ -495,18 +495,6 @@ -
  • - bind - trips a static_assert on the following platforms: -
      -
    • - MSVC -
    • -
    • - GCC < 4.9.2 -
    • -
    -
  • min_arity and max_arity diff --git a/doc/html/callable_traits/example_std_function_sugar.html b/doc/html/callable_traits/example_std_function_sugar.html deleted file mode 100644 index f672666..0000000 --- a/doc/html/callable_traits/example_std_function_sugar.html +++ /dev/null @@ -1,191 +0,0 @@ - - - -Example: std::function sugar - - - - - - - - - - - - - - - -
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    -
    -
    -PrevUpHomeNext -
    -
    - -

    - - Explanation -

    -

    - At a glance, there appear to be around 260 search - results on Stack Overflow concerning the conversion from std::bind - results to std::function, and around 340 search - results concerning the conversion of lambdas to std::function. - There are few good reasons for converting std::bind result - objects into std::function objects, and fewer still for creating - std::function objects without explicitly specifying - the function type. Regardless, here's a make_function - function, which can... -

    -
      -
    1. - Construct an std::function<T> - where T is not explicitly supplied by the user -
    2. -
    3. - Construct an std::function<T> - where T is the implied "signature" of an std::placeholders - expression -
    4. -
    -

    - make_function is rather silly, - especially since we have no contextual reason for incurring the costs of type - erasure. Still, it's a lightweight example of the kind of metaprogramming you - can do with CallableTraits. -

    -

    - - Usage -

    -
    - - - - - -
    [Note]Note

    - Due to limitations in the Microsoft compiler, this example will not compile - with MSVC. For more information, refer to the Compatibility - Issues section. -

    -
    #include <cassert>
    -
    -#include "make_function.hpp"
    -
    -using namespace example;
    -using namespace std::placeholders;
    -
    -int add(int i, int j) {
    -    return i + j;
    -}
    -
    -struct adder {
    -
    -    int eval(int i, int j) const {
    -        return i + j;
    -    }
    -};
    -
    -int main() {
    -
    -    // function pointer
    -    auto f = make_function(&add);
    -    assert(f(99, 1) == 100);
    -
    -    // function reference
    -    f = make_function(add);
    -    assert(f(99, 1) == 100);
    -
    -    // member function pointer (bound to object)
    -    f = make_function(&adder::eval, adder{}, _1, _2);
    -    assert(f(99, 1) == 100);
    -
    -    // lambda
    -    f = make_function([](int i, int j) {
    -        return i + j;
    -    });
    -
    -    assert(f(99, 1) == 100);
    -}
    -
    -

    - - Implementation -

    -
    #ifndef EXAMPLE_MAKE_FUNCTION_HPP
    -#define EXAMPLE_MAKE_FUNCTION_HPP
    -
    -#include <functional>
    -#include <callable_traits/function_type.hpp>
    -#include <callable_traits/bind.hpp>
    -
    -namespace example {
    -
    -    namespace ct = callable_traits;
    -
    -    // make_function turns a non-overloaded callable into a type-erased std::function object
    -    template<typename T>
    -    inline decltype(auto) make_function(T&& t) {
    -
    -        // callable_traits::function_type decays any non-overloaded callable type to
    -        // a plain function type, which is structured in terms of INVOKE.
    -
    -        using no_ref = typename std::remove_reference<T>::type;
    -        using f = ct::function_type<no_ref>;
    -        using result_type = std::function<f>;
    -        return result_type{ std::forward<T>(t) };
    -    }
    -
    -    // this make_function overload turns a bind expression into a type-erased std::function object
    -    template<typename T, typename First, typename... Others>
    -    inline decltype(auto) make_function(T&& t, First&& first, Others&&... others) {
    -
    -        // callable_traits::bind is essentially a compile-time parser of placeholder
    -        // expressions, for the purpose of retaining more type information than
    -        // std::bind normally allows - specifically, callable_traits::bind is used to
    -        // determine the de-facto signature of the std::bind return type, with special
    -        // considerations for conversions between reused placeholders and nested
    -        // placeholder expressions. For the sake of convenience, callable_traits::bind
    -        // is also a thin forwarding wrapper around std::bind (which is the only true
    -        // runtime element in CallableTraits).
    -
    -        using bind_expr = decltype(ct::bind(
    -                std::forward<T>(t),
    -                std::forward<First>(first),
    -                std::forward<Others>(others)...
    -        ));
    -
    -        using f = ct::function_type<bind_expr>;
    -        using result_type = std::function<f>;
    -
    -        return result_type{ std::bind(
    -                std::forward<T>(t),
    -                std::forward<First>(first),
    -                std::forward<Others>(others)...
    -        )};
    -    }
    -}
    -
    -#endif //#ifndef EXAMPLE_MAKE_FUNCTION_HPP
    -
    -
    - - - -
    -
    -
    -PrevUpHomeNext -
    - - diff --git a/doc/html/callable_traits/faq.html b/doc/html/callable_traits/faq.html index c01a56d..0a8e238 100644 --- a/doc/html/callable_traits/faq.html +++ b/doc/html/callable_traits/faq.html @@ -164,11 +164,7 @@ result -- no arguments necessary.

    - 7. bind - is used to intercept the signature information from a std::placeholder - expression before forwarding on to std::bind - or boost::bind. This gives library writers the power - to create more flexible template APIs for callable types. + 7 (TODO - fill this in)

    8. min_arity @@ -257,9 +253,7 @@ a type or a value argument. Even if variable template support were commonplace among production compilers, function templates would still have the upper hand in this regard. The same argument applies to alias - templates and class templates. Since CallableTraits supports - all value categories and qualifiers, using these function templates really - couldn't be any easier. + templates and class templates.

    diff --git a/doc/html/callable_traits/glossary.html b/doc/html/callable_traits/glossary.html index 0639125..5355959 100644 --- a/doc/html/callable_traits/glossary.html +++ b/doc/html/callable_traits/glossary.html @@ -43,7 +43,6 @@
    SimpleCallable
    SimpleInvokable
    Invokable
    -
    BindExpression
    ConstexprDefaultConstructible
    CallingConventionTag
    @@ -467,14 +466,6 @@
    -
    • - The return type of a call to callable_traits::bind -
    -
    -
    -
    • diff --git a/doc/html/callable_traits/headers.html b/doc/html/callable_traits/headers.html index 4426191..58b8cd6 100644 --- a/doc/html/callable_traits/headers.html +++ b/doc/html/callable_traits/headers.html @@ -202,9 +202,6 @@
    • #include<callable_traits/function_type.hpp>
    • -
    • - #include<callable_traits/bind.hpp> -
    diff --git a/doc/html/callable_traits/ref_arg_at.html b/doc/html/callable_traits/ref_arg_at.html index 4067885..f9e610d 100644 --- a/doc/html/callable_traits/ref_arg_at.html +++ b/doc/html/callable_traits/ref_arg_at.html @@ -47,9 +47,6 @@
  • SimpleFunctionObject
  • -
  • - BindExpression -
  • @@ -82,22 +79,6 @@
  • -
  • - Otherwise, when T is a - BindExpression, - then: -
      -
    • - Let MaxPlaceholder - represent the type of the largest std::placeholders - object in the bind expression tree -
    • -
    • - Index must be less - than std::is_placeholder<MaxPlaceholder>::value and greater than zero -
    • -
    -
  • diff --git a/doc/html/callable_traits/ref_args.html b/doc/html/callable_traits/ref_args.html index ea3b8e9..e3273ce 100644 --- a/doc/html/callable_traits/ref_args.html +++ b/doc/html/callable_traits/ref_args.html @@ -41,7 +41,6 @@ T must be one of the following: * Signature * SimpleFunctionObject - * BindExpression

    @@ -81,36 +80,6 @@ -
  • - Otherwise, when T is a - BindExpression, - then: -
      -
    • - Let bind_args... - represent the argument values that were passed to [namespace]bind which returned an instance - of T -
    • -
    • - Let bind_result represent - the return value of std::bind(bind_args...) -
    • -
    • - Let Args... - represent the "valid argument types" to bind_result's - operator() -
      • - Note: the "valid argument types" are implied by the - position of the std::placeholders - objects -
      -
    • -
    • - args<T> - aliases std::tuple<Args...> -
    • -
    -
  • diff --git a/doc/html/callable_traits/ref_arity.html b/doc/html/callable_traits/ref_arity.html index 8fe7de5..4663e29 100644 --- a/doc/html/callable_traits/ref_arity.html +++ b/doc/html/callable_traits/ref_arity.html @@ -7,7 +7,7 @@ - + @@ -20,7 +20,7 @@

    -PrevUpHomeNext +PrevUpHomeNext

    @@ -101,7 +101,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/callable_traits/ref_bind.html b/doc/html/callable_traits/ref_bind.html deleted file mode 100644 index 4b0e6df..0000000 --- a/doc/html/callable_traits/ref_bind.html +++ /dev/null @@ -1,286 +0,0 @@ - - - -bind - - - - - - - - - - - - - - - -
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    -
    -
    -PrevUpHomeNext -
    -
    -

    -bind -

    -
    - - - - - -
    [Note]Note

    - callable_traits::bind - is not compatible with the Microsoft Visual C++ compiler in Visual Studio - (a.k.a. MSVC). Accordingly, the example(s) below will not compile in MSVC. - However, Visual Studio users can still use Clang-cl. Refer to the Compatibility - Issues section for more information. -

    -
    namespace callable_traits {
    -
    -    template<typename... Ts>
    -    inline BindExpression bind(Ts&&... ts);
    -
    -}
    -
    -

    - callable_traits::bind - is used to parse type information from potentially complex std::placeholders - expressions. The type information in callable_traits::bind cannot legally/portably be extracted - from std::bind, because std::bind's - implementation is opaque. -

    -

    - - Constraints -

    -
      -
    • - The arguments to callable_traits::bind - must be legal arguments to std::bind, - substituting std::bind for callable_traits::bind in nested sub-expressions where - necessary to meet this constraint -
    • -
    • - All nested sub-expressions must be a call to callable_traits::bind instead of std::bind -
    • -
    • - If a call to callable_traits::bind - passes an OverloadedFunctionObject instance as its first - argument, then: -
      • - any placeholder objects passed in this call must be re-used somewhere - else in the expression tree, bing passed in another call to callable_traits::bind where a SimpleCallable as its first argument - (otherwise, no inference could be made about the parameter type being - "place-held") -
      -
    • -
    -

    - - Behavior -

    -
      -
    • - If any constraints are violated, the result is undefined -
    • -
    • - The return type of callable_traits::bind - can be passed to any of the following: -
        -
      • - callable_traits::args -
      • -
      • - callable_traits::arg_at -
      • -
      • - callable_traits::[function_type] -
      • -
      • - callable_traits::[result_of] -
      • -
      -
    • -
    • - For convenience, the object returned by callable_traits::bind serves as a wrapper around std::bind, forwarding from its operator() - to a private member object constructed from std::bind - in the original callable_traits::bind -
    • -
    -

    - - Notes -

    -
    • -

      - callable_traits::bind - is the only feature of CallableTraits with non-constexpr - behavior. However, the runtime behavior is only provided for convenience - -- callable_traits::bind - is designed to be a metaprogramming tool, and may be used in unevaluated - contexts. -

      -

      - - Example - 1 -

      -
      /* In this example, the last _1 placeholder in the bind
      -expression forces all other _1 slots to accept ScaryMonster,
      -because ScaryMonster is the narrowest of all _1 parameters. */
      -
      -#include <cassert>
      -#include <type_traits>
      -#include <functional>
      -#include <tuple>
      -#include <callable_traits/bind.hpp>
      -#include <callable_traits/args.hpp>
      -#include <callable_traits/function_type.hpp>
      -
      -struct Vampire {};
      -struct Robot {};
      -struct Animal {};
      -struct Dog : Animal {};
      -struct Poodle : Dog {};
      -struct ScaryMonster : Vampire, Robot, Poodle {};
      -
      -auto vampire_to_robot(Vampire) {
      -    return Robot{};
      -}
      -
      -auto robot_to_dog = [](Robot){
      -    return Dog{};
      -};
      -
      -struct converter {
      -    auto dog_to_vampire(Dog) {
      -        return Vampire{};
      -    }
      -};
      -
      -int take_all(Vampire, Robot, Animal, Dog, Poodle, ScaryMonster) {
      -    return 0;
      -}
      -
      -using namespace std::placeholders;
      -namespace ct = callable_traits;
      -
      -int main() {
      -
      -    auto b =
      -        ct::bind(&take_all,
      -            ct::bind(&converter::dog_to_vampire,
      -                converter{},
      -                ct::bind(robot_to_dog,
      -                    ct::bind(&vampire_to_robot, _1)
      -                )
      -            ),
      -            ct::bind(&vampire_to_robot, _3),
      -            Animal{},
      -            _1,
      -            _2,
      -            _1
      -        );
      -
      -    {
      -        using args = ct::args<decltype(b)>;
      -        using expect = std::tuple<ScaryMonster, Poodle, Vampire>;
      -        static_assert(std::is_same<args, expect>::value, "");
      -    } {
      -        using type = ct::function_type<decltype(b)>;
      -        using expect = int(ScaryMonster, Poodle, Vampire);
      -        static_assert(std::is_same<type, expect>::value, "");
      -    }
      -
      -    assert(b(ScaryMonster{}, Poodle{}, Vampire{}) == 0);
      -
      -    return 0;
      -}
      -
      -

      - - Example - 2 -

      -
      #include <cassert>
      -#include <type_traits>
      -#include <functional>
      -#include <tuple>
      -#include <callable_traits/bind.hpp>
      -#include <callable_traits/args.hpp>
      -#include <callable_traits/function_type.hpp>
      -
      -struct Vampire {};
      -struct Robot {};
      -struct Animal {};
      -struct Dog : Animal {};
      -struct Poodle : Dog {};
      -struct ScaryMonster : Poodle, Robot, Vampire {};
      -
      -auto take_vampire(const Vampire&) { return 0; }
      -auto take_robot(const Robot&) { return 0; }
      -auto take_dog(const Dog&) { return 0; }
      -auto take_scary_monster(const ScaryMonster&) { return 0; }
      -
      -int f(int, int, int, int) { return 0; }
      -
      -using namespace std::placeholders;
      -namespace ct = callable_traits;
      -
      -int main() {
      -
      -    ScaryMonster monster{};
      -
      -    auto b = ct::bind(
      -        &f,
      -        ct::bind(&take_vampire, _1),
      -        ct::bind(&take_robot, _1),
      -        ct::bind(&take_dog, _1),
      -        ct::bind(&take_scary_monster, _1)
      -    );
      -
      -    {
      -        using args = ct::args<decltype(b)>;
      -        using expect = std::tuple<const ScaryMonster&>;
      -        static_assert(std::is_same<args, expect>::value, "");
      -    } {
      -        using type = ct::function_type<decltype(b)>;
      -        using expect = int(const ScaryMonster&);
      -        static_assert(std::is_same<type, expect>::value, "");
      -    }
      -
      -    assert(b(monster) == 0);
      -
      -    return 0;
      -}
      -
      -
    -

    - - See - Also -

    -
    * [link_args]
    -* [link_arg_at]
    -* [function_type]
    -* [result_of]
    -
    -
    - - - -
    -
    -
    -PrevUpHomeNext -
    - - diff --git a/doc/html/callable_traits/ref_expand_args.html b/doc/html/callable_traits/ref_expand_args.html index 2526d65..ec03e85 100644 --- a/doc/html/callable_traits/ref_expand_args.html +++ b/doc/html/callable_traits/ref_expand_args.html @@ -46,9 +46,6 @@
  • SimpleFunctionObject
  • -
  • - BindExpression -
  • diff --git a/doc/html/callable_traits/ref_function_type.html b/doc/html/callable_traits/ref_function_type.html index f233068..e8cb8fa 100644 --- a/doc/html/callable_traits/ref_function_type.html +++ b/doc/html/callable_traits/ref_function_type.html @@ -165,34 +165,6 @@
  • -
  • - Otherwise, when T is a - BindExpression, - then: -
      -
    • - Let std::tuple<Args...> - represent callable_traits::args<T> -
    • -
    • - Let bind_args... - represent the argument values that were passed to [namespace]bind which returned an instance - of T -
    • -
    • - Let bind_result represent - the return value of std::bind(bind_args...) -
    • -
    • - Let Return represent - decltype(bind_result(std::declval<Args>()...)) -
    • -
    • - function_type<T> - aliases Return(Args...) -
    • -
    -
  • diff --git a/doc/html/callable_traits/ref_is_invokable.html b/doc/html/callable_traits/ref_is_invokable.html index c638206..1dca19b 100644 --- a/doc/html/callable_traits/ref_is_invokable.html +++ b/doc/html/callable_traits/ref_is_invokable.html @@ -6,7 +6,7 @@ - + @@ -20,7 +20,7 @@
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -229,7 +229,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/callable_traits/ref_result_of.html b/doc/html/callable_traits/ref_result_of.html index 9cc705a..1cafd20 100644 --- a/doc/html/callable_traits/ref_result_of.html +++ b/doc/html/callable_traits/ref_result_of.html @@ -7,7 +7,7 @@ - + @@ -20,7 +20,7 @@

    -PrevUpHomeNext +PrevUpHomeNext

    @@ -72,7 +72,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/callable_traits_interface_example.html b/doc/html/callable_traits_interface_example.html index 9c46119..ae9c3c9 100644 --- a/doc/html/callable_traits_interface_example.html +++ b/doc/html/callable_traits_interface_example.html @@ -6,7 +6,7 @@ - + @@ -20,7 +20,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    @@ -190,6 +190,7 @@ macro. The implementation can be found in the following section.

    #include <iostream>
    +#include <typeinfo>
     
     #include "interface.hpp"
     
    @@ -950,7 +951,7 @@
     
     
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/index.html b/doc/html/index.html index 98c1029..733c7ab 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -88,7 +88,6 @@
    SimpleCallable
    SimpleInvokable
    Invokable
    -
    BindExpression
    ConstexprDefaultConstructible
    CallingConventionTag
    @@ -117,7 +116,6 @@
    arg_at
    args
    arity
    -
    bind
    is_invokable
    is_invokable_constexpr
    clear_args
    @@ -151,8 +149,6 @@
    pop_back
    pop_front
    result_of
    -
    Example: std::function - sugar
    Example: Java-style interfaces without inheritance
    Contact
    @@ -407,10 +403,6 @@ calling conventions -
  • - std::bind - expressions with std::placeholders -
  • diff --git a/doc/html/standalone_HTML.manifest b/doc/html/standalone_HTML.manifest index 4a79512..5d3b758 100644 --- a/doc/html/standalone_HTML.manifest +++ b/doc/html/standalone_HTML.manifest @@ -16,7 +16,6 @@ callable_traits/ref_apply_return.html callable_traits/ref_arg_at.html callable_traits/ref_args.html callable_traits/ref_arity.html -callable_traits/ref_bind.html callable_traits/ref_is_invokable.html callable_traits/ref_is_invokable_constexpr.html callable_traits/ref_clear_args.html @@ -50,6 +49,5 @@ callable_traits/ref_push_front.html callable_traits/ref_pop_back.html callable_traits/ref_push_front0.html callable_traits/ref_result_of.html -callable_traits/example_std_function_sugar.html callable_traits_interface_example.html callable_traits/contact.html diff --git a/doc/make_function_example.qbk b/doc/make_function_example.qbk deleted file mode 100644 index 9a0f4d9..0000000 --- a/doc/make_function_example.qbk +++ /dev/null @@ -1,20 +0,0 @@ -[section Example: std::function sugar] - -[heading Explanation] - -At a glance, there appear to be around 260 [@http://stackoverflow.com/search?q=convert+std%3A%3Abind+to+std%3A%3Afunction search results] on Stack Overflow concerning the conversion from `std::bind` results to `std::function`, and around 340 [@http://stackoverflow.com/search?q=convert+lambda+to+std%3A%3Afunction search results] concerning the conversion of lambdas to `std::function`. There are few good reasons for converting `std::bind` result objects into `std::function` objects, and fewer still for creating `std::function` objects without explicitly specifying the function type. Regardless, here's a `make_function` function, which can... - -# Construct an `std::function` where T is not explicitly supplied by the user -# Construct an `std::function` where T is the implied "signature" of an `std::placeholders` expression - -`make_function` is rather silly, especially since we have no contextual reason for incurring the costs of type erasure. Still, it's a lightweight example of the kind of metaprogramming you can do with [libname]. - -[heading Usage] -[note Due to limitations in the Microsoft compiler, this example will not compile with MSVC. For more information, refer to the [link_compatibility_issues] section.] -[import ../example/make_function_example.cpp] -[make_function_example] - -[heading Implementation] -[import ../example/make_function.hpp] -[make_function_header] -[endsect] diff --git a/example/bind_1.cpp b/example/bind_1.cpp deleted file mode 100644 index 707bc88..0000000 --- a/example/bind_1.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/*<- - -Copyright Barrett Adair 2016 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) - -->*/ - -#include -#ifdef CALLABLE_TRAITS_DISABLE_BIND -int main(){ return 0; } -#else - -//[ bind_1 - -/* In this example, the last _1 placeholder in the bind -expression forces all other _1 slots to accept ScaryMonster, -because ScaryMonster is the narrowest of all _1 parameters. */ - -#include -#include -#include -#include -#include -#include -#include - -struct Vampire {}; -struct Robot {}; -struct Animal {}; -struct Dog : Animal {}; -struct Poodle : Dog {}; -struct ScaryMonster : Vampire, Robot, Poodle {}; - -auto vampire_to_robot(Vampire) { - return Robot{}; -} - -auto robot_to_dog = [](Robot){ - return Dog{}; -}; - -struct converter { - auto dog_to_vampire(Dog) { - return Vampire{}; - } -}; - -int take_all(Vampire, Robot, Animal, Dog, Poodle, ScaryMonster) { - return 0; -} - -using namespace std::placeholders; -namespace ct = callable_traits; - -int main() { - - auto b = - ct::bind(&take_all, - ct::bind(&converter::dog_to_vampire, - converter{}, - ct::bind(robot_to_dog, - ct::bind(&vampire_to_robot, _1) - ) - ), - ct::bind(&vampire_to_robot, _3), - Animal{}, - _1, - _2, - _1 - ); - - { - using args = ct::args; - using expect = std::tuple; - static_assert(std::is_same::value, ""); - } { - using type = ct::function_type; - using expect = int(ScaryMonster, Poodle, Vampire); - static_assert(std::is_same::value, ""); - } - - assert(b(ScaryMonster{}, Poodle{}, Vampire{}) == 0); - - return 0; -} -//] -#endif diff --git a/example/bind_2.cpp b/example/bind_2.cpp deleted file mode 100644 index 6dbb4f6..0000000 --- a/example/bind_2.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/*<- - -Copyright Barrett Adair 2016 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) - -->*/ - -#include -#ifdef CALLABLE_TRAITS_DISABLE_BIND -int main(){ return 0; } -#else - -//[ bind_2 -#include -#include -#include -#include -#include -#include -#include - -struct Vampire {}; -struct Robot {}; -struct Animal {}; -struct Dog : Animal {}; -struct Poodle : Dog {}; -struct ScaryMonster : Poodle, Robot, Vampire {}; - -auto take_vampire(const Vampire&) { return 0; } -auto take_robot(const Robot&) { return 0; } -auto take_dog(const Dog&) { return 0; } -auto take_scary_monster(const ScaryMonster&) { return 0; } - -int f(int, int, int, int) { return 0; } - -using namespace std::placeholders; -namespace ct = callable_traits; - -int main() { - - ScaryMonster monster{}; - - auto b = ct::bind( - &f, - ct::bind(&take_vampire, _1), - ct::bind(&take_robot, _1), - ct::bind(&take_dog, _1), - ct::bind(&take_scary_monster, _1) - ); - - { - using args = ct::args; - using expect = std::tuple; - static_assert(std::is_same::value, ""); - } { - using type = ct::function_type; - using expect = int(const ScaryMonster&); - static_assert(std::is_same::value, ""); - } - - assert(b(monster) == 0); - - return 0; -} -//] -#endif diff --git a/example/interface_example.cpp b/example/interface_example.cpp index b5dddf6..d874f47 100644 --- a/example/interface_example.cpp +++ b/example/interface_example.cpp @@ -19,6 +19,7 @@ int main(){ return 0; } //[ interface_example #include +#include #include "interface.hpp" diff --git a/example/make_function.hpp b/example/make_function.hpp deleted file mode 100644 index b32e155..0000000 --- a/example/make_function.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/*<- -Copyright Barrett Adair 2016 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) -->*/ - -//[ make_function_header - -#ifndef EXAMPLE_MAKE_FUNCTION_HPP -#define EXAMPLE_MAKE_FUNCTION_HPP - -#include -#include -#include - -namespace example { - - namespace ct = callable_traits; - - // make_function turns a non-overloaded callable into a type-erased std::function object - template - inline decltype(auto) make_function(T&& t) { - - // callable_traits::function_type decays any non-overloaded callable type to - // a plain function type, which is structured in terms of INVOKE. - - using no_ref = typename std::remove_reference::type; - using f = ct::function_type; - using result_type = std::function; - return result_type{ std::forward(t) }; - } - - // this make_function overload turns a bind expression into a type-erased std::function object - template - inline decltype(auto) make_function(T&& t, First&& first, Others&&... others) { - - // callable_traits::bind is essentially a compile-time parser of placeholder - // expressions, for the purpose of retaining more type information than - // std::bind normally allows - specifically, callable_traits::bind is used to - // determine the de-facto signature of the std::bind return type, with special - // considerations for conversions between reused placeholders and nested - // placeholder expressions. For the sake of convenience, callable_traits::bind - // is also a thin forwarding wrapper around std::bind (which is the only true - // runtime element in CallableTraits). - - using bind_expr = decltype(ct::bind( - std::forward(t), - std::forward(first), - std::forward(others)... - )); - - using f = ct::function_type; - using result_type = std::function; - - return result_type{ std::bind( - std::forward(t), - std::forward(first), - std::forward(others)... - )}; - } -} - -#endif //#ifndef EXAMPLE_MAKE_FUNCTION_HPP -//] diff --git a/example/make_function_example.cpp b/example/make_function_example.cpp deleted file mode 100644 index 1016de7..0000000 --- a/example/make_function_example.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/*<- -Copyright Barrett Adair 2016 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) -->*/ - -#include - -#ifdef CALLABLE_TRAITS_DISABLE_CONSTEXPR_CHECKS -int main(){ return 0; } -#else - -//[ make_function_example -#include - -#include "make_function.hpp" - -using namespace example; -using namespace std::placeholders; - -int add(int i, int j) { - return i + j; -} - -struct adder { - - int eval(int i, int j) const { - return i + j; - } -}; - -int main() { - - // function pointer - auto f = make_function(&add); - assert(f(99, 1) == 100); - - // function reference - f = make_function(add); - assert(f(99, 1) == 100); - - // member function pointer (bound to object) - f = make_function(&adder::eval, adder{}, _1, _2); - assert(f(99, 1) == 100); - - // lambda - f = make_function([](int i, int j) { - return i + j; - }); - - assert(f(99, 1) == 100); -} -//] -#endif diff --git a/include/callable_traits/bind.hpp b/include/callable_traits/bind.hpp deleted file mode 100644 index df4b911..0000000 --- a/include/callable_traits/bind.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/*! -@file - -@copyright Barrett Adair 2015 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) - -*/ - -#ifndef CALLABLE_TRAITS_BIND_HPP -#define CALLABLE_TRAITS_BIND_HPP - -#include -#include -#include -#include - -namespace callable_traits { - -#ifdef CALLABLE_TRAITS_DISABLE_BIND - -template -inline constexpr int -bind(T&&...) { - - static_assert(Allowed, - "callable_traits::bind is not supported on " - "your compiler. Refer to the Compatibility " - "section of the CallableTraits documentation " - "for more information."); - - return -1; -} - -#else - - template - inline constexpr auto - bind(T&& t, Args&&... args) -> - detail::bind_expression { - - return { - ::std::forward(t), - ::std::forward(args)... - }; - } - -#endif //#ifdef CALLABLE_TRAITS_DISABLE_BIND - -} - -#endif diff --git a/include/callable_traits/callable_traits.hpp b/include/callable_traits/callable_traits.hpp index 3f4f749..9e109ac 100644 --- a/include/callable_traits/callable_traits.hpp +++ b/include/callable_traits/callable_traits.hpp @@ -23,7 +23,6 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include #include #include #include diff --git a/include/callable_traits/detail/best_match.hpp b/include/callable_traits/detail/best_match.hpp deleted file mode 100644 index 6f3ab04..0000000 --- a/include/callable_traits/detail/best_match.hpp +++ /dev/null @@ -1,161 +0,0 @@ -/*! -Copyright (c) 2016 Barrett Adair - -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ - -#ifndef CALLABLE_TRAITS_DETAIL_BEST_MATCH_HPP -#define CALLABLE_TRAITS_DETAIL_BEST_MATCH_HPP - -#include -#include -#include -#include - -namespace callable_traits { - - namespace detail { - template class, typename...> - struct filter_impl; - - template class Pred> - struct filter_impl { - using type = std::tuple<>; - }; - - template class Pred, typename Head, typename ...Tail> - struct filter_impl - { - using type = typename std::conditional::value, - typename prepend::type>::type, - typename filter_impl::type - >::type; - }; - - template class Pred, typename... Ts> - using filter = typename filter_impl::type; - - template - struct can_convert { - - using is_non_reference = std::is_same::type>; - - using arg_type = typename std::conditional< - is_non_reference::value, - T&, - T - >::type; - - //todo - this should probably use std::is_convertible instead - template - struct apply { - - struct bad{}; - - template()(std::declval()))> - static Ret test(U); - - template - static bad test(...); - - using test_type = void(*)(K); - using result = decltype(test(test_type{})); - - static constexpr const bool value = !std::is_same::value; - }; - }; - - template - struct conversion_result { - using key = T; - using successful_conversions = Tup; - static constexpr const std::size_t count = std::tuple_size::value; - }; - - template - using map_conversions = - conversion_result::template apply, Ts...>>; - - template - struct conversion_result_sort_predicate { - - using candidate = typename T::key; - using other = typename U::key; - - using no_ref = typename std::remove_reference::type; - using no_ref_other = typename std::remove_reference::type; - - static constexpr bool const is_better_match = T::count > U::count; - static constexpr bool const is_same_match = T::count == U::count; - - static constexpr bool const is_lref = std::is_lvalue_reference::value; - static constexpr bool const is_rref = std::is_rvalue_reference::value; - static constexpr bool const is_ref = is_lref || is_rref; - static constexpr bool const is_const = std::is_const::value; - - static constexpr bool const is_other_lref = std::is_lvalue_reference::value; - static constexpr bool const is_other_rref = std::is_rvalue_reference::value; - static constexpr bool const is_other_ref = is_other_lref || is_other_rref; - static constexpr bool const is_other_const = std::is_const::value; - - static constexpr bool const has_better_reference = - (!is_ref && is_other_ref) || (is_lref && is_other_rref); - - static constexpr bool const has_same_reference = - is_lref == is_other_lref && is_rref == is_other_rref; - - static constexpr bool const has_better_const = (is_const && !is_other_const); - - static constexpr bool const has_same_const =is_const == is_other_const; - - static constexpr const bool value = - is_better_match - || (is_same_match && has_better_reference) - || (is_same_match && has_same_reference && has_better_const); - }; - - template - struct sorted_cartesian_product_of_conversions { - using type = tuple_sort< - std::tuple...>, - conversion_result_sort_predicate - >; - }; - - template - using best_conversion_result = at<0, - typename sorted_cartesian_product_of_conversions::type>; - - template - using has_valid_match = std::integral_constant::count == sizeof...(Ts) - >; - - template - struct is_invalid : std::is_same::type {}; - - template - using remove_invalid_types = filter; - - template - struct best_match_t { - - using has_valid = has_valid_match; - - static_assert(has_valid::value, "Conversion not found for all parameter types."); - - using result = typename best_conversion_result::key; - - using type = typename std::enable_if< - has_valid::value, - result - >::type; - }; - - template - using best_match = typename best_match_t::type; - } -} - -#endif diff --git a/include/callable_traits/detail/bind_expression.hpp b/include/callable_traits/detail/bind_expression.hpp deleted file mode 100644 index fe52d93..0000000 --- a/include/callable_traits/detail/bind_expression.hpp +++ /dev/null @@ -1,196 +0,0 @@ -/*! -Copyright (c) 2001-2004 Peter Dimov and Multi Media Ltd. -Copyright (c) 2001 David Abrahams -Copyright (c) 2005 Peter Dimov -Copyright (c) 2016 Barrett Adair - -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ - -#ifndef CALLABLE_TRAITS_DETAIL_BIND_EXPRESSION_HPP -#define CALLABLE_TRAITS_DETAIL_BIND_EXPRESSION_HPP - -#include -#include -#include -#include -#include -//#include - -#include -#include - -namespace callable_traits { - - namespace detail { - - template - struct is_callable_traits_bind - : std::false_type {}; - - template - struct is_callable_traits_bind> - : std::true_type {}; - - template - struct compare_ph_value { - static constexpr bool value = - PhRouteLeft::ph_value < PhRouteRight::ph_value; - }; - - template struct bind_expressions_filter; - - template <> struct bind_expressions_filter<> { - using type = std::tuple<>; - }; - - template - struct bind_expressions_filter { - - using filtered_tail = typename bind_expressions_filter::type; - using decayed_head = shallow_decay; - - using type = typename std::conditional< - is_callable_traits_bind::value, - typename prepend::type, - filtered_tail - >::type; - }; - - template - struct remove_non_bind_expressions { - using type = typename bind_expressions_filter::type; - }; - - template - struct is_empty_tuple : std::false_type{}; - - template<> - struct is_empty_tuple> : std::true_type{}; - - template - struct is_not_empty_tuple : std::true_type {}; - - template<> - struct is_not_empty_tuple> : std::false_type {}; - - template - struct flatten_bind_expressions; - - template - struct flatten_bind_expressions< - std::tuple, - std::true_type - > { - using type = decltype(std::tuple_cat( - std::declval::type>()... - )); - }; - - template - struct flatten_bind_expressions< - BindExpr, - typename is_not_empty_tuple::type - > { - using type = typename prepend< - BindExpr, - typename flatten_bind_expressions< - typename BindExpr::inner_bind_expressions - >::type - >::type; - }; - - //base case - bind expression has no inner bind expressions - template - struct flatten_bind_expressions< - BindExpr, - typename is_empty_tuple::type - > { - using type = std::tuple; - }; - - template>::value, int>::type = 0> - inline constexpr CALLALBLE_TRAITS_DECLTYPE_AUTO - unwrap_std_bind(T&& t){ - return t.get_std_bind(); - } - - template>::value, int>::type = 0> - inline constexpr T&& unwrap_std_bind(T&& t){ - return std::forward(t); - } - - template - struct bind_expression { - - private: - - using bind_type = typename std::remove_reference(), unwrap_std_bind(std::declval())...) - )>::type; - - bind_type std_bind; - - public: - - using bind_args_tuple = std::tuple< - typename categorize_bind_arg< - Args, - typename std::remove_reference::type - >::type... - >; - - using inner_bind_expressions = - typename remove_non_bind_expressions::type; - - using flattened_bind_expressions = - typename flatten_bind_expressions::type; - - using placeholder_route_map = typename placeholder_routes< - bind_expression, - bind_args_tuple - >::type; - - using no_ref = typename std::remove_reference::type; - using original_args = typename traits::arg_types; - using return_type = typename traits::return_type; - using result_type = return_type; - -#ifndef CALLABLE_TRAITS_DISABLE_REFERENCE_QUALIFIERS - - inline bind_type& - get_std_bind() & { - return std_bind; - } - - inline bind_type&& - get_std_bind() && { - return std::move(std_bind); - } - -#endif //#ifndef CALLABLE_TRAITS_DISABLE_REFERENCE_QUALIFIERS - - inline constexpr - bind_expression(Callable c, Args... args) - : std_bind( - std::bind(static_cast(c), - unwrap_std_bind(static_cast(args))...)) {} - - template - inline CALLALBLE_TRAITS_DECLTYPE_AUTO - operator()(Rgs&&... args) { - return std_bind(std::forward(args)...); - } - - inline operator bind_type&() { - return std_bind; - } - }; - - } -} - -#endif diff --git a/include/callable_traits/detail/bind_expression_parser.hpp b/include/callable_traits/detail/bind_expression_parser.hpp deleted file mode 100644 index 9eac780..0000000 --- a/include/callable_traits/detail/bind_expression_parser.hpp +++ /dev/null @@ -1,147 +0,0 @@ -/*! -Copyright (c) 2016 Barrett Adair - -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ - -#ifndef CALLABLE_TRAITS_DETAIL_BIND_EXPRESSION_PARSER_HPP -#define CALLABLE_TRAITS_DETAIL_BIND_EXPRESSION_PARSER_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace callable_traits { - - namespace detail { - - template - struct combine_placeholder_routes; - - template - struct combine_placeholder_routes> { - - using placeholder_route_map = decltype(std::tuple_cat(std::declval< - typename placeholder_routes< - BindExprs, - typename BindExprs::bind_args_tuple - >::type>()...)); - - using type = tuple_sort< - placeholder_route_map, - compare_ph_value - >; - }; - - template - struct ph_value_wrapper { - static constexpr const auto value = T::ph_value; - }; - - template struct filter_invalid_args; - - template <> struct filter_invalid_args<> { - using type = std::tuple<>; - }; - - template - struct filter_invalid_args { - - static constexpr const auto is_legal_arg = - !std::is_same{} - && !std::is_same{}; - - using type = typename std::conditional< - is_legal_arg, - typename prepend::type>::type, - typename filter_invalid_args::type - >::type; - }; - - template - struct valid_args; - - template - struct valid_args> { - using filtered_args = typename filter_invalid_args::type; - using type = typename std::conditional< - std::is_same>::value, - invalid_type, - filtered_args - >::type; - }; - - template - struct find_best_match; - - template - struct find_best_match> { - using type = best_match; - }; - - template - struct common_expected_arg_types; - - template - struct common_expected_arg_types, OtherGroupTuples...>> { - - using expected_types = std::tuple< - at...>; - - using type = typename prepend< - typename find_best_match::type>::type, - typename common_expected_arg_types>::type - >::type; - }; - - template<> - struct common_expected_arg_types> { - using type = std::tuple<>; - }; - - template - struct bind_expression_parser - { - static constexpr const bool value = false; - using arg_types = invalid_type; - using return_type = invalid_type; - using function_type = invalid_type; - using qualified_function_type = invalid_type; - }; - - template - struct bind_expression_parser> { - - static constexpr const bool value = true; - - using root_expression = bind_expression; - - using flattened_bind_expressions = - typename root_expression::flattened_bind_expressions; - - using placeholder_routes = typename combine_placeholder_routes< - flattened_bind_expressions - >::type; - - using grouped_placeholders = tuple_group_by< - placeholder_routes, - ph_value_wrapper - >; - - using arg_types = typename common_expected_arg_types::type; - using return_type = typename root_expression::return_type; - using function_type = build_function; - using qualified_function_type = function_type; - }; - } -} - -#endif diff --git a/include/callable_traits/detail/bind_expression_traits.hpp b/include/callable_traits/detail/bind_expression_traits.hpp deleted file mode 100644 index b96e907..0000000 --- a/include/callable_traits/detail/bind_expression_traits.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/*! -Copyright (c) 2016 Barrett Adair - -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ - -#ifndef CALLABLE_TRAITS_DETAIL_BIND_EXPRESSION_TRAITS_HPP -#define CALLABLE_TRAITS_DETAIL_BIND_EXPRESSION_TRAITS_HPP - -#include -#include - -namespace callable_traits { - - namespace detail { - - namespace bind_expr_detail { - - template class> - struct expand_bind_args; - - template class Container> - struct expand_bind_args, Container> { - using type = Container; - }; - } - - - - template - struct bind_expression_traits : default_callable_traits { - - using parser = bind_expression_parser; - static constexpr const bool value = parser::value; - using traits = bind_expression_traits; - using arg_types = typename parser::arg_types; - using return_type = typename parser::return_type; - using function_type = typename parser::function_type; - using qualified_function_type = typename parser::qualified_function_type; - - template class Container> - using expand_args = - typename bind_expr_detail::expand_bind_args::type; - }; - } -} - -#endif diff --git a/include/callable_traits/detail/categorize_bind_arg.hpp b/include/callable_traits/detail/categorize_bind_arg.hpp deleted file mode 100644 index 5818c6a..0000000 --- a/include/callable_traits/detail/categorize_bind_arg.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/*! -Copyright (c) 2001-2004 Peter Dimov and Multi Media Ltd. -Copyright (c) 2001 David Abrahams -Copyright (c) 2005 Peter Dimov -Copyright (c) 2016 Barrett Adair - -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ - -#ifndef CALLABLE_TRAITS_DETAIL_CATEGORIZE_BIND_ARG_HPP -#define CALLABLE_TRAITS_DETAIL_CATEGORIZE_BIND_ARG_HPP - -#include -#include -#include -#include - -namespace callable_traits { - - namespace detail { - - template - struct bind_value {}; - - template - struct categorize_bind_arg { - using type = typename std::conditional< - std::is_placeholder< NoRef >::value == 0, - bind_value, - placeholder::value> - >::type; - }; - - template - struct categorize_bind_arg< Ref, bind_value> { - using type = detail::bind_value; - }; - - template - struct categorize_bind_arg< Ref, std::reference_wrapper > { - using type = std::reference_wrapper; - }; - - template - struct categorize_bind_arg< Ref, placeholder > { - using type = placeholder; - }; - - template - struct categorize_bind_arg> { - - using return_type = typename bind_expression::return_type; - - using type = typename std::conditional< - std::is_same::value, - template_worm, - return_type - >::type; - }; - } -} - -#endif diff --git a/include/callable_traits/detail/function_object.hpp b/include/callable_traits/detail/function_object.hpp index 4868e53..c26325d 100644 --- a/include/callable_traits/detail/function_object.hpp +++ b/include/callable_traits/detail/function_object.hpp @@ -36,10 +36,9 @@ namespace callable_traits { using class_type = invalid_type; using invoke_type = invalid_type; - using is_function_object = std::integral_constant>::value>; + using is_function_object = typename std::is_class>::type; - using is_overloaded_function_object = std::integral_constant>::value>; diff --git a/include/callable_traits/detail/fwd/bind_expression_fwd.hpp b/include/callable_traits/detail/fwd/bind_expression_fwd.hpp deleted file mode 100644 index 67176b6..0000000 --- a/include/callable_traits/detail/fwd/bind_expression_fwd.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/*! -Copyright (c) 2016 Barrett Adair - -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ - -#ifndef CALLABLE_TRAITS_FWD_BIND_EXPRESSION_FWD_HPP -#define CALLABLE_TRAITS_FWD_BIND_EXPRESSION_FWD_HPP - -namespace callable_traits { - - namespace detail { - - template - struct bind_expression; - - } -} - -#endif \ No newline at end of file diff --git a/include/callable_traits/detail/fwd/bind_expression_parser_fwd.hpp b/include/callable_traits/detail/fwd/bind_expression_parser_fwd.hpp deleted file mode 100644 index e2731a7..0000000 --- a/include/callable_traits/detail/fwd/bind_expression_parser_fwd.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/*! -Copyright (c) 2016 Barrett Adair - -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ - -#ifndef CALLABLE_TRAITS_DETAIL_FWD_BIND_EXPRESSION_PARSER_FWD_HPP -#define CALLABLE_TRAITS_DETAIL_FWD_BIND_EXPRESSION_PARSER_FWD_HPP - -namespace callable_traits { - - namespace detail { - - template - struct bind_expression_parser; - - } -} - -#endif diff --git a/include/callable_traits/detail/is_constexpr_impl.hpp b/include/callable_traits/detail/is_constexpr_impl.hpp index 735782c..535c7d8 100644 --- a/include/callable_traits/detail/is_constexpr_impl.hpp +++ b/include/callable_traits/detail/is_constexpr_impl.hpp @@ -123,7 +123,7 @@ namespace callable_traits { using result = decltype(test{}(::std::forward(t))); using failure = substitution_failure; using is_not_constexpr = std::is_same; - return std::integral_constant{}; + return bool_type{}; } #endif //ifdef CALLABLE_TRAITS_DISABLE_CONSTEXPR_CHECKS diff --git a/include/callable_traits/detail/is_invokable_constexpr_impl.hpp b/include/callable_traits/detail/is_invokable_constexpr_impl.hpp index 09fcc87..f71de6f 100644 --- a/include/callable_traits/detail/is_invokable_constexpr_impl.hpp +++ b/include/callable_traits/detail/is_invokable_constexpr_impl.hpp @@ -44,7 +44,7 @@ namespace callable_traits { //generalize_if_dissimilar is used to abstract away the rules of INVOKE. typename Obj = generalize_if_dissimilar> auto operator()(P&& p, U&& u, Rgs&&... rgs) const -> if_integral_constant, CALLABLE_TRAITS_MAKE_CONSTEXPR(U&&) // resolves to a matching reference to a constexpr K object. Hence, K must be @@ -74,12 +74,12 @@ namespace callable_traits { //see comments on specialization above template auto operator()(T&& t, Rgs&&...) const -> if_not_integral_constant>; template::type> auto operator()(T&& t, Rgs&&...) const -> if_integral_constant>; + bool_type<(U::value(CALLABLE_TRAITS_MAKE_CONSTEXPR(Rgs&&)...), true)>>; auto operator()(...) const -> substitution_failure; }; @@ -100,7 +100,7 @@ namespace callable_traits { using test = test_invoke_constexpr; using result = decltype(test{}(::std::forward(t), ::std::forward(args)...)); using is_invalid_invoke = std::is_same; - return std::integral_constant{}; + return bool_type{}; } template @@ -114,7 +114,7 @@ namespace callable_traits { using test = test_invoke_constexpr, Args...>; using result = decltype(test{}( ::std::declval(), ::std::declval()...)); using is_invalid_invoke = std::is_same; - using type = std::integral_constant; + using type = bool_type; }; diff --git a/include/callable_traits/detail/is_invokable_impl.hpp b/include/callable_traits/detail/is_invokable_impl.hpp index a87e100..5c53b7c 100644 --- a/include/callable_traits/detail/is_invokable_impl.hpp +++ b/include/callable_traits/detail/is_invokable_impl.hpp @@ -19,7 +19,7 @@ namespace callable_traits { using result = decltype(test{}(::std::forward(t), ::std::forward(args)...)); using failure = detail::substitution_failure; using is_invalid_invoke = std::is_same; - return std::integral_constant{}; + return bool_type{}; } template @@ -30,7 +30,7 @@ namespace callable_traits { using result = decltype(test{}(::std::declval(), ::std::declval()...)); using failure = detail::substitution_failure; using is_invalid_invoke = std::is_same; - return std::integral_constant{}; + return bool_type{}; } } } diff --git a/include/callable_traits/detail/placeholder.hpp b/include/callable_traits/detail/placeholder.hpp deleted file mode 100644 index cad6b95..0000000 --- a/include/callable_traits/detail/placeholder.hpp +++ /dev/null @@ -1,114 +0,0 @@ -/*! -Copyright (c) 2002 Peter Dimov and Multi Media Ltd. -Copyright (c) 2016 Barrett Adair - -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ - -#ifndef CALLABLE_TRAITS_DETAIL_PLACEHOLDER_HPP -#define CALLABLE_TRAITS_DETAIL_PLACEHOLDER_HPP - -#include -#include -#include -#include - -namespace callable_traits { - - namespace detail { - - template - struct placeholder { - - placeholder() = default; - - template - placeholder(T const &) { - static_assert(I == std::is_placeholder::value, "Invalid placeholder"); - } - }; - } -} -namespace std { - - template - struct is_placeholder< callable_traits::detail::placeholder > { - static constexpr const int value = I; - }; -} - -namespace callable_traits { - - namespace detail { - - template - struct ph_route { - using expression = Expression; - static constexpr const auto original_arg_index = OriginalArgIndex; - static constexpr const auto ph_value = PhValue; - }; - - template struct argument_routing {}; - - template - struct argument_routing { - using type = - std::tuple< - ph_route< - Expression, - I, - std::is_placeholder::type>::value - >... - >; - }; - - //base case - template struct placeholder_routes_detail; - template <> struct placeholder_routes_detail<> { - using type = std::tuple<>; - }; - - template - struct placeholder_routes_detail { - //TODO - is there a faster way to do this? - using type = typename std::conditional< - Head::ph_value == 0, - typename placeholder_routes_detail::type, - typename prepend< - Head, - typename placeholder_routes_detail::type - >::type - >::type; - }; - - template - struct placeholder_routes_detail > { - using type = typename placeholder_routes_detail::type; - }; - - template - struct compare_placeholders { - static constexpr bool value = - std::is_placeholder::value < std::is_placeholder::value; - }; - - template struct placeholder_routes; - template struct placeholder_routes { using type = std::tuple<>; }; - - template - struct placeholder_routes > - { - using routed_placeholders = typename placeholder_routes_detail< - typename argument_routing< - Expression, - CALLABLE_TRAITS_MAKE_IX_SEQ(sizeof...(Args)), - std::tuple - >::type - >::type; - - using type = tuple_sort; - }; - } -} -#endif diff --git a/include/callable_traits/detail/required_definitions.hpp b/include/callable_traits/detail/required_definitions.hpp index 1a24d1c..41abec8 100644 --- a/include/callable_traits/detail/required_definitions.hpp +++ b/include/callable_traits/detail/required_definitions.hpp @@ -12,7 +12,6 @@ Distributed under the Boost Software License, Version 1.0. #include #include -#include #include #include #include diff --git a/include/callable_traits/detail/traits.hpp b/include/callable_traits/detail/traits.hpp index 845969c..5228a00 100644 --- a/include/callable_traits/detail/traits.hpp +++ b/include/callable_traits/detail/traits.hpp @@ -15,7 +15,6 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include #include namespace callable_traits { @@ -24,7 +23,6 @@ namespace callable_traits { template using traits = typename CALLABLE_TRAITS_DISJUNCTION( - bind_expression_traits>, function_object, function, pmf, diff --git a/include/callable_traits/detail/tuple_group_by.hpp b/include/callable_traits/detail/tuple_group_by.hpp deleted file mode 100644 index db8f117..0000000 --- a/include/callable_traits/detail/tuple_group_by.hpp +++ /dev/null @@ -1,122 +0,0 @@ -/*! -@file - -@coyright Modified Work Barrett Adair 2016 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ - -#ifndef CALLABLE_TRAITS_DETAIL_TUPLE_GROUP_BY_HPP -#define CALLABLE_TRAITS_DETAIL_TUPLE_GROUP_BY_HPP - -#include -#include -#include -#include - -namespace callable_traits { - - namespace detail { - - template class Pred> - struct group_by_value { - static constexpr auto value = Pred::value; - }; - - template class Pred> - struct distinct_group_by_values; - - template class Pred> - struct distinct_group_by_values, Pred> { - using type = std::tuple>; - }; - - template class Pred> - struct distinct_group_by_values, Pred> { - - static constexpr const auto is_in_same_group = - Pred::value == Pred::value; - - using next = typename distinct_group_by_values, Pred>::type; - - using type = typename std::conditional< - is_in_same_group, - next, - typename prepend, next>::type - >::type; - }; - - template struct group_by_filter_impl; - - template struct group_by_filter_impl { - using type = std::tuple<>; - }; - - template - struct group_by_filter_impl { - using pred_result = decltype(std::declval()(std::declval())); - using type = typename std::conditional< - pred_result::value, - typename prepend::type>::type, - typename group_by_filter_impl::type - >::type; - }; - - template - struct group_by_filter; - - template - struct group_by_filter> { - using type = typename group_by_filter_impl::type; - }; - - template class Pred, std::size_t I> - struct filter_predicate { - - using compare_against = at; - - template - auto operator()(T) -> - std::integral_constant::value == compare_against::value>; - }; - - template class Pred, typename ValuesSeq> - struct group_by_impl; - - template class Pred, std::size_t... I> - struct group_by_impl { - - using type = std::tuple< - typename group_by_filter< - filter_predicate, - Tup - >::type... - >; - }; - - template class Pred> - struct group_by_t { - - template - struct sort_predicate { - static constexpr const auto left = Pred::value; - static constexpr const auto right = Pred::value; - static constexpr const bool value = left < right; - }; - - using group_by_values = typename distinct_group_by_values::type; - - using type = typename group_by_impl< - tuple_sort, - group_by_values, - Pred, - CALLABLE_TRAITS_MAKE_IX_SEQ(std::tuple_size::value) - >::type; - }; - - template class Pred> - using tuple_group_by = typename group_by_t::type; - } -} - -#endif diff --git a/include/callable_traits/detail/tuple_sort.hpp b/include/callable_traits/detail/tuple_sort.hpp deleted file mode 100644 index ed2a058..0000000 --- a/include/callable_traits/detail/tuple_sort.hpp +++ /dev/null @@ -1,111 +0,0 @@ -/*! -@file - -@copyright Louis Dionne 2013-2016 -@coyright Modified Work Barrett Adair 2016 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ - -#ifndef CALLABLE_TRAITS_DETAIL_TUPLE_SORT_HPP -#define CALLABLE_TRAITS_DETAIL_TUPLE_SORT_HPP - - -#include -#include -#include - -//This is a slightly modified version of Boost.Hana's sort -namespace callable_traits { - - namespace detail { - - using empty_seq = CALLABLE_TRAITS_IX_SEQ(CALLABLE_TRAITS_EMPTY); - - template - struct insert; - - // We did not find the insertion point; continue processing elements - // recursively. - template - struct insert { - using type = typename insert< - Pred, Insert, Pred::template apply::value, - CALLABLE_TRAITS_IX_SEQ(Left..., Right1), - Right2, Right... - >::type; - }; - - // We did not find the insertion point, but there is only one element - // left. We insert at the end of the list, and we're done. - template - struct insert { - using type = CALLABLE_TRAITS_IX_SEQ(Left..., Last, Insert); - }; - - // We found the insertion point, we're done. - template - struct insert { - using type = CALLABLE_TRAITS_IX_SEQ(Left..., Insert, Right...); - }; - - template - struct insertion_sort; - - template - struct insertion_sort { - static constexpr bool pred_result = Pred::template apply::value; - using insert_result = typename insert< - Pred, T, pred_result, empty_seq, Result1, Results... - >::type; - using type = typename insertion_sort::type; - }; - - template - struct insertion_sort { - using type = typename insertion_sort< - Pred, CALLABLE_TRAITS_IX_SEQ(T), Ts... - >::type; - }; - - template - struct insertion_sort { - using type = Result; - }; - - template - struct sort_indices; - - template - struct sort_indices { - using type = typename insertion_sort::type; - }; - - template - struct sort_impl { - static constexpr std::size_t len = std::tuple_size::value; - using indices = typename sort_indices::type; - using type = typename sort_impl::type; - }; - - template - struct sort_impl { - using type = std::tuple...>; - }; - - template class Pred> - struct predicate { - template - using apply = Pred, at>; - }; - - template class Pred> - using tuple_sort = typename sort_impl>::type; - } -} - -#endif diff --git a/include/callable_traits/detail/unguarded/function.hpp b/include/callable_traits/detail/unguarded/function.hpp index 91116ca..f5fd23c 100644 --- a/include/callable_traits/detail/unguarded/function.hpp +++ b/include/callable_traits/detail/unguarded/function.hpp @@ -25,7 +25,7 @@ struct function using remove_varargs = type; using add_varargs = Return (Args..., ...) CALLABLE_TRAITS_INCLUDE_QUALIFIERS; - using has_member_qualifiers_function = std::integral_constant::value>; using qualifiers = qualifier_traits; diff --git a/include/callable_traits/detail/utility.hpp b/include/callable_traits/detail/utility.hpp index 536dea7..b82d096 100644 --- a/include/callable_traits/detail/utility.hpp +++ b/include/callable_traits/detail/utility.hpp @@ -33,6 +33,8 @@ namespace callable_traits { // used as return type in failed SFINAE tests struct substitution_failure : std::false_type{}; + template + using bool_type = std::integral_constant; // shorthand for std::tuple_element template @@ -47,7 +49,7 @@ namespace callable_traits { }; template - struct weak_at_t= std::tuple_size::value>>{ + struct weak_at_t= std::tuple_size::value>>{ using type = invalid_type; }; } @@ -65,7 +67,7 @@ namespace callable_traits { //polyfill for C++17 negation //TODO rename and move to polyfills folder template - using negate = std::integral_constant; + using negate = bool_type; namespace util_detail { @@ -132,7 +134,7 @@ namespace callable_traits { using add_member_pointer = T Class::*; template - using can_accept_member_qualifiers = std::integral_constant; namespace util_detail { @@ -154,7 +156,7 @@ namespace callable_traits { template> - using is_constexpr_constructible = std::integral_constant::value && std::is_default_constructible::value >; @@ -197,9 +199,8 @@ namespace callable_traits { //returns std::true_type for pointers and smart pointers template - using can_dereference = std::integral_constant::value - >; + using can_dereference = bool_type< + util_detail::can_dereference_t::value>; namespace util_detail { @@ -210,7 +211,7 @@ namespace callable_traits { }; template - struct generalize_t::value && !is_reference_wrapper::value >>{ using type = decltype(*std::declval()); diff --git a/include/callable_traits/is_like_function.hpp b/include/callable_traits/is_like_function.hpp index d49bc2b..f0cfd03 100644 --- a/include/callable_traits/is_like_function.hpp +++ b/include/callable_traits/is_like_function.hpp @@ -16,8 +16,7 @@ namespace callable_traits { template inline constexpr auto is_like_function() { - return std::integral_constant::value>{}; + return detail::bool_type::value>{}; } template diff --git a/test/bind_1.cpp b/test/bind_1.cpp deleted file mode 100644 index e56cad1..0000000 --- a/test/bind_1.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - -Copyright Barrett Adair 2016 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CALLABLE_TRAITS_DISABLE_BIND -int main(){ return 0; } -#else - -#ifndef CT_ASSERT -#define CT_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) -#endif //CT_ASSERT - -#ifndef CT_RUNTIME_ASSERT -#include -#undef NDEBUG -#define CT_RUNTIME_ASSERT(...) assert(__VA_ARGS__) -#endif //CT_RUNTIME_ASSERT - -using namespace std::placeholders; -namespace ct = callable_traits; - -struct Letter { - virtual operator const char*() const volatile = 0; -}; - -#define DEFINE_TEST_LETTER(L) \ -struct L : Letter { operator const char*() const volatile override { return #L; } } - -DEFINE_TEST_LETTER(A); -DEFINE_TEST_LETTER(B); -DEFINE_TEST_LETTER(C); -DEFINE_TEST_LETTER(D); -DEFINE_TEST_LETTER(E); -DEFINE_TEST_LETTER(F); -DEFINE_TEST_LETTER(G); - -auto letters( - const Letter& l1, - const Letter& l2, - const Letter& l3, - const Letter& l4, - const Letter& l5, - const Letter& l6, - const Letter& l7 - ) { - std::stringstream ss{}; - ss << l1 << l2 << l3 << l4 << l5 << l6 << l7; - return ss.str(); -} - -auto ordered_letters(A a, B b, C c, D d, E e, F f, G g) { - std::stringstream ss{}; - ss << a << b << c << d << e << f << g; - return ss.str(); -} - -template -constexpr auto -apply_helper(F&& f, Tuple&& t, CALLABLE_TRAITS_IX_SEQ(I...)) { - return std::forward(f)(std::get(std::forward(t))...); -} - -template -constexpr auto -apply(F&& f, Tuple&& t) { - return apply_helper( - std::forward(f), - std::forward(t), - CALLABLE_TRAITS_MAKE_IX_SEQ( - std::tuple_size>::value - ){} - ); -} - -int main() { - - auto a = A{}; - auto b = B{}; - auto c = C{}; - auto d = D{}; - auto e = E{}; - auto f = F{}; - auto g = G{}; - - CT_RUNTIME_ASSERT(letters(a, b, c, d, e, f, g) == "ABCDEFG"); - CT_RUNTIME_ASSERT(ordered_letters(a, b, c, d, e, f, g) == "ABCDEFG"); - - { - auto expr = ct::bind(&ordered_letters, _1, _2, _3, _4, _5, _6, _7); - auto test = std::bind(&ordered_letters, _1, _2, _3, _4, _5, _6, _7); - using args = ct::args; - using expected_args = std::tuple; - CT_ASSERT(std::is_same::value); - CT_ASSERT(std::is_same::value); - CT_RUNTIME_ASSERT(apply(expr, expected_args{}) == "ABCDEFG"); - CT_RUNTIME_ASSERT(apply(test, expected_args{}) == "ABCDEFG"); - } { - auto expr = ct::bind(&ordered_letters, a, b, c, _1, _2, _3, _4); - auto test = std::bind(&ordered_letters, a, b, c, _1, _2, _3, _4); - using args = ct::args; - using expected_args = std::tuple; - CT_ASSERT(std::is_same::value); - CT_ASSERT(std::is_same::value); - CT_RUNTIME_ASSERT(apply(test, expected_args{}) == "ABCDEFG"); - CT_RUNTIME_ASSERT(apply(test, expected_args{}) == "ABCDEFG"); - } { - auto expr = ct::bind(&ordered_letters, _7, _6, _5, _4, _3, _2, _1); - auto test = std::bind(&ordered_letters, _7, _6, _5, _4, _3, _2, _1); - using args = ct::args; - using expected_args = std::tuple; - CT_ASSERT(std::is_same::value); - CT_ASSERT(std::is_same::value); - CT_RUNTIME_ASSERT(apply(expr, expected_args{}) == "ABCDEFG"); - CT_RUNTIME_ASSERT(apply(test, expected_args{}) == "ABCDEFG"); - } { - auto expr = ct::bind(&ordered_letters, a, b, c, _4, _3, _2, _1); - auto test = std::bind(&ordered_letters, a, b, c, _4, _3, _2, _1); - using args = ct::args; - using expected_args = std::tuple; - CT_ASSERT(std::is_same::value); - CT_ASSERT(std::is_same::value); - CT_RUNTIME_ASSERT(apply(expr, expected_args{}) == "ABCDEFG"); - CT_RUNTIME_ASSERT(apply(test, expected_args{}) == "ABCDEFG"); - } { - auto expr = ct::bind(&ordered_letters, _4, _3, _2, _1, e, f, g); - auto test = std::bind(&ordered_letters, _4, _3, _2, _1, e, f, g); - using args = ct::args; - using expected_args = std::tuple; - CT_ASSERT(std::is_same::value); - CT_ASSERT(std::is_same::value); - CT_RUNTIME_ASSERT(apply(expr, expected_args{}) == "ABCDEFG"); - CT_RUNTIME_ASSERT(apply(test, expected_args{}) == "ABCDEFG"); - } { - auto expr = ct::bind(&letters, _1, _1, _3, _3, _2, a, b); - using args = ct::args; - using expected_args = std::tuple; - CT_ASSERT(std::is_same::value); - } -} - -#endif diff --git a/test/bind_2.cpp b/test/bind_2.cpp deleted file mode 100644 index d962115..0000000 --- a/test/bind_2.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - -Copyright Barrett Adair 2016 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CALLABLE_TRAITS_DISABLE_BIND -int main(){ return 0; } -#else - -#ifndef CT_ASSERT -#define CT_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) -#endif //CT_ASSERT - -#ifndef CT_RUNTIME_ASSERT -#include -#undef NDEBUG -#define CT_RUNTIME_ASSERT(...) assert(__VA_ARGS__) -#endif //CT_RUNTIME_ASSERT - -using namespace std::placeholders; -namespace ct = callable_traits; - -struct Letter { - virtual operator const char*() const volatile = 0; -}; - -#define DEFINE_TEST_LETTER(L) \ -struct L : Letter { operator const char*() const volatile override { return #L; } } - -DEFINE_TEST_LETTER(A); -DEFINE_TEST_LETTER(B); -DEFINE_TEST_LETTER(C); -DEFINE_TEST_LETTER(D); -DEFINE_TEST_LETTER(E); -DEFINE_TEST_LETTER(F); -DEFINE_TEST_LETTER(G); - -// functions `ordered_letters`, `BEEF_returns_D`, `BEEF_returns_G`, -// and `BEEF_returns_B` are used to set up a complex bind expression -// with ct::bind - -auto ordered_letters(A a, B b, C c, D d, E e, F f, G g) { - std::stringstream ss{}; - ss << a << b << c << d << e << f << g; - return ss.str(); -} - -auto BEEF_returns_D(B, E, E, F) { - return D{}; -} - -auto BEEF_returns_G(B, E, E, F) { - return G{}; -} - -auto BEEF_returns_B(B, E, E, F) { - return B{}; -} - -template -constexpr auto -apply_helper(F&& f, Tuple&& t, CALLABLE_TRAITS_IX_SEQ(I...)) { - return std::forward(f)(std::get(std::forward(t))...); -} - -//used to apply the expected_args tuple to std::bind -template -constexpr auto -apply(F&& f, Tuple&& t) { - return apply_helper( - std::forward(f), - std::forward(t), - CALLABLE_TRAITS_MAKE_IX_SEQ( - std::tuple_size>::value - ){} - ); -} - -const auto a = A{}; -const auto b = B{}; -const auto c = C{}; -const auto d = D{}; -const auto e = E{}; -const auto f = F{}; -const auto g = G{}; - -// lets us create a complex bind expression with both -// `std::bind` and `ct::bind` -#define BIND_WITH(bind_name) \ - bind_name(&ordered_letters, \ - _1, \ - _2, \ - _3, \ - bind_name(&BEEF_returns_D, \ - _2, \ - e, \ - _4, \ - _7 \ - ), \ - _5, \ - _6, \ - bind_name(&BEEF_returns_G, \ - bind_name(&BEEF_returns_B, \ - b, \ - _10, \ - e, \ - f \ - ), \ - _9, \ - e, \ - _8 \ - ) \ - ) \ -/**/ - -template -void check_expression_flattening(); - -int main() { - - assert(ordered_letters(a, b, c, d, e, f, g) == "ABCDEFG"); - - auto ct_bind = BIND_WITH(ct::bind); - auto std_bind = BIND_WITH(std::bind); - - // these are the argument types as dictated by the bind expression's placeholders - using expected_args = std::tuple; - using args = ct::args; - - CT_ASSERT(std::is_same::value); - CT_RUNTIME_ASSERT(apply(ct_bind, expected_args{}) == "ABCDEFG"); - CT_RUNTIME_ASSERT(apply(std_bind, expected_args{}) == "ABCDEFG"); -} - -#endif diff --git a/test/detail/best_match.cpp b/test/detail/best_match.cpp deleted file mode 100644 index 3dd7294..0000000 --- a/test/detail/best_match.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - -Copyright Barrett Adair 2016 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef CT_ASSERT -#define CT_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) -#endif //CT_ASSERT - -namespace ct = callable_traits; -namespace ctd = callable_traits::detail; - -struct Vampire {}; -struct Robot {}; -struct Animal {}; -struct Dog : Animal {}; -struct Poodle : Dog {}; -struct ScaryMonster : Poodle, Robot, Vampire {}; - -int main() { - - { - using test = ctd::best_match< - Vampire, Robot, Poodle, Animal, Dog, ScaryMonster>; - - using expect = ScaryMonster; - - CT_ASSERT(std::is_same::value); - } -} diff --git a/test/detail/flatten_bind_expressions.cpp b/test/detail/flatten_bind_expressions.cpp deleted file mode 100644 index 03259d8..0000000 --- a/test/detail/flatten_bind_expressions.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - -Copyright Barrett Adair 2016 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CALLABLE_TRAITS_DISABLE_BIND -int main(){ return 0; } -#else - -#ifndef CT_ASSERT -#define CT_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) -#endif //CT_ASSERT - -using namespace std::placeholders; -namespace ct = callable_traits; - -struct A {}; -struct B {}; -struct C {}; -struct D {}; -struct E {}; -struct F {}; -struct G {}; - -// functions `ordered_letters`, `BEEF_returns_D`, `BEEF_returns_G`, -// and `BEEF_returns_B` are used to set up a complex bind expression -// with ct::bind - -auto ordered_letters(A, B, C, D, E, F, G) { - return 0; -} - -auto BEEF_returns_D(B, E, E, F) { - return D{}; -} - -auto BEEF_returns_G(B, E, E, F) { - return G{}; -} - -auto BEEF_returns_B(B, E, E, F) { - return B{}; -} - -#define INNER_3 ct::bind(&BEEF_returns_B, B{}, _10, E{}, F{}) -#define INNER_2 ct::bind(&BEEF_returns_G, INNER_3, _9, E{}, _8) -#define INNER_1 ct::bind(&BEEF_returns_D, _2, E{}, _4, _7) - -int main() { - - auto root = ct::bind(&ordered_letters, _1, _2, _3, INNER_1, _5, _6, INNER_2); - - using test = decltype(root)::flattened_bind_expressions; - - using expect = std::tuple< - decltype(root), - decltype(INNER_1), - decltype(INNER_2), - decltype(INNER_3) - >; - - CT_ASSERT(std::is_same::value); - - return 0; -} - -#endif