| Home | Libraries | People | FAQ | More

## Reference Documentation

This reference will be most beneficial to readers familiar with the following C++ topics:

- template specializations
- SFINAE
- `INVOKE` rules
- function types
- function pointers
- function references
- pointers to member functions (a.k.a. PMFs)
- pointers to data members (a.k.a. PMDs)
- the function call operator, `operator()`
- universal references and reference collapsing rules
- cv-qualified and ref-qualified member functions
- "abominable" function types
- C-style variadics, a.k.a. varargs

### add_member_const

##### Header

    #include <boost/callable_traits/add_member_const.hpp>

##### Definition

    template<typename T>
    using add_member_const_t = //see below

    template<typename T>
    struct add_member_const : detail::add_member_const_impl<T> {};

##### Constraints

- `T` must be a function type or a member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### Behavior

- A substitution failure occurs if the constraints are violated.
- Adds a member `const` qualifier to `T`, if not already present.

##### Input/Output Examples

`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

    #include <type_traits>
    #include <boost/callable_traits/add_member_const.hpp>

    namespace ct = boost::callable_traits;

    struct foo {};

    int main() {

        {
            using pmf = int(foo::*)();
            using expect = int(foo::*)() const;
            using test = ct::add_member_const_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            // add_member_const_t doesn't change anything when
            // the function type is already const.
            using pmf = int(foo::*)() const &&;
            using expect = int(foo::*)() const &&;
            using test = ct::add_member_const_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using pmf = int(foo::*)() volatile &;
            using expect = int(foo::*)() const volatile &;
            using test = ct::add_member_const_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            // add_member_const_t can also be used with "abominable"
            // function types.
            using f = int();
            using expect = int() const;
            using test = ct::add_member_const_t<f>;
            static_assert(std::is_same<test, expect>::value, "");
        }
    }

### add_member_cv

##### Header

    #include <boost/callable_traits/add_member_cv.hpp>

##### Definition

    template<typename T>
    using add_member_cv_t = //see below

    template<typename T>
    struct add_member_cv : detail::add_member_cv_impl<T> {};

##### Constraints

- `T` must be a function type or a member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### 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

`T` | `add_member_cv_t<T>`
--- | ---
`int()` | `int() const volatile`
`int(foo::*)()` | `int(foo::*)() const volatile`
`int(foo::*)() &` | `int(foo::*)() const volatile &`
`int(foo::*)() &&` | `int(foo::*)() const volatile &&`
`int(foo::*)() const` | `int(foo::*)() const volatile`
`int(foo::*)() volatile` | `int(foo::*)() const volatile`
`int(foo::*)() transaction_safe` | `int(foo::*)() const volatile transaction_safe`
`int` | (substitution failure)
`int (&)()` | (substitution failure)
`int (*)()` | (substitution failure)
`int foo::*` | (substitution failure)
`int (foo::* const)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/add_member_cv.hpp>

    namespace ct = boost::callable_traits;

    struct foo {};

    int main() {

        {
            using pmf = void(foo::*)();
            using expect = void(foo::*)() const volatile;
            using test = ct::add_member_cv_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            // add_member_cv_t doesn't change anything when
            // the function type is already cv-qualified.
            using pmf = void(foo::*)() const volatile &&;
            using expect = void(foo::*)() const volatile &&;
            using test = ct::add_member_cv_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using pmf = void(foo::*)() volatile &;
            using expect = void(foo::*)() const volatile &;
            using test = ct::add_member_cv_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            // add_member_cv_t can also be used with "abominable"
            // function types.
            using f = void();
            using expect = void() const volatile;
            using test = ct::add_member_cv_t<f>;
            static_assert(std::is_same<test, expect>::value, "");
        }
    }

### add_member_lvalue_reference

##### Header

    #include <boost/callable_traits/add_member_lvalue_reference.hpp>

##### Definition

    template<typename T>
    using add_member_lvalue_reference_t = //see below

    template<typename T>
    struct add_member_lvalue_reference
      : detail::add_member_lvalue_reference_impl<T> {};

##### Constraints

- `T` must be a function type or a member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### 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).

##### Input/Output Examples

`T` | `add_member_lvalue_reference_t<T>`
--- | ---
`int()` | `int() &`
`int(foo::*)()` | `int(foo::*)() &`
`int(foo::*)() &` | `int(foo::*)() &`
`int(foo::*)() &&` | `int(foo::*)() &`
`int(foo::*)() const` | `int(foo::*)() const &`
`int(foo::*)() transaction_safe` | `int(foo::*)() & transaction_safe`
`int` | (substitution failure)
`int (&)()` | (substitution failure)
`int (*)()` | (substitution failure)
`int foo::*` | (substitution failure)
`int (foo::* const)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/add_member_lvalue_reference.hpp>

    namespace ct = boost::callable_traits;

    struct foo {};

    int main() {

        {
            using pmf = void(foo::*)();
            using expect = void(foo::*)() &;
            using test = ct::add_member_lvalue_reference_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            // add_member_lvalue_reference_t doesn't change anything when
            // the function type already has an lvalue qualifier.
            using pmf = void(foo::*)() &;
            using expect = void(foo::*)() &;
            using test = ct::add_member_lvalue_reference_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            // add_member_lvalue_reference_t models C++11 reference collapsing
            // rules, so that adding an lvalue qualifier to an
            // rvalue-qualified type will force the lvalue.
            using pmf = void(foo::*)() &&;
            using expect = void(foo::*)() &;
            using test = ct::add_member_lvalue_reference_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            // add_member_lvalue_reference_t can also be used to create "abominable"
            // function types.
            using f = void();
            using expect = void() &;
            using test = ct::add_member_lvalue_reference_t<f>;
            static_assert(std::is_same<test, expect>::value, "");
        }
    }

### add_member_rvalue_reference

##### Header

    #include <boost/callable_traits/add_member_rvalue_reference.hpp>

##### Definition

    template<typename T>
    using add_member_rvalue_reference_t = //see below

    template<typename T>
    struct add_member_rvalue_reference
      : detail::add_member_rvalue_reference_impl<T> {};

##### Constraints

- `T` must be a function type or a member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### 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).

##### Input/Output Examples

`T` | `add_member_rvalue_reference_t<T>`
--- | ---
`int()` | `int() &&`
`int(foo::*)()` | `int(foo::*)() &&`
`int(foo::*)() &` | `int(foo::*)() &`
`int(foo::*)() &&` | `int(foo::*)() &&`
`int(foo::*)() const` | `int(foo::*)() const &&`
`int(foo::*)() transaction_safe` | `int(foo::*)() && transaction_safe`
`int` | (substitution failure)
`int (&)()` | (substitution failure)
`int (*)()` | (substitution failure)
`int foo::*` | (substitution failure)
`int (foo::* const)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/add_member_rvalue_reference.hpp>

    namespace ct = boost::callable_traits;

    struct foo {};

    int main() {

        {
            using pmf = void(foo::*)();
            using expect = void(foo::*)() &&;
            using test = ct::add_member_rvalue_reference_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            // add_member_rvalue_reference_t doesn't change anything when
            // the function type already has an rvalue qualifier.
            using pmf = void(foo::*)() &&;
            using expect = void(foo::*)() &&;
            using test = ct::add_member_rvalue_reference_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            // add_member_rvalue_reference_t models C++11 reference collapsing
            // rules, so that adding an rvalue qualifier to an
            // lvalue-qualified type will not change anything.
            using pmf = void(foo::*)() const &;
            using expect = void(foo::*)() const &;
            using test = ct::add_member_rvalue_reference_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            // add_member_rvalue_reference_t can also be used with "abominable"
            // function types.
            using f = void() const;
            using expect = void() const &&;
            using test = ct::add_member_rvalue_reference_t<f>;
            static_assert(std::is_same<test, expect>::value, "");
        }
    }

