Giter VIP home page Giter VIP logo

cxx_function's Introduction

cxx_function library

A prototype for new std::function features, compatible with C++11.

by David Krauss (potatoswatter)

Highlights

  • Conforming to the std::function specification in C++11 and C++14

  • "Plus" noexcept guarantees for move and swap

  • Multi-signature, overloaded function objects:

      function< ret1( arg1 ), void(), void() const >
    
  • Including reference qualification

  • Deprecation warning when a call operator casts away const

  • Non-copyable target objects:

      unique_function< void() > f = [uptr = std::make_unique< resource_t >()] {…};
    
  • Including in-place construction

  • Full support of allocators:

      function_container< my_pool<char>, void() > = other_pooled_function;
    
  • Custom construct() and destroy()

  • std::scoped_allocator_adaptor reaches inside target objects

  • Allocator propagation by assignment, swap, and copying (needs testing)

  • Fancy pointers (not yet tested)

  • Queries allocator_traits interface exclusively; does not access allocators directly

  • Written in C++11; does not require migrating to a new language edition

  • Efficiency

  • Economizes space better than libc++ (Clang)

  • Economizes branch instructions better than libstdc++ (GCC)

  • Performs well compared to similar third-party libraries.

  • Avoids indirect branches for trivial target object copy construction, move construction, and destruction (common case for lambdas)

How to use

For std::function documentation, see cppreference.com or a recent C++ draft standard. Only new features are described here.

This library is tested against Clang 3.6 (with libc++ and libstdc++) and GCC 5.1 (with libstdc++) on OS X. There is a separate branch tested against VS2015. Please report bugs.

Overloaded functions

Each signature supplied to a template will be used to declare one operator() overload. Ordinary overload resolution is used to select between them. Each overload forwards its arguments along to the target. There is no function template or perfect forwarding involved in dispatching, so you can pass braced initializer lists.

Duplicate signatures are currently ignored. Different permutations of an overload set produce different types, but the distinction between them is not supported. Hopefully there ultimately may be a 1:1 mapping between overload sets and function types.

C++11 specifies that std::function::operator() is const-qualified, but implementations have always called the target object without const qualification. This is supported but deprecated by this library. Any signature without any function qualifiers (that is, supported by C++11) is shadowed by a const-qualified version. Calling this function will produce a deprecation warning. You can replace it by declaring the const-qualified signature in the list.

There are several general solutions to a deprecation warning:

  1. Pass the function by value or forwarding so it is not observed to be const.

    This has always been the canonical usage of std::function (and all Callable objects). This fix can be applied per call site, usually without affecting any external interface.

  2. Add a const qualifier to the signature. This explicitly solves the problem through greater exposition and tighter constraints. It requires that the target object be callable as const.

    This is usually a good idea in any case, since in practice most functions are not stateful. Ideally, function< void() const > should represent a function that does the same thing on each call. If you have function< void() > const instead, that means that calling may change some state, but you don't have permission to do so. (This is the crux of the issue.)

    If the target needs to change, but only in a way that doesn't affect its observable behavior, consider using mutable instead. Note that lambdas allow mutable, but the keyword is somewhat abused: the members of the lambda are not mutable. It only makes the call operator non-const. You will need to explicitly declare a class with a mutable member.

  3. Consistently remove const from the reference which gets called. Non-const references are the best way to share mutable access to values. More const is not necessarily better. Again, this reflects greater exposition and tighter constraints.

    If you must use a const_cast, do so within the target call handler, not on the function which gets called. The validity of const_cast depends on whether or not the affected object was created as const, and target objects never are.

If you declare a signature with no qualifiers and one with e.g. const & qualifiers, the automatic const overload will cause an overload resolution conflict. Declare a pair of & and && qualifiers instead. (Any such design would be very suspicious, though.)

A target object is checked against all the signatures when it is assigned to a wrapper. Like permutations of the same overload set, you can assign one function to another specialization which is different but appropriately callable. The result will be two function objects, one wrapped inside the other. This is Bad Design and it should probably be deprecated.

Non-copyable functions

The unique_function template works just like function, but it can handle any target object and it cannot be copied. To construct the target object in place (to avoid moving it), pass a dispatch tag like this (in C++11):

unique_function< void() > fn( in_place_t< target_type >{}, constructor_arg1, arg2 );

or this (since C++14):

