diff --git a/README.md b/README.md index 6ce7237..0a8d261 100644 --- a/README.md +++ b/README.md @@ -12,192 +12,10 @@ Distributed under the Boost Software License, Version 1.0. ![Try it online][badge.wandbox] -CallableTraits is a small, header-only library providing a uniform and comprehensive interface for the type-level manipulation of all callable types in C++. CallableTraits does all the dirty work for you (see an `std::is_function` [implementation ](http://en.cppreference.com/w/cpp/types/is_function#Possible_implementation) for a glimpse of the "dirty work"). +CallableTraits is a small, header-only library providing a uniform and comprehensive interface for the type-level manipulation of all callable types in C++. -This project is nearing completion. Lack of documentation and spotty code quality are the most glaring issues right now, but progress is being made on both fronts. Test coverage is not 100% yet, but we'll be there soon. +## Documentation [Here](http://badair.github.io/callable_traits/index.html) -## Overview - - -```cpp - -#include -#include -#include -#include - -// Most of this example uses a function object. Unless otherwise noted, all -// features shown in this example can be used for any "callable" types: -// lambdas, generic lambdas, function pointers, function references, -// function types, abominable function types, member function pointers, and -// member data pointers. Ambiguous callables (e.g. function objects with -// templated/overloaded operator()) are not addressed in this example, but -// are recognized and handled by CallableTraits. - -// Note: For more information about abominable function types, see Alisdair Meredith's -// proposal at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0172r0.html - -struct foo { - void operator()(int, int&&, const int&, void* = nullptr) const {} -}; - -namespace ct = callable_traits; -using namespace std::placeholders; - -int main() { - - // indexed argument types - using second_arg = ct::arg_at<1, foo>; - static_assert(std::is_same{}, ""); - - // arg types are packaged into std::tuple, which serves as the default - // type list in CallableTraits (runtime capabilities are not used). - using args = ct::args; - using expected_args = std::tuple; - static_assert(std::is_same{}, ""); - - //callable_traits::result_of is a bit friendlier than std::result_of - using return_type = ct::result_of; - static_assert(std::is_same{}, ""); - - // callable_traits::signature yields a plain function type - using signature = ct::signature; - using expected_signature = void(int, int&&, const int&, void*); - static_assert(std::is_same{}, ""); - - // when trait information can be conveyed in an integral_constant, - // callable_traits uses constexpr functions instead of template aliases. - // Note: min_arity and max_arity only differ logically from arity when - // the argument is a function object. - static_assert(ct::arity(foo{}) == 4, ""); - static_assert(ct::max_arity(foo{}) == 4, ""); - static_assert(ct::min_arity(foo{}) == 3, ""); - - // CallableTraits provides constexpr functions so that the user doesn't - // need to worry about reference collapsing or decltype when dealing with - // universal references to callables. Still, you don't need an instance, - // because CallableTraits provides non-deduced function templates for - // all constexpr functions besides can_invoke and bind_expr, which - // model std::invoke and std::bind, respectively (more on these below). - // Here's an example of the non-deduced functions, which take an explicit - // type argument. We'll ignore these for the rest of the example. - static_assert(ct::arity() == 4, ""); - static_assert(ct::max_arity() == 4, ""); - static_assert(ct::min_arity() == 3, ""); - - // C-style varargs (ellipses in a signature) can be detected. - static_assert(!ct::has_varargs(foo{}), ""); - - // callable_traits::is_ambiguous yields std::true_type - // only when the callable is overloaded or templated. - static_assert(!ct::is_ambiguous(foo{}), ""); - - // callable_traits::can_invoke allows us to preview whether - // std::invoke will compile with the given arguments. Keep - // in mind that failing cases must be SFINAE-friendly (i.e. - // any failing static_asserts can still be tripped). Note: The - // same sfinae restrictions apply to min_arity and max_arity - // for function objects. - int i = 0; - static_assert(ct::can_invoke(foo{}, 0, 0, i), ""); - // no error: std::invoke(foo{}, 0, 0, i); - - static_assert(!ct::can_invoke(foo{}, nullptr), ""); - // error: std::invoke(foo{}, nullptr); - - // callable_traits::bind_expr is a compile-time bind expression parser, - // very loosely based on the Boost.Bind implementation. Nested bind - // expressions are fully supported. The return type of bind_expr only - // contains type information, but can still be used in an evaluated - // context. The return type can be treated like a callable type when passed - // to result_of, signature, args, or arg_at template aliases. - using bind_expression = decltype(ct::bind_expr(foo{}, _1, _1, _1)); - - // Unfortunately, we can't do type manipulations with std::bind directly, - // because the ISO C++ standard says very little about the return type of - // std::bind. The purpose of callable_traits::bind_expr is to undo some of - // the arbitrary black-boxing that std::bind incurs. - auto bind_obj = std::bind(foo{}, _1, _1, _1); - - // Here, int is chosen as the expected argument for the bind expression - // because it's the best fit for all three placeholder slots. Behind - // the scenes, this is determined by a cartesian product of conversion - // combinations of the known parameter types represented by the reused - // placeholders (yes, this is slow). The type with the highest number of - // successful conversions "wins". int is chosen over int&& because - // non-reference types are preferred in the case of a tie. - static_assert(std::is_same< - ct::args, - std::tuple - >{}, ""); - - // callable_traits can facilitate the construction of std::function objects. - auto fn = std::function>{ bind_obj }; - fn(0); - - // For function objects, the following checks are determined by the - // qualifiers on operator(), rather than the category of the passed value. - // For member function pointers and abominable function types, the - // qualifier on the function type are used. - static_assert(ct::is_const_qualified(foo{}), ""); - static_assert(!ct::is_volatile_qualified(foo{}), ""); - static_assert(!ct::is_reference_qualified(foo{}), ""); - static_assert(!ct::is_lvalue_reference_qualified(foo{}), ""); - static_assert(!ct::is_rvalue_reference_qualified(foo{}), ""); - - - - // If you find yourself in the unfortunate situation of needing - // to manipulate member function pointer types, CallableTraits - // has all the tools you need to maintain your sanity. - - - - using pmf = decltype(&foo::operator()); - - { - // So that you don't have to scroll back up to see, here's the type of pmf: - using expected_pmf = void (foo::*)(int, int&&, const int&, void*) const; - static_assert(std::is_same{}, ""); - } - - { - // Let's remove the const qualifier: - using mutable_pmf = ct::remove_const_qualifier; - using expected_pmf = void (foo::*)(int, int&&, const int&, void*) /*no const!*/; - static_assert(std::is_same{}, ""); - } - - { - // Now let's add an rvalue qualifier (&&): - using rvalue_pmf = ct::add_rvalue_qualifier; - using expected_pmf = void (foo::*)(int, int&&, const int&, void*) const &&; - static_assert(std::is_same{}, ""); // ^^^^ - } - - // You get the picture. CallableTraits lets you add and remove all PMF - // qualifiers (const, volatile, &, &&, and any combination thereof). - // These type operations can be performed on abominable function types as well. - - - // Somehow, somewhere, there was a sad programmer who wanted to - // manipulate c-style varargs in a function signature. There's - // really no way to do this universally without doing all the work - // that CallableTraits already does, so CallableTraits includes in - // an add/remove feature for this, too. - { - - using varargs_pmf = ct::add_varargs; - using expected_pmf = void (foo::*)(int, int&&, const int&, void*, ...) const; - static_assert(std::is_same{}, ""); // ^^^ - - // note: MSVC likely requires __cdecl for a varargs PMF on your - // machine, at least if you intend to do anything useful with it. - } - - return 0; -} -``` ## Compatibility CallableTraits is currently tested and working on the following platforms, unless otherwise noted: @@ -214,10 +32,6 @@ CallableTraits is currently tested and working on the following platforms, unles I do not know the compatibility of CallableTraits for other/older compilers, but the `stdlib` implementation must include `std::index_sequence` and friends. -## Dependencies - -CallableTraits does not use Boost or any other libraries outside of the standard headers. However, much credit is due to Boost.Hana for the type sorting algorithm borrowed here, and to Boost.Bind for getting me started on the bind expression parts. - ## Building the tests and examples First, you'll need a recent version of [CMake](https://cmake.org/). These commands assume that `git` and `cmake` are available in your environment path. If you need help with this, [message me on Gitter](https://gitter.im/badair/callable_traits). diff --git a/doc/html/boost.png b/boost.png similarity index 100% rename from doc/html/boost.png rename to boost.png diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 2863840..4dd6f62 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -1,20 +1,53 @@ -# Copyright Peder Holt 2005. -# Copyright Modified Work Barrett Adair 2016. -# Use, modification, and distribution are -# subject to the Boost Software License, Version 1.0. (See accompanying +# Copyright 2010 Tim Blechmann +# Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -using quickbook ; +#import doxygen ; +import quickbook ; + +#doxygen autodoc +# : +#this [ glob ../../../boost/callable_traits/*.hpp ] +#or this [ glob ../include/callable_traits/*.hpp ] +# : +# #EXTRACT_ALL=YES +# "PREDEFINED=\"BOOST_DOXYGEN_INVOKED\" \\ +# " +# HIDE_UNDOC_MEMBERS=YES +# HIDE_UNDOC_CLASSES=YES +# INLINE_INHERITED_MEMB=YES +# EXTRACT_PRIVATE=NO +# ENABLE_PREPROCESSING=YES +# MACRO_EXPANSION=YES +# EXPAND_ONLY_PREDEF=YES +# SEARCH_INCLUDES=YES +# INCLUDE_PATH=$(BOOST_ROOT)/libs/callable_traits/include +# EXAMPLE_PATH=$(BOOST_ROOT)/libs/callable_traits/example +# BRIEF_MEMBER_DESC=YES +# REPEAT_BRIEF=YES +# ALWAYS_DETAILED_SEC=YES +# MULTILINE_CPP_IS_BRIEF=YES +# ; + +xml callable_traits : callable_traits.qbk : ; -xml callable_traits : callable_traits.qbk ; boostbook standalone - : - callable_traits - : - boost.root=../../../.. - nav.layout=none - navig.graphics=0 + : callable_traits + : html.stylesheet=boostbook.css + boost.root=../../../.. + boost.libraries=../../../libraries.htm +# toc.max.depth=3 +# toc.section.depth=1 +# chunk.section.depth=1 +# autodoc + pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/libs/callable_traits/doc/html ; -install html : ../../../doc/src/boostbook.css ; -install ../ : ../../../boost.png ; \ No newline at end of file +install html : boostbook.css ; +install ../ : boost.png ; +install css : [ glob $(BOOST_ROOT)/doc/src/*.css ] + : html ; +install images : [ glob $(BOOST_ROOT)/doc/src/images/*.png ] + : html/images ; +explicit css ; +explicit images ; diff --git a/doc/autodoc.xml b/doc/autodoc.xml new file mode 100644 index 0000000..69f8bfe --- /dev/null +++ b/doc/autodoc.xml @@ -0,0 +1,1283 @@ + +
+ +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +typename std::tuple_element< I, args< T >>::type + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +constexpr autoT && +constexpr auto + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + +constexpr autoT &&Args &&... + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + +constexpr autoArgs &&... + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + + +constexpr autoArgs &&... + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + + + +constexpr autoT && +constexpr auto + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + + + + + +constexpr autoT && +constexpr auto + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + + + + + + + + + +constexpr auto +constexpr autoT && + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + + + + + + + +constexpr autoT && +constexpr auto + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + + + + + + + + + + + +constexpr auto +constexpr autoT && + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + + + + + + + + + + + + + +constexpr auto +constexpr autoT && + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + + + + + + + + + + + + + + + +constexpr auto +constexpr autoT && + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + + + + + + + + + + + + + + + + + +constexpr auto +constexpr autoT && + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + + + + + + + + + + + + + + + + + + + +constexpr auto +constexpr autoT && + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + + + + + + + + + + + + + + + + + + + + + +constexpr auto +constexpr autoT && + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + + + + + + + + + + + + + + + + + + + + + + + +constexpr autoT && +constexpr auto + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + + + + + + + + + + + + + + + + + + + + + + + + + + + + +constexpr autoT && +constexpr auto + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +unspecified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/doc/boost.png b/doc/boost.png new file mode 100644 index 0000000..b4d51fc Binary files /dev/null and b/doc/boost.png differ diff --git a/doc/boostbook.css b/doc/boostbook.css new file mode 100644 index 0000000..28f8935 --- /dev/null +++ b/doc/boostbook.css @@ -0,0 +1,716 @@ + +/*============================================================================= +Copyright (c) 2004 Joel de Guzman +http://spirit.sourceforge.net/ + +Copyright 2013 Niall Douglas additions for colors and alignment. +Copyright 2013 Paul A. Bristow additions for more colors and alignments. + +Distributed under the Boost Software License, Version 1.0. (See accompany- +ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +/*============================================================================= +Body defaults +=============================================================================*/ + + body + { + margin: 1em; + font-family: sans-serif; + } + +/*============================================================================= +Paragraphs +=============================================================================*/ + + p + { + text-align: left; + font-size: 10pt; + line-height: 1.15; + } + +/*============================================================================= +Program listings +=============================================================================*/ + + /* Code on paragraphs */ + p tt.computeroutput + { + font-size: 9pt; + } + + pre.synopsis + { + font-size: 9pt; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + .programlisting, + .screen + { + font-size: 9pt; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + /* Program listings in tables don't get borders */ + td .programlisting, + td .screen + { + margin: 0pc 0pc 0pc 0pc; + padding: 0pc 0pc 0pc 0pc; + } + +/*============================================================================= +Headings +=============================================================================*/ + + h1, h2, h3, h4, h5, h6 + { + text-align: left; + margin: 1em 0em 0.5em 0em; + font-weight: bold; + } + + h1 { font-size: 140%; } + h2 { font-weight: bold; font-size: 140%; } + h3 { font-weight: bold; font-size: 130%; } + h4 { font-weight: bold; font-size: 120%; } + h5 { font-weight: normal; font-style: italic; font-size: 110%; } + h6 { font-weight: normal; font-style: italic; font-size: 100%; } + + /* Top page titles */ + title, + h1.title, + h2.title + h3.title, + h4.title, + h5.title, + h6.title, + .refentrytitle + { + font-weight: bold; + margin-bottom: 1pc; + } + + h1.title { font-size: 140% } + h2.title { font-size: 140% } + h3.title { font-size: 130% } + h4.title { font-size: 120% } + h5.title { font-size: 110% } + h6.title { font-size: 100% } + + .section h1 + { + margin: 0em 0em 0.5em 0em; + font-size: 140%; + } + + .section h2 { font-size: 140% } + .section h3 { font-size: 130% } + .section h4 { font-size: 120% } + .section h5 { font-size: 110% } + .section h6 { font-size: 100% } + + /* Code on titles */ + h1 tt.computeroutput { font-size: 140% } + h2 tt.computeroutput { font-size: 140% } + h3 tt.computeroutput { font-size: 130% } + h4 tt.computeroutput { font-size: 130% } + h5 tt.computeroutput { font-size: 130% } + h6 tt.computeroutput { font-size: 130% } + + +/*============================================================================= +Author +=============================================================================*/ + + h3.author + { + font-size: 100% + } + +/*============================================================================= +Lists +=============================================================================*/ + + li + { + font-size: 10pt; + line-height: 1.3; + } + + /* Unordered lists */ + ul + { + text-align: left; + } + + /* Ordered lists */ + ol + { + text-align: left; + } + +/*============================================================================= +Links +=============================================================================*/ + + a + { + text-decoration: none; /* no underline */ + } + + a:hover + { + text-decoration: underline; + } + +/*============================================================================= +Spirit style navigation +=============================================================================*/ + + .spirit-nav + { + text-align: right; + } + + .spirit-nav a + { + color: white; + padding-left: 0.5em; + } + + .spirit-nav img + { + border-width: 0px; + } + +/*============================================================================= +Copyright footer +=============================================================================*/ + .copyright-footer + { + text-align: right; + font-size: 70%; + } + + .copyright-footer p + { + text-align: right; + font-size: 80%; + } + +/*============================================================================= +Table of contents +=============================================================================*/ + + div.toc + { + margin: 1pc 4% 0pc 4%; + padding: 0.1pc 1pc 0.1pc 1pc; + font-size: 80%; + line-height: 1.15; + } + + .boost-toc + { + float: right; + padding: 0.5pc; + } + + /* Code on toc */ + .toc .computeroutput { font-size: 120% } + + /* No margin on nested menus */ + + .toc dl dl { margin: 0; } + +/*============================================================================= +Tables +=============================================================================*/ + + .table-title, + div.table p.title + { + margin-left: 4%; + padding-right: 0.5em; + padding-left: 0.5em; + } + + .informaltable table, + .table table + { + width: 92%; + margin-left: 4%; + margin-right: 4%; + } + + div.informaltable table, + div.table table + { + padding: 4px; + } + + /* Table Cells */ + div.informaltable table tr td, + div.table table tr td + { + padding: 0.5em; + text-align: left; + font-size: 9pt; + } + + div.informaltable table tr th, + div.table table tr th + { + padding: 0.5em 0.5em 0.5em 0.5em; + border: 1pt solid white; + font-size: 80%; + } + + table.simplelist + { + width: auto !important; + margin: 0em !important; + padding: 0em !important; + border: none !important; + } + table.simplelist td + { + margin: 0em !important; + padding: 0em !important; + text-align: left !important; + font-size: 9pt !important; + border: none !important; + } + +/*============================================================================= +Suppress margins in tables +=============================================================================*/ + + table th > *:first-child, + table td > *:first-child + { + margin-top: 0; + } + + table th > *:last-child, + table td > *:last-child + { + margin-bottom: 0; + } + +/*============================================================================= +Blurbs +=============================================================================*/ + + div.note, + div.tip, + div.important, + div.caution, + div.warning, + p.blurb + { + font-size: 9pt; /* A little bit smaller than the main text */ + line-height: 1.2; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + p.blurb img + { + padding: 1pt; + } + +/*============================================================================= +Variable Lists +=============================================================================*/ + + div.variablelist + { + margin: 1em 0; + } + + /* Make the terms in definition lists bold */ + div.variablelist dl dt, + span.term + { + font-weight: bold; + font-size: 10pt; + } + + div.variablelist table tbody tr td + { + text-align: left; + vertical-align: top; + padding: 0em 2em 0em 0em; + font-size: 10pt; + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + + div.variablelist dl dt + { + margin-bottom: 0.2em; + } + + div.variablelist dl dd + { + margin: 0em 0em 0.5em 2em; + font-size: 10pt; + } + + div.variablelist table tbody tr td p, + div.variablelist dl dd p + { + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + +/*============================================================================= +Misc +=============================================================================*/ + + /* Title of books and articles in bibliographies */ + span.title + { + font-style: italic; + } + + span.underline + { + text-decoration: underline; + } + + span.strikethrough + { + text-decoration: line-through; + } + + /* Copyright, Legal Notice */ + div div.legalnotice p + { + text-align: left + } + +/*============================================================================= +Colors +=============================================================================*/ + + @media screen + { + body { + background-color: #FFFFFF; + color: #000000; + } + + /* Syntax Highlighting */ + .keyword { color: #0000AA; } + .identifier { color: #000000; } + .special { color: #707070; } + .preprocessor { color: #402080; } + .char { color: teal; } + .comment { color: #800000; } + .string { color: teal; } + .number { color: teal; } + .white_bkd { background-color: #FFFFFF; } + .dk_grey_bkd { background-color: #999999; } + + /* Links */ + a, a .keyword, a .identifier, a .special, a .preprocessor + a .char, a .comment, a .string, a .number + { + color: #005a9c; + } + + a:visited, a:visited .keyword, a:visited .identifier, + a:visited .special, a:visited .preprocessor a:visited .char, + a:visited .comment, a:visited .string, a:visited .number + { + color: #9c5a9c; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, + h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, + h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited + { + text-decoration: none; /* no underline */ + color: #000000; + } + + /* Copyright, Legal Notice */ + .copyright + { + color: #666666; + font-size: small; + } + + div div.legalnotice p + { + color: #666666; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid #DCDCDC; + } + + .programlisting, + .screen + { + border: 1px solid #DCDCDC; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Blurbs */ + div.note, + div.tip, + div.important, + div.caution, + div.warning, + p.blurb + { + border: 1px solid #DCDCDC; + } + + /* Table of contents */ + div.toc + { + border: 1px solid #DCDCDC; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid #DCDCDC; + } + + div.informaltable table tr th, + div.table table tr th + { + background-color: #F0F0F0; + border: 1px solid #DCDCDC; + } + + .copyright-footer + { + color: #8F8F8F; + } + + /* Misc */ + span.highlight + { + color: #00A000; + } + } + + @media print + { + /* Links */ + a + { + color: black; + } + + a:visited + { + color: black; + } + + .spirit-nav + { + display: none; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid gray; + } + + .programlisting, + .screen + { + border: 1px solid gray; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Table of contents */ + div.toc + { + border: 1px solid gray; + } + + .informaltable table, + .table table + { + border: 1px solid gray; + border-collapse: collapse; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid gray; + } + + div.informaltable table tr th, + div.table table tr th + { + border: 1px solid gray; + } + + table.simplelist tr td + { + border: none !important; + } + + /* Misc */ + span.highlight + { + font-weight: bold; + } + } + +/*============================================================================= +Images +=============================================================================*/ + + span.inlinemediaobject img + { + vertical-align: middle; + } + +/*============================================================================== +Super and Subscript: style so that line spacing isn't effected, see +http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=1&postId=5341 +==============================================================================*/ + +sup, +sub { +height: 0; +line-height: 1; +vertical-align: baseline; +position: relative; + +} + +/* For internet explorer: */ + +* html sup, +* html sub { +vertical-align: bottom; +} + +sup { +bottom: 1ex; +} + +sub { +top: .5ex; +} + +/*============================================================================== +Indexes: pretty much the same as the TOC. +==============================================================================*/ + + .index + { + font-size: 80%; + padding-top: 0px; + padding-bottom: 0px; + margin-top: 0px; + margin-bottom: 0px; + margin-left: 0px; + } + + .index ul + { + padding-left: 3em; + } + + .index p + { + padding: 2px; + margin: 2px; + } + + .index-entry-level-0 + { + font-weight: bold; + } + + .index em + { + font-weight: bold; + } + + +/*============================================================================== +Alignment and coloring use 'role' feature, available from Quickbook 1.6 up. +Added from Niall Douglas for role color and alignment. +http://article.gmane.org/gmane.comp.lib.boost.devel/243318 +*/ + +/* Add text alignment (see http://www.w3schools.com/cssref/pr_text_text-align.asp) */ +span.aligncenter +{ + display: inline-block; width: 100%; text-align: center; +} +span.alignright +{ + display: inline-block; width: 100%; text-align: right; +} +/* alignleft is the default. */ +span.alignleft +{ + display: inline-block; width: 100%; text-align: left; +} + +/* alignjustify stretches the word spacing so that each line has equal width +within a chosen fraction of page width (here arbitrarily 20%). +*Not* useful inside table items as the column width remains the total string width. +Nor very useful, except to temporarily restrict the width. +*/ +span.alignjustify +{ + display: inline-block; width: 20%; text-align: justify; +} + +/* Text colors. +Names at http://www.w3.org/TR/2002/WD-css3-color-20020219/ 4.3. X11 color keywords. +Quickbook Usage: [role red Some red text] + +*/ +span.red { inline-block; color: red; } +span.green { color: green; } +span.lime { color: #00FF00; } +span.blue { color: blue; } +span.navy { color: navy; } +span.yellow { color: yellow; } +span.magenta { color: magenta; } +span.indigo { color: #4B0082; } +span.cyan { color: cyan; } +span.purple { color: purple; } +span.gold { color: gold; } +span.silver { color: silver; } /* lighter gray */ +span.gray { color: #808080; } /* light gray */ diff --git a/doc/callable_traits.qbk b/doc/callable_traits.qbk index 62e518d..f6a494a 100644 --- a/doc/callable_traits.qbk +++ b/doc/callable_traits.qbk @@ -13,126 +13,13 @@ [lang en] ] +[template library_name[][^CallableTraits]] +[template header_include_prefix[]callable_traits/] [section:introduction Introduction] +[heading Quick Example] +[import ../example/intro.cpp] +[intro] -[section:basic_example Basic Example] - - #include - #include - #include - #include - - struct foo { - void operator()(int, int&&, const int&, void* = nullptr) const {} - }; - - namespace ct = callable_traits; - using namespace std::placeholders; - - int main() { - - // indexed argument types - using second_arg = ct::arg_at<1, foo>; - static_assert(std::is_same::value, ""); - - // arg types are packaged into std::tuple, which serves as the default - // type list in CallableTraits (runtime capabilities are not used). - using args = ct::args; - using expected_args = std::tuple; - static_assert(std::is_same::value, ""); - - //callable_traits::result_of is a bit friendlier than std::result_of - using return_type = ct::result_of; - static_assert(std::is_same::value, ""); - - //has_void_return is a quicker way to perform the check above - static_assert(ct::has_void_return(foo{}), ""); - - // callable_traits::function_type decays a callable type to - // a plain function type, which is structured in terms of INVOKE - using function_type = ct::function_type; - using expected_function_type = void(int, int&&, const int&, void*); - static_assert(std::is_same::value, ""); - - // when trait information can be conveyed in an std::integral_constant, - // callable_traits opts for constexpr functions instead of template aliases. - // This is done to encourage value semantics, and to simplify usage inside - // of forwarding functions. - static_assert(ct::arity(foo{}) == 4, ""); - static_assert(ct::max_arity(foo{}) == 4, ""); - static_assert(ct::min_arity(foo{}) == 3, ""); - - // CallableTraits provides constexpr functions so that the user doesn't - // need to worry about reference collapsing or decltype when dealing with - // universal references to callables. Still, you don't NEED an instance, - // because CallableTraits provides non-deduced function templates for - // all constexpr functions (except for can_invoke/can_invoke_constexpr and bind, - // which model std::invoke and std::bind, respectively -- more on these below). - // Here's an example of the non-deduced version of arity, which take an - // explicit type argument. We'll ignore these non-deduced overloads for the - // rest of this example. - static_assert(ct::arity() == 4, ""); - - // C-style variadics detection (ellipses in a signature) - static_assert(!ct::has_varargs(foo{}), ""); - - int i = 0; - - // callable_traits::can_invoke allows us to preview whether std::invoke will - // compile with the given arguments. - static_assert(ct::can_invoke(foo{}, 0, 0, i), ""); - // no error: std::invoke(foo{}, 0, 0, i); - - static_assert(!ct::can_invoke(foo{}, nullptr), ""); - // error: std::invoke(foo{}, nullptr); - - // For function objects, the following checks are determined by the - // qualifiers on operator(), rather than the category of the passed value. - // For member function pointers and abominable function types, the - // qualifiers on the function type are used. - static_assert(ct::is_const_qualified(foo{}), ""); - static_assert(!ct::is_volatile_qualified(foo{}), ""); - static_assert(!ct::is_reference_qualified(foo{}), ""); - static_assert(!ct::is_lvalue_qualified(foo{}), ""); - static_assert(!ct::is_rvalue_qualified(foo{}), ""); - - - // If you find yourself in the unfortunate situation of needing - // to manipulate member function pointer types, CallableTraits - // has all the tools you need to maintain your sanity. - - - using pmf = decltype(&foo::operator()); - - // So that you don't have to scroll back up to see, here's the type of pmf: - using with_const = void (foo::*)(int, int&&, const int&, void*) const; - static_assert(std::is_same::value, ""); - - // Let's remove the const qualifier: - using mutable_pmf = ct::remove_const_qualifier; - using without_const = void (foo::*)(int, int&&, const int&, void*) /*no const!*/; - static_assert(std::is_same::value, ""); - - // Now let's add an rvalue qualifier (&&): - using rvalue_pmf = ct::add_rvalue_qualifier; - using with_rvalue = void (foo::*)(int, int&&, const int&, void*) const &&; - static_assert(std::is_same::value, ""); - - // You get the picture. CallableTraits lets you add and remove all PMF - // qualifiers (const, volatile, &, &&, and any combination thereof). - // These type operations can generally be performed on abominable function - // types as well. - - // is_constexpr would return std::true_type if foo's operator() were constexpr. - static_assert(!ct::is_constexpr(foo{}), ""); - - // to check constexprness of a function or member function, you must use an - // std::integral_constant, like this: - using pmf_constant = std::integral_constant; - static_assert(!ct::is_constexpr(pmf_constant{}), ""); - } - -[endsect] [section:motivation Motivation] The complexity of callable types in C++ is extensive: @@ -150,26 +37,26 @@ The complexity of callable types in C++ is extensive: *calling conventions (`__cdecl`, `__stdcall`, `__fastcall`, `pascal`, etc.) *`noexcept` ([@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0012r1.html part of the function type system in C++17]) -CallableTraits provides a comprehensive, uniform, and modern type-level interface for the manipulation and inspection of callable types in C++. By filling the gaps where existing library solutions fall short, CallableTraits aims to provide such an exhaustive interface for the features listed above that library writers will *never again* need to specialize templates for callable types. CallableTraits eliminates the need for horrific template specializations like these: +[library_name] provides a comprehensive, uniform, and modern type-level interface for the manipulation and inspection of callable types in C++. By filling the gaps where existing library solutions fall short, [library_name] aims to provide such an exhaustive interface for the features listed above that library writers will *never again* need to specialize templates for callable types. [library_name] eliminates the need for horrific template specializations like these: template - struct foo{ - //... - }; + struct foo{ + //... + }; -Several library solutions exist to manipulate these types, or to abstract away their complexities. However, these solutions are occasionally inflexible or lacking in features, especially regarding function objects/lambdas. In CallableTraits, function pointers, function references, function types, abominable function types, member function pointers, member data pointers, function objects/lambdas, and references/pointers/smart pointers thereof are generally interchangeable. +Several library solutions exist to manipulate these types, or to abstract away their complexities. However, these solutions are occasionally inflexible or lacking in features, especially regarding function objects/lambdas. In [library_name], function pointers, function references, function types, abominable function types, member function pointers, member data pointers, function objects/lambdas, and references/pointers/smart pointers thereof are generally interchangeable. -The use cases for CallableTraits are closely related to those of [@http://www.boost.org/doc/libs/1_60_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html function_traits] and [@http://www.boost.org/doc/libs/1_60_0/libs/function_types/doc/html/index.html FunctionTypes]. +The use cases for [library_name] are closely related to those of [@http://www.boost.org/doc/libs/1_60_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html function_traits] and [@http://www.boost.org/doc/libs/1_60_0/libs/function_types/doc/html/index.html FunctionTypes]. -[important CallableTraits currently offers no interface for the manipulation of calling conventions. Also, no features are currently implemented to account for C++17's `noexcept`. These features are planned for future versions on supported platforms.] +[important [library_name] currently offers no interface for the manipulation of calling conventions. Also, no features are currently implemented to account for C++17's `noexcept`. These features are planned for future versions on supported platforms.] [endsect] -[section:ten_reasons 10 reasons to use CallableTraits] +[section:ten_reasons 10 reasons to use [library_name]] -# CallableTraits' template aliases and `constexpr` `std::integral_constant` functions are preferable to `typename foo::type` and `foo::value` +# [library_name]' template aliases and `constexpr` `std::integral_constant` functions are preferable to `typename foo::type` and `foo::value` -# CallableTraits offers a familar, consistent interface for the synthesis and decomposition of callable types +# [library_name] offers a familar, consistent interface for the synthesis and decomposition of callable types * e.g. `remove_const_qualifier` parallels `std::remove_const` # universal references are accepted everywhere, so you don't need to worry about using `std::remove_reference` first @@ -178,7 +65,7 @@ The use cases for CallableTraits are closely related to those of [@http://www.bo # `arg_at<2, Callable>` is better than `typename function_traits::arg2_type` -# function objects are first-class citizens in CallableTraits +# function objects are first-class citizens in [library_name] * e.g. `result_of` can accept a function object # `is_constexpr` lets you check whether a function, member function, or function object is `constexpr` @@ -193,414 +80,346 @@ The use cases for CallableTraits are closely related to those of [@http://www.bo [section:function_sugar Use case: `std::function` sugar] -At the time of this writing, there are 260 [@http://stackoverflow.com/search?q=convert+std%3A%3Abind+to+std%3A%3Afunction search results] on Stack Overflow concerning the conversion from `std::bind` to `std::function`. There are 336 [@http://stackoverflow.com/search?q=convert+lambda+to+std%3A%3Afunction search results] concerning the conversion of lambdas to `std::function`. With this example, we'll kill both birds with the same stone. The `make_function` function defined below will leverage CallableTraits to... +At the time of this writing, there are 260 [@http://stackoverflow.com/search?q=convert+std%3A%3Abind+to+std%3A%3Afunction search results] on Stack Overflow concerning the conversion from `std::bind` to `std::function`. There are 336 [@http://stackoverflow.com/search?q=convert+lambda+to+std%3A%3Afunction search results] concerning the conversion of lambdas to `std::function`. With this example, we'll kill both birds with the same stone. The `make_function` function defined below will leverage [library_name] to... # Create an `std::function` where T is not explicitly supplied by the user # Create an `std::function` where T is the deduced "signature" of an `std::placeholders` expression. Without real-world context, `make_function` may seem rather silly to those who know the runtime costs of type erasure. However, whenever `std::function` is required by some 3rd party API, this example might make a bit more sense. - #include - #include - - namespace example_library { - - namespace ct = callable_traits; - - //`make_function` turns a non-overloaded callable into a type-erased std::function object - template - inline decltype(auto) make_function(T&& t) { - - // callable_traits::function_type decays any non-overloaded callable type to - // a plain function type, which is structured in terms of INVOKE. - - using signature = ct::function_type; - using result_type = std::function; - return result_type{ std::forward(t) }; - } - - //this `make_function` overload turns a bind expression into a type-erased std::function object - template - inline decltype(auto) make_function(T&& t, First&& first, Others&&... others) { - - // callable_traits::bind is essentially a compile-time parser of placeholders - // expressions, for the purpose of retaining more type information than - // std::bind normally allows - specifically, callable_traits::bind is used to - // determine the de-facto signature of the std::bind return type, with special - // considerations for conversions between reused placeholders and nested - // placeholder expressions. For the sake of convenience, callable_traits::bind - // is also a thin forwarding wrapper around std::bind (which is the only true - // runtime element in CallableTraits). - - using bind_expr = decltype(ct::bind( - std::forward(t), - std::forward(first), - std::forward(others)... - )); - - using signature = ct::function_type; - using result_type = std::function; - - return result_type{ std::bind( - std::forward(t), - std::forward(first), - std::forward(others)... - )}; - } - } - - //client code starts here - #include - - using namespace example_library; - using namespace std::placeholders; - - int add(int i, int j) { - return i + j; - } - - struct adder { - - int eval(int i, int j) const { - return i + j; - } - }; - - int main() { - - //function pointer - auto f = make_function(&add); - assert(f(99, 1) == 100); - - //function reference - f = make_function(add); - assert(f(99, 1) == 100); - - //member function pointer (bound to object) - f = make_function(&adder::eval, adder{}, _1, _2); - assert(f(99, 1) == 100); - - //lambda - f = make_function([](int i, int j) { - return i + j; - }); - - assert(f(99, 1) == 100); - } +[import ../example/make_function.cpp] +[make_function] [endsect] [endsect] -[section:reference Reference] - -CallableTraits contains the following type traits and metafunctions (psuedo-code): - -[*`std::integral_constant` constexpr functions] - -* `can_invoke(T&&, Args&&...)` -* `can_invoke_constexpr(T&&, Args&&...)` -* `is_constexpr(T&&)` -* `is_constexpr()` -* `has_varargs(T&&)` -* `has_varargs()` -* `has_void_return(T&&)` -* `has_void_return()` -* `arity(T&&)` -* `arity()` -* `min_arity(T&&)` -* `min_arity()` -* `max_arity(T&&)` -* `max_arity()` -* `is_unqualified(T&&)` -* `is_unqualified()` -* `is_const_qualified(T&&)` -* `is_const_qualified()` -* `is_volatile_qualified(T&&)` -* `is_volatile_qualified()` -* `is_cv_qualified(T&&)` -* `is_cv_qualified()` -* `is_reference_qualified(T&&)` -* `is_reference_qualified()` -* `is_lvalue_qualified(T&&)` -* `is_lvalue_qualified()` -* `is_rvalue_qualified(T&&)` -* `is_rvalue_qualified()` - -[*Template aliases] - -* `args` -* `arg_at` -* `function_type` -* `qualified_function_type` -* `result_of` -* `apply_return` -* `apply_member_pointer` -* `remove_member_pointer` -* `add_const_qualifier` -* `remove_const_qualifier` -* `add_volatile_qualifier` -* `remove_volatile_qualifier` -* `add_cv_qualifiers` -* `remove_cv_qualifiers` -* `add_lvalue_qualifier` -* `add_rvalue_qualifier` -* `remove_reference_qualifiers` -* `add_varargs` -* `remove_varargs` - -[*Other] - -* `bind(T&&, Args&&...)` - +[template ct_open_include[] `#include<`[^[header_include_prefix]]] +[template ct_close_include[]`.hpp>`] +[template include_header[name][ct_open_include][^[name]][ct_close_include][br]] [section:headers Headers] -The simplest way to use CallableTraits is to include the main header file: +The simplest way to use [library_name] is to include the main header file: - #include +[include_header callable_traits] -CallableTraits interface is also broken down by trait into individual header files. To use only the traits you need, include one or more of the following headers, which are listed alphabetically: +[library_name] interface is also broken down by trait into individual header files. To use only the traits you need, include one or more of the following headers, listed alphabetically: - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include +[include_header [link callable_traits.ref_add_const_qualifier add_const_qualifier]] +[include_header [link callable_traits.ref_add_cv_qualifiers add_cv_qualifiers]] +[include_header [link callable_traits.ref_add_lvalue_qualifier add_lvalue_qualifier]] +[include_header [link callable_traits.ref_add_rvalue_qualifier add_rvalue_qualifier]] +[include_header [link callable_traits.ref_add_varargs add_varargs]] +[include_header [link callable_traits.ref_add_volatile_qualifier add_volatile_qualifier]] +[include_header [link callable_traits.ref_apply_member_pointer apply_member_pointer]] +[include_header [link callable_traits.ref_apply_return apply_return]] +[include_header [link callable_traits.ref_arg_at arg_at]] +[include_header [link callable_traits.ref_args args]] +[include_header [link callable_traits.ref_arity arity]] +[include_header [link callable_traits.ref_bind bind]] +[include_header [link callable_traits.ref_can_invoke can_invoke]] +[include_header [link callable_traits.ref_can_invoke_constexpr can_invoke_constexpr]] +[include_header [link callable_traits.ref_function_type function_type]] +[include_header [link callable_traits.ref_has_varargs has_varargs]] +[include_header [link callable_traits.ref_has_void_return has_void_return]] +[include_header [link callable_traits.ref_is_const_qualified is_const_qualified]] +[include_header [link callable_traits.ref_is_constexpr is_constexpr]] +[include_header [link callable_traits.ref_is_lvalue_qualified is_lvalue_qualified]] +[include_header [link callable_traits.ref_is_reference_qualified is_reference_qualified]] +[include_header [link callable_traits.ref_is_rvalue_qualified is_rvalue_qualified]] +[include_header [link callable_traits.ref_is_unqualified is_unqualified]] +[include_header [link callable_traits.ref_is_volatile_qualified is_volatile_qualified]] +[include_header [link callable_traits.ref_max_arity max_arity]] +[include_header [link callable_traits.ref_min_arity min_arity]] +[include_header [link callable_traits.ref_qualified_function_type qualified_function_type]] +[include_header [link callable_traits.ref_remove_const_qualifier remove_const_qualifier]] +[include_header [link callable_traits.ref_remove_cv_qualifiers remove_cv_qualifiers]] +[include_header [link callable_traits.ref_remove_member_pointer remove_member_pointer]] +[include_header [link callable_traits.ref_remove_reference_qualifier remove_reference_qualifier]] +[include_header [link callable_traits.ref_remove_varargs remove_varargs]] +[include_header [link callable_traits.ref_remove_volatile_qualifier remove_volatile_qualifier]] +[include_header [link callable_traits.ref_result_of result_of]] [endsect] -[section add_const_qualifier] + + +[section:ref_add_const_qualifier add_const_qualifier] +[include_header add_const_qualifier] TODO -[endsect] - -[section add_cv_qualifiers] -TODO -[endsect] - -[section add_lvalue_qualifier] -TODO -[endsect] - -[section add_rvalue_qualifier] -TODO -[endsect] - -[section add_varargs] -TODO -[endsect] - -[section add_volatile_qualifier] -TODO -[endsect] - -[section apply_member_pointer] [heading Example] -[import ../example/apply_member_pointer/example.cpp] -[apply_member_pointer_example] +[import ../example/add_const_qualifier.cpp] +[add_const_qualifier] [endsect] -[section apply_return] +[section:ref_add_cv_qualifiers add_cv_qualifiers] +[include_header add_cv_qualifiers] TODO -[endsect] - -[section arg_at] -TODO -[endsect] - -[section args] [heading Example] -[import ../example/args/args.cpp] -[args_args] +[import ../example/add_cv_qualifiers.cpp] +[add_cv_qualifiers] [endsect] -[section arity] +[section:ref_add_lvalue_qualifier add_lvalue_qualifier] +[include_header add_lvalue_qualifier] TODO [endsect] -[section bind] +[section:ref_add_rvalue_qualifier add_rvalue_qualifier] +[include_header add_rvalue_qualifier] +TODO +[endsect] + +[section:ref_add_varargs add_varargs] +[include_header add_varargs] +TODO +[endsect] + +[section:ref_add_volatile_qualifier add_volatile_qualifier] +[include_header add_volatile_qualifier] +TODO +[endsect] + +[section:ref_apply_member_pointer apply_member_pointer] +[include_header apply_member_pointer] +TODO +[heading Example] +[import ../example/apply_member_pointer.cpp] +[apply_member_pointer] +[endsect] + +[section:ref_apply_return apply_return] +[include_header apply_return] +TODO +[heading Example] +[/import ../example/apply_return.cpp] +[apply_return] +[endsect] + +[section:ref_arg_at arg_at] +[include_header arg_at] +TODO +[heading Example] +[/import ../example/arg_at.cpp] +[arg_at] +[endsect] + +[section:ref_args args] +[include_header args] +TODO +[heading Example] +[import ../example/args.cpp] +[args] +[endsect] + +[section:ref_arity arity] +[include_header arity] +TODO +[heading Example] +[/import ../example/arity.cpp] +[arity] +[endsect] + +[section:ref_bind bind] +[include_header bind] +TODO [heading Example 1] -[import ../example/bind/example1.cpp] -[bind_example1] -TODO +[import ../example/bind_1.cpp] +[bind_1] +[heading Example 2] +[import ../example/bind_2.cpp] +[bind_2] [endsect] -[section can_invoke] +[section:ref_can_invoke can_invoke] +[include_header can_invoke] TODO +[heading Example - Function Object] +[import ../example/can_invoke_function_object.cpp] +[can_invoke_function_object] +[heading Example - Member Function Pointer] +[import ../example/can_invoke_member_function_pointer.cpp] +[can_invoke_member_function_pointer] +[heading Example - Function Pointer] +[import ../example/can_invoke_function_pointer.cpp] +[can_invoke_function_pointer] +[heading Example - Function Reference] +[import ../example/can_invoke_function_reference.cpp] +[can_invoke_function_reference] [endsect] -[section can_invoke_constexpr] +[section:ref_can_invoke_constexpr can_invoke_constexpr] +[include_header can_invoke_constexpr] TODO +[heading Example - Function Object] +[import ../example/can_invoke_constexpr_function_object.cpp] +[can_invoke_constexpr_function_object] +[heading Example - Member Function Pointer] +[import ../example/can_invoke_constexpr_member_function_pointer.cpp] +[can_invoke_constexpr_member_function_pointer] +[heading Example - Function Pointer] +[import ../example/can_invoke_constexpr_function_pointer.cpp] +[can_invoke_constexpr_function_pointer] [endsect] -[section function_type] +[section:ref_function_type function_type] +[include_header function_type] TODO -[endsect] - -[section has_varargs] -TODO -[endsect] - -[section has_void_return] -TODO -[endsect] - -[section is_const_qualified] -TODO -[endsect] - -[section is_constexpr] -TODO -[endsect] - -[section is_lvalue_qualified] -TODO -[endsect] - -[section is_reference_qualified] -TODO -[endsect] - -[section is_rvalue_qualified] -TODO -[endsect] - -[section is_unqualified] -TODO -[endsect] - -[section is_volatile_qualified] -TODO -[endsect] - -[section max_arity] -TODO -[endsect] - -[section min_arity] -TODO -[endsect] - -[section qualified_function_type] -TODO -[endsect] - -[section remove_const_qualifier] -TODO -[endsect] - -[section remove_cv_qualifiers] -TODO -[endsect] - -[section remove_member_pointer] [heading Example] - - #include - - namespace ct = callable_traits; - - struct foo; - - template - void test() { - using U = ct::remove_member_pointer; - static_assert(std::is_same{}, ""); - } - - int main() { - - { - using T = int(foo::*)(int) const; - using expect = int(int) const; - test(); - } { - using T = int foo::*; - using expect = int; - test(); - } { - using T = int(int); - test(); - } { - using T = int(*)(int); - test(); - } { - using T = int(&)(int); - test(); - } - } - +[import ../example/function_type.cpp] +[function_type] [endsect] -[section remove_reference_qualifier] +[section:ref_has_varargs has_varargs] +[include_header has_varargs] TODO -[endsect] - -[section remove_varargs] -TODO -[endsect] - -[section remove_volatile_qualifier] -TODO -[endsect] - -[section result_of] [heading Example] - - #include - - namespace ct = callable_traits; - - using expect = int; - - struct foo; - - template - void test() { - using result = ct::result_of; - static_assert(std::is_same{}, ""); - } - - int main() { - - test(); - test(); - test(); - test(); - test(); - - auto x = []() -> int { return 0; }; - - test(); - } +[/import ../example/has_varargs.cpp] +[has_varargs] [endsect] +[section:ref_has_void_return has_void_return] +[include_header has_void_return] +TODO +[heading Example] +[/import ../example/has_void_return.cpp] +[has_void_return] +[endsect] + +[section:ref_is_const_qualified is_const_qualified] +[include_header is_const_qualified] +TODO +[heading Example] +[/import ../example/is_const_qualified.cpp] +[is_const_qualified] +[endsect] + +[section:ref_is_constexpr is_constexpr] +[include_header is_constexpr] +TODO +[heading Example - Function Object] +[import ../example/is_constexpr_function_object.cpp] +[is_constexpr_function_object] +[heading Example - Function Pointer] +[import ../example/is_constexpr_function_pointer.cpp] +[is_constexpr_function_pointer] +[endsect] + +[section:ref_is_lvalue_qualified is_lvalue_qualified] +[include_header is_lvalue_qualified] +TODO +[heading Example] +[/import ../example/is_lvalue_qualified.cpp] +[is_lvalue_qualified] +[endsect] + +[section:ref_is_reference_qualified is_reference_qualified] +[include_header is_reference_qualified] +TODO +[heading Example] +[/import ../example/is_reference_qualified.cpp] +[is_reference_qualified] +[endsect] + +[section:ref_is_rvalue_qualified is_rvalue_qualified] +[include_header is_rvalue_qualified] +TODO +[heading Example] +[/import ../example/is_rvalue_qualified.cpp] +[is_rvalue_qualified] +[endsect] + +[section:ref_is_unqualified is_unqualified] +[include_header is_unqualified] +TODO +[heading Example] +[/import ../example/is_unqualified.cpp] +[is_unqualified] +[endsect] + +[section:ref_is_volatile_qualified is_volatile_qualified] +[include_header is_volatile_qualified] +TODO +[heading Example] +[/import ../example/is_volatile_qualified.cpp] +[is_volatile_qualified] +[endsect] + +[section:ref_max_arity max_arity] +[include_header max_arity] +TODO +[heading Example] +[/import ../example/max_arity.cpp] +[max_arity] +[endsect] + +[section:ref_min_arity min_arity] +[include_header min_arity] +TODO +[heading Example] +[/import ../example/min_arity.cpp] +[min_arity] +[endsect] + +[section:ref_qualified_function_type qualified_function_type] +[include_header qualified_function_type] +TODO +[heading Example] +[/import ../example/qualified_function_type.cpp] +[qualified_function_type] +[endsect] + +[section:ref_remove_const_qualifier remove_const_qualifier] +[include_header remove_const_qualifier] +TODO +[heading Example] +[/import ../example/remove_const_qualifier.cpp] +[remove_const_qualifier] +[endsect] + +[section:ref_remove_cv_qualifiers remove_cv_qualifiers] +[include_header remove_cv_qualifiers] +TODO +[heading Example] +[/import ../example/remove_cv_qualifiers.cpp] +[remove_cv_qualifiers] +[endsect] + +[section:ref_remove_member_pointer remove_member_pointer] +[include_header remove_member_pointer] +TODO +[heading Example] +[import ../example/remove_member_pointer.cpp] +[remove_member_pointer] +[endsect] + +[section:ref_remove_reference_qualifier remove_reference_qualifier] +[include_header remove_reference_qualifier] +TODO +[heading Example] +[/import ../example/remove_reference_qualifier.cpp] +[remove_reference_qualifier] +[endsect] + +[section:ref_remove_varargs remove_varargs] +[include_header remove_varargs] +TODO +[heading Example] +[/import ../example/remove_varargs.cpp] +[remove_varargs] +[endsect] + +[section:ref_remove_volatile_qualifier remove_volatile_qualifier] +[include_header remove_volatile_qualifier] +TODO +[heading Example] +[/import ../example/remove_volatile_qualifier.cpp] +[remove_volatile_qualifier] +[endsect] + +[section:ref_result_of result_of] +[include_header result_of] +[heading Example] +[import ../example/result_of.cpp] +[result_of] [endsect] diff --git a/doc/html/callable_traits/headers.html b/doc/html/callable_traits/headers.html new file mode 100644 index 0000000..ca6af69 --- /dev/null +++ b/doc/html/callable_traits/headers.html @@ -0,0 +1,91 @@ + + + +Headers + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ The simplest way to use CallableTraits is to include the + main header file: +

+

+ #include<callable_traits/callable_traits.hpp>
+

+

+ CallableTraits interface is also broken down by trait into + individual header files. To use only the traits you need, include one or more + of the following headers, listed alphabetically: +

+

+ #include<callable_traits/add_const_qualifier.hpp>
+ #include<callable_traits/add_cv_qualifiers.hpp>
+ #include<callable_traits/add_lvalue_qualifier.hpp>
+ #include<callable_traits/add_rvalue_qualifier.hpp>
+ #include<callable_traits/add_varargs.hpp>
+ #include<callable_traits/add_volatile_qualifier.hpp>
+ #include<callable_traits/apply_member_pointer.hpp>
+ #include<callable_traits/apply_return.hpp>
+ #include<callable_traits/arg_at.hpp>
+ #include<callable_traits/args.hpp>
+ #include<callable_traits/arity.hpp>
+ #include<callable_traits/bind.hpp>
+ #include<callable_traits/can_invoke.hpp>
+ #include<callable_traits/can_invoke_constexpr.hpp>
+ #include<callable_traits/function_type.hpp>
+ #include<callable_traits/has_varargs.hpp>
+ #include<callable_traits/has_void_return.hpp>
+ #include<callable_traits/is_const_qualified.hpp>
+ #include<callable_traits/is_constexpr.hpp>
+ #include<callable_traits/is_lvalue_qualified.hpp>
+ #include<callable_traits/is_reference_qualified.hpp>
+ #include<callable_traits/is_rvalue_qualified.hpp>
+ #include<callable_traits/is_unqualified.hpp>
+ #include<callable_traits/is_volatile_qualified.hpp>
+ #include<callable_traits/max_arity.hpp>
+ #include<callable_traits/min_arity.hpp>
+ #include<callable_traits/qualified_function_type.hpp>
+ #include<callable_traits/remove_const_qualifier.hpp>
+ #include<callable_traits/remove_cv_qualifiers.hpp>
+ #include<callable_traits/remove_member_pointer.hpp>
+ #include<callable_traits/remove_reference_qualifier.hpp>
+ #include<callable_traits/remove_varargs.hpp>
+ #include<callable_traits/remove_volatile_qualifier.hpp>
+ #include<callable_traits/result_of.hpp>
+

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_add_const_qualifier.html b/doc/html/callable_traits/ref_add_const_qualifier.html new file mode 100644 index 0000000..1df3743 --- /dev/null +++ b/doc/html/callable_traits/ref_add_const_qualifier.html @@ -0,0 +1,94 @@ + + + +add_const_qualifier + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/add_const_qualifier.hpp>
+ TODO +

+

+ + Example +

+
#include <type_traits>
+#include <callable_traits/add_const_qualifier.hpp>
+
+namespace ct = callable_traits;
+
+struct foo {};
+
+int main() {
+
+    {
+        using pmf = void(foo::*)();
+        using expect = void(foo::*)() const;
+        using test = ct::add_const_qualifier<pmf>;
+        static_assert(std::is_same<test, expect>::value, "");
+    } {
+        // add_const_qualifier doesn't change anything when
+        // the function type is already const.
+        using pmf = void(foo::*)() const &&;
+        using expect = void(foo::*)() const &&;
+        using test = ct::add_const_qualifier<pmf>;
+        static_assert(std::is_same<test, expect>::value, "");
+    } {
+        using pmf = void(foo::*)() volatile &;
+        using expect = void(foo::*)() const volatile &;
+        using test = ct::add_const_qualifier<pmf>;
+        static_assert(std::is_same<test, expect>::value, "");
+    } {
+        // add_const_qualifier can also be used to create "abominable"
+        // function types.
+        using f = void();
+        using expect = void() const;
+        using test = ct::add_const_qualifier<f>;
+        static_assert(std::is_same<test, expect>::value, "");
+    } {
+        // add_const_qualifier has no affect on function pointers,
+        // function references, function objects, or member data pointers.
+        using f = void(*)();
+        using expect = void(*)();
+        using test = ct::add_const_qualifier<f>;
+        static_assert(std::is_same<test, expect>::value, "");
+    }
+}
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_add_cv_qualifiers.html b/doc/html/callable_traits/ref_add_cv_qualifiers.html new file mode 100644 index 0000000..bfe00af --- /dev/null +++ b/doc/html/callable_traits/ref_add_cv_qualifiers.html @@ -0,0 +1,94 @@ + + + +add_cv_qualifiers + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/add_cv_qualifiers.hpp>
+ TODO +

+

+ + Example +

+
#include <type_traits>
+#include <callable_traits/add_cv_qualifiers.hpp>
+
+namespace ct = callable_traits;
+
+struct foo {};
+
+int main() {
+
+    {
+        using pmf = void(foo::*)();
+        using expect = void(foo::*)() const volatile;
+        using test = ct::add_cv_qualifiers<pmf>;
+        static_assert(std::is_same<test, expect>::value, "");
+    } {
+        // add_cv_qualifiers doesn't change anything when
+        // the function type is already cv-qualified.
+        using pmf = void(foo::*)() const volatile &&;
+        using expect = void(foo::*)() const volatile &&;
+        using test = ct::add_cv_qualifiers<pmf>;
+        static_assert(std::is_same<test, expect>::value, "");
+    } {
+        using pmf = void(foo::*)() volatile &;
+        using expect = void(foo::*)() const volatile &;
+        using test = ct::add_cv_qualifiers<pmf>;
+        static_assert(std::is_same<test, expect>::value, "");
+    } {
+        // add_cv_qualifiers can also be used to create "abominable"
+        // function types.
+        using f = void();
+        using expect = void() const volatile;
+        using test = ct::add_cv_qualifiers<f>;
+        static_assert(std::is_same<test, expect>::value, "");
+    } {
+        // add_cv_qualifiers has no affect on function pointers,
+        // function references, function objects, or member data pointers.
+        using f = void(&)();
+        using expect = void(&)();
+        using test = ct::add_cv_qualifiers<f>;
+        static_assert(std::is_same<test, expect>::value, "");
+    }
+}
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_add_lvalue_qualifier.html b/doc/html/callable_traits/ref_add_lvalue_qualifier.html new file mode 100644 index 0000000..aac1ca2 --- /dev/null +++ b/doc/html/callable_traits/ref_add_lvalue_qualifier.html @@ -0,0 +1,47 @@ + + + +add_lvalue_qualifier + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/add_lvalue_qualifier.hpp>
+ TODO +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_add_rvalue_qualifier.html b/doc/html/callable_traits/ref_add_rvalue_qualifier.html new file mode 100644 index 0000000..6d3f416 --- /dev/null +++ b/doc/html/callable_traits/ref_add_rvalue_qualifier.html @@ -0,0 +1,47 @@ + + + +add_rvalue_qualifier + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/add_rvalue_qualifier.hpp>
+ TODO +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_add_varargs.html b/doc/html/callable_traits/ref_add_varargs.html new file mode 100644 index 0000000..588fed0 --- /dev/null +++ b/doc/html/callable_traits/ref_add_varargs.html @@ -0,0 +1,47 @@ + + + +add_varargs + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/add_varargs.hpp>
+ TODO +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_add_volatile_qualifier.html b/doc/html/callable_traits/ref_add_volatile_qualifier.html new file mode 100644 index 0000000..612b9a8 --- /dev/null +++ b/doc/html/callable_traits/ref_add_volatile_qualifier.html @@ -0,0 +1,47 @@ + + + +add_volatile_qualifier + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/add_volatile_qualifier.hpp>
+ TODO +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_apply_member_pointer.html b/doc/html/callable_traits/ref_apply_member_pointer.html new file mode 100644 index 0000000..07a64c7 --- /dev/null +++ b/doc/html/callable_traits/ref_apply_member_pointer.html @@ -0,0 +1,77 @@ + + + +apply_member_pointer + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/apply_member_pointer.hpp>
+ TODO +

+

+ + Example +

+
#include <type_traits>
+#include <callable_traits/apply_member_pointer.hpp>
+
+namespace ct = callable_traits;
+
+struct foo;
+struct bar;
+
+using expect = int(foo::*)(int);
+
+template<typename T>
+void test() {
+    using U = ct::apply_member_pointer<T, foo>;
+    static_assert(std::is_same<expect, U>{}, "");
+}
+
+int main() {
+    test<int(int)>();
+    test<int(*)(int)>();
+    test<int(*&)(int)>();
+    test<int(* const)(int)>();
+    test<int(&)(int)>();
+    test<int(foo::*)(int)>();
+    test<int(bar::*)(int)>();
+}
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_apply_return.html b/doc/html/callable_traits/ref_apply_return.html new file mode 100644 index 0000000..bef6091 --- /dev/null +++ b/doc/html/callable_traits/ref_apply_return.html @@ -0,0 +1,54 @@ + + + +apply_return + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/apply_return.hpp>
+ TODO +

+

+ + Example +

+

+ [apply_return] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_arg_at.html b/doc/html/callable_traits/ref_arg_at.html new file mode 100644 index 0000000..9754235 --- /dev/null +++ b/doc/html/callable_traits/ref_arg_at.html @@ -0,0 +1,54 @@ + + + +arg_at + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+

+arg_at +

+

+ #include<callable_traits/arg_at.hpp>
+ TODO +

+

+ + Example +

+

+ [arg_at] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_args.html b/doc/html/callable_traits/ref_args.html new file mode 100644 index 0000000..6e22017 --- /dev/null +++ b/doc/html/callable_traits/ref_args.html @@ -0,0 +1,102 @@ + + + +args + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+

+args +

+

+ #include<callable_traits/args.hpp>
+ TODO +

+

+ + Example +

+
#include <type_traits>
+#include <memory>
+#include <callable_traits/callable_traits.hpp>
+
+namespace ct = callable_traits;
+
+// all callable types in this example use these parameter types
+using expect = std::tuple<int, float&, const char*>;
+
+template<typename T>
+void test(){
+    // this example shows how callable_traits::args
+    // bevaves consistently for many different types
+    using args = ct::args<T>;
+    static_assert(std::is_same<expect, args>{}, "");
+}
+
+int main() {
+
+
+    auto lamda = [](int, float&, const char*){};
+    using lam = decltype(lamda);
+    test<lam>();
+    test<lam*>();
+    test<lam&>();
+    test<lam&&>();
+    test<lam const &>();
+
+    struct foo;
+    using pmf = void(foo::*)(int, float&, const char*);
+    test<pmf>();
+    test<pmf&>();
+    test<pmf&&>();
+    test<pmf const &>();
+
+    using function_ptr = void(*)(int, float&, const char*);
+    test<function_ptr>();
+    test<function_ptr&>();
+    test<function_ptr&&>();
+    test<function_ptr const &>();
+
+    using function_ref = void(&)(int, float&, const char*);
+    test<function_ref>();
+
+    using function = void(int, float&, const char*);
+    test<function>();
+
+    using abominable = void(int, float&, const char*) const;
+    test<abominable>();
+}
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_arity.html b/doc/html/callable_traits/ref_arity.html new file mode 100644 index 0000000..c519166 --- /dev/null +++ b/doc/html/callable_traits/ref_arity.html @@ -0,0 +1,54 @@ + + + +arity + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+

+arity +

+

+ #include<callable_traits/arity.hpp>
+ TODO +

+

+ + Example +

+

+ [arity] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_bind.html b/doc/html/callable_traits/ref_bind.html new file mode 100644 index 0000000..771247c --- /dev/null +++ b/doc/html/callable_traits/ref_bind.html @@ -0,0 +1,177 @@ + + + +bind + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+

+bind +

+

+ #include<callable_traits/bind.hpp>
+ TODO +

+

+ + Example + 1 +

+
/* In this example, the last _1 placeholder in the bind
+expression forces all other _1 slots to accept ScaryMonster,
+because ScaryMonster is the narrowest of all _1 parameters. */
+
+#include <cassert>
+#include <type_traits>
+#include <functional>
+#include <tuple>
+#include <callable_traits/callable_traits.hpp>
+
+struct Vampire {};
+struct Robot {};
+struct Animal {};
+struct Dog : Animal {};
+struct Poodle : Dog {};
+struct ScaryMonster : Vampire, Robot, Poodle {};
+
+auto vampire_to_robot(Vampire) {
+    return Robot{};
+}
+
+auto robot_to_dog = [](Robot){
+    return Dog{};
+};
+
+struct converter {
+    auto dog_to_vampire(Dog) {
+        return Vampire{};
+    }
+};
+
+int take_all(Vampire, Robot, Animal, Dog, Poodle, ScaryMonster) {
+    return 0;
+}
+
+using namespace std::placeholders;
+namespace ct = callable_traits;
+
+int main() {
+
+    auto b =
+        ct::bind(&take_all,
+            ct::bind(&converter::dog_to_vampire,
+                converter{},
+                ct::bind(robot_to_dog,
+                    ct::bind(&vampire_to_robot, _1)
+                )
+            ),
+            ct::bind(&vampire_to_robot, _3),
+            Animal{},
+            _1,
+            _2,
+            _1
+        );
+
+    {
+        using args = ct::args<decltype(b)>;
+        using expect = std::tuple<ScaryMonster, Poodle, Vampire>;
+        static_assert(std::is_same<args, expect>::value, "");
+    } {
+        using type = ct::function_type<decltype(b)>;
+        using expect = int(ScaryMonster, Poodle, Vampire);
+        static_assert(std::is_same<type, expect>::value, "");
+    }
+
+    assert(b(ScaryMonster{}, Poodle{}, Vampire{}) == 0);
+
+    return 0;
+}
+
+

+ + Example + 2 +

+
#include <cassert>
+#include <type_traits>
+#include <functional>
+#include <tuple>
+#include <callable_traits/callable_traits.hpp>
+
+struct Vampire {};
+struct Robot {};
+struct Animal {};
+struct Dog : Animal {};
+struct Poodle : Dog {};
+struct ScaryMonster : Poodle, Robot, Vampire {};
+
+auto take_vampire(const Vampire&) { return 0; }
+auto take_robot(const Robot&) { return 0; }
+auto take_dog(const Dog&) { return 0; }
+auto take_scary_monster(const ScaryMonster&) { return 0; }
+
+int f(int, int, int, int) { return 0; }
+
+using namespace std::placeholders;
+namespace ct = callable_traits;
+
+int main() {
+
+    ScaryMonster monster{};
+
+    auto b = ct::bind(
+        &f,
+        ct::bind(&take_vampire, _1),
+        ct::bind(&take_robot, _1),
+        ct::bind(&take_dog, _1),
+        ct::bind(&take_scary_monster, _1)
+    );
+
+    {
+        using args = ct::args<decltype(b)>;
+        using expect = std::tuple<const ScaryMonster&>;
+        static_assert(std::is_same<args, expect>::value, "");
+    } {
+        using type = ct::function_type<decltype(b)>;
+        using expect = int(const ScaryMonster&);
+        static_assert(std::is_same<type, expect>::value, "");
+    }
+
+    assert(b(monster) == 0);
+
+    return 0;
+}
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_can_invoke.html b/doc/html/callable_traits/ref_can_invoke.html new file mode 100644 index 0000000..befe495 --- /dev/null +++ b/doc/html/callable_traits/ref_can_invoke.html @@ -0,0 +1,194 @@ + + + +can_invoke + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/can_invoke.hpp>
+ TODO +

+

+ + Example - + Function Object +

+
#include <type_traits>
+#include <callable_traits/callable_traits.hpp>
+
+namespace ct = callable_traits;
+
+// For the purpose of this example, 'Bad' represents
+// any non-arithmetic type
+struct Bad {};
+Bad bad{};
+
+// non-generic callables, such as `subtract` below,
+// don't have any "gotchas" when passed to
+// callable_traits::can_invoke.
+auto subtract = [](int x, int y) {
+    return x + y;
+};
+
+static_assert(!ct::can_invoke(subtract), "");
+static_assert(!ct::can_invoke(subtract, 1), "");
+static_assert(ct::can_invoke(subtract, 1, 2), ""); // <-- success
+static_assert(!ct::can_invoke(subtract, 1, 2, 3), "");
+static_assert(!ct::can_invoke(subtract, bad, bad), "");
+
+// Generic function objects (such as `add` and `multiply` below)
+// must be SFINAE-friendly in order for failing can_invoke calls
+// to actually compile. This applies to both generic lambdas and
+// templated function objects. Note: MSVC does not compile this
+// source code file because of the trailing return type below (MSVC
+// is non-conforming in this respect)
+
+auto add = [](auto x, auto y) -> decltype(x + y) {
+    return x + y;          // ^^^^^^^^^^^^^^^^^^ explicit return type allows SFINAE
+};
+
+template<int I>
+using int_c = std::integral_constant<int, I>;
+
+static_assert(!ct::can_invoke(add), "");
+static_assert(!ct::can_invoke(add, 1), "");
+static_assert(ct::can_invoke(add, 1, 2), ""); // <-- success
+static_assert(!ct::can_invoke(add, 1, 2, 3), "");
+static_assert(!ct::can_invoke(add, bad, bad), "");
+
+// 'multiply' isn't SFINAE-safe, because the return type depends
+// on an expression in the body. However, it still works if we
+// only try to call can_invoke with arguments where x * y is
+// a valid expression.
+auto multiply = [](auto x, auto y) {
+    return x * y;
+};
+
+
+static_assert(!ct::can_invoke(multiply), "");
+static_assert(!ct::can_invoke(multiply, 1), "");
+static_assert(ct::can_invoke(multiply, 1, 2), ""); // <-- success
+static_assert(!ct::can_invoke(multiply, 1, 2, 3), "");
+//static_assert(!ct::can_invoke(multiply, bad, bad), "");
+
+// The last, commented static_assert above would fail compile,
+// because the call cannot be SFINAE'd away. Error message in Clang:
+// "invalid operands to binary expression ('Bad' and 'Bad')"
+
+int main() {}
+
+

+ + Example + - Member Function Pointer +

+
#include <callable_traits/callable_traits.hpp>
+
+namespace ct = callable_traits;
+
+struct foo {
+    int bar(int) const {
+        return 1;
+    }
+};
+
+// can_invoke returns std::true_type here because the
+// arguments are valid to INVOKE
+static_assert(ct::can_invoke(&foo::bar, foo{}, 0), "");
+
+// can_invoke returns std::false_type here because the
+// arguments are NOT valid to INVOKE - foo::bar can't be
+// invoked like a void member function.
+static_assert(!ct::can_invoke(&foo::bar, foo{}), "");
+
+int main() {}
+
+

+ + Example - + Function Pointer +

+
#include <callable_traits/callable_traits.hpp>
+
+namespace ct = callable_traits;
+
+int foo(int&& i) {
+    return i;
+}
+
+// can_invoke returns std::true_type here because the
+// arguments are valid to INVOKE
+static_assert(ct::can_invoke(&foo, 0), "");
+
+int i = 0;
+
+// can_invoke returns std::false_type here because the
+// arguments are NOT valid to INVOKE - foo expects an
+// rvalue reference, not an lvalue reference.
+static_assert(!ct::can_invoke(&foo, i), "");
+
+int main() {}
+
+

+ + Example + - Function Reference +

+
#include <callable_traits/callable_traits.hpp>
+
+namespace ct = callable_traits;
+
+int foo(int&& i) {
+    return i;
+}
+
+// can_invoke returns std::true_type here because the
+// arguments are valid to INVOKE
+static_assert(ct::can_invoke(foo, 0), "");
+
+int i = 0;
+
+// can_invoke returns std::false_type here because the
+// arguments are NOT valid to INVOKE - foo expects an
+// rvalue reference, not an lvalue reference.
+static_assert(!ct::can_invoke(foo, i), "");
+
+int main() {}
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_can_invoke_constexpr.html b/doc/html/callable_traits/ref_can_invoke_constexpr.html new file mode 100644 index 0000000..3d06066 --- /dev/null +++ b/doc/html/callable_traits/ref_can_invoke_constexpr.html @@ -0,0 +1,186 @@ + + + +can_invoke_constexpr + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/can_invoke_constexpr.hpp>
+ TODO +

+

+ + Example + - Function Object +

+
#include <type_traits>
+#include <callable_traits/callable_traits.hpp>
+
+// NOTE: Due to non-compliance in MSVC, can_invoke_constexpr
+// always return std::false_type on that compiler, which causes
+// the static asserts below to fail.
+
+namespace ct = callable_traits;
+
+using T1 = std::integral_constant<int, 3>;
+using T2 = std::integral_constant<int, 7>;
+
+//'subtract' is a constexpr function object that
+// subtracts std::integral_constant types.
+struct subtract {
+
+    // To compile failing cases of can_invoke_constexpr, the function object
+    // must have a SFINAE-safe signature. In this case, 'subtract' is made
+    // SFINAE-safe with an explicit, trailing return type.
+    template<typename T1, typename T2>
+    constexpr auto operator()(T1, T2) const -> decltype(T1::value - T2::value) {
+        return T1::value - T2::value;
+    }
+};
+
+// can_invoke_constexpr returns std::true_type in the first case, because
+// INVOKE(subtract{}, T1{}, T2{}) is a valid expression, AND 'subtract{}' is
+// a constexpr function object.
+static_assert(ct::can_invoke_constexpr(subtract{}, T1{}, T2{}), "");
+static_assert(!ct::can_invoke_constexpr(subtract{}, 3, 7), "");
+static_assert(!ct::can_invoke_constexpr(subtract{}, T1{}), "");
+
+//this is a function object, but is NOT constexpr
+struct add {
+    template<typename T1, typename T2>
+    auto operator()(T1, T2) const -> decltype(T1::value + T2::value) {
+        return T1::value + T2::value;
+    }
+};
+
+// Even though INVOKE(add{}, T1{}, T2{}) is valid, the respective
+// can_invoke_constexpr call returns std::false_type because 'add{}'
+// is not a constexpr function object.
+static_assert(!ct::can_invoke_constexpr(add{}, T1{}, T2{}), "");
+static_assert(!ct::can_invoke_constexpr(add{}, 3, 7), "");
+
+
+// This last section demonstrates that can_invoke_constexpr will always
+// return std::false_type when any of the arguments do not decay to literal
+// types. (see http://en.cppreference.com/w/cpp/concept/LiteralType).
+// Even though 'S' below is a constexpr function object, it is incompatible
+// with can_invoke_constexpr because 'S' isn't a literal type. Additionally,
+// all arguments must be default constructible.
+
+struct S {
+    S() = delete;
+    S(int){};
+    constexpr int operator()() const { return 0; }
+};
+
+S s{0};
+static_assert(!ct::can_invoke_constexpr(s), "");
+
+
+int main() {}
+
+

+ + Example + - Member Function Pointer +

+
#include <type_traits>
+#include <callable_traits/callable_traits.hpp>
+
+// NOTE: Due to non-compliance in MSVC, can_invoke_constexpr
+// always returns std::false_type on that compiler, which
+// causes a static assert below to fail.
+
+namespace ct = callable_traits;
+
+struct foo {
+    constexpr int bar(int) const {
+        return 1;
+    }
+};
+
+using pmf_constant = std::integral_constant<decltype(&foo::bar), &foo::bar>;
+
+// can_invoke_constexpr returns true here because foo::bar
+// is constexpr, and the arguments are valid to INVOKE
+static_assert(ct::can_invoke_constexpr(pmf_constant{}, foo{}, 0), "");
+
+// can_invoke_constexpr returns false here because even though
+// foo::bar is constexpr, the arguments do not obey INVOKE rules
+static_assert(!ct::can_invoke_constexpr(pmf_constant{}, foo{}), "");
+
+int main() {}
+
+

+ + Example + - Function Pointer +

+
#include <type_traits>
+#include <callable_traits/callable_traits.hpp>
+
+namespace ct = callable_traits;
+
+constexpr int seven(int) {
+    return 7;
+}
+
+using seven_c = std::integral_constant<decltype(&seven), &seven>;
+
+// The first call to can_invoke_constexpr returns std::true_type
+// because `seven` is a constexpr function, and valid INVOKE arguments
+// are passed. The second call to can_invoke_constexpr returns
+// std::false_type, because the arguments are not valid to INVOKE
+static_assert(ct::can_invoke_constexpr(seven_c{}, 0), "");
+static_assert(!ct::can_invoke_constexpr(seven_c{}, nullptr), "");
+
+int eight(int) {
+    return 7;
+}
+
+using eight_c = std::integral_constant<decltype(&eight), &eight>;
+
+// `eight` is NOT a constexpr function, so can_invoke_constexpr
+// returns `std::false_type` even for valid INVOKE arguments.
+static_assert(!ct::can_invoke_constexpr(eight_c{}, 0), "");
+static_assert(!ct::can_invoke_constexpr(eight_c{}, nullptr), "");
+
+int main() {}
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_function_type.html b/doc/html/callable_traits/ref_function_type.html new file mode 100644 index 0000000..77e4abf --- /dev/null +++ b/doc/html/callable_traits/ref_function_type.html @@ -0,0 +1,92 @@ + + + +function_type + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/function_type.hpp>
+ TODO +

+

+ + Example +

+
#include <type_traits>
+#include <callable_traits/callable_traits.hpp>
+
+namespace ct = callable_traits;
+
+template<typename T>
+void test(){
+
+    // this example shows how callable_traits::function_type
+    // bevaves consistently for many different types
+    using type = ct::function_type<T>;
+    using expect = void(int, float&, const char*);
+    static_assert(std::is_same<expect, type>{}, "");
+}
+
+int main() {
+
+    auto lamda = [](int, float&, const char*){};
+    using lam = decltype(lamda);
+    test<lam>();
+    test<lam*>();
+    test<lam&>();
+    test<lam&&>();
+    test<lam const &>();
+
+    using function_ptr = void(*)(int, float&, const char*);
+    test<function_ptr>();
+    test<function_ptr&>();
+    test<function_ptr&&>();
+    test<function_ptr const &>();
+
+    using function_ref = void(&)(int, float&, const char*);
+    test<function_ref>();
+
+    using function = void(int, float&, const char*);
+    test<function>();
+
+    using abominable = void(int, float&, const char*) const;
+    test<abominable>();
+}
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_has_varargs.html b/doc/html/callable_traits/ref_has_varargs.html new file mode 100644 index 0000000..2151faf --- /dev/null +++ b/doc/html/callable_traits/ref_has_varargs.html @@ -0,0 +1,54 @@ + + + +has_varargs + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/has_varargs.hpp>
+ TODO +

+

+ + Example +

+

+ [has_varargs] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_has_void_return.html b/doc/html/callable_traits/ref_has_void_return.html new file mode 100644 index 0000000..76f6621 --- /dev/null +++ b/doc/html/callable_traits/ref_has_void_return.html @@ -0,0 +1,54 @@ + + + +has_void_return + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/has_void_return.hpp>
+ TODO +

+

+ + Example +

+

+ [has_void_return] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_is_const_qualified.html b/doc/html/callable_traits/ref_is_const_qualified.html new file mode 100644 index 0000000..415fa1b --- /dev/null +++ b/doc/html/callable_traits/ref_is_const_qualified.html @@ -0,0 +1,54 @@ + + + +is_const_qualified + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/is_const_qualified.hpp>
+ TODO +

+

+ + Example +

+

+ [is_const_qualified] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_is_constexpr.html b/doc/html/callable_traits/ref_is_constexpr.html new file mode 100644 index 0000000..557f02e --- /dev/null +++ b/doc/html/callable_traits/ref_is_constexpr.html @@ -0,0 +1,174 @@ + + + +is_constexpr + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/is_constexpr.hpp>
+ TODO +

+

+ + Example + - Function Object +

+
+ + + + + +
[Warning]Warning

+ When compiling in MSVC, is_constexpr + always returns std::false_type, because MSVC cannot compile + the logic that normally determines this. +

+
#include <type_traits>
+#include <callable_traits/callable_traits.hpp>
+
+namespace ct = callable_traits;
+
+//this is a constexpr function object (non-templated)
+struct zero {
+
+    constexpr auto operator()() const {
+        return 0;
+    }
+};
+
+static_assert(ct::is_constexpr<zero>(), "");
+static_assert(ct::is_constexpr(zero{}), "");
+
+
+
+//this is a constexpr function object (templated)
+struct subtract {
+
+    // For callable_traits::is_constexpr, generic function objects
+    // only need to be SFINAE-friendly if the body of the operator()
+    // function accesses member names besides "type" and "value".
+    // Unary/binary operators and constructor calls are okay to use.
+    template<typename T1, typename T2>
+    constexpr auto operator()(T1, T2) const {
+        return T1{} - T2{};
+    }
+};
+
+static_assert(ct::is_constexpr<subtract>(), "");
+static_assert(ct::is_constexpr(subtract{}), "");
+
+
+
+//this is NOT a constexpr function object
+struct add {
+    template<typename T1, typename T2>
+    auto operator()(T1, T2) const {
+        return T1{} + T2{};
+    }
+};
+
+static_assert(!ct::is_constexpr<add>(), "");
+static_assert(!ct::is_constexpr(add{}), "");
+
+auto multiply = [](auto t1, auto t2) -> decltype(t1.value * t2.value) {
+    return t1.value * t2.value;
+};
+
+static_assert(!ct::is_constexpr<decltype(multiply)>(), "");
+static_assert(!ct::is_constexpr(multiply), "");
+
+
+// is_constexpr will always return std::false_type when the argument
+// is either not a literal type, or is not default constructible. Below,
+// divide is not default constructible, so is_constexpr returns
+// std::false_type. For literal types that are default constructible, a
+// constexpr default constructor is assumed.
+
+struct divide {
+
+    divide() = delete;
+    constexpr divide(int){};
+
+    template<typename T1, typename T2>
+    constexpr auto operator()(T1, T2) const {
+        return T1{} / T2{};
+    }
+};
+
+static_assert(!ct::is_constexpr<divide>(), "");
+static_assert(!ct::is_constexpr(divide{0}), "");
+
+int main() {}
+
+

+ + Example + - Function Pointer +

+
#include <type_traits>
+#include <callable_traits/callable_traits.hpp>
+
+// NOTE: Due to non-compliance in MSVC, is_constexpr always
+// returns std::false_type on that compiler, which causes
+// the static asserts below to fail.
+
+namespace ct = callable_traits;
+
+constexpr int foo(const int&) {
+    return 1;
+}
+
+int bar(const int&) {
+    return 1;
+}
+
+// for is_constexpr calls, function pointers must
+// be passed as std::integral_constants
+using F = std::integral_constant<decltype(&foo), &foo>;
+using B = std::integral_constant<decltype(&bar), &bar>;
+
+static_assert(ct::is_constexpr(F{}), "");
+static_assert(ct::is_constexpr<F>(), "");
+static_assert(!ct::is_constexpr(B{}), "");
+static_assert(!ct::is_constexpr<B>(), "");
+
+int main() {}
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_is_lvalue_qualified.html b/doc/html/callable_traits/ref_is_lvalue_qualified.html new file mode 100644 index 0000000..4a69ddc --- /dev/null +++ b/doc/html/callable_traits/ref_is_lvalue_qualified.html @@ -0,0 +1,54 @@ + + + +is_lvalue_qualified + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/is_lvalue_qualified.hpp>
+ TODO +

+

+ + Example +

+

+ [is_lvalue_qualified] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_is_reference_qualified.html b/doc/html/callable_traits/ref_is_reference_qualified.html new file mode 100644 index 0000000..91519d0 --- /dev/null +++ b/doc/html/callable_traits/ref_is_reference_qualified.html @@ -0,0 +1,54 @@ + + + +is_reference_qualified + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/is_reference_qualified.hpp>
+ TODO +

+

+ + Example +

+

+ [is_reference_qualified] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_is_rvalue_qualified.html b/doc/html/callable_traits/ref_is_rvalue_qualified.html new file mode 100644 index 0000000..64cd7aa --- /dev/null +++ b/doc/html/callable_traits/ref_is_rvalue_qualified.html @@ -0,0 +1,54 @@ + + + +is_rvalue_qualified + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/is_rvalue_qualified.hpp>
+ TODO +

+

+ + Example +

+

+ [is_rvalue_qualified] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_is_unqualified.html b/doc/html/callable_traits/ref_is_unqualified.html new file mode 100644 index 0000000..63c7eaf --- /dev/null +++ b/doc/html/callable_traits/ref_is_unqualified.html @@ -0,0 +1,54 @@ + + + +is_unqualified + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/is_unqualified.hpp>
+ TODO +

+

+ + Example +

+

+ [is_unqualified] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_is_volatile_qualified.html b/doc/html/callable_traits/ref_is_volatile_qualified.html new file mode 100644 index 0000000..7a3e77a --- /dev/null +++ b/doc/html/callable_traits/ref_is_volatile_qualified.html @@ -0,0 +1,54 @@ + + + +is_volatile_qualified + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/is_volatile_qualified.hpp>
+ TODO +

+

+ + Example +

+

+ [is_volatile_qualified] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_max_arity.html b/doc/html/callable_traits/ref_max_arity.html new file mode 100644 index 0000000..280b39a --- /dev/null +++ b/doc/html/callable_traits/ref_max_arity.html @@ -0,0 +1,54 @@ + + + +max_arity + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/max_arity.hpp>
+ TODO +

+

+ + Example +

+

+ [max_arity] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_min_arity.html b/doc/html/callable_traits/ref_min_arity.html new file mode 100644 index 0000000..f0f8f69 --- /dev/null +++ b/doc/html/callable_traits/ref_min_arity.html @@ -0,0 +1,54 @@ + + + +min_arity + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/min_arity.hpp>
+ TODO +

+

+ + Example +

+

+ [min_arity] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_qualified_function_type.html b/doc/html/callable_traits/ref_qualified_function_type.html new file mode 100644 index 0000000..c8f0a4f --- /dev/null +++ b/doc/html/callable_traits/ref_qualified_function_type.html @@ -0,0 +1,54 @@ + + + +qualified_function_type + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/qualified_function_type.hpp>
+ TODO +

+

+ + Example +

+

+ [qualified_function_type] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_remove_const_qualifier.html b/doc/html/callable_traits/ref_remove_const_qualifier.html new file mode 100644 index 0000000..b0e3459 --- /dev/null +++ b/doc/html/callable_traits/ref_remove_const_qualifier.html @@ -0,0 +1,54 @@ + + + +remove_const_qualifier + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/remove_const_qualifier.hpp>
+ TODO +

+

+ + Example +

+

+ [remove_const_qualifier] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_remove_cv_qualifiers.html b/doc/html/callable_traits/ref_remove_cv_qualifiers.html new file mode 100644 index 0000000..fae36c4 --- /dev/null +++ b/doc/html/callable_traits/ref_remove_cv_qualifiers.html @@ -0,0 +1,54 @@ + + + +remove_cv_qualifiers + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/remove_cv_qualifiers.hpp>
+ TODO +

+

+ + Example +

+

+ [remove_cv_qualifiers] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_remove_member_pointer.html b/doc/html/callable_traits/ref_remove_member_pointer.html new file mode 100644 index 0000000..57e77ab --- /dev/null +++ b/doc/html/callable_traits/ref_remove_member_pointer.html @@ -0,0 +1,86 @@ + + + +remove_member_pointer + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/remove_member_pointer.hpp>
+ TODO +

+

+ + Example +

+
#include <type_traits>
+#include <callable_traits/callable_traits.hpp>
+
+namespace ct = callable_traits;
+
+struct foo;
+
+template<typename T, typename Expect>
+void test() {
+    using U = ct::remove_member_pointer<T>;
+    static_assert(std::is_same<Expect, U>{}, "");
+}
+
+int main() {
+
+    {
+        using T = int(foo::*)(int) const;
+        using expect = int(int) const;
+        test<T, expect>();
+    } {
+        using T = int foo::*;
+        using expect = int;
+        test<T, expect>();
+    } {
+        using T = int(int);
+        test<T, T>();
+    } {
+        using T = int(*)(int);
+        test<T, T>();
+    } {
+        using T = int(&)(int);
+        test<T, T>();
+    }
+}
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_remove_reference_qualifier.html b/doc/html/callable_traits/ref_remove_reference_qualifier.html new file mode 100644 index 0000000..0b803e9 --- /dev/null +++ b/doc/html/callable_traits/ref_remove_reference_qualifier.html @@ -0,0 +1,54 @@ + + + +remove_reference_qualifier + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/remove_reference_qualifier.hpp>
+ TODO +

+

+ + Example +

+

+ [remove_reference_qualifier] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_remove_varargs.html b/doc/html/callable_traits/ref_remove_varargs.html new file mode 100644 index 0000000..612036e --- /dev/null +++ b/doc/html/callable_traits/ref_remove_varargs.html @@ -0,0 +1,54 @@ + + + +remove_varargs + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/remove_varargs.hpp>
+ TODO +

+

+ + Example +

+

+ [remove_varargs] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_remove_volatile_qualifier.html b/doc/html/callable_traits/ref_remove_volatile_qualifier.html new file mode 100644 index 0000000..1d3d4b4 --- /dev/null +++ b/doc/html/callable_traits/ref_remove_volatile_qualifier.html @@ -0,0 +1,54 @@ + + + +remove_volatile_qualifier + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ #include<callable_traits/remove_volatile_qualifier.hpp>
+ TODO +

+

+ + Example +

+

+ [remove_volatile_qualifier] +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_result_of.html b/doc/html/callable_traits/ref_result_of.html new file mode 100644 index 0000000..2cfe24e --- /dev/null +++ b/doc/html/callable_traits/ref_result_of.html @@ -0,0 +1,77 @@ + + + +result_of + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHome +
+
+ +

+ #include<callable_traits/result_of.hpp>
+

+

+ + Example +

+
#include <type_traits>
+#include <callable_traits/callable_traits.hpp>
+
+namespace ct = callable_traits;
+
+using expect = int;
+
+struct foo;
+
+template<typename T>
+void test() {
+    using result = ct::result_of<T>;
+    static_assert(std::is_same<expect, result>{}, "");
+}
+
+int main() {
+
+    test<int()>();
+    test<int(*)()>();
+    test<int(&)()>();
+    test<int() const>();
+    test<int(foo::*)() const>();
+
+    auto x = []() -> int { return 0; };
+
+    test<decltype(x)>();
+}
+
+
+ + + +
+
+
+PrevUpHome +
+ + diff --git a/doc/html/callable_traits/tuto.html b/doc/html/callable_traits/tuto.html deleted file mode 100644 index 38a3d6c..0000000 --- a/doc/html/callable_traits/tuto.html +++ /dev/null @@ -1,249 +0,0 @@ - - - -Overview - - - - - - - -
Boost C++ Libraries
-
- -
-

-Overview

-

- CallableTraits contains the following type traits and metafunctions (psuedo-code): -

-

- std::integral_constant constexpr functions -

-
    -
  • - can_invoke(T&&, - Args&&...) -
  • -
  • - can_invoke_constexpr(T&&, - Args&&...) -
  • -
  • - is_constexpr(T&&) -
  • -
  • - is_constexpr<T>() -
  • -
  • - has_varargs(T&&) -
  • -
  • - has_varargs<T>() -
  • -
  • - has_void_return(T&&) -
  • -
  • - has_void_return<T>() -
  • -
  • - arity(T&&) -
  • -
  • - arity<T>() -
  • -
  • - min_arity(T&&) -
  • -
  • - min_arity<T>() -
  • -
  • - max_arity(T&&) -
  • -
  • - max_arity<T>() -
  • -
  • - is_unqualified(T&&) -
  • -
  • - is_unqualified<T>() -
  • -
  • - is_const_qualified(T&&) -
  • -
  • - is_const_qualified<T>() -
  • -
  • - is_volatile_qualified(T&&) -
  • -
  • - is_volatile_qualified<T>() -
  • -
  • - is_cv_qualified(T&&) -
  • -
  • - is_cv_qualified<T>() -
  • -
  • - is_reference_qualified(T&&) -
  • -
  • - is_reference_qualified<T>() -
  • -
  • - is_lvalue_qualified(T&&) -
  • -
  • - is_lvalue_qualified<T>() -
  • -
  • - is_rvalue_qualified(T&&) -
  • -
  • - is_rvalue_qualified<T>() -
  • -
-

- Template aliases -

-
    -
  • - args<T> -
  • -
  • - arg_at<I, T> -
  • -
  • - function_type<T> -
  • -
  • - qualified_function_type<T> -
  • -
  • - result_of<T> -
  • -
  • - apply_return<T, R> -
  • -
  • - apply_member_pointer<T, C> -
  • -
  • - remove_member_pointer<T> -
  • -
  • - add_const_qualifier<T> -
  • -
  • - remove_const_qualifier<T> -
  • -
  • - add_volatile_qualifier<T> -
  • -
  • - remove_volatile_qualifier<T> -
  • -
  • - add_cv_qualifiers<T> -
  • -
  • - remove_cv_qualifiers<T> -
  • -
  • - add_lvalue_qualifier<T> -
  • -
  • - add_rvalue_qualifier<T> -
  • -
  • - remove_reference_qualifiers<T> -
  • -
  • - add_varargs<T> -
  • -
  • - remove_varargs<T> -
  • -
-

- Other -

-
  • - bind(T&&, - Args&&...) -
-

- Note: CallableTraits currently offers no interface for the manipulation of - calling conventions. Also, no features are currently implemented to account - for C++17's noexcept, but will - be added in future versions for supported compilers. -

-

- The simplest way to use CallableTraits is to include the main header file: -

-
#include <callable_traits/callable_traits.hpp>
-
-

- CallableTraits interface is also broken down by trait into individual header - files. To use only the traits you need, include one or more of the following - headers, which are listed alphabetically: -

-
#include <callable_traits/add_const_qualifier.hpp>
-#include <callable_traits/add_cv_qualifiers.hpp>
-#include <callable_traits/add_lvalue_qualifier.hpp>
-#include <callable_traits/add_rvalue_qualifier.hpp>
-#include <callable_traits/add_varargs.hpp>
-#include <callable_traits/add_volatile_qualifier.hpp>
-#include <callable_traits/apply_member_pointer.hpp>
-#include <callable_traits/apply_return.hpp>
-#include <callable_traits/arg_at.hpp>
-#include <callable_traits/args.hpp>
-#include <callable_traits/arity.hpp>
-#include <callable_traits/bind.hpp>
-#include <callable_traits/can_invoke.hpp>
-#include <callable_traits/can_invoke_constexpr.hpp>
-#include <callable_traits/function_type.hpp>
-#include <callable_traits/has_varargs.hpp>
-#include <callable_traits/has_void_return.hpp>
-#include <callable_traits/is_const_qualified.hpp>
-#include <callable_traits/is_constexpr.hpp>
-#include <callable_traits/is_lvalue_qualified.hpp>
-#include <callable_traits/is_reference_qualified.hpp>
-#include <callable_traits/is_rvalue_qualified.hpp>
-#include <callable_traits/is_unqualified.hpp>
-#include <callable_traits/is_volatile_qualified.hpp>
-#include <callable_traits/max_arity.hpp>
-#include <callable_traits/min_arity.hpp>
-#include <callable_traits/qualified_function_type.hpp>
-#include <callable_traits/remove_const_qualifier.hpp>
-#include <callable_traits/remove_cv_qualifiers.hpp>
-#include <callable_traits/remove_member_pointer.hpp>
-#include <callable_traits/remove_reference_qualifier.hpp>
-#include <callable_traits/remove_varargs.hpp>
-#include <callable_traits/remove_volatile_qualifier.hpp>
-#include <callable_traits/result_of.hpp>
-
-
- - - -
-
- - - diff --git a/doc/html/index.html b/doc/html/index.html index c506437..e4b04d2 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -2,16 +2,23 @@ Chapter 1. CallableTraits - + - + -
Boost C++ Libraries
+ + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore

- - +

+ + Quick + Example +

+
#include <type_traits>
+#include <functional>
+#include <tuple>
+#include <callable_traits/callable_traits.hpp>
+
+struct foo {
+    void operator()(int, int&&, const int&, void* = nullptr) const {}
+};
+
+namespace ct = callable_traits;
+using namespace std::placeholders;
+
+int main() {
+
+    // indexed argument types
+    using second_arg = ct::arg_at<1, foo>;
+    static_assert(std::is_same<second_arg, int&&>::value, "");
+
+    // arg types are packaged into std::tuple, which serves as the default
+    // type list in CallableTraits (runtime capabilities are not used).
+    using args = ct::args<foo>;
+    using expected_args = std::tuple<int, int&&, const int&, void*>;
+    static_assert(std::is_same<args, expected_args>::value, "");
+
+    //callable_traits::result_of is a bit friendlier than std::result_of
+    using return_type = ct::result_of<foo>;
+    static_assert(std::is_same<return_type, void>::value, "");
+
+    //has_void_return is a quicker way to perform the check above
+    static_assert(ct::has_void_return(foo{}), "");
+
+    // callable_traits::function_type decays a callable type to
+    // a plain function type, which is structured in terms of INVOKE
+    using function_type = ct::function_type<foo>;
+    using expected_function_type = void(int, int&&, const int&, void*);
+    static_assert(std::is_same<function_type, expected_function_type>::value, "");
+
+    // when trait information can be conveyed in an std::integral_constant,
+    // callable_traits opts for constexpr functions instead of template aliases.
+    // This is done to encourage value semantics, and to simplify usage inside
+    // of forwarding functions.
+    static_assert(ct::arity(foo{}) == 4, "");
+    static_assert(ct::max_arity(foo{}) == 4, "");
+    static_assert(ct::min_arity(foo{}) == 3, "");
+
+    // CallableTraits provides constexpr functions so that the user doesn't
+    // need to worry about reference collapsing or decltype when dealing with
+    // universal references to callables. Still, you don't NEED an instance,
+    // because CallableTraits provides non-deduced function templates for
+    // all constexpr functions (except for can_invoke/can_invoke_constexpr and bind,
+    // which model std::invoke and std::bind, respectively -- more on these below).
+    // Here's an example of the non-deduced version of arity, which take an
+    // explicit type argument. We'll ignore these non-deduced overloads for the
+    // rest of this example.
+    static_assert(ct::arity<foo>() == 4, "");
+
+    // C-style variadics detection (ellipses in a signature)
+    static_assert(!ct::has_varargs(foo{}), "");
+
+    int i = 0;
+
+    // callable_traits::can_invoke allows us to preview whether std::invoke will
+    // compile with the given arguments.
+    static_assert(ct::can_invoke(foo{}, 0, 0, i), "");
+    // no error:     std::invoke(foo{}, 0, 0, i);
+
+    static_assert(!ct::can_invoke(foo{}, nullptr), "");
+    // error:         std::invoke(foo{}, nullptr);
+
+    // For function objects, the following checks are determined by the
+    // qualifiers on operator(), rather than the category of the passed value.
+    // For member function pointers and abominable function types, the
+    // qualifiers on the function type are used.
+    static_assert(ct::is_const_qualified(foo{}), "");
+    static_assert(!ct::is_volatile_qualified(foo{}), "");
+    static_assert(!ct::is_reference_qualified(foo{}), "");
+    static_assert(!ct::is_lvalue_qualified(foo{}), "");
+    static_assert(!ct::is_rvalue_qualified(foo{}), "");
+
+
+    // If you find yourself in the unfortunate situation of needing
+    // to manipulate member function pointer types, CallableTraits
+    // has all the tools you need to maintain your sanity.
+
+
+    using pmf = decltype(&foo::operator());
+
+    // So that you don't have to scroll back up to see, here's the type of pmf:
+    using with_const = void (foo::*)(int, int&&, const int&, void*) const;
+    static_assert(std::is_same<pmf, with_const>::value, "");
+
+    // Let's remove the const qualifier:
+    using mutable_pmf = ct::remove_const_qualifier<pmf>;
+    using without_const = void (foo::*)(int, int&&, const int&, void*) /*no const!*/;
+    static_assert(std::is_same<mutable_pmf, without_const>::value, "");
+
+    // Now let's add an rvalue qualifier (&&):
+    using rvalue_pmf = ct::add_rvalue_qualifier<pmf>;
+    using with_rvalue = void (foo::*)(int, int&&, const int&, void*) const &&;
+    static_assert(std::is_same<rvalue_pmf, with_rvalue>::value, "");
+
+    // You get the picture. CallableTraits lets you add and remove all PMF
+    // qualifiers (const, volatile, &, &&, and any combination thereof).
+    // These type operations can generally be performed on abominable function
+    // types as well.
+
+    // is_constexpr would return std::true_type if foo's operator() were constexpr.
+    static_assert(!ct::is_constexpr(foo{}), "");
+
+    // to check constexprness of a function or member function, you must use an
+    // std::integral_constant, like this:
+    using pmf_constant = std::integral_constant<pmf, &foo::operator()>;
+    static_assert(!ct::is_constexpr(pmf_constant{}), "");
+}
+
+
+

- The complexity of callable types in C++ is extensive: -

+ The complexity of callable types in C++ is extensive: +

  • - function types -
  • + function types +
  • - function pointers -
  • + function pointers +
  • - function references -
  • + function references +
  • - objects with operator() -
  • + objects with operator() +
  • - objects with function pointer conversions -
  • + objects with function pointer conversions +
  • - "abominable" - function types -
  • + "abominable" + function types +
  • - pointers to member data -
  • + pointers to member data +
  • - pointers to member functions -
  • + pointers to member functions +
  • - qualified overloads of member functions: const, - volatile, &, - && -
  • + qualified overloads of member functions: const, + volatile, &, && +
  • - C-style varargs (...) -
  • + C-style varargs (...) +
  • - calling conventions (__cdecl, - __stdcall, __fastcall, pascal, - etc.) -
  • + calling conventions (__cdecl, + __stdcall, __fastcall, pascal, + etc.) +
  • - noexcept (part - of the function type system in C++17) -
  • + noexcept (part + of the function type system in C++17) +

- CallableTraits provides a comprehensive, uniform, and modern type-level interface - for the manipulation and inspection of callable types in C++. By filling the - gaps where existing library solutions fall short, CallableTraits aims to provide - such an exhaustive interface for the features listed above that libary writers - will never again need to specialize templates - for callable types. With CallableTraits, library writers should never need - to write a template like this one: -

+ CallableTraits provides a comprehensive, uniform, and + modern type-level interface for the manipulation and inspection of callable + types in C++. By filling the gaps where existing library solutions fall short, + CallableTraits aims to provide such an exhaustive interface + for the features listed above that library writers will never + again need to specialize templates for callable types. CallableTraits + eliminates the need for horrific template specializations like these: +

template<typename Ret, typename T, typename... Args>
 struct foo<Ret(T::*)(Args..., ...) const volatile &&>{
-        //...
+                //...
 };
 

- Several library solutions exist to manipulate these types, or to abstract away - their complexities. However, these solutions are occasionally inflexible or - lacking in features, especially regarding function objects/lambdas. In CallableTraits, - function pointers, function references, function types, abominable function - types, member function pointers, member data pointers, function objects/lambdas, - and references/pointers/smart pointers thereof are generally interchangeable. -

+ Several library solutions exist to manipulate these types, or to abstract + away their complexities. However, these solutions are occasionally inflexible + or lacking in features, especially regarding function objects/lambdas. In + CallableTraits, function pointers, function references, + function types, abominable function types, member function pointers, member + data pointers, function objects/lambdas, and references/pointers/smart pointers + thereof are generally interchangeable. +

- The use cases for CallableTraits are closely related to those of function_traits - and FunctionTypes. -

+ The use cases for CallableTraits are closely related to + those of function_traits + and FunctionTypes. +

+
+ + + + + +
[Important]Important

+ CallableTraits currently offers no interface for the + manipulation of calling conventions. Also, no features are currently implemented + to account for C++17's noexcept. + These features are planned for future versions on supported platforms. +

+

-10 reasons to use CallableTraits

+10 reasons + to use CallableTraits +
  1. - CallableTraits' template aliases and constexpr - std::integral_constant functions are preferable - to typename foo::type - and foo::value + CallableTraits' template aliases and constexpr std::integral_constant + functions are preferable to typename + foo::type and foo::value
  2. - CallableTraits offers a familar, consistent interface for the synthesis - and decomposition of callable types + CallableTraits offers a familar, consistent interface + for the synthesis and decomposition of callable types
    • - e.g. callable_traits::remove_const_qualifier + e.g. remove_const_qualifier parallels std::remove_const
  3. @@ -151,7 +335,7 @@ function_traits<Callable>::arg2_type
  4. - function objects are first-class citizens in CallableTraits + function objects are first-class citizens in CallableTraits
    • e.g. result_of can accept a function object @@ -179,15 +363,16 @@

    -Use case example: std::function - sugar

    +Use case: + std::function sugar +

At the time of this writing, there are 260 search results on Stack Overflow concerning the conversion from std::bind to std::function. There are 336 search results concerning the conversion of lambdas to std::function. With this example, we'll kill both birds with the same stone. The make_function function defined below will - leverage CallableTraits to... + leverage CallableTraits to...

  1. @@ -202,9 +387,9 @@

Without real-world context, make_function - may seem rather silly to those who are aware of the runtime costs of type - erasure. However, whenever std::function - is required by some 3rd party API, this example makes a bit more sense. + may seem rather silly to those who know the runtime costs of type erasure. + However, whenever std::function is required by some 3rd party + API, this example might make a bit more sense.

#include <functional>
 #include <callable_traits/callable_traits.hpp>
@@ -213,11 +398,11 @@
 
     namespace ct = callable_traits;
 
-    //`make_function` turns a non-overloaded callable into a type-erased std::function object
+    //make_function turns a non-overloaded callable into a type-erased std::function object
     template<typename T>
     inline decltype(auto) make_function(T&& t) {
 
-        // callable_traits::function_type decays any non-overloaded callable type to 
+        // callable_traits::function_type decays any non-overloaded callable type to
         // a plain function type, which is structured in terms of INVOKE.
 
         using signature = ct::function_type<T&&>;
@@ -225,7 +410,7 @@
         return result_type{ std::forward<T>(t) };
     }
 
-    //this `make_function` overload turns a bind expression into a type-erased std::function object
+    //this make_function overload turns a bind expression into a type-erased std::function object
     template<typename T, typename First, typename... Others>
     inline decltype(auto) make_function(T&& t, First&& first, Others&&... others) {
 
@@ -235,22 +420,22 @@
         // determine the de-facto signature of the std::bind return type, with special
         // considerations for conversions between reused placeholders and nested
         // placeholder expressions. For the sake of convenience, callable_traits::bind
-        // is also a thin forwarding wrapper around std::bind (which is the only true 
+        // is also a thin forwarding wrapper around std::bind (which is the only true
         // runtime element in CallableTraits).
 
         using bind_expr = decltype(ct::bind(
-            std::forward<T>(t),
-            std::forward<First>(first),
-            std::forward<Others>(others)...
+                std::forward<T>(t),
+                std::forward<First>(first),
+                std::forward<Others>(others)...
         ));
 
         using signature = ct::function_type<bind_expr>;
         using result_type = std::function<signature>;
 
         return result_type{ std::bind(
-            std::forward<T>(t),
-            std::forward<First>(first),
-            std::forward<Others>(others)...
+                std::forward<T>(t),
+                std::forward<First>(first),
+                std::forward<Others>(others)...
         )};
     }
 }
@@ -302,6 +487,6 @@
 
 
 
- +
Next
diff --git a/doc/html/standalone_HTML.manifest b/doc/html/standalone_HTML.manifest index 1045230..8971a3e 100644 --- a/doc/html/standalone_HTML.manifest +++ b/doc/html/standalone_HTML.manifest @@ -1,2 +1,36 @@ index.html -callable_traits/tuto.html +callable_traits/headers.html +callable_traits/ref_add_const_qualifier.html +callable_traits/ref_add_cv_qualifiers.html +callable_traits/ref_add_lvalue_qualifier.html +callable_traits/ref_add_rvalue_qualifier.html +callable_traits/ref_add_varargs.html +callable_traits/ref_add_volatile_qualifier.html +callable_traits/ref_apply_member_pointer.html +callable_traits/ref_apply_return.html +callable_traits/ref_arg_at.html +callable_traits/ref_args.html +callable_traits/ref_arity.html +callable_traits/ref_bind.html +callable_traits/ref_can_invoke.html +callable_traits/ref_can_invoke_constexpr.html +callable_traits/ref_function_type.html +callable_traits/ref_has_varargs.html +callable_traits/ref_has_void_return.html +callable_traits/ref_is_const_qualified.html +callable_traits/ref_is_constexpr.html +callable_traits/ref_is_lvalue_qualified.html +callable_traits/ref_is_reference_qualified.html +callable_traits/ref_is_rvalue_qualified.html +callable_traits/ref_is_unqualified.html +callable_traits/ref_is_volatile_qualified.html +callable_traits/ref_max_arity.html +callable_traits/ref_min_arity.html +callable_traits/ref_qualified_function_type.html +callable_traits/ref_remove_const_qualifier.html +callable_traits/ref_remove_cv_qualifiers.html +callable_traits/ref_remove_member_pointer.html +callable_traits/ref_remove_reference_qualifier.html +callable_traits/ref_remove_varargs.html +callable_traits/ref_remove_volatile_qualifier.html +callable_traits/ref_result_of.html diff --git a/example/add_const_qualifier.cpp b/example/add_const_qualifier.cpp new file mode 100644 index 0000000..9e0a531 --- /dev/null +++ b/example/add_const_qualifier.cpp @@ -0,0 +1,50 @@ +/*<- +Copyright Barrett Adair 2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) +->*/ + +//[ add_const_qualifier +#include +#include + +namespace ct = callable_traits; + +struct foo {}; + +int main() { + + { + using pmf = void(foo::*)(); + using expect = void(foo::*)() const; + using test = ct::add_const_qualifier; + static_assert(std::is_same::value, ""); + } { + // add_const_qualifier doesn't change anything when + // the function type is already const. + using pmf = void(foo::*)() const &&; + using expect = void(foo::*)() const &&; + using test = ct::add_const_qualifier; + static_assert(std::is_same::value, ""); + } { + using pmf = void(foo::*)() volatile &; + using expect = void(foo::*)() const volatile &; + using test = ct::add_const_qualifier; + static_assert(std::is_same::value, ""); + } { + // add_const_qualifier can also be used to create "abominable" + // function types. + using f = void(); + using expect = void() const; + using test = ct::add_const_qualifier; + static_assert(std::is_same::value, ""); + } { + // add_const_qualifier has no affect on function pointers, + // function references, function objects, or member data pointers. + using f = void(*)(); + using expect = void(*)(); + using test = ct::add_const_qualifier; + static_assert(std::is_same::value, ""); + } +} +//] diff --git a/example/add_cv_qualifiers.cpp b/example/add_cv_qualifiers.cpp new file mode 100644 index 0000000..7eded16 --- /dev/null +++ b/example/add_cv_qualifiers.cpp @@ -0,0 +1,50 @@ +/*<- +Copyright Barrett Adair 2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) +->*/ + +//[ add_cv_qualifiers +#include +#include + +namespace ct = callable_traits; + +struct foo {}; + +int main() { + + { + using pmf = void(foo::*)(); + using expect = void(foo::*)() const volatile; + using test = ct::add_cv_qualifiers; + static_assert(std::is_same::value, ""); + } { + // add_cv_qualifiers doesn't change anything when + // the function type is already cv-qualified. + using pmf = void(foo::*)() const volatile &&; + using expect = void(foo::*)() const volatile &&; + using test = ct::add_cv_qualifiers; + static_assert(std::is_same::value, ""); + } { + using pmf = void(foo::*)() volatile &; + using expect = void(foo::*)() const volatile &; + using test = ct::add_cv_qualifiers; + static_assert(std::is_same::value, ""); + } { + // add_cv_qualifiers can also be used to create "abominable" + // function types. + using f = void(); + using expect = void() const volatile; + using test = ct::add_cv_qualifiers; + static_assert(std::is_same::value, ""); + } { + // add_cv_qualifiers has no affect on function pointers, + // function references, function objects, or member data pointers. + using f = void(&)(); + using expect = void(&)(); + using test = ct::add_cv_qualifiers; + static_assert(std::is_same::value, ""); + } +} +//] diff --git a/example/apply_member_pointer/example.cpp b/example/apply_member_pointer.cpp similarity index 95% rename from example/apply_member_pointer/example.cpp rename to example/apply_member_pointer.cpp index 978a9f3..3b3d70f 100644 --- a/example/apply_member_pointer/example.cpp +++ b/example/apply_member_pointer.cpp @@ -5,7 +5,7 @@ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) ->*/ -//[ apply_member_pointer_example +//[ apply_member_pointer #include #include diff --git a/example/args/args.cpp b/example/args.cpp similarity index 87% rename from example/args/args.cpp rename to example/args.cpp index 056204e..c529d80 100644 --- a/example/args/args.cpp +++ b/example/args.cpp @@ -5,20 +5,20 @@ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) ->*/ -//[ args_args +//[ args #include #include #include namespace ct = callable_traits; -//` all callable types in this example use these parameter types +// all callable types in this example use these parameter types using expect = std::tuple; template void test(){ - /*` this example shows how callable_traits::args - bevaves consistently for many different types */ + // this example shows how callable_traits::args + // bevaves consistently for many different types using args = ct::args; static_assert(std::is_same{}, ""); } diff --git a/example/bind/example1.cpp b/example/bind_1.cpp similarity index 89% rename from example/bind/example1.cpp rename to example/bind_1.cpp index d58a676..a01b319 100644 --- a/example/bind/example1.cpp +++ b/example/bind_1.cpp @@ -6,7 +6,12 @@ Distributed under the Boost Software License, Version 1.0. ->*/ -//[ bind_example1 +//[ bind_1 + +/* In this example, the last _1 placeholder in the bind +expression forces all other _1 slots to accept ScaryMonster, +because ScaryMonster is the narrowest of all _1 parameters. */ + #include #include #include @@ -58,10 +63,6 @@ int main() { _1 ); - /*` the last _1 placeholder in this bind expression forces - all other _1 slots to accept ScaryMonster, the - narrowest of all _1 parameters. */ - { using args = ct::args; using expect = std::tuple; diff --git a/example/bind/example2.cpp b/example/bind_2.cpp similarity index 98% rename from example/bind/example2.cpp rename to example/bind_2.cpp index 0d6740c..7ccc032 100644 --- a/example/bind/example2.cpp +++ b/example/bind_2.cpp @@ -1,11 +1,12 @@ -/* +/*<- Copyright Barrett Adair 2016 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ +->*/ +//[ bind_2 #include #include #include @@ -55,3 +56,4 @@ int main() { return 0; } +//] diff --git a/example/can_invoke_constexpr/function_object.cpp b/example/can_invoke_constexpr_function_object.cpp similarity index 97% rename from example/can_invoke_constexpr/function_object.cpp rename to example/can_invoke_constexpr_function_object.cpp index 9f04940..6955e57 100644 --- a/example/can_invoke_constexpr/function_object.cpp +++ b/example/can_invoke_constexpr_function_object.cpp @@ -1,9 +1,10 @@ -/* +/*<- Copyright Barrett Adair 2016 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) -*/ +->*/ +//[ can_invoke_constexpr_function_object #include #include @@ -69,3 +70,4 @@ static_assert(!ct::can_invoke_constexpr(s), ""); int main() {} +//] diff --git a/example/can_invoke_constexpr/function_pointer.cpp b/example/can_invoke_constexpr_function_pointer.cpp similarity index 95% rename from example/can_invoke_constexpr/function_pointer.cpp rename to example/can_invoke_constexpr_function_pointer.cpp index 140d864..fee8798 100644 --- a/example/can_invoke_constexpr/function_pointer.cpp +++ b/example/can_invoke_constexpr_function_pointer.cpp @@ -1,10 +1,11 @@ -/*! +/*!<- Copyright (c) 2016 Barrett Adair Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ +->*/ +//[ can_invoke_constexpr_function_pointer #include #include @@ -35,4 +36,4 @@ static_assert(!ct::can_invoke_constexpr(eight_c{}, 0), ""); static_assert(!ct::can_invoke_constexpr(eight_c{}, nullptr), ""); int main() {} - +//] diff --git a/example/can_invoke_constexpr/member_function_pointer.cpp b/example/can_invoke_constexpr_member_function_pointer.cpp similarity index 92% rename from example/can_invoke_constexpr/member_function_pointer.cpp rename to example/can_invoke_constexpr_member_function_pointer.cpp index c7168e9..ec21480 100644 --- a/example/can_invoke_constexpr/member_function_pointer.cpp +++ b/example/can_invoke_constexpr_member_function_pointer.cpp @@ -1,11 +1,12 @@ -/*! +/*!<- Copyright (c) 2016 Barrett Adair Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ +->*/ +//[ can_invoke_constexpr_member_function_pointer #include #include @@ -31,4 +32,5 @@ static_assert(ct::can_invoke_constexpr(pmf_constant{}, foo{}, 0), ""); // foo::bar is constexpr, the arguments do not obey INVOKE rules static_assert(!ct::can_invoke_constexpr(pmf_constant{}, foo{}), ""); -int main() { return 0; } +int main() {} +//] diff --git a/example/can_invoke/function_object.cpp b/example/can_invoke_function_object.cpp similarity index 95% rename from example/can_invoke/function_object.cpp rename to example/can_invoke_function_object.cpp index cf62710..6e26f9a 100644 --- a/example/can_invoke/function_object.cpp +++ b/example/can_invoke_function_object.cpp @@ -1,13 +1,10 @@ -/* +/*<- Copyright Barrett Adair 2016 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) -*/ - - -// NOTE: This does not compile in MSVC, which can't handle -// the trailing return type on the generic lambda 'add' +->*/ +//[ can_invoke_function_object #include #include @@ -71,3 +68,4 @@ static_assert(!ct::can_invoke(multiply, 1, 2, 3), ""); // "invalid operands to binary expression ('Bad' and 'Bad')" int main() {} +//] diff --git a/example/can_invoke/function_pointer.cpp b/example/can_invoke_function_pointer.cpp similarity index 75% rename from example/can_invoke/function_pointer.cpp rename to example/can_invoke_function_pointer.cpp index b166f74..6ff98d2 100644 --- a/example/can_invoke/function_pointer.cpp +++ b/example/can_invoke_function_pointer.cpp @@ -1,10 +1,10 @@ -/*! -Copyright (c) 2016 Barrett Adair - +/*<- +Copyright Barrett Adair 2016 Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ +(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) +->*/ +//[ can_invoke_function_pointer #include namespace ct = callable_traits; @@ -24,5 +24,5 @@ int i = 0; // rvalue reference, not an lvalue reference. static_assert(!ct::can_invoke(&foo, i), ""); -int main() { return 0; } - +int main() {} +//] diff --git a/example/can_invoke/function_reference.cpp b/example/can_invoke_function_reference.cpp similarity index 75% rename from example/can_invoke/function_reference.cpp rename to example/can_invoke_function_reference.cpp index dc1315d..7264be5 100644 --- a/example/can_invoke/function_reference.cpp +++ b/example/can_invoke_function_reference.cpp @@ -1,10 +1,10 @@ -/*! -Copyright (c) 2016 Barrett Adair - +/*<- +Copyright Barrett Adair 2016 Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ +(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) +->*/ +//[ can_invoke_function_reference #include namespace ct = callable_traits; @@ -24,5 +24,6 @@ int i = 0; // rvalue reference, not an lvalue reference. static_assert(!ct::can_invoke(foo, i), ""); -int main() { return 0; } +int main() {} +//] diff --git a/example/can_invoke/member_function_pointer.cpp b/example/can_invoke_member_function_pointer.cpp similarity index 76% rename from example/can_invoke/member_function_pointer.cpp rename to example/can_invoke_member_function_pointer.cpp index ca0888d..159a598 100644 --- a/example/can_invoke/member_function_pointer.cpp +++ b/example/can_invoke_member_function_pointer.cpp @@ -1,10 +1,10 @@ -/*! -Copyright (c) 2016 Barrett Adair - +/*<- +Copyright Barrett Adair 2016 Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ +(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) +->*/ +//[ can_invoke_member_function_pointer #include namespace ct = callable_traits; @@ -24,4 +24,6 @@ static_assert(ct::can_invoke(&foo::bar, foo{}, 0), ""); // invoked like a void member function. static_assert(!ct::can_invoke(&foo::bar, foo{}), ""); -int main() { return 0; } +int main() {} + +//] diff --git a/example/function_type/function_type.cpp b/example/function_type.cpp similarity index 76% rename from example/function_type/function_type.cpp rename to example/function_type.cpp index 36502a3..156e66d 100644 --- a/example/function_type/function_type.cpp +++ b/example/function_type.cpp @@ -1,24 +1,24 @@ -/*! +/*<- Copyright (c) 2016 Barrett Adair Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ +->*/ +//[ function_type #include -#include #include namespace ct = callable_traits; -using expect = void(int, float&, const char*); - template void test(){ + // this example shows how callable_traits::function_type // bevaves consistently for many different types - using args = ct::function_type; - static_assert(std::is_same{}, ""); + using type = ct::function_type; + using expect = void(int, float&, const char*); + static_assert(std::is_same{}, ""); } int main() { @@ -31,13 +31,6 @@ int main() { test(); test(); - /*struct foo; - using pmf = void(foo::*)(int, float&, const char*); - test(); - test(); - test(); - test();*/ - using function_ptr = void(*)(int, float&, const char*); test(); test(); @@ -53,3 +46,4 @@ int main() { using abominable = void(int, float&, const char*) const; test(); } +//] diff --git a/example/intro.cpp b/example/intro.cpp index d6db630..ea06b43 100644 --- a/example/intro.cpp +++ b/example/intro.cpp @@ -1,9 +1,10 @@ -/* +/*<- Copyright Barrett Adair 2016 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) -*/ +->*/ +//[ intro #include #include #include @@ -118,3 +119,4 @@ int main() { using pmf_constant = std::integral_constant; static_assert(!ct::is_constexpr(pmf_constant{}), ""); } +//] diff --git a/example/is_constexpr/function_object.cpp b/example/is_constexpr_function_object.cpp similarity index 88% rename from example/is_constexpr/function_object.cpp rename to example/is_constexpr_function_object.cpp index d8616e6..5ee9019 100644 --- a/example/is_constexpr/function_object.cpp +++ b/example/is_constexpr_function_object.cpp @@ -1,12 +1,13 @@ -/* +/*<- Copyright Barrett Adair 2016 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) -*/ +->*/ -// NOTE: Due to non-compliance in MSVC, is_constexpr always -// returns std::false_type on that compiler, which causes -// the static asserts below to fail. +//[ is_constexpr_function_object +/*`[warning When compiling in MSVC, `is_constexpr` always returns +`std::false_type`, because MSVC cannot compile the logic that normally determines +this.]*/ #include #include @@ -65,7 +66,7 @@ static_assert(!ct::is_constexpr(multiply), ""); // is_constexpr will always return std::false_type when the argument // is either not a literal type, or is not default constructible. Below, -// `divide` is not default constructible, so is_constexpr returns +// divide is not default constructible, so is_constexpr returns // std::false_type. For literal types that are default constructible, a // constexpr default constructor is assumed. @@ -84,3 +85,4 @@ static_assert(!ct::is_constexpr(), ""); static_assert(!ct::is_constexpr(divide{0}), ""); int main() {} +//] diff --git a/example/is_constexpr/function_pointer.cpp b/example/is_constexpr_function_pointer.cpp similarity index 93% rename from example/is_constexpr/function_pointer.cpp rename to example/is_constexpr_function_pointer.cpp index d8cdef0..ec433ca 100644 --- a/example/is_constexpr/function_pointer.cpp +++ b/example/is_constexpr_function_pointer.cpp @@ -1,11 +1,12 @@ -/*! +/*!<- Copyright (c) 2016 Barrett Adair Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ +->*/ +//[ is_constexpr_function_pointer #include #include @@ -33,4 +34,5 @@ static_assert(ct::is_constexpr(), ""); static_assert(!ct::is_constexpr(B{}), ""); static_assert(!ct::is_constexpr(), ""); -int main() { return 0; } +int main() {} +//] diff --git a/example/make_function.cpp b/example/make_function.cpp new file mode 100644 index 0000000..61ea83f --- /dev/null +++ b/example/make_function.cpp @@ -0,0 +1,95 @@ +/*<- +Copyright Barrett Adair 2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) +->*/ + +//[ make_function +#include +#include + +namespace example_library { + + namespace ct = callable_traits; + + //make_function turns a non-overloaded callable into a type-erased std::function object + template + inline decltype(auto) make_function(T&& t) { + + // callable_traits::function_type decays any non-overloaded callable type to + // a plain function type, which is structured in terms of INVOKE. + + using signature = ct::function_type; + using result_type = std::function; + return result_type{ std::forward(t) }; + } + + //this make_function overload turns a bind expression into a type-erased std::function object + template + inline decltype(auto) make_function(T&& t, First&& first, Others&&... others) { + + // callable_traits::bind is essentially a compile-time parser of placeholders + // expressions, for the purpose of retaining more type information than + // std::bind normally allows - specifically, callable_traits::bind is used to + // determine the de-facto signature of the std::bind return type, with special + // considerations for conversions between reused placeholders and nested + // placeholder expressions. For the sake of convenience, callable_traits::bind + // is also a thin forwarding wrapper around std::bind (which is the only true + // runtime element in CallableTraits). + + using bind_expr = decltype(ct::bind( + std::forward(t), + std::forward(first), + std::forward(others)... + )); + + using signature = ct::function_type; + using result_type = std::function; + + return result_type{ std::bind( + std::forward(t), + std::forward(first), + std::forward(others)... + )}; + } +} + +//client code starts here +#include + +using namespace example_library; +using namespace std::placeholders; + +int add(int i, int j) { + return i + j; +} + +struct adder { + + int eval(int i, int j) const { + return i + j; + } +}; + +int main() { + + //function pointer + auto f = make_function(&add); + assert(f(99, 1) == 100); + + //function reference + f = make_function(add); + assert(f(99, 1) == 100); + + //member function pointer (bound to object) + f = make_function(&adder::eval, adder{}, _1, _2); + assert(f(99, 1) == 100); + + //lambda + f = make_function([](int i, int j) { + return i + j; + }); + + assert(f(99, 1) == 100); +} +//] diff --git a/example/remove_member_pointer/example.cpp b/example/remove_member_pointer.cpp similarity index 92% rename from example/remove_member_pointer/example.cpp rename to example/remove_member_pointer.cpp index 398bbdd..7b5a67d 100644 --- a/example/remove_member_pointer/example.cpp +++ b/example/remove_member_pointer.cpp @@ -1,10 +1,11 @@ -/*! +/*!<- Copyright (c) 2016 Barrett Adair Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ - +->*/ +//[ remove_member_pointer +#include #include namespace ct = callable_traits; @@ -38,4 +39,4 @@ int main() { test(); } } - +//] diff --git a/example/result_of/example.cpp b/example/result_of.cpp similarity index 92% rename from example/result_of/example.cpp rename to example/result_of.cpp index 5ebaab4..ed758b3 100644 --- a/example/result_of/example.cpp +++ b/example/result_of.cpp @@ -1,10 +1,12 @@ -/*! +/*!<- Copyright (c) 2016 Barrett Adair Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) -*/ +->*/ +//[ result_of +#include #include namespace ct = callable_traits; @@ -31,4 +33,4 @@ int main() { test(); } - +//] diff --git a/example/std_function/example.cpp b/example/std_function/example.cpp deleted file mode 100644 index c1088a4..0000000 --- a/example/std_function/example.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - -Copyright Barrett Adair 2015 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) - -*/ - -#include -#undef NDEBUG -#include "make_function.hpp" - -using example::make_function; -using namespace std::placeholders; - -int add(int i, int j) { - return i + j; -} - -struct adder { - - int eval(int i, int j) const { - return i + j; - } -}; - -void check_add(std::function& f) { - - auto add_result = f(99, 1); - assert(add_result == 100); -} - -int main() { - - //function pointer - auto f = make_function(&add); - check_add(f); - - //function reference - f = make_function(add); - check_add(f); - - //lambda - f = make_function([](int i, int j) { - return i + j; - }); - check_add(f); - - //member function pointer (bound to object) - f = make_function(&adder::eval, adder{}, _1, _2); - check_add(f); -} diff --git a/example/std_function/make_function.hpp b/example/std_function/make_function.hpp deleted file mode 100644 index 10f03cf..0000000 --- a/example/std_function/make_function.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include - -#ifndef EXAMPLE_ADAPTORS_HPP -#define EXAMPLE_ADAPTORS_HPP - -namespace example { - - namespace ct = callable_traits; - - //`make_function` turns any (non-overloaded) callable into std::function - template - inline decltype(auto) make_function(T&& t) { - using signature = ct::function_type; - using result_type = std::function; - return result_type{ ::std::forward(t) }; - } - - //this `make_function` overload turns a bind expression into std::function - template - inline decltype(auto) make_function(T&& t, First&& first, Others&&... others) { - - using bind_expr = decltype(::callable_traits::bind( - ::std::forward(t), - ::std::forward(first), - ::std::forward(others)... - )); - - using signature = ct::function_type; - using result_type = std::function; - - return result_type{ ::std::bind( - ::std::forward(t), - ::std::forward(first), - ::std::forward(others)... - )}; - } -} - -#endif diff --git a/include/callable_traits/add_const_qualifier.hpp b/include/callable_traits/add_const_qualifier.hpp index 4aa7e78..5394c2f 100644 --- a/include/callable_traits/add_const_qualifier.hpp +++ b/include/callable_traits/add_const_qualifier.hpp @@ -1,5 +1,5 @@ /*! -@file +@file add_const_qualifier @copyright Barrett Adair 2015 Distributed under the Boost Software License, Version 1.0. diff --git a/include/callable_traits/detail/function.hpp b/include/callable_traits/detail/function.hpp index ad35b96..ced2ba2 100644 --- a/include/callable_traits/detail/function.hpp +++ b/include/callable_traits/detail/function.hpp @@ -168,15 +168,15 @@ namespace callable_traits { using add_varargs = typename base::add_varargs*; using remove_reference = T*; - using add_lvalue_reference = T*&; - using add_rvalue_reference = T*&&; + using add_lvalue_reference = T*; + using add_rvalue_reference = T*; - using add_const = T * const; - using add_volatile = T * volatile; - using add_cv = T * const volatile; - using remove_const = typename base::remove_cv *; - using remove_volatile = typename base::remove_cv *; - using remove_cv = typename base::remove_cv *; + using add_const = T*; + using add_volatile = T*; + using add_cv = T*; + using remove_const = T*; + using remove_volatile = T*; + using remove_cv = T*; template using apply_return = typename base::template apply_return&; @@ -192,16 +192,16 @@ namespace callable_traits { using remove_varargs = typename base::remove_varargs&; using add_varargs = typename base::add_varargs&; - using remove_reference = T; + using remove_reference = T&; using add_lvalue_reference = T&; - using add_rvalue_reference = T&&; + using add_rvalue_reference = T&; - using add_const = typename base::add_const; - using add_volatile = typename base::add_volatile; - using add_cv = typename base::add_cv; - using remove_const = typename base::remove_const; - using remove_volatile = typename base::remove_volatile; - using remove_cv = typename base::remove_cv; + using add_const = T&; + using add_volatile = T&; + using add_cv = T&; + using remove_const = T&; + using remove_volatile = T&; + using remove_cv = T&; template using apply_return = typename base::template apply_return&; diff --git a/include/callable_traits/detail/function_object.hpp b/include/callable_traits/detail/function_object.hpp index 98e255e..bacf17f 100644 --- a/include/callable_traits/detail/function_object.hpp +++ b/include/callable_traits/detail/function_object.hpp @@ -103,15 +103,15 @@ namespace callable_traits { template using apply_return = invalid_type; - using remove_reference = invalid_type; - using add_lvalue_reference = invalid_type; - using add_rvalue_reference = invalid_type; - using add_const = invalid_type; - using add_volatile = invalid_type; - using add_cv = invalid_type; - using remove_const = invalid_type; - using remove_volatile = invalid_type; - using remove_cv = invalid_type; + using remove_reference = type; + using add_lvalue_reference = type; + using add_rvalue_reference = type; + using add_const = type; + using add_volatile = type; + using add_cv = type; + using remove_const = type; + using remove_volatile = type; + using remove_cv = type; }; template diff --git a/include/callable_traits/detail/pmd.hpp b/include/callable_traits/detail/pmd.hpp index e4cb920..87c031f 100644 --- a/include/callable_traits/detail/pmd.hpp +++ b/include/callable_traits/detail/pmd.hpp @@ -55,6 +55,7 @@ namespace callable_traits { using traits = pmd; using class_type = T; using invoke_type = T const &; + using type = D T::*; using function_type = D(invoke_type); using arg_types = std::tuple; @@ -65,15 +66,15 @@ namespace callable_traits { template using apply_member_pointer = D C::*; - using remove_reference = invalid_type; - using add_lvalue_reference = invalid_type; - using add_rvalue_reference = invalid_type; - using add_const = invalid_type; - using add_volatile = invalid_type; - using add_cv = invalid_type; - using remove_const = invalid_type; - using remove_volatile = invalid_type; - using remove_cv = invalid_type; + using remove_reference = type; + using add_lvalue_reference = type; + using add_rvalue_reference = type; + using add_const = type; + using add_volatile = type; + using add_cv = type; + using remove_const = type; + using remove_volatile = type; + using remove_cv = type; template using apply_return = invalid_type; diff --git a/qtcreator/main/main.cpp b/qtcreator/main/main.cpp index a645a21..7eded16 100644 --- a/qtcreator/main/main.cpp +++ b/qtcreator/main/main.cpp @@ -1,53 +1,50 @@ -/* - -Copyright Barrett Adair 2015 +/*<- +Copyright Barrett Adair 2016 Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) +(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) +->*/ -*/ +//[ add_cv_qualifiers +#include +#include -#include -#include "../example/std_function/make_function.hpp" +namespace ct = callable_traits; -using example::make_function; -using namespace std::placeholders; - -int add(int i, int j) { - return i + j; -} - -struct adder { - - int eval(int i, int j) const { - return i + j; - } -}; - -void check_add(std::function f) { - - auto add_result = f(99, 1); - assert(add_result == 100); -} +struct foo {}; int main() { - //function pointer - auto f = make_function(&add); - check_add(f); - - //function reference - f = make_function(add); - check_add(f); - - //lambda - f = make_function([](int i, int j) { - return i + j; - }); - - check_add(f); - - //member function pointer (bound to object) - f = make_function(&adder::eval, adder{}, _1, _2); - - check_add(f); + { + using pmf = void(foo::*)(); + using expect = void(foo::*)() const volatile; + using test = ct::add_cv_qualifiers; + static_assert(std::is_same::value, ""); + } { + // add_cv_qualifiers doesn't change anything when + // the function type is already cv-qualified. + using pmf = void(foo::*)() const volatile &&; + using expect = void(foo::*)() const volatile &&; + using test = ct::add_cv_qualifiers; + static_assert(std::is_same::value, ""); + } { + using pmf = void(foo::*)() volatile &; + using expect = void(foo::*)() const volatile &; + using test = ct::add_cv_qualifiers; + static_assert(std::is_same::value, ""); + } { + // add_cv_qualifiers can also be used to create "abominable" + // function types. + using f = void(); + using expect = void() const volatile; + using test = ct::add_cv_qualifiers; + static_assert(std::is_same::value, ""); + } { + // add_cv_qualifiers has no affect on function pointers, + // function references, function objects, or member data pointers. + using f = void(&)(); + using expect = void(&)(); + using test = ct::add_cv_qualifiers; + static_assert(std::is_same::value, ""); + } } +//] diff --git a/qtcreator/tests_and_examples/tests_and_examples.pro b/qtcreator/tests_and_examples/tests_and_examples.pro index 2b2f0ca..8aa3da3 100644 --- a/qtcreator/tests_and_examples/tests_and_examples.pro +++ b/qtcreator/tests_and_examples/tests_and_examples.pro @@ -4,13 +4,3 @@ CONFIG -= qt OTHER_FILES += ../../test/* \ ../../test/detail/* \ ../../example/* \ - ../../example/is_constexpr/* \ - ../../example/can_invoke/* \ - ../../example/can_invoke_constexpr/* \ - ../../example/bind/* \ - ../../example/args/* \ - ../../example/function_type/* \ - ../../example/apply_member_pointer/* \ - ../../example/remove_member_pointer/* \ - ../../example/result_of/* \ - ../../example/std_function/* \