### add_member_volatile

##### Header

    #include <boost/callable_traits/add_member_volatile.hpp>

##### Definition

    template<typename T>
    using add_member_volatile_t = //see below

    template<typename T>
    struct add_member_volatile : detail::add_member_volatile_impl<T> {};

##### Constraints

- `T` must be a function type or a member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### Behavior

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

##### Input/Output Examples

`T` | `add_member_volatile_t<T>`
--- | ---
`int()` | `int() volatile`
`int(foo::*)()` | `int(foo::*)() volatile`
`int(foo::*)() &` | `int(foo::*)() volatile &`
`int(foo::*)() &&` | `int(foo::*)() volatile &&`
`int(foo::*)() const` | `int(foo::*)() const volatile`
`int(foo::*)() transaction_safe` | `int(foo::*)() volatile transaction_safe`
`int` | (substitution failure)
`int (&)()` | (substitution failure)
`int (*)()` | (substitution failure)
`int foo::*` | (substitution failure)
`int (foo::* const)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/add_member_volatile.hpp>

    namespace ct = boost::callable_traits;

    struct foo {};

    int main() {

        {
            using pmf = void(foo::*)();
            using expect = void(foo::*)() volatile;
            using test = ct::add_member_volatile_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            // add_member_volatile_t doesn't change anything when
            // the function type is already volatile.
            using pmf = void(foo::*)() volatile &&;
            using expect = void(foo::*)() volatile &&;
            using test = ct::add_member_volatile_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using pmf = void(foo::*)() const &;
            using expect = void(foo::*)() const volatile &;
            using test = ct::add_member_volatile_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            // add_member_volatile_t can also be used with "abominable"
            // function types.
            using f = void();
            using expect = void() volatile;
            using test = ct::add_member_volatile_t<f>;
            static_assert(std::is_same<test, expect>::value, "");
        }
    }

### add_noexcept

##### Header

    #include <boost/callable_traits/add_noexcept.hpp>

##### Definition

    template<typename T>
    using add_noexcept_t = //see below

    template<typename T>
    struct add_noexcept : detail::add_noexcept_impl<T> {};

##### Constraints

- `T` must be one of the following:
  - function type
  - function pointer type
  - function reference type
  - member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### Behavior

- A substitution failure occurs if the constraints are violated.
- Adds a `noexcept` specifier to `T`, if not already present.

##### Input/Output Examples

`T` | `add_noexcept_t<T>`
--- | ---
`int()` | `int() noexcept`
`int (&)()` | `int(&)() noexcept`
`int (*)()` | `int(*)() noexcept`
`int(foo::*)()` | `int(foo::*)() noexcept`
`int(foo::*)() &` | `int(foo::*)() & noexcept`
`int(foo::*)() &&` | `int(foo::*)() && noexcept`
`int(foo::*)() const transaction_safe` | `int(foo::*)() const transaction_safe noexcept`
`int(foo::*)() noexcept` | `int(foo::*)() noexcept`
`int` | (substitution failure)
`int foo::*` | (substitution failure)
`int (*&)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/add_noexcept.hpp>

    using boost::callable_traits::add_noexcept_t;

    static_assert(std::is_same<
        add_noexcept_t<int()>,
        int() noexcept
    >{}, "");

    int main() {}

### add_transaction_safe

##### Header

    #include <boost/callable_traits/add_transaction_safe.hpp>

##### Definition

    template<typename T>
    using add_transaction_safe_t = //see below

    template<typename T>
    struct add_transaction_safe
      : detail::add_transaction_safe_impl<T> {};

##### Constraints

- `T` must be one of the following:
  - function type
  - function pointer type
  - function reference type
  - member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### Behavior

- A substitution failure occurs if the constraints are violated.
- Adds the `transaction_safe` specifier to `T`, if not already present.

##### Input/Output Examples

`T` | `add_transaction_safe_t<T>`
--- | ---
`int()` | `int() transaction_safe`
`int (&)()` | `int(&)() transaction_safe`
`int (*)()` | `int(*)() transaction_safe`
`int(foo::*)()` | `int(foo::*)() transaction_safe`
`int(foo::*)() &` | `int(foo::*)() & transaction_safe`
`int(foo::*)() &&` | `int(foo::*)() && transaction_safe`
`int(foo::*)() const` | `int(foo::*)() const transaction_safe`
`int(foo::*)() transaction_safe` | `int(foo::*)() transaction_safe`
`int` | (substitution failure)
`int foo::*` | (substitution failure)
`int (*&)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/add_transaction_safe.hpp>

    using boost::callable_traits::add_transaction_safe_t;

    using not_safe = int();
    using safe = int() transaction_safe;
    using safe_added = add_transaction_safe_t<not_safe>;

    static_assert(std::is_same<safe, safe_added>{}, "");

    int main() {}

### add_varargs

##### Header

    #include <boost/callable_traits/add_varargs.hpp>

##### Definition

    template<typename T>
    using add_varargs_t = //see below

    template<typename T>
    struct add_varargs : detail::add_varargs_impl<T> {};

##### Constraints

- `T` must be one of the following:
  - function type
  - function pointer type
  - function reference type
  - member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### Behavior

- A substitution failure occurs if the constraints are violated.
- Adds C-style variadics (`...`) to the signature of `T`, if not already present.

##### Input/Output Examples

`T` | `add_varargs_t<T>`
--- | ---
`int()` | `int(...)`
`int(int)` | `int(int, ...)`
`int (&)()` | `int(&)(...)`
`int (*)()` | `int(*)(...)`
`int (*)(...)` | `int(*)(...)`
`int(foo::*)()` | `int(foo::*)(...)`
`int(foo::*)() &` | `int(foo::*)(...) &`
`int(foo::*)() &&` | `int(foo::*)(...) &&`
`int(foo::*)() const` | `int(foo::*)(...) const`
`int(foo::*)() transaction_safe` | `int(foo::*)(...) transaction_safe`
`int` | (substitution failure)
`int foo::*` | (substitution failure)
`int (*&)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/add_varargs.hpp>

    namespace ct = boost::callable_traits;

    struct foo {};

    int main() {

        {
            using f = void(int);
            using expect = void(int, ...);
            using test = ct::add_varargs_t<f>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using fp = void(*)();
            using expect = void(*)(...);
            using test = ct::add_varargs_t<fp>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using fr = void(&)(const char*);
            using expect = void(&)(const char*, ...);
            using test = ct::add_varargs_t<fr>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using pmf = void(foo::*)() const;
            using expect = void(foo::*)(...) const;
            using test = ct::add_varargs_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");

            // add_varargs_t doesn't change anything when
            // the type already has varargs.
            using twice = ct::add_varargs_t<test>;
            static_assert(std::is_same<test, twice>::value, "");
        }
    }

### apply_member_pointer

##### Header

    #include <boost/callable_traits/apply_member_pointer.hpp>

##### Definition

    template<typename T, typename C>
    using apply_member_pointer_t = //see below

    template<typename T, typename C>
    struct apply_member_pointer : detail::apply_member_pointer_impl<T, C> {};

##### Constraints

- `T` may be any type except `void`
- `C` must be a user-defined type

##### Behavior

