Stratosphere: Add WrapIpcCommandImpl templating.

This commit is contained in:
Michael Scire 2018-04-20 19:34:29 -06:00
parent b5d3ce04e8
commit 7a2cfa4d60
80 changed files with 6694 additions and 162 deletions

View file

@ -48,7 +48,7 @@ CFLAGS := -g -Wall -O2 -ffunction-sections \
CFLAGS += $(INCLUDE) -D__SWITCH__
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++1z
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)

View file

@ -0,0 +1,47 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_BOOST_CLBL_TRTS_HPP
#define BOOST_CLBL_TRTS_BOOST_CLBL_TRTS_HPP
#include <boost/callable_traits/detail/core.hpp>
#include <boost/callable_traits/add_member_const.hpp>
#include <boost/callable_traits/add_member_cv.hpp>
#include <boost/callable_traits/add_member_lvalue_reference.hpp>
#include <boost/callable_traits/add_member_rvalue_reference.hpp>
#include <boost/callable_traits/add_member_volatile.hpp>
#include <boost/callable_traits/add_noexcept.hpp>
#include <boost/callable_traits/add_transaction_safe.hpp>
#include <boost/callable_traits/add_varargs.hpp>
#include <boost/callable_traits/apply_member_pointer.hpp>
#include <boost/callable_traits/apply_return.hpp>
#include <boost/callable_traits/args.hpp>
#include <boost/callable_traits/class_of.hpp>
#include <boost/callable_traits/function_type.hpp>
#include <boost/callable_traits/has_member_qualifiers.hpp>
#include <boost/callable_traits/has_varargs.hpp>
#include <boost/callable_traits/has_void_return.hpp>
#include <boost/callable_traits/is_const_member.hpp>
#include <boost/callable_traits/is_invocable.hpp>
#include <boost/callable_traits/is_lvalue_reference_member.hpp>
#include <boost/callable_traits/is_reference_member.hpp>
#include <boost/callable_traits/is_rvalue_reference_member.hpp>
#include <boost/callable_traits/is_noexcept.hpp>
#include <boost/callable_traits/is_transaction_safe.hpp>
#include <boost/callable_traits/is_volatile_member.hpp>
#include <boost/callable_traits/qualified_class_of.hpp>
#include <boost/callable_traits/remove_member_const.hpp>
#include <boost/callable_traits/remove_member_cv.hpp>
#include <boost/callable_traits/remove_member_reference.hpp>
#include <boost/callable_traits/remove_member_volatile.hpp>
#include <boost/callable_traits/remove_noexcept.hpp>
#include <boost/callable_traits/remove_transaction_safe.hpp>
#include <boost/callable_traits/remove_varargs.hpp>
#include <boost/callable_traits/return_type.hpp>
#endif

View file

@ -0,0 +1,105 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_CONST_HPP
#define BOOST_CLBL_TRTS_ADD_MEMBER_CONST_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ add_member_const_hpp
/*`
[section:ref_add_member_const add_member_const]
[heading Header]
``#include <boost/callable_traits/add_member_const.hpp>``
[heading Definition]
*/
template<typename T>
using add_member_const_t = //see below
//<-
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
detail::sfinae_try<
typename detail::traits<T>::add_member_const,
detail::fail_when_same<typename detail::traits<T>::add_member_const,
detail::abominable_functions_not_supported_on_this_compiler,
this_compiler_doesnt_support_abominable_function_types>,
detail::fail_if_invalid<typename detail::traits<T>::add_member_const,
member_qualifiers_are_illegal_for_this_type>>;
#else
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_member_const,
member_qualifiers_are_illegal_for_this_type>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
namespace detail {
template<typename T, typename = std::false_type>
struct add_member_const_impl {};
template<typename T>
struct add_member_const_impl <T, typename std::is_same<
add_member_const_t<T>, detail::dummy>::type>
{
using type = add_member_const_t<T>;
};
}
//->
template<typename T>
struct add_member_const : detail::add_member_const_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading Behavior]
* A substitution failure occurs 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<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)]]
]
[heading Example Program]
[import ../example/add_member_const.cpp]
[add_member_const]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_ADD_MEMBER_CONST_HPP

View file

@ -0,0 +1,101 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_CV_HPP
#define BOOST_CLBL_TRTS_ADD_MEMBER_CV_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ add_member_cv_hpp
/*`
[section:ref_add_member_cv add_member_cv]
[heading Header]
``#include <boost/callable_traits/add_member_cv.hpp>``
[heading Definition]
*/
template<typename T>
using add_member_cv_t = //see below
//<-
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
detail::sfinae_try<
typename detail::traits<T>::add_member_cv,
detail::fail_when_same<typename detail::traits<T>::add_member_cv,
detail::abominable_functions_not_supported_on_this_compiler,
this_compiler_doesnt_support_abominable_function_types>,
detail::fail_if_invalid<typename detail::traits<T>::add_member_cv,
member_qualifiers_are_illegal_for_this_type>>;
#else
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_member_cv,
member_qualifiers_are_illegal_for_this_type>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
namespace detail {
template<typename T, typename = std::false_type>
struct add_member_cv_impl {};
template<typename T>
struct add_member_cv_impl <T, typename std::is_same<
add_member_cv_t<T>, detail::dummy>::type>
{
using type = add_member_cv_t<T>;
};
}
//->
template<typename T>
struct add_member_cv : detail::add_member_cv_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[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]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/add_member_cv.cpp]
[add_member_cv]
[endsect]
*/
//]
#endif

View file

@ -0,0 +1,114 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_LVALUE_REFERENCE_HPP
#define BOOST_CLBL_TRTS_ADD_MEMBER_LVALUE_REFERENCE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ add_member_lvalue_reference_hpp
/*`
[section:ref_add_member_lvalue_reference add_member_lvalue_reference]
[heading Header]
``#include <boost/callable_traits/add_member_lvalue_reference.hpp>``
[heading Definition]
*/
#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
template<typename T>
struct add_member_lvalue_reference_t {
static_assert(std::is_same<T, detail::dummy>::value,
"Reference member qualifiers are not supported by this configuration.");
};
#else
template<typename T>
using add_member_lvalue_reference_t = //see below
//<-
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
detail::sfinae_try<
typename detail::traits<T>::add_member_lvalue_reference,
detail::fail_when_same<typename detail::traits<T>::add_member_lvalue_reference,
detail::abominable_functions_not_supported_on_this_compiler,
this_compiler_doesnt_support_abominable_function_types>,
detail::fail_if_invalid<
typename detail::traits<T>::add_member_lvalue_reference,
member_qualifiers_are_illegal_for_this_type>>;
#else
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_member_lvalue_reference,
member_qualifiers_are_illegal_for_this_type>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
namespace detail {
template<typename T, typename = std::false_type>
struct add_member_lvalue_reference_impl {};
template<typename T>
struct add_member_lvalue_reference_impl <T, typename std::is_same<
add_member_lvalue_reference_t<T>, detail::dummy>::type>
{
using type = add_member_lvalue_reference_t<T>;
};
}
//->
template<typename T>
struct add_member_lvalue_reference
: detail::add_member_lvalue_reference_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[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).
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/add_member_lvalue_reference.cpp]
[add_member_lvalue_reference]
[endsect]
*/
//]
#endif

View file

@ -0,0 +1,113 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_RVALUE_REFERENCE_HPP
#define BOOST_CLBL_TRTS_ADD_MEMBER_RVALUE_REFERENCE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ add_member_rvalue_reference_hpp
/*`
[section:ref_add_member_rvalue_reference add_member_rvalue_reference]
[heading Header]
``#include <boost/callable_traits/add_member_rvalue_reference.hpp>``
[heading Definition]
*/
#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
template<typename T>
struct add_member_rvalue_reference_t {
static_assert(std::is_same<T, detail::dummy>::value,
"Reference member qualifiers are not supported by this configuration.");
};
#else
template<typename T>
using add_member_rvalue_reference_t = //see below
//<-
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
detail::sfinae_try<
typename detail::traits<T>::add_member_rvalue_reference,
detail::fail_when_same<typename detail::traits<T>::add_member_rvalue_reference,
detail::abominable_functions_not_supported_on_this_compiler,
this_compiler_doesnt_support_abominable_function_types>,
detail::fail_if_invalid<typename detail::traits<T>::add_member_rvalue_reference,
member_qualifiers_are_illegal_for_this_type>>;
#else
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_member_rvalue_reference,
member_qualifiers_are_illegal_for_this_type>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
namespace detail {
template<typename T, typename = std::false_type>
struct add_member_rvalue_reference_impl {};
template<typename T>
struct add_member_rvalue_reference_impl <T, typename std::is_same<
add_member_rvalue_reference_t<T>, detail::dummy>::type>
{
using type = add_member_rvalue_reference_t<T>;
};
}
//->
template<typename T>
struct add_member_rvalue_reference
: detail::add_member_rvalue_reference_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[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).
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/add_member_rvalue_reference.cpp]
[add_member_rvalue_reference]
[endsect][/section:ref_add_member_rvalue_reference]
*/
//]
#endif

View file

@ -0,0 +1,100 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_MEMBER_VOLATILE_HPP
#define BOOST_CLBL_TRTS_ADD_MEMBER_VOLATILE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ add_member_volatile_hpp
/*`
[section:ref_add_member_volatile add_member_volatile]
[heading Header]
``#include <boost/callable_traits/add_member_volatile.hpp>``
[heading Definition]
*/
template<typename T>
using add_member_volatile_t = //see below
//<-
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
detail::sfinae_try<
typename detail::traits<T>::add_member_volatile,
detail::fail_when_same<typename detail::traits<T>::add_member_volatile,
detail::abominable_functions_not_supported_on_this_compiler,
this_compiler_doesnt_support_abominable_function_types>,
detail::fail_if_invalid<
typename detail::traits<T>::add_member_volatile,
member_qualifiers_are_illegal_for_this_type>>;
#else
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_member_volatile,
member_qualifiers_are_illegal_for_this_type>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
namespace detail {
template<typename T, typename = std::false_type>
struct add_member_volatile_impl {};
template<typename T>
struct add_member_volatile_impl <T, typename std::is_same<
add_member_volatile_t<T>, detail::dummy>::type>
{
using type = add_member_volatile_t<T>;
};
}
//->
template<typename T>
struct add_member_volatile : detail::add_member_volatile_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[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]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/add_member_volatile.cpp]
[add_member_volatile]
[endsect][/section:ref_add_member_volatile]
*/
//]
#endif

View file

@ -0,0 +1,108 @@
/*
@file add_noexcept
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_NOEXCEPT_HPP
#define BOOST_CLBL_TRTS_ADD_NOEXCEPT_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(add_noexcept)
BOOST_CLBL_TRTS_SFINAE_MSG(add_noexcept, cannot_add_noexcept_to_this_type)
#ifndef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
template<typename T>
struct add_noexcept_t {
static_assert(std::is_same<T, detail::dummy>::value,
"noexcept types not supported by this configuration.");
};
template<typename T>
struct add_noexcept {
static_assert(std::is_same<T, detail::dummy>::value,
"noexcept types not supported by this configuration.");
};
#else
//[ add_noexcept_hpp
/*`
[section:ref_add_noexcept add_noexcept]
[heading Header]
``#include <boost/callable_traits/add_noexcept.hpp>``
[heading Definition]
*/
template<typename T>
using add_noexcept_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_noexcept,
cannot_add_noexcept_to_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct add_noexcept_impl {};
template<typename T>
struct add_noexcept_impl <T, typename std::is_same<
add_noexcept_t<T>, detail::dummy>::type>
{
using type = add_noexcept_t<T>;
};
}
//->
template<typename T>
struct add_noexcept : detail::add_noexcept_impl<T> {};
//<-
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Adds a `noexcept` specifier to `T`, if not already present.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/add_noexcept.cpp]
[add_noexcept]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_ADD_NOEXCEPT_HPP

View file

@ -0,0 +1,110 @@
/*
@file add_transaction_safe
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_TRANSACTION_SAFE_HPP
#define BOOST_CLBL_TRTS_ADD_TRANSACTION_SAFE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(add_transaction_safe)
BOOST_CLBL_TRTS_SFINAE_MSG(add_transaction_safe, cannot_add_transaction_safe_to_this_type)
#ifndef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
template<typename T>
struct add_transaction_safe_t {
static_assert(std::is_same<T, detail::dummy>::value,
"transaction_safe not supported by this configuration.");
};
template<typename T>
struct add_transaction_safe {
static_assert(std::is_same<T, detail::dummy>::value,
"transaction_safe not supported by this configuration.");
};
#else
//[ add_transaction_safe_hpp
/*`
[section:ref_add_transaction_safe add_transaction_safe]
[heading Header]
``#include <boost/callable_traits/add_transaction_safe.hpp>``
[heading Definition]
*/
template<typename T>
using add_transaction_safe_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_transaction_safe,
cannot_add_transaction_safe_to_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct add_transaction_safe_impl {};
template<typename T>
struct add_transaction_safe_impl <T, typename std::is_same<
add_transaction_safe_t<T>, detail::dummy>::type>
{
using type = add_transaction_safe_t<T>;
};
}
//->
template<typename T>
struct add_transaction_safe
: detail::add_transaction_safe_impl<T> {};
//<-
#endif // #ifndef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Adds the `transaction_safe` specifier to `T`, if not already present.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/add_transaction_safe.cpp]
[add_transaction_safe]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_ADD_TRANSACTION_SAFE_HPP

View file

@ -0,0 +1,90 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ADD_VARARGS_HPP
#define BOOST_CLBL_TRTS_ADD_VARARGS_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ add_varargs_hpp
/*`
[section:ref_add_varargs add_varargs]
[heading Header]
``#include <boost/callable_traits/add_varargs.hpp>``
[heading Definition]
*/
template<typename T>
using add_varargs_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::add_varargs,
varargs_are_illegal_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct add_varargs_impl {};
template<typename T>
struct add_varargs_impl <T, typename std::is_same<
add_varargs_t<T>, detail::dummy>::type>
{
using type = add_varargs_t<T>;
};
}
//->
template<typename T>
struct add_varargs : detail::add_varargs_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Adds C-style variadics (`...`) to the signature of `T`, if not already present.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/add_varargs.cpp]
[add_varargs]
[endsect]
*/
//]
#endif

View file

@ -0,0 +1,123 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_APPLY_MEMBER_POINTER_HPP
#define BOOST_CLBL_TRTS_APPLY_MEMBER_POINTER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(apply_member_pointer)
BOOST_CLBL_TRTS_SFINAE_MSG(apply_member_pointer, members_cannot_have_a_type_of_void)
BOOST_CLBL_TRTS_SFINAE_MSG(apply_member_pointer, second_template_argument_must_be_a_class_or_struct)
namespace detail {
template<typename T, typename C, bool = std::is_class<C>::value>
struct make_member_pointer;
template<typename T, typename C>
struct make_member_pointer<T, C, true> {
using type = typename std::remove_reference<T>::type C::*;
};
template<typename C>
struct make_member_pointer<void, C, true> {
using type = invalid_type;
};
template<typename T, typename C>
struct make_member_pointer<T, C, false> {
using type = error_type<T>;
};
template<typename T, typename C>
using make_member_pointer_t = typename make_member_pointer<T, C>::type;
}
//[ apply_member_pointer_hpp
/*`
[section:ref_apply_member_pointer apply_member_pointer]
[heading Header]
``#include <boost/callable_traits/apply_member_pointer.hpp>``
[heading Definition]
*/
template<typename T, typename C>
using apply_member_pointer_t = //see below
//<-
detail::sfinae_try<
detail::fallback_if_invalid<
typename detail::traits<T>::template apply_member_pointer<C>,
typename detail::make_member_pointer<T, C>::type>,
detail::fail_when_same<void, T, members_cannot_have_a_type_of_void>,
detail::fail_if<!std::is_class<C>::value,
second_template_argument_must_be_a_class_or_struct> >;
namespace detail {
template<typename T, typename C, typename = std::false_type>
struct apply_member_pointer_impl {};
template<typename T, typename C>
struct apply_member_pointer_impl <T, C, typename std::is_same<
apply_member_pointer_t<T, C>, detail::dummy>::type>
{
using type = apply_member_pointer_t<T, C>;
};
}
//->
template<typename T, typename C>
struct apply_member_pointer : detail::apply_member_pointer_impl<T, C> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `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 (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::*`.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/apply_member_pointer.cpp]
[apply_member_pointer]
[endsect]
*/
//]
#endif

View file

