diff --git a/doc/callable_traits.qbk b/doc/callable_traits.qbk index cd7168b..2befe67 100644 --- a/doc/callable_traits.qbk +++ b/doc/callable_traits.qbk @@ -95,8 +95,8 @@ [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_can_invoke[][link callable_traits.ref_can_invoke [^can_invoke]]] -[template link_can_invoke_constexpr[][link callable_traits.ref_can_invoke_constexpr [^can_invoke_constexpr]]] +[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]]] [template link_expand_args[][link callable_traits.ref_expand_args [^expand_args]]] [template link_function_type[][link callable_traits.ref_function_type [^function_type]]] @@ -128,7 +128,6 @@ [template link_insert_args[][link callable_traits.ref_insert_args [^insert_args]]] [template link_remove_args[][link callable_traits.ref_remove_args [^remove_args]]] [template link_replace_args[][link callable_traits.ref_replace_args [^replace_args]]] -[template link_is_callable[][link callable_traits.ref_is_callable [^is_callable]]] [template link_result_of[][link callable_traits.ref_result_of [^result_of]]] [template cc_warning_rationale[] @@ -273,7 +272,7 @@ CallableTraits has not been tested on every platform under the sun. If you find [section:compatibility_issues Known Issues] -* [link_is_constexpr] and [link_can_invoke_constexpr] always `std::false_type` on the following platforms: +* [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: @@ -370,7 +369,7 @@ There are real reasons to write code like this, but they are few and far between [*4.] [namespace_scoped][link_arg_at]`<2, Callable>` is more flexible than `typename boost::function_traits::arg3_type`. -[*5.] [link_can_invoke] is used to test `INVOKE`-ability at compile-time, with value semantics. For the craziest metaprogrammers, [link_can_invoke_constexpr] does the same as `can_invoke` for [link_constexpr_constructible] types, with an added check for `constexpr`-ness +[*5.] [link_is_invokable] is used to test `INVOKE`-ability at compile-time, with value semantics. For the craziest metaprogrammers, [link_IS_INVOKABLE_constexpr] does the same as `is_invokable` for [link_constexpr_constructible] types, with an added check for `constexpr`-ness [*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. @@ -788,8 +787,8 @@ The [libname] interface is also broken down by trait into individual header file [section ['INVOKE]] -* [include_header [link_can_invoke]] -* [include_header [link_can_invoke_constexpr]] +* [include_header [link_is_invokable]] +* [include_header [link_IS_INVOKABLE_constexpr]] * [include_header [link_function_type]] * [include_header [link_bind]] @@ -807,7 +806,7 @@ The [libname] interface is also broken down by trait into individual header file [section Constant Expressions] * [include_header [link_is_constexpr]] -* [include_header [link_can_invoke_constexpr]] +* [include_header [link_IS_INVOKABLE_constexpr]] [endsect] @@ -1334,12 +1333,12 @@ For `add_calling_convention` to work as-intended, you must: [endsect] -[section:ref_can_invoke can_invoke] +[section:ref_is_invokable is_invokable] namespace ``[lib_namespace]`` { template - inline constexpr auto can_invoke(T&&, Args&&...); + inline constexpr auto is_invokable(T&&, Args&&...); } @@ -1348,38 +1347,38 @@ For `add_calling_convention` to work as-intended, you must: * No other constraints [heading Behavior] -* If all arguments to `can_invoke` can legally be forwarded to [invoke], then an instance of `std::true_type` is returned +* If all arguments to `is_invokable` can legally be forwarded to [invoke], then an instance of `std::true_type` is returned * Otherwise, an instance of `std::false_type` is returned [heading Example - Function Object] -[import ../example/can_invoke_function_object.cpp] -[can_invoke_function_object] +[import ../example/is_invokable_function_object.cpp] +[is_invokable_function_object] [heading Example - Member Function Pointer] -[import ../example/can_invoke_member_function_pointer.cpp] -[can_invoke_member_function_pointer] +[import ../example/is_invokable_member_function_pointer.cpp] +[is_invokable_member_function_pointer] [heading Example - Function Pointer] -[import ../example/can_invoke_function_pointer.cpp] -[can_invoke_function_pointer] +[import ../example/is_invokable_function_pointer.cpp] +[is_invokable_function_pointer] [heading Example - Function Reference] -[import ../example/can_invoke_function_reference.cpp] -[can_invoke_function_reference] +[import ../example/is_invokable_function_reference.cpp] +[is_invokable_function_reference] [heading See Also] -* [link_can_invoke_constexpr] +* [link_IS_INVOKABLE_constexpr] [endsect] -[section:ref_can_invoke_constexpr can_invoke_constexpr] +[section:ref_IS_INVOKABLE_constexpr is_invokable_constexpr] -[note `can_invoke_constexpr` [msvc_incompatible]] +[note `is_invokable_constexpr` [msvc_incompatible]] namespace ``[lib_namespace]`` { template - inline constexpr auto can_invoke_constexpr(T&& t, Args&&... args); + inline constexpr auto is_invokable_constexpr(T&& t, Args&&... args); } @@ -1388,24 +1387,24 @@ For `add_calling_convention` to work as-intended, you must: [heading Behavior] * An instance of `std::false_type` is returned, except when: - * arguments to `can_invoke_constexpr` can legally be forwarded to [invoke], *and* + * arguments to `is_invokable_constexpr` can legally be forwarded to [invoke], *and* * `std::decay_t` is [link_constexpr_constructible], *and* * `std::decay_t...` are also all [link_constexpr_constructible], *and* * an invocation of the arguments following [invoke] semantics is a constant expression, then: * an instance of `std::true_type` is returned [heading Example - Function Object] -[import ../example/can_invoke_constexpr_function_object.cpp] -[can_invoke_constexpr_function_object] +[import ../example/is_invokable_constexpr_function_object.cpp] +[is_invokable_constexpr_function_object] [heading Example - Member Function Pointer] -[import ../example/can_invoke_constexpr_member_function_pointer.cpp] -[can_invoke_constexpr_member_function_pointer] +[import ../example/is_invokable_constexpr_member_function_pointer.cpp] +[is_invokable_constexpr_member_function_pointer] [heading Example - Function Pointer] -[import ../example/can_invoke_constexpr_function_pointer.cpp] -[can_invoke_constexpr_function_pointer] +[import ../example/is_invokable_constexpr_function_pointer.cpp] +[is_invokable_constexpr_function_pointer] [heading See Also] -* [link_can_invoke] +* [link_is_invokable] * [link_is_constexpr] [endsect] @@ -1676,13 +1675,6 @@ For `has_calling_convention` to work as-intended, you must: [endsect] -[section:ref_is_callable is_callable] -TODO -[heading Example] -[/import ../example/is_callable.cpp] -[is_callable] -[endsect] - [section:ref_has_void_return has_void_return] TODO [heading Example] diff --git a/example/intro.cpp b/example/intro.cpp index 170584f..4fdb715 100644 --- a/example/intro.cpp +++ b/example/intro.cpp @@ -73,13 +73,13 @@ int main() { int i = 0; - // ``[namespace_scoped]``can_invoke allows us to preview whether + // ``[namespace_scoped]``is_invokable allows us to preview whether // std::invoke would compile with the given arguments. - static_assert(ct::can_invoke(foo{}, 0, 0, i), ""); + static_assert(ct::is_invokable(foo{}, 0, 0, i), ""); // no error: std::invoke(foo{}, 0, 0, i); // This call returns std::false_type, because it's an illegal call. - static_assert(!ct::can_invoke(foo{}, nullptr), ""); + static_assert(!ct::is_invokable(foo{}, nullptr), ""); // error: std::invoke(foo{}, nullptr); // For function objects, the following checks are determined by the diff --git a/example/can_invoke_constexpr_function_object.cpp b/example/is_invokable_constexpr_function_object.cpp similarity index 64% rename from example/can_invoke_constexpr_function_object.cpp rename to example/is_invokable_constexpr_function_object.cpp index 43bd5f5..8fb517c 100644 --- a/example/can_invoke_constexpr_function_object.cpp +++ b/example/is_invokable_constexpr_function_object.cpp @@ -4,16 +4,16 @@ 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 #ifdef CALLABLE_TRAITS_DISABLE_CONSTEXPR_CHECKS int main(){ return 0; } #else -//[ can_invoke_constexpr_function_object +//[ is_invokable_constexpr_function_object #include -#include +#include -// NOTE: Due to non-compliance in MSVC, can_invoke_constexpr +// NOTE: Due to non-compliance in MSVC, is_invokable_constexpr // always return std::false_type on that compiler, which causes // the static asserts below to fail. @@ -26,7 +26,7 @@ using T2 = std::integral_constant; // subtracts std::integral_constant types. struct subtract { - // To compile failing cases of can_invoke_constexpr, the function object + // To compile failing cases of is_invokable_constexpr, the function object // must have a SFINAE-safe signature. In this case, 'subtract' is made // SFINAE-safe with an explicit, trailing return type. template @@ -35,12 +35,12 @@ struct subtract { } }; -// can_invoke_constexpr returns std::true_type in the first case, because +// is_invokable_constexpr returns std::true_type in the first case, because // INVOKE(subtract{}, T1{}, T2{}) is a valid expression, AND 'subtract{}' is // a constexpr function object. -static_assert(ct::can_invoke_constexpr(subtract{}, T1{}, T2{}), ""); -static_assert(!ct::can_invoke_constexpr(subtract{}, 3, 7), ""); -static_assert(!ct::can_invoke_constexpr(subtract{}, T1{}), ""); +static_assert(ct::is_invokable_constexpr(subtract{}, T1{}, T2{}), ""); +static_assert(!ct::is_invokable_constexpr(subtract{}, 3, 7), ""); +static_assert(!ct::is_invokable_constexpr(subtract{}, T1{}), ""); //this is a function object, but is NOT constexpr struct add { @@ -51,17 +51,17 @@ struct add { }; // Even though INVOKE(add{}, T1{}, T2{}) is valid, the respective -// can_invoke_constexpr call returns std::false_type because 'add{}' +// is_invokable_constexpr call returns std::false_type because 'add{}' // is not a constexpr function object. -static_assert(!ct::can_invoke_constexpr(add{}, T1{}, T2{}), ""); -static_assert(!ct::can_invoke_constexpr(add{}, 3, 7), ""); +static_assert(!ct::is_invokable_constexpr(add{}, T1{}, T2{}), ""); +static_assert(!ct::is_invokable_constexpr(add{}, 3, 7), ""); -// This last section demonstrates that can_invoke_constexpr will always +// This last section demonstrates that is_invokable_constexpr will always // return std::false_type when any of the arguments do not decay to literal // types. (see http://en.cppreference.com/w/cpp/concept/LiteralType). // Even though 'S' below is a constexpr function object, it is incompatible -// with can_invoke_constexpr because 'S' isn't a literal type. Additionally, +// with is_invokable_constexpr because 'S' isn't a literal type. Additionally, // all arguments must be default constructible. struct S { @@ -71,7 +71,7 @@ struct S { }; S s{0}; -static_assert(!ct::can_invoke_constexpr(s), ""); +static_assert(!ct::is_invokable_constexpr(s), ""); int main() {} diff --git a/example/can_invoke_constexpr_function_pointer.cpp b/example/is_invokable_constexpr_function_pointer.cpp similarity index 58% rename from example/can_invoke_constexpr_function_pointer.cpp rename to example/is_invokable_constexpr_function_pointer.cpp index b192add..e418c34 100644 --- a/example/can_invoke_constexpr_function_pointer.cpp +++ b/example/is_invokable_constexpr_function_pointer.cpp @@ -10,9 +10,9 @@ Distributed under the Boost Software License, Version 1.0. int main(){ return 0; } #else -//[ can_invoke_constexpr_function_pointer +//[ is_invokable_constexpr_function_pointer #include -#include +#include namespace ct = callable_traits; @@ -22,12 +22,12 @@ constexpr int seven(int) { using seven_c = std::integral_constant; -// The first call to can_invoke_constexpr returns std::true_type +// The first call to is_invokable_constexpr returns std::true_type // because `seven` is a constexpr function, and valid INVOKE arguments -// are passed. The second call to can_invoke_constexpr returns +// are passed. The second call to is_invokable_constexpr returns // std::false_type, because the arguments are not valid to INVOKE -static_assert(ct::can_invoke_constexpr(seven_c{}, 0), ""); -static_assert(!ct::can_invoke_constexpr(seven_c{}, nullptr), ""); +static_assert(ct::is_invokable_constexpr(seven_c{}, 0), ""); +static_assert(!ct::is_invokable_constexpr(seven_c{}, nullptr), ""); int eight(int) { return 7; @@ -35,10 +35,10 @@ int eight(int) { using eight_c = std::integral_constant; -// `eight` is NOT a constexpr function, so can_invoke_constexpr +// `eight` is NOT a constexpr function, so is_invokable_constexpr // returns `std::false_type` even for valid INVOKE arguments. -static_assert(!ct::can_invoke_constexpr(eight_c{}, 0), ""); -static_assert(!ct::can_invoke_constexpr(eight_c{}, nullptr), ""); +static_assert(!ct::is_invokable_constexpr(eight_c{}, 0), ""); +static_assert(!ct::is_invokable_constexpr(eight_c{}, nullptr), ""); int main() {} //] diff --git a/example/can_invoke_constexpr_member_function_pointer.cpp b/example/is_invokable_constexpr_member_function_pointer.cpp similarity index 63% rename from example/can_invoke_constexpr_member_function_pointer.cpp rename to example/is_invokable_constexpr_member_function_pointer.cpp index c823a0f..17af062 100644 --- a/example/can_invoke_constexpr_member_function_pointer.cpp +++ b/example/is_invokable_constexpr_member_function_pointer.cpp @@ -10,11 +10,11 @@ Distributed under the Boost Software License, Version 1.0. int main(){ return 0; } #else -//[ can_invoke_constexpr_member_function_pointer +//[ is_invokable_constexpr_member_function_pointer #include -#include +#include -// NOTE: Due to non-compliance in MSVC, can_invoke_constexpr +// NOTE: Due to non-compliance in MSVC, is_invokable_constexpr // always returns std::false_type on that compiler, which // causes a static assert below to fail. @@ -28,13 +28,13 @@ struct foo { using pmf_constant = std::integral_constant; -// can_invoke_constexpr returns true here because foo::bar +// is_invokable_constexpr returns true here because foo::bar // is constexpr, and the arguments are valid to INVOKE -static_assert(ct::can_invoke_constexpr(pmf_constant{}, foo{}, 0), ""); +static_assert(ct::is_invokable_constexpr(pmf_constant{}, foo{}, 0), ""); -// can_invoke_constexpr returns false here because even though +// is_invokable_constexpr returns false here because even though // foo::bar is constexpr, the arguments do not obey INVOKE rules -static_assert(!ct::can_invoke_constexpr(pmf_constant{}, foo{}), ""); +static_assert(!ct::is_invokable_constexpr(pmf_constant{}, foo{}), ""); int main() {} //] diff --git a/example/can_invoke_function_object.cpp b/example/is_invokable_function_object.cpp similarity index 60% rename from example/can_invoke_function_object.cpp rename to example/is_invokable_function_object.cpp index bcad9cc..591ca36 100644 --- a/example/can_invoke_function_object.cpp +++ b/example/is_invokable_function_object.cpp @@ -8,7 +8,7 @@ Distributed under the Boost Software License, Version 1.0. int main(){ return 0; } #else -//[ can_invoke_function_object +//[ is_invokable_function_object #include #include @@ -21,19 +21,19 @@ Bad bad{}; // non-generic callables, such as `subtract` below, // don't have any "gotchas" when passed to -// callable_traits::can_invoke. +// callable_traits::is_invokable. auto subtract = [](int x, int y) { return x + y; }; -static_assert(!ct::can_invoke(subtract), ""); -static_assert(!ct::can_invoke(subtract, 1), ""); -static_assert(ct::can_invoke(subtract, 1, 2), ""); // <-- success -static_assert(!ct::can_invoke(subtract, 1, 2, 3), ""); -static_assert(!ct::can_invoke(subtract, bad, bad), ""); +static_assert(!ct::is_invokable(subtract), ""); +static_assert(!ct::is_invokable(subtract, 1), ""); +static_assert(ct::is_invokable(subtract, 1, 2), ""); // <-- success +static_assert(!ct::is_invokable(subtract, 1, 2, 3), ""); +static_assert(!ct::is_invokable(subtract, bad, bad), ""); // Generic function objects (such as `add` and `multiply` below) -// must be SFINAE-friendly in order for failing can_invoke calls +// must be SFINAE-friendly in order for failing is_invokable calls // to actually compile. This applies to both generic lambdas and // templated function objects. Note: MSVC does not compile this // source code file because of the trailing return type below (MSVC @@ -46,26 +46,26 @@ auto add = [](auto x, auto y) -> decltype(x + y) { template using int_c = std::integral_constant; -static_assert(!ct::can_invoke(add), ""); -static_assert(!ct::can_invoke(add, 1), ""); -static_assert(ct::can_invoke(add, 1, 2), ""); // <-- success -static_assert(!ct::can_invoke(add, 1, 2, 3), ""); -static_assert(!ct::can_invoke(add, bad, bad), ""); +static_assert(!ct::is_invokable(add), ""); +static_assert(!ct::is_invokable(add, 1), ""); +static_assert(ct::is_invokable(add, 1, 2), ""); // <-- success +static_assert(!ct::is_invokable(add, 1, 2, 3), ""); +static_assert(!ct::is_invokable(add, bad, bad), ""); // 'multiply' isn't SFINAE-safe, because the return type depends // on an expression in the body. However, it still works if we -// only try to call can_invoke with arguments where x * y is +// only try to call is_invokable with arguments where x * y is // a valid expression. auto multiply = [](auto x, auto y) { return x * y; }; -static_assert(!ct::can_invoke(multiply), ""); -static_assert(!ct::can_invoke(multiply, 1), ""); -static_assert(ct::can_invoke(multiply, 1, 2), ""); // <-- success -static_assert(!ct::can_invoke(multiply, 1, 2, 3), ""); -//static_assert(!ct::can_invoke(multiply, bad, bad), ""); +static_assert(!ct::is_invokable(multiply), ""); +static_assert(!ct::is_invokable(multiply, 1), ""); +static_assert(ct::is_invokable(multiply, 1, 2), ""); // <-- success +static_assert(!ct::is_invokable(multiply, 1, 2, 3), ""); +//static_assert(!ct::is_invokable(multiply, bad, bad), ""); // The last, commented static_assert above would fail compile, // because the call cannot be SFINAE'd away. Error message in Clang: diff --git a/example/can_invoke_function_pointer.cpp b/example/is_invokable_function_pointer.cpp similarity index 65% rename from example/can_invoke_function_pointer.cpp rename to example/is_invokable_function_pointer.cpp index 6ff98d2..eff02a9 100644 --- a/example/can_invoke_function_pointer.cpp +++ b/example/is_invokable_function_pointer.cpp @@ -4,7 +4,7 @@ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) ->*/ -//[ can_invoke_function_pointer +//[ is_invokable_function_pointer #include namespace ct = callable_traits; @@ -13,16 +13,16 @@ int foo(int&& i) { return i; } -// can_invoke returns std::true_type here because the +// is_invokable returns std::true_type here because the // arguments are valid to INVOKE -static_assert(ct::can_invoke(&foo, 0), ""); +static_assert(ct::is_invokable(&foo, 0), ""); int i = 0; -// can_invoke returns std::false_type here because the +// is_invokable returns std::false_type here because the // arguments are NOT valid to INVOKE - foo expects an // rvalue reference, not an lvalue reference. -static_assert(!ct::can_invoke(&foo, i), ""); +static_assert(!ct::is_invokable(&foo, i), ""); int main() {} //] diff --git a/example/can_invoke_function_reference.cpp b/example/is_invokable_function_reference.cpp similarity index 65% rename from example/can_invoke_function_reference.cpp rename to example/is_invokable_function_reference.cpp index 7264be5..977a01d 100644 --- a/example/can_invoke_function_reference.cpp +++ b/example/is_invokable_function_reference.cpp @@ -4,7 +4,7 @@ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) ->*/ -//[ can_invoke_function_reference +//[ is_invokable_function_reference #include namespace ct = callable_traits; @@ -13,16 +13,16 @@ int foo(int&& i) { return i; } -// can_invoke returns std::true_type here because the +// is_invokable returns std::true_type here because the // arguments are valid to INVOKE -static_assert(ct::can_invoke(foo, 0), ""); +static_assert(ct::is_invokable(foo, 0), ""); int i = 0; -// can_invoke returns std::false_type here because the +// is_invokable returns std::false_type here because the // arguments are NOT valid to INVOKE - foo expects an // rvalue reference, not an lvalue reference. -static_assert(!ct::can_invoke(foo, i), ""); +static_assert(!ct::is_invokable(foo, i), ""); int main() {} //] diff --git a/example/can_invoke_member_function_pointer.cpp b/example/is_invokable_member_function_pointer.cpp similarity index 64% rename from example/can_invoke_member_function_pointer.cpp rename to example/is_invokable_member_function_pointer.cpp index 159a598..69853a7 100644 --- a/example/can_invoke_member_function_pointer.cpp +++ b/example/is_invokable_member_function_pointer.cpp @@ -4,7 +4,7 @@ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) ->*/ -//[ can_invoke_member_function_pointer +//[ is_invokable_member_function_pointer #include namespace ct = callable_traits; @@ -15,14 +15,14 @@ struct foo { } }; -// can_invoke returns std::true_type here because the +// is_invokable returns std::true_type here because the // arguments are valid to INVOKE -static_assert(ct::can_invoke(&foo::bar, foo{}, 0), ""); +static_assert(ct::is_invokable(&foo::bar, foo{}, 0), ""); -// can_invoke returns std::false_type here because the +// is_invokable returns std::false_type here because the // arguments are NOT valid to INVOKE - foo::bar can't be // invoked like a void member function. -static_assert(!ct::can_invoke(&foo::bar, foo{}), ""); +static_assert(!ct::is_invokable(&foo::bar, foo{}), ""); int main() {} diff --git a/example/overview.cpp b/example/overview.cpp index 95ccec8..6a813a8 100644 --- a/example/overview.cpp +++ b/example/overview.cpp @@ -94,8 +94,8 @@ static_assert(!is_volatile_member(), ""); static_assert(!has_void_return(), ""); static_assert(!is_constexpr>(), ""); static_assert(!has_varargs(), ""); -static_assert(can_invoke(), ""); -static_assert(!can_invoke(), ""); +static_assert(is_invokable(), ""); +static_assert(!is_invokable(), ""); //` You can use [libname] to manipulate parameter lists (not defined in terms of INVOKE, since that wouldn't make sense here): diff --git a/include/callable_traits/callable_traits.hpp b/include/callable_traits/callable_traits.hpp index 0739b64..3f4f749 100644 --- a/include/callable_traits/callable_traits.hpp +++ b/include/callable_traits/callable_traits.hpp @@ -25,8 +25,8 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/include/callable_traits/detail/can_invoke_constexpr_impl.hpp b/include/callable_traits/detail/is_invokable_constexpr_impl.hpp similarity index 90% rename from include/callable_traits/detail/can_invoke_constexpr_impl.hpp rename to include/callable_traits/detail/is_invokable_constexpr_impl.hpp index 8692ee1..c539b52 100644 --- a/include/callable_traits/detail/can_invoke_constexpr_impl.hpp +++ b/include/callable_traits/detail/is_invokable_constexpr_impl.hpp @@ -1,5 +1,5 @@ -#ifndef CALLABLE_TRAITS_DETAIL_CAN_INVOKE_CONSTEXPR_T_HPP -#define CALLABLE_TRAITS_DETAIL_CAN_INVOKE_CONSTEXPR_T_HPP +#ifndef CALLABLE_TRAITS_DETAIL_IS_INVOKABLE_CONSTEXPR_T_HPP +#define CALLABLE_TRAITS_DETAIL_IS_INVOKABLE_CONSTEXPR_T_HPP #include #include @@ -16,12 +16,12 @@ namespace callable_traits { #ifdef CALLABLE_TRAITS_DISABLE_CONSTEXPR_CHECKS inline constexpr auto - can_invoke_constexpr_impl(...) { + is_invokable_constexpr_impl(...) { return std::false_type{}; } template - struct can_invoke_constexpr_impl_types { + struct is_invokable_constexpr_impl_types { using type = std::false_type; }; @@ -87,14 +87,14 @@ namespace callable_traits { template>::value, int>::type = 0> inline constexpr auto - can_invoke_constexpr_impl(T&&, Args&&...) { + is_invokable_constexpr_impl(T&&, Args&&...) { return std::false_type{}; } template::value, int>::type = 0> inline constexpr auto - can_invoke_constexpr_impl(T&& t, Args&&... args) { + is_invokable_constexpr_impl(T&& t, Args&&... args) { using traits = traits; using test = test_invoke_constexpr; using result = decltype(test{}(::std::forward(t), ::std::forward(args)...)); @@ -103,12 +103,12 @@ namespace callable_traits { } template - struct can_invoke_constexpr_impl_types { + struct is_invokable_constexpr_impl_types { using type = std::false_type; }; template - struct can_invoke_constexpr_impl_types { + struct is_invokable_constexpr_impl_types { using test = test_invoke_constexpr, Args...>; using result = decltype(test{}( ::std::declval(), ::std::declval()...)); @@ -121,5 +121,5 @@ namespace callable_traits { #endif //ifndef CALLABLE_TRAITS_DISABLE_CONSTEXPR_CHECKS } } -#endif // CALLABLE_TRAITS_DETAIL_CAN_INVOKE_CONSTEXPR_T_HPP +#endif // CALLABLE_TRAITS_DETAIL_IS_INVOKABLE_CONSTEXPR_T_HPP diff --git a/include/callable_traits/detail/can_invoke_impl.hpp b/include/callable_traits/detail/is_invokable_impl.hpp similarity index 83% rename from include/callable_traits/detail/can_invoke_impl.hpp rename to include/callable_traits/detail/is_invokable_impl.hpp index 18a1f2c..19d60ad 100644 --- a/include/callable_traits/detail/can_invoke_impl.hpp +++ b/include/callable_traits/detail/is_invokable_impl.hpp @@ -1,5 +1,5 @@ -#ifndef CALLABLE_TRAITS_DETAIL_CAN_INVOKE_IMPL_HPP -#define CALLABLE_TRAITS_DETAIL_CAN_INVOKE_IMPL_HPP +#ifndef CALLABLE_TRAITS_DETAIL_IS_INVOKABLE_IMPL_HPP +#define CALLABLE_TRAITS_DETAIL_IS_INVOKABLE_IMPL_HPP #include #include @@ -12,7 +12,7 @@ namespace callable_traits { template inline constexpr auto - can_invoke_impl(T&& t, Args&&... args) { + is_invokable_impl(T&& t, Args&&... args) { using traits = detail::traits; using test = detail::test_invoke; using result = decltype(test{}(::std::forward(t), ::std::forward(args)...)); @@ -23,7 +23,7 @@ namespace callable_traits { template inline constexpr auto - can_invoke_impl() { + is_invokable_impl() { using traits = detail::traits; using test = detail::test_invoke; using result = decltype(test{}(::std::declval(), ::std::declval()...)); @@ -34,5 +34,5 @@ namespace callable_traits { } } -#endif // CALLABLE_TRAITS_DETAIL_CAN_INVOKE_IMPL_HPP +#endif // CALLABLE_TRAITS_DETAIL_IS_INVOKABLE_IMPL_HPP diff --git a/include/callable_traits/is_callable.hpp b/include/callable_traits/is_callable.hpp deleted file mode 100644 index a02b37d..0000000 --- a/include/callable_traits/is_callable.hpp +++ /dev/null @@ -1,32 +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_IS_CALLABLE_HPP -#define CALLABLE_TRAITS_IS_CALLABLE_HPP - -#include -#include -#include - -namespace callable_traits { - - template - static constexpr inline auto - is_callable() { - return std::integral_constant().value >= 0>{}; - } - - template - static constexpr inline auto - is_callable(T&&) { - return is_callable(); - } -} - -#endif //CALLABLE_TRAITS_IS_CALLABLE_HPP diff --git a/include/callable_traits/can_invoke.hpp b/include/callable_traits/is_invokable.hpp similarity index 62% rename from include/callable_traits/can_invoke.hpp rename to include/callable_traits/is_invokable.hpp index ce78d27..705369c 100644 --- a/include/callable_traits/can_invoke.hpp +++ b/include/callable_traits/is_invokable.hpp @@ -7,10 +7,10 @@ Distributed under the Boost Software License, Version 1.0. */ -#ifndef CALLABLE_TRAITS_CAN_INVOKE_HPP -#define CALLABLE_TRAITS_CAN_INVOKE_HPP +#ifndef CALLABLE_TRAITS_IS_INVOKABLE_HPP +#define CALLABLE_TRAITS_IS_INVOKABLE_HPP -#include +#include #include #include @@ -18,16 +18,16 @@ namespace callable_traits { template inline constexpr auto - can_invoke(Args&&... args) { - return detail::can_invoke_impl( + is_invokable(Args&&... args) { + return detail::is_invokable_impl( ::std::forward(args)... ); } template inline constexpr auto - can_invoke() { - return detail::can_invoke_impl(); + is_invokable() { + return detail::is_invokable_impl(); } } diff --git a/include/callable_traits/can_invoke_constexpr.hpp b/include/callable_traits/is_invokable_constexpr.hpp similarity index 65% rename from include/callable_traits/can_invoke_constexpr.hpp rename to include/callable_traits/is_invokable_constexpr.hpp index 5b054b0..e3dde6f 100644 --- a/include/callable_traits/can_invoke_constexpr.hpp +++ b/include/callable_traits/is_invokable_constexpr.hpp @@ -7,10 +7,10 @@ Distributed under the Boost Software License, Version 1.0. */ -#ifndef CALLABLE_TRAITS_CAN_INVOKE_CONSTEXPR_HPP -#define CALLABLE_TRAITS_CAN_INVOKE_CONSTEXPR_HPP +#ifndef CALLABLE_TRAITS_IS_INVOKABLE_CONSTEXPR_HPP +#define CALLABLE_TRAITS_IS_INVOKABLE_CONSTEXPR_HPP -#include +#include #include #include @@ -18,8 +18,8 @@ namespace callable_traits { template inline constexpr auto - can_invoke_constexpr(T&& t, Args&&... args) { - return detail::can_invoke_constexpr_impl( + is_invokable_constexpr(T&& t, Args&&... args) { + return detail::is_invokable_constexpr_impl( ::std::forward(t), ::std::forward(args)... ); @@ -27,10 +27,10 @@ namespace callable_traits { template inline constexpr auto - can_invoke_constexpr() { + is_invokable_constexpr() { using are_constexpr_constructible = detail::are_all_constexpr_constructible; - return typename detail::can_invoke_constexpr_impl_types< + return typename detail::is_invokable_constexpr_impl_types< are_constexpr_constructible::value, Args...>::type{}; } } diff --git a/qtcreator/main/main.cpp b/qtcreator/main/main.cpp index 95ccec8..2e79fc4 100644 --- a/qtcreator/main/main.cpp +++ b/qtcreator/main/main.cpp @@ -1,143 +1,70 @@ -/*<- -Copyright Barrett Adair 2016 +/* + +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) -->*/ +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -#include -#ifdef CALLABLE_TRAITS_DISABLE_ABOMINABLE_FUNCTIONS -int main(){} -#else - - - -//[ overview -#include +*/ #include -#include +#include +#include +#include -using std::is_same; -using std::tuple; +#ifndef CT_ASSERT +#define CT_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) +#endif //CT_ASSERT -using namespace callable_traits; - -struct number { - int value; - auto add(int n) const { return value + n; } +struct foo1 { + int bar(char, float&, int = 0) { return{}; } }; -using pmf = decltype(&number::add); +struct foo2 { + int bar(char, float&, int = 0, ...) { return{}; } +}; -//` Manipulate member functions pointers with ease: -static_assert(is_same< - remove_member_const, - int(number::*)(int) ->{}, ""); +struct foo3 { + int operator()(char, float&, int = 0) { return{}; } +}; -static_assert(is_same< - add_member_volatile, - int(number::*)(int) const volatile ->{}, ""); +struct foo4 { + int operator()(char, float&, int = 0, ...) { return{}; } +}; -static_assert(is_same< - parent_class_of, - number ->{}, ""); +int foo5(char, float&, int = 0) { return{}; } -static_assert(is_same< - remove_member_pointer, - int (int) const ->{}, ""); +int foo6(char, float&, int = 0, ...) { return{}; } -//` INVOKE-aware metafunctions: +struct foo7 { + int bar() { return{}; } +}; -static_assert(is_same< - args, - tuple ->{}, ""); +namespace ct = callable_traits; +using std::is_same; -static_assert(is_same< - arg_at<0, pmf>, - const number& ->{}, ""); +int main() { -static_assert(is_same< - arg_at<1, pmf>, - int ->{}, ""); + { + using pmf = decltype(&foo1::bar); + using args = ct::args; + CT_ASSERT(is_same>{}); + } { + using pmf = decltype(&foo2::bar); + using args = ct::args; + CT_ASSERT(is_same>{}); + } { + using args = ct::args; + CT_ASSERT(is_same>{}); + } { + using args = ct::args; + CT_ASSERT(is_same>{}); + } { + using args = ct::args; + CT_ASSERT(is_same>{}); + } { + using args = ct::args; + CT_ASSERT(is_same>{}); + } -static_assert(is_same< - result_of, - int ->{}, ""); - -static_assert(is_same< - function_type, - int(const number&, int) ->{}, ""); - -static_assert(is_same< - qualified_parent_class_of, - const number& ->{}, ""); - -//` `arity` is defined as the number of parameters to a callable type. This is defined in terms of INVOKE, so that member function pointers always have an arity of at least one: -static_assert(arity(&number::add) == 2, ""); - -//` The [libname] interface uses constexpr function templates for type traits, which accept values and return `integral_constant`s. However, if you don't have any values lying around, you can always use types instead. We'll use types in the rest of the overview: -static_assert(arity() == 2, ""); // same as above, but with a type instead of a value - -//` Here are a few other trait examples: -static_assert(is_const_member(), ""); -static_assert(!is_volatile_member(), ""); -static_assert(!has_void_return(), ""); -static_assert(!is_constexpr>(), ""); -static_assert(!has_varargs(), ""); -static_assert(can_invoke(), ""); -static_assert(!can_invoke(), ""); - -//` You can use [libname] to manipulate parameter lists (not defined in terms of INVOKE, since that wouldn't make sense here): - -using pmf_2 = push_back; - -static_assert(is_same< - pmf_2, - int(number::*)(int, char, short, long) const ->{}, ""); - -static_assert(is_same< - pop_front, - int(number::*)(char, short, long) const ->{}, ""); - -static_assert(is_same< - insert_args<2, pmf_2, short*, long*>, - int(number::*)(int, char, short*, long*, short, long) const ->{}, ""); - -static_assert(is_same< - replace_args<2, pmf_2, short*, long*>, - int(number::*)(int, char, short*, long*) const ->{}, ""); - -static_assert(is_same< - remove_args<2, pmf_2>, - int(number::*)(int, char, long) const ->{}, ""); - -static_assert(is_same< - clear_args, - int(number::*)() const ->{}, ""); - -static_assert(is_same< - add_varargs, - int(number::*)(int, char, short, long, ...) const ->{}, ""); - -//] - -int main() {} - -#endif + return 0; +} diff --git a/test/can_invoke.cpp b/test/can_invoke.cpp deleted file mode 100644 index b86d4ad..0000000 --- a/test/can_invoke.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - -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) - -*/ - -#include -#include -#include -#include - -#ifndef CT_ASSERT -#define CT_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) -#endif //CT_ASSERT - -struct foo1 { - int bar(char, float&, int = 0) { return{}; } -}; - -struct foo2 { - int bar(char, float&, int = 0, ...) { return{}; } -}; - -struct foo3 { - int operator()(char, float&, int = 0) { return{}; } -}; - -struct foo4 { - int operator()(char, float&, int = 0, ...) { return{}; } -}; - -int foo5(char, float&, int = 0) { return{}; } - -int foo6(char, float&, int = 0, ...) { return{}; } - -namespace ct = callable_traits; -using std::is_same; - -int main() { - - { - float f = 3.0; - foo1 foo{}; - - CT_ASSERT(decltype(ct::can_invoke(&foo1::bar, foo1{}, 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(&foo1::bar, foo1{}, 'a', 3.0, 1)){}); - CT_ASSERT(decltype(ct::can_invoke(&foo1::bar, std::declval(), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(&foo1::bar, std::declval(), 'a', 3.0, 1)){}); - CT_ASSERT(decltype(ct::can_invoke(&foo1::bar, std::declval>(), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(&foo1::bar, std::declval>(), 'a', 3.0, 1)){}); - CT_ASSERT(decltype(ct::can_invoke(&foo1::bar, std::ref(foo), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(&foo1::bar, std::ref(foo), 'a', 3.0, 1)){}); - - //todo - more of these type-level tests - CT_ASSERT(decltype(ct::can_invoke()){}); - CT_ASSERT(!decltype(ct::can_invoke()){}); - CT_ASSERT(decltype(ct::can_invoke()){}); - CT_ASSERT(!decltype(ct::can_invoke()){}); - } { - float f = 3.0; - foo2 foo{}; - - CT_ASSERT(decltype(ct::can_invoke(&foo2::bar, foo2{}, 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(&foo2::bar, foo2{}, 'a', 3.0, 1)){}); - CT_ASSERT(decltype(ct::can_invoke(&foo2::bar, std::declval(), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(&foo2::bar, std::declval(), 'a', 3.0, 1)){}); - CT_ASSERT(decltype(ct::can_invoke(&foo2::bar, std::declval>(), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(&foo2::bar, std::declval>(), 'a', 3.0, 1)){}); - CT_ASSERT(decltype(ct::can_invoke(&foo2::bar, std::ref(foo), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(&foo2::bar, std::ref(foo), 'a', 3.0, 1)){}); - } { - float f = 3.0; - foo3 foo{}; - - CT_ASSERT(decltype(ct::can_invoke(foo3{}, 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(foo3{}, 'a', 3.0, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(std::declval(), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(std::declval(), 'a', 3.0, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(std::declval>(), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(std::declval>(), 'a', 3.0, 1)){}); - CT_ASSERT(decltype(ct::can_invoke(std::ref(foo), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(std::ref(foo), 'a', 3.0, 1)){}); - } { - float f = 3.0; - foo4 foo{}; - - CT_ASSERT(decltype(ct::can_invoke(foo4{}, 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(foo4{}, 'a', 3.0, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(std::declval(), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(std::declval(), 'a', 3.0, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(std::declval>(), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(std::declval>(), 'a', 3.0, 1)){}); - CT_ASSERT(decltype(ct::can_invoke(std::ref(foo), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(std::ref(foo), 'a', 3.0, 1)){}); - } { - float f = 3.0; - - CT_ASSERT(decltype(ct::can_invoke(foo5, 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(foo5, 'a', 3.0, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(&foo5, 'a', 3.0, 1)){}); - CT_ASSERT(decltype(ct::can_invoke(std::ref(foo5), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(std::ref(foo5), 'a', 3.0, 1)){}); - } { - float f = 3.0; - - CT_ASSERT(decltype(ct::can_invoke(foo6, 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(foo6, 'a', 3.0, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(&foo6, 'a', 3.0, 1)){}); - CT_ASSERT(decltype(ct::can_invoke(std::ref(foo6), 'a', f, 1)){}); - CT_ASSERT(!decltype(ct::can_invoke(std::ref(foo6), 'a', 3.0, 1)){}); - } - - return 0; -} diff --git a/test/can_invoke_constexpr.cpp b/test/can_invoke_constexpr.cpp deleted file mode 100644 index bb872ef..0000000 --- a/test/can_invoke_constexpr.cpp +++ /dev/null @@ -1,87 +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) -*/ - -#include -#include - -#ifdef CALLABLE_TRAITS_DISABLE_CONSTEXPR_CHECKS -int main(){ return 0; } -#else - -#ifndef CT_ASSERT -#define CT_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) -#endif //CT_ASSERT - -struct foo1 { - int operator()() const { - return 0; - } -}; - -struct foo2 { - constexpr int operator()(int) const { - return 1; - } - constexpr int operator()() const { - return 1; - } -}; - -struct foo3 { - constexpr int bar(int) const { - return 1; - } -}; - -constexpr int bar(const int&) { - return 1; -} - -using foo4 = std::integral_constant; - -using foo1_pmf = std::integral_constant; -using foo3_pmf = std::integral_constant; - -namespace ct = callable_traits; - -// value syntax -CT_ASSERT(!ct::can_invoke_constexpr(foo1{})); -CT_ASSERT(!ct::can_invoke_constexpr(foo1{}, 0)); - -CT_ASSERT( ct::can_invoke_constexpr(foo2{})); -CT_ASSERT( ct::can_invoke_constexpr(foo2{}, 0)); - -CT_ASSERT(!ct::can_invoke_constexpr(foo4{})); -CT_ASSERT( ct::can_invoke_constexpr(foo4{}, 0)); - -CT_ASSERT(!ct::can_invoke_constexpr(foo1_pmf{}, foo1{})); -CT_ASSERT(!ct::can_invoke_constexpr(foo1_pmf{}, foo1{}, 0)); - -CT_ASSERT(!ct::can_invoke_constexpr(foo3_pmf{}, foo3{})); -CT_ASSERT( ct::can_invoke_constexpr(foo3_pmf{}, foo3{}, 0)); - - - -// type syntax -CT_ASSERT(!ct::can_invoke_constexpr()); -CT_ASSERT(!ct::can_invoke_constexpr()); - -CT_ASSERT( ct::can_invoke_constexpr()); -CT_ASSERT( ct::can_invoke_constexpr()); - -CT_ASSERT(!ct::can_invoke_constexpr()); -CT_ASSERT( ct::can_invoke_constexpr()); - -CT_ASSERT(!ct::can_invoke_constexpr()); -CT_ASSERT(!ct::can_invoke_constexpr()); - -CT_ASSERT(!ct::can_invoke_constexpr()); -CT_ASSERT( ct::can_invoke_constexpr()); - -int main() {} - -#endif diff --git a/test/is_callable.cpp b/test/is_callable.cpp deleted file mode 100644 index 7bc32d1..0000000 --- a/test/is_callable.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include - -#ifndef CT_ASSERT -#define CT_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) -#endif //CT_ASSERT - -namespace callable_traits { - - template - static constexpr inline auto - is_callable() { - return std::integral_constant().value >= 0>{}; - } - - template - static constexpr inline auto - is_callable(T&&) { - return is_callable(); - } -} - -namespace ct = callable_traits; - -void foo() {} - -struct bar { - template - auto operator()(T&& t) { - return t; - } -}; - -static_assert(ct::is_callable(foo), ""); -static_assert(ct::is_callable(&foo), ""); -static_assert(ct::is_callable(), ""); -static_assert(ct::is_callable(), ""); -static_assert(ct::is_callable(), ""); - -#ifndef CALLABLE_TRAITS_DISABLE_ARITY_RANGE -static_assert(ct::is_callable(bar{}), ""); -#endif //#ifndef CALLABLE_TRAITS_DISABLE_ARITY_RANGES - -int main() {} diff --git a/test/is_invokable.cpp b/test/is_invokable.cpp new file mode 100644 index 0000000..21978b5 --- /dev/null +++ b/test/is_invokable.cpp @@ -0,0 +1,116 @@ +/* + +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) + +*/ + +#include +#include +#include +#include + +#ifndef CT_ASSERT +#define CT_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) +#endif //CT_ASSERT + +struct foo1 { + int bar(char, float&, int = 0) { return{}; } +}; + +struct foo2 { + int bar(char, float&, int = 0, ...) { return{}; } +}; + +struct foo3 { + int operator()(char, float&, int = 0) { return{}; } +}; + +struct foo4 { + int operator()(char, float&, int = 0, ...) { return{}; } +}; + +int foo5(char, float&, int = 0) { return{}; } + +int foo6(char, float&, int = 0, ...) { return{}; } + +namespace ct = callable_traits; +using std::is_same; + +int main() { + + { + float f = 3.0; + foo1 foo{}; + + CT_ASSERT(decltype(ct::is_invokable(&foo1::bar, foo1{}, 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(&foo1::bar, foo1{}, 'a', 3.0, 1)){}); + CT_ASSERT(decltype(ct::is_invokable(&foo1::bar, std::declval(), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(&foo1::bar, std::declval(), 'a', 3.0, 1)){}); + CT_ASSERT(decltype(ct::is_invokable(&foo1::bar, std::declval>(), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(&foo1::bar, std::declval>(), 'a', 3.0, 1)){}); + CT_ASSERT(decltype(ct::is_invokable(&foo1::bar, std::ref(foo), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(&foo1::bar, std::ref(foo), 'a', 3.0, 1)){}); + + //todo - more of these type-level tests + CT_ASSERT(decltype(ct::is_invokable()){}); + CT_ASSERT(!decltype(ct::is_invokable()){}); + CT_ASSERT(decltype(ct::is_invokable()){}); + CT_ASSERT(!decltype(ct::is_invokable()){}); + } { + float f = 3.0; + foo2 foo{}; + + CT_ASSERT(decltype(ct::is_invokable(&foo2::bar, foo2{}, 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(&foo2::bar, foo2{}, 'a', 3.0, 1)){}); + CT_ASSERT(decltype(ct::is_invokable(&foo2::bar, std::declval(), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(&foo2::bar, std::declval(), 'a', 3.0, 1)){}); + CT_ASSERT(decltype(ct::is_invokable(&foo2::bar, std::declval>(), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(&foo2::bar, std::declval>(), 'a', 3.0, 1)){}); + CT_ASSERT(decltype(ct::is_invokable(&foo2::bar, std::ref(foo), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(&foo2::bar, std::ref(foo), 'a', 3.0, 1)){}); + } { + float f = 3.0; + foo3 foo{}; + + CT_ASSERT(decltype(ct::is_invokable(foo3{}, 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(foo3{}, 'a', 3.0, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(std::declval(), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(std::declval(), 'a', 3.0, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(std::declval>(), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(std::declval>(), 'a', 3.0, 1)){}); + CT_ASSERT(decltype(ct::is_invokable(std::ref(foo), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(std::ref(foo), 'a', 3.0, 1)){}); + } { + float f = 3.0; + foo4 foo{}; + + CT_ASSERT(decltype(ct::is_invokable(foo4{}, 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(foo4{}, 'a', 3.0, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(std::declval(), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(std::declval(), 'a', 3.0, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(std::declval>(), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(std::declval>(), 'a', 3.0, 1)){}); + CT_ASSERT(decltype(ct::is_invokable(std::ref(foo), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(std::ref(foo), 'a', 3.0, 1)){}); + } { + float f = 3.0; + + CT_ASSERT(decltype(ct::is_invokable(foo5, 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(foo5, 'a', 3.0, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(&foo5, 'a', 3.0, 1)){}); + CT_ASSERT(decltype(ct::is_invokable(std::ref(foo5), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(std::ref(foo5), 'a', 3.0, 1)){}); + } { + float f = 3.0; + + CT_ASSERT(decltype(ct::is_invokable(foo6, 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(foo6, 'a', 3.0, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(&foo6, 'a', 3.0, 1)){}); + CT_ASSERT(decltype(ct::is_invokable(std::ref(foo6), 'a', f, 1)){}); + CT_ASSERT(!decltype(ct::is_invokable(std::ref(foo6), 'a', 3.0, 1)){}); + } + + return 0; +} diff --git a/test/is_invokable_constexpr.cpp b/test/is_invokable_constexpr.cpp new file mode 100644 index 0000000..6655962 --- /dev/null +++ b/test/is_invokable_constexpr.cpp @@ -0,0 +1,87 @@ +/*! +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) +*/ + +#include +#include + +#ifdef CALLABLE_TRAITS_DISABLE_CONSTEXPR_CHECKS +int main(){ return 0; } +#else + +#ifndef CT_ASSERT +#define CT_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) +#endif //CT_ASSERT + +struct foo1 { + int operator()() const { + return 0; + } +}; + +struct foo2 { + constexpr int operator()(int) const { + return 1; + } + constexpr int operator()() const { + return 1; + } +}; + +struct foo3 { + constexpr int bar(int) const { + return 1; + } +}; + +constexpr int bar(const int&) { + return 1; +} + +using foo4 = std::integral_constant; + +using foo1_pmf = std::integral_constant; +using foo3_pmf = std::integral_constant; + +namespace ct = callable_traits; + +// value syntax +CT_ASSERT(!ct::is_invokable_constexpr(foo1{})); +CT_ASSERT(!ct::is_invokable_constexpr(foo1{}, 0)); + +CT_ASSERT( ct::is_invokable_constexpr(foo2{})); +CT_ASSERT( ct::is_invokable_constexpr(foo2{}, 0)); + +CT_ASSERT(!ct::is_invokable_constexpr(foo4{})); +CT_ASSERT( ct::is_invokable_constexpr(foo4{}, 0)); + +CT_ASSERT(!ct::is_invokable_constexpr(foo1_pmf{}, foo1{})); +CT_ASSERT(!ct::is_invokable_constexpr(foo1_pmf{}, foo1{}, 0)); + +CT_ASSERT(!ct::is_invokable_constexpr(foo3_pmf{}, foo3{})); +CT_ASSERT( ct::is_invokable_constexpr(foo3_pmf{}, foo3{}, 0)); + + + +// type syntax +CT_ASSERT(!ct::is_invokable_constexpr()); +CT_ASSERT(!ct::is_invokable_constexpr()); + +CT_ASSERT( ct::is_invokable_constexpr()); +CT_ASSERT( ct::is_invokable_constexpr()); + +CT_ASSERT(!ct::is_invokable_constexpr()); +CT_ASSERT( ct::is_invokable_constexpr()); + +CT_ASSERT(!ct::is_invokable_constexpr()); +CT_ASSERT(!ct::is_invokable_constexpr()); + +CT_ASSERT(!ct::is_invokable_constexpr()); +CT_ASSERT( ct::is_invokable_constexpr()); + +int main() {} + +#endif diff --git a/test/can_invoke_libcxx.cpp b/test/is_invokable_libcxx.cpp similarity index 97% rename from test/can_invoke_libcxx.cpp rename to test/is_invokable_libcxx.cpp index ca4f5ac..a51c7a2 100644 --- a/test/can_invoke_libcxx.cpp +++ b/test/is_invokable_libcxx.cpp @@ -1,7 +1,7 @@ //TODO how to accomodate Boost license? //These are the libc++ tests for std::functional. I've modified them -//slightly to instead test callable_traits::can_invoke +//slightly to instead test callable_traits::is_invokable //===----------------------------------------------------------------------===// // @@ -102,7 +102,7 @@ void test_b12(Functor&& f) { // Run invoke and check the return value. auto ret = - ct::can_invoke(func_ptr, std::forward(f), std::move(arg)); + ct::is_invokable(func_ptr, std::forward(f), std::move(arg)); //assert(ret == 42); CT_ASSERT(decltype(ret){}); } @@ -115,7 +115,7 @@ void test_b34(Functor&& f) { // Run invoke and check the return value. auto ret = - ct::can_invoke(func_ptr, std::forward(f)); + ct::is_invokable(func_ptr, std::forward(f)); //assert(ret == 42); CT_ASSERT(decltype(ret){}); } @@ -125,7 +125,7 @@ void test_b5(Functor&& f) { NonCopyable arg; // Run invoke and check the return value. - auto ret = ct::can_invoke(std::forward(f), std::move(arg)); + auto ret = ct::is_invokable(std::forward(f), std::move(arg)); //assert(ret == 42); CT_ASSERT(decltype(ret){}); }