- A substitution failure occurs if the constraints are violated.
- When `T` is a function, function pointer (unqualified), 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 (unqualified) 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<T> C::*`.

##### Input/Output Examples

`T` | `apply_member_pointer_t<T, foo>`
--- | ---
`int()` | `int(foo::*)()`
`int (&)()` | `int(foo::*)()`
`int (*)()` | `int(foo::*)()`
`int(bar::*)()` | `int(foo::*)()`
`int(bar::*)() &` | `int(foo::*)() &`
`int(bar::*)() &&` | `int(foo::*)() &&`
`int(bar::*)() const` | `int(foo::*)() const`
`int(bar::*)() transaction_safe` | `int(foo::*)() transaction_safe`
`int bar::*` | `int foo::*`
`int` | `int foo::*`
`int &` | `int foo::*`
`const int &` | `const int foo::*`
`int (*const)()` | `int (*const foo::*)()`
`void` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/apply_member_pointer.hpp>

    namespace ct = boost::callable_traits;

    struct foo;
    struct bar;

    int main() {

        {
            // function type -> member function pointer type
            using f = int(int);
            using g = ct::apply_member_pointer_t<f, foo>;
            using expect = int(foo::*)(int);
            static_assert(std::is_same<g, 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, "");
        }
    }

### apply_return

##### Header

    #include <boost/callable_traits/apply_return.hpp>

##### Definition

    template<typename T, typename R>
    using apply_return_t = //see below

    template<typename T, typename R>
    struct apply_return : detail::apply_return_impl<T, R> {};

##### Constraints

- `T` must one of the following:
  - `std::tuple` template instantiation
  - function
  - function pointer
  - function reference
  - member function pointer
  - member data pointer
- If `T` is a pointer, it may not be cv/ref qualified

##### Behavior

- When `T` is `std::tuple<Args...>`, the aliased type is `R(Args...)`.
- When `T` is a function, function pointer, function reference, or member function pointer, the aliased type's return type is `R`, but is otherwise identical to `T`.
- When `T` is a member data pointer of class `foo` to a `U` type (such that `T` is `U foo::*`), the aliased type is `R foo::*`.

##### Input/Output Examples

`T` | `apply_return_t<T, float>`
--- | ---
`std::tuple<int, int>` | `float(int, int)`
`int()` | `float()`
`int (&)()` | `float(&)()`
`int (*)()` | `float(*)()`
`int (*)(...)` | `float(*)()`
`int(foo::*)()` | `float(foo::*)()`
`int(foo::*)() &` | `float(foo::*)() &`
`int(foo::*)() &&` | `float(foo::*)() &&`
`int(foo::*)() const` | `float(foo::*)() const`
`int(foo::*)() transaction_safe` | `float(foo::*)() transaction_safe`
`int foo::*` | `float foo::*`
`int` | (substitution failure)
`int (*const)()` | (substitution failure)

##### Example Program

[apply_return]

### args

##### Header

    #include <boost/callable_traits/args.hpp>

##### Definition

    template<typename T, template<class...> class Container = std::tuple>
    using args_t = //see below

    template<typename T,
        template<class...> class Container = std::tuple>
    struct args : detail::args_impl<T, Container> {};

##### Constraints

- `T` must be one of the following:
  - function
  - function pointer
  - function reference
  - member function pointer
  - member data pointer
  - user-defined type with a non-overloaded `operator()`
  - type of a non-generic lambda

##### Behavior

- When the constraints are violated, a substitution failure occurs.
- When `T` is a function, function pointer, or function reference, the aliased type is `Container` instantiated with the function's parameter types.
- When `T` is a function object, the aliased type is `Container` instantiated with the `T::operator()` parameter types.
- When `T` is a member function pointer, the aliased type is a `Container` instantiation, where the first type argument is a reference to the parent class of `T`, qualified according to the member qualifiers on `T`, such that the first type is equivalent to `boost::callable_traits::qualified_class_of_t<T>`. The subsequent type arguments, if any, are the parameter types of the member function.
- When `T` is a member data pointer, the aliased type is `Container` with a single element, which is a `const` reference to the parent class of `T`.

##### Input/Output Examples

`T` | `args_t<T>`
--- | ---
`void(float, char, int)` | `std::tuple<float, char, int>`
`void(*)(float, char, int)` | `std::tuple<float, char, int`
`void(&)(float, char, int)` | `std::tuple<float, char, int`
`void(float, char, int) const &&` | `std::tuple<float, char, int>`
`void(*)()` | `std::tuple<>`
`void(foo::* const &)(float, char, int)` | `std::tuple<foo&, float, char, int>`
`int(foo::*)(int) const` | `std::tuple<const foo&, int>`
`void(foo::*)() volatile &&` | `std::tuple<volatile foo &&>`
`int foo::*` | `std::tuple<const foo&>`
`const int foo::*` | `std::tuple<const foo&>`
`int` | (substitution failure)
`int (*const)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <memory>
    #include <boost/callable_traits.hpp>

    namespace ct = boost::callable_traits;

    template<typename T, typename Expect>
    void test(){
        using args_t = ct::args_t<T>;
        static_assert(std::is_same<args_t, Expect>::value, "");
    }

    int main() {

        {
            auto lamda = [](int, float&, const char*){};
            using lam = decltype(lamda);
            using expect = std::tuple<int, float&, const char*>;

            test<lam, expect>();
        }

        {
            struct foo;
            using pmf = void(foo::*)(int, float&, const char*);
            using expect = std::tuple<foo&, int, float&, const char*>;

            test<pmf, expect>();
        }

        {
            using function_ptr = void(*)(int, float&, const char*);
            using expect = std::tuple<int, float&, const char*>;
            test<function_ptr, expect>();
        }

        {
            using function_ref = void(&)(int, float&, const char*);
            using expect = std::tuple<int, float&, const char*>;
            test<function_ref, expect>();
        }

        {
            using function = void(int, float&, const char*);
            using expect = std::tuple<int, float&, const char*>;
            test<function, expect>();
        }

        {
            using abominable = void(int, float&, const char*) const;
            using expect = std::tuple<int, float&, const char*>;
            test<abominable, expect>();
        }
    }

### class_of

##### Header

    #include <boost/callable_traits/class_of.hpp>

##### Definition

    template<typename T>
    using class_of_t = //see below

    template<typename T>
    struct class_of : detail::class_of_impl<T> {};

##### Constraints

- `T` must be a member pointer

##### Behavior

- A substitution failure occurs if the constraints are violated.
- The aliased type is the parent class of the member. In other words, if `T` is expanded to `U C::*`, the aliased type is `C`.

##### Input/Output Examples

`T` | `class_of_t<T>`
--- | ---
`int foo::*` | `foo`
`void(foo::* const &)() const` | `foo`

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/class_of.hpp>

    namespace ct = boost::callable_traits;

    struct foo;

    static_assert(std::is_same<foo, ct::class_of_t<int(foo::*)()>>::value, "");
    static_assert(std::is_same<foo, ct::class_of_t<int foo::*>>::value, "");

    int main() {}

### function_type

##### Header

    #include <boost/callable_traits/function_type.hpp>

##### Definition

    template<typename T>
    using function_type_t = //see below

    template<typename T>
    struct function_type : detail::function_type_impl<T> {};

##### Constraints

- `T` must be one of the following:
  - function
  - function pointer
  - function reference
  - member function pointer
  - member data pointer
  - user-defined type with a non-overloaded `operator()`
  - type of a non-generic lambda

##### Behavior