@ -0,0 +1,109 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_APPLY_RETURN_HPP
#define BOOST_CLBL_TRTS_APPLY_RETURN_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(apply_return)
BOOST_CLBL_TRTS_SFINAE_MSG(apply_return, invalid_types_for_apply_return)
namespace detail {
template<typename T, typename R>
struct apply_return_helper {
using type = typename detail::traits<T>::template apply_return<R>;
};
//special case
template<typename... Args, typename R>
struct apply_return_helper<std::tuple<Args...>, R> {
using type = R(Args...);
};
}
//[ apply_return_hpp
/*`
[section:ref_apply_return apply_return]
[heading Header]
``#include <boost/callable_traits/apply_return.hpp>``
[heading Definition]
*/
template<typename T, typename R>
using apply_return_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::apply_return_helper<T, R>::type,
invalid_types_for_apply_return>;
namespace detail {
template<typename T, typename R, typename = std::false_type>
struct apply_return_impl {};
template<typename T, typename R>
struct apply_return_impl <T, R, typename std::is_same<
apply_return_t<T, R>, detail::dummy>::type>
{
using type = apply_return_t<T, R>;
};
}
//->
template<typename T, typename R>
struct apply_return : detail::apply_return_impl<T, R> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading 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::*`.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[/import ../example/apply_return.cpp]
[apply_return]
[endsect]
*/
//]
#endif

View file

@ -0,0 +1,97 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_ARGS_HPP
#define BOOST_CLBL_TRTS_ARGS_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ args_hpp
/*`[section:ref_args args]
[heading Header]
``#include <boost/callable_traits/args.hpp>``
[heading Definition]
*/
template<typename T, template<class...> class Container = std::tuple>
using args_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<
detail::shallow_decay<T>>::template expand_args<Container>,
cannot_expand_the_parameter_list_of_first_template_argument>;
namespace detail {
template<typename T, template<class...> class Container,
typename = std::false_type>
struct args_impl {};
template<typename T, template<class...> class Container>
struct args_impl <T, Container, typename std::is_same<
args_t<T, Container>, detail::dummy>::type>
{
using type = args_t<T, Container>;
};
}
//->
template<typename T,
template<class...> class Container = std::tuple>
struct args : detail::args_impl<T, Container> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading 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`.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/args.cpp]
[args]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_ARGS_HPP

View file

@ -0,0 +1,75 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_class_of_HPP
#define BOOST_CLBL_TRTS_class_of_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ class_of_hpp
/*`
[section:ref_class_of class_of]
[heading Header]
``#include <boost/callable_traits/class_of.hpp>``
[heading Definition]
*/
template<typename T>
using class_of_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<detail::shallow_decay<T>>::class_type,
type_is_not_a_member_pointer>;
namespace detail {
template<typename T, typename = std::false_type>
struct class_of_impl {};
template<typename T>
struct class_of_impl <T, typename std::is_same<
class_of_t<T>, detail::dummy>::type>
{
using type = class_of_t<T>;
};
}
//->
template<typename T>
struct class_of : detail::class_of_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be a member pointer
[heading 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`.
[heading Input/Output Examples]
[table
[[`T`] [`class_of_t<T>`]]
[[`int foo::*`] [`foo`]]
[[`void(foo::* const &)() const`] [`foo`]]
]
[heading Example Program]
[import ../example/class_of.cpp]
[class_of]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_class_of_HPP

View file

@ -0,0 +1,109 @@
/*
@Copyright Barrett Adair 2016-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_CONFIG_HPP
#define BOOST_CLBL_TRTS_DETAIL_CONFIG_HPP
#include <type_traits>
#include <tuple>
#include <utility>
#include <cstdint>
#define BOOST_CLBL_TRTS_EMPTY_
#define BOOST_CLBL_TRTS_EMPTY BOOST_CLBL_TRTS_EMPTY_
#ifdef __cpp_transactional_memory
# define BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
#endif
#ifdef __cpp_inline_variables
# define BOOST_CLBL_TRAITS_INLINE_VAR inline
#else
# define BOOST_CLBL_TRAITS_INLINE_VAR
#endif
#ifdef __cpp_noexcept_function_type
# define BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#endif
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
# define BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER transaction_safe
#else
# define BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
#endif
#ifndef __clang__
# if defined(__GNUC__)
# define BOOST_CLBL_TRTS_GCC
# if __GNUC__ >= 6
# define BOOST_CLBL_TRTS_GCC_AT_LEAST_6_0_0
# endif
# if __GNUC__ < 5
# define BOOST_CLBL_TRTS_GCC_OLDER_THAN_5_0_0
# endif
# if __GNUC__ >= 5
# define BOOST_CLBL_TRTS_GCC_AT_LEAST_4_9_2
# elif __GNUC__ == 4 && __GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ >= 2
# define BOOST_CLBL_TRTS_GCC_AT_LEAST_4_9_2
# else
# define BOOST_CLBL_TRTS_GCC_OLDER_THAN_4_9_2
# endif //#if __GNUC__ >= 5
# endif //#if defined __GNUC__
#endif // #ifndef __clang__
#ifdef _MSC_VER
# ifdef __clang__
# define BOOST_CLBL_TRTS_CLANG_C2
# else
# define BOOST_CLBL_TRTS_MSVC
# endif // #ifdef __clang__
#endif // #ifdef _MSC_VER
#define BOOST_CLBL_TRTS_IX_SEQ(...) ::std::index_sequence< __VA_ARGS__ >
#define BOOST_CLBL_TRTS_MAKE_IX_SEQ(...) ::std::make_index_sequence< __VA_ARGS__ >
#define BOOST_CLBL_TRTS_DISJUNCTION(...) ::std::disjunction< __VA_ARGS__ >
#ifndef __cpp_variable_templates
# define BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
#endif
#ifndef __cpp_lib_logical_traits
# include <boost/callable_traits/detail/polyfills/disjunction.hpp>
#endif //__cpp_lib_logical_traits
#ifndef __cpp_lib_integer_sequence
# include <boost/callable_traits/detail/polyfills/make_index_sequence.hpp>
#endif // __cpp_lib_integer_sequence
#if defined(BOOST_CLBL_TRTS_MSVC) && !defined(BOOST_DISABLE_WIN32)
# define BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC __cdecl
# define BOOST_CLBL_TRTS_PMF_VARGARGS_CDECL_DEFAULT
#else
# define BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#endif // #if defined(BOOST_CLBL_TRTS_MSVC) && !defined(BOOST_DISABLE_WIN32))
#if (defined(BOOST_CLBL_TRTS_GCC) && !defined(BOOST_CLBL_TRTS_GCC_AT_LEAST_4_9_2)) || defined(__INTEL_COMPILER)
# define BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
# define BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
#endif // #if defined BOOST_CLBL_TRTS_GCC && !defined(BOOST_CLBL_TRTS_GCC_AT_LEAST_4_9_2)
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
# define BOOST_CLBL_TRTS_ABOMINABLE_CONST BOOST_CLBL_TRTS_EMPTY
# define BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE BOOST_CLBL_TRTS_EMPTY
#else
# define BOOST_CLBL_TRTS_ABOMINABLE_CONST const
# define BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE volatile
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
# define BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER noexcept
#else
# define BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER BOOST_CLBL_TRTS_EMPTY
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_CONFIG_HPP

View file

@ -0,0 +1,19 @@
/*
@Copyright Barrett Adair 2016-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_CORE_HPP
#define BOOST_CLBL_TRTS_DETAIL_CORE_HPP
#include <boost/callable_traits/detail/utility.hpp>
#include <boost/callable_traits/detail/traits.hpp>
#include <boost/callable_traits/detail/function_object.hpp>
#include <boost/callable_traits/detail/function.hpp>
#include <boost/callable_traits/detail/pmf.hpp>
#include <boost/callable_traits/detail/pmd.hpp>
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_CORE_HPP

View file

@ -0,0 +1,207 @@
/*
Copyright Barrett Adair 2016-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_DEFAULT_BOOST_CLBL_TRTS_HPP
#define BOOST_CLBL_TRTS_DETAIL_DEFAULT_BOOST_CLBL_TRTS_HPP
namespace boost { namespace callable_traits { namespace detail {
template<typename T = void>
struct default_callable_traits {
// value is used by all traits classes to participate
// in the <callable_traits/detail/traits.hpp> disjunction.
static constexpr bool value = false;
// used facilitate the disjunction in
// <callable_traits/detail/traits.hpp>
using traits = default_callable_traits;
using error_t = error_type<T>;
// represents the type under consideration
using type = error_t;
// std::true_type for callables with C-style variadics
using has_varargs = std::false_type;
using return_type = error_t;
// arg_types is a std::tuple of argument types for
// callables that are not overloaded/templated function objects.
// arg_types IS defined in terms of INVOKE, which means
// a PMF's arg_types tuple will use a reference to its
// parent class as the first argument, with qualifiers added to
// match the PMF's own qualifiers.
using arg_types = error_t;
// arg_types without the decltype(*this) parameter for member functions
using non_invoke_arg_types = error_t;
// An "approximation" of a callable type, in the form
// of a plain function type. Defined in terms of INVOKE.
// An identity alias for qualified/unqualified plain function
// types.
using function_type = error_t;
// Used to smoothen the edges between PMFs and function objects
using function_object_signature = error_t;
// An identity alias for qualified/unqualified plain function
// types. Equivalent to remove_member_pointer for PMFs. Same
// as function_type for other callable types.
using qualified_function_type = error_t;
// Removes C-style variadics from a signature, if present.
// Aliases error_t for function objects and PMDs.
using remove_varargs = error_t;
// Adds C-style variadics to a signature. Aliases
// error_t for function objects and PMDs.
using add_varargs = error_t;
// std::true_type when the signature includes noexcept, when
// the feature is available
using is_noexcept = std::false_type;
// adds noexcept to a signature if the feature is available
using add_noexcept = error_t;
// removes noexcept from a signature if present
using remove_noexcept = error_t;
// std::true_type when the signature includes transaction_safe, when
// the feature is available
using is_transaction_safe = std::false_type;
// adds transaction_safe to a signature if the feature is available
using add_transaction_safe = error_t;
// removes transaction_safe from a signature if present
using remove_transaction_safe = error_t;
// The class of a PMD or PMF. error_t for other types
using class_type = error_t;
// The qualified reference type of class_type. error_t
// for non-member-pointers.
using invoke_type = error_t;
// Removes reference qualifiers from a signature.
using remove_reference = error_t;
// Adds an lvalue qualifier to a signature, in arbitrary
// accordance with C++11 reference collapsing rules.
using add_member_lvalue_reference = error_t;
// Adds an rvalue qualifier to a signature, in arbitrary
// accordance with C++11 reference collapsing rules.
using add_member_rvalue_reference = error_t;
// Adds a const qualifier to a signature.
using add_member_const = error_t;
// Adds a volatile qualifier to a signature.
using add_member_volatile = error_t;
// Adds both const and volatile qualifiers to a signature.
using add_member_cv = error_t;
// Removes a const qualifier from a signature, if present.
using remove_member_const = error_t;
// Removes a volatile qualifier from a signature, if present.
using remove_member_volatile = error_t;
// Removes both const and volatile qualifiers from a
// signature, if any.
using remove_member_cv = error_t;
// Removes the member pointer from PMDs and PMFs. An identity
// alias for other callable types.
using remove_member_pointer = error_t;
// Changes the parent class type for PMDs and PMFs. Turns
// function pointers, function references, and
// qualified/unqualified function types into PMFs. Turns
// everything else into member data pointers.
template<typename C,
typename U = T,
typename K = typename std::remove_reference<U>::type,
typename L = typename std::conditional<
std::is_same<void, K>::value, error_t, K>::type,
typename Class = typename std::conditional<
std::is_class<C>::value, C, error_t>::type>
using apply_member_pointer = typename std::conditional<
std::is_same<L, error_t>::value || std::is_same<Class, error_t>::value,
error_t, L Class::*>::type;
// Changes the return type of PMFs, function pointers, function
// references, and qualified/unqualified function types. Changes
// the data type of PMDs. error_t for function objects.
template<typename>
using apply_return = error_t;
// Expands the argument types into a template
template<template<class...> class Container>
using expand_args = error_t;
template<template<class...> class Container, typename... RightArgs>
using expand_args_left = error_t;
template<template<class...> class Container, typename... LeftArgs>
using expand_args_right = error_t;
using clear_args = error_t;
template<typename... NewArgs>
using push_front = error_t;
template<typename... NewArgs>
using push_back = error_t;
template<std::size_t ElementCount>
using pop_front = error_t;
template<std::size_t ElementCount>
using pop_back = error_t;
template<std::size_t Index, typename... NewArgs>
using insert_args = error_t;
template<std::size_t Index, std::size_t Count>
using remove_args = error_t;
template<std::size_t Index, typename... NewArgs>
using replace_args = error_t;
static constexpr qualifier_flags cv_flags = cv_of<T>::value;
static constexpr qualifier_flags ref_flags = ref_of<T>::value;
static constexpr qualifier_flags q_flags = cv_flags | ref_flags;
using has_member_qualifiers = std::integral_constant<bool, q_flags != default_>;
using is_const_member = std::integral_constant<bool, 0 < (cv_flags & const_)>;
using is_volatile_member = std::integral_constant<bool, 0 < (cv_flags & volatile_)>;
using is_cv_member = std::integral_constant<bool, cv_flags == (const_ | volatile_)>;
#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
using is_reference_member = std::false_type;
using is_lvalue_reference_member = std::false_type;
using is_rvalue_reference_member = std::false_type;
#else
using is_reference_member = std::integral_constant<bool, 0 < ref_flags>;
using is_lvalue_reference_member = std::integral_constant<bool, ref_flags == lref_>;
using is_rvalue_reference_member = std::integral_constant<bool, ref_flags == rref_>;
#endif //#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
};
}}} // namespace boost::callable_traits::detail
#endif // BOOST_CLBL_TRTS_DETAIL_DEFAULT_BOOST_CLBL_TRTS_HPP

View file

@ -0,0 +1,54 @@
#ifndef BOOST_CLBL_TRTS_DETAIL_FORWARD_DECLARATIONS
#define BOOST_CLBL_TRTS_DETAIL_FORWARD_DECLARATIONS
#include <boost/callable_traits/detail/config.hpp>
#include <boost/callable_traits/detail/default_callable_traits.hpp>
namespace boost { namespace callable_traits { namespace detail {
template<typename T>
struct function;
template<typename T>
struct has_normal_call_operator
{
template<typename N, N Value>
struct check { check(std::nullptr_t) {} };
template<typename U>
static std::int8_t test(
check<decltype(&U::operator()), &U::operator()>);
template<typename>
static std::int16_t test(...);
static constexpr bool value =
sizeof(test<T>(nullptr)) == sizeof(std::int8_t);
};
struct callable_dummy {
void operator()() {}
};
template<typename T>
using default_to_function_object = typename std::conditional<
has_normal_call_operator<T>::value,
T, callable_dummy>::type;
template<typename T>
struct pmf;
template<typename T>
struct pmd;
template<typename F, typename T = typename std::remove_reference<F>::type>
using function_object_base = typename std::conditional<
has_normal_call_operator<T>::value,
pmf<decltype(&default_to_function_object<T>::operator())>,
default_callable_traits<T>>::type;
template<typename T, typename Base = function_object_base<T>>
struct function_object;
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_FORWARD_DECLARATIONS

View file

@ -0,0 +1,192 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_FUNCTION_HPP
#define BOOST_CLBL_TRTS_DETAIL_FUNCTION_HPP
#include <boost/callable_traits/detail/config.hpp>
#include <boost/callable_traits/detail/qualifier_flags.hpp>
#include <boost/callable_traits/detail/forward_declarations.hpp>
#include <boost/callable_traits/detail/set_function_qualifiers.hpp>
#include <boost/callable_traits/detail/default_callable_traits.hpp>
namespace boost { namespace callable_traits { namespace detail {
template<typename T>
struct function : default_callable_traits<T> {};
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &&
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &&
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &&
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &&
#include <boost/callable_traits/detail/unguarded/function.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
// function pointers
#define BOOST_CLBL_TRTS_CC_TAG dummy
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC
#define BOOST_CLBL_TRTS_ST
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs.hpp>
#undef BOOST_CLBL_TRTS_ST
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
/* ?
#ifdef BOOST_CLBL_TRTS_ENABLE_CDECL
#define BOOST_CLBL_TRTS_CC_TAG cdecl_tag
#define BOOST_CLBL_TRTS_VARARGS_CC __cdecl
#define BOOST_CLBL_TRTS_CC __cdecl
#define BOOST_CLBL_TRTS_ST
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
#undef BOOST_CLBL_TRTS_ST
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif*/
#ifdef BOOST_CLBL_TRTS_ENABLE_STDCALL
#define BOOST_CLBL_TRTS_CC_TAG stdcall_tag
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC __stdcall
#define BOOST_CLBL_TRTS_ST
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
#undef BOOST_CLBL_TRTS_ST
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif
#ifdef BOOST_CLBL_TRTS_ENABLE_FASTCALL
#define BOOST_CLBL_TRTS_CC_TAG fastcall_tag
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC __fastcall
#define BOOST_CLBL_TRTS_ST
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_ST
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif
#ifdef BOOST_CLBL_TRTS_ENABLE_PASCAL
#define BOOST_CLBL_TRTS_CC_TAG pascal_tag
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC
#define BOOST_CLBL_TRTS_ST pascal
#include <boost/callable_traits/detail/unguarded/function_ptr.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_ST
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif
template<typename T>
struct function<T&> : std::conditional<function<T>::value,
function<T>, default_callable_traits<T&>>::type {
static constexpr const bool value = !std::is_pointer<T>::value;
using traits = function;
using base = function<T>;
using type = T&;
using remove_varargs = typename base::remove_varargs&;
using add_varargs = typename base::add_varargs&;
using remove_member_reference = reference_error;
using add_member_lvalue_reference = reference_error;
using add_member_rvalue_reference = reference_error;
using add_member_const = reference_error;
using add_member_volatile = reference_error;
using add_member_cv = reference_error;
using remove_member_const = reference_error;
using remove_member_volatile = reference_error;
using remove_member_cv = reference_error;
template<typename NewReturn>
using apply_return = typename base::template apply_return<NewReturn>&;
using clear_args = typename base::clear_args&;
template<typename... NewArgs>
using push_front = typename base::template push_front<NewArgs...>&;
template<typename... NewArgs>
using push_back = typename base::template push_back<NewArgs...>&;
template<std::size_t Count>
using pop_back = typename base::template pop_back<Count>&;
template<std::size_t Count>
using pop_front = typename base::template pop_front<Count>&;
template<std::size_t Index, typename... NewArgs>
using insert_args = typename base::template insert_args<Index, NewArgs...>&;
template<std::size_t Index, std::size_t Count>
using remove_args = typename base::template remove_args<Index, Count>&;
template<std::size_t Index, typename... NewArgs>
using replace_args = typename base::template replace_args<Index, NewArgs...>&;
};
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_FUNCTION_HPP

View file

@ -0,0 +1,107 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_FUNCTION_OBJECT_HPP
#define BOOST_CLBL_TRTS_DETAIL_FUNCTION_OBJECT_HPP
#include <boost/callable_traits/detail/pmf.hpp>
#include <boost/callable_traits/detail/default_callable_traits.hpp>
#include <boost/callable_traits/detail/forward_declarations.hpp>
#include <boost/callable_traits/detail/utility.hpp>
namespace boost { namespace callable_traits { namespace detail {
template<typename T, typename Base>
struct function_object : Base {
using type = T;
using error_t = error_type<T>;
using function_type = typename Base::function_object_signature;
using arg_types = typename Base::non_invoke_arg_types;
using non_invoke_arg_types = arg_types;
static constexpr const bool value = std::is_class<
typename std::remove_reference<T>::type>::value;
using traits = function_object;
using class_type = error_t;
using invoke_type = error_t;
using remove_varargs = error_t;
using add_varargs = error_t;
using is_noexcept = typename Base::is_noexcept;
using add_noexcept = error_t;
using remove_noexcept = error_t;
using is_transaction_safe = typename Base::is_transaction_safe;
using add_transaction_safe = error_t;
using remove_transaction_safe = error_t;
using clear_args = error_t;
template<template<class...> class Container>
using expand_args = typename function<function_type>::template
expand_args<Container>;
template<template<class...> class Container, typename... RightArgs>
using expand_args_left = typename function<function_type>::template
expand_args_left<Container, RightArgs...>;
template<template<class...> class Container, typename... LeftArgs>
using expand_args_right = typename function<function_type>::template
expand_args_right<Container, LeftArgs...>;
template<typename C, typename U = T>
using apply_member_pointer =
typename std::remove_reference<U>::type C::*;
template<typename>
using apply_return = error_t;
template<typename...>
using push_front = error_t;
template<typename...>
using push_back = error_t;
template<std::size_t ElementCount>
using pop_args_front = error_t;
template<std::size_t ElementCount>
using pop_args_back = error_t;
template<std::size_t Index, typename... NewArgs>
using insert_args = error_t;
template<std::size_t Index, std::size_t Count>
using remove_args = error_t;
template<std::size_t Index, typename... NewArgs>
using replace_args = error_t;
template<std::size_t Count>
using pop_front = error_t;
template<std::size_t Count>
using pop_back = error_t;
using remove_member_reference = error_t;
using add_member_lvalue_reference = error_t;
using add_member_rvalue_reference = error_t;
using add_member_const = error_t;
using add_member_volatile = error_t;
using add_member_cv = error_t;
using remove_member_const = error_t;
using remove_member_volatile = error_t;
using remove_member_cv = error_t;
};
template<typename T, typename U, typename Base>
struct function_object <T U::*, Base>
: default_callable_traits<> {};
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_FUNCTION_OBJECT_HPP

View file

@ -0,0 +1,148 @@
/*!
@file
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP
#define BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP
#include <boost/callable_traits/detail/config.hpp>
#include <boost/callable_traits/detail/forward_declarations.hpp>
#include <boost/callable_traits/detail/utility.hpp>
#include <type_traits>
#include <utility>
namespace boost { namespace callable_traits { namespace detail {
template<typename T>
struct can_dereference_t
{
template<typename>
struct check {};
template<typename U>
static std::int8_t test(
check<typename std::remove_reference<decltype(*std::declval<U>())>::type>*
);
template<typename>
static std::int16_t test(...);
static constexpr const bool value =
sizeof(test<T>(nullptr)) == sizeof(std::int8_t);
};
//returns std::true_type for pointers and smart pointers
template<typename T>
using can_dereference = std::integral_constant<bool,
can_dereference_t<T>::value>;
template<typename T, typename = std::true_type>
struct generalize_t {
using type = T;
};
template<typename T>
struct generalize_t<T, std::integral_constant<bool,
can_dereference<T>::value && !is_reference_wrapper<T>::value
>>{
using type = decltype(*std::declval<T>());
};
template<typename T>
struct generalize_t<T, is_reference_wrapper<T>> {
using type = decltype(std::declval<T>().get());
};
// When T is a pointer, generalize<T> is the resulting type of the
// pointer dereferenced. When T is an std::reference_wrapper, generalize<T>
// is the underlying reference type. Otherwise, generalize<T> is T.
template<typename T>
using generalize = typename generalize_t<T>::type;
// handles the member pointer rules of INVOKE
template<typename Base, typename T,
typename IsBaseOf = std::is_base_of<Base, shallow_decay<T>>,
typename IsSame = std::is_same<Base, shallow_decay<T>>>
using generalize_if_dissimilar = typename std::conditional<
IsBaseOf::value || IsSame::value, T, generalize<T>>::type;
template<typename Traits, bool = Traits::is_const_member::value
|| Traits::is_volatile_member::value
|| Traits::is_lvalue_reference_member::value
|| Traits::is_rvalue_reference_member::value>
struct test_invoke {
template<typename... Rgs,
typename U = typename Traits::type>
auto operator()(Rgs&&... rgs) const ->
success<decltype(std::declval<U>()(static_cast<Rgs&&>(rgs)...))>;
auto operator()(...) const -> substitution_failure;
};
template<typename F>
struct test_invoke<function<F>, true /*abominable*/> {
auto operator()(...) const -> substitution_failure;
};
template<typename Pmf, bool Ignored>
struct test_invoke<pmf<Pmf>, Ignored> {
using class_t = typename pmf<Pmf>::class_type;
template<typename U, typename... Rgs,
typename Obj = generalize_if_dissimilar<class_t, U&&>>
auto operator()(U&& u, Rgs&&... rgs) const ->
success<decltype((std::declval<Obj>().*std::declval<Pmf>())(static_cast<Rgs&&>(rgs)...))>;
auto operator()(...) const -> substitution_failure;
};
template<typename Pmd, bool Ignored>
struct test_invoke<pmd<Pmd>, Ignored> {
using class_t = typename pmd<Pmd>::class_type;
template<typename U,
typename Obj = generalize_if_dissimilar<class_t, U&&>>
auto operator()(U&& u) const ->
success<decltype(std::declval<Obj>().*std::declval<Pmd>())>;
auto operator()(...) const -> substitution_failure;
};
template<typename T, typename... Args>
struct is_invocable_impl {
using traits = detail::traits<T>;
using test = detail::test_invoke<traits>;
using result = decltype(test{}(::std::declval<Args>()...));
using type = std::integral_constant<bool, result::value>;
};
template<typename... Args>
struct is_invocable_impl<void, Args...> {
using type = std::false_type;
};
template<typename IsInvocable, typename Ret, typename T, typename... Args>
struct is_invocable_r_impl {
using traits = detail::traits<T>;
using test = detail::test_invoke<traits>;
using result = decltype(test{}(::std::declval<Args>()...));
using type = typename std::is_convertible<typename result::_::type, Ret>::type;
};
template<typename Ret, typename T, typename... Args>
struct is_invocable_r_impl<std::false_type, Ret, T, Args...> {
using type = std::false_type;
};
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP

View file

@ -0,0 +1,51 @@
#ifndef BOOST_CLBL_TRTS_PARAMETER_INDEX_HELPER_HPP
#define BOOST_CLBL_TRTS_PARAMETER_INDEX_HELPER_HPP
#include <boost/callable_traits/detail/config.hpp>
namespace boost { namespace callable_traits { namespace detail {
template<std::size_t I, typename T, bool IgnoreThisPointer = false,
bool AllowPlus1 = false, std::size_t Count = 0>
struct parameter_index_helper {
using error_t = error_type<T>;
using args_tuple = typename std::conditional<IgnoreThisPointer,
typename detail::traits<T>::non_invoke_arg_types,
typename detail::traits<T>::arg_types>::type;
static constexpr bool has_parameter_list =
!std::is_same<args_tuple, invalid_type>::value
&& !std::is_same<args_tuple, reference_error>::value;
using temp_tuple = typename std::conditional<has_parameter_list,
args_tuple, std::tuple<error_t>>::type;
static constexpr std::size_t parameter_list_size =
std::tuple_size<temp_tuple>::value;
static constexpr bool is_out_of_range = has_parameter_list &&
I >= parameter_list_size + static_cast<std::size_t>(AllowPlus1);
static constexpr bool is_count_out_of_range = has_parameter_list &&
I + Count > parameter_list_size + static_cast<std::size_t>(AllowPlus1);
static constexpr std::size_t index =
has_parameter_list && !is_out_of_range ? I : 0;
static constexpr std::size_t count =
has_parameter_list && !is_count_out_of_range ? Count : 0;
using permissive_tuple = typename std::conditional<
has_parameter_list && !is_out_of_range,
args_tuple, std::tuple<error_t>>::type;
using permissive_function = typename std::conditional<
has_parameter_list && !is_out_of_range,
T, error_t(error_t)>::type;
};
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_PARAMETER_INDEX_HELPER_HPP

View file

@ -0,0 +1,53 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_PMD_HPP
#define BOOST_CLBL_TRTS_DETAIL_PMD_HPP
#include <boost/callable_traits/detail/forward_declarations.hpp>
#include <boost/callable_traits/detail/function.hpp>
#include <boost/callable_traits/detail/traits.hpp>
#include <boost/callable_traits/detail/default_callable_traits.hpp>
#include <boost/callable_traits/detail/utility.hpp>
namespace boost { namespace callable_traits { namespace detail {
template<typename T>
struct pmd : default_callable_traits<T> {};
template<typename D, typename T>
struct pmd<D T::*> : default_callable_traits<> {
static constexpr bool value = true;
using traits = pmd;
using class_type = T;
using invoke_type = T const &;
using type = D T::*;
using function_type = typename std::add_lvalue_reference<D>::type(invoke_type);
using qualified_function_type = D(invoke_type);
using arg_types = std::tuple<invoke_type>;
using non_invoke_arg_types = std::tuple<>;
using return_type = typename std::add_lvalue_reference<D>::type;
template<typename C>
using apply_member_pointer = D C::*;
template<typename R>
using apply_return = R T::*;
template<template<class...> class Container>
using expand_args = Container<invoke_type>;
using is_member_pointer = std::true_type;
};
}}} // namespace boost::callable_traits::detail
#endif

View file

@ -0,0 +1,97 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_PMF_HPP
#define BOOST_CLBL_TRTS_DETAIL_PMF_HPP
#include <boost/callable_traits/detail/forward_declarations.hpp>
#include <boost/callable_traits/detail/set_function_qualifiers.hpp>
#include <boost/callable_traits/detail/qualifier_flags.hpp>
#include <boost/callable_traits/detail/default_callable_traits.hpp>
#include <boost/callable_traits/detail/utility.hpp>
namespace boost { namespace callable_traits { namespace detail {
template<qualifier_flags Applied, bool IsTransactionSafe, bool IsNoExcept,
typename CallingConvention, typename T, typename Return,
typename... Args>
struct set_member_function_qualifiers_t;
template<qualifier_flags Applied, bool IsTransactionSafe, bool IsNoexcept,
typename CallingConvention, typename T, typename Return,
typename... Args>
struct set_varargs_member_function_qualifiers_t;
template<qualifier_flags Flags, bool IsTransactionSafe, bool IsNoexcept,
typename... Ts>
using set_member_function_qualifiers =
typename set_member_function_qualifiers_t<Flags, IsTransactionSafe,
IsNoexcept, Ts...>::type;
template<qualifier_flags Flags, bool IsTransactionSafe, bool IsNoexcept,
typename... Ts>
using set_varargs_member_function_qualifiers =
typename set_varargs_member_function_qualifiers_t<Flags,
IsTransactionSafe, IsNoexcept, Ts...>::type;
template<typename T>
struct pmf : default_callable_traits<T> {};
#define BOOST_CLBL_TRTS_CC_TAG dummy
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC
#include <boost/callable_traits/detail/unguarded/pmf.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#define BOOST_CLBL_TRTS_CC_TAG dummy
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC
#include <boost/callable_traits/detail/unguarded/pmf_varargs.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#ifdef BOOST_CLBL_TRTS_ENABLE_CDECL
#define BOOST_CLBL_TRTS_CC_TAG cdecl_tag
#define BOOST_CLBL_TRTS_VARARGS_CC __cdecl
#define BOOST_CLBL_TRTS_CC __cdecl
#include <boost/callable_traits/detail/unguarded/pmf.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_CDECL
// Defining this macro enables undocumented features, likely broken.
// Too much work to maintain, but knock yourself out
#ifdef BOOST_CLBL_TRTS_ENABLE_STDCALL
#define BOOST_CLBL_TRTS_CC_TAG stdcall_tag
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC __stdcall
#include <boost/callable_traits/detail/unguarded/pmf.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_STDCALL
// Defining this macro enables undocumented features, likely broken.
// Too much work to officially maintain, but knock yourself out
#ifdef BOOST_CLBL_TRTS_ENABLE_FASTCALL
#define BOOST_CLBL_TRTS_CC_TAG fastcall_tag
#define BOOST_CLBL_TRTS_VARARGS_CC BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC
#define BOOST_CLBL_TRTS_CC __fastcall
#include <boost/callable_traits/detail/unguarded/pmf.hpp>
#undef BOOST_CLBL_TRTS_CC
#undef BOOST_CLBL_TRTS_CC_TAG
#undef BOOST_CLBL_TRTS_VARARGS_CC
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_FASTCALL
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_PMF_HPP

View file

@ -0,0 +1,31 @@
/*
Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_POLYFILLS_DISJUNCTION_HPP
#define BOOST_CLBL_TRTS_DETAIL_POLYFILLS_DISJUNCTION_HPP
#undef BOOST_CLBL_TRTS_DISJUNCTION
#define BOOST_CLBL_TRTS_DISJUNCTION(...) \
::boost::callable_traits::detail::disjunction<__VA_ARGS__>
namespace boost { namespace callable_traits { namespace detail {
//polyfill for C++17 std::disjunction
template<typename...>
struct disjunction : std::false_type {};
template<typename T>
struct disjunction<T> : T {};
template<typename T, typename... Ts>
struct disjunction<T, Ts...>
: std::conditional<T::value != false, T, disjunction<Ts...>>::type {};
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_POLYFILLS_DISJUNCTION_HPP

View file

@ -0,0 +1,50 @@
/*
Copyright Barrett Adair 2016-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_POLYFILLS_MAKE_INDEX_SEQUENCE_HPP
#define BOOST_CLBL_TRTS_DETAIL_POLYFILLS_MAKE_INDEX_SEQUENCE_HPP
#undef BOOST_CLBL_TRTS_IX_SEQ
#define BOOST_CLBL_TRTS_IX_SEQ(...) \
::boost::callable_traits::detail::index_sequence<__VA_ARGS__>
#undef BOOST_CLBL_TRTS_MAKE_IX_SEQ
#define BOOST_CLBL_TRTS_MAKE_IX_SEQ(...) \
::boost::callable_traits::detail::make_index_sequence<__VA_ARGS__>
namespace boost { namespace callable_traits { namespace detail {
template<std::size_t...>
struct index_sequence { using type = index_sequence; };
template<typename, typename>
struct concat;
template<std::size_t... I1, std::size_t... I2>
struct concat<index_sequence<I1...>, index_sequence<I2...>>
: index_sequence<I1..., (sizeof...(I1)+I2)...> {};
template<std::size_t N>
struct make_index_sequence_t;
template<std::size_t N>
struct make_index_sequence_t : concat<
typename make_index_sequence_t<N/2>::type,
typename make_index_sequence_t<N - N/2>::type >::type {};
template<>
struct make_index_sequence_t<0> : index_sequence<> {};
template<>
struct make_index_sequence_t<1> : index_sequence<0> {};
template<std::size_t... I>
using make_index_sequence = typename make_index_sequence_t<I...>::type;
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_POLYFILLS_MAKE_INDEX_SEQUENCE_HPP

View file

@ -0,0 +1,123 @@
/*
Defines `qualifier_flags`
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_QUALIFIER_FLAGS_HPP
#define BOOST_CLBL_TRTS_QUALIFIER_FLAGS_HPP
#include <boost/callable_traits/detail/config.hpp>
namespace boost { namespace callable_traits { namespace detail {
//bit qualifier_flags used to signify cv/ref qualifiers
using qualifier_flags = std::uint32_t;
/*
| && & V C |
--------------------------------------------
0 | 0 0 0 0 | default
1 | 0 0 0 1 | const
2 | 0 0 1 0 | volatile
3 | 0 0 1 1 | const volatile
--------------------------------------------
4 | 0 1 0 0 | &
5 | 0 1 0 1 | const &
6 | 0 1 1 0 | volatile &
7 | 0 1 1 1 | const volatile &
--------------------------------------------
8 | 1 0 0 0 | &&
9 | 1 0 0 1 | const &&
10 | 1 0 1 0 | volatile &&
11 | 1 0 1 1 | const volatile &&
*/
// Flag representing the default qualifiers on a type
// or member function overload.
constexpr qualifier_flags default_ = 0;
// Flag representing a const qualifier on a type or
// member function overload.
constexpr qualifier_flags const_ = 1;
// Flag representing a volatile qualifier on a type
// or member function overload.
constexpr qualifier_flags volatile_ = 2;
#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
constexpr qualifier_flags lref_ = default_;
constexpr qualifier_flags rref_ = default_;
#else
// Flag representing an lvalue reference type, or
// an lvalue-reference-qualified member function
// overload.
constexpr qualifier_flags lref_ = 4;
// Flag representing an lvalue reference type, or
// an rvalue-reference-qualified member function
// overload.
constexpr qualifier_flags rref_ = 8;
#endif //#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
constexpr qualifier_flags cv_ = 3;
template<qualifier_flags Flags>
using remove_const_flag = std::integral_constant<
qualifier_flags, Flags & ~const_>;
template<qualifier_flags Flags>
using is_const = std::integral_constant<bool,
(Flags & const_) != 0>;
template<qualifier_flags Flags>
using remove_volatile_flag = std::integral_constant<
qualifier_flags, Flags & ~volatile_>;
template<typename U, typename T = typename std::remove_reference<U>::type>
using cv_of = std::integral_constant<qualifier_flags,
(std::is_const<T>::value ? const_ : default_)
| (std::is_volatile<T>::value ? volatile_ : default_)>;
template<typename T>
using ref_of = std::integral_constant<qualifier_flags,
std::is_rvalue_reference<T>::value ? rref_
: (std::is_lvalue_reference<T>::value ? lref_
: default_)>;
//bit-flag implementation of C++11 reference collapsing rules
template<qualifier_flags Existing,
qualifier_flags Other,
bool AlreadyHasRef = (Existing & (lref_ | rref_)) != 0,
bool AlreadyHasLRef = (Existing & lref_) == lref_,
bool IsAddingLRef = (Other & lref_) == lref_
>
using collapse_flags = std::integral_constant<qualifier_flags,
!AlreadyHasRef ? (Existing | Other)
: (AlreadyHasLRef ? (Existing | (Other & ~rref_))
: (IsAddingLRef ? ((Existing & ~rref_) | Other )
: (Existing | Other)))>;
template<typename T> struct flag_map { static constexpr qualifier_flags value = default_; };
template<typename T> struct flag_map<T &> { static constexpr qualifier_flags value = lref_; };
template<typename T> struct flag_map<T &&> { static constexpr qualifier_flags value = rref_; };
template<typename T> struct flag_map<T const> { static constexpr qualifier_flags value = const_; };
template<typename T> struct flag_map<T const &> { static constexpr qualifier_flags value = const_ | lref_; };
template<typename T> struct flag_map<T const &&> { static constexpr qualifier_flags value = const_ | rref_; };
template<typename T> struct flag_map<T volatile> { static constexpr qualifier_flags value = volatile_; };
template<typename T> struct flag_map<T volatile &> { static constexpr qualifier_flags value = volatile_ | lref_; };
template<typename T> struct flag_map<T volatile &&> { static constexpr qualifier_flags value = volatile_ | rref_; };
template<typename T> struct flag_map<T const volatile> { static constexpr qualifier_flags value = const_ | volatile_; };
template<typename T> struct flag_map<T const volatile &> { static constexpr qualifier_flags value = const_ | volatile_ | lref_; };
template<typename T> struct flag_map<T const volatile &&> { static constexpr qualifier_flags value = const_ | volatile_ | rref_; };
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_QUALIFIER_FLAGS_HPP

View file

@ -0,0 +1,120 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_SET_FUNCTION_QUALIFIERS_HPP
#define BOOST_CLBL_TRTS_DETAIL_SET_FUNCTION_QUALIFIERS_HPP
#include <boost/callable_traits/detail/qualifier_flags.hpp>
#define BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(QUAL) \
template<typename Return, typename... Args> \
struct set_function_qualifiers_t < \
flag_map<int QUAL>::value, false, false, Return, Args...> { \
using type = Return(Args...) QUAL; \
}; \
\
template<typename Return, typename... Args> \
struct set_function_qualifiers_t < \
flag_map<int QUAL>::value, true, false, Return, Args...> { \
using type = Return(Args...) QUAL \
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER; \
}; \
\
template<typename Return, typename... Args> \
struct set_function_qualifiers_t < \
flag_map<int QUAL>::value, false, true, Return, Args...> { \
using type = Return(Args...) QUAL \
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER; \
}; \
\
template<typename Return, typename... Args> \
struct set_function_qualifiers_t < \
flag_map<int QUAL>::value, true, true, Return, Args...> { \
using type = Return(Args...) QUAL \
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER \
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER; \
}; \
\
template<typename Return, typename... Args> \
struct set_varargs_function_qualifiers_t < \
flag_map<int QUAL>::value, false, false, Return, Args...> { \
using type = Return(Args..., ...) QUAL; \
}; \
\
template<typename Return, typename... Args> \
struct set_varargs_function_qualifiers_t < \
flag_map<int QUAL>::value, true, false, Return, Args...> { \
using type = Return(Args..., ...) QUAL \
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER; \
}; \
\
template<typename Return, typename... Args> \
struct set_varargs_function_qualifiers_t < \
flag_map<int QUAL>::value, false, true, Return, Args...> { \
using type = Return(Args..., ...) QUAL \
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER; \
}; \
\
template<typename Return, typename... Args> \
struct set_varargs_function_qualifiers_t < \
flag_map<int QUAL>::value, true, true, Return, Args...> { \
using type = Return(Args..., ...) QUAL \
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER \
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER; \
} \
/**/
namespace boost { namespace callable_traits { namespace detail {
template<qualifier_flags Applied, bool IsTransactionSafe,
bool IsNoexcept, typename Return, typename... Args>
struct set_function_qualifiers_t {
using type = Return(Args...);
};
template<qualifier_flags Applied, bool IsTransactionSafe,
bool IsNoexcept, typename Return, typename... Args>
struct set_varargs_function_qualifiers_t {
using type = Return(Args..., ...);
};
#ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(volatile);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const volatile);
#ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(&);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(&&);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const &);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const &&);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(volatile &);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(volatile &&);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const volatile &);
BOOST_CLBL_TRTS_SET_FUNCTION_QUALIFIERS(const volatile &&);
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
template<qualifier_flags Flags, bool IsTransactionSafe, bool IsNoexcept,
typename... Ts>
using set_function_qualifiers =
typename set_function_qualifiers_t<Flags, IsTransactionSafe, IsNoexcept,
Ts...>::type;
template<qualifier_flags Flags, bool IsTransactionSafe, bool IsNoexcept,
typename... Ts>
using set_varargs_function_qualifiers =
typename set_varargs_function_qualifiers_t<Flags, IsTransactionSafe,
IsNoexcept, Ts...>::type;
}}} // namespace boost::callable_traits::detail
#endif //BOOST_CLBL_TRTS_DETAIL_SET_FUNCTION_QUALIFIERS_HPP

View file

@ -0,0 +1,89 @@
/*
@Copyright Barrett Adair 2016-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_SFINAE_ERRORS_HPP
#define BOOST_CLBL_TRTS_SFINAE_ERRORS_HPP
#include <boost/callable_traits/detail/config.hpp>
namespace boost { namespace callable_traits { namespace detail {
struct sfinae_error{};
template<typename T>
struct success {
static constexpr bool value = true;
struct _ { using type = T; };
};
template<bool B, typename T>
struct fail_if : T {
static_assert(std::is_base_of<sfinae_error, T>::value,
"incorrect usage of fail_if");
static constexpr bool value = B;
};
template<typename T, typename... FailIfs>
using sfinae_try = typename BOOST_CLBL_TRTS_DISJUNCTION(
FailIfs..., success<T>)::_::type;
template<typename FailMsg, typename ForceTwoPhaseLookup>
struct fail {
using type = typename std::conditional<std::is_same<ForceTwoPhaseLookup, std::false_type>::value,
FailMsg, FailMsg>::type::_::type;
};
}}} // namespace boost::callable_traits::detail
#define BOOST_CLBL_TRTS_PP_CAT_(x, y) x ## y
#define BOOST_CLBL_TRTS_PP_CAT(x, y) BOOST_CLBL_TRTS_PP_CAT_(x, y)
#define BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(origin) \
namespace error { \
template<typename ErrorMessage> \
struct origin : \
::boost::callable_traits::detail::sfinae_error \
{ struct _ {}; }; \
} \
/**/
#define BOOST_CLBL_TRTS_SFINAE_MSG(origin, name) \
struct BOOST_CLBL_TRTS_PP_CAT(name, _ ){}; \
struct name : error::origin< \
BOOST_CLBL_TRTS_PP_CAT(name, _ )>{}; \
/**/
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(parameters)
BOOST_CLBL_TRTS_SFINAE_MSG(parameters, index_out_of_range_for_parameter_list)
BOOST_CLBL_TRTS_SFINAE_MSG(parameters, cannot_determine_parameters_for_this_type)
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(varargs)
BOOST_CLBL_TRTS_SFINAE_MSG(varargs, varargs_are_illegal_for_this_type)
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(member_qualifiers)
BOOST_CLBL_TRTS_SFINAE_MSG(member_qualifiers, member_qualifiers_are_illegal_for_this_type)
BOOST_CLBL_TRTS_SFINAE_MSG(member_qualifiers, this_compiler_doesnt_support_abominable_function_types)
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(transaction_safe_)
BOOST_CLBL_TRTS_SFINAE_MSG(transaction_safe_, transaction_safe_is_not_supported_by_this_configuration)
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(expand_args)
BOOST_CLBL_TRTS_SFINAE_MSG(expand_args, cannot_expand_the_parameter_list_of_first_template_argument)
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(member_pointer_required)
BOOST_CLBL_TRTS_SFINAE_MSG(member_pointer_required, type_is_not_a_member_pointer)
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(reference_error)
BOOST_CLBL_TRTS_SFINAE_MSG(reference_error, reference_type_not_supported_by_this_metafunction)
}} // namespace boost::callable_traits
#endif // #ifndef BOOST_CLBL_TRTS_SFINAE_ERRORS_HPP

View file

@ -0,0 +1,29 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_TRAITS_HPP
#define BOOST_CLBL_TRTS_DETAIL_TRAITS_HPP
#include <boost/callable_traits/detail/forward_declarations.hpp>
#include <boost/callable_traits/detail/utility.hpp>
namespace boost { namespace callable_traits { namespace detail {
// Here is where the magic happens
template<typename T>
using traits = typename BOOST_CLBL_TRTS_DISJUNCTION(
function_object<unwrap_reference<T>>,
function<T>,
pmf<T>,
pmd<T>,
default_callable_traits<T>
)::traits;
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_TRAITS_HPP

View file

@ -0,0 +1,23 @@
/*
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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
#include <boost/callable_traits/detail/unguarded/function_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
#include <boost/callable_traits/detail/unguarded/function_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE

View file

@ -0,0 +1,23 @@
/*
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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
#include <boost/callable_traits/detail/unguarded/function_3.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
#include <boost/callable_traits/detail/unguarded/function_3.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES

View file

@ -0,0 +1,260 @@
/*
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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
macros used:
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS - the function-level qualifiers for the
current inclusion (combinations of `const` `volatile` `&` `&&`, or nothing)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
the current include (`transaction_safe` or nothing)
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is enabled, otherwise nothing
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
the current include (`noexcept` or nothing)
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
*/
template<typename Return, typename... Args>
struct function<Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
: default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS> {
static constexpr bool value = true;
using traits = function;
using return_type = Return;
using arg_types = std::tuple<Args...>;
using non_invoke_arg_types = arg_types;
using type = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using function_type = Return(Args...);
using qualified_function_type = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using remove_varargs = type;
using add_varargs = Return (Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
using remove_noexcept = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_noexcept = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
using remove_transaction_safe = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_transaction_safe = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using qualifiers = default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>;
template<qualifier_flags Flags>
using set_qualifiers = set_function_qualifiers<Flags, is_transaction_safe::value,
is_noexcept::value, Return, Args...>;
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
using add_member_lvalue_reference = abominable_functions_not_supported_on_this_compiler;
using add_member_rvalue_reference = abominable_functions_not_supported_on_this_compiler;
using add_member_const = abominable_functions_not_supported_on_this_compiler;
using add_member_volatile = abominable_functions_not_supported_on_this_compiler;
using add_member_cv = abominable_functions_not_supported_on_this_compiler;
#else
using add_member_lvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, lref_>::value>;
using add_member_rvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, rref_>::value>;
using add_member_const = set_qualifiers<qualifiers::q_flags | const_>;
using add_member_volatile = set_qualifiers<qualifiers::q_flags | volatile_>;
using add_member_cv = set_qualifiers<qualifiers::q_flags | cv_>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
using remove_member_reference = set_qualifiers<qualifiers::cv_flags>;
using remove_member_const = set_qualifiers<
qualifiers::ref_flags | remove_const_flag<qualifiers::cv_flags>::value>;
using remove_member_volatile = set_qualifiers<
qualifiers::ref_flags | remove_volatile_flag<qualifiers::cv_flags>::value>;
using remove_member_cv = set_qualifiers<qualifiers::ref_flags>;
template<typename U>
using apply_member_pointer = add_member_pointer<type, U>;
template<typename NewReturn>
using apply_return = NewReturn(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<template<class...> class Container>
using expand_args = Container<Args...>;
using is_member_pointer = std::false_type;
};
template<typename Return, typename... Args>
struct function<Return (Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
: default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS> {
static constexpr bool value = true;
using has_varargs = std::true_type;
using traits = function;
using return_type = Return;
using arg_types = std::tuple<Args...>;
using type = Return (Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using function_type = Return(Args..., ...);
using qualified_function_type = Return(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using remove_varargs = Return (Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_varargs = type;
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
using remove_noexcept = Return(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_noexcept = Return(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
using remove_transaction_safe = Return(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_transaction_safe = Return(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using qualifiers = default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>;
template<qualifier_flags Flags>
using set_qualifiers = set_varargs_function_qualifiers<Flags, is_transaction_safe::value,
is_noexcept::value, Return, Args...>;
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
using add_member_lvalue_reference = abominable_functions_not_supported_on_this_compiler;
using add_member_rvalue_reference = abominable_functions_not_supported_on_this_compiler;
using add_member_const = abominable_functions_not_supported_on_this_compiler;
using add_member_volatile = abominable_functions_not_supported_on_this_compiler;
using add_member_cv = abominable_functions_not_supported_on_this_compiler;
#else
using add_member_lvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, lref_>::value>;
using add_member_rvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, rref_>::value>;
using add_member_const = set_qualifiers<qualifiers::q_flags | const_>;
using add_member_volatile = set_qualifiers<qualifiers::q_flags | volatile_>;
using add_member_cv = set_qualifiers<qualifiers::q_flags | cv_>;
#endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
using remove_member_reference = set_qualifiers<qualifiers::cv_flags>;
using remove_member_const = set_qualifiers<
qualifiers::ref_flags | remove_const_flag<qualifiers::cv_flags>::value>;
using remove_member_volatile = set_qualifiers<
qualifiers::ref_flags | remove_volatile_flag<qualifiers::cv_flags>::value>;
using remove_member_cv = set_qualifiers<qualifiers::ref_flags>;
template<typename U>
using apply_member_pointer =
Return( BOOST_CLBL_TRTS_DEFAULT_VARARGS_CC U::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename NewReturn>
using apply_return = NewReturn(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<template<class...> class Container>
using expand_args = Container<Args...>;
using is_member_pointer = std::false_type;
};

View file

@ -0,0 +1,25 @@
/*
Copyright (c) 2016 Modified Work 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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
#include <boost/callable_traits/detail/unguarded/function_ptr_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
#include <boost/callable_traits/detail/unguarded/function_ptr_2.hpp>
#endif
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE

View file

@ -0,0 +1,23 @@
/*
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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
#include <boost/callable_traits/detail/unguarded/function_ptr_3.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
#include <boost/callable_traits/detail/unguarded/function_ptr_3.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES

View file

@ -0,0 +1,94 @@
/*
Copyright (c) 2016 Modified Work 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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
macros used:
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
the current include (`transaction_safe` or nothing)
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is enabled, otherwise nothing
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
the current include (`noexcept` or nothing)
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
*/
template<typename Return, typename... Args>
struct function<
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
: default_callable_traits<> {
static constexpr bool value = true;
using traits = function;
using return_type = Return;
using arg_types = std::tuple<Args...>;
using non_invoke_arg_types = arg_types;
using type = BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using function_type = Return(Args...);
using qualified_function_type = function_type;
using remove_varargs = type;
using add_varargs =
BOOST_CLBL_TRTS_ST Return (BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
using remove_noexcept = Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_noexcept = Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
using remove_transaction_safe = Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_transaction_safe = Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename U>
using apply_member_pointer =
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC U::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename NewReturn>
using apply_return =
BOOST_CLBL_TRTS_ST NewReturn(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<template<class...> class Container>
using expand_args = Container<Args...>;
using is_member_pointer = std::false_type;
};

View file

@ -0,0 +1,23 @@
/*
Copyright (c) 2016 Modified Work 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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE

View file

@ -0,0 +1,23 @@
/*
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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs_3.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
#include <boost/callable_traits/detail/unguarded/function_ptr_varargs_3.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES

View file

@ -0,0 +1,98 @@
/*
Copyright (c) 2016 Modified Work 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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
macros used:
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
the current include (`transaction_safe` or nothing)
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is enabled, otherwise nothing
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
the current include (`noexcept` or nothing)
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
*/
template<typename Return, typename... Args>
struct function<BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
: default_callable_traits<> {
static constexpr bool value = true;
using has_varargs = std::true_type;
using traits = function;
using return_type = Return;
using arg_types = std::tuple<Args...>;
using non_invoke_arg_types = arg_types;
using type =
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using function_type = Return(Args..., ...);
using qualified_function_type = function_type;
using remove_varargs =
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_varargs = type;
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
using remove_noexcept = BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_noexcept = BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
using remove_transaction_safe = Return(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_transaction_safe = Return(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename U>
using apply_member_pointer =
BOOST_CLBL_TRTS_ST Return(BOOST_CLBL_TRTS_VARARGS_CC U::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename NewReturn>
using apply_return =
BOOST_CLBL_TRTS_ST NewReturn(BOOST_CLBL_TRTS_VARARGS_CC *)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<template<class...> class Container>
using expand_args = Container<Args...>;
using is_member_pointer = std::false_type;
};

View file

@ -0,0 +1,94 @@
/*
Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
Copyright (c) 2016 Modified Work 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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
BOOST_CLBL_TRTS_ABOMINABLE_CONST
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
BOOST_CLBL_TRTS_ABOMINABLE_CONST BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS &
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS &&
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const &
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS volatile &
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const volatile &
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const &&
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS volatile &&
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const volatile &&
#include <boost/callable_traits/detail/unguarded/pmf_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS

View file

@ -0,0 +1,74 @@
/*
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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
template<typename Return, typename T, typename... Args>
struct set_member_function_qualifiers_t<
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
false, // IsTransactionSafe
false, // IsNoexcept
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS;
};
template<typename Return, typename T, typename... Args>
struct set_member_function_qualifiers_t<
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
false,
true,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
};
template<typename Return, typename T, typename... Args>
struct set_member_function_qualifiers_t<
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
true,
false,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER;
};
template<typename Return, typename T, typename... Args>
struct set_member_function_qualifiers_t<
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
true,
true,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
};
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
#include <boost/callable_traits/detail/unguarded/pmf_3.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
#include <boost/callable_traits/detail/unguarded/pmf_3.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#endif

View file

@ -0,0 +1,23 @@
/*
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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
#include <boost/callable_traits/detail/unguarded/pmf_4.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
#include <boost/callable_traits/detail/unguarded/pmf_4.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES

View file

@ -0,0 +1,147 @@
/*
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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS - the function-level qualifiers for the
current inclusion (combinations of `const` `volatile` `&` `&&`, or nothing)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
the current include (`transaction_safe` or nothing)
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is defined, otherwise nothing
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
the current include (`noexcept` or nothing)
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
*/
template<typename Return, typename T, typename... Args>
struct pmf<Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
: default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS> {
static constexpr bool value = true;
using traits = pmf;
using return_type = Return;
using type = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using invoke_type = typename std::conditional<
std::is_rvalue_reference<T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS,
typename std::add_lvalue_reference<T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::type
>::type;
using arg_types = std::tuple<invoke_type, Args...>;
using non_invoke_arg_types = std::tuple<Args...>;
using function_object_signature = Return(Args...);
using function_type = Return(invoke_type, Args...);
using qualified_function_type = Return(Args...)
BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using remove_varargs = type;
using add_varargs =
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
using remove_noexcept = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_noexcept = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
using remove_transaction_safe = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_transaction_safe = Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using class_type = T;
using qualifiers = default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>;
template<qualifier_flags Flags>
using set_qualifiers = set_member_function_qualifiers<
Flags, is_transaction_safe::value, is_noexcept::value,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...>;
using remove_member_reference = set_qualifiers<qualifiers::cv_flags>;
using add_member_lvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, lref_>::value>;
using add_member_rvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, rref_>::value>;
using add_member_const = set_qualifiers<qualifiers::q_flags | const_>;
using add_member_volatile = set_qualifiers<qualifiers::q_flags | volatile_>;
using add_member_cv = set_qualifiers<qualifiers::q_flags | cv_>;
using remove_member_const = set_qualifiers<
qualifiers::ref_flags | remove_const_flag<qualifiers::cv_flags>::value>;
using remove_member_volatile = set_qualifiers<
qualifiers::ref_flags | remove_volatile_flag<qualifiers::cv_flags>::value>;
using remove_member_cv = set_qualifiers<qualifiers::ref_flags>;
template<typename U>
using apply_member_pointer =
Return(BOOST_CLBL_TRTS_CC U::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename NewReturn>
using apply_return =
NewReturn(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<template<class...> class Container>
using expand_args = Container<invoke_type, Args...>;
using is_member_pointer = std::true_type;
};

View file

@ -0,0 +1,89 @@
/*
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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
BOOST_CLBL_TRTS_ABOMINABLE_CONST
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS \
BOOST_CLBL_TRTS_ABOMINABLE_CONST BOOST_CLBL_TRTS_ABOMINABLE_VOLATILE
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS &
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS &&
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const &
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS volatile &
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const volatile &
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const &&
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS volatile &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS volatile &&
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#define BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS const volatile &&
#define BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS const volatile &&
#include <boost/callable_traits/detail/unguarded/pmf_varargs_2.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
#undef BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
#endif // #ifndef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS

View file

@ -0,0 +1,78 @@
/*
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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
template<typename T, typename Return, typename... Args>
struct set_varargs_member_function_qualifiers_t <
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
false, // IsTransactionSafe
false, // IsNoexcept
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type =
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS;
};
template<typename T, typename Return, typename... Args>
struct set_varargs_member_function_qualifiers_t <
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
false,
true,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type =
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
};
template<typename T, typename Return, typename... Args>
struct set_varargs_member_function_qualifiers_t <
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
true,
false,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type =
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER;
};
template<typename T, typename Return, typename... Args>
struct set_varargs_member_function_qualifiers_t <
flag_map<int BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
true,
true,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...> {
using type =
Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
};
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::false_type
#include <boost/callable_traits/detail/unguarded/pmf_varargs_3.hpp>
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE
#ifdef BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE std::true_type
#define BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE transaction_safe
#include <boost/callable_traits/detail/unguarded/pmf_varargs_3.hpp>
#endif
#undef BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
#undef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE

View file

@ -0,0 +1,23 @@
/*
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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
*/
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::false_type
#include <boost/callable_traits/detail/unguarded/pmf_varargs_4.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES
#define BOOST_CLBL_TRTS_NOEXCEPT_SPEC noexcept
#define BOOST_CLBL_TRTS_IS_NOEXCEPT std::true_type
#include <boost/callable_traits/detail/unguarded/pmf_varargs_4.hpp>
#undef BOOST_CLBL_TRTS_NOEXCEPT_SPEC
#undef BOOST_CLBL_TRTS_IS_NOEXCEPT
#endif // #ifdef BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES

View file

@ -0,0 +1,149 @@
/*
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)
HEADER GUARDS INTENTIONALLY OMITTED
DO NOT INCLUDE THIS HEADER DIRECTLY
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS - the function-level qualifiers for the
current inclusion (combinations of `const` `volatile` `&` `&&`, or nothing)
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE - the transaction_safe specifier for
the current include (`transaction_safe` or nothing)
BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE is `transaction_safe`
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER - `transaction_safe` when
BOOST_CLBL_TRTS_ENABLE_TRANSACTION_SAFE is enabled, otherwise nothing
BOOST_CLBL_TRTS_NOEXCEPT_SPEC - the noexcept specifier for
the current include (`noexcept` or nothing)
BOOST_CLBL_TRTS_IS_NOEXCEPT - `std::true_type` or `std::false_type`,
tied on whether BOOST_CLBL_TRTS_NOEXCEPT_SPEC is `noexcept`
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER - `noexcept` if
BOOST_CLBL_TRTS_ENABLE_NOEXCEPT_TYPES is defined, otherwise nothing
*/
template<typename Return, typename T, typename... Args>
struct pmf<Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC>
: default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS> {
static constexpr bool value = true;
using has_varargs = std::true_type;
using traits = pmf;
using return_type = Return;
using type = Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using invoke_type = typename std::conditional<
std::is_rvalue_reference<T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::value,
T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS,
typename std::add_lvalue_reference<T BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>::type
>::type;
using arg_types = std::tuple<invoke_type, Args...>;
using non_invoke_arg_types = std::tuple<Args...>;
using function_object_signature = Return(Args..., ...);
using function_type = Return(invoke_type, Args..., ...);
using qualified_function_type = Return(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_ABOMINABLE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using remove_varargs =
Return(BOOST_CLBL_TRTS_CC T::*)(Args...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_varargs = type;
using is_noexcept = BOOST_CLBL_TRTS_IS_NOEXCEPT;
using remove_noexcept = Return(BOOST_CLBL_TRTS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE;
using add_noexcept = Return(BOOST_CLBL_TRTS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPECIFIER;
using is_transaction_safe = BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE;
using remove_transaction_safe = Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using add_transaction_safe = Return(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
using class_type = T;
using qualifiers = default_callable_traits<dummy BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS>;
template<qualifier_flags Flags>
using set_qualifiers = set_varargs_member_function_qualifiers<
Flags, is_transaction_safe::value, is_noexcept::value,
BOOST_CLBL_TRTS_CC_TAG, T, Return, Args...>;
using remove_member_reference = set_qualifiers<qualifiers::cv_flags>;
using add_member_lvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, lref_>::value>;
using add_member_rvalue_reference = set_qualifiers<
collapse_flags<qualifiers::q_flags, rref_>::value>;
using add_member_const = set_qualifiers<qualifiers::q_flags | const_>;
using add_member_volatile = set_qualifiers<qualifiers::q_flags | volatile_>;
using add_member_cv = set_qualifiers<qualifiers::q_flags | cv_>;
using remove_member_const = set_qualifiers<
qualifiers::ref_flags | remove_const_flag<qualifiers::cv_flags>::value>;
using remove_member_volatile = set_qualifiers<
qualifiers::ref_flags | remove_volatile_flag<qualifiers::cv_flags>::value>;
using remove_member_cv = set_qualifiers<qualifiers::ref_flags>;
template<typename U>
using apply_member_pointer =
Return(BOOST_CLBL_TRTS_VARARGS_CC U::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<typename NewReturn>
using apply_return =
NewReturn(BOOST_CLBL_TRTS_VARARGS_CC T::*)(Args..., ...)
BOOST_CLBL_TRTS_INCLUDE_QUALIFIERS
BOOST_CLBL_TRTS_INCLUDE_TRANSACTION_SAFE
BOOST_CLBL_TRTS_NOEXCEPT_SPEC;
template<template<class...> class Container>
using expand_args = Container<invoke_type, Args...>;
using is_member_pointer = std::true_type;
};

View file

@ -0,0 +1,111 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP
#define BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP
#include <boost/callable_traits/detail/config.hpp>
#include <boost/callable_traits/detail/sfinae_errors.hpp>
#include <boost/callable_traits/detail/qualifier_flags.hpp>
namespace boost { namespace callable_traits { namespace detail {
struct cdecl_tag{};
struct stdcall_tag{};
struct fastcall_tag{};
struct pascal_tag{};
struct invalid_type { invalid_type() = delete; };
struct reference_error { reference_error() = delete; };
template<typename T>
using error_type = typename std::conditional<
std::is_reference<T>::value, reference_error, invalid_type>::type;
#ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
struct abominable_functions_not_supported_on_this_compiler{};
#endif
// used to convey "this type doesn't matter" in code
struct dummy {};
// used as return type in failed SFINAE tests
struct substitution_failure : std::false_type{};
template<bool Value>
using bool_type = std::integral_constant<bool, Value>;
// shorthand for std::tuple_element
template<std::size_t I, typename Tup>
using at = typename std::tuple_element<I, Tup>::type;
template<typename T, typename Class>
using add_member_pointer = T Class::*;
template<typename L, typename R, typename ErrorType>
using fail_when_same = fail_if<std::is_same<L, R>::value, ErrorType>;
template<typename T, typename ErrorType,
typename U = typename std::remove_reference<T>::type>
using try_but_fail_if_invalid = sfinae_try<T,
fail_when_same<U, invalid_type, ErrorType>,
fail_when_same<U, reference_error,
reference_type_not_supported_by_this_metafunction>>;
template<typename T, typename ErrorType,
typename U = typename std::remove_reference<T>::type,
bool is_reference_error = std::is_same<reference_error, U>::value>
using fail_if_invalid = fail_if<
std::is_same<U, invalid_type>::value || is_reference_error,
typename std::conditional<is_reference_error,
reference_type_not_supported_by_this_metafunction, ErrorType>::type>;
template<typename T, typename Fallback>
using fallback_if_invalid = typename std::conditional<
std::is_same<T, invalid_type>::value, Fallback, T>::type;
template<typename T, template<class> class Alias, typename U = Alias<T>>
struct force_sfinae {
using type = U;
};
template<typename T>
using shallow_decay = typename std::remove_cv<
typename std::remove_reference<T>::type>::type;
template<typename T>
struct is_reference_wrapper_t {
using type = std::false_type;
};
template<typename T>
struct is_reference_wrapper_t<std::reference_wrapper<T>> {
using type = std::true_type;
};
template<typename T>
using is_reference_wrapper =
typename is_reference_wrapper_t<shallow_decay<T>>::type;
template<typename T, typename = std::true_type>
struct unwrap_reference_t {
using type = T;
};
template<typename T>
struct unwrap_reference_t<T, is_reference_wrapper<T>> {
using type = decltype(std::declval<T>().get());
};
// removes std::reference_wrapper
template<typename T>
using unwrap_reference = typename unwrap_reference_t<T>::type;
}}} // namespace boost::callable_traits::detail
#endif // #ifndef BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP

View file

@ -0,0 +1,97 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_FUNCTION_TYPE_HPP
#define BOOST_CLBL_TRTS_FUNCTION_TYPE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ function_type_hpp
/*`[section:ref_function_type function_type]
[heading Header]
``#include <boost/callable_traits/function_type.hpp>``
[heading Definition]
*/
template<typename T>
using function_type_t = //see below
//<-
detail::try_but_fail_if_invalid<typename detail::traits<
detail::shallow_decay<T>>::function_type,
cannot_determine_parameters_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct function_type_impl {};
template<typename T>
struct function_type_impl <T, typename std::is_same<
function_type_t<T>, detail::dummy>::type>
{
using type = function_type_t<T>;
};
}
//->
template<typename T>
struct function_type : detail::function_type_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading 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.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/function_type.cpp]
[function_type]
[endsect]
*/
//]
#endif