unique_function< void() > fn( in_place< target_type >, constructor_arg1, arg2 );

This also works with all the other templates. Likewise, there are new functions for assignent after construction:

fn.emplace_assign< target_type >( constructor_arg1, arg2 );
fn.allocate_assign< target_type >( allocator, constructor_arg1, arg2 );

You can assign any of the other templates to a unique_function, but not vice versa. There is no risk of double wrapping, as long as the signature lists match exactly. Whereas other implementations tend to throw an error deep from deep inside their templates for a non-copyable target, this library checks copyability for the non-unique types before anything else happens.

Note that copyability is different from an rvalue-qualified (&&) signature. For example:

  • function< void() && > ideally represents a function that can be copied, and called once per copy.
  • unique_function< void() > represents a function with abilities that can't be replicated in a copy (hence "unique"), but can still be called many times.
  • unique_function< void() && > represents a one-shot function that can only ever be called once.

To call an object with an rvalue-qualified signature, use std::move( my_func ) ( args ). This usage also works on ordinary, unqualified signatures and it is backward-compatible with C++11 std::function.

Movable and non-movable targets

A target which is not movable must be initialized using in-place initialization.

A target with a move constructor that is not declared noexcept (or throw(), which is deprecated) will be allocated on the heap; it cannot be stored within the wrapper. Once a target is placed on the heap, it will never be moved at all, except to an allocator representing a different memory pool. (See below.) It's better to remember the noexcept. Also, use = default when possible, as it automatically computes and sets noexcept for you.

Enhanced safety

A function object returning const & or && should avoid returning a reference to a temporary. This library forbids target objects whose return type would force function to return a dangling reference. The standard library currently allows them.

function< int const &() > fn = []{ return 5; }; // Binding 5 to int const& would produce a dangling return value.

This protection is not perfect. It may be defeated by implicit conversion between class types. This slips through the cracks:

function< std::pair< long, long > const &() > fn = []{ return std::make_pair( 1, 2 ); };

Allocators

This library implements a new allocator model, conforming (almost, see "Bugs" below) to the C++11 specification. (How can it be both new and old? Because the normative std::function allocator model has been underspecified, there are several equally-conforming models.) As for function alone, this library behaviorally matches libc++ and libstdc++, but additionally supporting the allocator methods construct and destroy.

function and unique_function use an allocator to handle target objects that cannot fit into the wrapper storage (equal to the size of three pointers). They behave as clients of the allocator, but not as containers. The behavior of std::shared_ptr via std::allocate_shared is closely analogous: the allocator is used when the object is created and destroyed, but it is invisible in the meantime. The only difference is that function permits additional operations like copying.

function_container and unique_function_container behave more like allocator-aware containers. They encapsulate a permanent allocator instance, of a type given by the initial template argument. The target object of these wrappers always uses either the given allocator, or only the storage within the wrapper. When a pre-existing target is assigned from a corresponding wrapper specialization, it's adopted by following these steps:

  1. If the allocator specifies propagate_on_container_move_assignment or propagate_on_container_copy_assignment (whichever is applicable) as std::true_type, and the source is also a container, then the allocator is assigned.

  2. If the target is stored within the wrapper, allocators aren't an issue. It's copied or moved directly, using memcpy if possible.

  3. Otherwise, the type of the new target's allocator is compared to the type of the container allocator. Both are rebound to Allocator< char > and the resulting types are compared using typeid.

  4. If the types don't match, an exception is thrown! Do not let this happen: only assign to function_container when you know the memory scheme originating the assigned value. The type of the exception is allocator_mismatch_error.

  5. Otherwise, the allocators are compared using the == operator. Again, both instances are rebound to a value_type of char. If they compare equal, then the assignment proceeds as if the container were just a non-container function.

    If they are unequal, or if it's a copy-assignment, the target is reallocated by the container's allocator. The container's allocator is then updated to reflect any change. (The new value is still equal to the old value, though.)

  6. In any case, if the operation is a move, the source wrapper is set to nullptr. This guarantees deallocation from the source memory pool when the destination pool is different.

Note that initializing a function_container from a function will not adopt the allocator. It will use a default-initialized allocator. Ideally, the compiler will complain that the allocator cannot be default-initialized. These constructor overloads should probably be deprecated, because it looks like the allocator is getting dynamically copy/move-initialized.

Since the allocator of function_container is fixed, it does not implement the assign or allocate_assign functions.