- When the constraints are violated, a substitution failure occurs.
- When `T` is a function, the aliased type is identical to `T`, except that the aliased function type will not have member qualifiers or the `transaction_safe` specifier.
- When `T` is a function pointer, the aliased type is equivalent to `std::remove_pointer_t<T>`.
- When `T` is a function reference, the aliased type is equivalent to `std::remove_reference_t<T>`.
- When `T` is a function object, the aliased type is a function type with the same return type and parameter list as `T`'s `operator()`.
- When `T` is a member function pointer, the aliased type is a function type with the same return type as `T`, and the first parameter is a reference to the parent class of `T`, qualified according to the member qualifiers on `T`. The subsequent parameters, if any, are the parameter types of `T`.
- When `T` is a member data pointer, the aliased type is a function type returning the underlying member type of `T`, taking a single parameter, which is a `const` reference to the parent type of `T`.
- In all cases, the aliased function type will not have member qualifiers, and will not have the `transaction_safe` specifier.

##### Input/Output Examples

`T` | `function_type_t<T>`
--- | ---
`void(int)` | `void(int)`
`void(int) const` | `void(int)`
`void(int) transaction_safe` | `void(int)`
`void(*const &)(int)` | `void(int)`
`void(&)(int)` | `void(int)`
`void(* volatile)()` | `void()`
`int(foo::*)(int)` | `int(foo&, int)`
`int(foo::*)(int) const` | `int(const foo&, int)`
`void(foo::*)() volatile &&` | `void(volatile foo&&)`
`int foo::*` | `int(const foo&)`
`const int foo::*` | `int(const foo&)`
`int` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits.hpp>

    namespace ct = boost::callable_traits;

    template<typename T>
    void test(){

        // this example shows how boost::callable_traits::function_type_t
        // bevaves consistently for many different types
        using type = ct::function_type_t<T>;
        using expect = void(int, float&, const char*);
        static_assert(std::is_same<expect, type>{}, "");
    }

    int main() {

        auto lamda = [](int, float&, const char*){};
        using lam = decltype(lamda);
        test<lam>();

        using function_ptr = void(*)(int, float&, const char*);
        test<function_ptr>();

        using function_ref = void(&)(int, float&, const char*);
        test<function_ref>();

        using function = void(int, float&, const char*);
        test<function>();

        using abominable = void(int, float&, const char*) const;
        test<abominable>();
    }

### has_member_qualifiers

##### Header

    #include <boost/callable_traits/has_member_qualifiers.hpp>

##### Definition

    // inherits from either std::true_type or std::false_type
    template<typename T>
    struct has_member_qualifiers;

    // only available when variable templates are supported
    template<typename T>
    constexpr bool has_member_qualifiers_v = //see below

##### Constraints

- none

##### Behavior

- `std::false_type` is inherited by `has_member_qualifiers<T>` and is aliased by `typename has_member_qualifiers<T>::type`, except when one of the following criteria is met, in which case `std::true_type` would be similarly inherited and aliased:
  - `T` is a function with member qualifiers
  - `T` is a member function pointer with member qualifiers
  - `T` is a function object with a member-qualified `operator()`
- On compilers that support variable templates, `has_member_qualifiers_v<T>` is equivalent to `has_member_qualifiers<T>::value`.

##### Input/Output Examples

`T` | `has_member_qualifiers_v<T>`
--- | ---
`void() const` | `true`
`void() const transaction_safe` | `true`
`void() volatile &&` | `true`
`int(foo::*)() &` | `true`
`void(foo::*)() const` | `true`
`void(foo::*&)() const` | `true`
`void(foo::* const)() const` | `true`
`void()` | `false`
`void() transaction_safe` | `false`
`void(*)()` | `false`
`void(*&)()` | `false`
`int` | `false`
`const int` | `false`
`int foo::*` | `false`
`const int foo::*` | `false`

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/has_member_qualifiers.hpp>

    namespace ct = boost::callable_traits;

    struct foo;

    static_assert(ct::has_member_qualifiers<int(foo::*)() const>::value, "");
    static_assert(ct::has_member_qualifiers<int(foo::*)() volatile>::value, "");
    static_assert(!ct::has_member_qualifiers<int(foo::*)()>::value, "");

    int main() {}

### has_varargs

##### Header

    #include <boost/callable_traits/has_varargs.hpp>

##### Definition

    // inherits from either std::true_type or std::false_type
    template<typename T>
    struct has_varargs;

    // only available when variable templates are supported
    template<typename T>
    constexpr bool has_varargs_v = //see below

##### Constraints

- none

##### Behavior

- `std::false_type` is inherited by `has_varargs<T>` and is aliased by `typename has_varargs<T>::type`, except when one of the following criteria is met, in which case `std::true_type` would be similarly inherited and aliased:
  - `T` is a function, function pointer, or function reference where the function's parameter list includes C-style variadics.
  - `T` is a pointer to a member function with C-style variadics in the parameter list.
  - `T` is a function object with a non-overloaded `operator()`, which has C-style variadics in the parameter list of its `operator()`.
- On compilers that support variable templates, `has_varargs_v<T>` is equivalent to `has_varargs<T>::value`.

##### Input/Output Examples

`T` | `has_varargs_v<T>`
--- | ---
`void(...)` | `true`
`void(int, ...) const` | `true`
`void(* volatile)(...)` | `true`
`void(&)(...)` | `true`
`void(foo::*)(...) const` | `true`
`void(*)()` | `false`
`void(*&)()` | `false`
`int` | `false`
`const int` | `false`
`int foo::*` | `false`

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/has_varargs.hpp>

    namespace ct = boost::callable_traits;

    static_assert(ct::has_varargs<int(...)>::value, "");
    static_assert(!ct::has_varargs<int()>::value, "");

    int main() {}

### has_void_return

##### Header

    #include <boost/callable_traits/has_void_return.hpp>

##### Definition

    // inherits from either std::true_type or std::false_type
    template<typename T>
    struct has_void_return;

    // only available when variable templates are supported
    template<typename T>
    constexpr bool has_void_return_v = //see below

##### Constraints

- none

##### Behavior

- `std::false_type` is inherited by `has_void_return<T>` and is aliased by `typename has_void_return<T>::type`, except when one of the following criteria is met, in which case `std::true_type` would be similarly inherited and aliased:
  - `T` is a function, function pointer, or function reference where the function's return type is `void`.
  - `T` is a pointer to a member function whose return type is `void`.
  - `T` is a function object with a non-overloaded `operator()`, where the `operator()` function returns `void`.
- On compilers that support variable templates, `has_void_return_v<T>` is equivalent to `has_void_return<T>::value`.

##### Input/Output Examples

`T` | `has_void_return_v<T>`
--- | ---
`void()` | `true`
`void(int) const` | `true`
`void(* const &)()` | `true`
`void(&)()` | `true`
`void(foo::*)() const` | `true`
`int(*)()` | `false`
`int(*&)()` | `false`
`int` | `false`
`int foo::*` | `false`
`void* foo::*` | `false`

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/has_void_return.hpp>

    namespace ct = boost::callable_traits;

    static_assert(ct::has_void_return<void()>::value, "");
    static_assert(!ct::has_void_return<int()>::value, "");

    int main() {}

### is_const_member

##### Header

    #include <boost/callable_traits/is_const_member.hpp>

##### Definition

    // inherits from either std::true_type or std::false_type
    template<typename T>
    struct is_const_member;

    // only available when variable templates are supported
    template<typename T>
    constexpr bool is_const_member_v = //see below