View file

@ -0,0 +1,99 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_HAS_MEMBER_QUALIFIERS_HPP
#define BOOST_CLBL_TRTS_HAS_MEMBER_QUALIFIERS_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ has_member_qualifiers_hpp
/*`[section:ref_has_member_qualifiers has_member_qualifiers]
[heading Header]
``#include <boost/callable_traits/has_member_qualifiers.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct has_member_qualifiers;
//<-
template<typename T>
struct has_member_qualifiers : detail::traits<
detail::shallow_decay<T>>::has_member_qualifiers {
using type = typename detail::traits<
detail::shallow_decay<T>>::has_member_qualifiers;
};
// older compilers don't support variable templates
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct has_member_qualifiers_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool has_member_qualifiers_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::has_member_qualifiers::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading 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`.
[heading Input/Output Examples]
[table
[[`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`]]
]
[heading Example Program]
[import ../example/has_member_qualifiers.cpp]
[has_member_qualifiers]
[endsect]
*/
//]
#endif //BOOST_CLBL_TRTS_HAS_MEMBER_QUALIFIERS_HPP

View file

@ -0,0 +1,94 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_HAS_VARARGS_HPP
#define BOOST_CLBL_TRTS_HAS_VARARGS_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ has_varargs_hpp
/*`[section:ref_has_varargs has_varargs]
[heading Header]
``#include <boost/callable_traits/has_varargs.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct has_varargs;
//<-
template<typename T>
struct has_varargs : detail::traits<
detail::shallow_decay<T>>::has_varargs {
using type = typename detail::traits<
detail::shallow_decay<T>>::has_varargs;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct has_varargs_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool has_varargs_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::has_varargs::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading 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`.
[heading Input/Output Examples]
[table
[[`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`]]
]
[heading Example Program]
[import ../example/has_varargs.cpp]
[has_varargs]
[endsect]
*/
//]
#endif

