diff --git a/doc/callable_traits.qbk b/doc/callable_traits.qbk index d448759..b904bbd 100644 --- a/doc/callable_traits.qbk +++ b/doc/callable_traits.qbk @@ -357,60 +357,9 @@ To include the experimental examples for calling conventions in the build, appen [import ../include/callable_traits/apply_return.hpp] [apply_return_hpp] -[section:ref_apply_return apply_return] +[import ../include/callable_traits/arg_at.hpp] +[arg_at_hpp] -[heading Constraints] - -`T` must be a [link_signature] or a [link_pmd]. - -[heading Behavior] -* `apply_return` aliases [^[*NewReturn] [Category] ( [Args] [VarArgs] ) [MemberQualifiers]] - -[heading Example] -[/import ../example/apply_return.cpp] -[apply_return] - -[endsect][/section:ref_apply_return] - - - - -[section:ref_arg_at arg_at] - - namespace ``[lib_namespace]`` { - - template - using arg_at = /* implementation-defined */; - - } - -[heading Constraints] -* `T` must be one of the following: - * [link_signature] - * [link_simple_fn_obj] -* 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 - -[heading Behavior] -* If any constraints are violated, a substitution failure occurs -* Otherwise, `arg_at` aliases `std::tuple_element_t>`, such that: - * `arg_at<0, void(char, short, long, int*)>` aliases `char` - * `arg_at<1, void(*)(char, short, long, int*)>` aliases `short` - * `arg_at<2, void(&)(char, short, long, int*)>` aliases `long` - -[heading Example] -[/import ../example/arg_at.cpp] -[arg_at] - -[/[heading See Also] -* [link_args] -* [link_expand_args]] - -[endsect][/section:ref_arg_at] diff --git a/doc/html/callable_traits/ref_add_member_const.html b/doc/html/callable_traits/ref_add_member_const.html index 7739f32..abe3bce 100644 --- a/doc/html/callable_traits/ref_add_member_const.html +++ b/doc/html/callable_traits/ref_add_member_const.html @@ -26,41 +26,52 @@ +

+ + Header +

+
#include<callable_traits/add_member_const.hpp>
+

+ + Definition +

namespace callable_traits {
 
     template<typename T>
-    struct add_member_const {
-
-        using type = //implementation-defined
-    };
+    using add_member_const_t = //implementation-defined
 
     template<typename T>
-    using add_member_const_t = typename add_member_const<T>::type;
+    struct add_member_const {
+        using type = add_member_const_t<T>;
+    };
 }
 

- + Constraints

  • - T must be a function or - a member function pointer + T must be a function type + or a member function pointer type

- + Behavior

    +
  • + A substitution failure occuers if the constraints are violated +
  • Adds a member const qualifier to T, if not already present
  • -
  • +

- - Input/Output - Examples -

+ + Input/Output + Examples +
@@ -68,180 +79,178 @@ +

+ T +

+ +

+ add_member_const_t<T> +

+ +

+ int() +

+ +

+ int() + const +

+ +

+ int(foo::*)() +

+ +

+ int(foo::*)() + const +

+ +

+ int(foo::*)() + & +

+ +

+ int(foo::*)() + const & +

+ +

+ int(foo::*)() + && +

+ +

+ int(foo::*)() + const && +

+ +

+ int(foo::*)() + const +

+ +

+ int(foo::*)() + const +

+ +

+ int(foo::*)() + volatile +

+ +

+ int(foo::*)() + const volatile +

+ +

+ int(foo::*)() + transaction_safe +

+ +

+ int(foo::*)() + const transaction_safe +

+ +

+ int +

+ +

+ (substitution failure) +

+ +

+ int (&)() +

+ +

+ (substitution failure) +

+ +

+ int (*)() +

+ +

+ (substitution failure) +

+ +

+ int foo::* +

+ +

+ (substitution failure) +

+ +

+ int (foo::* + const)() +

+ +

+ (substitution failure) +

+
-

- T -

-
-

- add_member_const_t<T> -

-
-

- int() -

-
-

- int() - const -

-
-

- int(foo::*)() -

-
-

- int(foo::*)() - const -

-
-

- int(foo::*)() - & -

-
-

- int(foo::*)() - const & -

-
-

- int(foo::*)() - && -

-
-

- int(foo::*)() - const && -

-
-

- int(foo::*)() - const -

-
-

- int(foo::*)() - const -

-
-

- int(foo::*)() - volatile -

-
-

- int(foo::*)() - const volatile -

-
-

- int(foo::*)() - transaction_safe -

-
-

- int(foo::*)() - const transaction_safe -

-
-

- int -

-
-

- (substitution failure) -

-
-

- int (&)() -

-
-

- (substitution failure) -

-
-

- int (*)() -

-
-

- (substitution failure) -

-
-

- int foo::* -

-
-

- (substitution failure) -

-
-

- int (foo::* - const)() -

-
-

- (substitution failure) -

-
- -

- + Example Program

@@ -279,10 +288,6 @@ using test = ct::add_member_const_t<f>; static_assert(std::is_same<test, expect>::value, ""); } - - // A substitution failure will occur if add_member_const_t is used - // with function pointers, function references, function objects, - // or member data pointers. } diff --git a/doc/html/callable_traits/ref_add_member_cv.html b/doc/html/callable_traits/ref_add_member_cv.html index 91fb96e..c79c7aa 100644 --- a/doc/html/callable_traits/ref_add_member_cv.html +++ b/doc/html/callable_traits/ref_add_member_cv.html @@ -26,36 +26,49 @@ +

+ + Header +

+
#include<callable_traits/add_member_cv.hpp>
+

+ + Definition +

namespace callable_traits {
 
     template<typename T>
-    struct add_member_cv {
-
-        using type = //implementation-defined
-    };
+    using add_member_cv_t = //implementation-defined
 
     template<typename T>
-    using add_member_cv_t = typename add_member_cv<T>::type;
+    struct add_member_cv {
+        using type = add_member_cv_t<T>;
+    };
 }
 

- + Constraints

  • - T must be a function or - a member function pointer + T must be a function type + or a member function pointer type

- + Behavior

-
  • +
      +
    • + A substitution failure occurs if the constraints are violated +
    • +
    • Adds member const and volatile qualifiers to T, if not already present -
    +
  • +

- + Input/Output Examples

@@ -240,7 +253,7 @@

- + Example Program

@@ -278,11 +291,6 @@ using test = ct::add_member_cv_t<f>; static_assert(std::is_same<test, expect>::value, ""); } - -// A substitution failure will occur if add_member_cv_t is used -// with function pointers, function references, function objects, -// or member data pointers. - } diff --git a/doc/html/callable_traits/ref_add_member_lvalue_reference.html b/doc/html/callable_traits/ref_add_member_lvalue_reference.html index 475be69..1a29988 100644 --- a/doc/html/callable_traits/ref_add_member_lvalue_reference.html +++ b/doc/html/callable_traits/ref_add_member_lvalue_reference.html @@ -26,32 +26,42 @@ +

+ + Header +

+
#include<callable_traits/add_member_lvalue_reference.hpp>
+

+ + Definition +

namespace callable_traits {
 
     template<typename T>
-    struct add_member_lvalue_reference {
-
-        using type = //implementation-defined
-    };
+    using add_member_lvalue_reference_t = //implementation-defined
 
     template<typename T>
-    using add_member_lvalue_reference_t =
-        typename add_member_lvalue_reference<T>::type;
+    struct add_member_lvalue_reference {
+        using type = add_member_lvalue_reference_t<T>;
+    };
 }
 

- + Constraints

  • - T must be a function or - a member function pointer + T must be a function type + or a member function pointer type

- + Behavior

    +
  • + A substitution failure occurs if the constraints are violated +
  • Adds a member lvalue reference qualifier (&) to T, if not already present @@ -62,7 +72,7 @@

- + Input/Output Examples

@@ -230,7 +240,7 @@

- + Example Program

@@ -271,10 +281,6 @@ using test = ct::add_member_lvalue_reference_t<f>; static_assert(std::is_same<test, expect>::value, ""); } - - // A substitution failure will occur if add_member_lvalue_reference_t - // is used with function pointers, function references, function objects, - // or member data pointers. } diff --git a/doc/html/callable_traits/ref_add_member_rvalue_reference.html b/doc/html/callable_traits/ref_add_member_rvalue_reference.html index 21d9711..108de50 100644 --- a/doc/html/callable_traits/ref_add_member_rvalue_reference.html +++ b/doc/html/callable_traits/ref_add_member_rvalue_reference.html @@ -26,32 +26,42 @@ +

+ + Header +

+
#include<callable_traits/add_member_rvalue_reference.hpp>
+

+ + Definition +

namespace callable_traits {
 