##### Constraints

- none

##### Behavior

- `is_const_member<T>::value` is `true` when either:
  - `T` is a function type with a `const` member qualifier
  - `T` is a pointer to a member function with a `const` member qualifier
  - `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a `const` member qualifier
- On compilers that support variable templates, `is_const_member_v<T>` is equivalent to `is_const_member<T>::value`.

##### Input/Output Examples

`T` | `is_const_member_v<T>`
--- | ---
`int() const` | `true`
`int() const volatile` | `true`
`int() const & transaction_safe` | `true`
`int() const &&` | `true`
`int(foo::*&)() const` | `true`
`int(foo::*)() const volatile` | `true`
`int(foo::*)() const volatile &&` | `true`
`int(foo::* const)() const` | `true`
`int()` | `false`
`int() volatile` | `false`
`int() &&` | `false`
`int(*)()` | `false`
`int` | `false`
`int foo::*` | `false`
`const int foo::*` | `false`

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/is_const_member.hpp>

    namespace ct = boost::callable_traits;

    struct foo;

    static_assert(ct::is_const_member<int(foo::*)() const>::value, "");
    static_assert(!ct::is_const_member<int(foo::*)()>::value, "");

    int main() {}

### is_cv_member

##### Header

    #include <boost/callable_traits/is_cv_member.hpp>

##### Definition

    // inherits from either std::true_type or std::false_type
    template<typename T>
    struct is_cv_member;

    // only available when variable templates are supported
    template<typename T>
    constexpr bool is_cv_member_v = //see below

##### Constraints

- none

##### Behavior

- `is_cv_member<T>::value` is `true` when either:
  - `T` is a function type with both `const` and `volatile` member qualifiers
  - `T` is a pointer to a member function with both `const` and `volatile` member qualifiers
  - `T` is a function object with a non-overloaded `operator()`, where the `operator()` has both `const` and `volatile` member qualifiers
- On compilers that support variable templates, `is_cv_member_v<T>` is equivalent to `is_cv_member<T>::value`.

##### Input/Output Examples

`T` | `is_cv_member_v<T>`
--- | ---
`int() const volatile` | `true`
`int() const volatile &` | `true`
`int(foo::* const &)() const volatile` | `true`
`int() const` | `false`
`int() volatile` | `false`
`int(foo::*)() const` | `false`
`int() const` | `false`
`int() volatile` | `false`
`int() &&` | `false`
`int(*)()` | `false`
`int` | `false`
`int foo::*` | `false`
`const int foo::*` | `false`

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/is_cv_member.hpp>

    namespace ct = boost::callable_traits;

    struct foo;

    static_assert(ct::is_cv_member<int(foo::*)() const volatile>::value, "");
    static_assert(!ct::is_cv_member<int(foo::*)()>::value, "");
    static_assert(!ct::is_cv_member<int(foo::*)() const>::value, "");
    static_assert(!ct::is_cv_member<int(foo::*)() volatile>::value, "");

    int main() {}

### is_invocable

##### Header

    #include <boost/callable_traits/is_invocable.hpp>

##### Definition

    // inherits from either std::true_type or std::false_type
    template<typename T, typename... Args>
    struct is_invocable;

    // inherits from either std::true_type or std::false_type
    template<typename Ret, typename T, typename... Args>
    struct is_invocable_r;

    // only available when variable templates are supported
    template<typename T, typename... Args>
    constexpr bool is_invocable_v = //see below

    // only available when variable templates are supported
    template<typename Ret, typename T, typename... Args>
    constexpr bool is_invocable_r_v = //see below

##### Constraints

- none

##### Behavior

- standalone c++11 implementation of c++17 `std::is_invocable`, `std::is_invocable_r`

  | Note
  ref-qualified overloads of `operator()` with different signatures are not handled correctly yet.

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/is_invocable.hpp>

    namespace ct = boost::callable_traits;

    struct foo {
        template<typename T>
        typename std::enable_if<std::is_integral<T>::value>::type
        operator()(T){}
    };

    static_assert(ct::is_invocable<foo, int>::value, "");
    static_assert(!ct::is_invocable<foo, double>::value, "");

    int main() {}

### is_lvalue_reference_member

##### Header

    #include <boost/callable_traits/is_lvalue_reference_member.hpp>

##### Definition

    // inherits from either std::true_type or std::false_type
    template<typename T>
    struct is_lvalue_reference_member;

    // only available when variable templates are supported
    template<typename T>
    constexpr bool is_lvalue_reference_member_v = //see below

##### Constraints

- none

##### Behavior

- `is_lvalue_reference_member<T>::value` is `true` when either:
  - `T` is a function type with a '&' member qualifier
  - `T` is a pointer to a member function with a '&' member qualifiers
  - `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a '&' member qualifier
- On compilers that support variable templates, `is_lvalue_reference_member_v<T>` is equivalent to `is_lvalue_reference_member<T>::value`.

##### Input/Output Examples

`T` | `is_lvalue_reference_member_v<T>`
--- | ---
`int() &` | `true`
`int(foo::* const)() const &` | `true`
`int() const` | `false`
`int() volatile` | `false`
`int(foo::*)() const` | `false`
`int() const` | `false`
`int() volatile` | `false`
`int() &&` | `false`
`int(*)()` | `false`
`int` | `false`
`int foo::*` | `false`
`const int foo::*` | `false`

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/is_lvalue_reference_member.hpp>

    namespace ct = boost::callable_traits;

    static_assert(ct::is_lvalue_reference_member<int()&>::value, "");
    static_assert(!ct::is_lvalue_reference_member<int()&&>::value, "");
    static_assert(!ct::is_lvalue_reference_member<int()>::value, "");

    struct foo;

    static_assert(ct::is_lvalue_reference_member<int(foo::*)()&>::value, "");
    static_assert(!ct::is_lvalue_reference_member<int(foo::*)()&&>::value, "");
    static_assert(!ct::is_lvalue_reference_member<int(foo::*)()>::value, "");

    int main() {}

### is_reference_member

##### Header

    #include <boost/callable_traits/is_reference_member.hpp>

##### Definition

    // inherits from either std::true_type or std::false_type
    template<typename T>
    struct is_reference_member;

    // only available when variable templates are supported
    template<typename T>
    constexpr bool is_reference_member_v = //see below

##### Constraints

- none

##### Behavior

- `is_reference_member<T>::value` is `true` when either:
  - `T` is a function type with a '&' or '&&' member qualifier
  - `T` is a pointer to a member function with a '&' or '&&' member qualifiers
  - `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a '&' or '&&' member qualifier
- On compilers that support variable templates, `is_reference_member_v<T>` is equivalent to `is_reference_member<T>::value`.

##### Input/Output Examples

`T` | `is_reference_member_v<T>`
--- | ---
`int() &` | `true`
`int() const &&` | `true`
`int(foo::* const)() &&` | `true`
`int(foo::*)(...) volatile &` | `true`
`int() const` | `false`
`int() volatile` | `false`
`int(foo::*)() const` | `false`
`int() const` | `false`
`int() volatile` | `false`
`int(*)()` | `false`
`int` | `false`
`int foo::*` | `false`
`const int foo::*` | `false`

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/is_reference_member.hpp>

    namespace ct = boost::callable_traits;

    static_assert(ct::is_reference_member<int()&>::value, "");
    static_assert(ct::is_reference_member<int()&&>::value, "");
    static_assert(!ct::is_reference_member<int()>::value, "");

    struct foo;

    static_assert(ct::is_reference_member<int(foo::*)()&>::value, "");
    static_assert(ct::is_reference_member<int(foo::*)()&&>::value, "");
    static_assert(!ct::is_reference_member<int(foo::*)()>::value, "");

    int main() {}

### is_rvalue_reference_member

##### Header

    #include <boost/callable_traits/is_rvalue_reference_member.hpp>

##### Definition

    // inherits from either std::true_type or std::false_type
    template<typename T>
    struct is_rvalue_reference_member;

    // only available when variable templates are supported
    template<typename T>
    constexpr bool is_rvalue_reference_member_v = //see below

##### Constraints

- none

##### Behavior

- `is_rvalue_reference_member<T>::value` is `true` when either:
  - `T` is a function type with a '&&' member qualifier
  - `T` is a pointer to a member function with a '&&' member qualifiers
  - `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a '&&' member qualifier