View file

@ -0,0 +1,93 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_HAS_VOID_RETURN_HPP
#define BOOST_CLBL_TRTS_HAS_VOID_RETURN_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ has_void_return_hpp
/*`[section:ref_has_void_return has_void_return]
[heading Header]
``#include <boost/callable_traits/has_void_return.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct has_void_return;
//<-
template<typename T>
struct has_void_return
: std::is_same<typename detail::traits<
detail::shallow_decay<T>>::return_type, void> {};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct has_void_return_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool has_void_return_v = //see below
//<-
std::is_same<typename detail::traits<
detail::shallow_decay<T>>::return_type, void>::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading 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`.
[heading Input/Output Examples]
[table
[[`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`]]
]
[heading Example Program]
[import ../example/has_void_return.cpp]
[has_void_return]
[endsect]
*/
//]
#endif

View file

@ -0,0 +1,97 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_CONST_MEMBER_HPP
#define BOOST_CLBL_TRTS_IS_CONST_MEMBER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_const_member_hpp
/*`[section:ref_is_const_member is_const_member]
[heading Header]
``#include <boost/callable_traits/is_const_member.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_const_member;
//<-
template<typename T>
struct is_const_member
: detail::traits<detail::shallow_decay<T>>::is_const_member {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_const_member;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_const_member_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_const_member_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_const_member::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading 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`.
[heading Input/Output Examples]
[table
[[`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`]]
]
[heading Example Program]
[import ../example/is_const_member.cpp]
[is_const_member]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_CONST_MEMBER_HPP

View file

@ -0,0 +1,95 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_CV_MEMBER_HPP
#define BOOST_CLBL_TRTS_IS_CV_MEMBER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_cv_member_hpp
/*`[section:ref_is_cv_member is_cv_member]
[heading Header]
``#include <boost/callable_traits/is_cv_member.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_cv_member;
//<-
template<typename T>
struct is_cv_member
: detail::traits<detail::shallow_decay<T>>::is_cv_member {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_cv_member;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_cv_member_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_cv_member_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_cv_member::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading 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`.
[heading Input/Output Examples]
[table
[[`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`]]
]
[heading Example Program]
[import ../example/is_cv_member.cpp]
[is_cv_member]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_CV_MEMBER_HPP

View file

@ -0,0 +1,103 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_INVOCABLE_HPP
#define BOOST_CLBL_TRTS_IS_INVOCABLE_HPP
#include <boost/callable_traits/detail/core.hpp>
#include <boost/callable_traits/detail/is_invocable_impl.hpp>
namespace boost { namespace callable_traits {
//[ is_invocable_hpp
/*`[section:ref_is_invocable is_invocable]
[heading Header]
``#include <boost/callable_traits/is_invocable.hpp>``
[heading 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;
//<-
template<typename T, typename... Args>
struct is_invocable : detail::is_invocable_impl<T, Args...>::type {
using type = typename detail::is_invocable_impl<T, Args...>::type;
};
template<typename Ret, typename T, typename... Args>
struct is_invocable_r
: detail::is_invocable_r_impl<
typename detail::is_invocable_impl<T, Args...>::type, Ret, T, Args...>::type
{
using type = typename detail::is_invocable_r_impl<
typename detail::is_invocable_impl<T, Args...>::type, Ret, T, Args...>::type;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T, typename... Args>
struct is_invocable_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
template<typename Ret, typename T, typename... Args>
struct is_invocable_r_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T, typename... Args>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_invocable_v = //see below
//<-
detail::is_invocable_impl<detail::traits<T>, Args...>::type::value;
//->
// only available when variable templates are supported
template<typename Ret, typename T, typename... Args>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_invocable_r_v = //see below
//<-
detail::is_invocable_r_impl<
typename detail::is_invocable_impl<T, Args...>::type,
Ret, T, Args...>::type::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading 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.]
[heading Example Program]
[import ../example/is_invocable.cpp]
[is_invocable]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_INVOCABLE_HPP

View file

@ -0,0 +1,95 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_LVALUE_REFERENCE_MEMBER_HPP
#define BOOST_CLBL_TRTS_IS_LVALUE_REFERENCE_MEMBER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_lvalue_reference_member_hpp
/*`[section:ref_is_lvalue_reference_member is_lvalue_reference_member]
[heading Header]
``#include <boost/callable_traits/is_lvalue_reference_member.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_lvalue_reference_member;
//<-
template<typename T>
struct is_lvalue_reference_member
: detail::traits<detail::shallow_decay<T>>::is_lvalue_reference_member {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_lvalue_reference_member;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_lvalue_reference_member_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_lvalue_reference_member_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_lvalue_reference_member::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading 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`.
[heading Input/Output Examples]
[table
[[`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`]]
]
[heading Example Program]
[import ../example/is_lvalue_reference_member.cpp]
[is_lvalue_reference_member]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_LVALUE_REFERENCE_MEMBER_HPP

View file

@ -0,0 +1,95 @@
/*
@file is_noexcept
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_NOEXCEPT_HPP
#define BOOST_CLBL_TRTS_IS_NOEXCEPT_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_noexcept_hpp
/*`[section:ref_is_noexcept is_noexcept]
[heading Header]
``#include <boost/callable_traits/is_noexcept.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_noexcept;
//<-
template<typename T>
struct is_noexcept : detail::traits<detail::shallow_decay<T>>::is_noexcept {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_noexcept;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_noexcept_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_noexcept_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_noexcept::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
*
[heading 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`.
[heading Input/Output Examples]
[table
[[`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`]]
]
[heading Example Program]
[import ../example/is_noexcept.cpp]
[is_noexcept]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_NOEXCEPT_HPP

View file

@ -0,0 +1,98 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_REFERENCE_MEMBER_HPP
#define BOOST_CLBL_TRTS_IS_REFERENCE_MEMBER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_reference_member_hpp
/*`[section:ref_is_reference_member is_reference_member]
[heading Header]
``#include <boost/callable_traits/is_reference_member.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_reference_member;
//<-
template<typename T>
struct is_reference_member : detail::traits<
detail::shallow_decay<T>>::is_reference_member {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_reference_member;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_reference_member_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_reference_member_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_reference_member::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading 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`.
[heading Input/Output Examples]
[table
[[`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`]]
]
[heading Example Program]
[import ../example/is_reference_member.cpp]
[is_reference_member]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_REFERENCE_MEMBER_HPP

View file

@ -0,0 +1,97 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_RVALUE_REFERENCE_MEMBER_HPP
#define BOOST_CLBL_TRTS_IS_RVALUE_REFERENCE_MEMBER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_rvalue_reference_member_hpp
/*`[section:ref_is_rvalue_reference_member is_rvalue_reference_member]
[heading Header]
``#include <boost/callable_traits/is_rvalue_reference_member.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_rvalue_reference_member;
//<-
template<typename T>
struct is_rvalue_reference_member : detail::traits<
detail::shallow_decay<T>>::is_rvalue_reference_member {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_rvalue_reference_member;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_rvalue_reference_member_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_rvalue_reference_member_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_rvalue_reference_member::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading 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`.
[heading Input/Output Examples]
[table
[[`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`]]
]
[heading Example Program]
[import ../example/is_rvalue_reference_member.cpp]
[is_rvalue_reference_member]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_RVALUE_REFERENCE_MEMBER_HPP

View file

@ -0,0 +1,98 @@
/*
@file is_transaction_safe
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE_HPP
#define BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_transaction_safe_hpp
/*`[section:ref_is_transaction_safe is_transaction_safe]
[heading Header]
``#include <boost/callable_traits/is_transaction_safe.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_transaction_safe;
//<-
template<typename T>
struct is_transaction_safe : detail::traits<
detail::shallow_decay<T>>::is_transaction_safe {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_transaction_safe;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_transaction_safe_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_transaction_safe_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_transaction_safe::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
*
[heading 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`.
[heading Input/Output Examples]
[table
[[`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`]]
]
[heading Example Program]
[import ../example/is_transaction_safe.cpp]
[is_transaction_safe]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_TRANSACTION_SAFE_HPP

View file

@ -0,0 +1,100 @@
/*
*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_IS_VOLATILE_MEMBER_HPP
#define BOOST_CLBL_TRTS_IS_VOLATILE_MEMBER_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ is_volatile_member_hpp
/*`[section:ref_is_volatile_member is_volatile_member]
[heading Header]
``#include <boost/callable_traits/is_volatile_member.hpp>``
[heading Definition]
*/
// inherits from either std::true_type or std::false_type
template<typename T>
struct is_volatile_member;
//<-
template<typename T>
struct is_volatile_member : detail::traits<
detail::shallow_decay<T>>::is_volatile_member {
using type = typename detail::traits<
detail::shallow_decay<T>>::is_volatile_member;
};
#ifdef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
template<typename T>
struct is_volatile_member_v {
static_assert(std::is_same<T, detail::dummy>::value,
"Variable templates not supported on this compiler.");
};
#else
//->
// only available when variable templates are supported
template<typename T>
//<-
BOOST_CLBL_TRAITS_INLINE_VAR
//->
constexpr bool is_volatile_member_v = //see below
//<-
detail::traits<detail::shallow_decay<T>>::is_volatile_member::value;
#endif
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* none
[heading 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`.
[heading Input/Output Examples]
[table
[[`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`]]
]
[heading Example Program]
[import ../example/is_volatile_member.cpp]
[is_volatile_member]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_IS_VOLATILE_MEMBER_HPP

View file

@ -0,0 +1,81 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_QUALIFIED_class_of_HPP
#define BOOST_CLBL_TRTS_QUALIFIED_class_of_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ qualified_class_of_hpp
/*`
[section:ref_qualified_class_of qualified_class_of]
[heading Header]
``#include <boost/callable_traits/qualified_class_of.hpp>``
[heading Definition]
*/
template<typename T>
using qualified_class_of_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<detail::shallow_decay<T>>::invoke_type,
type_is_not_a_member_pointer>;
namespace detail {
template<typename T, typename = std::false_type>
struct qualified_class_of_impl {};
template<typename T>
struct qualified_class_of_impl <T, typename std::is_same<
qualified_class_of_t<T>, detail::dummy>::type>
{
using type = qualified_class_of_t<T>;
};
}
//->
template<typename T>
struct qualified_class_of : detail::qualified_class_of_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading Constraints]
* `T` must be a member pointer
[heading 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 &`.
[heading Input/Output Examples]
[table
[[`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 &`]]
]
[heading Example Program]
[import ../example/qualified_class_of.cpp]
[qualified_class_of]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_QUALIFIED_class_of_HPP

View file

@ -0,0 +1,85 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_CONST_HPP
#define BOOST_CLBL_TRTS_REMOVE_MEMBER_CONST_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ remove_member_const_hpp
/*`
[section:ref_remove_member_const remove_member_const]
[heading Header]
``#include <boost/callable_traits/remove_member_const.hpp>``
[heading Definition]
*/
template<typename T>
using remove_member_const_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_member_const,
member_qualifiers_are_illegal_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_member_const_impl {};
template<typename T>
struct remove_member_const_impl <T, typename std::is_same<
remove_member_const_t<T>, detail::dummy>::type>
{
using type = remove_member_const_t<T>;
};
}
//->
template<typename T>
struct remove_member_const : detail::remove_member_const_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Removes the member `const` qualifier from `T`, if present.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/remove_member_const.cpp]
[remove_member_const]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_CONST_HPP