     template<typename T>
-    struct add_member_rvalue_reference {
-
-        using type = //implementation-defined
-    };
+    using add_member_rvalue_reference_t = //implementation-defined
 
     template<typename T>
-    using add_member_rvalue_reference_t =
-        typename add_member_rvalue_reference<T>::type;
+    struct add_member_rvalue_reference {
+        using type = add_member_rvalue_reference_t<T>;
+    };
 }
 

- + Constraints

  • - T must be a function or - a member function pointer + T must be a function type + or a member function pointer type

- + Behavior

    +
  • + A substitution failure occurs if the constraints are violated +
  • Adds a member rvalue reference qualifier (&&) to T, if not already present @@ -62,7 +72,7 @@

- + Input/Output Examples

@@ -230,7 +240,7 @@

- + Example Program

@@ -271,10 +281,6 @@ using test = ct::add_member_rvalue_reference_t<f>; static_assert(std::is_same<test, expect>::value, ""); } - - // A substitution failure will occur if add_member_rvalue_reference_t - // is used with function pointers, function references, function objects, - // or member data pointers. } diff --git a/doc/html/callable_traits/ref_add_member_volatile.html b/doc/html/callable_traits/ref_add_member_volatile.html index baff461..b946744 100644 --- a/doc/html/callable_traits/ref_add_member_volatile.html +++ b/doc/html/callable_traits/ref_add_member_volatile.html @@ -26,36 +26,49 @@ +

+ + Header +

+
#include<callable_traits/add_member_volatile.hpp>
+

+ + Definition +

namespace callable_traits {
 
     template<typename T>
-    struct add_member_volatile {
-
-        using type = //implementation-defined
-    };
+    using add_member_volatile_t = //implementation-defined
 
     template<typename T>
-    using add_member_volatile_t = typename add_member_volatile<T>::type;
+    struct add_member_volatile {
+        using type = add_member_volatile_t<T>;
+    };
 }
 

- + Constraints

  • - T must be a function or - a member function pointer + T must be a function type + or a member function pointer type

- + Behavior

-
  • +
      +
    • + A substitution failure occurs if the constraints are violated +
    • +
    • Adds a member volatile qualifier to T, if not already present -
    +
  • +

- + Input/Output Examples

@@ -223,7 +236,7 @@

- + Example Program

#include <type_traits>
@@ -260,10 +273,6 @@
         using test = ct::add_member_volatile_t<f>;
         static_assert(std::is_same<test, expect>::value, "");
     }
-
-    // A substitution failure will occur if add_member_volatile_t
-    // is used with function pointers, function references,
-    // function objects, or member data pointers.
 }
 
diff --git a/doc/html/callable_traits/ref_add_transaction_safe.html b/doc/html/callable_traits/ref_add_transaction_safe.html index 3336c96..01817db 100644 --- a/doc/html/callable_traits/ref_add_transaction_safe.html +++ b/doc/html/callable_traits/ref_add_transaction_safe.html @@ -26,51 +26,65 @@ +

+ + Header +

+
#include<callable_traits/add_transaction_safe.hpp>
+

+ + Definition +

namespace callable_traits {
 
     template<typename T>
-    struct add_transaction_safe {
-
-        using type = //implementation-defined
-    };
+    using add_transaction_safe_t = //implementation-defined
 
     template<typename T>
-    using add_transaction_safe_t =
-        typename add_transaction_safe<T>::type;
+    struct add_transaction_safe {
+        using type = add_transaction_safe_t<T>;
+    };
+
+
 }
 

- + Constraints

  • T must be one of the following:
    • - function + function type
    • - function pointer + function pointer type
    • - function reference + function reference type
    • - member function pointer + member function pointer type

- + Behavior

-
  • +
      +
    • + A substitution failure occurs if the constraints are violated +
    • +
    • Adds a transaction_safe specifier to T, if not already present -
    +
  • +

- + Input/Output Examples

@@ -239,7 +253,7 @@

- + Example Program

diff --git a/doc/html/callable_traits/ref_add_varargs.html b/doc/html/callable_traits/ref_add_varargs.html index a94a80d..7580ea1 100644 --- a/doc/html/callable_traits/ref_add_varargs.html +++ b/doc/html/callable_traits/ref_add_varargs.html @@ -26,70 +26,63 @@ +

+ + Header +

+
#include<callable_traits/add_varargs.hpp>
+

+ + Definition +

namespace callable_traits {
 
     template<typename T>
-    struct add_varargs {
-
-        using type = //implementation-defined
-    };
+    using add_varargs_t = //implementation-defined
 
     template<typename T>
-    using add_varargs_t = typename add_varargs<T>::type;
+    struct add_varargs {
+        using type = add_varargs_t<T>;
+    };
 }
 

- + Constraints

  • T must be one of the following:
    • - function + function type
    • - function pointer + function pointer type
    • - function reference + function reference type
    • - member function pointer + member function pointer type

- + Behavior

-
  • +
      +
    • + A substitution failure occurs if the constraints are violated +
    • +
    • Adds C-style variadics (...) to the signature of T, if not already present -
        -
      • - add_varargs<int()> - aliases int(...) -
      • -
      • - add_varargs<int(*)()> - aliases int(*)(int, ...) -
      • -
      • - add_varargs<int(&)()> - aliases int(&)(int, ...) -
      • -
      • - add_varargs<int(foo::*)() - const> - aliases int(foo::*)(...) - const -
      • +
      -

    - + Input/Output Examples

    @@ -278,7 +271,7 @@

- + Example Program

@@ -317,21 +310,6 @@ using twice = ct::add_varargs_t<test>; static_assert(std::is_same<test, twice>::value, ""); } - - // add_varargs_t fails in a SFINAE-friendly manner when - // used on a function object or a member data pointer. - // - // { - // using d = int foo::*; - // using test = ct::add_varargs_t<d>; - // } - // - // The error message is about as obvious as it can be without - // resorting to a SFINAE-unfriendly static_assert (namespaces - // omitted for brevity): - // - // error: no type named 'type' in 'struct disjunction< - // type_value<invalid_type, false>, add_varargs_t_error<0> >' } diff --git a/doc/html/callable_traits/ref_apply_member_pointer.html b/doc/html/callable_traits/ref_apply_member_pointer.html index a19b271..ed8fd2b 100644 --- a/doc/html/callable_traits/ref_apply_member_pointer.html +++ b/doc/html/callable_traits/ref_apply_member_pointer.html @@ -26,43 +26,34 @@ +

+ + Header +

+
#include<callable_traits/apply_member_pointer.hpp>
+

+ + Definition +

namespace callable_traits {
 
     template<typename T, typename C>
-    struct apply_member_pointer {
-
-        using type = //implementation-defined
-    };
+    using apply_member_pointer_t = //implementation-defined
 
     template<typename T, typename C>
-    using apply_member_pointer_t =
-        typename apply_member_pointer<T, C>::type;
+    struct apply_member_pointer {
+        using type = apply_member_pointer_t<T, C>;
+    };
 }
 

- + Constraints

  • - T must be one of the following: -
      -
    • - function -
    • -
    • - function pointer -
    • -
    • - function reference -
    • -
    • - member function pointer -
    • -
    • - member data pointer -
    • -
    + T may be any type except + void
  • C must be a user-defined @@ -70,10 +61,13 @@

- + Behavior

    +
  • + A substitution failure occurs if the constraints are violated +
  • When T is a function, function pointer, or function reference, then the aliased type is a member function @@ -86,9 +80,12 @@ C with the same parameters and return type
  • +
  • + Otherwise, the aliased type is a member data pointer equivalent to std::remove_reference_t<T> C::* +

- + Input/Output Examples

@@ -234,19 +231,33 @@

- (substitution failure) + int foo::*

- bar + int &

- (substitution failure) + int foo::* +

+ + + + +

+ const int + & +

+ + +

+ const int + foo::*

@@ -256,6 +267,18 @@ int (*const)()

+ +

+ int (*const foo::*)() +

+ + + + +

+ void +

+

(substitution failure) @@ -265,7 +288,7 @@

- + Example Program