- On compilers that support variable templates, `is_rvalue_reference_member_v<T>` is equivalent to `is_rvalue_reference_member<T>::value`.

##### Input/Output Examples

`T` | `is_rvalue_reference_member_v<T>`
--- | ---
`int() const &&` | `true`
`int(foo::*)() &&` | `true`
`int() const` | `false`
`int() volatile` | `false`
`int(foo::* volatile)() const` | `false`
`int() const` | `false`
`int() volatile` | `false`
`int() &` | `false`
`int(*)()` | `false`
`int` | `false`
`int foo::*` | `false`
`const int foo::*` | `false`

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/is_rvalue_reference_member.hpp>

    namespace ct = boost::callable_traits;

    static_assert(ct::is_rvalue_reference_member<int()&&>::value, "");
    static_assert(!ct::is_rvalue_reference_member<int()&>::value, "");
    static_assert(!ct::is_rvalue_reference_member<int()>::value, "");

    struct foo;

    static_assert(ct::is_rvalue_reference_member<int(foo::*)()&&>::value, "");
    static_assert(!ct::is_rvalue_reference_member<int(foo::*)()&>::value, "");
    static_assert(!ct::is_rvalue_reference_member<int(foo::*)()>::value, "");

    int main() {}

### is_noexcept

##### Header

    #include <boost/callable_traits/is_noexcept.hpp>

##### Definition

    // inherits from either std::true_type or std::false_type
    template<typename T>
    struct is_noexcept;

    // only available when variable templates are supported
    template<typename T>
    constexpr bool is_noexcept_v = //see below

##### Constraints

- none

- ##### Behavior

- `is_noexcept<T>::value` is `true` when either:
  - `T` is a function type, function pointer type, function reference type, or member function pointer type where the function has a `noexcept` specifier
  - `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a `noexcept` specifier
- On compilers that support variable templates, `is_noexcept_v<T>` is equivalent to `is_noexcept<T>::value`.

##### Input/Output Examples

`T` | `is_noexcept_v<T>`
--- | ---
`int() const noexcept` | `true`
`int(* const &)() noexcept` | `true`
`int(&)() noexcept` | `true`
`int(foo::*)() noexcept` | `true`
`int() const` | `false`
`int() volatile` | `false`
`int(foo::*)() const` | `false`
`int() const` | `false`
`int() volatile` | `false`
`int() &` | `false`
`int(*)()` | `false`
`int` | `false`
`int foo::*` | `false`
`const int foo::*` | `false`

##### Example Program

    #include <boost/callable_traits/is_noexcept.hpp>

    namespace ct = boost::callable_traits;

    struct foo;

    static_assert(ct::is_noexcept<int() noexcept>::value, "");
    static_assert(ct::is_noexcept<int(*)() noexcept>::value, "");
    static_assert(ct::is_noexcept<int(&)() noexcept>::value, "");
    static_assert(ct::is_noexcept<int(foo::*)() const noexcept>::value, "");

    static_assert(!ct::is_noexcept<int()>::value, "");
    static_assert(!ct::is_noexcept<int(*)()>::value, "");
    static_assert(!ct::is_noexcept<int(&)()>::value, "");
    static_assert(!ct::is_noexcept<int(foo::*)() const>::value, "");

    int main() {}

### is_transaction_safe

##### Header

    #include <boost/callable_traits/is_transaction_safe.hpp>

##### Definition

    // inherits from either std::true_type or std::false_type
    template<typename T>
    struct is_transaction_safe;

    // only available when variable templates are supported
    template<typename T>
    constexpr bool is_transaction_safe_v = //see below

##### Constraints

- none

- ##### Behavior

- `is_transaction_safe<T>::value` is `true` when either:
  - `T` is a function type, function pointer type, function reference type, or member function pointer type where the function has a `transaction_safe` specifier
  - `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a `transaction_safe` specifier
- On compilers that support variable templates, `is_transaction_safe_v<T>` is equivalent to `is_transaction_safe<T>::value`.

##### Input/Output Examples

`T` | `is_transaction_safe_v<T>`
--- | ---
`int() const transaction_safe` | `true`
`int(*)() transaction_safe` | `true`
`int(&)() transaction_safe` | `true`
`int(foo::* const)() transaction_safe` | `true`
`int() const` | `false`
`int() volatile` | `false`
`int(foo::*)() const` | `false`
`int() const` | `false`
`int() volatile` | `false`
`int() &` | `false`
`int(*)()` | `false`
`int` | `false`
`int foo::*` | `false`
`const int foo::*` | `false`

##### Example Program

    #include <boost/callable_traits/is_transaction_safe.hpp>

    namespace ct = boost::callable_traits;

    struct foo;

    static_assert(ct::is_transaction_safe<int() transaction_safe>::value, "");
    static_assert(ct::is_transaction_safe<int(*)() transaction_safe>::value, "");
    static_assert(ct::is_transaction_safe<int(&)() transaction_safe>::value, "");
    static_assert(ct::is_transaction_safe<int(foo::*)() const transaction_safe>::value, "");

    static_assert(!ct::is_transaction_safe<int()>::value, "");
    static_assert(!ct::is_transaction_safe<int(*)()>::value, "");
    static_assert(!ct::is_transaction_safe<int(&)()>::value, "");
    static_assert(!ct::is_transaction_safe<int(foo::*)() const>::value, "");

    int main() {}

### is_volatile_member

##### Header

    #include <boost/callable_traits/is_volatile_member.hpp>

##### Definition

    // inherits from either std::true_type or std::false_type
    template<typename T>
    struct is_volatile_member;

    // only available when variable templates are supported
    template<typename T>
    constexpr bool is_volatile_member_v = //see below

##### Constraints

- none

##### Behavior

- `is_volatile_member<T>::value` is `true` when either:
  - `T` is a function type with a `volatile` member qualifier
  - `T` is a pointer to a member function with a `volatile` member qualifier
  - `T` is a function object with a non-overloaded `operator()`, where the `operator()` has a `volatile` member qualifier
- On compilers that support variable templates, `is_volatile_member_v<T>` is equivalent to `is_volatile_member<T>::value`.

##### Input/Output Examples