View file

@ -0,0 +1,87 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_CV_HPP
#define BOOST_CLBL_TRTS_REMOVE_MEMBER_CV_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ remove_member_cv_hpp
/*`
[section:ref_remove_member_cv remove_member_cv]
[heading Header]
``#include <boost/callable_traits/remove_member_cv.hpp>``
[heading Definition]
*/
template<typename T>
using remove_member_cv_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_member_cv,
member_qualifiers_are_illegal_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_member_cv_impl {};
template<typename T>
struct remove_member_cv_impl <T, typename std::is_same<
remove_member_cv_t<T>, detail::dummy>::type>
{
using type = remove_member_cv_t<T>;
};
}
//->
template<typename T>
struct remove_member_cv : detail::remove_member_cv_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Removes member `const` and/or `volatile` qualifiers from `T`, if present.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/remove_member_cv.cpp]
[remove_member_cv]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_CV_HPP

View file

@ -0,0 +1,85 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_REFERENCE_HPP
#define BOOST_CLBL_TRTS_REMOVE_MEMBER_REFERENCE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ remove_member_reference_hpp
/*`
[section:ref_remove_member_reference remove_member_reference]
[heading Header]
``#include <boost/callable_traits/remove_member_reference.hpp>``
[heading Definition]
*/
template<typename T>
using remove_member_reference_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_member_reference,
member_qualifiers_are_illegal_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_member_reference_impl {};
template<typename T>
struct remove_member_reference_impl <T, typename std::is_same<
remove_member_reference_t<T>, detail::dummy>::type>
{
using type = remove_member_reference_t<T>;
};
}
//->
template<typename T>
struct remove_member_reference
: detail::remove_member_reference_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading Behavior]
* A substitution failure occuers if the constraints are violated.
* Removes member `&` or `&&` qualifiers from `T`, if present.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/remove_member_reference.cpp]
[remove_member_reference]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_REFERENCE_HPP