Propagation

Container allocators are "sticky:" the allocator designated at initialization is used throughout the container's lifetime.

Non-container function allocators are "stealthy:" the allocator is only used to manage the target object, and any copies of it. It cannot be observed by get_allocator. (It really does exist though, and an accessor could easily be implemented.)

There exist allocator properties propagate_on_container_move_assignment and propagate_on_container_copy_assignment. These affect the semantics of assignment between containers, but do not enable a container to observe the allocator of a non-container. They reduce stickiness, but not stealthiness.

POCMA and POCCA have a similar effect on function_container as on any other container such as std::vector. In particular, POCMA is sufficient for container move assignment to be noexcept. However, is_always_equal is also sufficient for that, and using these traits is a serious anti-pattern: Allocators are supposed to be orthogonal to containers. is_always_equal furthermore eliminates the requirement that the target be move-constructible, which POCMA does not do. It is the better alternative. (However, is_always_equal support is only getting added to libc++ and libstdc++ as I write this.)

Usage

Memory management gets harder as it gets stricter. Here are some ground rules for this library:

  1. Use best practices for container allocators. Use scoped_allocator_adaptor.

  2. Do not assign something to a function_container unless it was created using a compatible function_container, or you're sure it was created using allocator_arg_t with a function.

  3. Use function_container only for persistent storage; don't pass it around everywhere. It's not suitable as a value type. Use function for that. Do not try to hack the allocator model using propagate_on_container_*_assignment.

  4. If you're afraid about copies running against resource constraints, use unique_*. Note that when you give a function to someone, they may (in theory) make unlimited copies of it. On the other hand, resource exhaustion is something that allocators manage, so you should be prepared for this case and not "afraid" of it :) .

  5. The memory resource backing the allocators must persist as long as any functions may be alive and using the storage. Always assert that memory resources (pools) are empty before freeing them, lest references go dangling. Do not pass custom-allocated functions to a library that will retain them indefinitely, unless you're willing to take a risk by either (a) destroying the pool at the last possible moment before program termination or (b) not destroying the pool at all.

Bugs

Please report issues on GitHub. Here are some that are already known:

  • function and unique_function constructors taking an allocator but no target should be deprecated, and should accept any allocator type. Instead, they require a std::allocator specialization and give no warning.

    Note that this constructor is not implemented at all by libstdc++ (GCC), and it doesn't do anything in libc++ (Clang), so unless you already have a more exotic library, you should not be using it. The most likely result of this bug is simply that usages needing migration to function_container get flagged with overload resolution failures.

  • The allocator and the pointer it generates (which may be a "fancy pointer," or a type other than T*) must fit into the wrapper storage space, equal to three native pointers. There are subtle issues here requiring further research, but std::allocate_shared already practically solves this problem so I will probably end up doing the same thing.

  • Double wrapping allows a function to be spread across multiple memory pools. There are many ways to accidentally forget to reallocate some owned resources, but the library could do a better job of catching mistakes.

    The same goes for all cases of double wrapping, really. None of them are semantically incorrect or involve privilege violations (such as accidentally allocating with std::allocator), but it's an easy mistake which wastes resources.

I'm not adding these bugs to the database myself. Feel free to do so. It helps to mention a motivating case. All are fixable.

cxx_function's People

Contributors

mpusz avatar potswa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cxx_function's Issues

[Feature Request] MSVC support for the main header

As of revision e7beb8b the cxx_function.hpp header doesn't support MSVC:

cxx_function/cxx_function.hpp(181): error C2065: 'has_trivial_copy_constructor': undeclared identifier (compiling source file test-continuable-connection-all.cpp)
cxx_function/cxx_function.hpp(182): note: see reference to class template instantiation 'cxx_function::impl::erasure_trivially_movable<erasure>' being compiled (compiling source file test-continuable-connection-all.cpp)

It would be nice if the generic header would also support MSVC (14+), so it could be used as drop-in replacement on all platforms.

Overloaded signatures don't seem to work or be tested

https://godbolt.org/z/RcyhgH

#include <cxx_function.hpp>

int foo(int);

cxx_function::function<int(), int(int)> f = foo;
cxx_function::function<int(int), int()> g = foo;

My impression from the README is that this code is supposed to compile. It doesn't.
I don't see any test cases in test/ that try to use multiple signatures, so my working hypothesis is that the README is simply over-optimistically out-of-sync with what's actually implemented.