`T` | `is_volatile_member_v<T>`
--- | ---
`int() volatile` | `true`
`int() const volatile` | `true`
`int() volatile &&` | `true`
`int(foo::*)() volatile` | `true`
`int(foo::* const)() volatile` | `true`
`int(foo::*)() const volatile` | `true`
`int(foo::*)() const volatile &&` | `true`
`int()` | `false`
`int() const` | `false`
`int() &&` | `false`
`int(*)()` | `false`
`int` | `false`
`int foo::*` | `false`
`volatile int foo::*` | `false`

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/is_volatile_member.hpp>

    namespace ct = boost::callable_traits;

    static_assert(ct::is_volatile_member<int() volatile>::value, "");
    static_assert(ct::is_volatile_member<int() const volatile>::value, "");
    static_assert(!ct::is_volatile_member<int()>::value, "");

    struct foo;

    static_assert(ct::is_volatile_member<int(foo::*)() volatile>::value, "");
    static_assert(!ct::is_volatile_member<int(foo::*)() const>::value, "");
    static_assert(!ct::is_volatile_member<int(foo::*)()>::value, "");

    int main() {}

### qualified_class_of

##### Header

    #include <boost/callable_traits/qualified_class_of.hpp>

##### Definition

    template<typename T>
    using qualified_class_of_t = //see below

    template<typename T>
    struct qualified_class_of : detail::qualified_class_of_impl<T> {};

##### Constraints

- `T` must be a member pointer

##### Behavior

- A substitution failure occurs if the constraints are violated.
- If `T` is a member function pointer, the aliased type is the parent class of the member, qualified according to the member qualifiers on `T`. If `T` does not have a member reference qualifier, then the aliased type will be an lvalue reference.
- If `T` is a member data pointer, the aliased type is equivalent to `ct::class_of<T> const &`.

##### Input/Output Examples

`T` | `qualified_class_of_t<T>`
--- | ---
`void(foo::*)()` | `foo &`
`void(foo::* volatile)() const` | `foo const &`
`void(foo::*)() &&` | `foo &&`
`void(foo::*&)() volatile &&` | `foo volatile &&`
`int foo::*` | `foo const &`
`const int foo::*` | `foo const &`

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/qualified_class_of.hpp>

    namespace ct = boost::callable_traits;

    struct foo;

    static_assert(std::is_same<foo &,
        ct::qualified_class_of_t<int(foo::*)()>>::value, "");

    static_assert(std::is_same<foo const &,
        ct::qualified_class_of_t<int(foo::*)() const>>::value, "");

    static_assert(std::is_same<foo volatile &&,
        ct::qualified_class_of_t<int(foo::*)() volatile &&>>::value, "");

    int main() {}

### remove_member_const

##### Header

    #include <boost/callable_traits/remove_member_const.hpp>

##### Definition

    template<typename T>
    using remove_member_const_t = //see below

    template<typename T>
    struct remove_member_const : detail::remove_member_const_impl<T> {};

##### Constraints

- `T` must be a function type or a member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### Behavior

- A substitution failure occurs if the constraints are violated.
- Removes the member `const` qualifier from `T`, if present.

##### Input/Output Examples

`T` | `remove_member_const_t<T>`
--- | ---
`int() const` | `int()`
`int(foo::*)() const` | `int(foo::*)()`
`int(foo::*)() const &` | `int(foo::*)() &`
`int(foo::*)() const &&` | `int(foo::*)() &&`
`int(foo::*)() const` | `int(foo::*)()`
`int(foo::*)() const volatile` | `int(foo::*)() volatile`
`int` | (substitution failure)
`int (&)()` | (substitution failure)
`int (*)()` | (substitution failure)
`int foo::*` | (substitution failure)
`int (foo::* const)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/remove_member_const.hpp>

    namespace ct = boost::callable_traits;

    struct foo {};

    int main() {

        {
            using pmf = int(foo::*)() const;
            using expect = int(foo::*)();
            using test = ct::remove_member_const_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using pmf = int(foo::*)() const &&;
            using expect = int(foo::*)() &&;
            using test = ct::remove_member_const_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using pmf = int(foo::*)() const volatile &;
            using expect = int(foo::*)() volatile &;
            using test = ct::remove_member_const_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using f = int() const;
            using expect = int();
            using test = ct::remove_member_const_t<f>;
            static_assert(std::is_same<test, expect>::value, "");
        }
    }

### remove_member_cv

##### Header

    #include <boost/callable_traits/remove_member_cv.hpp>

##### Definition

    template<typename T>
    using remove_member_cv_t = //see below

    template<typename T>
    struct remove_member_cv : detail::remove_member_cv_impl<T> {};

##### Constraints

- `T` must be a function type or a member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### Behavior

- A substitution failure occurs if the constraints are violated.
- Removes member `const` and/or `volatile` qualifiers from `T`, if present.

##### Input/Output Examples

`T` | `remove_member_cv_t<T>`
--- | ---
`int() const volatile` | `int()`
`int(foo::*)() const volatile` | `int(foo::*)()`
`int(foo::*)() volatile` | `int(foo::*)()`
`int(foo::*)() const` | `int(foo::*)()`
`int(foo::*)() const &` | `int(foo::*)() &`
`int(foo::*)() const &&` | `int(foo::*)() &&`
`int(foo::*)() const` | `int(foo::*)()`
`int` | (substitution failure)
`int (&)()` | (substitution failure)
`int (*)()` | (substitution failure)
`int foo::*` | (substitution failure)
`int (foo::* const)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/remove_member_cv.hpp>

    namespace ct = boost::callable_traits;

    struct foo {};

    int main() {

        {
            using pmf = int(foo::*)() const volatile;
            using expect = int(foo::*)();
            using test = ct::remove_member_cv_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using pmf = int(foo::*)() const &&;
            using expect = int(foo::*)() &&;
            using test = ct::remove_member_cv_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using pmf = int(foo::*)() const volatile &;
            using expect = int(foo::*)() &;
            using test = ct::remove_member_cv_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using f = int() const volatile;
            using expect = int();
            using test = ct::remove_member_cv_t<f>;
            static_assert(std::is_same<test, expect>::value, "");
        }
    }

### remove_member_reference

##### Header

    #include <boost/callable_traits/remove_member_reference.hpp>

##### Definition

    template<typename T>
    using remove_member_reference_t = //see below

    template<typename T>
    struct remove_member_reference
      : detail::remove_member_reference_impl<T> {};

##### Constraints

- `T` must be a function type or a member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### Behavior

- A substitution failure occuers if the constraints are violated.
- Removes member `&` or `&&` qualifiers from `T`, if present.

##### Input/Output Examples