View file

@ -0,0 +1,85 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_VOLATILE_HPP
#define BOOST_CLBL_TRTS_REMOVE_MEMBER_VOLATILE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ remove_member_volatile_hpp
/*`
[section:ref_remove_member_volatile remove_member_volatile]
[heading Header]
``#include <boost/callable_traits/remove_member_volatile.hpp>``
[heading Definition]
*/
template<typename T>
using remove_member_volatile_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_member_volatile,
member_qualifiers_are_illegal_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_member_volatile_impl {};
template<typename T>
struct remove_member_volatile_impl <T, typename std::is_same<
remove_member_volatile_t<T>, detail::dummy>::type>
{
using type = remove_member_volatile_t<T>;
};
}
//->
template<typename T>
struct remove_member_volatile : detail::remove_member_volatile_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Removes the member `volatile` qualifier from `T`, if present.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/remove_member_volatile.cpp]
[remove_member_volatile]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_VOLATILE_HPP

View file

@ -0,0 +1,93 @@
/*
@file remove_noexcept
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_NOEXCEPT_HPP
#define BOOST_CLBL_TRTS_REMOVE_NOEXCEPT_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(remove_noexcept)
BOOST_CLBL_TRTS_SFINAE_MSG(remove_noexcept, cannot_remove_noexcept_from_this_type)
//[ remove_noexcept_hpp
/*`
[section:ref_remove_noexcept remove_noexcept]
[heading Header]
``#include <boost/callable_traits/remove_noexcept.hpp>``
[heading Definition]
*/
template<typename T>
using remove_noexcept_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_noexcept,
cannot_remove_noexcept_from_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_noexcept_impl {};
template<typename T>
struct remove_noexcept_impl <T, typename std::is_same<
remove_noexcept_t<T>, detail::dummy>::type>
{
using type = remove_noexcept_t<T>;
};
}
//->
template<typename T>
struct remove_noexcept : detail::remove_noexcept_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Removes the `noexcept` specifier from `T`, if present.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/remove_noexcept.cpp]
[remove_noexcept]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_NOEXCEPT_HPP

View file

