├── .drone.star ├── .drone └── drone.sh ├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── LICENSE.md ├── README.md ├── appveyor.yml ├── boost_hof.pc.in ├── build.jam ├── cmake ├── BCMTest.cmake └── SphinxDoc.cmake ├── doc ├── Jamfile.v2 ├── Makefile ├── _templates │ └── redirect.html ├── conf.py ├── genreadme ├── index.rst ├── make.bat ├── requirements.txt └── src │ ├── acknowledgements.md │ ├── adaptors.rst │ ├── building.md │ ├── concepts.md │ ├── configurations.md │ ├── decorators.rst │ ├── definitions.md │ ├── discussion.rst │ ├── example_overloading.md │ ├── example_polymorphic_constructors.md │ ├── example_print.md │ ├── examples.rst │ ├── faq.md │ ├── functions.rst │ ├── gettingstarted.md │ ├── index.md │ ├── intro.rst │ ├── js │ └── configure.js │ ├── license.md │ ├── more_examples.md │ ├── overview.rst │ ├── partialfunctions.md │ ├── point_free.md │ ├── reference.rst │ ├── traits.rst │ └── utilities.rst ├── example ├── example.h ├── in.cpp ├── pointfree.cpp ├── print.cpp ├── sequence.cpp └── static_if.cpp ├── include └── boost │ ├── hof.hpp │ └── hof │ ├── alias.hpp │ ├── always.hpp │ ├── apply.hpp │ ├── apply_eval.hpp │ ├── arg.hpp │ ├── capture.hpp │ ├── combine.hpp │ ├── compose.hpp │ ├── config.hpp │ ├── construct.hpp │ ├── decay.hpp │ ├── decorate.hpp │ ├── detail │ ├── and.hpp │ ├── callable_base.hpp │ ├── can_be_called.hpp │ ├── compressed_pair.hpp │ ├── constexpr_deduce.hpp │ ├── delegate.hpp │ ├── forward.hpp │ ├── holder.hpp │ ├── intrinsics.hpp │ ├── join.hpp │ ├── make.hpp │ ├── move.hpp │ ├── noexcept.hpp │ ├── pp.hpp │ ├── recursive_constexpr_depth.hpp │ ├── remove_rvalue_reference.hpp │ ├── result_of.hpp │ ├── result_type.hpp │ ├── seq.hpp │ ├── static_const_var.hpp │ ├── unpack_tuple.hpp │ ├── unwrap.hpp │ └── using.hpp │ ├── eval.hpp │ ├── first_of.hpp │ ├── fix.hpp │ ├── flip.hpp │ ├── flow.hpp │ ├── fold.hpp │ ├── function.hpp │ ├── function_param_limit.hpp │ ├── identity.hpp │ ├── if.hpp │ ├── implicit.hpp │ ├── indirect.hpp │ ├── infix.hpp │ ├── is_invocable.hpp │ ├── is_unpackable.hpp │ ├── lambda.hpp │ ├── lazy.hpp │ ├── lift.hpp │ ├── limit.hpp │ ├── match.hpp │ ├── mutable.hpp │ ├── pack.hpp │ ├── partial.hpp │ ├── pipable.hpp │ ├── placeholders.hpp │ ├── proj.hpp │ ├── protect.hpp │ ├── repeat.hpp │ ├── repeat_while.hpp │ ├── result.hpp │ ├── returns.hpp │ ├── reveal.hpp │ ├── reverse_fold.hpp │ ├── rotate.hpp │ ├── static.hpp │ ├── tap.hpp │ ├── unpack.hpp │ ├── unpack_sequence.hpp │ └── version.hpp ├── index.html ├── meta └── libraries.json └── test ├── Jamfile.v2 ├── alias.cpp ├── always.cpp ├── apply.cpp ├── apply_eval.cpp ├── arg.cpp ├── capture.cpp ├── combine.cpp ├── compose.cpp ├── construct.cpp ├── decay.cpp ├── decorate.cpp ├── fail ├── always.cpp ├── apply_eval.cpp ├── flip_lazy.cpp ├── implicit.cpp ├── rotate_lazy.cpp ├── unpack.cpp └── unpack_uncallable.cpp ├── filter.cpp ├── final_base.cpp ├── first_of.cpp ├── fix.cpp ├── flip.cpp ├── flow.cpp ├── fold.cpp ├── function.cpp ├── identity.cpp ├── if.cpp ├── implicit.cpp ├── indirect.cpp ├── infix.cpp ├── is_invocable.cpp ├── issue8.cpp ├── lambda.cpp ├── lazy.cpp ├── lift.cpp ├── limit.cpp ├── match.cpp ├── mutable.cpp ├── pack.cpp ├── partial.cpp ├── pipable.cpp ├── placeholders.cpp ├── proj.cpp ├── protect.cpp ├── repeat.cpp ├── repeat_while.cpp ├── result.cpp ├── returns.cpp ├── reveal.cpp ├── reverse_fold.cpp ├── rotate.cpp ├── static.cpp ├── static_def ├── static_def.cpp ├── static_def.hpp └── static_def2.cpp ├── tap.cpp ├── test.hpp ├── tuple_for_each.cpp ├── tuple_transform.cpp ├── unpack.cpp └── virtual_base.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | doc/html/ 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright Paul Fultz II 2016-2018 2 | 3 | Boost Software License - Version 1.0 - August 17th, 2003 4 | 5 | Permission is hereby granted, free of charge, to any person or organization 6 | obtaining a copy of the software and accompanying documentation covered by 7 | this license (the "Software") to use, reproduce, display, distribute, 8 | execute, and transmit the Software, and to prepare derivative works of the 9 | Software, and to permit third-parties to whom the Software is furnished to 10 | do so, all subject to the following: 11 | 12 | The copyright notices in the Software and this entire statement, including 13 | the above license grant, this restriction and the following disclaimer, 14 | must be included in all copies of the Software, in whole or in part, and 15 | all derivative works of the Software, unless such copies or derivative 16 | works are solely in the form of machine-executable object code generated by 17 | a source language processor. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 22 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 23 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 24 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | 2 | 3 | environment: 4 | matrix: 5 | # - GENERATOR: "Visual Studio 14 2015 Win64" 6 | # CONFIG: Debug 7 | 8 | # - GENERATOR: "Visual Studio 14 2015 Win64" 9 | # CONFIG: Release 10 | 11 | - GENERATOR: "Visual Studio 14 2015" 12 | CONFIG: Debug 13 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 14 | 15 | - GENERATOR: "Visual Studio 14 2015" 16 | CONFIG: Release 17 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 18 | 19 | - GENERATOR: "Visual Studio 15 2017" 20 | CONFIG: Debug 21 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 22 | 23 | - GENERATOR: "Visual Studio 15 2017" 24 | CONFIG: Release 25 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 26 | 27 | matrix: 28 | fast_finish: true 29 | 30 | build_script: 31 | - cmd: set PATH=C:\Program Files (x86)\CMake\bin;%PATH% 32 | # - cmd: set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH% 33 | # - cmd: call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\vsvars32.bat" 34 | - cmd: set CTEST_OUTPUT_ON_FAILURE=1 35 | - cmd: cmake --version 36 | - cmd: mkdir build 37 | - cmd: cd build 38 | - cmd: SET CXXFLAGS=/DBOOST_HOF_HAS_GENERIC_LAMBDA=1 39 | - cmd: cmake .. -G"%GENERATOR%" -DBUILD_EXAMPLES=On 40 | - cmd: cmake --build . --config %CONFIG% --target check 41 | 42 | # test_script: 43 | # - cmd: ctest -C Debug --output-on-failure 44 | # - cmd: cd ../../ -------------------------------------------------------------------------------- /boost_hof.pc.in: -------------------------------------------------------------------------------- 1 | Name: boost_hof 2 | Description: C++ function utility library 3 | URL: https://github.com/pfultz2/hof 4 | Version: @boost_hof_VERSION_MAJOR@.@boost_hof_VERSION_MINOR@ 5 | 6 | Cflags: -I@CMAKE_INSTALL_PREFIX@/include 7 | -------------------------------------------------------------------------------- /build.jam: -------------------------------------------------------------------------------- 1 | # Copyright René Ferdinand Rivera Morell 2023-2024 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # (See accompanying file LICENSE_1_0.txt or copy at 4 | # http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | require-b2 5.2 ; 7 | 8 | project /boost/hof 9 | : common-requirements 10 | include 11 | ; 12 | 13 | explicit 14 | [ alias boost_hof : : : : $(boost_dependencies) ] 15 | [ alias all : boost_hof test ] 16 | ; 17 | 18 | call-if : boost-library hof 19 | ; 20 | 21 | -------------------------------------------------------------------------------- /cmake/BCMTest.cmake: -------------------------------------------------------------------------------- 1 | option(BUILD_TESTING off) 2 | 3 | include(CMakeParseArguments) 4 | enable_testing() 5 | 6 | if(NOT TARGET check) 7 | add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C ${CMAKE_CFG_INTDIR}) 8 | endif() 9 | 10 | if(NOT TARGET tests) 11 | add_custom_target(tests COMMENT "Build all tests.") 12 | add_dependencies(check tests) 13 | endif() 14 | 15 | function(bcm_mark_as_test) 16 | foreach(TEST_TARGET ${ARGN}) 17 | if (NOT BUILD_TESTING) 18 | set_target_properties(${TEST_TARGET} 19 | PROPERTIES EXCLUDE_FROM_ALL TRUE 20 | ) 21 | endif() 22 | add_dependencies(tests ${TEST_TARGET}) 23 | endforeach() 24 | endfunction(bcm_mark_as_test) 25 | 26 | function(bcm_add_test) 27 | set(options COMPILE_ONLY WILL_FAIL) 28 | set(oneValueArgs NAME) 29 | set(multiValueArgs SOURCES CONTENT) 30 | 31 | cmake_parse_arguments(PARSE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 32 | 33 | # TODO: Check if name exists 34 | 35 | set(SOURCES ${PARSE_SOURCES}) 36 | if(PARSE_CONTENT) 37 | file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generated-${PARSE_NAME}.cpp "${PARSE_CONTENT}") 38 | set(SOURCES ${CMAKE_CURRENT_BINARY_DIR}/generated-${PARSE_NAME}.cpp) 39 | endif() 40 | 41 | if(PARSE_COMPILE_ONLY) 42 | if(PARSE_WILL_FAIL) 43 | add_library(_${PARSE_NAME}_TEST_FAIL STATIC EXCLUDE_FROM_ALL ${SOURCES}) 44 | add_custom_target(${PARSE_NAME} 45 | COMMAND ${CMAKE_COMMAND} --build . --target _${PARSE_NAME}_TEST_FAIL --config $ 46 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) 47 | add_test(NAME ${PARSE_NAME} 48 | COMMAND ${CMAKE_COMMAND} --build . --target _${PARSE_NAME}_TEST_FAIL --config $ 49 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) 50 | set_tests_properties(${PARSE_NAME} PROPERTIES WILL_FAIL TRUE) 51 | else() 52 | add_library(${PARSE_NAME} STATIC ${SOURCES}) 53 | bcm_mark_as_test(${PARSE_NAME}) 54 | endif() 55 | else() 56 | add_executable (${PARSE_NAME} ${SOURCES}) 57 | bcm_mark_as_test(${PARSE_NAME}) 58 | if(WIN32) 59 | add_test(NAME ${PARSE_NAME} WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH} COMMAND ${PARSE_NAME}${CMAKE_EXECUTABLE_SUFFIX}) 60 | else() 61 | add_test(NAME ${PARSE_NAME} COMMAND ${PARSE_NAME}) 62 | endif() 63 | if(WILL_FAIL) 64 | set_tests_properties(${PARSE_NAME} PROPERTIES WILL_FAIL TRUE) 65 | endif() 66 | endif() 67 | endfunction(bcm_add_test) 68 | 69 | function(bcm_test_header) 70 | set(options STATIC) 71 | set(oneValueArgs NAME HEADER) 72 | set(multiValueArgs) 73 | 74 | cmake_parse_arguments(PARSE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 75 | 76 | if(PARSE_STATIC) 77 | file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/header-main-include-${PARSE_NAME}.cpp 78 | "#include <${PARSE_HEADER}>\nint main() {}\n" 79 | ) 80 | file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/header-static-include-${PARSE_NAME}.cpp 81 | "#include <${PARSE_HEADER}>\n" 82 | ) 83 | bcm_add_test(NAME header-static-include-${PARSE_NAME} SOURCES 84 | ${CMAKE_CURRENT_BINARY_DIR}/header-main-include-${PARSE_NAME}.cpp 85 | ${CMAKE_CURRENT_BINARY_DIR}/header-static-include-${PARSE_NAME}.cpp 86 | ) 87 | else() 88 | bcm_add_test(NAME header-include-${PARSE_NAME} CONTENT 89 | "#include <${PARSE_HEADER}>\nint main() {}\n" 90 | ) 91 | endif() 92 | endfunction(bcm_test_header) 93 | -------------------------------------------------------------------------------- /cmake/SphinxDoc.cmake: -------------------------------------------------------------------------------- 1 | include(CMakeParseArguments) 2 | include(ProcessorCount) 3 | 4 | find_program(SPHINX_EXECUTABLE NAMES sphinx-build 5 | HINTS 6 | $ENV{SPHINX_DIR} 7 | PATH_SUFFIXES bin 8 | DOC "Sphinx documentation generator" 9 | ) 10 | 11 | mark_as_advanced(SPHINX_EXECUTABLE) 12 | 13 | function(clean_doc_output DIR) 14 | set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${DIR}) 15 | endfunction() 16 | 17 | set(BINARY_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/sphinx/_build") 18 | 19 | # Sphinx cache with pickled ReST documents 20 | set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/sphinx/_doctrees") 21 | 22 | # HTML output directory 23 | set(SPHINX_DEFAULT_HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/sphinx/html") 24 | function(add_sphinx_doc SRC_DIR) 25 | set(options) 26 | set(oneValueArgs HTML_DIR) 27 | set(multiValueArgs VARS TEMPLATE_VARS) 28 | 29 | cmake_parse_arguments(PARSE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 30 | ProcessorCount(N) 31 | 32 | set(ADDITIONAL_ARGS) 33 | foreach(VAR ${PARSE_VARS}) 34 | list(APPEND ADDITIONAL_ARGS "-D ${VAR}") 35 | endforeach() 36 | foreach(VAR ${PARSE_TEMPLATE_VARS}) 37 | list(APPEND ADDITIONAL_ARGS "-A ${VAR}") 38 | endforeach() 39 | 40 | if(PARSE_HTML_DIR) 41 | set(SPHINX_HTML_DIR ${PARSE_HTML_DIR} CACHE PATH "Path to html output") 42 | else() 43 | set(SPHINX_HTML_DIR ${SPHINX_DEFAULT_HTML_DIR} CACHE PATH "Path to html output") 44 | endif() 45 | 46 | clean_doc_output(${SPHINX_HTML_DIR}) 47 | clean_doc_output(${SPHINX_CACHE_DIR}) 48 | clean_doc_output(${BINARY_BUILD_DIR}) 49 | 50 | add_custom_target(doc 51 | ${SPHINX_EXECUTABLE} 52 | -j ${N} 53 | -n 54 | -b html 55 | -d "${SPHINX_CACHE_DIR}" 56 | ${ADDITIONAL_ARGS} 57 | "${SRC_DIR}" 58 | "${SPHINX_HTML_DIR}" 59 | COMMENT "Building HTML documentation with Sphinx") 60 | endfunction() 61 | 62 | -------------------------------------------------------------------------------- /doc/Jamfile.v2: -------------------------------------------------------------------------------- 1 | #============================================================================= 2 | # Copyright (c) 2017 Paul Fultz II 3 | # Jamfile.v2 4 | # Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | #============================================================================== 7 | project boost/hof/doc ; 8 | 9 | path-constant HERE : . ; 10 | 11 | make hof-doc : : @make-hof-doc ; 12 | 13 | actions make-hof-doc { 14 | sphinx-build -b html $(HERE) $(HERE)/html/ 15 | } 16 | 17 | 18 | alias boostdoc ; 19 | explicit boostdoc ; 20 | alias boostrelease : hof-doc ; 21 | explicit boostrelease ; 22 | 23 | -------------------------------------------------------------------------------- /doc/_templates/redirect.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | Page Redirection 14 | 15 | 16 | 17 | If you are not redirected automatically, follow the link to example 18 | 19 | -------------------------------------------------------------------------------- /doc/genreadme: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cat src/index.md src/building.md | sed -e 's,\](\(.*\)\.md),](http://pfultz2.github.io/Fit/doc/html//en/latest/\1/index.html\),g' 4 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | .. Copyright 2018 Paul Fultz II 2 | Distributed under the Boost Software License, Version 1.0. 3 | (http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | .. _contents: 6 | 7 | Boost.HOF 8 | ========= 9 | 10 | **Paul Fultz II** 11 | 12 | .. toctree:: 13 | :maxdepth: 3 14 | 15 | src/intro 16 | src/overview 17 | src/reference 18 | 19 | src/configurations 20 | src/discussion 21 | src/acknowledgements 22 | src/license 23 | 24 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | #============================================================================= 2 | # Copyright (c) 2017 Paul Fultz II 3 | # requirements.txt 4 | # Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | #============================================================================== 7 | sphinx==5.2.1 8 | myst-parser==0.18.1 9 | git+https://github.com/pfultz2/sphinx-boost@8ad7d424c6b613864976546d801439c34a27e3f6 10 | -------------------------------------------------------------------------------- /doc/src/acknowledgements.md: -------------------------------------------------------------------------------- 1 | Acknowledgements 2 | ================ 3 | 4 | * [Boost.Egg](http://p-stade.sourceforge.net/boost/libs/egg/doc/html/index.html): A very powerful library for function objects in C++98. 5 | - Shunsuke Sogame 6 | * [Boost.Hana](https://github.com/ldionne/hana): A metaprogramming library with many functional constructs 7 | - Louis Dionne 8 | * [named-operators](https://github.com/klmr/named-operator): A library to create named operators 9 | - Konrad Rudolph 10 | * [Pack/Unpack without Using Tuple](http://jamboree.github.io/cout/tricks/2014/07/21/pack-unpack-without-using-tuple.html) 11 | - Jamboree 12 | * [for_each_argument](http://isocpp.org/blog/2015/01/for-each-argument-sean-parent) 13 | - Sean Parent 14 | * [Suggested Design for Customization Points](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html) 15 | - Eric Niebler 16 | * [FC++](https://yanniss.github.io/fc++/): Functional Programming in C++ 17 | - Brian McNamara and Yannis Smaragdakis 18 | * [Boost.Phoenix](http://www.boost.org/doc/libs/1_59_0/libs/phoenix/doc/html/index.html) 19 | - Joel de Guzman, Dan Marsden, Thomas Heller, and John Fletcher 20 | -------------------------------------------------------------------------------- /doc/src/adaptors.rst: -------------------------------------------------------------------------------- 1 | .. Copyright 2018 Paul Fultz II 2 | Distributed under the Boost Software License, Version 1.0. 3 | (http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | Function Adaptors 6 | ================= 7 | 8 | .. toctree:: 9 | :maxdepth: 1 10 | 11 | ../../include/boost/hof/combine 12 | ../../include/boost/hof/compose 13 | ../../include/boost/hof/decorate 14 | ../../include/boost/hof/first_of 15 | ../../include/boost/hof/fix 16 | ../../include/boost/hof/flip 17 | ../../include/boost/hof/flow 18 | ../../include/boost/hof/fold 19 | ../../include/boost/hof/implicit 20 | ../../include/boost/hof/indirect 21 | ../../include/boost/hof/infix 22 | ../../include/boost/hof/lazy 23 | ../../include/boost/hof/match 24 | ../../include/boost/hof/mutable 25 | ../../include/boost/hof/partial 26 | ../../include/boost/hof/pipable 27 | ../../include/boost/hof/proj 28 | ../../include/boost/hof/protect 29 | ../../include/boost/hof/result 30 | ../../include/boost/hof/reveal 31 | ../../include/boost/hof/reverse_fold 32 | ../../include/boost/hof/rotate 33 | ../../include/boost/hof/static 34 | ../../include/boost/hof/unpack -------------------------------------------------------------------------------- /doc/src/building.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | Building 7 | ======== 8 | 9 | Boost.HigherOrderFunctions library uses cmake to build. To configure with cmake create a build directory, and run cmake: 10 | 11 | mkdir build 12 | cd build 13 | cmake .. 14 | 15 | Installing 16 | ---------- 17 | 18 | To install the library just run the `install` target: 19 | 20 | cmake --build . --target install 21 | 22 | Tests 23 | ----- 24 | 25 | The tests can be built and run by using the `check` target: 26 | 27 | cmake --build . --target check 28 | 29 | The tests can also be run using Boost.Build, just copy library to the boost source tree, and then: 30 | 31 | cd test 32 | b2 33 | 34 | Documentation 35 | ------------- 36 | 37 | The documentation is built using Sphinx. First, install the requirements needed for the documentation using `pip`: 38 | 39 | pip install -r doc/requirements.txt 40 | 41 | Then html documentation can be generated using `sphinx-build`: 42 | 43 | sphinx-build -b html doc/ doc/html/ 44 | 45 | The final docs will be in the `doc/html` folder. 46 | 47 | -------------------------------------------------------------------------------- /doc/src/configurations.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | Configurations 7 | ============== 8 | 9 | There are several configuration macros that control the behavior of Boost.HigherOrderFunctions library. 10 | 11 | ```eval_rst 12 | +-----------------------------------------+--------------------------------------------------------------------------------+ 13 | | Name | Description | 14 | +=========================================+================================================================================+ 15 | | ``BOOST_HOF_CHECK_UNPACK_SEQUENCE`` | Unpack has extra checks to ensure that the function will be invoked with the | 16 | | | sequence. This extra check can help improve error reporting but it can slow | 17 | | | down compilation. This is enabled by default. | 18 | +-----------------------------------------+--------------------------------------------------------------------------------+ 19 | | ``BOOST_HOF_NO_EXPRESSION_SFINAE`` | This controls whether the library will use expression SFINAE to detect the | 20 | | | callability of functions. On MSVC, this is enabled by default, since it does | 21 | | | not have full support for expression SFINAE. | 22 | +-----------------------------------------+--------------------------------------------------------------------------------+ 23 | | ``BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH`` | Because C++ instantiates `constexpr` functions eagerly, recursion with | 24 | | | `constexpr` functions can cause the compiler to reach its internal limits. The | 25 | | | setting is used by the library to set a limit on recursion depth to avoid | 26 | | | infinite template instantiations. The default is 16, but increasing the limit | 27 | | | can increase compile times. | 28 | +-----------------------------------------+--------------------------------------------------------------------------------+ 29 | ``` 30 | -------------------------------------------------------------------------------- /doc/src/decorators.rst: -------------------------------------------------------------------------------- 1 | .. Copyright 2018 Paul Fultz II 2 | Distributed under the Boost Software License, Version 1.0. 3 | (http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | Decorators 6 | ========== 7 | 8 | .. toctree:: 9 | :maxdepth: 1 10 | 11 | ../../include/boost/hof/capture 12 | ../../include/boost/hof/if 13 | ../../include/boost/hof/limit 14 | ../../include/boost/hof/repeat 15 | ../../include/boost/hof/repeat_while -------------------------------------------------------------------------------- /doc/src/definitions.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | Definitions 7 | =========== 8 | 9 | Function Adaptor 10 | ---------------- 11 | 12 | A [function adaptor]() takes a function(or functions) and returns a new function with enhanced capability. Each adaptor has a functional form with a corresponding class with `_adaptor` appended to it: 13 | 14 | ```cpp 15 | template 16 | FunctionAdaptor_adaptor FunctionAdaptor(Fs...); 17 | ``` 18 | 19 | Both the functional form and the class form can be used to construct the adaptor. 20 | 21 | Static Function Adaptor 22 | ----------------------- 23 | 24 | A static function adaptor is a [function adaptor]() that doesn't have a functional form. It is only a class. It has an additional requirement that the function is [`DefaultConstructible`](DefaultConstructible): 25 | 26 | ```cpp 27 | template 28 | class StaticFunctionAdaptor; 29 | ``` 30 | 31 | Decorator 32 | --------- 33 | 34 | A decorator is a function that returns a [function adaptor](). The [function adaptor]() may be an unspecified or private type. 35 | 36 | ```cpp 37 | template 38 | FunctionAdaptor Decorator(Ts...); 39 | ``` 40 | 41 | Semantics 42 | --------- 43 | 44 | Some parts of the documentation provide the meaning(or equivalence) of an expression. Here is a guide of those symbols: 45 | 46 | * `f`, `g`, `fs`, `gs`, `p` are functions 47 | * `x`, `y`, `xs`, `ys` are parameters to a function 48 | * `T` represents some type 49 | * `...` are parameter packs and represent variadic parameters 50 | 51 | Signatures 52 | ---------- 53 | 54 | All the functions are global function objects except where an explicit template parameter is required on older compilers. However, the documentation still shows the traditional signature since it is much clearer. So instead of writing this: 55 | 56 | ```cpp 57 | struct if_f 58 | { 59 | template 60 | constexpr auto operator()(IntegralConstant) const; 61 | }; 62 | const constexpr if_f if_ = {}; 63 | ``` 64 | 65 | The direct function signature is written even though it is actually declared like above: 66 | 67 | ```cpp 68 | template 69 | constexpr auto if_(IntegralConstant); 70 | ``` 71 | 72 | Its usage is the same except it has the extra benefit that the function can be directly passed to another function. 73 | 74 | -------------------------------------------------------------------------------- /doc/src/discussion.rst: -------------------------------------------------------------------------------- 1 | .. Copyright 2018 Paul Fultz II 2 | Distributed under the Boost Software License, Version 1.0. 3 | (http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | Discussion 6 | ========== 7 | 8 | .. toctree:: 9 | :maxdepth: 2 10 | 11 | partialfunctions 12 | faq 13 | -------------------------------------------------------------------------------- /doc/src/example_polymorphic_constructors.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | Polymorphic constructors 7 | ======================== 8 | 9 | Writing polymorphic constructors(such as `make_tuple`) is a boilerplate that 10 | has to be written over and over again for template classes: 11 | 12 | template 13 | struct unwrap_refwrapper 14 | { 15 | typedef T type; 16 | }; 17 | 18 | template 19 | struct unwrap_refwrapper> 20 | { 21 | typedef T& type; 22 | }; 23 | 24 | template 25 | struct unwrap_ref_decay 26 | : unwrap_refwrapper::type> 27 | {}; 28 | 29 | template 30 | std::tuple::type...> make_tuple(Types&&... args) 31 | { 32 | return std::tuple::type...>(std::forward(args)...); 33 | } 34 | 35 | The [`construct`](include/boost/hof/construct) function takes care of all this boilerplate, and the above can be simply written like this: 36 | 37 | BOOST_HOF_STATIC_FUNCTION(make_tuple) = construct(); 38 | -------------------------------------------------------------------------------- /doc/src/examples.rst: -------------------------------------------------------------------------------- 1 | .. Copyright 2018 Paul Fultz II 2 | Distributed under the Boost Software License, Version 1.0. 3 | (http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | Examples 6 | ======== 7 | 8 | .. toctree:: 9 | :maxdepth: 1 10 | 11 | example_print 12 | example_overloading 13 | example_polymorphic_constructors 14 | more_examples -------------------------------------------------------------------------------- /doc/src/faq.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | FAQ 7 | === 8 | 9 | #### Q: Why is `const` required for the call operator on function objects? 10 | 11 | Mutable function objects are not prohibited, they just need to be explicit by 12 | using the adaptor [`mutable_`](/include/boost/hof/mutable). The main reason for this, is that it can lead to 13 | many surprising behaviours. Many times function objects are copied by value 14 | everywhere. For example, 15 | 16 | ```cpp 17 | struct counter 18 | { 19 | int i; 20 | counter() : i(0) 21 | {} 22 | 23 | template 24 | int operator()(Ts&&...) 25 | { 26 | return i++; 27 | } 28 | }; 29 | 30 | 31 | counter c{}; 32 | proj(mutable_(c))(1,1); 33 | // Prints 0, not 2 34 | std::cout << c.i << std::endl; 35 | ``` 36 | 37 | The example won't ever yield the expected value, because the function mutates 38 | a copy of the objects. Instead, `std::ref` should be used: 39 | 40 | ```cpp 41 | counter c{}; 42 | proj(std::ref(c))(1,1); 43 | // Prints 2 44 | std::cout << c.i << std::endl; 45 | ``` 46 | 47 | Which will print the expected value. 48 | 49 | Another reason why `const` is required is because of supporting `constexpr` on 50 | C++11 compilers. In C++11, `constexpr` implies `const`, so it would be 51 | impossible to provide a non-const overload for functions that is `constexpr`. 52 | Instead, `constexpr` would have to be made explicit. Considering the pitfalls 53 | of mutable function objects, it would be better to make mutability explicit 54 | rather than `constexpr`. 55 | 56 | #### Q: Is the reinterpret cast in BOOST_HOF_STATIC_LAMBDA undefined behaviour? 57 | 58 | Not really, since the objects are empty, there is no data access. There is a 59 | static assert to guard against this restriction. 60 | 61 | Now there could be an insane implementation where this doesn't work(perhaps 62 | the lambdas are not empty for some strange reason), which the library would 63 | have to apply a different technique to make it work. However, this is quite 64 | unlikely considering that C++ will probably get constexpr lambdas and inline 65 | variables in the future. 66 | 67 | Alternatively, the factory pattern can be used instead of 68 | [`BOOST_HOF_STATIC_LAMBDA_FUNCTION`](BOOST_HOF_STATIC_LAMBDA_FUNCTION), which doesn't require an reinterpret cast: 69 | 70 | ```cpp 71 | struct sum_factory 72 | { 73 | auto operator*() const 74 | { 75 | return [](auto x, auto y) 76 | { 77 | return x + y; 78 | }; 79 | } 80 | } 81 | 82 | BOOST_HOF_STATIC_FUNCTION(sum) = boost::hof::indirect(sum_factory{}); 83 | ``` 84 | -------------------------------------------------------------------------------- /doc/src/functions.rst: -------------------------------------------------------------------------------- 1 | .. Copyright 2018 Paul Fultz II 2 | Distributed under the Boost Software License, Version 1.0. 3 | (http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | Functions 6 | ========= 7 | 8 | .. toctree:: 9 | :maxdepth: 1 10 | 11 | ../../include/boost/hof/always 12 | ../../include/boost/hof/arg 13 | ../../include/boost/hof/construct 14 | ../../include/boost/hof/decay 15 | ../../include/boost/hof/identity 16 | ../../include/boost/hof/placeholders -------------------------------------------------------------------------------- /doc/src/index.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | About 7 | ===== 8 | 9 | HigherOrderFunctions is a header-only C++11/C++14 library that provides utilities for functions and function objects, which can solve many problems with much simpler constructs than what's traditionally been done with metaprogramming. 10 | 11 | HigherOrderFunctions is: 12 | 13 | - Modern: HigherOrderFunctions takes advantages of modern C++11/C++14 features. It supports both `constexpr` initialization and `constexpr` evaluation of functions. It takes advantage of type deduction, variadic templates, and perfect forwarding to provide a simple and modern interface. 14 | - Relevant: HigherOrderFunctions provides utilities for functions and does not try to implement a functional language in C++. As such, HigherOrderFunctions solves many problems relevant to C++ programmers, including initialization of function objects and lambdas, overloading with ordering, improved return type deduction, and much more. 15 | - Lightweight: HigherOrderFunctions builds simple lightweight abstraction on top of function objects. It does not require subscribing to an entire framework. Just use the parts you need. 16 | 17 | HigherOrderFunctions is divided into three components: 18 | 19 | * Function Adaptors and Decorators: These enhance functions with additional capability. 20 | * Functions: These return functions that achieve a specific purpose. 21 | * Utilities: These are general utilities that are useful when defining or using functions 22 | 23 | GitHub: [https://github.com/pfultz2/higherorderfunctions/](https://github.com/pfultz2/higherorderfunctions/) 24 | 25 | Documentation: [http://pfultz2.github.io/higherorderfunctions/doc/html/](http://pfultz2.github.io/higherorderfunctions/doc/html/) 26 | 27 | Motivation 28 | ========== 29 | 30 | - Improve the expressiveness and capabilities of functions, including first-class citizens for function overload set, extension methods, infix operators and much more. 31 | - Simplify constructs in C++ that have generally required metaprogramming 32 | - Enable point-free style programming 33 | - Workaround the limitations of lambdas in C++14 34 | 35 | Requirements 36 | ============ 37 | 38 | This requires a C++11 compiler. There are no third-party dependencies. This has been tested on clang 3.5-3.8, gcc 4.6-7, and Visual Studio 2015 and 2017. 39 | 40 | Constexpr support 41 | ---------------- 42 | 43 | Both MSVC and gcc 4.6 have limited constexpr support due to many bugs in the implementation of constexpr. However, constexpr initialization of functions is supported when using the [`BOOST_HOF_STATIC_FUNCTION`](BOOST_HOF_STATIC_FUNCTION) and [`BOOST_HOF_STATIC_LAMBDA_FUNCTION`](BOOST_HOF_STATIC_LAMBDA_FUNCTION) constructs. 44 | 45 | Noexcept support 46 | ---------------- 47 | 48 | On older compilers such as gcc 4.6 and gcc 4.7, `noexcept` is not used due to many bugs in the implementation. Also, most compilers don't support deducing `noexcept` with member function pointers. Only newer versions of gcc(4.9 and later) support this. 49 | -------------------------------------------------------------------------------- /doc/src/intro.rst: -------------------------------------------------------------------------------- 1 | .. Copyright 2018 Paul Fultz II 2 | Distributed under the Boost Software License, Version 1.0. 3 | (http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | Introduction 6 | ============ 7 | 8 | .. toctree:: 9 | :maxdepth: 2 10 | 11 | index 12 | building 13 | gettingstarted 14 | examples 15 | point_free 16 | -------------------------------------------------------------------------------- /doc/src/js/configure.js: -------------------------------------------------------------------------------- 1 | if (typeof $ === "function"){ 2 | $( document ).ready(function() { 3 | console.log("Configure hljs"); 4 | hljs.configure({languages:['cpp']}); 5 | }); 6 | } 7 | -------------------------------------------------------------------------------- /doc/src/license.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | License 7 | ======= 8 | 9 | Boost Software License - Version 1.0 - August 17th, 2003 10 | 11 | Permission is hereby granted, free of charge, to any person or organization 12 | obtaining a copy of the software and accompanying documentation covered by 13 | this license (the "Software") to use, reproduce, display, distribute, 14 | execute, and transmit the Software, and to prepare derivative works of the 15 | Software, and to permit third-parties to whom the Software is furnished to 16 | do so, all subject to the following: 17 | 18 | The copyright notices in the Software and this entire statement, including 19 | the above license grant, this restriction and the following disclaimer, 20 | must be included in all copies of the Software, in whole or in part, and 21 | all derivative works of the Software, unless such copies or derivative 22 | works are solely in the form of machine-executable object code generated by 23 | a source language processor. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 28 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 29 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 30 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 31 | -------------------------------------------------------------------------------- /doc/src/more_examples.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | More examples 7 | ============= 8 | 9 | As Boost.HigherOrderFunctions is a collection of generic utilities 10 | related to functions, there are many useful cases with the library, but a key 11 | point of many of these utilities is that they can solve these problems with 12 | much simpler constructs than what's traditionally been done with 13 | metaprogramming. Let's take look at some of the use cases for using Boost.HigherOrderFunctions. 14 | 15 | Initialization 16 | -------------- 17 | 18 | The [`BOOST_HOF_STATIC_FUNCTION`](/include/boost/hof/function) will help initialize function objects at 19 | global scope, and will ensure that it is initialized at compile-time and (on 20 | platforms that support it) will have a unique address across translation 21 | units, thereby reducing executable bloat and potential ODR violations. 22 | 23 | In addition, [`BOOST_HOF_STATIC_LAMBDA_FUNCTION`](/include/boost/hof/lambda) allows initializing a lambda 24 | in the same manner. This allows for simple and compact function definitions 25 | when working with generic lambdas and function adaptors. 26 | 27 | Of course, the library can still be used without requiring global function 28 | objects for those who prefer to avoid them will still find the library useful. 29 | 30 | 31 | Projections 32 | ----------- 33 | 34 | Instead of writing the projection multiple times in algorithms: 35 | 36 | std::sort(std::begin(people), std::end(people), 37 | [](const Person& a, const Person& b) { 38 | return a.year_of_birth < b.year_of_birth; 39 | }); 40 | 41 | We can use the [`proj`](/include/boost/hof/by) adaptor to project `year_of_birth` on the comparison 42 | operator: 43 | 44 | std::sort(std::begin(people), std::end(people), 45 | proj(&Person::year_of_birth, _ < _)); 46 | 47 | Ordering evaluation of arguments 48 | -------------------------------- 49 | 50 | When we write `f(foo(), bar())`, the standard does not guarantee the order in 51 | which the `foo()` and `bar()` arguments are evaluated. So with `apply_eval` we 52 | can order them from left-to-right: 53 | 54 | apply_eval(f, [&]{ return foo(); }, [&]{ return bar(); }); 55 | 56 | Extension methods 57 | ----------------- 58 | 59 | Chaining many functions together, like what is done for range based libraries, 60 | can make things hard to read: 61 | 62 | auto r = transform( 63 | filter( 64 | numbers, 65 | [](int x) { return x > 2; } 66 | ), 67 | [](int x) { return x * x; } 68 | ); 69 | 70 | It would be nice to write this: 71 | 72 | auto r = numbers 73 | .filter([](int x) { return x > 2; }) 74 | .transform([](int x) { return x * x; }); 75 | 76 | The proposal [N4165](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4165.pdf) 77 | for Unified Call Syntax(UFCS) would have allowed a function call of `x.f(y)` to become 78 | `f(x, y)`. However, this was rejected by the committee. So instead pipable functions can be 79 | used to achieve extension methods. So it can be written like this: 80 | 81 | auto r = numbers 82 | | filter([](int x) { return x > 2; }) 83 | | transform([](int x) { return x * x; }); 84 | 85 | Now, if some users feel a little worried about overloading the _bitwise or_ 86 | operator, pipable functions can also be used with [`flow`](/include/boost/hof/flow) like this: 87 | 88 | auto r = flow( 89 | filter([](int x) { return x > 2; }), 90 | transform([](int x) { return x * x; }) 91 | )(numbers); 92 | 93 | No fancy or confusing operating overloading and everything is still quite 94 | readable. 95 | 96 | -------------------------------------------------------------------------------- /doc/src/overview.rst: -------------------------------------------------------------------------------- 1 | .. Copyright 2018 Paul Fultz II 2 | Distributed under the Boost Software License, Version 1.0. 3 | (http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | Overview 6 | ======== 7 | 8 | .. toctree:: 9 | :maxdepth: 2 10 | 11 | definitions 12 | concepts 13 | -------------------------------------------------------------------------------- /doc/src/partialfunctions.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | Partial function evaluation 7 | =========================== 8 | 9 | Many of the adaptors(such as [partial](partial) or [pipable](pipable)) in the library supports optional partial evaluation of functions. For example, if we have the `sum` function adapted with the `partial` adaptor: 10 | 11 | auto sum = partial([](int x, int y) 12 | { 13 | return x+y; 14 | }); 15 | 16 | So if we write `sum(1, 2)` it will return 3, however, if we write `sum(1)` it will return a new function, which when called again, it will evaluate the function and return 3: 17 | 18 | int i = sum(1, 2); // Returns 3 19 | auto f = sum(1); 20 | int j = f(2); // returns 3 21 | 22 | Of course due to limitations in C++, deciding whether evaluate the function or to partially evaluated it, is based on the callability of the function and not arity. So if we call `sum(1, 2, 3)`, it will return a function: 23 | 24 | auto f = sum(1, 2, 3); 25 | 26 | However, this can get out of hand as the function `f` will never be evaluated. Plus, it would be nice to produce an error at the point of calling the function rather than a confusing error of trying to use a partial function. The [limit](limit) decorator lets us annotate the function with the max arity: 27 | 28 | auto sum = partial(limit_c<2>([](int x, int y) 29 | { 30 | return x+y; 31 | })); 32 | 33 | So now if we call `sum(1, 2, 3)`, we will get a compiler error. So this improves the situation, but it is not without its limitations. For example if we were to define a triple sum using the [pipable](pipable) adaptor: 34 | 35 | auto sum = pipable(limit_c<3>([](int x, int y, int z) 36 | { 37 | return x+y+z; 38 | })); 39 | 40 | So if we call `sum(1)`, there is no compiler error, not until we try to pipe in a value: 41 | 42 | auto f = sum(1); // No error here 43 | auto i = 2 | f; // Compile error 44 | 45 | Of course, the goal may not be to use the pipable call, which could lead to some confusing errors. Currently, there is not a good solution to this. 46 | 47 | -------------------------------------------------------------------------------- /doc/src/reference.rst: -------------------------------------------------------------------------------- 1 | .. Copyright 2018 Paul Fultz II 2 | Distributed under the Boost Software License, Version 1.0. 3 | (http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | Reference 6 | ========= 7 | 8 | .. toctree:: 9 | :maxdepth: 2 10 | 11 | adaptors 12 | decorators 13 | functions 14 | traits 15 | utilities 16 | -------------------------------------------------------------------------------- /doc/src/traits.rst: -------------------------------------------------------------------------------- 1 | .. Copyright 2018 Paul Fultz II 2 | Distributed under the Boost Software License, Version 1.0. 3 | (http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | Traits 6 | ====== 7 | 8 | .. toctree:: 9 | :maxdepth: 1 10 | 11 | ../../include/boost/hof/function_param_limit 12 | ../../include/boost/hof/is_invocable 13 | ../../include/boost/hof/is_unpackable 14 | ../../include/boost/hof/unpack_sequence -------------------------------------------------------------------------------- /doc/src/utilities.rst: -------------------------------------------------------------------------------- 1 | .. Copyright 2018 Paul Fultz II 2 | Distributed under the Boost Software License, Version 1.0. 3 | (http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | Utilities 6 | ========= 7 | 8 | .. toctree:: 9 | :maxdepth: 1 10 | 11 | ../../include/boost/hof/apply 12 | ../../include/boost/hof/apply_eval 13 | ../../include/boost/hof/eval 14 | ../../include/boost/hof/function 15 | ../../include/boost/hof/lambda 16 | ../../include/boost/hof/lift 17 | ../../include/boost/hof/pack 18 | ../../include/boost/hof/returns 19 | ../../include/boost/hof/tap 20 | -------------------------------------------------------------------------------- /example/example.h: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2016 Paul Fultz II 3 | example.h 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | 8 | #ifndef BOOST_HOF_GUARD_EXAMPLE_H 9 | #define BOOST_HOF_GUARD_EXAMPLE_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /example/in.cpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2017 Paul Fultz II 3 | in.cpp 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | /*============================================================================= 8 | Copyright (c) 2016 Paul Fultz II 9 | in.cpp 10 | Distributed under the Boost Software License, Version 1.0. (See accompanying 11 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 12 | ==============================================================================*/ 13 | 14 | #include "example.h" 15 | 16 | using namespace boost::hof; 17 | 18 | #ifdef _MSC_VER 19 | template 20 | auto member_find(const R& r, const T& x) BOOST_HOF_RETURNS(r.find(x)); 21 | #endif 22 | 23 | // Function to find an iterator using a containers built-in find if available 24 | BOOST_HOF_STATIC_LAMBDA_FUNCTION(find_iterator) = first_of( 25 | [](const std::string& s, const auto& x) 26 | { 27 | auto index = s.find(x); 28 | if (index == std::string::npos) return s.end(); 29 | else return s.begin() + index; 30 | }, 31 | #ifdef _MSC_VER 32 | // On MSVC, trailing decltype doesn't work with generic lambdas, so a 33 | // seperate function can be used instead. 34 | BOOST_HOF_LIFT(member_find), 35 | #else 36 | [](const auto& r, const auto& x) BOOST_HOF_RETURNS(r.find(x)), 37 | #endif 38 | [](const auto& r, const auto& x) 39 | { 40 | using std::begin; 41 | using std::end; 42 | return std::find(begin(r), end(r), x); 43 | } 44 | ); 45 | // Implement an infix `in` operator to check if a range contains an element 46 | BOOST_HOF_STATIC_LAMBDA_FUNCTION(in) = infix( 47 | [](const auto& x, const auto& r) 48 | { 49 | using std::end; 50 | return find_iterator(r, x) != end(r); 51 | } 52 | ); 53 | // Negate version of `in` 54 | BOOST_HOF_STATIC_LAMBDA_FUNCTION(not_in) = infix(compose(not _, in)); 55 | 56 | int main() 57 | { 58 | // Check if vector contains element 59 | std::vector numbers = { 1, 2, 3, 4, 5 }; 60 | if (5 numbers) std::cout << "Yes" << std::endl; 61 | 62 | // Check if string contains element 63 | std::string s = "hello world"; 64 | if ("hello" s) std::cout << "Yes" << std::endl; 65 | 66 | // Check if map contains element 67 | std::map number_map = { 68 | { 1, "1" }, 69 | { 2, "2" }, 70 | { 3, "3" }, 71 | { 4, "4" } 72 | }; 73 | 74 | if (4 number_map) std::cout << "Yes" << std::endl; 75 | 76 | // Check if map doesn't contains element 77 | if (not (8 numbers)) std::cout << "No" << std::endl; 78 | if (8 numbers) std::cout << "No" << std::endl; 79 | 80 | } 81 | 82 | -------------------------------------------------------------------------------- /example/pointfree.cpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2017 Paul Fultz II 3 | pointfree.cpp 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | /*============================================================================= 8 | Copyright (c) 2016 Paul Fultz II 9 | pointfree.cpp 10 | Distributed under the Boost Software License, Version 1.0. (See accompanying 11 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 12 | ==============================================================================*/ 13 | 14 | #include "example.h" 15 | 16 | using namespace boost::hof; 17 | 18 | BOOST_HOF_STATIC_FUNCTION(simple_print) = BOOST_HOF_LIFT(std::ref(std::cout) << _); 19 | BOOST_HOF_STATIC_FUNCTION(print) = proj(simple_print); 20 | BOOST_HOF_STATIC_FUNCTION(print_lines) = proj(flow(simple_print, _ << std::integral_constant{})); 21 | BOOST_HOF_STATIC_FUNCTION(max) = fold(BOOST_HOF_LIFT(std::max)); 22 | 23 | int main() 24 | { 25 | simple_print("Hello\n"); 26 | print("Hello", "World\n"); 27 | print_lines("Hello", "World"); 28 | 29 | auto n = max(1, 2, 4, 3); // Returns 4 30 | auto m = max(0.1, 0.2, 0.5, 0.4); // Returns 0.5 31 | 32 | print_lines(n, m); 33 | } 34 | -------------------------------------------------------------------------------- /example/print.cpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2017 Paul Fultz II 3 | print.cpp 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | /*============================================================================= 8 | Copyright (c) 2016 Paul Fultz II 9 | print.cpp 10 | Distributed under the Boost Software License, Version 1.0. (See accompanying 11 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 12 | ==============================================================================*/ 13 | 14 | #include "example.h" 15 | 16 | using namespace boost::hof; 17 | 18 | // ADL Lookup for ranges 19 | namespace adl { 20 | 21 | using std::begin; 22 | using std::end; 23 | 24 | template 25 | auto adl_begin(R&& r) BOOST_HOF_RETURNS(begin(r)); 26 | template 27 | auto adl_end(R&& r) BOOST_HOF_RETURNS(end(r)); 28 | } 29 | 30 | // Iterate over a tuple 31 | BOOST_HOF_STATIC_LAMBDA_FUNCTION(for_each_tuple) = [](const auto& sequence, auto f) 32 | { 33 | return unpack(proj(f))(sequence); 34 | }; 35 | 36 | #ifdef _MSC_VER 37 | // On MSVC, trailing decltype doesn't work with generic lambdas, so seperate 38 | // functions can be used instead. 39 | template 40 | auto print_with_cout(Self, const T& x) -> decltype(std::cout << x, void()) 41 | { 42 | std::cout << x << std::endl; 43 | } 44 | 45 | template 46 | auto print_with_range(Self self, const T& range) -> decltype(self(*adl::adl_begin(range)), void()) 47 | { 48 | for(const auto& x:range) self(x); 49 | } 50 | 51 | template 52 | auto print_with_tuple(Self self, const T& tuple) -> decltype(for_each_tuple(tuple, self), void()) 53 | { 54 | for_each_tuple(tuple, self); 55 | } 56 | 57 | // Recursively print everything 58 | BOOST_HOF_STATIC_FUNCTION(simple_print) = fix(first_of( 59 | BOOST_HOF_LIFT(print_with_cout), 60 | BOOST_HOF_LIFT(print_with_range), 61 | BOOST_HOF_LIFT(print_with_tuple) 62 | )); 63 | #else 64 | // Recursively print everything 65 | BOOST_HOF_STATIC_LAMBDA_FUNCTION(simple_print) = fix(first_of( 66 | [](auto, const auto& x) -> decltype(std::cout << x, void()) 67 | { 68 | std::cout << x << std::endl; 69 | }, 70 | [](auto self, const auto& range) -> decltype(self(*adl::adl_begin(range)), void()) 71 | { 72 | for(const auto& x:range) self(x); 73 | }, 74 | [](auto self, const auto& tuple) -> decltype(for_each_tuple(tuple, self), void()) 75 | { 76 | for_each_tuple(tuple, self); 77 | } 78 | )); 79 | #endif 80 | 81 | // Make print function varidiac 82 | BOOST_HOF_STATIC_LAMBDA_FUNCTION(print) = proj(simple_print); 83 | 84 | int main() 85 | { 86 | print(5, "Hello world"); 87 | print(5); 88 | std::vector v = { 1, 2, 3, 4 }; 89 | print(v); 90 | 91 | auto t = std::make_tuple(1, 2, 3, 4); 92 | print(t); 93 | 94 | auto m = std::make_tuple(3, v, t); 95 | print(m); 96 | } 97 | -------------------------------------------------------------------------------- /example/static_if.cpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2017 Paul Fultz II 3 | static_if.cpp 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | /*============================================================================= 8 | Copyright (c) 2016 Paul Fultz II 9 | static_if.cpp 10 | Distributed under the Boost Software License, Version 1.0. (See accompanying 11 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 12 | ==============================================================================*/ 13 | 14 | #include "example.h" 15 | 16 | using namespace boost::hof; 17 | 18 | // static_if example taken from Baptiste Wicht: 19 | // http://baptiste-wicht.com/posts/2015/07/simulate-static_if-with-c11c14.html 20 | 21 | template 22 | void decrement_kindof(T& value) 23 | { 24 | eval(first_of( 25 | if_(std::is_same())([&](auto id){ 26 | id(value).pop_back(); 27 | }), 28 | [&](auto id){ 29 | --id(value); 30 | } 31 | )); 32 | } 33 | 34 | int main() 35 | { 36 | std::string s = "hello!"; 37 | decrement_kindof(s); 38 | assert(s == "hello"); 39 | 40 | int i = 4; 41 | decrement_kindof(i); 42 | assert(i == 3); 43 | } 44 | -------------------------------------------------------------------------------- /include/boost/hof.hpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2016 Paul Fultz II 3 | boost/hof.hpp 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | 8 | #ifndef BOOST_HOF_GUARD_BOOST_HOF_HPP 9 | #define BOOST_HOF_GUARD_BOOST_HOF_HPP 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | 58 | 59 | namespace boost { namespace hof { 60 | 61 | }} // namespace boost::hof 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /include/boost/hof/arg.hpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2014 Paul Fultz II 3 | arg.h 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | 8 | #ifndef BOOST_HOF_GUARD_FUNCTION_ARGS_H 9 | #define BOOST_HOF_GUARD_FUNCTION_ARGS_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /// arg 17 | /// === 18 | /// 19 | /// Description 20 | /// ----------- 21 | /// 22 | /// The `arg` function returns a function object that returns the Nth argument 23 | /// passed to it. It actually starts at 1, so it is not the zero-based index 24 | /// of the argument. 25 | /// 26 | /// Synopsis 27 | /// -------- 28 | /// 29 | /// template 30 | /// constexpr auto arg(IntegralConstant); 31 | /// 32 | /// template 33 | /// constexpr auto arg_c(Ts&&...); 34 | /// 35 | /// 36 | /// Example 37 | /// ------- 38 | /// 39 | /// #include 40 | /// #include 41 | /// using namespace boost::hof; 42 | /// 43 | /// int main() { 44 | /// assert(arg(std::integral_constant())(1,2,3,4,5) == 3); 45 | /// } 46 | /// 47 | 48 | namespace boost { namespace hof { 49 | 50 | namespace detail { 51 | 52 | template 53 | struct perfect_ref 54 | { 55 | typedef T type; 56 | typedef typename std::remove_reference::type value_type; 57 | T&& value; 58 | constexpr perfect_ref(value_type& x) noexcept 59 | : value(BOOST_HOF_FORWARD(T)(x)) 60 | {} 61 | }; 62 | 63 | template 64 | struct ignore 65 | { 66 | template 67 | constexpr ignore(T&&...) noexcept 68 | {} 69 | }; 70 | 71 | template 72 | struct args_at 73 | { 74 | template 75 | constexpr auto operator()(ignore..., T x, Ts...) const 76 | BOOST_HOF_RETURNS(BOOST_HOF_FORWARD(typename T::type)(x.value)); 77 | }; 78 | 79 | template 80 | constexpr args_at make_args_at(seq) noexcept 81 | { 82 | return {}; 83 | } 84 | 85 | template 86 | constexpr auto get_args(Ts&&... xs) BOOST_HOF_RETURNS 87 | ( 88 | boost::hof::detail::make_args_at(typename gens::type())(nullptr, BOOST_HOF_RETURNS_CONSTRUCT(perfect_ref)(xs)...) 89 | ); 90 | 91 | template 92 | struct make_args_f 93 | { 94 | template::type> 95 | constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS 96 | ( 97 | boost::hof::detail::get_args(BOOST_HOF_FORWARD(Ts)(xs)...) 98 | ); 99 | }; 100 | 101 | struct arg_f 102 | { 103 | template 104 | constexpr make_args_f operator()(IntegralConstant) const noexcept 105 | { 106 | return make_args_f(); 107 | } 108 | }; 109 | 110 | } 111 | #if BOOST_HOF_HAS_VARIABLE_TEMPLATES 112 | template 113 | BOOST_HOF_STATIC_CONSTEXPR detail::make_args_f arg_c = {}; 114 | #else 115 | template 116 | constexpr auto arg_c(Ts&&... xs) BOOST_HOF_RETURNS 117 | ( 118 | boost::hof::detail::get_args(BOOST_HOF_FORWARD(Ts)(xs)...) 119 | ); 120 | #endif 121 | 122 | BOOST_HOF_DECLARE_STATIC_VAR(arg, detail::arg_f); 123 | 124 | }} // namespace boost::hof 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /include/boost/hof/decay.hpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2015 Paul Fultz II 3 | decay.h 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | 8 | #ifndef BOOST_HOF_GUARD_DECAY_H 9 | #define BOOST_HOF_GUARD_DECAY_H 10 | 11 | /// decay 12 | /// ===== 13 | /// 14 | /// Description 15 | /// ----------- 16 | /// 17 | /// The `decay` function is a unary function object that returns what's given to it after decaying its type. 18 | /// 19 | /// Synopsis 20 | /// -------- 21 | /// 22 | /// struct 23 | /// { 24 | /// template 25 | /// constexpr typename decay::type operator()(T&& x) const 26 | /// { 27 | /// return boost::hof::forward(x); 28 | /// } 29 | /// } decay; 30 | /// 31 | /// References 32 | /// ---------- 33 | /// 34 | /// * [n3255](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3255.html) - Proposal for `decay_copy` 35 | /// 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | namespace boost { namespace hof { namespace detail { 43 | 44 | template 45 | struct decay_mf 46 | : unwrap_reference::type> 47 | {}; 48 | 49 | struct decay_f 50 | { 51 | template< 52 | class T, 53 | class Result=typename unwrap_reference::type>::type, 54 | class=typename std::enable_if<(BOOST_HOF_IS_CONSTRUCTIBLE(Result, T))>::type 55 | > 56 | constexpr Result operator()(T&& x) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Result, T&&) 57 | { 58 | return BOOST_HOF_FORWARD(T)(x); 59 | } 60 | }; 61 | 62 | } 63 | 64 | BOOST_HOF_DECLARE_STATIC_VAR(decay, detail::decay_f); 65 | 66 | }} // namespace boost::hof 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /include/boost/hof/detail/and.hpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2015 Paul Fultz II 3 | and.h 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | 8 | #ifndef BOOST_HOF_GUARD_AND_H 9 | #define BOOST_HOF_GUARD_AND_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace boost { namespace hof { namespace detail { 16 | 17 | constexpr bool and_c() 18 | { 19 | return true; 20 | } 21 | 22 | template 23 | constexpr bool and_c(bool b, Ts... bs) 24 | { 25 | return b && and_c(bs...); 26 | } 27 | 28 | #ifdef _MSC_VER 29 | 30 | template 31 | struct and_; 32 | 33 | template 34 | struct and_ 35 | : std::integral_constant::value)> 36 | {}; 37 | 38 | template<> 39 | struct and_<> 40 | : std::true_type 41 | {}; 42 | 43 | #define BOOST_HOF_AND_UNPACK(Bs) (boost::hof::detail::and_c(Bs...)) 44 | #else 45 | template struct bool_seq {}; 46 | template 47 | BOOST_HOF_USING(and_, std::is_same, bool_seq<(Ts::value, true)...>>); 48 | 49 | #define BOOST_HOF_AND_UNPACK(Bs) BOOST_HOF_IS_BASE_OF(boost::hof::detail::bool_seq, boost::hof::detail::bool_seq<(Bs || true)...>) 50 | 51 | #endif 52 | 53 | }}} // namespace boost::hof 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /include/boost/hof/detail/callable_base.hpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2015 Paul Fultz II 3 | callable_base.h 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | 8 | #ifndef BOOST_HOF_GUARD_CALLABLE_BASE_H 9 | #define BOOST_HOF_GUARD_CALLABLE_BASE_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #ifndef BOOST_HOF_CALLABLE_BASE_USE_TEMPLATE_ALIAS 16 | #if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7) 17 | #define BOOST_HOF_CALLABLE_BASE_USE_TEMPLATE_ALIAS 0 18 | #else 19 | #define BOOST_HOF_CALLABLE_BASE_USE_TEMPLATE_ALIAS 1 20 | #endif 21 | #endif 22 | 23 | namespace boost { namespace hof { namespace detail { 24 | 25 | template 26 | struct non_class_function 27 | { 28 | F f; 29 | BOOST_HOF_DELEGATE_CONSTRUCTOR(non_class_function, F, f) 30 | 31 | template 32 | constexpr BOOST_HOF_SFINAE_RESULT(apply_f, id_, id_...) 33 | operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS 34 | ( 35 | boost::hof::apply(f, BOOST_HOF_FORWARD(Ts)(xs)...) 36 | ); 37 | }; 38 | 39 | template 40 | struct callable_base_type 41 | : std::conditional<(BOOST_HOF_IS_CLASS(F) && !BOOST_HOF_IS_FINAL(F) && !BOOST_HOF_IS_POLYMORPHIC(F)), F, non_class_function> 42 | {}; 43 | 44 | #if BOOST_HOF_CALLABLE_BASE_USE_TEMPLATE_ALIAS 45 | template 46 | using callable_base = typename callable_base_type::type; 47 | #else 48 | template 49 | struct callable_base 50 | : callable_base_type::type 51 | { 52 | typedef typename callable_base_type::type base; 53 | BOOST_HOF_INHERIT_CONSTRUCTOR(callable_base, base) 54 | }; 55 | 56 | template 57 | struct callable_base_type> 58 | : callable_base_type 59 | {}; 60 | 61 | #endif 62 | 63 | }}} // namespace boost::hof 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /include/boost/hof/detail/can_be_called.hpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2015 Paul Fultz II 3 | can_be_called.h 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | 8 | #ifndef BOOST_HOF_GUARD_CAN_BE_CALLED_H 9 | #define BOOST_HOF_GUARD_CAN_BE_CALLED_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace boost { namespace hof { namespace detail { 17 | 18 | #if BOOST_HOF_NO_EXPRESSION_SFINAE 19 | struct dont_care 20 | { 21 | dont_care(...); 22 | }; 23 | 24 | template 25 | struct never_care 26 | { 27 | typedef dont_care type; 28 | }; 29 | 30 | struct cant_be_called_type 31 | {}; 32 | 33 | struct no_type 34 | {}; 35 | 36 | template 37 | struct is_callable_wrapper_fallback 38 | { 39 | template 40 | auto operator()(Ts&&...) const 41 | -> decltype(std::declval()(std::declval()...)); 42 | }; 43 | 44 | template::type>::type> 45 | struct is_callable_wrapper_base 46 | : std::conditional> 47 | {}; 48 | 49 | template 50 | struct is_callable_wrapper : is_callable_wrapper_base::type 51 | { 52 | is_callable_wrapper(); 53 | typedef cant_be_called_type const &(*pointer_to_function)(typename never_care::type...); 54 | operator pointer_to_function() const; 55 | }; 56 | 57 | template 58 | struct not_ 59 | : std::integral_constant 60 | {}; 61 | 62 | template 63 | struct can_be_called 64 | : not_()(std::declval()...) 66 | )>::type>> 67 | {}; 68 | 69 | template 70 | struct check_args; 71 | 72 | template 73 | struct check_args 74 | : and_...> 75 | {}; 76 | 77 | template 78 | struct can_be_called 79 | : std::conditional, 81 | std::false_type 82 | >::type 83 | {}; 84 | 85 | template 86 | struct can_be_called 87 | : std::conditional, 89 | std::false_type 90 | >::type 91 | {}; 92 | 93 | #else 94 | 95 | template 96 | T&& called_val() noexcept; 97 | 98 | template 99 | struct callable_args 100 | {}; 101 | 102 | template 103 | struct can_be_called_impl 104 | : std::false_type 105 | {}; 106 | 107 | template 108 | struct can_be_called_impl, typename detail::holder< 109 | decltype( boost::hof::detail::called_val()(boost::hof::detail::called_val()...) ) 110 | >::type> 111 | : std::true_type 112 | {}; 113 | 114 | template 115 | BOOST_HOF_USING(can_be_called, can_be_called_impl>); 116 | 117 | #endif 118 | 119 | }}} // namespace boost::hof 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /include/boost/hof/detail/constexpr_deduce.hpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2015 Paul Fultz II 3 | constexpr_deduce.h 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | 8 | #ifndef BOOST_HOF_GUARD_FUNCTION_CONSTEXPR_DEDUCE_H 9 | #define BOOST_HOF_GUARD_FUNCTION_CONSTEXPR_DEDUCE_H 10 | 11 | #include 12 | 13 | #define BOOST_HOF_CONST_FOLD(x) (__builtin_constant_p(x) ? (x) : (x)) 14 | 15 | #ifndef BOOST_HOF_HAS_CONST_FOLD 16 | #if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7 17 | #define BOOST_HOF_HAS_CONST_FOLD 0 18 | #elif defined(__clang__) || defined (__GNUC__) 19 | #define BOOST_HOF_HAS_CONST_FOLD 1 20 | #else 21 | #define BOOST_HOF_HAS_CONST_FOLD 0 22 | #endif 23 | #endif 24 | 25 | 26 | namespace boost { namespace hof { 27 | 28 | namespace detail { 29 | 30 | struct constexpr_deduce 31 | { 32 | constexpr constexpr_deduce() 33 | {} 34 | template 35 | constexpr operator F() const 36 | { 37 | return F(); 38 | } 39 | }; 40 | 41 | template 42 | struct constexpr_deduce_unique 43 | { 44 | constexpr constexpr_deduce_unique() 45 | {} 46 | #if BOOST_HOF_HAS_CONST_FOLD 47 | template 48 | constexpr operator const F&() const 49 | { 50 | static_assert(BOOST_HOF_IS_EMPTY(F), "Function or lambda expression must be empty"); 51 | return BOOST_HOF_CONST_FOLD(reinterpret_cast(static_const_var())); 52 | } 53 | #else 54 | template 55 | constexpr operator F() const 56 | { 57 | // static_assert(std::is_default_constructible::value, "Function not default constructible"); 58 | return F(); 59 | } 60 | #endif 61 | }; 62 | 63 | }}} // namespace boost::hof 64 | 65 | #define BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE true ? boost::hof::detail::constexpr_deduce() : 66 | #define BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE_UNIQUE(T) true ? boost::hof::detail::constexpr_deduce_unique() : 67 | 68 | #ifdef _MSC_VER 69 | #define BOOST_HOF_DETAIL_MSVC_CONSTEXPR_DEDUCE BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE 70 | #else 71 | #define BOOST_HOF_DETAIL_MSVC_CONSTEXPR_DEDUCE 72 | #endif 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /include/boost/hof/detail/forward.hpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2014 Paul Fultz II 3 | forward.h 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | 8 | #ifndef BOOST_HOF_GUARD_FORWARD_H 9 | #define BOOST_HOF_GUARD_FORWARD_H 10 | 11 | #include 12 | 13 | namespace boost { namespace hof { 14 | 15 | // contexpr-friendly forwarding 16 | 17 | template 18 | constexpr T&& forward(typename std::remove_reference::type& t) noexcept 19 | { return static_cast(t); } 20 | 21 | 22 | template 23 | constexpr T&& forward(typename std::remove_reference::type&& t) noexcept 24 | { 25 | static_assert(!std::is_lvalue_reference::value, "T must not be an lvalue reference type"); 26 | return static_cast(t); 27 | } 28 | 29 | #if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7) || defined(_MSC_VER) 30 | #define BOOST_HOF_FORWARD(...) boost::hof::forward<__VA_ARGS__> 31 | #else 32 | #define BOOST_HOF_FORWARD(...) static_cast<__VA_ARGS__ &&> 33 | #endif 34 | 35 | }} // namespace boost::hof 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/boost/hof/detail/holder.hpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2014 Paul Fultz II 3 | holder.h 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | 8 | #ifndef BOOST_HOF_GUARD_HOLDER_H 9 | #define BOOST_HOF_GUARD_HOLDER_H 10 | 11 | namespace boost { namespace hof { namespace detail { 12 | 13 | template 14 | struct holder 15 | { 16 | typedef void type; 17 | }; 18 | 19 | template class T> 20 | struct template_holder 21 | { 22 | typedef void type; 23 | }; 24 | 25 | }}} // namespace boost::hof 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/boost/hof/detail/join.hpp: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2012 Paul Fultz II 3 | join.h 4 | Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | ==============================================================================*/ 7 | 8 | #ifndef BOOST_HOF_GUARD_FUNCTION_DETAIL_JOIN_H 9 | #define BOOST_HOF_GUARD_FUNCTION_DETAIL_JOIN_H 10 | 11 | #include 12 | 13 | namespace boost { namespace hof { namespace detail { 14 | 15 | template 16 | struct join_args 17 | {}; 18 | 19 | template