`T` | `remove_member_const_t<T>`
--- | ---
`int() &` | `int()`
`int(foo::*)() &` | `int(foo::*)()`
`int(foo::*)() const &` | `int(foo::*)() const`
`int(foo::*)() const &&` | `int(foo::*)() const`
`int(foo::*)()` | `int(foo::*)()`
`int` | (substitution failure)
`int (&)()` | (substitution failure)
`int (*)()` | (substitution failure)
`int foo::*` | (substitution failure)
`int (foo::* const)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/remove_member_reference.hpp>

    namespace ct = boost::callable_traits;

    struct foo {};

    int main() {

        {
            using pmf = int(foo::*)() &;
            using expect = int(foo::*)();
            using test = ct::remove_member_reference_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using pmf = int(foo::*)() const &&;
            using expect = int(foo::*)() const;
            using test = ct::remove_member_reference_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using pmf = int(foo::*)() const volatile &;
            using expect = int(foo::*)() const volatile;
            using test = ct::remove_member_reference_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using f = int() &&;
            using expect = int();
            using test = ct::remove_member_reference_t<f>;
            static_assert(std::is_same<test, expect>::value, "");
        }
    }

### remove_member_volatile

##### Header

    #include <boost/callable_traits/remove_member_volatile.hpp>

##### Definition

    template<typename T>
    using remove_member_volatile_t = //see below

    template<typename T>
    struct remove_member_volatile : detail::remove_member_volatile_impl<T> {};

##### Constraints

- `T` must be a function type or a member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### Behavior

- A substitution failure occurs if the constraints are violated.
- Removes the member `volatile` qualifier from `T`, if present.

##### Input/Output Examples

`T` | `remove_member_volatile_t<T>`
--- | ---
`int() volatile` | `int()`
`int(foo::*)() volatile` | `int(foo::*)()`
`int(foo::*)() volatile &` | `int(foo::*)() &`
`int(foo::*)() volatile &&` | `int(foo::*)() &&`
`int(foo::*)() volatile` | `int(foo::*)()`
`int(foo::*)() const volatile` | `int(foo::*)() const`
`int` | (substitution failure)
`int (&)()` | (substitution failure)
`int (*)()` | (substitution failure)
`int foo::*` | (substitution failure)
`int (foo::* const)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/remove_member_volatile.hpp>

    namespace ct = boost::callable_traits;

    struct foo {};

    int main() {

        {
            using pmf = int(foo::*)() const volatile;
            using expect = int(foo::*)() const;
            using test = ct::remove_member_volatile_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using pmf = int(foo::*)() volatile &&;
            using expect = int(foo::*)() &&;
            using test = ct::remove_member_volatile_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using pmf = int(foo::*)() volatile &;
            using expect = int(foo::*)() &;
            using test = ct::remove_member_volatile_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using f = int() const volatile;
            using expect = int() const;
            using test = ct::remove_member_volatile_t<f>;
            static_assert(std::is_same<test, expect>::value, "");
        }
    }

### remove_noexcept

##### Header

    #include <boost/callable_traits/remove_noexcept.hpp>

##### Definition

    template<typename T>
    using remove_noexcept_t = //see below

    template<typename T>
    struct remove_noexcept : detail::remove_noexcept_impl<T> {};

##### Constraints

- `T` must be one of the following:
  - function type
  - function pointer type
  - function reference type
  - member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### Behavior

- A substitution failure occurs if the constraints are violated.
- Removes the `noexcept` specifier from `T`, if present.

##### Input/Output Examples

`T` | `remove_noexcept_t<T>`
--- | ---
`int() const noexcept` | `int() const`
`int(*)() noexcept` | `int(*)()`
`int(&)() noexcept` | `int(&)()`
`int(foo::*)() noexcept` | `int(foo::*)()`
`int() const` | `int() const`
`int(*)()` | `int(*)()`
`int(&)()` | `int(&)()`
`int` | (substitution failure)
`int foo::*` | (substitution failure)
`int (foo::* const)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/remove_noexcept.hpp>

    using boost::callable_traits::remove_noexcept_t;

    static_assert(std::is_same<
        remove_noexcept_t<int() noexcept>,
        int()
    >{}, "");

    int main() {}

### remove_transaction_safe

##### Header

    #include <boost/callable_traits/remove_transaction_safe.hpp>

##### Definition

    template<typename T>
    using remove_transaction_safe_t = //see below

    template<typename T>
    struct remove_transaction_safe : detail::remove_transaction_safe_impl<T> {};

##### Constraints

- `T` must be one of the following:
  - function type
  - function pointer type
  - function reference type
  - member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### Behavior

- A substitution failure occurs if the constraints are violated.
- Removes the member `transaction_safe` specifier from `T`, if present.

##### Input/Output Examples

`T` | `remove_transaction_safe_t<T>`
--- | ---
`int() const transaction_safe` | `int() const`
`int(*)() transaction_safe` | `int(*)()`
`int(&)() transaction_safe` | `int(&)()`
`int(foo::*)() transaction_safe` | `int(foo::*)()`
`int() const` | `int() const`
`int(*)()` | `int(*)()`
`int(&)()` | `int(&)()`
`int` | (substitution failure)
`int foo::*` | (substitution failure)
`int (foo::* const)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/remove_transaction_safe.hpp>

    namespace ct = boost::callable_traits;

    using ts = int() transaction_safe;
    using not_ts = int();
    using ts_removed = ct::remove_transaction_safe_t<ts>;

    static_assert(std::is_same<not_ts, ts_removed>{}, "");

    int main() {}

### remove_varargs

##### Header

    #include <boost/callable_traits/remove_varargs.hpp>

##### Definition

    template<typename T>
    using remove_varargs_t = //see below

    template<typename T>
    struct remove_varargs : detail::remove_varargs_impl<T> {};

##### Constraints

- `T` must be one of the following:
  - function type
  - function pointer type
  - function reference type
  - member function pointer type
- If `T` is a pointer, it may not be cv/ref qualified

##### Behavior

- A substitution failure occurs if the constraints are violated.
- Removes C-style variadics (`...`) from the signature of `T`, if present.

##### Input/Output Examples

`T` | `remove_varargs_t<T>`
--- | ---
`int(...)` | `int()`
`int(int, ...)` | `int(int)`
`int (&)(...)` | `int(&)()`
`int (*)()` | `int(*)()`
`int(foo::*)(...)` | `int(foo::*)()`
`int(foo::*)(...) &` | `int(foo::*)() &`
`int(foo::*)(...) &&` | `int(foo::*)() &&`
`int(foo::*)(...) const` | `int(foo::*)() const`
`int(foo::*)(...) transaction_safe` | `int(foo::*)() transaction_safe`
`int` | (substitution failure)
`int foo::*` | (substitution failure)
`int (* const)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits/remove_varargs.hpp>

    namespace ct = boost::callable_traits;

    struct foo {};

    int main() {

        {
            using f = void(int, ...);
            using expect = void(int);
            using test = ct::remove_varargs_t<f>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using fp = void(*)(...);
            using expect = void(*)();
            using test = ct::remove_varargs_t<fp>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using fr = void(&)(const char*, ...);
            using expect = void(&)(const char*);
            using test = ct::remove_varargs_t<fr>;
            static_assert(std::is_same<test, expect>::value, "");
        } {
            using pmf = void(foo::*)(...) const;
            using expect = void(foo::*)() const;
            using test = ct::remove_varargs_t<pmf>;
            static_assert(std::is_same<test, expect>::value, "");
        }
    }

### return_type

##### Header

    #include <boost/callable_traits/return_type.hpp>

##### Definition

    template<typename T>
    using return_type_t = //see below

    template<typename T>
    struct return_type : detail::return_type_impl<T> {};

##### Constraints

- `T` must be one of the following:
  - function
  - function pointer
  - function reference
  - member function pointer
  - member data pointer
  - user-defined type with a non-overloaded `operator()`
  - type of a non-generic lambda

##### Behavior

- When the constraints are violated, a substitution failure occurs.
- The aliased type is the return type of `T`.

##### Input/Output Examples

`T` | `return_type_t<T, std::tuple>`
--- | ---
`void()` | `void`
`float(*)()` | `float`
`const char*(&)()` | `const char *`
`int(foo::*)() const` | `int`
`int` | (substitution failure)
`int (*const)()` | (substitution failure)

##### Example Program

    #include <type_traits>
    #include <boost/callable_traits.hpp>

    namespace ct = boost::callable_traits;

    using expect = int;

    struct foo;

    template<typename T>
    void test() {
        using result = ct::return_type_t<T>;
        static_assert(std::is_same<expect, result>{}, "");
    }

    int main() {

        test<int()>();
        test<int(*)()>();
        test<int(&)()>();
        test<int() const>();
        test<int(foo::*)() const>();

        auto x = []() -> int { return 0; };

        test<decltype(x)>();
    }