@ -0,0 +1,93 @@
/*
@file remove_transaction_safe
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_TRANSACTION_SAFE_HPP
#define BOOST_CLBL_TRTS_REMOVE_TRANSACTION_SAFE_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(remove_transaction_safe)
BOOST_CLBL_TRTS_SFINAE_MSG(remove_transaction_safe, cannot_remove_transaction_safe_from_this_type)
//[ remove_transaction_safe_hpp
/*`
[section:ref_remove_transaction_safe remove_transaction_safe]
[heading Header]
``#include <boost/callable_traits/remove_transaction_safe.hpp>``
[heading Definition]
*/
template<typename T>
using remove_transaction_safe_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_transaction_safe,
cannot_remove_transaction_safe_from_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_transaction_safe_impl {};
template<typename T>
struct remove_transaction_safe_impl <T, typename std::is_same<
remove_transaction_safe_t<T>, detail::dummy>::type>
{
using type = remove_transaction_safe_t<T>;
};
}
//->
template<typename T>
struct remove_transaction_safe : detail::remove_transaction_safe_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Removes the member `transaction_safe` specifier from `T`, if present.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/remove_transaction_safe.cpp]
[remove_transaction_safe]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_TRANSACTION_SAFE_HPP

View file

@ -0,0 +1,91 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_REMOVE_VARARGS_HPP
#define BOOST_CLBL_TRTS_REMOVE_VARARGS_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
//[ remove_varargs_hpp
/*`
[section:ref_remove_varargs remove_varargs]
[heading Header]
``#include <boost/callable_traits/remove_varargs.hpp>``
[heading Definition]
*/
template<typename T>
using remove_varargs_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<T>::remove_varargs,
varargs_are_illegal_for_this_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct remove_varargs_impl {};
template<typename T>
struct remove_varargs_impl <T, typename std::is_same<
remove_varargs_t<T>, detail::dummy>::type>
{
using type = remove_varargs_t<T>;
};
}
//->
template<typename T>
struct remove_varargs : detail::remove_varargs_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Removes C-style variadics (`...`) from the signature of `T`, if present.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/remove_varargs.cpp]
[remove_varargs]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_VARARGS_HPP

View file

@ -0,0 +1,90 @@
/*
@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CLBL_TRTS_RESULT_OF_HPP
#define BOOST_CLBL_TRTS_RESULT_OF_HPP
#include <boost/callable_traits/detail/core.hpp>
namespace boost { namespace callable_traits {
BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(return_type)
BOOST_CLBL_TRTS_SFINAE_MSG(return_type, unable_to_determine_return_type)
//[ return_type_hpp
/*`
[section:ref_return_type return_type]
[heading Header]
``#include <boost/callable_traits/return_type.hpp>``
[heading Definition]
*/
template<typename T>
using return_type_t = //see below
//<-
detail::try_but_fail_if_invalid<
typename detail::traits<detail::shallow_decay<T>>::return_type,
unable_to_determine_return_type>;
namespace detail {
template<typename T, typename = std::false_type>
struct return_type_impl {};
template<typename T>
struct return_type_impl <T, typename std::is_same<
return_type_t<T>, detail::dummy>::type>
{
using type = return_type_t<T>;
};
}
//->
template<typename T>
struct return_type : detail::return_type_impl<T> {};
//<-
}} // namespace boost::callable_traits
//->
/*`
[heading 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
[heading Behavior]
* When the constraints are violated, a substitution failure occurs.
* The aliased type is the return type of `T`.
[heading Input/Output Examples]
[table
[[`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)]]
]
[heading Example Program]
[import ../example/return_type.cpp]
[return_type]
[endsect]
*/
//]
#endif // #ifndef BOOST_CLBL_TRTS_RESULT_OF_HPP

View file

@ -0,0 +1,386 @@
#pragma once
#include <switch.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <tuple>
#include <boost/callable_traits.hpp>
#include <type_traits>
#include <iomanip>
/* Represents an A descriptor. */
template <typename T>
struct InBuffer {
T *buffer;
size_t num_elements;
BufferType type;
InBuffer(void *b, size_t n) : buffer((T *)b), num_elements(n/sizeof(T)) { }
};
/* Represents a B descriptor. */
template <typename T>
struct OutBuffer {
T *buffer;
size_t num_elements;
OutBuffer(void *b, size_t n) : buffer((T *)b), num_elements(n/sizeof(T)) { }
};
/* Represents an X descriptor. */
template <typename T>
struct InPointer {
T *pointer;
size_t num_elements;
InPointer(void *p, size_t n) : pointer((T *)p), num_elements(n/sizeof(T)) { }
};
/* Represents a C descriptor. */
struct OutPointerWithServerSizeBase {};
template <typename T, size_t n>
struct OutPointerWithServerSize : OutPointerWithServerSizeBase {
T *pointer;
static const size_t num_elements = n;
OutPointerWithServerSize(void *p) : pointer((T *)p) { }
};
/* Represents a C descriptor with size in raw data. */
template <typename T>
struct OutPointerWithClientSize {
T *pointer;
size_t num_elements;
OutPointerWithClientSize(void *p, size_t n) : pointer((T *)p), num_elements(n/sizeof(T)) { }
};
/* Represents an input PID. */
struct PidDescriptor {
u64 pid;
PidDescriptor(u64 p) : pid(p) { }
};
/* Represents a moved handle. */
struct MovedHandle {
Handle handle;
MovedHandle(Handle h) : handle(h) { }
};
/* Represents a copied handle. */
struct CopiedHandle {
Handle handle;
CopiedHandle(Handle h) : handle(h) { }
};
/* Utilities. */
template <typename T, template <typename...> class Template>
struct is_specialization_of {
static const bool value = false;
};
template <template <typename...> class Template, typename... Args>
struct is_specialization_of<Template<Args...>, Template> {
static const bool value = true;
};
template<typename Tuple>
struct pop_front;
template<typename Head, typename... Tail>
struct pop_front<std::tuple<Head, Tail...>> {
using type = std::tuple<Tail...>;
};
template <typename T>
struct is_ipc_buffer {
static const bool value = is_specialization_of<T, InBuffer>::value
|| is_specialization_of<T, OutBuffer>::value
|| is_specialization_of<T, InPointer>::value
|| std::is_base_of<OutPointerWithServerSizeBase, T>::value
|| is_specialization_of<T, OutPointerWithClientSize>::value;
};
template <typename T>
struct size_in_raw_data {
static const size_t value = (is_ipc_buffer<T>::value) ? 0 : ((sizeof(T) < sizeof(u32)) ? sizeof(u32) : (sizeof(T) + 3) & (~3));
};
template <typename ...Args>
struct size_in_raw_data_for_arguments {
static const size_t value = (size_in_raw_data<Args>::value + ... + 0);
};
template <typename T>
struct size_in_raw_data_with_out_pointers {
static const size_t value = is_specialization_of<T, OutPointerWithClientSize>::value ? 2 : size_in_raw_data<T>::value;
};
template <typename ...Args>
struct size_in_raw_data_with_out_pointers_for_arguments {
static const size_t value = ((size_in_raw_data_with_out_pointers<Args>::value + ... + 0) + 3) & ~3;
};
template <typename T>
struct is_ipc_inbuffer {
static const size_t value = (is_specialization_of<T, InBuffer>::value) ? 1 : 0;
};
template <typename ...Args>
struct num_inbuffers_in_arguments {
static const size_t value = (is_ipc_inbuffer<Args>::value + ... + 0);
};
template <typename T>
struct is_ipc_inpointer {
static const size_t value = (is_specialization_of<T, InPointer>::value) ? 1 : 0;
};
template <typename ...Args>
struct num_inpointers_in_arguments {
static const size_t value = (is_ipc_inpointer<Args>::value + ... + 0);
};
template <typename T>
struct is_ipc_outpointer {
static const size_t value = (is_specialization_of<T, OutPointerWithClientSize>::value || std::is_base_of<OutPointerWithServerSizeBase, T>::value) ? 1 : 0;
};
template <typename ...Args>
struct num_outpointers_in_arguments {
static const size_t value = (is_ipc_outpointer<Args>::value + ... + 0);
};
template <typename T>
struct is_ipc_inoutbuffer {
static const size_t value = (is_specialization_of<T, InBuffer>::value || is_specialization_of<T, OutBuffer>::value) ? 1 : 0;
};
template <typename ...Args>
struct num_inoutbuffers_in_arguments {
static const size_t value = (is_ipc_inoutbuffer<Args>::value + ... + 0);
};
template <typename T>
struct is_ipc_handle {
static const size_t value = (std::is_same<T, MovedHandle>::value || std::is_same<T, CopiedHandle>::value) ? 1 : 0;
};
template <typename ...Args>
struct num_handles_in_arguments {
static const size_t value = (is_ipc_handle<Args>::value + ... + 0);
};
template <typename ...Args>
struct num_pids_in_arguments {
static const size_t value = ((std::is_same<Args, PidDescriptor>::value ? 1 : 0) + ... + 0);
};
template<typename T>
T GetValueFromIpcParsedCommand(IpcParsedCommand& r, IpcCommand& out_c, u8 *pointer_buffer, size_t& pointer_buffer_offset, size_t& cur_rawdata_index, size_t& cur_c_size_offset, size_t& a_index, size_t& b_index, size_t& x_index, size_t& c_index, size_t& h_index) {
const size_t old_rawdata_index = cur_rawdata_index;
const size_t old_c_size_offset = cur_c_size_offset;
const size_t old_pointer_buffer_offset = pointer_buffer_offset;
if constexpr (is_specialization_of<T, InBuffer>::value) {
return T(r.Buffers[a_index], r.BufferSizes[a_index++]);
} else if constexpr (is_specialization_of<T, OutBuffer>::value) {
return T(r.Buffers[b_index], r.BufferSizes[b_index++]);
} else if constexpr (is_specialization_of<T, InPointer>::value) {
return T(r.Statics[x_index], r.StaticSizes[x_index++]);
} else if constexpr (std::is_base_of<OutPointerWithServerSizeBase, T>::value) {
T t = T(pointer_buffer + old_pointer_buffer_offset);
ipcAddSendStatic(&out_c, pointer_buffer + old_pointer_buffer_offset, t.num_elements * sizeof(*t.pointer), c_index++);
return t;
} else if constexpr (is_specialization_of<T, OutPointerWithClientSize>::value) {
cur_c_size_offset += sizeof(u16);
u16 sz = *((u16 *)((u8 *)(r.Raw) + old_c_size_offset));
pointer_buffer_offset += sz;
ipcAddSendStatic(&out_c, pointer_buffer + old_pointer_buffer_offset, sz, c_index++);
return T(pointer_buffer + old_pointer_buffer_offset, sz);
} else if constexpr (is_ipc_handle<T>::value) {
return r.Handles[h_index++];
} else if constexpr (std::is_same<T, PidDescriptor>::value) {
return PidDescriptor(r.Pid);
} else {
cur_rawdata_index += size_in_raw_data<T>::value / sizeof(u32);
return *((T *)((u32 *)r.Raw + old_rawdata_index));
}
}
template <typename T>
bool ValidateIpcParsedCommandArgument(IpcParsedCommand& r, size_t& cur_rawdata_index, size_t& cur_c_size_offset, size_t& a_index, size_t& b_index, size_t& x_index, size_t& c_index, size_t& h_index, size_t& total_c_size) {
const size_t old_c_size_offset = cur_c_size_offset;
if constexpr (is_specialization_of<T, InBuffer>::value) {
return r.Buffers[a_index] != NULL && r.BufferDirections[a_index++] == BufferDirection_Send;
} else if constexpr (is_specialization_of<T, OutBuffer>::value) {
return r.Buffers[b_index] != NULL && r.BufferDirections[b_index++] == BufferDirection_Recv;
} else if constexpr (is_specialization_of<T, InPointer>::value) {
return r.Statics[x_index] != NULL;
} else if constexpr (std::is_base_of<OutPointerWithServerSizeBase, T>::value) {
total_c_size += T::num_elements;
return true;
} else if constexpr (is_specialization_of<T, OutPointerWithClientSize>::value) {
cur_c_size_offset += sizeof(u16);
u16 sz = *((u16 *)((u8 *)(r.Raw) + old_c_size_offset));
total_c_size += sz;
return true;
} else if constexpr (std::is_same<T, MovedHandle>::value) {
return !r.WasHandleCopied[h_index++];
} else if constexpr (std::is_same<T, CopiedHandle>::value) {
return r.WasHandleCopied[h_index++];
} else {
return true;
}
}
/* Validator. */
template <typename ArgsTuple>
struct Validator;
template<typename... Args>
struct Validator<std::tuple<Args...>> {
IpcParsedCommand &r;
size_t pointer_buffer_size;
Result operator()() {
if (r.RawSize < size_in_raw_data_with_out_pointers_for_arguments<Args... >::value) {
return 0xF601;
}
if (r.NumBuffers != num_inoutbuffers_in_arguments<Args... >::value) {
return 0xF601;
}
if (r.NumStatics != num_inpointers_in_arguments<Args... >::value) {
return 0xF601;
}
if (r.NumStaticsOut != num_outpointers_in_arguments<Args... >::value) {
return 0xF601;
}
if (r.NumHandles != num_handles_in_arguments<Args... >::value) {
return 0xF601;
}
constexpr size_t num_pids = num_pids_in_arguments<Args... >::value;
static_assert(num_pids <= 1, "Number of PID descriptors in IpcCommandImpl cannot be > 1");
if ((r.HasPid && num_pids == 0) || (!r.HasPid && num_pids)) {
return 0xF601;
}
size_t a_index = 0, b_index = num_inbuffers_in_arguments<Args ...>::value, x_index = 0, c_index = 0, h_index = 0;
size_t cur_rawdata_index = 4;
size_t cur_c_size_offset = 8 + size_in_raw_data_for_arguments<Args... >::value;
size_t total_c_size = 0;
if (!(ValidateIpcParsedCommandArgument<Args>(r, cur_rawdata_index, cur_c_size_offset, a_index, b_index, x_index, c_index, h_index, total_c_size) && ...)) {
return 0xF601;
}
if (total_c_size > pointer_buffer_size) {
return 0xF601;
}
return 0;
}
};
/* Decoder. */
template<typename OutTuple, typename ArgsTuple>
struct Decoder;
template<typename OutTuple, typename... Args>
struct Decoder<OutTuple, std::tuple<Args...>> {
static std::tuple<Args...> Decode(IpcParsedCommand& r, IpcCommand &out_c, u8 *pointer_buffer) {
size_t a_index = 0, b_index = num_inbuffers_in_arguments<Args ...>::value, x_index = 0, c_index = 0, h_index = 0;
size_t cur_rawdata_index = 4;
size_t cur_c_size_offset = 8 + size_in_raw_data_for_arguments<Args... >::value;
size_t pointer_buffer_offset = 0;
return std::tuple<Args... > {
GetValueFromIpcParsedCommand<Args>(r, out_c, pointer_buffer, pointer_buffer_offset, cur_rawdata_index, cur_c_size_offset, a_index, b_index, x_index, c_index, h_index)
...
};
}
};
/* Encoder. */
template<typename ArgsTuple>
struct Encoder;
template<typename T>
constexpr size_t GetAndUpdateOffsetIntoRawData(size_t& offset) {
auto old = offset;
if (old == 0) {
offset += sizeof(u64);
} else {
offset += size_in_raw_data<T>::value;
}
return old;
}
template<typename... Args>
struct Encoder<std::tuple<Args...>> {
IpcCommand &out_command;
auto operator()(Args... args) {
static_assert(sizeof...(Args) > 0, "IpcCommandImpls must return std::tuple<Result, ...>");
size_t offset = 0;
u8 *tls = (u8 *)armGetTls();
std::fill(tls, tls + 0x100, 0x100);
/* Remove the extra space resulting from first Result type. */
struct {
u64 magic;
u64 result;
} *raw = (decltype(raw))ipcPrepareHeader(&out_command, sizeof(*raw) + size_in_raw_data_for_arguments<Args... >::value - sizeof(Result));
raw->magic = SFCO_MAGIC;
u8 *raw_data = (u8 *)&raw->result;
((*((Args *)(raw_data + GetAndUpdateOffsetIntoRawData<Args>(offset))) = (args)), ...);
if (R_FAILED(raw->result)) {
ipcPrepareHeader(&out_command, sizeof(raw));
}
return raw->result;
}
};
template<auto IpcCommandImpl, typename Class>
Result WrapIpcCommandImpl(Class *myfancypointer, IpcParsedCommand& r, IpcCommand &out_command, u8 *pointer_buffer, size_t pointer_buffer_size) {
using InArgs = typename boost::callable_traits::args_t<decltype(IpcCommandImpl)>;
using InArgsWithoutThis = typename pop_front<InArgs>::type;
using OutArgs = typename boost::callable_traits::return_type_t<decltype(IpcCommandImpl)>;
static_assert(is_specialization_of<OutArgs, std::tuple>::value, "IpcCommandImpls must return std::tuple<Result, ...>");
static_assert(std::is_same_v<std::tuple_element_t<0, OutArgs>, Result>, "IpcCommandImpls must return std::tuple<Result, ...>");
ipcInitialize(&out_command);
Result rc = Validator<InArgsWithoutThis>{r, pointer_buffer_size}();
if (R_FAILED(rc)) {
return 0xF601;
}
auto args = Decoder<OutArgs, InArgsWithoutThis>::Decode(r, out_command, pointer_buffer);
auto result = std::apply( [=](auto&&... args) { return (myfancypointer->*IpcCommandImpl)(args...); }, args);
return std::apply(Encoder<OutArgs>{out_command}, result);
}