Refactor Allocator support entirely into container classes

Following LWG direction and general good architecture, function_container should implement all allocator support rather than activating functionality in the common base shared with function.

"cxx_function.hpp" should be purged of Allocator code and a new header "cxx_function_container.hpp" added. Is anyone using function_container, whom the move would disturb?

VS2015 support

I tried to compile this header with VS2015U1 and got trouble. I didn't make a patch because I think my fixes might be just hacks and I'm not sure which issues are compiler issues and which one are from the code.

I wrote this "test" and tried to compile it alone in VS2015U1:

#include <utilcxx/function.hpp>

void foo()
{
    cxx_function::function<void()> f;
    cxx_function::unique_function<void()> u;

}

Here function.hpp is a copy past of current master of cxx_function.

First issue:

I think this is a compiler issue but I'm not totally sure yet.

utilcxx\function.hpp(360): error C2039: 'value': is not a member of '`global namespace''

line 360:

template< typename t, typename v >
    struct is_always_equal< t, v, typename std::enable_if< decltype (std::declval< t >() == std::declval< t >())::value >::type >
        : std::true_type {};

It seems like VS is failing to understand the decltype() usage in the enable_if, and I think previous versions were having issues too. Anyway I replaced the code by this to try to go forward, it removes this error:

template< typename t, typename v >
    using sometype = decltype (std::declval< t >() == std::declval< t >());

    template< typename t, typename v >
    struct is_always_equal< t, v, typename std::enable_if< sometype<t,v>::value >::type >
        : std::true_type {};

Second issue:

The second error is more tricky and general:

utilcxx\function.hpp(795): error C2039: 'wrapper_base<void __cdecl(void)>': is not a member of 'cxx_function::impl::wrapper<cxx_function::impl::is_copyable_all_callable<cxx_function::function<void (void)>,void (void)>::temp,cxx_function::impl::wrapper_no_allocator,void (void)>'
utilcxx\function.hpp(1075): note: see reference to class template instantiation 'cxx_function::impl::wrapper<cxx_function::impl::is_copyable_all_callable<cxx_function::function<void (void)>,void (void)>::temp,cxx_function::impl::wrapper_no_allocator,void (void)>' being compiled
main.cpp(5): note: see reference to class template instantiation 'cxx_function::function<void (void)>' being compiled

Here the issue seems to be that you are re-using the current type name as part of the name of a base class when doing using declarations to import base type's members into the child type.
For example:

template< template< typename ... > class is_targetable, typename allocator_manager, typename ... sig >
    class wrapper
        : public allocator_manager
        , wrapper_base< sig ... > {
        //...
        using wrapper::wrapper_base::storage;
        using wrapper::wrapper_base::storage_address;
        using wrapper::wrapper_base::init;

Here, my understanding of the C++ standard (I might be wrong) is that repeating wrapper in the using declarations are unnecessary if not an error.
Anyway, removing them everywhere the compiler point the same issue seems to make things go forward.

template< template< typename ... > class is_targetable, typename allocator_manager, typename ... sig >
    class wrapper
        : public allocator_manager
        , wrapper_base< sig ... > {
        //...
        using wrapper_base::storage;                   // ok
        using wrapper_base::storage_address;    // ok
        using wrapper_base::init;                          // ok

I'm even less sure for this case who is correct, the compiler or the code...

Third issue:

Not sure again what is correct.

utilcxx\function.hpp(908): error C2876: 'cxx_function::impl::wrapper_dispatch<cxx_function::impl::wrapper_base<void (void)>,0,void (void)>': not all overloads are accessible

This is modified code in the wrapper class definition:

public:
        using wrapper_base::operator ();  // error
        using wrapper_base::target;
        using wrapper_base::target_type;
        using wrapper_base::verify_type;
        using wrapper_base::operator bool;
        using wrapper_base::complete_object_address;

I figured that operator() is actually defined in wrapper_forward class, from which wrapper_base inherit from publicly. So at first glance it seems that the compiler is wrong as the operator should be accessible. That being said, this case is a bit tricky because I'm not sure if it's correct to have using declaration make reference to a name which is defined in a parent class 2 levels up.
Anyway, the cleanest way to fix this is to just do a using declaration in wrapper_base to make sure the compiler see the function all the way down.

    template< typename ... sig >
    class wrapper_base
        : public wrapper_dispatch< wrapper_base< sig ... >, 0, sig ... > {
        template< template< typename ... > class, typename, typename ... >
        friend class wrapper;
        typedef std::aligned_storage< sizeof(void *[3]) >::type effective_storage_type;
    protected:
        using wrapper_dispatch::operator();  // line added, fixes the error

The next errors were the same as the second one but for the function class, which led to this code:

    template< typename ... sig >
class function
    : impl::wrapper< impl::is_copyable_all_callable< function< sig ... >, sig ... >::template temp, impl::wrapper_no_allocator, sig ... > {
    template< template< typename ... > class, typename, typename ... >
    friend class impl::wrapper;
public:
    using wrapper::wrapper;

    function() noexcept = default; // Investigate why these are needed. Compiler bug?
    function(function && s) noexcept = default;
    function(function const &) = default;
    function & operator = (function && s) noexcept = default;
    function & operator = (function const & o) = default;

    using wrapper::operator ();
    using wrapper::operator =;
    using wrapper::swap;
    using wrapper::target;
    using wrapper::target_type;
    using wrapper::verify_type;
    using wrapper::operator bool;
    using wrapper::complete_object_address;

    using wrapper::assign;
    using wrapper::emplace_assign;
    using wrapper::allocate_assign;
    // No allocator_type or get_allocator.
};

Fourth Issue:

With this change I got the following error:

utilcxx\function.hpp(1102): error C2535: 'cxx_function::function<void (void)>::function(source &&)': member function already defined or declared
utilcxx\function.hpp(1081): note: compiler has generated 'cxx_function::function<void (void)>::function' here
main.cpp(5): note: see reference to class template instantiation 'cxx_function::function<void (void)>' being compiled

So the constructor delegation on line using wrapper::wrapper; is (obviously) importing constructors from wrapper, which is good, but the compiler don't like that we redefine some of the constructors. So I removed the unnecessary constructor to get this:

    template< typename ... sig >
class function
    : impl::wrapper< impl::is_copyable_all_callable< function< sig ... >, sig ... >::template temp, impl::wrapper_no_allocator, sig ... > {
    template< template< typename ... > class, typename, typename ... >
    friend class impl::wrapper;
public:
    using wrapper::wrapper;   // apparent source of the problem?
    // constructors removed HERE
    // ...
};

With this modification I still get the same error, with the same source, that is the using constructor declaration.
Replacing this line by this one seems to work but I suspect that it's actually wrong if not misleading:

    template< typename ... sig >
class function
    : impl::wrapper< impl::is_copyable_all_callable< function< sig ... >, sig ... >::template temp, impl::wrapper_no_allocator, sig ... > {
    template< template< typename ... > class, typename, typename ... >
    friend class impl::wrapper;
public:
    // constructor forwarding everything to the base type
    template< class... anything >
    function( anything&&... x ) : wrapper( std::forward<anything>(x) ) {}

This is dirty and I'm sure it have bloody edge cases.

For unique_function I did the same, with a twist: I kept the deleted operations so that it does what we expect. I ended up with this:

template< typename ... sig >
class unique_function
    : impl::wrapper< impl::is_all_callable< sig ... >::template temp, impl::wrapper_no_allocator, sig ... > {
    template< template< typename ... > class, typename, typename ... >
    friend class impl::wrapper;
public:
    template< class... anything >
    unique_function(anything&&... x) : wrapper( std::forward<anything>(x)... ) {}

    unique_function(unique_function const &) = delete;
    unique_function & operator = (unique_function const & o) = delete;

    using wrapper::operator ();
    using wrapper::operator =;
    using wrapper::swap;
    using wrapper::target;
    using wrapper::target_type;
    using wrapper::verify_type;
    using wrapper::operator bool;
    using wrapper::complete_object_address;

    using wrapper::assign;
    using wrapper::emplace_assign;
    using wrapper::allocate_assign;
    // No allocator_type or get_allocator.
};

At this point I changed my test to this executable program:

#include <iostream>
#include <utilcxx/function.hpp>

int main()
{
    cxx_function::function<void()> f = [] { std::cout << "Hello, " << std::endl; };
    cxx_function::unique_function<void()> u = [] { std::cout << "World!" << std::endl; };

    f();
    u();
}

This compiles and run correctly for me.

I tried some tests but they fail, for example swap.cpp fails with an error suggesting that the template forwarding constructor was indeed too dirty.

Anyway I don't have enough time to go further for now, tell me if I can help in some ways.

Guarantee static initialization of "vtable"

std::tuple does not have constexpr constructors (besides the default one), at least not in C++11 and C++14 which are supported by this library. A custom class would guarantee static initialization and avoid the "static initialization order fiasco" (which, in fact, applies to dynamic initialization of nonlocal variables, but whatever).

Also, it would allow slicing the copy constructor from function "vtables," to produce tables compatible with unique_function even if the latter doesn't have a slot for copy constructors. (Actually, that optimization may be too minor to bother with.)

construct() and destroy() should work without uses_allocator, with local storage

Currently is_small disables local storage according to std::uses_allocator. If uses_allocator returns false_type and local storage is applied, then construct and destroy don't get called.

Instead, construct and destroy should be applied to the local storage. A copy of the allocator needs to be saved to call destroy, but hopefully this can be avoided.

Detect whether the allocator actually implements destroy; if not, use ordinary destruction.

If the allocator is scoped_allocator_adaptor and get_allocator() works on the target, then it would be nice to use that for destruction. But, that would be too presumptuous. It might be OK to check for implementation of destroy on scoped_allocator_adaptor::outer_allocator_type. A more generic means would be nice.

Assertion failed: (pool[ 2 ] == op.state.capacity() + 1 + sizeof (stateful_op)), function main, file scoped_allocator.cpp, line 106.

When running the scoped_allocator test with -O3 on my mac, I get the stated assertion. My g++ appears to be clang++ masquerading as g++, version as follows:

$ g++ --version
Configured with: --prefix=/Applications/Xcode_9.3.0_fb.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.1.0 (clang-902.0.39.1)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode_9.3.0_fb.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

fails to compile on newer gcc

Hi,

on newer compilers, cxx_function fails to compile.

See e.g. https://wandbox.org/permlink/9xxy5Ny6X6ZeUmxI (scroll down, to see the compile output)
(On the top left you'll find a window where you can select various gcc and clang compiler versions.
With gcc, it only works with 6.3.0 or lower...)

In file included from prog.cc:20:
cxx_function.hpp:511:39: error: 'is_nothrow_callable' is not a member of 'std'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: note: suggested alternative: 'is_nothrow_swappable'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:90: error: template argument 1 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                          ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: expected '(' before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: template argument 3 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:107: error: expected unqualified-id before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                           ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: error: 'is_nothrow_callable' is not a member of 'std'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: note: suggested alternative: 'is_nothrow_swappable'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:90: error: template argument 1 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                          ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: expected '(' before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: template argument 3 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:107: error: expected unqualified-id before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                           ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: error: 'is_nothrow_callable' is not a member of 'std'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: note: suggested alternative: 'is_nothrow_swappable'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:90: error: template argument 1 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                          ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: expected '(' before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: template argument 3 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:107: error: expected unqualified-id before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                           ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: error: 'is_nothrow_callable' is not a member of 'std'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: note: suggested alternative: 'is_nothrow_swappable'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:90: error: template argument 1 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                          ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: expected '(' before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: template argument 3 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:107: error: expected unqualified-id before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                           ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:75:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: error: 'is_nothrow_callable' is not a member of 'std'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: note: suggested alternative: 'is_nothrow_swappable'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:90: error: template argument 1 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                          ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: expected '(' before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: template argument 3 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:107: error: expected unqualified-id before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                           ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: error: 'is_nothrow_callable' is not a member of 'std'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: note: suggested alternative: 'is_nothrow_swappable'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:90: error: template argument 1 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                          ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: expected '(' before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: template argument 3 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:107: error: expected unqualified-id before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                           ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: error: 'is_nothrow_callable' is not a member of 'std'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: note: suggested alternative: 'is_nothrow_swappable'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:90: error: template argument 1 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                          ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: expected '(' before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: template argument 3 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:107: error: expected unqualified-id before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                           ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: error: 'is_nothrow_callable' is not a member of 'std'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: note: suggested alternative: 'is_nothrow_swappable'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:90: error: template argument 1 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                          ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: expected '(' before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: template argument 3 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:107: error: expected unqualified-id before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                           ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:5: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: error: 'is_nothrow_callable' is not a member of 'std'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: note: suggested alternative: 'is_nothrow_swappable'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:90: error: template argument 1 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                          ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: expected '(' before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: template argument 3 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:107: error: expected unqualified-id before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                           ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: error: 'is_nothrow_callable' is not a member of 'std'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: note: suggested alternative: 'is_nothrow_swappable'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:90: error: template argument 1 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                          ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: expected '(' before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: template argument 3 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:107: error: expected unqualified-id before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                           ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:5: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
     ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: error: 'is_nothrow_callable' is not a member of 'std'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: note: suggested alternative: 'is_nothrow_swappable'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:90: error: template argument 1 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                          ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: expected '(' before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: template argument 3 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:107: error: expected unqualified-id before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                           ^
cxx_function.hpp:66:5: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
     ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: error: 'is_nothrow_callable' is not a member of 'std'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:39: note: suggested alternative: 'is_nothrow_swappable'
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                       ^~~~~~~~~~~~~~~~~~~
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:90: error: template argument 1 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                          ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: expected '(' before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:99: error: template argument 3 is invalid
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                   ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~
cxx_function.hpp:511:107: error: expected unqualified-id before '>' token
         typename std::enable_if< std::is_nothrow_callable< t TYPE_QUALS ( arg ... ), ret >::value >::type > \
                                                                                                           ^
cxx_function.hpp:66:43: note: in expansion of macro 'NOEXCEPT_CASE'
     MACRO( TYPE_QUALS, FN_QUALS, UNSAFE ) MACRO( const TYPE_QUALS, const FN_QUALS, IGNORE )
                                           ^~~~~
cxx_function.hpp:68:56: note: in expansion of macro 'DISPATCH_CQ'
     DISPATCH_CQ( MACRO, UNSAFE, TYPE_QUALS, FN_QUALS ) DISPATCH_CQ( MACRO, IGNORE, volatile TYPE_QUALS, volatile FN_QUALS )
                                                        ^~~~~~~~~~~
cxx_function.hpp:72:60: note: in expansion of macro 'DISPATCH_CV'
     DISPATCH_CV( MACRO, IGNORE, & TYPE_QUALS, & FN_QUALS ) DISPATCH_CV( MACRO, IGNORE, && TYPE_QUALS, && FN_QUALS )
                                                            ^~~~~~~~~~~
cxx_function.hpp:75:58: note: in expansion of macro 'DISPATCH_CVREFQ'
     DISPATCH_CV( MACRO, UNSAFE, & TYPE_QUALS, FN_QUALS ) DISPATCH_CVREFQ( MACRO, TYPE_QUALS, FN_QUALS )
                                                          ^~~~~~~~~~~~~~~
cxx_function.hpp:513:5: note: in expansion of macro 'DISPATCH_CVOBJQ'
     DISPATCH_CVOBJQ( NOEXCEPT_CASE, IGNORE, , )
     ^~~~~~~~~~~~~~~

Continuous integration testing on GCC and Clang

Currently this project runs AppVeyor CI checking MSVC compatibility. My laptop has GCC 5.1 and Clang 3.6 which are quite old. Everything else is checked ad-hoc on an online compiler. It would be nice to test many compiler + version + standard library + language flag combinations using a proper CI service.

One thing that was significant in 2015 (when I created this) was that Linux used the GCC library even with Clang. If that's still the case, then mind the coverage.

Clang compilation error.

Compiling the cxx_function.hpp with clang++ 3.7.0 and gcc 5.2.0's libstdc++ produces an error:

/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/uses_allocator.h:49:31: error: 'allocator_type' is a protected member of 'cxx_function::impl::wrapper_no_allocator'
                                   __void_t<typename _Tp::allocator_type>>

Making this typedef public fixes the error, and makes cxx_function usable with clang.

memcpy object with no trivial copy-assignment

Hi,

I'm encountering the following error with gcc 8.1:

cxx_function.hpp:626:24: warning: 'void* memcpy(void*, const void*, size_t)' writing to an object of type 'struct cxx_function::impl::erasure_base' with no trivial copy-assignment; use copy-initialization instead [-Wclass-memaccess]
std::memcpy( & this->erasure(), & s.erasure(), sizeof (storage) );

Is this spurious?

Trivialize moving of std::allocator targets

libc++'s move constructor avoids the indirect call for allocated targets.

This library doesn't because of support for fancy pointers and nontrivial allocator destructors. The wrapper should be able to handle moves, absent those corner cases.

The behavior could be selected by a new vtable slot, or something besides a valid function pointer or nullptr in the move_constructor_destructor slot.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.