@@ -277,22 +300,80 @@ struct foo; struct bar; -using expect = int(foo::*)(int); - int main() { { + // function type -> member function pointer type using f = int(int); - using test = ct::apply_member_pointer_t<f, foo>; + using g = ct::apply_member_pointer_t<f, foo>; using expect = int(foo::*)(int); - static_assert(std::is_same<test, expect>::value, ""); + static_assert(std::is_same<g, expect>::value, ""); } { - using f = int(*)(int); - using test = ct::apply_member_pointer_t<f, foo>; - using expect = int(foo::*)(int); - static_assert(std::is_same<test, expect>::value, ""); + // function pointer type (unqualified) -> member function pointer type + using f = int(*)(); + using g = ct::apply_member_pointer_t<f, foo>; + using expect = int(foo::*)(); + static_assert(std::is_same<g, expect>::value, ""); + } + + + { + // function pointer type (qualified) -> member data pointer type + + // Look out for cases like these two. If the input type to apply_member_pointer + // is a qualified function pointer type, then the aliased type is a member data + // pointer to a qualified function pointer. + + { + using f = int(*&)(); + using g = ct::apply_member_pointer_t<f, foo>; + using expect = int (* foo::*)(); + static_assert(std::is_same<g, expect>::value, ""); + } + + { + using f = int(* const)(); + using g = ct::apply_member_pointer_t<f, foo>; + using expect = int (* const foo::*)(); + static_assert(std::is_same<g, expect>::value, ""); + } + } + + { + // function reference type -> member function pointer type + using f = void(&)(); + using g = ct::apply_member_pointer_t<f, foo>; + using expect = void(foo::*)(); + static_assert(std::is_same<g, expect>::value, ""); + } + + { + // member function pointer type -> member function pointer type + // (note the different parent class) + using f = int(bar::*)() const; + using g = ct::apply_member_pointer_t<f, foo>; + using expect = int(foo::*)() const; + static_assert(std::is_same<g, expect>::value, ""); + } + + { + // non-callable type -> member data pointer type + using g = ct::apply_member_pointer_t<int, foo>; + using expect = int foo::*; + static_assert(std::is_same<g, expect>::value, ""); + } + + + { + // function object type -> member data pointer type + // the same is true for lambdas and generic lambdas + auto lambda = [](){}; + using f = decltype(lambda); + using g = ct::apply_member_pointer_t<f, foo>; + using expect = f foo::*; + static_assert(std::is_same<g, expect>::value, ""); } } diff --git a/doc/html/callable_traits/ref_apply_return.html b/doc/html/callable_traits/ref_apply_return.html index 0466a36..7184c8e 100644 --- a/doc/html/callable_traits/ref_apply_return.html +++ b/doc/html/callable_traits/ref_apply_return.html @@ -7,7 +7,7 @@ - + @@ -20,26 +20,34 @@

-PrevUpHomeNext +PrevUpHomeNext
+

+ + Header +

+
#include<callable_traits/apply_return.hpp>
+

+ + Definition +

namespace callable_traits {
 
     template<typename T, typename R>
-    struct apply_return {
-
-        using type = //implementation-defined
-    };
+    using apply_return_t = //implementation-defined
 
     template<typename T, typename R>
-    using apply_return_t = typename apply_return<T, R>::type;
+    struct apply_return {
+        using type = apply_return_t<T, R>;
+    };
 }
 

- + Constraints

  • @@ -66,7 +74,7 @@

- + Behavior

    @@ -89,7 +97,7 @@

- + Input/Output Examples

@@ -278,7 +286,7 @@

- + Example Program

@@ -296,7 +304,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/callable_traits/ref_apply_return0.html b/doc/html/callable_traits/ref_apply_return0.html deleted file mode 100644 index 36bd31c..0000000 --- a/doc/html/callable_traits/ref_apply_return0.html +++ /dev/null @@ -1,66 +0,0 @@ - - - -apply_return - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- - Constraints -

-

- T must be a [link_signature] - or a [link_pmd]. -

-

- - Behavior -

-
  • - apply_return<T, NewReturn> aliases NewReturn - [Category] ( [Args] [VarArgs] ) [MemberQualifiers] -
-

- - Example -

-

- [apply_return] -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/callable_traits/ref_arg_at.html b/doc/html/callable_traits/ref_arg_at.html index 513d8be..585e5fc 100644 --- a/doc/html/callable_traits/ref_arg_at.html +++ b/doc/html/callable_traits/ref_arg_at.html @@ -6,7 +6,7 @@ - + @@ -20,17 +20,23 @@
-PrevUpHomeNext +PrevUpHomeNext
-
namespace callable_traits {
+
namespace callable_traits {
 
-    template<std::size_t Index, typename T>
-    using arg_at = /* implementation-defined */;
+    template<std::size_t I, typename T>
+    struct arg_at {
 
+        using type = //implementation-defined
+
+    };
+
+    template<std::size_t I, typename T>
+    using arg_at_t = typename arg_at<I, T>::type;
 }
 

@@ -42,42 +48,30 @@ T must be one of the following:
  • - [link_signature] + function
  • - [link_simple_fn_obj] + function pointer +
  • +
  • + function reference +
  • +
  • + member function pointer +
  • +
  • + member data pointer +
  • +
  • + user-defined type with non-overloaded operator() +
  • +
  • + type of a non-generic lambda
  • - 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<T>::operator()) -
    • -
    • - Index must be less - than ArgCount and - greater than zero -
    • -
    + I must be less than std::tuple_size<callable_traits::args_t<T>>::value
  • @@ -125,7 +119,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/callable_traits_interface_example.html b/doc/html/callable_traits_interface_example.html index 2803d12..703423f 100644 --- a/doc/html/callable_traits_interface_example.html +++ b/doc/html/callable_traits_interface_example.html @@ -284,7 +284,6 @@ #include <callable_traits/is_like_function.hpp> #include <callable_traits/remove_member_cv.hpp> #include <callable_traits/get_qualifier_flags.hpp> -#include <callable_traits/apply_member_pointer.hpp> #include <callable_traits/remove_member_pointer.hpp> #include <callable_traits/remove_member_reference.hpp> #include <callable_traits/qualified_parent_class_of.hpp> diff --git a/doc/html/index.html b/doc/html/index.html index f3e1c56..5d2090b 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -65,7 +65,6 @@
    add_varargs
    apply_member_pointer
    apply_return
    -
    apply_return
    arg_at
    args
    clear_args
    diff --git a/doc/html/standalone_HTML.manifest b/doc/html/standalone_HTML.manifest index 756b7bd..6fe24a6 100644 --- a/doc/html/standalone_HTML.manifest +++ b/doc/html/standalone_HTML.manifest @@ -11,7 +11,6 @@ callable_traits/ref_add_transaction_safe.html callable_traits/ref_add_varargs.html callable_traits/ref_apply_member_pointer.html callable_traits/ref_apply_return.html -callable_traits/ref_apply_return0.html callable_traits/ref_arg_at.html callable_traits/ref_args.html callable_traits/ref_clear_args.html diff --git a/example/add_member_const.cpp b/example/add_member_const.cpp index c2007b9..43d605c 100644 --- a/example/add_member_const.cpp +++ b/example/add_member_const.cpp @@ -44,10 +44,6 @@ int main() { using test = ct::add_member_const_t; static_assert(std::is_same::value, ""); } - - // A substitution failure will occur if add_member_const_t is used - // with function pointers, function references, function objects, - // or member data pointers. } //] #endif //#ifdef CALLABLE_TRAITS_DISABLE_REFERENCE_QUALIFIERS diff --git a/example/add_member_cv.cpp b/example/add_member_cv.cpp index b83619c..160a9ea 100644 --- a/example/add_member_cv.cpp +++ b/example/add_member_cv.cpp @@ -44,11 +44,6 @@ int main() { using test = ct::add_member_cv_t; static_assert(std::is_same::value, ""); } - -// A substitution failure will occur if add_member_cv_t is used -// with function pointers, function references, function objects, -// or member data pointers. - } //] #endif //#ifdef CALLABLE_TRAITS_DISABLE_REFERENCE_QUALIFIERS diff --git a/example/add_member_lvalue_reference.cpp b/example/add_member_lvalue_reference.cpp index bc30840..59101e2 100644 --- a/example/add_member_lvalue_reference.cpp +++ b/example/add_member_lvalue_reference.cpp @@ -47,10 +47,6 @@ int main() { using test = ct::add_member_lvalue_reference_t; static_assert(std::is_same::value, ""); } - - // A substitution failure will occur if add_member_lvalue_reference_t - // is used with function pointers, function references, function objects, - // or member data pointers. } //] diff --git a/example/add_member_rvalue_reference.cpp b/example/add_member_rvalue_reference.cpp index a125817..27d6811 100644 --- a/example/add_member_rvalue_reference.cpp +++ b/example/add_member_rvalue_reference.cpp @@ -47,10 +47,6 @@ int main() { using test = ct::add_member_rvalue_reference_t; static_assert(std::is_same::value, ""); } - - // A substitution failure will occur if add_member_rvalue_reference_t - // is used with function pointers, function references, function objects, - // or member data pointers. } //] diff --git a/example/add_member_volatile.cpp b/example/add_member_volatile.cpp index c2b5da1..c74ad3c 100644 --- a/example/add_member_volatile.cpp +++ b/example/add_member_volatile.cpp @@ -44,10 +44,6 @@ int main() { using test = ct::add_member_volatile_t; static_assert(std::is_same::value, ""); } - - // A substitution failure will occur if add_member_volatile_t - // is used with function pointers, function references, - // function objects, or member data pointers. } //] diff --git a/example/add_varargs.cpp b/example/add_varargs.cpp index afd258d..c6c7c76 100644 --- a/example/add_varargs.cpp +++ b/example/add_varargs.cpp @@ -40,20 +40,5 @@ int main() { using twice = ct::add_varargs_t; static_assert(std::is_same::value, ""); } - - // add_varargs_t fails in a SFINAE-friendly manner when - // used on a function object or a member data pointer. - // - // { - // using d = int foo::*; - // using test = ct::add_varargs_t; - // } - // - // The error message is about as obvious as it can be without - // resorting to a SFINAE-unfriendly static_assert (namespaces - // omitted for brevity): - // - // error: no type named 'type' in 'struct disjunction< - // type_value, add_varargs_t_error<0> >' } //] diff --git a/example/apply_member_pointer.cpp b/example/apply_member_pointer.cpp index fce0d7f..3b0883e 100644 --- a/example/apply_member_pointer.cpp +++ b/example/apply_member_pointer.cpp @@ -14,22 +14,80 @@ namespace ct = callable_traits; struct foo; struct bar; -using expect = int(foo::*)(int); - int main() { { + // function type -> member function pointer type using f = int(int); - using test = ct::apply_member_pointer_t; + using g = ct::apply_member_pointer_t; using expect = int(foo::*)(int); - static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, ""); } { - using f = int(*)(int); - using test = ct::apply_member_pointer_t; - using expect = int(foo::*)(int); - static_assert(std::is_same::value, ""); + // function pointer type (unqualified) -> member function pointer type + using f = int(*)(); + using g = ct::apply_member_pointer_t; + using expect = int(foo::*)(); + static_assert(std::is_same::value, ""); + } + + + { + // function pointer type (qualified) -> member data pointer type + + // Look out for cases like these two. If the input type to apply_member_pointer + // is a ``[*qualified]`` function pointer type, then the aliased type is a member data + // pointer to a ``[*qualified function pointer]``. + + { + using f = int(*&)(); + using g = ct::apply_member_pointer_t; + using expect = int (* foo::*)(); + static_assert(std::is_same::value, ""); + } + + { + using f = int(* const)(); + using g = ct::apply_member_pointer_t; + using expect = int (* const foo::*)(); + static_assert(std::is_same::value, ""); + } + } + + { + // function reference type -> member function pointer type + using f = void(&)(); + using g = ct::apply_member_pointer_t; + using expect = void(foo::*)(); + static_assert(std::is_same::value, ""); + } + + { + // member function pointer type -> member function pointer type + // (note the different parent class) + using f = int(bar::*)() const; + using g = ct::apply_member_pointer_t; + using expect = int(foo::*)() const; + static_assert(std::is_same::value, ""); + } + + { + // non-callable type -> member data pointer type + using g = ct::apply_member_pointer_t; + using expect = int foo::*; + static_assert(std::is_same::value, ""); + } + + + { + // function object type -> member data pointer type + // the same is true for lambdas and generic lambdas + auto lambda = [](){}; + using f = decltype(lambda); + using g = ct::apply_member_pointer_t; + using expect = f foo::*; + static_assert(std::is_same::value, ""); } } //] diff --git a/example/interface.hpp b/example/interface.hpp index 0fe0636..f60ac94 100644 --- a/example/interface.hpp +++ b/example/interface.hpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/include/callable_traits/add_member_const.hpp b/include/callable_traits/add_member_const.hpp index a7c1245..b463296 100644 --- a/include/callable_traits/add_member_const.hpp +++ b/include/callable_traits/add_member_const.hpp @@ -12,32 +12,37 @@ Distributed under the Boost Software License, Version 1.0. #include //[ add_member_const_hpp -//`[section:ref_add_member_const add_member_const] +/*` +[section:ref_add_member_const add_member_const] +[heading Header] +``#include`` +[heading Definition] +*/ namespace callable_traits { template - struct add_member_const { - - using type = //implementation-defined - //<- - detail::fail_if_invalid< - typename detail::traits::add_member_const, - member_qualifiers_are_illegal_for_this_type>; - //-> - }; + using add_member_const_t = //implementation-defined +//<- + detail::fail_if_invalid< + typename detail::traits::add_member_const, + member_qualifiers_are_illegal_for_this_type>; +//-> template - using add_member_const_t = typename add_member_const::type; + struct add_member_const { + using type = add_member_const_t; + }; } /*` [heading Constraints] -* `T` must be a function or a member function pointer +* `T` must be a function type or a member function pointer type [heading Behavior] +* A substitution failure occuers if the constraints are violated * Adds a member `const` qualifier to `T`, if not already present -* + [heading Input/Output Examples] [table [[`T`] [`add_member_const_t`]] diff --git a/include/callable_traits/add_member_cv.hpp b/include/callable_traits/add_member_cv.hpp index 0116fc2..83c0359 100644 --- a/include/callable_traits/add_member_cv.hpp +++ b/include/callable_traits/add_member_cv.hpp @@ -11,31 +11,36 @@ Distributed under the Boost Software License, Version 1.0. #include -//[add_member_cv_hpp -//`[section:ref_add_member_cv add_member_cv] +//[ add_member_cv_hpp +/*` +[section:ref_add_member_cv add_member_cv] +[heading Header] +``#include`` +[heading Definition] +*/ namespace callable_traits { template - struct add_member_cv { - - using type = //implementation-defined - //<- - detail::fail_if_invalid< - typename detail::traits::add_member_cv, - member_qualifiers_are_illegal_for_this_type>; - //-> - }; + using add_member_cv_t = //implementation-defined +//<- + detail::fail_if_invalid< + typename detail::traits::add_member_cv, + member_qualifiers_are_illegal_for_this_type>; +//-> template - using add_member_cv_t = typename add_member_cv::type; + struct add_member_cv { + using type = add_member_cv_t; + }; } /*` [heading Constraints] -* `T` must be a function or a member function pointer +* `T` must be a function type or a member function pointer type [heading Behavior] +* A substitution failure occurs if the constraints are violated * Adds member `const` and `volatile` qualifiers to `T`, if not already present [heading Input/Output Examples] diff --git a/include/callable_traits/add_member_lvalue_reference.hpp b/include/callable_traits/add_member_lvalue_reference.hpp index 968881b..873f7b1 100644 --- a/include/callable_traits/add_member_lvalue_reference.hpp +++ b/include/callable_traits/add_member_lvalue_reference.hpp @@ -11,32 +11,36 @@ Distributed under the Boost Software License, Version 1.0. #include -//[add_member_lvalue_reference_hpp -//`[section:ref_add_member_lvalue_reference add_member_lvalue_reference] +//[ add_member_lvalue_reference_hpp +/*` +[section:ref_add_member_lvalue_reference add_member_lvalue_reference] +[heading Header] +``#include`` +[heading Definition] +*/ namespace callable_traits { template - struct add_member_lvalue_reference { - - using type = //implementation-defined - //<- - detail::fail_if_invalid< - typename detail::traits::add_member_lvalue_reference, - member_qualifiers_are_illegal_for_this_type>; - //-> - }; + using add_member_lvalue_reference_t = //implementation-defined +//<- + detail::fail_if_invalid< + typename detail::traits::add_member_lvalue_reference, + member_qualifiers_are_illegal_for_this_type>; +//-> template - using add_member_lvalue_reference_t = - typename add_member_lvalue_reference::type; + struct add_member_lvalue_reference { + using type = add_member_lvalue_reference_t; + }; } /*` [heading Constraints] -* `T` must be a function or a member function pointer +* `T` must be a function type or a member function pointer type [heading Behavior] +* A substitution failure occurs if the constraints are violated * Adds a member lvalue reference qualifier (`&`) to `T`, if not already present * If an rvalue reference qualifier is present, the lvalue reference qualifier replaces it (in accordance with reference collapsing rules) diff --git a/include/callable_traits/add_member_rvalue_reference.hpp b/include/callable_traits/add_member_rvalue_reference.hpp index c58f630..74e3939 100644 --- a/include/callable_traits/add_member_rvalue_reference.hpp +++ b/include/callable_traits/add_member_rvalue_reference.hpp @@ -11,32 +11,36 @@ Distributed under the Boost Software License, Version 1.0. #include -//[add_member_rvalue_reference_hpp -//`[section:ref_add_member_rvalue_reference add_member_rvalue_reference] +//[ add_member_rvalue_reference_hpp +/*` +[section:ref_add_member_rvalue_reference add_member_rvalue_reference] +[heading Header] +``#include`` +[heading Definition] +*/ namespace callable_traits { template - struct add_member_rvalue_reference { - - using type = //implementation-defined - //<- - detail::fail_if_invalid< - typename detail::traits::add_member_rvalue_reference, - member_qualifiers_are_illegal_for_this_type>; - //-> - }; + using add_member_rvalue_reference_t = //implementation-defined +//<- + detail::fail_if_invalid< + typename detail::traits::add_member_rvalue_reference, + member_qualifiers_are_illegal_for_this_type>; +//-> template - using add_member_rvalue_reference_t = - typename add_member_rvalue_reference::type; + struct add_member_rvalue_reference { + using type = add_member_rvalue_reference_t; + }; } /*` [heading Constraints] -* `T` must be a function or a member function pointer +* `T` must be a function type or a member function pointer type [heading Behavior] +* A substitution failure occurs if the constraints are violated * Adds a member rvalue reference qualifier (`&&`) to `T`, if not already present * If an lvalue reference qualifier is present, the lvalue reference qualifier remains (in accordance with reference collapsing rules) diff --git a/include/callable_traits/add_member_volatile.hpp b/include/callable_traits/add_member_volatile.hpp index 8197a0c..2f26c7f 100644 --- a/include/callable_traits/add_member_volatile.hpp +++ b/include/callable_traits/add_member_volatile.hpp @@ -11,31 +11,36 @@ Distributed under the Boost Software License, Version 1.0. #include -//[add_member_volatile_hpp -//`[section:ref_add_member_volatile add_member_volatile] +//[ add_member_volatile_hpp +/*` +[section:ref_add_member_volatile add_member_volatile] +[heading Header] +``#include`` +[heading Definition] +*/ namespace callable_traits { template - struct add_member_volatile { - - using type = //implementation-defined - //<- - detail::fail_if_invalid< - typename detail::traits::add_member_volatile, - member_qualifiers_are_illegal_for_this_type>; - //-> - }; + using add_member_volatile_t = //implementation-defined +//<- + detail::fail_if_invalid< + typename detail::traits::add_member_volatile, + member_qualifiers_are_illegal_for_this_type>; +//-> template - using add_member_volatile_t = typename add_member_volatile::type; + struct add_member_volatile { + using type = add_member_volatile_t; + }; } /*` [heading Constraints] -* `T` must be a function or a member function pointer +* `T` must be a function type or a member function pointer type [heading Behavior] +* A substitution failure occurs if the constraints are violated * Adds a member volatile qualifier to `T`, if not already present [heading Input/Output Examples] diff --git a/include/callable_traits/add_transaction_safe.hpp b/include/callable_traits/add_transaction_safe.hpp index 637b555..a5733ec 100644 --- a/include/callable_traits/add_transaction_safe.hpp +++ b/include/callable_traits/add_transaction_safe.hpp @@ -12,50 +12,50 @@ Distributed under the Boost Software License, Version 1.0. #include -//[add_transaction_safe_hpp -//`[section:ref_add_transaction_safe add_transaction_safe] +//[ add_transaction_safe_hpp +/*` +[section:ref_add_transaction_safe add_transaction_safe] +[heading Header] +``#include`` +[heading Definition] +*/ namespace callable_traits { - //<- - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(add_transaction_safe) - - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(add_transaction_safe, - cannot_add_transaction_safe_to_this_type) - //-> template - struct add_transaction_safe { - - using type = //implementation-defined + using add_transaction_safe_t = //implementation-defined //<- #ifdef CALLABLE_TRAITS_ENABLE_TRANSACTION_SAFE - detail::fail_if_invalid< - typename detail::traits::add_transaction_safe, - cannot_add_transaction_safe_to_this_type>; + detail::fail_if_invalid< + typename detail::traits::add_transaction_safe, + cannot_add_transaction_safe_to_this_type>; #else - detail::sfinae_try>; + detail::sfinae_try>; #endif //-> - }; template - using add_transaction_safe_t = - typename add_transaction_safe::type; + struct add_transaction_safe { + using type = add_transaction_safe_t; + }; + + } /*` [heading Constraints] * `T` must be one of the following: - * function - * function pointer - * function reference - * member function pointer + * function type + * function pointer type + * function reference type + * member function pointer type [heading Behavior] +* A substitution failure occurs if the constraints are violated * Adds a `transaction_safe` specifier to `T`, if not already present [heading Input/Output Examples] diff --git a/include/callable_traits/add_varargs.hpp b/include/callable_traits/add_varargs.hpp index 5086408..9498798 100644 --- a/include/callable_traits/add_varargs.hpp +++ b/include/callable_traits/add_varargs.hpp @@ -12,40 +12,41 @@ Distributed under the Boost Software License, Version 1.0. #include -//[add_varargs_hpp -//`[section:ref_add_varargs add_varargs] +//[ add_varargs_hpp +/*` +[section:ref_add_varargs add_varargs] +[heading Header] +``#include`` +[heading Definition] +*/ namespace callable_traits { template - struct add_varargs { - - using type = //implementation-defined - //<- - detail::fail_if_invalid< - typename detail::traits::add_varargs, - varargs_are_illegal_for_this_type>; - //-> - }; + using add_varargs_t = //implementation-defined +//<- + detail::fail_if_invalid< + typename detail::traits::add_varargs, + varargs_are_illegal_for_this_type>; +//-> template - using add_varargs_t = typename add_varargs::type; + struct add_varargs { + using type = add_varargs_t; + }; } /*` [heading Constraints] * `T` must be one of the following: - * function - * function pointer - * function reference - * member function pointer + * function type + * function pointer type + * function reference type + * member function pointer type [heading Behavior] +* A substitution failure occurs if the constraints are violated * Adds C-style variadics (`...`) to the signature of `T`, if not already present - * `add_varargs` aliases `int(...)` - * `add_varargs` aliases `int(*)(int, ...)` - * `add_varargs` aliases `int(&)(int, ...)` - * `add_varargs` aliases `int(foo::*)(...) const` [heading Input/Output Examples] [table diff --git a/include/callable_traits/apply_member_pointer.hpp b/include/callable_traits/apply_member_pointer.hpp index 48fcc69..ed25cc5 100644 --- a/include/callable_traits/apply_member_pointer.hpp +++ b/include/callable_traits/apply_member_pointer.hpp @@ -13,39 +13,71 @@ Distributed under the Boost Software License, Version 1.0. #include //[ apply_member_pointer_hpp -//`[section:ref_apply_member_pointer apply_member_pointer] +/*` +[section:ref_apply_member_pointer apply_member_pointer] +[heading Header] +``#include`` +[heading Definition] +*/ namespace callable_traits { +//<- + namespace detail { + + template::value> + struct make_member_pointer; + + template + struct make_member_pointer { + using type = typename std::remove_reference::type C::*; + }; + + template + struct make_member_pointer { + using type = invalid_type; + }; + + template + struct make_member_pointer { + using type = invalid_type; + }; + + template + using make_member_pointer_t = typename make_member_pointer::type; + } +//-> + + template + using apply_member_pointer_t = //implementation-defined +//<- + detail::sfinae_try< + detail::fallback_if_invalid< + typename detail::traits::template apply_member_pointer, + typename detail::make_member_pointer::type>, + + detail::fail_if::value, + members_cannot_have_a_type_of_void>, + + detail::fail_if::value, + second_template_argument_must_be_a_class_or_struct> >; +//-> template struct apply_member_pointer { - - using type = //implementation-defined - //<- - detail::fallback_if_invalid< - typename detail::traits::template apply_member_pointer, - typename std::remove_reference::type C::*>; - //-> + using type = apply_member_pointer_t; }; - - template - using apply_member_pointer_t = - typename apply_member_pointer::type; } /*` [heading Constraints] -* `T` must be one of the following: - * function - * function pointer - * function reference - * member function pointer - * member data pointer +* `T` may be any type except `void` * `C` must be a user-defined type [heading Behavior] +* A substitution failure occurs if the constraints are violated * When `T` is a function, function pointer, or function reference, then the aliased type is a member function pointer of `C` with the same parameters and return type * When `T` is a member function pointer of any type, the aliased type is a member function pointer of `C` with the same parameters and return type +* Otherwise, the aliased type is a member data pointer equivalent to `std::remove_reference_t C::*` [heading Input/Output Examples] [table @@ -59,9 +91,11 @@ namespace callable_traits { [[`int(bar::*)() const`] [`int(foo::*)() const`]] [[`int(bar::*)() transaction_safe`] [`int(foo::*)() transaction_safe`]] [[`int bar::*`] [`int foo::*`]] - [[`int`] [(substitution failure)]] - [[`bar`] [(substitution failure)]] - [[`int (*const)()`] [(substitution failure)]] + [[`int`] [`int foo::*`]] + [[`int &`] [`int foo::*`]] + [[`const int &`] [`const int foo::*`]] + [[`int (*const)()`] [`int (*const foo::*)()`]] + [[`void`] [(substitution failure)]] ] [heading Example Program] diff --git a/include/callable_traits/apply_return.hpp b/include/callable_traits/apply_return.hpp index e5ccb01..fc6d2db 100644 --- a/include/callable_traits/apply_return.hpp +++ b/include/callable_traits/apply_return.hpp @@ -12,7 +12,12 @@ Distributed under the Boost Software License, Version 1.0. #include //[ apply_return_hpp -//`[section:ref_apply_return apply_return] +/*` +[section:ref_apply_return apply_return] +[heading Header] +``#include`` +[heading Definition] +*/ namespace callable_traits { //<- @@ -29,26 +34,20 @@ namespace callable_traits { using type = R(Args...); }; } + //-> - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(apply_return) - - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(apply_return, - invalid_types_for_apply_return) + template + using apply_return_t = //implementation-defined + //<- + detail::fail_if_invalid< + typename detail::apply_return_helper::type, + invalid_types_for_apply_return>; //-> template struct apply_return { - - using type = //implementation-defined - //<- - detail::fail_if_invalid< - typename detail::apply_return_helper::type, - invalid_types_for_apply_return>; - //-> + using type = apply_return_t; }; - - template - using apply_return_t = typename apply_return::type; } /*` diff --git a/include/callable_traits/arg_at.hpp b/include/callable_traits/arg_at.hpp index 46531f6..971a86a 100644 --- a/include/callable_traits/arg_at.hpp +++ b/include/callable_traits/arg_at.hpp @@ -14,32 +14,65 @@ Distributed under the Boost Software License, Version 1.0. #include #include +//[ arg_at_hpp +//`[section:ref_arg_at arg_at] + namespace callable_traits { template struct arg_at { - + //<- private: using arg_types = typename args::type; public: + //-> - // SFINAEs away if index is out of range or if argument - // types cannot be determined. Simple error messages are - // provided in case the error occurs outside of a SFINAE context + using type = //implementation-defined - using type = detail::sfinae_try< + //<- + // substitution failure if index is out of range or if argument + // types cannot be determined. Simple error messages are provided + // in case the error occurs outside of a SFINAE context + detail::sfinae_try< - detail::at, + detail::at, - detail::fail_if= std::tuple_size::value, - index_out_of_range_for_parameter_list> - >; + detail::fail_if= std::tuple_size::value, + index_out_of_range_for_parameter_list> + >; + //-> }; template using arg_at_t = typename arg_at::type; } +/*` +[heading Constraints] +* `T` must be one of the following: + * function + * function pointer + * function reference + * member function pointer + * member data pointer + * user-defined type with non-overloaded `operator()` + * type of a non-generic lambda + +* `I` must be less than `std::tuple_size>::value` + +[heading Behavior] +* If any constraints are violated, a substitution failure occurs +* Otherwise, `arg_at` aliases `std::tuple_element_t>`, such that: + * `arg_at<0, void(char, short, long, int*)>` aliases `char` + * `arg_at<1, void(*)(char, short, long, int*)>` aliases `short` + * `arg_at<2, void(&)(char, short, long, int*)>` aliases `long` + +[heading Example] +[/import ../example/arg_at.cpp] +[arg_at] +[endsect] +*/ +//] #endif diff --git a/include/callable_traits/clear_args.hpp b/include/callable_traits/clear_args.hpp index bce90d2..1436be6 100644 --- a/include/callable_traits/clear_args.hpp +++ b/include/callable_traits/clear_args.hpp @@ -14,11 +14,6 @@ Distributed under the Boost Software License, Version 1.0. namespace callable_traits { - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(clear_args) - - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(clear_args, - cannot_clear_the_parameter_list_for_this_type) - template struct clear_args { diff --git a/include/callable_traits/config.hpp b/include/callable_traits/config.hpp index e067ea1..1ce527b 100644 --- a/include/callable_traits/config.hpp +++ b/include/callable_traits/config.hpp @@ -77,7 +77,7 @@ Distributed under the Boost Software License, Version 1.0. #define CALLABLE_TRAITS_DEFAULT_VARARGS_CC __cdecl #define CALLABLE_TRAITS_PMF_VARGARGS_CDECL_DEFAULT - //Visual Studio 2015 Update 2 broke std::make_index_sequence + // Visual Studio 2015 Update 2 broke std::make_index_sequence #if _MSC_FULL_VER == 190023918 #include #endif //#if _MSC_FULL_VER == 190023918 diff --git a/include/callable_traits/detail/default_callable_traits.hpp b/include/callable_traits/detail/default_callable_traits.hpp index 7a5543a..4adf4fd 100644 --- a/include/callable_traits/detail/default_callable_traits.hpp +++ b/include/callable_traits/detail/default_callable_traits.hpp @@ -15,6 +15,7 @@ namespace callable_traits { namespace detail { + template struct default_callable_traits { // value is used by all traits classes to participate @@ -144,10 +145,18 @@ namespace callable_traits { // Changes the parent class type for PMDs and PMFs. Turns // function pointers, function references, and - // qualified/unqualified function types into PMFs. invalid_type - // for function objects. - template - using apply_member_pointer = invalid_type; + // qualified/unqualified function types into PMFs. Turns + // everything else into member data pointers. + template::type, + typename L = typename std::conditional< + std::is_same::value, invalid_type, K>::type, + typename Class = typename std::conditional< + std::is_class::value, C, invalid_type>::type> + using apply_member_pointer = typename std::conditional< + std::is_same::value || std::is_same::value, + invalid_type, L Class::*>::type; // Changes the return type of PMFs, function pointers, function // references, and qualified/unqualified function types. Changes diff --git a/include/callable_traits/detail/function.hpp b/include/callable_traits/detail/function.hpp index 2cfc96f..b79ac08 100644 --- a/include/callable_traits/detail/function.hpp +++ b/include/callable_traits/detail/function.hpp @@ -26,7 +26,7 @@ namespace callable_traits { namespace detail { template - struct function : default_callable_traits {}; + struct function : default_callable_traits<> {}; #undef CALLABLE_TRAITS_INCLUDE_QUALIFIERS #define CALLABLE_TRAITS_INCLUDE_QUALIFIERS @@ -154,6 +154,9 @@ namespace callable_traits { template struct function : function { + + static constexpr const bool value = !std::is_pointer::value; + using traits = function; using base = function; using type = T&; diff --git a/include/callable_traits/detail/function_object.hpp b/include/callable_traits/detail/function_object.hpp index 3261e2b..f9f4afb 100644 --- a/include/callable_traits/detail/function_object.hpp +++ b/include/callable_traits/detail/function_object.hpp @@ -62,8 +62,9 @@ namespace callable_traits { using clear_args = invalid_type; - template - using apply_member_pointer = invalid_type; + template + using apply_member_pointer = + typename std::remove_reference::type C::*; template using apply_return = invalid_type; @@ -108,7 +109,7 @@ namespace callable_traits { template struct function_object - : default_callable_traits {}; + : default_callable_traits<> {}; } } diff --git a/include/callable_traits/detail/fwd/function_object_fwd.hpp b/include/callable_traits/detail/fwd/function_object_fwd.hpp index f453082..0288700 100644 --- a/include/callable_traits/detail/fwd/function_object_fwd.hpp +++ b/include/callable_traits/detail/fwd/function_object_fwd.hpp @@ -20,16 +20,18 @@ namespace callable_traits { template struct has_normal_call_operator { - template struct check { check(std::nullptr_t) {} }; + template + struct check { check(std::nullptr_t) {} }; template - static std::int8_t test(check); + static std::int8_t test( + check); template static std::int16_t test(...); - static constexpr bool value = sizeof(test(nullptr)) == sizeof(std::int8_t); - + static constexpr bool value = + sizeof(test(nullptr)) == sizeof(std::int8_t); }; struct callable_dummy { @@ -38,7 +40,7 @@ namespace callable_traits { template struct ambiguous_function_object_traits - : qualifier_traits, default_callable_traits {}; + : qualifier_traits, default_callable_traits {}; template using default_to_function_object = typename std::conditional< @@ -54,7 +56,8 @@ namespace callable_traits { ambiguous_function_object_traits >::type; - template>> + template>> struct function_object; } } diff --git a/include/callable_traits/detail/pmd.hpp b/include/callable_traits/detail/pmd.hpp index b078bc4..5763939 100644 --- a/include/callable_traits/detail/pmd.hpp +++ b/include/callable_traits/detail/pmd.hpp @@ -23,7 +23,7 @@ namespace callable_traits { namespace detail { template - struct pmd : default_callable_traits {}; + struct pmd : default_callable_traits {}; template struct pmd > { @@ -33,7 +33,7 @@ namespace callable_traits { template struct pmd - : default_callable_traits, qualifier_traits { + : default_callable_traits<>, qualifier_traits { static constexpr bool value = true; diff --git a/include/callable_traits/detail/pmf.hpp b/include/callable_traits/detail/pmf.hpp index 59ed798..decfdc0 100644 --- a/include/callable_traits/detail/pmf.hpp +++ b/include/callable_traits/detail/pmf.hpp @@ -41,7 +41,7 @@ namespace callable_traits { typename set_varargs_member_function_qualifiers_t::type; template - struct pmf : default_callable_traits {}; + struct pmf : default_callable_traits {}; template struct pmf > { diff --git a/include/callable_traits/detail/sfinae_errors.hpp b/include/callable_traits/detail/sfinae_errors.hpp index c63a3c3..be34923 100644 --- a/include/callable_traits/detail/sfinae_errors.hpp +++ b/include/callable_traits/detail/sfinae_errors.hpp @@ -33,11 +33,15 @@ namespace callable_traits { static constexpr bool value = B; }; - template + template using sfinae_try = typename CALLABLE_TRAITS_DISJUNCTION( - ThrowIfs..., - success - )::_::type; + FailIfs..., success)::_::type; + + template + struct fail { + using type = typename std::conditional::type::_::type; + }; } #define CALLABLE_TRAITS_PP_CAT_(x, y) x ## y @@ -52,46 +56,41 @@ namespace callable_traits_ERROR { \ } \ /**/ -#define CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(origin, name) \ +#define CALLABLE_TRAITS_SFINAE_MSG(origin, name) \ struct CALLABLE_TRAITS_PP_CAT(name, _ ){}; \ struct name : callable_traits_ERROR::origin< \ CALLABLE_TRAITS_PP_CAT(name, _ )>{}; \ /**/ - /*** parameter manipulation errors ***/ + CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(parameters) - - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(parameters, - index_out_of_range_for_parameter_list) - - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(parameters, - cannot_determine_parameters_for_this_type) - - - /*** parent class errors ***/ + CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(clear_args) + CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(apply_return) CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(parent_class) - - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(parent_class, - type_is_not_a_member_pointer) - - - /*** member qualifier errors ***/ - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(member_qualifiers) - - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(member_qualifiers, - member_qualifiers_are_illegal_for_this_type) - - - /*** varargs errors ***/ + CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(apply_member_pointer) CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(varargs) - - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(varargs, - varargs_are_illegal_for_this_type) - - /*** transaction_safe errors ***/ + CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(member_qualifiers) CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(transaction_safe_error) + CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(add_transaction_safe) + CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(expand_args) + CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(remove_member_pointer) + CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(remove_transaction_safe) + CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(result_of) - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(transaction_safe_error, - transaction_safe_is_not_enabled_on_this_platform) + CALLABLE_TRAITS_SFINAE_MSG(parameters, index_out_of_range_for_parameter_list) + CALLABLE_TRAITS_SFINAE_MSG(parameters, cannot_determine_parameters_for_this_type) + CALLABLE_TRAITS_SFINAE_MSG(clear_args, cannot_clear_the_parameter_list_for_this_type) + CALLABLE_TRAITS_SFINAE_MSG(apply_return, invalid_types_for_apply_return) + CALLABLE_TRAITS_SFINAE_MSG(parent_class, type_is_not_a_member_pointer) + CALLABLE_TRAITS_SFINAE_MSG(apply_member_pointer, members_cannot_have_a_type_of_void) + CALLABLE_TRAITS_SFINAE_MSG(apply_member_pointer, second_template_argument_must_be_a_class_or_struct) + CALLABLE_TRAITS_SFINAE_MSG(member_qualifiers, member_qualifiers_are_illegal_for_this_type) + CALLABLE_TRAITS_SFINAE_MSG(varargs, varargs_are_illegal_for_this_type) + CALLABLE_TRAITS_SFINAE_MSG(transaction_safe_error, transaction_safe_is_not_enabled_on_this_platform) + CALLABLE_TRAITS_SFINAE_MSG(add_transaction_safe, cannot_add_transaction_safe_to_this_type) + CALLABLE_TRAITS_SFINAE_MSG(remove_transaction_safe, cannot_remove_transaction_safe_from_this_type) + CALLABLE_TRAITS_SFINAE_MSG(expand_args, cannot_expand_the_parameter_list_of_first_template_argument) + CALLABLE_TRAITS_SFINAE_MSG(remove_member_pointer, cannot_remove_member_pointer_from_this_type) + CALLABLE_TRAITS_SFINAE_MSG(result_of, unable_to_determine_return_type) } #endif // #ifndef CALLABLE_TRAITS_SFINAE_ERRORS_HPP diff --git a/include/callable_traits/detail/traits.hpp b/include/callable_traits/detail/traits.hpp index 5228a00..0c29f67 100644 --- a/include/callable_traits/detail/traits.hpp +++ b/include/callable_traits/detail/traits.hpp @@ -27,7 +27,8 @@ namespace callable_traits { function, pmf, pmd, - function_object + function_object, + default_callable_traits )::traits; } } diff --git a/include/callable_traits/detail/unguarded/function_2.hpp b/include/callable_traits/detail/unguarded/function_2.hpp index 3667e2d..e674a6a 100644 --- a/include/callable_traits/detail/unguarded/function_2.hpp +++ b/include/callable_traits/detail/unguarded/function_2.hpp @@ -27,7 +27,7 @@ CALLABLE_TRAITS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when template struct function - : qualifier_traits, default_callable_traits { + : qualifier_traits, default_callable_traits<> { static constexpr bool value = true; @@ -121,7 +121,7 @@ struct function struct function - : qualifier_traits, default_callable_traits { + : qualifier_traits, default_callable_traits<> { static constexpr bool value = true; diff --git a/include/callable_traits/detail/unguarded/function_ptr_2.hpp b/include/callable_traits/detail/unguarded/function_ptr_2.hpp index c53b3f7..7a7a6cf 100644 --- a/include/callable_traits/detail/unguarded/function_ptr_2.hpp +++ b/include/callable_traits/detail/unguarded/function_ptr_2.hpp @@ -30,7 +30,7 @@ struct has_calling_convention_t< template struct function< CALLABLE_TRAITS_ST Return(CALLABLE_TRAITS_CC *)(Args...) CALLABLE_TRAITS_INCLUDE_TRANSACTION_SAFE> - : qualifier_traits, default_callable_traits { + : qualifier_traits, default_callable_traits<> { static constexpr bool value = true; diff --git a/include/callable_traits/detail/unguarded/function_ptr_varargs_2.hpp b/include/callable_traits/detail/unguarded/function_ptr_varargs_2.hpp index 74989fb..173c03f 100644 --- a/include/callable_traits/detail/unguarded/function_ptr_varargs_2.hpp +++ b/include/callable_traits/detail/unguarded/function_ptr_varargs_2.hpp @@ -30,7 +30,7 @@ struct has_calling_convention_t< template struct function - : qualifier_traits, default_callable_traits { + : qualifier_traits, default_callable_traits<> { static constexpr bool value = true; diff --git a/include/callable_traits/detail/unguarded/pmf_3.hpp b/include/callable_traits/detail/unguarded/pmf_3.hpp index 9893288..ae9e39f 100644 --- a/include/callable_traits/detail/unguarded/pmf_3.hpp +++ b/include/callable_traits/detail/unguarded/pmf_3.hpp @@ -33,7 +33,7 @@ struct has_calling_convention_t< template struct pmf - : qualifier_traits, default_callable_traits { + : qualifier_traits, default_callable_traits<> { static constexpr bool value = true; diff --git a/include/callable_traits/detail/unguarded/pmf_varargs_3.hpp b/include/callable_traits/detail/unguarded/pmf_varargs_3.hpp index 7e13187..d4e0d52 100644 --- a/include/callable_traits/detail/unguarded/pmf_varargs_3.hpp +++ b/include/callable_traits/detail/unguarded/pmf_varargs_3.hpp @@ -32,7 +32,7 @@ struct has_calling_convention_t< template struct pmf - : qualifier_traits, default_callable_traits { + : qualifier_traits, default_callable_traits<> { static constexpr bool value = true; diff --git a/include/callable_traits/expand_args.hpp b/include/callable_traits/expand_args.hpp index 8db3b7f..ab0f704 100644 --- a/include/callable_traits/expand_args.hpp +++ b/include/callable_traits/expand_args.hpp @@ -14,11 +14,6 @@ Distributed under the Boost Software License, Version 1.0. namespace callable_traits { - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(expand_args) - - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(expand_args, - cannot_expand_the_parameter_list_of_first_template_argument) - template class Container> struct expand_args { diff --git a/include/callable_traits/remove_member_pointer.hpp b/include/callable_traits/remove_member_pointer.hpp index 27ca87f..ee9d5b4 100644 --- a/include/callable_traits/remove_member_pointer.hpp +++ b/include/callable_traits/remove_member_pointer.hpp @@ -14,11 +14,6 @@ Distributed under the Boost Software License, Version 1.0. namespace callable_traits { - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(remove_member_pointer) - - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(remove_member_pointer, - cannot_remove_member_pointer_from_this_type) - template struct remove_member_pointer { diff --git a/include/callable_traits/remove_transaction_safe.hpp b/include/callable_traits/remove_transaction_safe.hpp index 7f9614d..46111ef 100644 --- a/include/callable_traits/remove_transaction_safe.hpp +++ b/include/callable_traits/remove_transaction_safe.hpp @@ -14,11 +14,6 @@ Distributed under the Boost Software License, Version 1.0. namespace callable_traits { - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(remove_transaction_safe) - - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(remove_transaction_safe, - cannot_remove_transaction_safe_from_this_type) - template struct remove_transaction_safe { diff --git a/include/callable_traits/result_of.hpp b/include/callable_traits/result_of.hpp index fd914a4..b6512a7 100644 --- a/include/callable_traits/result_of.hpp +++ b/include/callable_traits/result_of.hpp @@ -14,11 +14,6 @@ Distributed under the Boost Software License, Version 1.0. namespace callable_traits { - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_ORIGIN(result_of) - - CALLABLE_TRAITS_DEFINE_SFINAE_ERROR_FOR(result_of, - unable_to_determine_return_type) - template struct result_of { diff --git a/qtcreator/main/main.cpp b/qtcreator/main/main.cpp index 08b2919..dc365c5 100644 --- a/qtcreator/main/main.cpp +++ b/qtcreator/main/main.cpp @@ -5,44 +5,104 @@ 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_ABOMINABLE_FUNCTIONS -int main(){ return 0; } -#else +#include "test.hpp" +#include -//[ function_type -#include -#include +struct foo; -namespace ct = callable_traits; - -template -void test(){ - - // this example shows how callable_traits::function_type_t - // bevaves consistently for many different types - using type = ct::function_type_t; - using expect = void(int, float&, const char*); - static_assert(std::is_same{}, ""); +template +void test_case() { + assert_same, Output>(); } int main() { - auto lamda = [](int, float&, const char*){}; - using lam = decltype(lamda); - test(); + test_case(); - using function_ptr = void(*)(int, float&, const char*); - test(); +#ifndef CALLABLE_TRAITS_DISABLE_ABOMINABLE_FUNCTIONS + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); +#endif - using function_ref = void(&)(int, float&, const char*); - test(); + test_case(); - using function = void(int, float&, const char*); - test(); +#ifndef CALLABLE_TRAITS_DISABLE_ABOMINABLE_FUNCTIONS + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); +#endif + + test_case(); + +#ifndef CALLABLE_TRAITS_DISABLE_ABOMINABLE_FUNCTIONS + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); +#endif + + test_case(); + +#ifndef CALLABLE_TRAITS_DISABLE_ABOMINABLE_FUNCTIONS + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); +#endif - using abominable = void(int, float&, const char*) const; - test(); } -//] -#endif //#ifdef CALLABLE_TRAITS_DISABLE_ABOMINABLE_FUNCTIONS diff --git a/qtcreator/main/main.pro b/qtcreator/main/main.pro index a29b582..dc7cd53 100644 --- a/qtcreator/main/main.pro +++ b/qtcreator/main/main.pro @@ -9,6 +9,7 @@ CONFIG -= qt app_bundle QMAKE_CXXFLAGS += -std=c++17 -fgnu-tm -Wall -Wextra -pedantic INCLUDEPATH += ../../include +INCLUDEPATH += ../../test INCLUDEPATH += C:/local/boost_1_59_0 SOURCES += ./main.cpp diff --git a/test/add_member_const_constraints.cpp b/test/add_member_const_constraints.cpp new file mode 100644 index 0000000..ae5de03 --- /dev/null +++ b/test/add_member_const_constraints.cpp @@ -0,0 +1,35 @@ +/* +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 "test.hpp" +#include + +struct foo; + +namespace ct = callable_traits; + +int main() { + assert_sfinae(); + assert_sfinae(); + assert_sfinae(); + assert_sfinae(); + assert_sfinae(); + assert_sfinae(); + assert_sfinae(); + assert_sfinae(); + assert_sfinae(); + assert_sfinae(); + + auto lambda = [](){}; + assert_sfinae(); + assert_sfinae(); + assert_sfinae(); +} diff --git a/test/apply_member_pointer_constraints.cpp b/test/apply_member_pointer_constraints.cpp new file mode 100644 index 0000000..8666a6a --- /dev/null +++ b/test/apply_member_pointer_constraints.cpp @@ -0,0 +1,18 @@ +/*<- +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 "test.hpp" +#include + +struct foo; + +int main() { + assert_sfinae(); + assert_sfinae(); + assert_sfinae(); +} + diff --git a/test/apply_member_pointer_function.cpp b/test/apply_member_pointer_function.cpp new file mode 100644 index 0000000..1f656a7 --- /dev/null +++ b/test/apply_member_pointer_function.cpp @@ -0,0 +1,113 @@ +/*<- +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 "test.hpp" +#include + +struct foo; + +template +void test_case() { + assert_same, Output>(); +} + +int main() { + + test_case(); + +#ifndef CALLABLE_TRAITS_DISABLE_ABOMINABLE_FUNCTIONS + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); +#endif + + test_case(); + +#ifndef CALLABLE_TRAITS_DISABLE_ABOMINABLE_FUNCTIONS + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); +#endif + +//MSVC doesn't like varargs on abominable functions +#ifndef CALLABLE_TRAITS_MSVC + + test_case(); + + +#ifndef CALLABLE_TRAITS_DISABLE_ABOMINABLE_FUNCTIONS + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); +#endif //#ifndef CALLABLE_TRAITS_DISABLE_ABOMINABLE_FUNCTIONS + + test_case(); + +#ifndef CALLABLE_TRAITS_DISABLE_ABOMINABLE_FUNCTIONS + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); +#endif //#ifndef CALLABLE_TRAITS_DISABLE_ABOMINABLE_FUNCTIONS +#endif //#ifndef CALLABLE_TRAITS_MSVC + +} diff --git a/test/apply_member_pointer_pmd.cpp b/test/apply_member_pointer_pmd.cpp new file mode 100644 index 0000000..98a96a5 --- /dev/null +++ b/test/apply_member_pointer_pmd.cpp @@ -0,0 +1,30 @@ +/*<- +Copyright (c) 2016 arett 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 "test.hpp" +#include + +struct foo; + +template +void test_case() { + assert_same, Output>(); +} + +int main() { + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + + //member data - function pointer + test_case(); + test_case(); +} + diff --git a/test/apply_member_pointer_pmf.cpp b/test/apply_member_pointer_pmf.cpp new file mode 100644 index 0000000..d0ef51c --- /dev/null +++ b/test/apply_member_pointer_pmf.cpp @@ -0,0 +1,94 @@ +/*<- +Copyright (c) 2016 arett 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 "test.hpp" +#include + +struct a; +struct b; + +template +void test_case() { + assert_same, Output>(); +} + +int main() { + + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); + test_case(); +} diff --git a/test/test.hpp b/test/test.hpp new file mode 100644 index 0000000..a1356ee --- /dev/null +++ b/test/test.hpp @@ -0,0 +1,72 @@ +/* +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 + +namespace ct = callable_traits; + +#ifndef CT_ASSERT +#define CT_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) +#endif //CT_ASSERT + +#ifdef CALLABLE_TRAITS_DISABLE_REFERENCE_QUALIFIERS +#define LREF +#define RREF +#else +#define LREF & +#define RREF && +#endif + +#define TX_SAFE CALLABLE_TRAITS_TRANSACTION_SAFE_SPECIFIER +#define VA_CC CALLABLE_TRAITS_DEFAULT_VARARGS_CC + +template class, typename...> +struct is_substitution_failure; + +template class MetaFn, typename T> +struct is_substitution_failure { + + template + static auto test(...) -> std::true_type; + + template>::type* = nullptr> + static auto test(int) -> std::false_type; + + static constexpr bool value = decltype(test(0))::value; +}; + +template class MetaFn, typename T1, typename T2> +struct is_substitution_failure { + + template + static auto test(...) -> std::true_type; + + template>::type* = nullptr> + static auto test(int) -> std::false_type; + + static constexpr bool value = decltype(test(0))::value; +}; + +template class Template, typename T1, typename T2> +void assert_sfinae() { + CT_ASSERT(is_substitution_failure::value); +} + +template class Template, typename T> +void assert_sfinae() { + CT_ASSERT(is_substitution_failure::value); +} + +template +void assert_same() { + CT_ASSERT(std::is_same::value); +}