View file

@ -1,8 +1,10 @@
#pragma once
#include <switch.h>
#include "ipc_templating.hpp"
class IServiceObject {
public:
virtual ~IServiceObject() { }
virtual Result dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) = 0;
virtual Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) = 0;
};

View file

@ -6,50 +6,23 @@
#include "ldr_launch_queue.hpp"
#include "ldr_registration.hpp"
Result DebugMonitorService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) {
std::tuple<Result> fake_clear_launch_queue() {
LaunchQueue::clear();
return std::make_tuple(0);
}
Result DebugMonitorService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
Result rc = 0xF601;
switch ((DebugMonitorServiceCmd)cmd_id) {
case Dmnt_Cmd_AddTitleToLaunchQueue:
/* Validate arguments. */
if (in_rawdata_size < 0x10 || r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 1) {
break;
}
if (r->Statics[0] == NULL) {
rc = 0xCE01;
break;
}
rc = add_title_to_launch_queue(((u64 *)in_rawdata)[0], (const char *)r->Statics[0], r->StaticSizes[0]);
*out_raw_data_count = 0;
rc = WrapIpcCommandImpl<&DebugMonitorService::add_title_to_launch_queue>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
case Dmnt_Cmd_ClearLaunchQueue:
if (r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 0) {
break;
}
rc = clear_launch_queue();
*out_raw_data_count = 0;
rc = WrapIpcCommandImpl<&DebugMonitorService::clear_launch_queue>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
case Dmnt_Cmd_GetNsoInfo:
if (in_rawdata_size < 0x8 || r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 1) {
break;
}
rc = get_nso_info(((u64 *)in_rawdata)[0], r->Statics[0], r->StaticSizes[0], out_rawdata);
if (R_SUCCEEDED(rc)) {
*out_raw_data_count = 1;
} else {
*out_raw_data_count = 0;
}
rc = WrapIpcCommandImpl<&DebugMonitorService::get_nso_info>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
default:
break;
@ -57,21 +30,23 @@ Result DebugMonitorService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32
return rc;
}
Result DebugMonitorService::add_title_to_launch_queue(u64 tid, const char *args, size_t args_size) {
return LaunchQueue::add(tid, args, args_size);
std::tuple<Result> DebugMonitorService::add_title_to_launch_queue(u64 tid, InPointer<char> args) {
fprintf(stderr, "Add to launch queue: %p, %X\n", args.pointer, args.num_elements);
return std::make_tuple(LaunchQueue::add(tid, args.pointer, args.num_elements));
}
Result DebugMonitorService::clear_launch_queue() {
std::tuple<Result> DebugMonitorService::clear_launch_queue(u64 dat) {
fprintf(stderr, "Clear launch queue: %lx\n", dat);
LaunchQueue::clear();
return 0;
return std::make_tuple(0);
}
Result DebugMonitorService::get_nso_info(u64 pid, void *out, size_t out_size, u32 *out_num_nsos) {
u32 max_out = out_size / (sizeof(Registration::NsoInfo));
std::tuple<Result, u32> DebugMonitorService::get_nso_info(u64 pid, OutPointerWithClientSize<Registration::NsoInfo> out) {
u32 out_num_nsos = 0;
Registration::NsoInfo *nso_out = (Registration::NsoInfo *)out;
//std::fill(out.pointer, out.pointer + out.num_elements, (const Registration::NsoInfo){0});
std::fill(nso_out, nso_out + max_out, (const Registration::NsoInfo){0});
Result rc = Registration::get_nso_infos_for_process_id(out.pointer, out.num_elements, pid, &out_num_nsos);
return Registration::get_nso_infos_for_process_id(nso_out, max_out, pid, out_num_nsos);
return std::make_tuple(rc, out_num_nsos);
}

View file

@ -2,6 +2,7 @@
#include <switch.h>
#include "iserviceobject.hpp"
#include "ldr_registration.hpp"
enum DebugMonitorServiceCmd {
Dmnt_Cmd_AddTitleToLaunchQueue = 0,
@ -11,11 +12,11 @@ enum DebugMonitorServiceCmd {
class DebugMonitorService : IServiceObject {
public:
Result dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count);
Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size);
private:
/* Actual commands. */
Result add_title_to_launch_queue(u64 tid, const char *args, size_t args_size);
Result clear_launch_queue();
Result get_nso_info(u64 pid, void *out, size_t out_size, u32 *out_num_nsos);
std::tuple<Result> add_title_to_launch_queue(u64 tid, InPointer<char> args);
std::tuple<Result> clear_launch_queue(u64 dat);
std::tuple<Result, u32> get_nso_info(u64 pid, OutPointerWithClientSize<Registration::NsoInfo> out);
};

View file

@ -3,43 +3,22 @@
#include "ldr_registration.hpp"
#include "ldr_launch_queue.hpp"
Result ProcessManagerService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) {
Result ProcessManagerService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
Result rc = 0xF601;
switch ((ProcessManagerServiceCmd)cmd_id) {
case Pm_Cmd_CreateProcess:
/* TODO */
rc = WrapIpcCommandImpl<&ProcessManagerService::create_process>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
case Pm_Cmd_GetProgramInfo:
/* TODO */
rc = WrapIpcCommandImpl<&ProcessManagerService::get_program_info>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
case Pm_Cmd_RegisterTitle:
/* Validate arguments. */
if (in_rawdata_size < 0x10 || r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 0) {
break;
}
u64 out_index;
rc = register_title((Registration::TidSid *)in_rawdata, &out_index);
if (R_SUCCEEDED(rc)) {
((u64 *)out_rawdata)[0] = out_index;
*out_raw_data_count = 2;
} else {
((u64 *)out_rawdata)[0] = 0;
*out_raw_data_count = 0;
}
rc = WrapIpcCommandImpl<&ProcessManagerService::register_title>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
case Pm_Cmd_UnregisterTitle:
/* Validate arguments. */
if (in_rawdata_size < 0x8 || r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 0) {
break;
}
rc = unregister_title(((u64 *)in_rawdata)[0]);
*out_raw_data_count = 0;
rc = WrapIpcCommandImpl<&ProcessManagerService::unregister_title>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
default:
break;
@ -47,28 +26,29 @@ Result ProcessManagerService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u
return rc;
}
Result ProcessManagerService::create_process() {
std::tuple<Result> ProcessManagerService::create_process() {
/* TODO */
return 0xF601;
return std::make_tuple(0xF601);
}
Result ProcessManagerService::get_program_info() {
std::tuple<Result> ProcessManagerService::get_program_info() {
/* TODO */
return 0xF601;
return std::make_tuple(0xF601);
}
Result ProcessManagerService::register_title(const Registration::TidSid *tid_sid, u64 *out_index) {
if (Registration::register_tid_sid(tid_sid, out_index)) {
return 0;
std::tuple<Result, u64> ProcessManagerService::register_title(Registration::TidSid tid_sid) {
u64 out_index = 0;
if (Registration::register_tid_sid(&tid_sid, &out_index)) {
return std::make_tuple(0, out_index);
} else {
return 0xE09;
return std::make_tuple(0xE09, out_index);
}
}
Result ProcessManagerService::unregister_title(u64 index) {
std::tuple<Result> ProcessManagerService::unregister_title(u64 index) {
if (Registration::unregister_index(index)) {
return 0;
return std::make_tuple(0);
} else {
return 0x1009;
return std::make_tuple(0x1009);
}
}

View file

@ -13,12 +13,12 @@ enum ProcessManagerServiceCmd {
class ProcessManagerService : IServiceObject {
public:
Result dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count);
Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size);
private:
/* Actual commands. */
Result create_process();
Result get_program_info();
Result register_title(const Registration::TidSid *tid_sid, u64 *out_index);
Result unregister_title(u64 index);
std::tuple<Result> create_process();
std::tuple<Result> get_program_info();
std::tuple<Result, u64> register_title(Registration::TidSid tid_sid);
std::tuple<Result> unregister_title(u64 index);
};

View file

@ -18,20 +18,21 @@ Registration::Process *Registration::get_free_process() {
Registration::Process *Registration::get_process(u64 index) {
unsigned int i;
for (i = 0; !g_registration_list.processes[i].in_use || g_registration_list.processes[i].index != index; i++) {
if (i >= REGISTRATION_LIST_MAX) {
return NULL;
}
for (i = 0; i < REGISTRATION_LIST_MAX && (!g_registration_list.processes[i].in_use || g_registration_list.processes[i].index != index); i++) {
}
if (i >= REGISTRATION_LIST_MAX) {
return NULL;
}
return &g_registration_list.processes[i];
}
Registration::Process *Registration::get_process_by_process_id(u64 pid) {
unsigned int i;
for (i = 0; !g_registration_list.processes[i].in_use || g_registration_list.processes[i].process_id != pid; i++) {
if (i >= REGISTRATION_LIST_MAX) {
return NULL;
}
for (i = 0; i < REGISTRATION_LIST_MAX && (!g_registration_list.processes[i].in_use || g_registration_list.processes[i].process_id != pid); i++) {
}
if (i >= REGISTRATION_LIST_MAX) {
return NULL;
}
return &g_registration_list.processes[i];
}

View file

@ -2,35 +2,16 @@
#include "ldr_shell.hpp"
#include "ldr_launch_queue.hpp"
Result ShellService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) {
Result ShellService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
Result rc = 0xF601;
switch ((ShellServiceCmd)cmd_id) {
case Shell_Cmd_AddTitleToLaunchQueue:
/* Validate arguments. */
if (in_rawdata_size < 0x10 || r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 1) {
break;
}
if (r->Statics[0] == NULL) {
rc = 0xCE01;
break;
}
rc = add_title_to_launch_queue(((u64 *)in_rawdata)[0], (const char *)r->Statics[0], r->StaticSizes[0]);
*out_raw_data_count = 0;
rc = WrapIpcCommandImpl<&ShellService::add_title_to_launch_queue>(this, r, out_c, pointer_buffer, pointer_buffer_size);
break;
rc = WrapIpcCommandImpl<&ShellService::add_title_to_launch_queue>(this, r, out_c, pointer_buffer, pointer_buffer_size);
case Shell_Cmd_ClearLaunchQueue:
if (r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 0) {
break;
}
rc = clear_launch_queue();
*out_raw_data_count = 0;
break;
default:
break;
@ -38,11 +19,13 @@ Result ShellService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_b
return rc;
}
Result ShellService::add_title_to_launch_queue(u64 tid, const char *args, size_t args_size) {
return LaunchQueue::add(tid, args, args_size);
std::tuple<Result> ShellService::add_title_to_launch_queue(u64 tid, InPointer<char> args) {
fprintf(stderr, "Add to launch queue: %p, %X\n", args.pointer, args.num_elements);
return std::make_tuple(LaunchQueue::add(tid, args.pointer, args.num_elements));
}
Result ShellService::clear_launch_queue() {
std::tuple<Result> ShellService::clear_launch_queue(u64 dat) {
fprintf(stderr, "Clear launch queue: %lx\n", dat);
LaunchQueue::clear();
return 0;
return std::make_tuple(0);
}

View file

@ -10,10 +10,10 @@ enum ShellServiceCmd {
class ShellService : IServiceObject {
public:
Result dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count);
Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size);
private:
/* Actual commands. */
Result add_title_to_launch_queue(u64 tid, const char *args, size_t args_size);
Result clear_launch_queue();
std::tuple<Result> add_title_to_launch_queue(u64 tid, InPointer<char> args);
std::tuple<Result> clear_launch_queue(u64 dat);
};

View file

@ -3,6 +3,7 @@
#include <type_traits>
#include <cstdio>
#include "ipc_templating.hpp"
#include "iserviceobject.hpp"
#include "iwaitable.hpp"
#include "serviceserver.hpp"
@ -83,15 +84,13 @@ class ServiceSession : public IWaitable {
/* TODO: Panic? */
}
u32 *cmdbuf = (u32 *)armGetTls();
u32 out_words = 4;
u32 extra_rawdata_count = 0;
u32 wordcount = 0;
Result retval = 0;
u32 *rawdata_start = cmdbuf;
IpcParsedCommand r;
IpcCommand c;
fprintf(stderr, "Doing ServiceSession parse...\n");
ipcInitialize(&c);
@ -100,7 +99,6 @@ class ServiceSession : public IWaitable {
if (R_SUCCEEDED(retval)) {
rawdata_start = (u32 *)r.Raw;
wordcount = r.RawSize;
switch (r.CommandType) {
case IpcCommandType_Close:
/* TODO: This should close the session and clean up its resources. */
@ -116,13 +114,11 @@ class ServiceSession : public IWaitable {
break;
case IpcCommandType_Request:
case IpcCommandType_RequestWithContext:
retval = this->service_object->dispatch(&r, &c, cmdbuf, rawdata_start[2], &rawdata_start[4], wordcount - 6, &cmdbuf[8], &extra_rawdata_count);
out_words += extra_rawdata_count;
retval = this->service_object->dispatch(r, c, rawdata_start[2], (u8 *)this->pointer_buffer, sizeof(this->pointer_buffer));
break;
case IpcCommandType_Control:
case IpcCommandType_ControlWithContext:
retval = this->dispatch_control_command(&r, &c, cmdbuf, rawdata_start[2], &rawdata_start[4], wordcount - 6, &cmdbuf[8], &extra_rawdata_count);
out_words += extra_rawdata_count;
retval = this->dispatch_control_command(r, c, rawdata_start[2]);
break;
case IpcCommandType_Invalid:
default:
@ -133,16 +129,6 @@ class ServiceSession : public IWaitable {
}
if (retval != 0xF601) {
struct {
u64 magic;
u64 retval;
} *raw;
raw = (decltype(raw))ipcPrepareHeader(&c, out_words * 4);
raw->magic = SFCO_MAGIC;
raw->retval = retval;
rc = svcReplyAndReceive(&handle_index, &this->server_handle, 1, this->server_handle, 0);
} else {
rc = retval;
@ -152,30 +138,46 @@ class ServiceSession : public IWaitable {
return rc;
}
Result dispatch_control_command(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) {
/* Control commands. */
std::tuple<Result> ConvertCurrentObjectToDomain() {
/* TODO */
return std::make_tuple(0xF601);
}
std::tuple<Result> CopyFromCurrentDomain() {
/* TODO */
return std::make_tuple(0xF601);
}
std::tuple<Result> CloneCurrentObject() {
/* TODO */
return std::make_tuple(0xF601);
}
std::tuple<Result, u32> QueryPointerBufferSize() {
return std::make_tuple(0x0, (u32)sizeof(this->pointer_buffer));
}
std::tuple<Result> CloneCurrentObjectEx() {
/* TODO */
return std::make_tuple(0xF601);
}
Result dispatch_control_command(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id) {
Result rc = 0xF601;
/* TODO: Implement. */
switch ((IpcControlCommand)cmd_id) {
case IpcCtrl_Cmd_ConvertCurrentObjectToDomain:
/* TODO */
rc = WrapIpcCommandImpl<&ServiceSession::ConvertCurrentObjectToDomain>(this, r, out_c, (u8 *)this->pointer_buffer, sizeof(this->pointer_buffer));
break;
case IpcCtrl_Cmd_CopyFromCurrentDomain:
/* TODO */
rc = WrapIpcCommandImpl<&ServiceSession::CopyFromCurrentDomain>(this, r, out_c, (u8 *)this->pointer_buffer, sizeof(this->pointer_buffer));
break;
case IpcCtrl_Cmd_CloneCurrentObject:
/* TODO */
rc = WrapIpcCommandImpl<&ServiceSession::CloneCurrentObject>(this, r, out_c, (u8 *)this->pointer_buffer, sizeof(this->pointer_buffer));
break;
case IpcCtrl_Cmd_QueryPointerBufferSize:
if (r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 0 || r->NumStaticsOut != 0) {
break;
}
*out_rawdata = sizeof(this->pointer_buffer);
*out_raw_data_count = 1;
rc = 0;
rc = WrapIpcCommandImpl<&ServiceSession::QueryPointerBufferSize>(this, r, out_c, (u8 *)this->pointer_buffer, sizeof(this->pointer_buffer));
break;
case IpcCtrl_Cmd_CloneCurrentObjectEx:
/* TODO */
rc = WrapIpcCommandImpl<&ServiceSession::CloneCurrentObjectEx>(this, r, out_c, (u8 *)this->pointer_buffer, sizeof(this->pointer_buffer));
break;
default:
break;