summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hof
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/hof
parentInitial commit. (diff)
downloadceph-upstream/16.2.11+ds.tar.xz
ceph-upstream/16.2.11+ds.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/hof')
-rw-r--r--src/boost/libs/hof/CMakeLists.txt159
-rw-r--r--src/boost/libs/hof/LICENSE.md25
-rw-r--r--src/boost/libs/hof/README.md90
-rw-r--r--src/boost/libs/hof/boost_hof.pc.in6
-rw-r--r--src/boost/libs/hof/cmake/BCMTest.cmake92
-rw-r--r--src/boost/libs/hof/cmake/SphinxDoc.cmake61
-rw-r--r--src/boost/libs/hof/example/example.h67
-rw-r--r--src/boost/libs/hof/example/in.cpp81
-rw-r--r--src/boost/libs/hof/example/pointfree.cpp33
-rw-r--r--src/boost/libs/hof/example/print.cpp96
-rw-r--r--src/boost/libs/hof/example/sequence.cpp122
-rw-r--r--src/boost/libs/hof/example/static_if.cpp43
-rw-r--r--src/boost/libs/hof/index.html17
-rw-r--r--src/boost/libs/hof/meta/libraries.json11
-rw-r--r--src/boost/libs/hof/test/Jamfile.v231
-rw-r--r--src/boost/libs/hof/test/alias.cpp24
-rw-r--r--src/boost/libs/hof/test/always.cpp65
-rw-r--r--src/boost/libs/hof/test/apply.cpp467
-rw-r--r--src/boost/libs/hof/test/apply_eval.cpp63
-rw-r--r--src/boost/libs/hof/test/arg.cpp53
-rw-r--r--src/boost/libs/hof/test/capture.cpp96
-rw-r--r--src/boost/libs/hof/test/combine.cpp71
-rw-r--r--src/boost/libs/hof/test/compose.cpp186
-rw-r--r--src/boost/libs/hof/test/construct.cpp222
-rw-r--r--src/boost/libs/hof/test/decay.cpp28
-rw-r--r--src/boost/libs/hof/test/decorate.cpp35
-rw-r--r--src/boost/libs/hof/test/fail/always.cpp14
-rw-r--r--src/boost/libs/hof/test/fail/apply_eval.cpp11
-rw-r--r--src/boost/libs/hof/test/fail/flip_lazy.cpp14
-rw-r--r--src/boost/libs/hof/test/fail/implicit.cpp29
-rw-r--r--src/boost/libs/hof/test/fail/rotate_lazy.cpp14
-rw-r--r--src/boost/libs/hof/test/fail/unpack.cpp27
-rw-r--r--src/boost/libs/hof/test/fail/unpack_uncallable.cpp24
-rw-r--r--src/boost/libs/hof/test/filter.cpp54
-rw-r--r--src/boost/libs/hof/test/final_base.cpp26
-rw-r--r--src/boost/libs/hof/test/first_of.cpp216
-rw-r--r--src/boost/libs/hof/test/fix.cpp100
-rw-r--r--src/boost/libs/hof/test/flip.cpp61
-rw-r--r--src/boost/libs/hof/test/flow.cpp169
-rw-r--r--src/boost/libs/hof/test/fold.cpp93
-rw-r--r--src/boost/libs/hof/test/function.cpp106
-rw-r--r--src/boost/libs/hof/test/identity.cpp68
-rw-r--r--src/boost/libs/hof/test/if.cpp154
-rw-r--r--src/boost/libs/hof/test/implicit.cpp56
-rw-r--r--src/boost/libs/hof/test/indirect.cpp52
-rw-r--r--src/boost/libs/hof/test/infix.cpp115
-rw-r--r--src/boost/libs/hof/test/is_invocable.cpp192
-rw-r--r--src/boost/libs/hof/test/issue8.cpp48
-rw-r--r--src/boost/libs/hof/test/lambda.cpp103
-rw-r--r--src/boost/libs/hof/test/lazy.cpp713
-rw-r--r--src/boost/libs/hof/test/lift.cpp58
-rw-r--r--src/boost/libs/hof/test/limit.cpp49
-rw-r--r--src/boost/libs/hof/test/match.cpp193
-rw-r--r--src/boost/libs/hof/test/mutable.cpp72
-rw-r--r--src/boost/libs/hof/test/pack.cpp395
-rw-r--r--src/boost/libs/hof/test/partial.cpp108
-rw-r--r--src/boost/libs/hof/test/pipable.cpp90
-rw-r--r--src/boost/libs/hof/test/placeholders.cpp813
-rw-r--r--src/boost/libs/hof/test/proj.cpp164
-rw-r--r--src/boost/libs/hof/test/protect.cpp302
-rw-r--r--src/boost/libs/hof/test/repeat.cpp66
-rw-r--r--src/boost/libs/hof/test/repeat_while.cpp95
-rw-r--r--src/boost/libs/hof/test/result.cpp26
-rw-r--r--src/boost/libs/hof/test/returns.cpp56
-rw-r--r--src/boost/libs/hof/test/reveal.cpp157
-rw-r--r--src/boost/libs/hof/test/reverse_fold.cpp93
-rw-r--r--src/boost/libs/hof/test/rotate.cpp71
-rw-r--r--src/boost/libs/hof/test/static.cpp24
-rw-r--r--src/boost/libs/hof/test/static_def/static_def.cpp59
-rw-r--r--src/boost/libs/hof/test/static_def/static_def.hpp61
-rw-r--r--src/boost/libs/hof/test/static_def/static_def2.cpp58
-rw-r--r--src/boost/libs/hof/test/tap.cpp25
-rw-r--r--src/boost/libs/hof/test/test.hpp190
-rw-r--r--src/boost/libs/hof/test/tuple_for_each.cpp247
-rw-r--r--src/boost/libs/hof/test/tuple_transform.cpp90
-rw-r--r--src/boost/libs/hof/test/unpack.cpp255
-rw-r--r--src/boost/libs/hof/test/virtual_base.cpp37
77 files changed, 8557 insertions, 0 deletions
diff --git a/src/boost/libs/hof/CMakeLists.txt b/src/boost/libs/hof/CMakeLists.txt
new file mode 100644
index 000000000..2ba06272e
--- /dev/null
+++ b/src/boost/libs/hof/CMakeLists.txt
@@ -0,0 +1,159 @@
+#=============================================================================
+# Copyright (c) 2017 Paul Fultz II
+# CMakeLists.txt
+# 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)
+#==============================================================================
+cmake_minimum_required (VERSION 2.8)
+project (boost_hof)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
+foreach(level MAJOR MINOR PATCH)
+ file(STRINGS include/boost/hof/version.hpp
+ _define_${level}
+ REGEX "#define BOOST_HOF_${level}_VERSION")
+ string(REGEX MATCH "([0-9]+)" boost_hof_VERSION_${level} "${_define_${level}}")
+endforeach()
+
+include(CheckCXXCompilerFlag)
+enable_language(CXX)
+
+if(NOT CMAKE_CXX_FLAGS MATCHES "-std=")
+
+ if(CMAKE_HOST_APPLE)
+ check_cxx_compiler_flag("-stdlib=libc++" COMPILER_HAS_CXX_FLAG_libcxx)
+ if(COMPILER_HAS_CXX_FLAG_libcxx)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
+ endif()
+ endif()
+
+ set(ENABLE_CXXFLAGS_TO_CHECK
+ -std=gnu++17
+ -std=c++17
+ -std=gnu++1z
+ -std=c++1z
+ -std=gnu++14
+ -std=c++14
+ -std=gnu++1y
+ -std=c++1y
+ -std=gnu++11
+ -std=c++11
+ -std=gnu++0x
+ -std=c++0x)
+
+ foreach(flag ${ENABLE_CXXFLAGS_TO_CHECK})
+ string(REPLACE "-std=" "_" flag_var ${flag})
+ string(REPLACE "+" "x" flag_var ${flag_var})
+ check_cxx_compiler_flag("${flag}" COMPILER_HAS_CXX_FLAG${flag_var})
+ if(COMPILER_HAS_CXX_FLAG${flag_var})
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ break()
+ endif()
+ endforeach()
+
+endif()
+
+install (DIRECTORY include/boost DESTINATION include)
+configure_file(boost_hof.pc.in boost_hof.pc)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/boost_hof.pc DESTINATION lib/pkgconfig)
+
+include(SphinxDoc)
+
+add_sphinx_doc(${CMAKE_CURRENT_SOURCE_DIR}/doc HTML_DIR ${CMAKE_CURRENT_SOURCE_DIR}/doc/html)
+
+include(BCMTest)
+
+include_directories(include)
+
+file(GLOB TESTS test/*.cpp)
+foreach(TEST ${TESTS})
+ get_filename_component(BASE_NAME ${TEST} NAME_WE)
+ bcm_add_test(NAME ${BASE_NAME} SOURCES ${TEST})
+ set_tests_properties(${BASE_NAME} PROPERTIES FAIL_REGULAR_EXPRESSION "FAILED")
+endforeach()
+bcm_add_test(NAME static_def SOURCES test/static_def/static_def.cpp test/static_def/static_def2.cpp)
+set_tests_properties(static_def PROPERTIES FAIL_REGULAR_EXPRESSION "FAILED")
+
+file(GLOB FAIL_TESTS test/fail/*.cpp)
+foreach(TEST ${FAIL_TESTS})
+ get_filename_component(BASE_NAME ${TEST} NAME_WE)
+ bcm_add_test(NAME fail-${BASE_NAME} COMPILE_ONLY WILL_FAIL SOURCES ${TEST})
+endforeach()
+
+file(GLOB HEADERS include/boost/hof/*.hpp)
+foreach(HEADER ${HEADERS})
+ get_filename_component(BASE_NAME ${HEADER} NAME_WE)
+ bcm_test_header(NAME ${BASE_NAME} HEADER boost/hof/${BASE_NAME}.hpp STATIC)
+endforeach()
+bcm_test_header(NAME hof HEADER boost/hof.hpp STATIC)
+
+function(extract_doc SOURCE OUTPUTVAR)
+ file(READ ${SOURCE} CONTENT)
+ string(REGEX REPLACE "(\n(/[^/][^/]|//[^/]|[^/][^/][^/])([^\n])*)" "" CONTENT "\n${CONTENT}")
+ string(REPLACE "/// " "" CONTENT "${CONTENT}")
+ set(${OUTPUTVAR} "${CONTENT}" PARENT_SCOPE)
+endfunction()
+
+function(build_example SECTIONCONTENT NAME)
+ string(MD5 MD5_SECTION "${SECTIONCONTENT}")
+ set(TARGET_NAME "example-${NAME}-${MD5_SECTION}")
+ set(CONTENT "")
+ foreach(LINE ${SECTIONCONTENT})
+ if(LINE MATCHES "^ ")
+ string(SUBSTRING ${LINE} "4" "-1" OUTPUT_LINE)
+ list(APPEND CONTENT ${OUTPUT_LINE})
+ endif()
+ endforeach()
+ string(REPLACE ";" "\n" CONTENT "${CONTENT}")
+ string(REPLACE "$$__semicolon__$$" ";" CONTENT "${CONTENT}")
+ if(NOT CONTENT MATCHES "int main")
+ string(APPEND CONTENT "int main() {}")
+ endif()
+ message(STATUS "Adding example: ${TARGET_NAME}")
+ bcm_add_test(NAME ${TARGET_NAME} CONTENT "${CONTENT}\n")
+endfunction()
+
+function(extract_example SOURCE)
+ extract_doc(${SOURCE} CONTENT)
+ string(REPLACE ";" "$$__semicolon__$$" CONTENT "${CONTENT}")
+ string(REPLACE "\n" ";" CONTENT "${CONTENT}")
+
+ get_filename_component(BASE_NAME ${SOURCE} NAME_WE)
+
+ set(SECTION "")
+ set(PREVLINE "")
+ set(APPEND_SECTION Off)
+ foreach(LINE ${CONTENT})
+ if(APPEND_SECTION)
+ if((LINE MATCHES "^---") OR (LINE MATCHES "^==="))
+ build_example("${SECTION}" ${BASE_NAME})
+ set(APPEND_SECTION Off)
+ set(SECTION "")
+ elseif(NOT PREVLINE MATCHES "^---")
+ list(APPEND SECTION ${PREVLINE})
+ endif()
+ else()
+ if((LINE MATCHES "^---") AND (PREVLINE MATCHES "^Example"))
+ set(APPEND_SECTION One)
+ endif()
+ endif()
+ set(PREVLINE "${LINE}")
+ endforeach()
+ list(APPEND SECTION ${PREVLINE})
+ if(APPEND_SECTION)
+ build_example("${SECTION}" ${BASE_NAME})
+ endif()
+endfunction()
+
+set(BUILD_EXAMPLES off CACHE BOOL "Set this to build the examples")
+
+if (BUILD_EXAMPLES)
+ file(GLOB EXAMPLES example/*.cpp)
+ foreach(EXAMPLE ${EXAMPLES})
+ get_filename_component(BASE_NAME ${EXAMPLE} NAME_WE)
+ bcm_add_test(NAME example-${BASE_NAME} SOURCES ${EXAMPLE})
+ endforeach()
+ foreach(HEADER ${HEADERS})
+ extract_example(${HEADER})
+ endforeach()
+endif()
diff --git a/src/boost/libs/hof/LICENSE.md b/src/boost/libs/hof/LICENSE.md
new file mode 100644
index 000000000..10bd33bcd
--- /dev/null
+++ b/src/boost/libs/hof/LICENSE.md
@@ -0,0 +1,25 @@
+Copyright Paul Fultz II 2016-2018
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/src/boost/libs/hof/README.md b/src/boost/libs/hof/README.md
new file mode 100644
index 000000000..e0cfa0c0b
--- /dev/null
+++ b/src/boost/libs/hof/README.md
@@ -0,0 +1,90 @@
+# Boost.Hof <a target="_blank" href="https://travis-ci.org/boostorg/hof">![Travis status][badge.Travis]</a> <a target="_blank" href="https://ci.appveyor.com/project/pfultz2/hof">![Appveyor status][badge.Appveyor]</a>
+
+About
+=====
+
+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 whats traditionally been done with metaprogramming.
+
+HigherOrderFunctions is:
+
+- Modern: HigherOrderFunctions takes advantages of modern C++11/C++14 features. It support 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.
+- 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.
+- 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.
+
+HigherOrderFunctions is divided into three components:
+
+* Function Adaptors and Decorators: These enhance functions with additional capability.
+* Functions: These return functions that achieve a specific purpose.
+* Utilities: These are general utilities that are useful when defining or using functions
+
+Github: [https://github.com/boostorg/hof/](https://github.com/boostorg/hof/)
+
+Documentation: [http://boost-hof.readthedocs.io/](http://boost-hof.readthedocs.io/)
+
+Motivation
+==========
+
+- Improve the expressiveness and capabilities of functions, including first-class citizens for function overload set, extension methods, infix operators and much more.
+- Simplify constructs in C++ that have generally required metaprogramming
+- Enable point-free style programming
+- Workaround the limitations of lambdas in C++14
+
+Requirements
+============
+
+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.
+
+Contexpr support
+----------------
+
+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.
+
+Noexcept support
+----------------
+
+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.
+
+Building
+========
+
+Boost.HigherOrderFunctions library uses cmake to build. To configure with cmake create a build directory, and run cmake:
+
+ mkdir build
+ cd build
+ cmake ..
+
+Installing
+----------
+
+To install the library just run the `install` target:
+
+ cmake --build . --target install
+
+Tests
+-----
+
+The tests can be built and run by using the `check` target:
+
+ cmake --build . --target check
+
+The tests can also be ran using Boost.Build, just copy library to the boost source tree, and then:
+
+ cd test
+ b2
+
+Documentation
+-------------
+
+The documentation is built using Sphinx. First, install the requirements needed for the documentation using `pip`:
+
+ pip install -r doc/requirements.txt
+
+Then html documentation can be generated using `sphinx-build`:
+
+ sphinx-build -b html doc/ doc/html/
+
+The final docs will be in the `doc/html` folder.
+
+<!-- Links -->
+[badge.Travis]: https://travis-ci.org/boostorg/hof.svg?branch=master
+[badge.Appveyor]: https://ci.appveyor.com/api/projects/status/bjj27h3v3bxbgpsp/branch/develop
diff --git a/src/boost/libs/hof/boost_hof.pc.in b/src/boost/libs/hof/boost_hof.pc.in
new file mode 100644
index 000000000..f1ea54651
--- /dev/null
+++ b/src/boost/libs/hof/boost_hof.pc.in
@@ -0,0 +1,6 @@
+Name: boost_hof
+Description: C++ function utility library
+URL: https://github.com/pfultz2/hof
+Version: @boost_hof_VERSION_MAJOR@.@boost_hof_VERSION_MINOR@
+
+Cflags: -I@CMAKE_INSTALL_PREFIX@/include
diff --git a/src/boost/libs/hof/cmake/BCMTest.cmake b/src/boost/libs/hof/cmake/BCMTest.cmake
new file mode 100644
index 000000000..a7215f9c0
--- /dev/null
+++ b/src/boost/libs/hof/cmake/BCMTest.cmake
@@ -0,0 +1,92 @@
+option(BUILD_TESTING off)
+
+include(CMakeParseArguments)
+enable_testing()
+
+if(NOT TARGET check)
+ add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C ${CMAKE_CFG_INTDIR})
+endif()
+
+if(NOT TARGET tests)
+ add_custom_target(tests COMMENT "Build all tests.")
+ add_dependencies(check tests)
+endif()
+
+function(bcm_mark_as_test)
+ foreach(TEST_TARGET ${ARGN})
+ if (NOT BUILD_TESTING)
+ set_target_properties(${TEST_TARGET}
+ PROPERTIES EXCLUDE_FROM_ALL TRUE
+ )
+ endif()
+ add_dependencies(tests ${TEST_TARGET})
+ endforeach()
+endfunction(bcm_mark_as_test)
+
+function(bcm_add_test)
+ set(options COMPILE_ONLY WILL_FAIL)
+ set(oneValueArgs NAME)
+ set(multiValueArgs SOURCES CONTENT)
+
+ cmake_parse_arguments(PARSE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ # TODO: Check if name exists
+
+ set(SOURCES ${PARSE_SOURCES})
+ if(PARSE_CONTENT)
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generated-${PARSE_NAME}.cpp "${PARSE_CONTENT}")
+ set(SOURCES ${CMAKE_CURRENT_BINARY_DIR}/generated-${PARSE_NAME}.cpp)
+ endif()
+
+ if(PARSE_COMPILE_ONLY)
+ if(PARSE_WILL_FAIL)
+ add_library(_${PARSE_NAME}_TEST_FAIL STATIC EXCLUDE_FROM_ALL ${SOURCES})
+ add_custom_target(${PARSE_NAME}
+ COMMAND ${CMAKE_COMMAND} --build . --target _${PARSE_NAME}_TEST_FAIL --config $<CONFIGURATION>
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+ add_test(NAME ${PARSE_NAME}
+ COMMAND ${CMAKE_COMMAND} --build . --target _${PARSE_NAME}_TEST_FAIL --config $<CONFIGURATION>
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+ set_tests_properties(${PARSE_NAME} PROPERTIES WILL_FAIL TRUE)
+ else()
+ add_library(${PARSE_NAME} STATIC ${SOURCES})
+ bcm_mark_as_test(${PARSE_NAME})
+ endif()
+ else()
+ add_executable (${PARSE_NAME} ${SOURCES})
+ bcm_mark_as_test(${PARSE_NAME})
+ if(WIN32)
+ add_test(NAME ${PARSE_NAME} WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH} COMMAND ${PARSE_NAME}${CMAKE_EXECUTABLE_SUFFIX})
+ else()
+ add_test(NAME ${PARSE_NAME} COMMAND ${PARSE_NAME})
+ endif()
+ if(WILL_FAIL)
+ set_tests_properties(${PARSE_NAME} PROPERTIES WILL_FAIL TRUE)
+ endif()
+ endif()
+endfunction(bcm_add_test)
+
+function(bcm_test_header)
+ set(options STATIC)
+ set(oneValueArgs NAME HEADER)
+ set(multiValueArgs)
+
+ cmake_parse_arguments(PARSE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if(PARSE_STATIC)
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/header-main-include-${PARSE_NAME}.cpp
+ "#include <${PARSE_HEADER}>\nint main() {}\n"
+ )
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/header-static-include-${PARSE_NAME}.cpp
+ "#include <${PARSE_HEADER}>\n"
+ )
+ bcm_add_test(NAME header-static-include-${PARSE_NAME} SOURCES
+ ${CMAKE_CURRENT_BINARY_DIR}/header-main-include-${PARSE_NAME}.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/header-static-include-${PARSE_NAME}.cpp
+ )
+ else()
+ bcm_add_test(NAME header-include-${PARSE_NAME} CONTENT
+ "#include <${PARSE_HEADER}>\nint main() {}\n"
+ )
+ endif()
+endfunction(bcm_test_header)
diff --git a/src/boost/libs/hof/cmake/SphinxDoc.cmake b/src/boost/libs/hof/cmake/SphinxDoc.cmake
new file mode 100644
index 000000000..6cedf77bb
--- /dev/null
+++ b/src/boost/libs/hof/cmake/SphinxDoc.cmake
@@ -0,0 +1,61 @@
+include(CMakeParseArguments)
+include(ProcessorCount)
+
+find_program(SPHINX_EXECUTABLE NAMES sphinx-build
+ HINTS
+ $ENV{SPHINX_DIR}
+ PATH_SUFFIXES bin
+ DOC "Sphinx documentation generator"
+)
+
+mark_as_advanced(SPHINX_EXECUTABLE)
+
+function(clean_doc_output DIR)
+ set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${DIR})
+endfunction()
+
+set(BINARY_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/sphinx/_build")
+
+# Sphinx cache with pickled ReST documents
+set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/sphinx/_doctrees")
+
+# HTML output directory
+set(SPHINX_DEFAULT_HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/sphinx/html")
+function(add_sphinx_doc SRC_DIR)
+ set(options)
+ set(oneValueArgs HTML_DIR)
+ set(multiValueArgs VARS TEMPLATE_VARS)
+
+ cmake_parse_arguments(PARSE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+ ProcessorCount(N)
+
+ set(ADDITIONAL_ARGS)
+ foreach(VAR ${PARSE_VARS})
+ list(APPEND ADDITIONAL_ARGS "-D ${VAR}")
+ endforeach()
+ foreach(VAR ${PARSE_TEMPLATE_VARS})
+ list(APPEND ADDITIONAL_ARGS "-A ${VAR}")
+ endforeach()
+
+ if(PARSE_HTML_DIR)
+ set(SPHINX_HTML_DIR ${PARSE_HTML_DIR} CACHE PATH "Path to html output")
+ else()
+ set(SPHINX_HTML_DIR ${SPHINX_DEFAULT_HTML_DIR} CACHE PATH "Path to html output")
+ endif()
+
+ clean_doc_output(${SPHINX_HTML_DIR})
+ clean_doc_output(${SPHINX_CACHE_DIR})
+ clean_doc_output(${BINARY_BUILD_DIR})
+
+ add_custom_target(doc
+ ${SPHINX_EXECUTABLE}
+ -j ${N}
+ -n
+ -b html
+ -d "${SPHINX_CACHE_DIR}"
+ ${ADDITIONAL_ARGS}
+ "${SRC_DIR}"
+ "${SPHINX_HTML_DIR}"
+ COMMENT "Building HTML documentation with Sphinx")
+endfunction()
+
diff --git a/src/boost/libs/hof/example/example.h b/src/boost/libs/hof/example/example.h
new file mode 100644
index 000000000..0d88b1727
--- /dev/null
+++ b/src/boost/libs/hof/example/example.h
@@ -0,0 +1,67 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ example.h
+ 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)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_EXAMPLE_H
+#define BOOST_HOF_GUARD_EXAMPLE_H
+
+#include <boost/hof/alias.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/apply_eval.hpp>
+#include <boost/hof/apply.hpp>
+#include <boost/hof/arg.hpp>
+#include <boost/hof/proj.hpp>
+#include <boost/hof/capture.hpp>
+#include <boost/hof/combine.hpp>
+#include <boost/hof/compose.hpp>
+#include <boost/hof/fold.hpp>
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/construct.hpp>
+#include <boost/hof/decay.hpp>
+#include <boost/hof/decorate.hpp>
+#include <boost/hof/eval.hpp>
+#include <boost/hof/fix.hpp>
+#include <boost/hof/flip.hpp>
+#include <boost/hof/flow.hpp>
+#include <boost/hof/function.hpp>
+#include <boost/hof/identity.hpp>
+#include <boost/hof/if.hpp>
+#include <boost/hof/implicit.hpp>
+#include <boost/hof/indirect.hpp>
+#include <boost/hof/infix.hpp>
+#include <boost/hof/is_invocable.hpp>
+#include <boost/hof/lambda.hpp>
+#include <boost/hof/lazy.hpp>
+#include <boost/hof/lift.hpp>
+#include <boost/hof/limit.hpp>
+#include <boost/hof/match.hpp>
+#include <boost/hof/mutable.hpp>
+#include <boost/hof/pack.hpp>
+#include <boost/hof/partial.hpp>
+#include <boost/hof/pipable.hpp>
+#include <boost/hof/placeholders.hpp>
+#include <boost/hof/protect.hpp>
+#include <boost/hof/repeat.hpp>
+#include <boost/hof/repeat_while.hpp>
+#include <boost/hof/result.hpp>
+#include <boost/hof/returns.hpp>
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/reverse_fold.hpp>
+#include <boost/hof/rotate.hpp>
+#include <boost/hof/static.hpp>
+#include <boost/hof/tap.hpp>
+#include <boost/hof/unpack.hpp>
+
+#include <algorithm>
+#include <vector>
+#include <map>
+#include <memory>
+#include <iostream>
+#include <string>
+#include <cassert>
+#include <iso646.h>
+
+#endif
diff --git a/src/boost/libs/hof/example/in.cpp b/src/boost/libs/hof/example/in.cpp
new file mode 100644
index 000000000..a89541403
--- /dev/null
+++ b/src/boost/libs/hof/example/in.cpp
@@ -0,0 +1,81 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ in.cpp
+ 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)
+==============================================================================*/
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ in.cpp
+ 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)
+==============================================================================*/
+
+#include "example.h"
+
+using namespace boost::hof;
+
+#ifdef _MSC_VER
+template<class R, class T>
+auto member_find(const R& r, const T& x) BOOST_HOF_RETURNS(r.find(x));
+#endif
+
+// Function to find an iterator using a containers built-in find if available
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(find_iterator) = first_of(
+ [](const std::string& s, const auto& x)
+ {
+ auto index = s.find(x);
+ if (index == std::string::npos) return s.end();
+ else return s.begin() + index;
+ },
+#ifdef _MSC_VER
+ // On MSVC, trailing decltype doesn't work with generic lambdas, so a
+ // seperate function can be used instead.
+ BOOST_HOF_LIFT(member_find),
+#else
+ [](const auto& r, const auto& x) BOOST_HOF_RETURNS(r.find(x)),
+#endif
+ [](const auto& r, const auto& x)
+ {
+ using std::begin;
+ using std::end;
+ return std::find(begin(r), end(r), x);
+ }
+);
+// Implement an infix `in` operator to check if a range contains an element
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(in) = infix(
+ [](const auto& x, const auto& r)
+ {
+ using std::end;
+ return find_iterator(r, x) != end(r);
+ }
+);
+// Negate version of `in`
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(not_in) = infix(compose(not _, in));
+
+int main()
+{
+ // Check if vector contains element
+ std::vector<int> numbers = { 1, 2, 3, 4, 5 };
+ if (5 <in> numbers) std::cout << "Yes" << std::endl;
+
+ // Check if string contains element
+ std::string s = "hello world";
+ if ("hello" <in> s) std::cout << "Yes" << std::endl;
+
+ // Check if map contains element
+ std::map<int, std::string> number_map = {
+ { 1, "1" },
+ { 2, "2" },
+ { 3, "3" },
+ { 4, "4" }
+ };
+
+ if (4 <in> number_map) std::cout << "Yes" << std::endl;
+
+ // Check if map doesn't contains element
+ if (not (8 <in> numbers)) std::cout << "No" << std::endl;
+ if (8 <not_in> numbers) std::cout << "No" << std::endl;
+
+}
+
diff --git a/src/boost/libs/hof/example/pointfree.cpp b/src/boost/libs/hof/example/pointfree.cpp
new file mode 100644
index 000000000..6aa136479
--- /dev/null
+++ b/src/boost/libs/hof/example/pointfree.cpp
@@ -0,0 +1,33 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ pointfree.cpp
+ 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)
+==============================================================================*/
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ pointfree.cpp
+ 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)
+==============================================================================*/
+
+#include "example.h"
+
+using namespace boost::hof;
+
+BOOST_HOF_STATIC_FUNCTION(simple_print) = BOOST_HOF_LIFT(std::ref(std::cout) << _);
+BOOST_HOF_STATIC_FUNCTION(print) = proj(simple_print);
+BOOST_HOF_STATIC_FUNCTION(print_lines) = proj(flow(simple_print, _ << std::integral_constant<char, '\n'>{}));
+BOOST_HOF_STATIC_FUNCTION(max) = fold(BOOST_HOF_LIFT(std::max));
+
+int main()
+{
+ simple_print("Hello\n");
+ print("Hello", "World\n");
+ print_lines("Hello", "World");
+
+ auto n = max(1, 2, 4, 3); // Returns 4
+ auto m = max(0.1, 0.2, 0.5, 0.4); // Returns 0.5
+
+ print_lines(n, m);
+}
diff --git a/src/boost/libs/hof/example/print.cpp b/src/boost/libs/hof/example/print.cpp
new file mode 100644
index 000000000..0149c8708
--- /dev/null
+++ b/src/boost/libs/hof/example/print.cpp
@@ -0,0 +1,96 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ print.cpp
+ 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)
+==============================================================================*/
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ print.cpp
+ 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)
+==============================================================================*/
+
+#include "example.h"
+
+using namespace boost::hof;
+
+// ADL Lookup for ranges
+namespace adl {
+
+using std::begin;
+using std::end;
+
+template<class R>
+auto adl_begin(R&& r) BOOST_HOF_RETURNS(begin(r));
+template<class R>
+auto adl_end(R&& r) BOOST_HOF_RETURNS(end(r));
+}
+
+// Iterate over a tuple
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(for_each_tuple) = [](const auto& sequence, auto f)
+{
+ return unpack(proj(f))(sequence);
+};
+
+#ifdef _MSC_VER
+// On MSVC, trailing decltype doesn't work with generic lambdas, so seperate
+// functions can be used instead.
+template<class Self, class T>
+auto print_with_cout(Self, const T& x) -> decltype(std::cout << x, void())
+{
+ std::cout << x << std::endl;
+}
+
+template<class Self, class T>
+auto print_with_range(Self self, const T& range) -> decltype(self(*adl::adl_begin(range)), void())
+{
+ for(const auto& x:range) self(x);
+}
+
+template<class Self, class T>
+auto print_with_tuple(Self self, const T& tuple) -> decltype(for_each_tuple(tuple, self), void())
+{
+ for_each_tuple(tuple, self);
+}
+
+// Recursively print everything
+BOOST_HOF_STATIC_FUNCTION(simple_print) = fix(first_of(
+ BOOST_HOF_LIFT(print_with_cout),
+ BOOST_HOF_LIFT(print_with_range),
+ BOOST_HOF_LIFT(print_with_tuple)
+));
+#else
+// Recursively print everything
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(simple_print) = fix(first_of(
+ [](auto, const auto& x) -> decltype(std::cout << x, void())
+ {
+ std::cout << x << std::endl;
+ },
+ [](auto self, const auto& range) -> decltype(self(*adl::adl_begin(range)), void())
+ {
+ for(const auto& x:range) self(x);
+ },
+ [](auto self, const auto& tuple) -> decltype(for_each_tuple(tuple, self), void())
+ {
+ for_each_tuple(tuple, self);
+ }
+));
+#endif
+
+// Make print function varidiac
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(print) = proj(simple_print);
+
+int main()
+{
+ print(5, "Hello world");
+ print(5);
+ std::vector<int> v = { 1, 2, 3, 4 };
+ print(v);
+
+ auto t = std::make_tuple(1, 2, 3, 4);
+ print(t);
+
+ auto m = std::make_tuple(3, v, t);
+ print(m);
+}
diff --git a/src/boost/libs/hof/example/sequence.cpp b/src/boost/libs/hof/example/sequence.cpp
new file mode 100644
index 000000000..3ecdd659f
--- /dev/null
+++ b/src/boost/libs/hof/example/sequence.cpp
@@ -0,0 +1,122 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ sequence.cpp
+ 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)
+==============================================================================*/
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ print.cpp
+ 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)
+==============================================================================*/
+
+#include "example.h"
+#include <tuple>
+
+using namespace boost::hof;
+
+// Transform each element of a tuple by calling f
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_transform) = [](auto&& sequence, auto f)
+{
+ return unpack(proj(f, construct<std::tuple>()))(std::forward<decltype(sequence)>(sequence));
+};
+// Call f on each element of tuple
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_for_each) = [](auto&& sequence, auto f)
+{
+ return unpack(proj(f))(std::forward<decltype(sequence)>(sequence));
+};
+// Fold over tuple using a f as the binary operator
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_fold) = [](auto&& sequence, auto f)
+{
+ return unpack(fold(f))(std::forward<decltype(sequence)>(sequence));
+};
+// Concat multiple tuples
+BOOST_HOF_STATIC_FUNCTION(tuple_cat) = unpack(construct<std::tuple>());
+// Join a tuple of tuples into just a tuple
+BOOST_HOF_STATIC_FUNCTION(tuple_join) = unpack(tuple_cat);
+// Filter elements in a tuple using a predicate
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_filter) = [](auto&& sequence, auto predicate)
+{
+ return compose(tuple_join, tuple_transform)(
+ std::forward<decltype(sequence)>(sequence),
+ [&](auto&& x)
+ {
+ return first_of(
+ if_(predicate(std::forward<decltype(x)>(x)))(pack),
+ always(pack())
+ )(std::forward<decltype(x)>(x));
+ }
+ );
+};
+// Zip two tuples together
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_zip_with) = [](auto&& sequence1, auto&& sequence2, auto f)
+{
+ auto&& functions = tuple_transform(
+ std::forward<decltype(sequence1)>(sequence1),
+ [&](auto&& x)
+ {
+ return [&](auto&& y)
+ {
+ return f(std::forward<decltype(x)>(x), std::forward<decltype(y)>(y));
+ };
+ }
+ );
+ auto combined = unpack(capture(construct<std::tuple>())(combine))(functions);
+ return unpack(combined)(std::forward<decltype(sequence2)>(sequence2));
+};
+// Dot product of a tuple
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_dot) = [](auto&& a, auto&& b)
+{
+ auto product = tuple_zip_with(a, b, [](auto x, auto y) { return x*y; });
+ return tuple_fold(product, [](auto x, auto y) { return x+y; });
+};
+
+void run_each()
+{
+ auto t = std::make_tuple(1, 2);
+ tuple_for_each(t, [](int i) { std::cout << i << std::endl; });
+}
+
+void run_transform()
+{
+ auto t = std::make_tuple(1, 2);
+ auto r = tuple_transform(t, [](int i) { return i*i; });
+ assert(r == std::make_tuple(1, 4));
+ (void)r;
+}
+
+void run_filter()
+{
+ auto t = std::make_tuple(1, 2, 'x', 3);
+ auto r = tuple_filter(t, [](auto x) { return std::is_same<int, decltype(x)>(); });
+ assert(r == std::make_tuple(1, 2, 3));
+ (void)r;
+}
+
+void run_zip()
+{
+ auto t1 = std::make_tuple(1, 2);
+ auto t2 = std::make_tuple(3, 4);
+ auto p = tuple_zip_with(t1, t2, [](auto x, auto y) { return x*y; });
+ int r = tuple_fold(p, [](auto x, auto y) { return x+y; });
+ assert(r == (1*3 + 4*2));
+ (void)r;
+}
+
+void run_dot()
+{
+ auto t1 = std::make_tuple(1, 2);
+ auto t2 = std::make_tuple(3, 4);
+ int r = tuple_dot(t1, t2);
+ assert(r == (1*3 + 4*2));
+ (void)r;
+}
+
+int main()
+{
+ run_transform();
+ run_filter();
+ run_zip();
+}
+
diff --git a/src/boost/libs/hof/example/static_if.cpp b/src/boost/libs/hof/example/static_if.cpp
new file mode 100644
index 000000000..898e66213
--- /dev/null
+++ b/src/boost/libs/hof/example/static_if.cpp
@@ -0,0 +1,43 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ static_if.cpp
+ 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)
+==============================================================================*/
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ static_if.cpp
+ 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)
+==============================================================================*/
+
+#include "example.h"
+
+using namespace boost::hof;
+
+// static_if example taken from Baptiste Wicht:
+// http://baptiste-wicht.com/posts/2015/07/simulate-static_if-with-c11c14.html
+
+template<typename T>
+void decrement_kindof(T& value)
+{
+ eval(first_of(
+ if_(std::is_same<std::string, T>())([&](auto id){
+ id(value).pop_back();
+ }),
+ [&](auto id){
+ --id(value);
+ }
+ ));
+}
+
+int main()
+{
+ std::string s = "hello!";
+ decrement_kindof(s);
+ assert(s == "hello");
+
+ int i = 4;
+ decrement_kindof(i);
+ assert(i == 3);
+}
diff --git a/src/boost/libs/hof/index.html b/src/boost/libs/hof/index.html
new file mode 100644
index 000000000..8d5423a58
--- /dev/null
+++ b/src/boost/libs/hof/index.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="refresh" content="0; URL=doc/html/index.html">
+ </head>
+
+ <body>
+ Automatic redirection failed, click this <a href="doc/html/index.html">link</a>
+ <hr>
+ <p>Copyright Paul Fultz II 2018</p>
+ <p>
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file <a href="LICENSE.md">LICENSE.md</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+ </body>
+</html>
diff --git a/src/boost/libs/hof/meta/libraries.json b/src/boost/libs/hof/meta/libraries.json
new file mode 100644
index 000000000..382409d93
--- /dev/null
+++ b/src/boost/libs/hof/meta/libraries.json
@@ -0,0 +1,11 @@
+{
+ "key": "hof",
+ "name": "HOF",
+ "authors": [ "Paul Fultz II" ],
+ "maintainers": [ "Paul Fultz II <pfultz2 -at- yahoo.com>" ],
+ "description": "Higher-order functions for C++",
+ "category": [
+ "Metaprogramming",
+ "Function-objects"
+ ]
+}
diff --git a/src/boost/libs/hof/test/Jamfile.v2 b/src/boost/libs/hof/test/Jamfile.v2
new file mode 100644
index 000000000..198de5bd3
--- /dev/null
+++ b/src/boost/libs/hof/test/Jamfile.v2
@@ -0,0 +1,31 @@
+#=============================================================================
+# Copyright (c) 2017 Paul Fultz II
+# Jamfile.v2
+# 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)
+#==============================================================================
+import testing ;
+import ../../config/checks/config : requires ;
+
+project hof
+ : requirements [ requires cxx11_variadic_templates cxx11_constexpr ]
+ <include>../include/
+ ;
+
+rule test_all
+{
+ local all_rules = ;
+
+ for local fileb in [ glob *.cpp ]
+ {
+ all_rules += [ run $(fileb)
+ : # additional args
+ : # test-files
+ : # requirements
+ ] ;
+ }
+
+ return $(all_rules) ;
+}
+
+test-suite hof : [ test_all r ] : ;
diff --git a/src/boost/libs/hof/test/alias.cpp b/src/boost/libs/hof/test/alias.cpp
new file mode 100644
index 000000000..d6f94c2cd
--- /dev/null
+++ b/src/boost/libs/hof/test/alias.cpp
@@ -0,0 +1,24 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ alias.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/alias.hpp>
+#include "test.hpp"
+
+struct foo
+{
+ int i;
+ foo(int i_) : i(i_)
+ {}
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ boost::hof::alias<int> ai = 5;
+ BOOST_HOF_TEST_CHECK(boost::hof::alias_value(ai) == 5);
+ boost::hof::alias_inherit<foo> af = foo{5};
+ BOOST_HOF_TEST_CHECK(boost::hof::alias_value(af).i == 5);
+}
+
diff --git a/src/boost/libs/hof/test/always.cpp b/src/boost/libs/hof/test/always.cpp
new file mode 100644
index 000000000..8acb08a9f
--- /dev/null
+++ b/src/boost/libs/hof/test/always.cpp
@@ -0,0 +1,65 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ always.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/always.hpp>
+#include <boost/hof/function.hpp>
+#include <memory>
+#include "test.hpp"
+
+BOOST_HOF_TEST_CASE()
+{
+ static const int ten = 10;
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::always(ten)(1,2,3,4,5) == 10);
+ BOOST_HOF_TEST_CHECK( boost::hof::always(ten)(1,2,3,4,5) == 10 );
+
+ int i = 10;
+ BOOST_HOF_TEST_CHECK( boost::hof::always(std::ref(i))(1,2,3,4,5) == 10 );
+ BOOST_HOF_TEST_CHECK( &boost::hof::always(std::ref(i))(1,2,3,4,5) == &i );
+
+ boost::hof::always()(1, 2);
+ static_assert(std::is_same<decltype(boost::hof::always()(1, 2)), BOOST_HOF_ALWAYS_VOID_RETURN>::value, "Failed");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ int i = 10;
+ BOOST_HOF_TEST_CHECK( boost::hof::always_ref(i)(1,2,3,4,5) == 10 );
+ BOOST_HOF_TEST_CHECK( &boost::hof::always_ref(i)(1,2,3,4,5) == &i );
+}
+
+BOOST_HOF_STATIC_FUNCTION(gten) = boost::hof::always(std::integral_constant<int, 10>{});
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(gten(1,2,3,4,5) == 10);
+ BOOST_HOF_TEST_CHECK(gten(1,2,3,4,5) == 10);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::always(10);
+ STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(decltype(f));
+ BOOST_HOF_TEST_CHECK(f(1,2,3,4,5) == 10);
+}
+
+struct copy_throws
+{
+ copy_throws() {}
+ copy_throws(copy_throws const&) {}
+ copy_throws(copy_throws&&) noexcept {}
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::always()()), "noexcept always");
+ static_assert(noexcept(boost::hof::always(1)()), "noexcept always");
+ static_assert(!noexcept(boost::hof::always(copy_throws{})()), "noexcept always");
+ copy_throws ct{};
+ static_assert(!noexcept(boost::hof::always(ct)()), "noexcept always");
+ static_assert(noexcept(boost::hof::always(std::ref(ct))()) == BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(std::reference_wrapper<copy_throws>), "noexcept always");
+ auto ctf = boost::hof::always(copy_throws{});
+ static_assert(!noexcept(ctf()), "noexcept always");
+}
diff --git a/src/boost/libs/hof/test/apply.cpp b/src/boost/libs/hof/test/apply.cpp
new file mode 100644
index 000000000..e85eb915f
--- /dev/null
+++ b/src/boost/libs/hof/test/apply.cpp
@@ -0,0 +1,467 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ apply.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/apply.hpp>
+#include "test.hpp"
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(binary_class(), 1, 2) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::apply(binary_class(), 1, 2) == 3);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::apply(boost::hof::apply, binary_class(), 1, 2) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(boost::hof::apply, binary_class(), 1, 2) == 3);
+}
+
+struct member_sum_f
+{
+ int i;
+ constexpr member_sum_f(int x) : i(x)
+ {}
+
+ constexpr int add(int x) const
+ {
+ return i+x;
+ }
+};
+
+struct member_sum_f_derived
+: member_sum_f
+{
+ constexpr member_sum_f_derived(int x) : member_sum_f(x)
+ {}
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f(1), 2) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3);
+
+#ifdef __clang__
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f(1), 2) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3);
+#endif
+
+ static_assert(std::is_base_of<member_sum_f, member_sum_f>::value, "Base of failed");
+ std::unique_ptr<member_sum_f> msp(new member_sum_f(1));
+ BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, msp, 2) == 3);
+
+ std::unique_ptr<member_sum_f_derived> mspd(new member_sum_f_derived(1));
+ BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, mspd, 2) == 3);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f(3)) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3);
+
+#ifdef __clang__
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f(3)) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3);
+#endif
+
+ std::unique_ptr<member_sum_f> msp(new member_sum_f(3));
+ BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, msp) == 3);
+
+ std::unique_ptr<member_sum_f_derived> mspd(new member_sum_f_derived(3));
+ BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, mspd) == 3);
+}
+
+
+struct mem_hash
+{
+ mutable unsigned int hash;
+
+ mem_hash(): hash(0) {}
+
+ int f0() { f1(17); return 0; }
+ int g0() const { g1(17); return 0; }
+
+ int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
+ int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
+
+ int f2(int a1, int a2) { f1(a1); f1(a2); return 0; }
+ int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; }
+
+ int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; }
+ int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; }
+
+ int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; }
+ int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; }
+
+ int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; }
+ int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; }
+
+ int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; }
+ int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); return 0; }
+
+ int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); return 0; }
+ int g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); return 0; }
+
+ int f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); return 0; }
+ int g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); return 0; }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+
+ mem_hash x;
+
+ mem_hash const & rcx = x;
+ mem_hash const * pcx = &x;
+
+ std::shared_ptr<mem_hash> sp(new mem_hash);
+
+ boost::hof::apply(&mem_hash::f0, x);
+ boost::hof::apply(&mem_hash::f0, &x);
+ boost::hof::apply(&mem_hash::f0, sp);
+
+ boost::hof::apply(&mem_hash::g0, x);
+ boost::hof::apply(&mem_hash::g0, rcx);
+ boost::hof::apply(&mem_hash::g0, &x);
+ boost::hof::apply(&mem_hash::g0, pcx);
+ boost::hof::apply(&mem_hash::g0, sp);
+
+ boost::hof::apply(&mem_hash::f1, x, 1);
+ boost::hof::apply(&mem_hash::f1, &x, 1);
+ boost::hof::apply(&mem_hash::f1, sp, 1);
+
+ boost::hof::apply(&mem_hash::g1, x, 1);
+ boost::hof::apply(&mem_hash::g1, rcx, 1);
+ boost::hof::apply(&mem_hash::g1, &x, 1);
+ boost::hof::apply(&mem_hash::g1, pcx, 1);
+ boost::hof::apply(&mem_hash::g1, sp, 1);
+
+ boost::hof::apply(&mem_hash::f2, x, 1, 2);
+ boost::hof::apply(&mem_hash::f2, &x, 1, 2);
+ boost::hof::apply(&mem_hash::f2, sp, 1, 2);
+
+ boost::hof::apply(&mem_hash::g2, x, 1, 2);
+ boost::hof::apply(&mem_hash::g2, rcx, 1, 2);
+ boost::hof::apply(&mem_hash::g2, &x, 1, 2);
+ boost::hof::apply(&mem_hash::g2, pcx, 1, 2);
+ boost::hof::apply(&mem_hash::g2, sp, 1, 2);
+
+ boost::hof::apply(&mem_hash::f3, x, 1, 2, 3);
+ boost::hof::apply(&mem_hash::f3, &x, 1, 2, 3);
+ boost::hof::apply(&mem_hash::f3, sp, 1, 2, 3);
+
+ boost::hof::apply(&mem_hash::g3, x, 1, 2, 3);
+ boost::hof::apply(&mem_hash::g3, rcx, 1, 2, 3);
+ boost::hof::apply(&mem_hash::g3, &x, 1, 2, 3);
+ boost::hof::apply(&mem_hash::g3, pcx, 1, 2, 3);
+ boost::hof::apply(&mem_hash::g3, sp, 1, 2, 3);
+
+ boost::hof::apply(&mem_hash::f4, x, 1, 2, 3, 4);
+ boost::hof::apply(&mem_hash::f4, &x, 1, 2, 3, 4);
+ boost::hof::apply(&mem_hash::f4, sp, 1, 2, 3, 4);
+
+ boost::hof::apply(&mem_hash::g4, x, 1, 2, 3, 4);
+ boost::hof::apply(&mem_hash::g4, rcx, 1, 2, 3, 4);
+ boost::hof::apply(&mem_hash::g4, &x, 1, 2, 3, 4);
+ boost::hof::apply(&mem_hash::g4, pcx, 1, 2, 3, 4);
+ boost::hof::apply(&mem_hash::g4, sp, 1, 2, 3, 4);
+
+ boost::hof::apply(&mem_hash::f5, x, 1, 2, 3, 4, 5);
+ boost::hof::apply(&mem_hash::f5, &x, 1, 2, 3, 4, 5);
+ boost::hof::apply(&mem_hash::f5, sp, 1, 2, 3, 4, 5);
+
+ boost::hof::apply(&mem_hash::g5, x, 1, 2, 3, 4, 5);
+ boost::hof::apply(&mem_hash::g5, rcx, 1, 2, 3, 4, 5);
+ boost::hof::apply(&mem_hash::g5, &x, 1, 2, 3, 4, 5);
+ boost::hof::apply(&mem_hash::g5, pcx, 1, 2, 3, 4, 5);
+ boost::hof::apply(&mem_hash::g5, sp, 1, 2, 3, 4, 5);
+
+ boost::hof::apply(&mem_hash::f6, x, 1, 2, 3, 4, 5, 6);
+ boost::hof::apply(&mem_hash::f6, &x, 1, 2, 3, 4, 5, 6);
+ boost::hof::apply(&mem_hash::f6, sp, 1, 2, 3, 4, 5, 6);
+
+ boost::hof::apply(&mem_hash::g6, x, 1, 2, 3, 4, 5, 6);
+ boost::hof::apply(&mem_hash::g6, rcx, 1, 2, 3, 4, 5, 6);
+ boost::hof::apply(&mem_hash::g6, &x, 1, 2, 3, 4, 5, 6);
+ boost::hof::apply(&mem_hash::g6, pcx, 1, 2, 3, 4, 5, 6);
+ boost::hof::apply(&mem_hash::g6, sp, 1, 2, 3, 4, 5, 6);
+
+ boost::hof::apply(&mem_hash::f7, x, 1, 2, 3, 4, 5, 6, 7);
+ boost::hof::apply(&mem_hash::f7, &x, 1, 2, 3, 4, 5, 6, 7);
+ boost::hof::apply(&mem_hash::f7, sp, 1, 2, 3, 4, 5, 6, 7);
+
+ boost::hof::apply(&mem_hash::g7, x, 1, 2, 3, 4, 5, 6, 7);
+ boost::hof::apply(&mem_hash::g7, rcx, 1, 2, 3, 4, 5, 6, 7);
+ boost::hof::apply(&mem_hash::g7, &x, 1, 2, 3, 4, 5, 6, 7);
+ boost::hof::apply(&mem_hash::g7, pcx, 1, 2, 3, 4, 5, 6, 7);
+ boost::hof::apply(&mem_hash::g7, sp, 1, 2, 3, 4, 5, 6, 7);
+
+ boost::hof::apply(&mem_hash::f8, x, 1, 2, 3, 4, 5, 6, 7, 8);
+ boost::hof::apply(&mem_hash::f8, &x, 1, 2, 3, 4, 5, 6, 7, 8);
+ boost::hof::apply(&mem_hash::f8, sp, 1, 2, 3, 4, 5, 6, 7, 8);
+
+ boost::hof::apply(&mem_hash::g8, x, 1, 2, 3, 4, 5, 6, 7, 8);
+ boost::hof::apply(&mem_hash::g8, rcx, 1, 2, 3, 4, 5, 6, 7, 8);
+ boost::hof::apply(&mem_hash::g8, &x, 1, 2, 3, 4, 5, 6, 7, 8);
+ boost::hof::apply(&mem_hash::g8, pcx, 1, 2, 3, 4, 5, 6, 7, 8);
+ boost::hof::apply(&mem_hash::g8, sp, 1, 2, 3, 4, 5, 6, 7, 8);
+
+ BOOST_HOF_TEST_CHECK(boost::hof::apply(&mem_hash::hash, x) == 17610 && boost::hof::apply(&mem_hash::hash, sp) == 2155);
+}
+
+struct hash_base
+{
+ mutable unsigned int hash;
+
+ hash_base(): hash(0) {}
+
+ int f0() { f1(17); return 0; }
+ int g0() const { g1(17); return 0; }
+
+ int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
+ int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
+
+ int f2(int a1, int a2) { f1(a1); f1(a2); return 0; }
+ int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; }
+
+ int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; }
+ int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; }
+
+ int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; }
+ int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; }
+
+ int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; }
+ int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; }
+
+ int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; }
+ int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); return 0; }
+
+ int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); return 0; }
+ int g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); return 0; }
+
+ int f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); return 0; }
+ int g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); return 0; }
+};
+
+struct derived_hash: public hash_base
+{
+};
+
+BOOST_HOF_TEST_CASE()
+{
+
+ derived_hash x;
+
+ derived_hash const & rcx = x;
+ derived_hash const * pcx = &x;
+
+ std::shared_ptr<derived_hash> sp(new derived_hash);
+
+ boost::hof::apply(&derived_hash::f0, x);
+ boost::hof::apply(&derived_hash::f0, &x);
+ boost::hof::apply(&derived_hash::f0, sp);
+
+ boost::hof::apply(&derived_hash::g0, x);
+ boost::hof::apply(&derived_hash::g0, rcx);
+ boost::hof::apply(&derived_hash::g0, &x);
+ boost::hof::apply(&derived_hash::g0, pcx);
+ boost::hof::apply(&derived_hash::g0, sp);
+
+ boost::hof::apply(&derived_hash::f1, x, 1);
+ boost::hof::apply(&derived_hash::f1, &x, 1);
+ boost::hof::apply(&derived_hash::f1, sp, 1);
+
+ boost::hof::apply(&derived_hash::g1, x, 1);
+ boost::hof::apply(&derived_hash::g1, rcx, 1);
+ boost::hof::apply(&derived_hash::g1, &x, 1);
+ boost::hof::apply(&derived_hash::g1, pcx, 1);
+ boost::hof::apply(&derived_hash::g1, sp, 1);
+
+ boost::hof::apply(&derived_hash::f2, x, 1, 2);
+ boost::hof::apply(&derived_hash::f2, &x, 1, 2);
+ boost::hof::apply(&derived_hash::f2, sp, 1, 2);
+
+ boost::hof::apply(&derived_hash::g2, x, 1, 2);
+ boost::hof::apply(&derived_hash::g2, rcx, 1, 2);
+ boost::hof::apply(&derived_hash::g2, &x, 1, 2);
+ boost::hof::apply(&derived_hash::g2, pcx, 1, 2);
+ boost::hof::apply(&derived_hash::g2, sp, 1, 2);
+
+ boost::hof::apply(&derived_hash::f3, x, 1, 2, 3);
+ boost::hof::apply(&derived_hash::f3, &x, 1, 2, 3);
+ boost::hof::apply(&derived_hash::f3, sp, 1, 2, 3);
+
+ boost::hof::apply(&derived_hash::g3, x, 1, 2, 3);
+ boost::hof::apply(&derived_hash::g3, rcx, 1, 2, 3);
+ boost::hof::apply(&derived_hash::g3, &x, 1, 2, 3);
+ boost::hof::apply(&derived_hash::g3, pcx, 1, 2, 3);
+ boost::hof::apply(&derived_hash::g3, sp, 1, 2, 3);
+
+ boost::hof::apply(&derived_hash::f4, x, 1, 2, 3, 4);
+ boost::hof::apply(&derived_hash::f4, &x, 1, 2, 3, 4);
+ boost::hof::apply(&derived_hash::f4, sp, 1, 2, 3, 4);
+
+ boost::hof::apply(&derived_hash::g4, x, 1, 2, 3, 4);
+ boost::hof::apply(&derived_hash::g4, rcx, 1, 2, 3, 4);
+ boost::hof::apply(&derived_hash::g4, &x, 1, 2, 3, 4);
+ boost::hof::apply(&derived_hash::g4, pcx, 1, 2, 3, 4);
+ boost::hof::apply(&derived_hash::g4, sp, 1, 2, 3, 4);
+
+ boost::hof::apply(&derived_hash::f5, x, 1, 2, 3, 4, 5);
+ boost::hof::apply(&derived_hash::f5, &x, 1, 2, 3, 4, 5);
+ boost::hof::apply(&derived_hash::f5, sp, 1, 2, 3, 4, 5);
+
+ boost::hof::apply(&derived_hash::g5, x, 1, 2, 3, 4, 5);
+ boost::hof::apply(&derived_hash::g5, rcx, 1, 2, 3, 4, 5);
+ boost::hof::apply(&derived_hash::g5, &x, 1, 2, 3, 4, 5);
+ boost::hof::apply(&derived_hash::g5, pcx, 1, 2, 3, 4, 5);
+ boost::hof::apply(&derived_hash::g5, sp, 1, 2, 3, 4, 5);
+
+ boost::hof::apply(&derived_hash::f6, x, 1, 2, 3, 4, 5, 6);
+ boost::hof::apply(&derived_hash::f6, &x, 1, 2, 3, 4, 5, 6);
+ boost::hof::apply(&derived_hash::f6, sp, 1, 2, 3, 4, 5, 6);
+
+ boost::hof::apply(&derived_hash::g6, x, 1, 2, 3, 4, 5, 6);
+ boost::hof::apply(&derived_hash::g6, rcx, 1, 2, 3, 4, 5, 6);
+ boost::hof::apply(&derived_hash::g6, &x, 1, 2, 3, 4, 5, 6);
+ boost::hof::apply(&derived_hash::g6, pcx, 1, 2, 3, 4, 5, 6);
+ boost::hof::apply(&derived_hash::g6, sp, 1, 2, 3, 4, 5, 6);
+
+ boost::hof::apply(&derived_hash::f7, x, 1, 2, 3, 4, 5, 6, 7);
+ boost::hof::apply(&derived_hash::f7, &x, 1, 2, 3, 4, 5, 6, 7);
+ boost::hof::apply(&derived_hash::f7, sp, 1, 2, 3, 4, 5, 6, 7);
+
+ boost::hof::apply(&derived_hash::g7, x, 1, 2, 3, 4, 5, 6, 7);
+ boost::hof::apply(&derived_hash::g7, rcx, 1, 2, 3, 4, 5, 6, 7);
+ boost::hof::apply(&derived_hash::g7, &x, 1, 2, 3, 4, 5, 6, 7);
+ boost::hof::apply(&derived_hash::g7, pcx, 1, 2, 3, 4, 5, 6, 7);
+ boost::hof::apply(&derived_hash::g7, sp, 1, 2, 3, 4, 5, 6, 7);
+
+ boost::hof::apply(&derived_hash::f8, x, 1, 2, 3, 4, 5, 6, 7, 8);
+ boost::hof::apply(&derived_hash::f8, &x, 1, 2, 3, 4, 5, 6, 7, 8);
+ boost::hof::apply(&derived_hash::f8, sp, 1, 2, 3, 4, 5, 6, 7, 8);
+
+ boost::hof::apply(&derived_hash::g8, x, 1, 2, 3, 4, 5, 6, 7, 8);
+ boost::hof::apply(&derived_hash::g8, rcx, 1, 2, 3, 4, 5, 6, 7, 8);
+ boost::hof::apply(&derived_hash::g8, &x, 1, 2, 3, 4, 5, 6, 7, 8);
+ boost::hof::apply(&derived_hash::g8, pcx, 1, 2, 3, 4, 5, 6, 7, 8);
+ boost::hof::apply(&derived_hash::g8, sp, 1, 2, 3, 4, 5, 6, 7, 8);
+
+ BOOST_HOF_TEST_CHECK(boost::hof::apply(&derived_hash::hash, x) == 17610 && boost::hof::apply(&derived_hash::hash, sp) == 2155);
+}
+
+struct dm_t
+{
+ int m;
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ dm_t x = { 0 };
+
+ boost::hof::apply( &dm_t::m, x ) = 401;
+
+ BOOST_HOF_TEST_CHECK( x.m == 401 );
+ BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, x ) == 401 );
+
+ boost::hof::apply( &dm_t::m, &x ) = 502;
+
+ BOOST_HOF_TEST_CHECK( x.m == 502 );
+ BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, &x ) == 502 );
+
+ dm_t * px = &x;
+
+ boost::hof::apply( &dm_t::m, px ) = 603;
+
+ BOOST_HOF_TEST_CHECK( x.m == 603 );
+ BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, px ) == 603 );
+
+ dm_t const & cx = x;
+ dm_t const * pcx = &x;
+
+ BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, cx ) == 603 );
+ BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, pcx ) == 603 );
+
+}
+
+
+struct X_ref
+{
+ int f()
+ {
+ return 1;
+ }
+
+ int g() const
+ {
+ return 2;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ X_ref x;
+
+ BOOST_HOF_TEST_CHECK( boost::hof::apply( &X_ref::f, std::ref( x ) ) == 1 );
+ BOOST_HOF_TEST_CHECK( boost::hof::apply( &X_ref::g, std::cref( x ) ) == 2 );
+}
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+struct copy_throws
+{
+ copy_throws() {}
+ copy_throws(copy_throws const&) {}
+ copy_throws(copy_throws&&) noexcept {}
+};
+
+struct no_throw_fo
+{
+ void operator()() noexcept {}
+ void operator()(copy_throws) noexcept {}
+};
+
+struct throws_fo
+{
+ void operator()() {}
+};
+
+struct member_obj
+{
+ int x;
+};
+// Only newer versions of gcc support deducing noexcept for member function pointers
+#if defined(__GNUC__) && !defined (__clang__) && ((__GNUC__ == 4 && __GNUC_MINOR__ > 8) || (__GNUC__ > 4))
+struct no_throw_member_fun
+{
+ void foo_nullary() noexcept {}
+ void foo_unary(copy_throws) noexcept {}
+};
+BOOST_HOF_TEST_CASE()
+{
+ no_throw_member_fun obj;
+ copy_throws arg;
+ static_assert(noexcept(boost::hof::apply(&no_throw_member_fun::foo_nullary, obj)), "");
+ static_assert(!noexcept(boost::hof::apply(&no_throw_member_fun::foo_unary, obj, arg)), "");
+ static_assert(noexcept(boost::hof::apply(&no_throw_member_fun::foo_unary, obj, std::move(arg))), "");
+}
+#endif
+BOOST_HOF_TEST_CASE()
+{
+ no_throw_fo obj;
+ copy_throws arg;
+ static_assert(noexcept(boost::hof::apply(obj)), "");
+ static_assert(!noexcept(boost::hof::apply(obj, arg)), "");
+ static_assert(noexcept(boost::hof::apply(obj, std::move(arg))), "");
+}
+BOOST_HOF_TEST_CASE()
+{
+ throws_fo obj;
+ static_assert(!noexcept(boost::hof::apply(obj)), "");
+}
+BOOST_HOF_TEST_CASE()
+{
+ member_obj obj{42};
+ static_assert(noexcept(boost::hof::apply(&member_obj::x, obj)), "");
+}
+#endif
diff --git a/src/boost/libs/hof/test/apply_eval.cpp b/src/boost/libs/hof/test/apply_eval.cpp
new file mode 100644
index 000000000..c97d87c30
--- /dev/null
+++ b/src/boost/libs/hof/test/apply_eval.cpp
@@ -0,0 +1,63 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ apply_eval.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/apply_eval.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/placeholders.hpp>
+#include "test.hpp"
+
+#include <memory>
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply_eval(binary_class(), boost::hof::always(1), boost::hof::always(2)) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::apply_eval(binary_class(), []{ return 1; }, []{ return 2;}) == 3);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ boost::hof::apply_eval(boost::hof::always(), boost::hof::always(1), boost::hof::always(2));
+}
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::apply_eval(boost::hof::always(), boost::hof::always(1), boost::hof::always(2))), "noexcept apply_eval");
+}
+#endif
+BOOST_HOF_TEST_CASE()
+{
+ int i = 3;
+ BOOST_HOF_TEST_CHECK(boost::hof::apply_eval(boost::hof::_ - boost::hof::_, [&]{ return i++; }, [&]{ return i++;}) == -1);
+ BOOST_HOF_TEST_CHECK(boost::hof::apply_eval(boost::hof::_ - boost::hof::_, [&]{ return ++i; }, [&]{ return ++i;}) == -1);
+}
+
+struct indirect_sum_f
+{
+ template<class T, class U>
+ auto operator()(T x, U y) const
+ BOOST_HOF_RETURNS(*x + *y);
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(
+ boost::hof::apply_eval(
+ indirect_sum_f(),
+ []{ return std::unique_ptr<int>(new int(1)); },
+ []{ return std::unique_ptr<int>(new int(2)); })
+ == 3);
+}
+
+std::unique_ptr<int> moveable(int i)
+{
+ return std::unique_ptr<int>{new int(i)};
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(*boost::hof::apply_eval(&moveable, boost::hof::always(1)) == 1);
+ BOOST_HOF_TEST_CHECK(*boost::hof::apply_eval(&moveable, boost::hof::always(3)) == 3);
+}
diff --git a/src/boost/libs/hof/test/arg.cpp b/src/boost/libs/hof/test/arg.cpp
new file mode 100644
index 000000000..b6343a330
--- /dev/null
+++ b/src/boost/libs/hof/test/arg.cpp
@@ -0,0 +1,53 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ arg.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/arg.hpp>
+#include <boost/hof/is_invocable.hpp>
+#include <type_traits>
+#include "test.hpp"
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::arg_c<3>(1,2,3,4,5) == 3);
+ BOOST_HOF_TEST_CHECK( boost::hof::arg_c<3>(1,2,3,4,5) == 3 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::arg(std::integral_constant<int, 3>())(1,2,3,4,5) == 3);
+ BOOST_HOF_TEST_CHECK( boost::hof::arg(std::integral_constant<int, 3>())(1,2,3,4,5) == 3 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto at_3 = boost::hof::arg(std::integral_constant<int, 3>());
+ static_assert(boost::hof::is_invocable<decltype(at_3), int, int, int>::value, "Not SFINAE-friendly");
+ static_assert(!boost::hof::is_invocable<decltype(at_3), int, int>::value, "Not SFINAE-friendly");
+ static_assert(!boost::hof::is_invocable<decltype(at_3), int>::value, "Not SFINAE-friendly");
+}
+
+struct foo {};
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(!boost::hof::is_invocable<decltype(boost::hof::arg), int>::value, "Not sfinae friendly");
+ static_assert(!boost::hof::is_invocable<decltype(boost::hof::arg), foo>::value, "Not sfinae friendly");
+}
+
+struct copy_throws
+{
+ copy_throws() {}
+ copy_throws(copy_throws const&) {}
+ copy_throws(copy_throws&&) noexcept {}
+};
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::arg_c<3>(1,2,3,4,5)), "noexcept arg");
+ static_assert(noexcept(boost::hof::arg(std::integral_constant<int, 3>())(1,2,3,4,5)), "noexcept arg");
+ static_assert(!noexcept(boost::hof::arg(std::integral_constant<int, 3>())(1,2,copy_throws{},4,5)), "noexcept arg");
+}
+#endif
diff --git a/src/boost/libs/hof/test/capture.cpp b/src/boost/libs/hof/test/capture.cpp
new file mode 100644
index 000000000..ac80447e3
--- /dev/null
+++ b/src/boost/libs/hof/test/capture.cpp
@@ -0,0 +1,96 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ capture.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/capture.hpp>
+#include <boost/hof/identity.hpp>
+#include "test.hpp"
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture_basic(1, 2)(binary_class())() == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::capture_basic(1, 2)(binary_class())() == 3);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture_basic(1)(binary_class())(2) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::capture_basic(1)(binary_class())(2) == 3);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture_basic()(binary_class())(1, 2) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::capture_basic()(binary_class())(1, 2) == 3);
+
+ static const int one = 1;
+ static const int two = 2;
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture_forward(one, two)(binary_class())() == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::capture_forward(one, two)(binary_class())() == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::capture_forward(1, 2)(binary_class())() == 3);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture_forward(one)(binary_class())(two) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::capture_forward(1)(binary_class())(2) == 3);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture_forward()(binary_class())(one, two) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::capture_forward()(binary_class())(one, two) == 3);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture(1, 2)(binary_class())() == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::capture(1, 2)(binary_class())() == 3);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture(1)(binary_class())(2) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::capture(1)(binary_class())(2) == 3);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture()(binary_class())(1, 2) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::capture()(binary_class())(1, 2) == 3);
+}
+
+struct add_member
+{
+ int i;
+
+ add_member(int ip) : i(ip)
+ {}
+
+ int add(int j) const
+ {
+ return i + j;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::capture_basic(add_member(1), 2)(&add_member::add)() == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::capture_basic(add_member(1))(&add_member::add)(2) == 3);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto id = boost::hof::identity;
+ auto f = boost::hof::capture(boost::hof::identity)(boost::hof::identity);
+ static_assert(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(decltype(id)), "Id not default constructible");
+ static_assert(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(decltype(f)), "Not default constructible");
+ f();
+}
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::capture(boost::hof::identity)(boost::hof::identity)()), "noexcept capture");
+ static_assert(noexcept(boost::hof::capture_basic(boost::hof::identity)(boost::hof::identity)()), "noexcept capture");
+ static_assert(noexcept(boost::hof::capture_forward(boost::hof::identity)(boost::hof::identity)()), "noexcept capture");
+}
+#endif
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::capture_basic(boost::hof::identity)(boost::hof::identity);
+ f();
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::capture_forward(boost::hof::identity)(boost::hof::identity);
+ f();
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::capture(boost::hof::identity)(add_member{1});
+ static_assert(!boost::hof::is_invocable<decltype(f), int>::value, "Not sfinae friendly");
+}
+
diff --git a/src/boost/libs/hof/test/combine.cpp b/src/boost/libs/hof/test/combine.cpp
new file mode 100644
index 000000000..6340150e9
--- /dev/null
+++ b/src/boost/libs/hof/test/combine.cpp
@@ -0,0 +1,71 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ combine.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/combine.hpp>
+#include "test.hpp"
+
+#include <boost/hof/construct.hpp>
+#include <boost/hof/capture.hpp>
+#include <utility>
+#include <tuple>
+
+template<class T, class U>
+struct mini_pair
+{
+ T first;
+ U second;
+
+ template<class X, class Y>
+ constexpr mini_pair(X&& x, Y&& y)
+ : first(boost::hof::forward<X>(x)), second(boost::hof::forward<Y>(y))
+ {}
+};
+
+template<class T1, class U1, class T2, class U2>
+constexpr bool operator==(const mini_pair<T1, U1>& x, const mini_pair<T2, U2>& y)
+{
+ return x.first == y.first && x.second == y.second;
+}
+
+template<class T, class U>
+constexpr mini_pair<T, U> make_mini_pair(T x, U y)
+{
+ return mini_pair<T, U>(x, y);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(
+ boost::hof::combine(
+ boost::hof::construct<std::tuple>(),
+ boost::hof::capture_basic(1)(boost::hof::construct<std::pair>()),
+ boost::hof::capture_basic(2)(boost::hof::construct<std::pair>())
+ )(2, 4)
+ == std::make_tuple(std::make_pair(1, 2), std::make_pair(2, 4)));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(
+ boost::hof::combine(
+ boost::hof::construct<mini_pair>(),
+ boost::hof::capture_basic(1)(boost::hof::construct<mini_pair>()),
+ boost::hof::capture_basic(2)(boost::hof::construct<mini_pair>())
+ )(2, 4)
+ == make_mini_pair(make_mini_pair(1, 2), make_mini_pair(2, 4)));
+
+ BOOST_HOF_STATIC_TEST_CHECK(
+ boost::hof::combine(
+ boost::hof::construct<mini_pair>(),
+ boost::hof::capture_basic(1)(boost::hof::construct<mini_pair>()),
+ boost::hof::capture_basic(2)(boost::hof::construct<mini_pair>())
+ )(2, 4)
+ == make_mini_pair(make_mini_pair(1, 2), make_mini_pair(2, 4)));
+}
+
+
+
+
diff --git a/src/boost/libs/hof/test/compose.cpp b/src/boost/libs/hof/test/compose.cpp
new file mode 100644
index 000000000..f36291fda
--- /dev/null
+++ b/src/boost/libs/hof/test/compose.cpp
@@ -0,0 +1,186 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ compose.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/compose.hpp>
+#include <boost/hof/function.hpp>
+#include <boost/hof/lambda.hpp>
+#include <boost/hof/placeholders.hpp>
+#include <memory>
+#include "test.hpp"
+
+namespace compose_test {
+struct increment
+{
+ template<class T>
+ constexpr T operator()(T x) const noexcept
+ {
+ return x + 1;
+ }
+};
+
+struct decrement
+{
+ template<class T>
+ constexpr T operator()(T x) const noexcept
+ {
+ return x - 1;
+ }
+};
+
+struct negate
+{
+ template<class T>
+ constexpr T operator()(T x) const noexcept
+ {
+ return -x;
+ }
+};
+
+struct increment_movable
+{
+ std::unique_ptr<int> n;
+ increment_movable()
+ : n(new int(1))
+ {}
+ template<class T>
+ T operator()(T x) const
+ {
+ return x + *n;
+ }
+};
+
+struct decrement_movable
+{
+ std::unique_ptr<int> n;
+ decrement_movable()
+ : n(new int(1))
+ {}
+ template<class T>
+ T operator()(T x) const
+ {
+ return x - *n;
+ }
+};
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::compose(increment(), decrement(), increment())(3)), "noexcept compose");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::compose(boost::hof::identity)(3) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::compose(boost::hof::identity, boost::hof::identity)(3) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::compose(boost::hof::identity, boost::hof::identity, boost::hof::identity)(3) == 3);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(boost::hof::identity)(3) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(boost::hof::identity, boost::hof::identity)(3) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(boost::hof::identity, boost::hof::identity, boost::hof::identity)(3) == 3);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ int r = boost::hof::compose(increment(), decrement(), increment())(3);
+ BOOST_HOF_TEST_CHECK(r == 4);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(increment(), decrement(), increment())(3) == 4);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ int r = boost::hof::compose(increment(), negate(), decrement(), decrement())(3);
+ BOOST_HOF_TEST_CHECK(r == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(increment(), negate(), decrement(), decrement())(3) == 0);
+}
+BOOST_HOF_TEST_CASE()
+{
+ constexpr auto f = boost::hof::compose(increment(), decrement());
+#ifndef _MSC_VER
+ static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty");
+#endif
+ static_assert(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(decltype(f)), "Compose function not default constructible");
+ int r = f(3);
+ BOOST_HOF_TEST_CHECK(r == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(f(3) == 3);
+}
+
+#ifndef _MSC_VER
+BOOST_HOF_TEST_CASE()
+{
+ constexpr auto f = boost::hof::compose(increment(), negate(), decrement(), decrement());
+ static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty");
+ static_assert(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(decltype(f)), "Compose function not default constructible");
+ int r = f(3);
+ BOOST_HOF_TEST_CHECK(r == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(f(3) == 0);
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ STATIC_ASSERT_MOVE_ONLY(increment_movable);
+ STATIC_ASSERT_MOVE_ONLY(decrement_movable);
+ int r = boost::hof::compose(increment_movable(), decrement_movable(), increment_movable())(3);
+ BOOST_HOF_TEST_CHECK(r == 4);
+}
+
+template<class T>
+struct print;
+
+BOOST_HOF_TEST_CASE()
+{
+ const auto f = boost::hof::compose([](int i) { return i+1; }, [](int i) { return i-1; }, [](int i) { return i+1; });
+#ifndef _MSC_VER
+ static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty");
+#endif
+ int r = f(3);
+ BOOST_HOF_TEST_CHECK(r == 4);
+}
+
+
+BOOST_HOF_STATIC_FUNCTION(f_compose_single_function) = boost::hof::compose(increment());
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(f_compose_single_function(3) == 4);
+ BOOST_HOF_STATIC_TEST_CHECK(f_compose_single_function(3) == 4);
+}
+
+BOOST_HOF_STATIC_FUNCTION(f_compose_function) = boost::hof::compose(increment(), decrement(), increment());
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(f_compose_function(3) == 4);
+ BOOST_HOF_STATIC_TEST_CHECK(f_compose_function(3) == 4);
+}
+
+BOOST_HOF_STATIC_FUNCTION(f_compose_function_4) = boost::hof::compose(increment(), negate(), decrement(), decrement());
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(f_compose_function_4(3) == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(f_compose_function_4(3) == 0);
+}
+
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(f_compose_lambda) = boost::hof::compose(
+ [](int i) { return i+1; },
+ [](int i) { return i-1; },
+ [](int i) { return i+1; }
+);
+
+BOOST_HOF_TEST_CASE()
+{
+ int r = f_compose_lambda(3);
+ BOOST_HOF_TEST_CHECK(r == 4);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::compose(boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1)(3) == 36);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1)(3) == 36);
+}
+}
diff --git a/src/boost/libs/hof/test/construct.cpp b/src/boost/libs/hof/test/construct.cpp
new file mode 100644
index 000000000..953f0f6c3
--- /dev/null
+++ b/src/boost/libs/hof/test/construct.cpp
@@ -0,0 +1,222 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ construct.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/construct.hpp>
+#include "test.hpp"
+
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/proj.hpp>
+#include <boost/hof/placeholders.hpp>
+
+#include <tuple>
+#include <type_traits>
+#include <vector>
+
+template<class T>
+struct ac
+{
+ T value;
+ constexpr ac(T i) : value(i)
+ {}
+};
+
+template<class... Ts>
+struct tuple_meta
+{
+ typedef std::tuple<Ts...> type;
+};
+
+struct tuple_meta_class
+{
+ template<class... Ts>
+ struct apply
+ {
+ typedef std::tuple<Ts...> type;
+ };
+};
+
+struct implicit_default
+{
+ int mem1;
+ std::string mem2;
+};
+
+struct user_default
+{
+ int mem1;
+ std::string mem2;
+ user_default() { }
+};
+
+struct user_construct
+{
+ int mem1;
+ std::string mem2;
+ user_construct(int) { }
+};
+
+template<class T>
+struct template_user_construct
+{
+ int mem1;
+ std::string mem2;
+ template_user_construct(T) { }
+};
+
+
+BOOST_HOF_TEST_CASE()
+{
+ auto v = boost::hof::construct<std::vector<int>>()(5, 5);
+ BOOST_HOF_TEST_CHECK(v.size() == 5);
+ BOOST_HOF_TEST_CHECK(v == std::vector<int>{5, 5, 5, 5, 5});
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto v = boost::hof::construct_basic<std::vector<int>>()(5, 5);
+ BOOST_HOF_TEST_CHECK(v.size() == 5);
+ BOOST_HOF_TEST_CHECK(v == std::vector<int>{5, 5, 5, 5, 5});
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto v = boost::hof::construct_forward<std::vector<int>>()(5, 5);
+ BOOST_HOF_TEST_CHECK(v.size() == 5);
+ BOOST_HOF_TEST_CHECK(v == std::vector<int>{5, 5, 5, 5, 5});
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto x = boost::hof::construct<implicit_default>()();
+ BOOST_HOF_TEST_CHECK(x.mem1 == 0);
+ BOOST_HOF_TEST_CHECK(x.mem2 == "");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto x = boost::hof::construct<user_default>()();
+ BOOST_HOF_TEST_CHECK(x.mem1 == 0);
+ BOOST_HOF_TEST_CHECK(x.mem2 == "");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto x = boost::hof::construct<user_construct>()(3);
+ BOOST_HOF_TEST_CHECK(x.mem1 == 0);
+ BOOST_HOF_TEST_CHECK(x.mem2 == "");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto x = boost::hof::construct<template_user_construct>()(3);
+ BOOST_HOF_TEST_CHECK(x.mem1 == 0);
+ BOOST_HOF_TEST_CHECK(x.mem2 == "");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto x = boost::hof::construct_forward<template_user_construct>()(3);
+ BOOST_HOF_TEST_CHECK(x.mem1 == 0);
+ BOOST_HOF_TEST_CHECK(x.mem2 == "");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto x = boost::hof::construct_basic<template_user_construct>()(3);
+ BOOST_HOF_TEST_CHECK(x.mem1 == 0);
+ BOOST_HOF_TEST_CHECK(x.mem2 == "");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto v = boost::hof::construct<std::vector<int>>()({5, 5, 5, 5, 5});
+ BOOST_HOF_TEST_CHECK(v.size() == 5);
+ BOOST_HOF_TEST_CHECK(v == std::vector<int>{5, 5, 5, 5, 5});
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto t = boost::hof::construct<std::tuple>()(1, 2, 3);
+ static_assert(std::is_same<std::tuple<int, int, int>, decltype(t)>::value, "");
+ BOOST_HOF_TEST_CHECK(t == std::make_tuple(1, 2, 3));
+// GCC 4.7 doesn't have fully constexpr tuple
+#if BOOST_HOF_HAS_CONSTEXPR_TUPLE
+ BOOST_HOF_STATIC_TEST_CHECK(std::make_tuple(1, 2, 3) == boost::hof::construct<std::tuple>()(1, 2, 3));
+#endif
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto t = boost::hof::construct<std::pair>()(1, 2);
+ static_assert(std::is_same<std::pair<int, int>, decltype(t)>::value, "");
+ BOOST_HOF_TEST_CHECK(t == std::make_pair(1, 2));
+// GCC 4.7 doesn't have fully constexpr pair
+#if BOOST_HOF_HAS_CONSTEXPR_TUPLE
+ BOOST_HOF_STATIC_TEST_CHECK(std::make_pair(1, 2) == boost::hof::construct<std::pair>()(1, 2));
+#endif
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::first_of(boost::hof::construct<std::pair>(), boost::hof::identity);
+ BOOST_HOF_TEST_CHECK(f(1, 2) == std::make_pair(1, 2));
+ BOOST_HOF_TEST_CHECK(f(1) == 1);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto x = boost::hof::construct<ac>()(1);
+ static_assert(std::is_same<ac<int>, decltype(x)>::value, "");
+ BOOST_HOF_TEST_CHECK(x.value == ac<int>(1).value);
+ BOOST_HOF_STATIC_TEST_CHECK(ac<int>(1).value == boost::hof::construct<ac>()(1).value);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto x = boost::hof::construct_basic<ac>()(1);
+ static_assert(std::is_same<ac<int>, decltype(x)>::value, "");
+ BOOST_HOF_TEST_CHECK(x.value == ac<int>(1).value);
+ BOOST_HOF_STATIC_TEST_CHECK(ac<int>(1).value == boost::hof::construct<ac>()(1).value);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ int i = 1;
+ auto x = boost::hof::construct_forward<ac>()(i);
+ static_assert(std::is_same<ac<int&>, decltype(x)>::value, "");
+ BOOST_HOF_TEST_CHECK(&x.value == &i);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ int i = 1;
+ auto x = boost::hof::construct_basic<ac>()(i);
+ static_assert(std::is_same<ac<int&>, decltype(x)>::value, "");
+ BOOST_HOF_TEST_CHECK(&x.value == &i);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto t = boost::hof::construct_meta<tuple_meta>()(1, 2, 3);
+ static_assert(std::is_same<std::tuple<int, int, int>, decltype(t)>::value, "");
+ BOOST_HOF_TEST_CHECK(t == std::make_tuple(1, 2, 3));
+// GCC 4.7 doesn't have fully constexpr tuple
+#if BOOST_HOF_HAS_CONSTEXPR_TUPLE
+ BOOST_HOF_STATIC_TEST_CHECK(std::make_tuple(1, 2, 3) == boost::hof::construct_meta<tuple_meta>()(1, 2, 3));
+#endif
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto t = boost::hof::construct_meta<tuple_meta_class>()(1, 2, 3);
+ static_assert(std::is_same<std::tuple<int, int, int>, decltype(t)>::value, "");
+ BOOST_HOF_TEST_CHECK(t == std::make_tuple(1, 2, 3));
+// GCC 4.7 doesn't have fully constexpr tuple
+#if BOOST_HOF_HAS_CONSTEXPR_TUPLE
+ BOOST_HOF_STATIC_TEST_CHECK(std::make_tuple(1, 2, 3) == boost::hof::construct_meta<tuple_meta_class>()(1, 2, 3));
+#endif
+}
+
diff --git a/src/boost/libs/hof/test/decay.cpp b/src/boost/libs/hof/test/decay.cpp
new file mode 100644
index 000000000..bcf235bfd
--- /dev/null
+++ b/src/boost/libs/hof/test/decay.cpp
@@ -0,0 +1,28 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ decay.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/decay.hpp>
+#include "test.hpp"
+
+#define CHECK_DECAY(T) \
+ STATIC_ASSERT_SAME(decltype(boost::hof::decay(std::declval<T>())), std::decay<T>::type)
+
+BOOST_HOF_TEST_CASE()
+{
+ CHECK_DECAY(int);
+ CHECK_DECAY(int*);
+ CHECK_DECAY(int&);
+ CHECK_DECAY(int&&);
+ CHECK_DECAY(const int&);
+ CHECK_DECAY(int[2]);
+ CHECK_DECAY(int(int));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::decay(3) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::decay(3) == 3);
+}
diff --git a/src/boost/libs/hof/test/decorate.cpp b/src/boost/libs/hof/test/decorate.cpp
new file mode 100644
index 000000000..11b1f5b66
--- /dev/null
+++ b/src/boost/libs/hof/test/decorate.cpp
@@ -0,0 +1,35 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ decorate.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/decorate.hpp>
+#include "test.hpp"
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::decorate(boost::hof::always(1))(boost::hof::always(1))(boost::hof::always(1))(5) == 1);
+}
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+struct copy_throws
+{
+ copy_throws() {}
+ copy_throws(copy_throws const&) {}
+ copy_throws(copy_throws&&) noexcept {}
+};
+
+struct no_throw_fo
+{
+ void operator()() const noexcept {}
+ void operator()(copy_throws) const noexcept {}
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::decorate(boost::hof::always(1))(boost::hof::always(1))(boost::hof::always(1))(5)), "noexcept decorator");
+ static_assert(!noexcept(boost::hof::decorate(boost::hof::always(1))(boost::hof::always(1))(boost::hof::always(1))(copy_throws{})), "noexcept decorator");
+}
+
+#endif
diff --git a/src/boost/libs/hof/test/fail/always.cpp b/src/boost/libs/hof/test/fail/always.cpp
new file mode 100644
index 000000000..76b6e5d70
--- /dev/null
+++ b/src/boost/libs/hof/test/fail/always.cpp
@@ -0,0 +1,14 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ always.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/always.hpp>
+#include <memory>
+
+int main() {
+ auto f = boost::hof::always(std::unique_ptr<int>{new int(1)});
+ auto i = f(1, 2, 3);
+ (void)i;
+}
diff --git a/src/boost/libs/hof/test/fail/apply_eval.cpp b/src/boost/libs/hof/test/fail/apply_eval.cpp
new file mode 100644
index 000000000..c87d7ed9d
--- /dev/null
+++ b/src/boost/libs/hof/test/fail/apply_eval.cpp
@@ -0,0 +1,11 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ apply_eval.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/apply_eval.hpp>
+
+int main() {
+ (void)boost::hof::apply_eval(boost::hof::always(), 1, 2);
+}
diff --git a/src/boost/libs/hof/test/fail/flip_lazy.cpp b/src/boost/libs/hof/test/fail/flip_lazy.cpp
new file mode 100644
index 000000000..7d5e0dc36
--- /dev/null
+++ b/src/boost/libs/hof/test/fail/flip_lazy.cpp
@@ -0,0 +1,14 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ flip_lazy.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/lazy.hpp>
+#include <boost/hof/placeholders.hpp>
+#include <boost/hof/flip.hpp>
+
+int main() {
+ auto i = (boost::hof::flip(boost::hof::_1 - boost::hof::_2) * boost::hof::_1)(3, 6);
+ (void)i;
+}
diff --git a/src/boost/libs/hof/test/fail/implicit.cpp b/src/boost/libs/hof/test/fail/implicit.cpp
new file mode 100644
index 000000000..df81297ac
--- /dev/null
+++ b/src/boost/libs/hof/test/fail/implicit.cpp
@@ -0,0 +1,29 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ implicit.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/implicit.hpp>
+
+template<class T>
+struct auto_caster
+{
+ template<class U>
+ T operator()(U x)
+ {
+ return T(x);
+ }
+};
+
+
+int main()
+{
+ boost::hof::implicit<auto_caster> auto_cast = {};
+ auto x = auto_cast(1.5);
+ (void)x;
+// This is not possible in c++17 due to guaranteed copy elison
+#if BOOST_HOF_HAS_STD_17 || (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7)
+ static_assert(false, "Always fail");
+#endif
+}
diff --git a/src/boost/libs/hof/test/fail/rotate_lazy.cpp b/src/boost/libs/hof/test/fail/rotate_lazy.cpp
new file mode 100644
index 000000000..59c4f4e95
--- /dev/null
+++ b/src/boost/libs/hof/test/fail/rotate_lazy.cpp
@@ -0,0 +1,14 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ rotate_lazy.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/lazy.hpp>
+#include <boost/hof/placeholders.hpp>
+#include <boost/hof/rotate.hpp>
+
+int main() {
+ auto i = (boost::hof::rotate(boost::hof::_1 - boost::hof::_2) * boost::hof::_1)(3, 6);
+ (void)i;
+}
diff --git a/src/boost/libs/hof/test/fail/unpack.cpp b/src/boost/libs/hof/test/fail/unpack.cpp
new file mode 100644
index 000000000..f4758be0c
--- /dev/null
+++ b/src/boost/libs/hof/test/fail/unpack.cpp
@@ -0,0 +1,27 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ unpack.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/unpack.hpp>
+
+struct foo
+{};
+
+namespace boost { namespace hof {
+
+template<>
+struct unpack_sequence<foo>
+{
+ template<class F, class S>
+ constexpr static int apply(F&&, S&&)
+ {
+ return 0;
+ }
+};
+}
+
+int main() {
+ boost::hof::unpack(boost::hof::always(1))(foo{});
+}
diff --git a/src/boost/libs/hof/test/fail/unpack_uncallable.cpp b/src/boost/libs/hof/test/fail/unpack_uncallable.cpp
new file mode 100644
index 000000000..d3c946f4e
--- /dev/null
+++ b/src/boost/libs/hof/test/fail/unpack_uncallable.cpp
@@ -0,0 +1,24 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ unpack_uncallable.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/unpack.hpp>
+
+struct foo
+{};
+
+namespace boost { namespace hof {
+
+template<>
+struct unpack_sequence<foo>
+{
+ template<class F, class S>
+ constexpr static auto apply(F&&, S&& s) BOOST_HOF_RETURNS(s.bar);
+};
+}
+
+int main() {
+ boost::hof::unpack(boost::hof::always(1))(foo{});
+}
diff --git a/src/boost/libs/hof/test/filter.cpp b/src/boost/libs/hof/test/filter.cpp
new file mode 100644
index 000000000..0b0268e01
--- /dev/null
+++ b/src/boost/libs/hof/test/filter.cpp
@@ -0,0 +1,54 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ filter.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/if.hpp>
+#include "test.hpp"
+
+#include <boost/hof/proj.hpp>
+#include <boost/hof/lift.hpp>
+#include <boost/hof/construct.hpp>
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/unpack.hpp>
+
+#include <tuple>
+
+BOOST_HOF_LIFT_CLASS(make_tuple_f, std::make_tuple);
+
+struct integer_predicate
+{
+ constexpr integer_predicate()
+ {}
+ template<class T>
+ constexpr auto operator()(T x) const BOOST_HOF_RETURNS
+ (
+ boost::hof::first_of(
+ boost::hof::if_(std::is_integral<T>())(boost::hof::pack_basic),
+ boost::hof::always(boost::hof::pack_basic())
+ )(boost::hof::move(x))
+ )
+};
+
+struct filter_integers
+{
+ template<class Seq>
+ constexpr auto operator()(Seq s) const BOOST_HOF_RETURNS
+ (
+ boost::hof::unpack(
+ boost::hof::proj(integer_predicate(), boost::hof::unpack(make_tuple_f()))
+ )(std::move(s))
+ )
+};
+
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(filter_integers()(boost::hof::pack_basic(1, 2, 2.0, 3)) == std::make_tuple(1, 2, 3));
+#if BOOST_HOF_HAS_CONSTEXPR_TUPLE
+ BOOST_HOF_STATIC_TEST_CHECK(filter_integers()(boost::hof::pack_basic(1, 2, 2.0, 3)) == std::make_tuple(1, 2, 3));
+#endif
+}
+
+
diff --git a/src/boost/libs/hof/test/final_base.cpp b/src/boost/libs/hof/test/final_base.cpp
new file mode 100644
index 000000000..d348e922a
--- /dev/null
+++ b/src/boost/libs/hof/test/final_base.cpp
@@ -0,0 +1,26 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ final_base.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/flip.hpp>
+#include "test.hpp"
+
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define FINAL
+#else
+#define FINAL final
+#endif
+
+
+struct f FINAL {
+ int operator()(int i, void *) const {
+ return i;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::flip(f())(nullptr, 2) == 2);
+}
diff --git a/src/boost/libs/hof/test/first_of.cpp b/src/boost/libs/hof/test/first_of.cpp
new file mode 100644
index 000000000..c995e5142
--- /dev/null
+++ b/src/boost/libs/hof/test/first_of.cpp
@@ -0,0 +1,216 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ first_of.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/static.hpp>
+#include <boost/hof/lambda.hpp>
+#include <boost/hof/function.hpp>
+#include <memory>
+#include "test.hpp"
+
+namespace conditional_test {
+
+#define CONDITIONAL_FUNCTION(n) \
+struct t ## n {}; \
+struct f ## n \
+{ \
+ constexpr int operator()(t ## n) const \
+ { \
+ return n; \
+ } \
+};
+
+CONDITIONAL_FUNCTION(1)
+CONDITIONAL_FUNCTION(2)
+CONDITIONAL_FUNCTION(3)
+
+#define CONDITIONAL_MOVE_FUNCTION(n) \
+struct t_move ## n {}; \
+struct f_move ## n \
+{ \
+ std::unique_ptr<int> i;\
+ f_move ## n(int ip) : i(new int(ip)) {}; \
+ int operator()(t_move ## n) const \
+ { \
+ return *i; \
+ } \
+};
+
+CONDITIONAL_MOVE_FUNCTION(1)
+CONDITIONAL_MOVE_FUNCTION(2)
+CONDITIONAL_MOVE_FUNCTION(3)
+
+struct ff
+{
+ constexpr int operator()(t2) const
+ {
+ return 500;
+ }
+};
+
+static constexpr boost::hof::static_<boost::hof::first_of_adaptor<f1, f2, f3, ff> > f = {};
+
+BOOST_HOF_STATIC_FUNCTION(f_constexpr) = boost::hof::first_of_adaptor<f1, f2, f3, ff>();
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(f(t1()) == 1);
+ BOOST_HOF_TEST_CHECK(f(t2()) == 2);
+ BOOST_HOF_TEST_CHECK(f(t3()) == 3);
+
+ BOOST_HOF_STATIC_TEST_CHECK(f_constexpr(t1()) == 1);
+ BOOST_HOF_STATIC_TEST_CHECK(f_constexpr(t2()) == 2);
+ BOOST_HOF_STATIC_TEST_CHECK(f_constexpr(t3()) == 3);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, f2{})(t1()) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, f2{})(t2()) == 2);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, f2{})(t1()) == 1);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, f2{})(t2()) == 2);
+}
+
+#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7)
+#else
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f1{}, f2{}))(t1()) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f1{}, f2{}))(t2()) == 2);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f1{}, f2{}))(t1()) == 1);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f1{}, f2{}))(t2()) == 2);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t1()) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t2()) == 2);
+ BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t3()) == 3);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t1()) == 1);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t2()) == 2);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t3()) == 3);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t1()) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t2()) == 2);
+ BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t3()) == 3);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t1()) == 1);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t2()) == 2);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t3()) == 3);
+}
+
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f_move_local = boost::hof::first_of(f_move1(1), f_move2(2), f_move3(3));
+ STATIC_ASSERT_MOVE_ONLY(decltype(f_move_local));
+ BOOST_HOF_TEST_CHECK(f_move_local(t_move1()) == 1);
+ BOOST_HOF_TEST_CHECK(f_move_local(t_move2()) == 2);
+ BOOST_HOF_TEST_CHECK(f_move_local(t_move3()) == 3);
+}
+#ifndef _MSC_VER
+static constexpr auto lam = boost::hof::first_of(
+ BOOST_HOF_STATIC_LAMBDA(t1)
+ {
+ return 1;
+ },
+ BOOST_HOF_STATIC_LAMBDA(t2)
+ {
+ return 2;
+ },
+ BOOST_HOF_STATIC_LAMBDA(t3)
+ {
+ return 3;
+ }
+);
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(lam(t1()) == 1);
+ BOOST_HOF_TEST_CHECK(lam(t2()) == 2);
+ BOOST_HOF_TEST_CHECK(lam(t3()) == 3);
+}
+#endif
+
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(static_fun) = boost::hof::first_of(
+ [](t1)
+ {
+ return 1;
+ },
+ [](t2)
+ {
+ return 2;
+ },
+ [](t3)
+ {
+ return 3;
+ }
+);
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(static_fun(t1()) == 1);
+ BOOST_HOF_TEST_CHECK(static_fun(t2()) == 2);
+ BOOST_HOF_TEST_CHECK(static_fun(t3()) == 3);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::identity, boost::hof::identity)(3) == 3);
+}
+
+template<class T>
+struct throw_fo
+{
+ void operator()(T) const {}
+};
+
+template<class T>
+struct no_throw_fo
+{
+ void operator()(T) const noexcept {}
+};
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ typedef boost::hof::first_of_adaptor<throw_fo<t1>, no_throw_fo<t2>> fun;
+ auto g = fun{};
+ static_assert(noexcept(g(t2{})), "noexcept conditional");
+ static_assert(!noexcept(g(t1{})), "noexcept conditional");
+
+ static_assert(noexcept(fun{}(t2{})), "noexcept conditional");
+ static_assert(!noexcept(fun{}(t1{})), "noexcept conditional");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ typedef boost::hof::first_of_adaptor<no_throw_fo<t2>, throw_fo<t1>> fun;
+ auto g = fun{};
+ static_assert(noexcept(g(t2{})), "noexcept conditional");
+ static_assert(!noexcept(g(t1{})), "noexcept conditional");
+
+ static_assert(noexcept(fun{}(t2{})), "noexcept conditional");
+ static_assert(!noexcept(fun{}(t1{})), "noexcept conditional");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::first_of_adaptor<no_throw_fo<t2>, throw_fo<t1>>{}(t2{})), "noexcept conditional");
+ static_assert(!noexcept(boost::hof::first_of_adaptor<no_throw_fo<t2>, throw_fo<t1>>{}(t1{})), "noexcept conditional");
+
+ static_assert(noexcept(boost::hof::first_of(no_throw_fo<t2>{}, throw_fo<t1>{})(t2{})), "noexcept conditional");
+ static_assert(!noexcept(boost::hof::first_of(no_throw_fo<t2>{}, throw_fo<t1>{})(t1{})), "noexcept conditional");
+}
+#endif
+}
diff --git a/src/boost/libs/hof/test/fix.cpp b/src/boost/libs/hof/test/fix.cpp
new file mode 100644
index 000000000..8262d9eb0
--- /dev/null
+++ b/src/boost/libs/hof/test/fix.cpp
@@ -0,0 +1,100 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ fix.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/fix.hpp>
+#include <boost/hof/static.hpp>
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/result.hpp>
+#include "test.hpp"
+
+#include <memory>
+
+struct factorial_t
+{
+ template<class Self, class T>
+ T operator()(Self s, T x) const noexcept
+ {
+ return x == 0 ? 1 : x * s(x-1);
+ }
+};
+
+struct factorial_constexpr_t
+{
+ template<class Self, class T>
+ constexpr T operator()(Self s, T x) const noexcept
+ {
+ return x == 0 ? 1 : x * s(x-1);
+ }
+};
+
+struct factorial_move_t
+{
+ std::unique_ptr<int> i;
+ factorial_move_t() : i(new int(1))
+ {}
+ template<class Self, class T>
+ T operator()(const Self& s, T x) const
+ {
+ return x == 0 ? *i : x * s(x-1);
+ }
+};
+
+static constexpr boost::hof::fix_adaptor<factorial_t> factorial = {};
+static constexpr boost::hof::fix_adaptor<factorial_constexpr_t> factorial_constexpr = {};
+static constexpr boost::hof::static_<boost::hof::fix_adaptor<factorial_move_t> > factorial_move = {};
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(factorial(5)), "noexcept fix");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ const int r = factorial(5);
+ BOOST_HOF_TEST_CHECK(r == 5*4*3*2*1);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ const int r = boost::hof::reveal(factorial)(5);
+ BOOST_HOF_TEST_CHECK(r == 5*4*3*2*1);
+}
+
+#if !BOOST_HOF_NO_EXPRESSION_SFINAE
+BOOST_HOF_TEST_CASE()
+{
+ const int r = boost::hof::fix(boost::hof::result<int>(factorial_constexpr_t()))(5);
+ BOOST_HOF_TEST_CHECK(r == 5*4*3*2*1);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ const int r = boost::hof::result<int>(factorial_constexpr)(5);
+ BOOST_HOF_TEST_CHECK(r == 5*4*3*2*1);
+}
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fix(boost::hof::result<int>(factorial_constexpr_t()))(5) == 5*4*3*2*1);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::result<int>(factorial_constexpr)(5) == 5*4*3*2*1);
+}
+#endif
+BOOST_HOF_TEST_CASE()
+{
+#if BOOST_HOF_HAS_GENERIC_LAMBDA
+ auto factorial_ = boost::hof::fix([](auto s, auto x) -> decltype(x) { return x == 0 ? 1 : x * s(x-1); });
+ int r = boost::hof::result<int>(factorial_)(5);
+ BOOST_HOF_TEST_CHECK(r == 5*4*3*2*1);
+#endif
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ const int r = factorial_move(5);
+ BOOST_HOF_TEST_CHECK(r == 5*4*3*2*1);
+ BOOST_HOF_TEST_CHECK(boost::hof::fix(factorial_move_t())(5) == 5*4*3*2*1);
+}
diff --git a/src/boost/libs/hof/test/flip.cpp b/src/boost/libs/hof/test/flip.cpp
new file mode 100644
index 000000000..599997421
--- /dev/null
+++ b/src/boost/libs/hof/test/flip.cpp
@@ -0,0 +1,61 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ flip.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/flip.hpp>
+#include <boost/hof/placeholders.hpp>
+#include "test.hpp"
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::flip(boost::hof::_ - boost::hof::_)(2, 5));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::flip(boost::hof::_ - boost::hof::_)(2, 5));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ typedef std::integral_constant<int, 1> one;
+ typedef std::integral_constant<int, 2> two;
+ typedef std::integral_constant<int, 3> three;
+ BOOST_HOF_TEST_CHECK(1 == boost::hof::arg(one{})(1, 2, 3, 4));
+ BOOST_HOF_STATIC_TEST_CHECK(1 == boost::hof::arg(one{})(1, 2, 3, 4));
+ BOOST_HOF_TEST_CHECK(2 == boost::hof::flip(boost::hof::arg(one{}))(1, 2, 3, 4));
+ BOOST_HOF_STATIC_TEST_CHECK(2 == boost::hof::flip(boost::hof::arg(one{}))(1, 2, 3, 4));
+
+ BOOST_HOF_TEST_CHECK(2 == boost::hof::arg(two{})(1, 2, 3, 4));
+ BOOST_HOF_STATIC_TEST_CHECK(2 == boost::hof::arg(two{})(1, 2, 3, 4));
+ BOOST_HOF_TEST_CHECK(1 == boost::hof::flip(boost::hof::arg(two{}))(1, 2, 3, 4));
+ BOOST_HOF_STATIC_TEST_CHECK(1 == boost::hof::flip(boost::hof::arg(two{}))(1, 2, 3, 4));
+
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::arg(three{})(1, 2, 3, 4));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::arg(three{})(1, 2, 3, 4));
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::flip(boost::hof::arg(three{}))(1, 2, 3, 4));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::flip(boost::hof::arg(three{}))(1, 2, 3, 4));
+}
+
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define FINAL
+#else
+#define FINAL final
+#endif
+
+
+struct f FINAL {
+ int operator()(int i, void *) const {
+ return i;
+ }
+};
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(boost::hof::flip(boost::hof::_ - boost::hof::_)(2, 5), "noexcept flip");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::flip(f())(nullptr, 2) == 2);
+}
diff --git a/src/boost/libs/hof/test/flow.cpp b/src/boost/libs/hof/test/flow.cpp
new file mode 100644
index 000000000..755374e47
--- /dev/null
+++ b/src/boost/libs/hof/test/flow.cpp
@@ -0,0 +1,169 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ flow.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/flow.hpp>
+#include <boost/hof/function.hpp>
+#include <boost/hof/lambda.hpp>
+#include <boost/hof/placeholders.hpp>
+#include <memory>
+#include "test.hpp"
+
+namespace flow_test {
+struct increment
+{
+ template<class T>
+ constexpr T operator()(T x) const noexcept
+ {
+ return x + 1;
+ }
+};
+
+struct decrement
+{
+ template<class T>
+ constexpr T operator()(T x) const noexcept
+ {
+ return x - 1;
+ }
+};
+
+struct negate
+{
+ template<class T>
+ constexpr T operator()(T x) const noexcept
+ {
+ return -x;
+ }
+};
+
+struct increment_movable
+{
+ std::unique_ptr<int> n;
+ increment_movable()
+ : n(new int(1))
+ {}
+ template<class T>
+ T operator()(T x) const
+ {
+ return x + *n;
+ }
+};
+
+struct decrement_movable
+{
+ std::unique_ptr<int> n;
+ decrement_movable()
+ : n(new int(1))
+ {}
+ template<class T>
+ T operator()(T x) const
+ {
+ return x - *n;
+ }
+};
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::flow(increment(), decrement(), increment())(3)), "noexcept flow");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::flow(boost::hof::identity)(3) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::flow(boost::hof::identity, boost::hof::identity)(3) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::flow(boost::hof::identity, boost::hof::identity, boost::hof::identity)(3) == 3);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(boost::hof::identity)(3) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(boost::hof::identity, boost::hof::identity)(3) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(boost::hof::identity, boost::hof::identity, boost::hof::identity)(3) == 3);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ int r = boost::hof::flow(increment(), decrement(), increment())(3);
+ BOOST_HOF_TEST_CHECK(r == 4);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(increment(), decrement(), increment())(3) == 4);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ int r = boost::hof::flow(increment(), negate(), decrement(), decrement())(3);
+ BOOST_HOF_TEST_CHECK(r == -6);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(increment(), negate(), decrement(), decrement())(3) == -6);
+}
+#ifndef _MSC_VER
+BOOST_HOF_TEST_CASE()
+{
+ constexpr auto f = boost::hof::flow(increment(), decrement());
+ static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty");
+ int r = f(3);
+ BOOST_HOF_TEST_CHECK(r == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(f(3) == 3);
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ STATIC_ASSERT_MOVE_ONLY(increment_movable);
+ STATIC_ASSERT_MOVE_ONLY(decrement_movable);
+ int r = boost::hof::flow(increment_movable(), decrement_movable(), increment_movable())(3);
+ BOOST_HOF_TEST_CHECK(r == 4);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ const auto f = boost::hof::flow([](int i) { return i+1; }, [](int i) { return i-1; }, [](int i) { return i+1; });
+#ifndef _MSC_VER
+ static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty");
+#endif
+ int r = f(3);
+ BOOST_HOF_TEST_CHECK(r == 4);
+}
+
+
+BOOST_HOF_STATIC_FUNCTION(f_flow_single_function) = boost::hof::flow(increment());
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(f_flow_single_function(3) == 4);
+ BOOST_HOF_STATIC_TEST_CHECK(f_flow_single_function(3) == 4);
+}
+
+BOOST_HOF_STATIC_FUNCTION(f_flow_function) = boost::hof::flow(increment(), decrement(), increment());
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(f_flow_function(3) == 4);
+ BOOST_HOF_STATIC_TEST_CHECK(f_flow_function(3) == 4);
+}
+
+BOOST_HOF_STATIC_FUNCTION(f_flow_function_4) = boost::hof::flow(increment(), negate(), decrement(), decrement());
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(f_flow_function_4(3) == -6);
+ BOOST_HOF_STATIC_TEST_CHECK(f_flow_function_4(3) == -6);
+}
+
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(f_flow_lambda) = boost::hof::flow(
+ [](int i) { return i+1; },
+ [](int i) { return i-1; },
+ [](int i) { return i+1; }
+);
+
+BOOST_HOF_TEST_CASE()
+{
+ int r = f_flow_lambda(3);
+ BOOST_HOF_TEST_CHECK(r == 4);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::flow(boost::hof::_1 + boost::hof::_1, boost::hof::_1 * boost::hof::_1)(3) == 36);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(boost::hof::_1 + boost::hof::_1, boost::hof::_1 * boost::hof::_1)(3) == 36);
+}
+}
diff --git a/src/boost/libs/hof/test/fold.cpp b/src/boost/libs/hof/test/fold.cpp
new file mode 100644
index 000000000..cf1cf9cba
--- /dev/null
+++ b/src/boost/libs/hof/test/fold.cpp
@@ -0,0 +1,93 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ fold.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/fold.hpp>
+#include "test.hpp"
+
+struct max_f
+{
+ template<class T, class U>
+ constexpr T operator()(T x, U y) const noexcept
+ {
+ return x > y ? x : y;
+ }
+};
+
+struct sum_f
+{
+ template<class T, class U>
+ constexpr T operator()(T x, U y) const BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(x+y)
+ {
+ return x + y;
+ }
+};
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::fold(max_f(), 0)(2, 3, 4, 5)), "noexcept fold");
+ static_assert(noexcept(boost::hof::fold(sum_f(), 0)(2, 3, 4, 5)), "noexcept fold");
+ static_assert(!noexcept(boost::hof::fold(sum_f(), std::string())("hello", "-", "world")), "noexcept fold");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f(), 0)(2, 3, 4, 5) == 5);
+ BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f(), 0)(5, 4, 3, 2) == 5);
+ BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f(), 0)(2, 3, 5, 4) == 5);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f(), 0)(2, 3, 4, 5) == 5);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f(), 0)(5, 4, 3, 2) == 5);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f(), 0)(2, 3, 5, 4) == 5);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f(), 0)() == 0);
+ BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f(), 0)(5) == 5);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f(), 0)() == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f(), 0)(5) == 5);
+}
+
+template<class... Ts>
+constexpr auto find_positive_max(Ts... xs) BOOST_HOF_RETURNS
+(
+ boost::hof::fold(max_f(), 0)(xs...)
+);
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(find_positive_max() == 0);
+ BOOST_HOF_TEST_CHECK(find_positive_max(5) == 5);
+
+ BOOST_HOF_STATIC_TEST_CHECK(find_positive_max() == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(find_positive_max(5) == 5);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f())(5) == 5);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f())(5) == 5);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f())(2, 3, 4, 5) == 5);
+ BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f())(5, 4, 3, 2) == 5);
+ BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f())(2, 3, 5, 4) == 5);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f())(2, 3, 4, 5) == 5);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f())(5, 4, 3, 2) == 5);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f())(2, 3, 5, 4) == 5);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::fold(sum_f(), std::string())("hello", "-", "world") == "hello-world");
+}
diff --git a/src/boost/libs/hof/test/function.cpp b/src/boost/libs/hof/test/function.cpp
new file mode 100644
index 000000000..fc4a4774f
--- /dev/null
+++ b/src/boost/libs/hof/test/function.cpp
@@ -0,0 +1,106 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ function.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/function.hpp>
+#include <boost/hof/partial.hpp>
+#include <boost/hof/infix.hpp>
+#include <memory>
+#include "test.hpp"
+
+namespace test_constexpr {
+
+struct sum_f
+{
+ template<class T, class U>
+ constexpr T operator()(T x, U y) const
+ {
+ return x+y;
+ }
+};
+
+BOOST_HOF_STATIC_FUNCTION(sum_init) = sum_f();
+
+BOOST_HOF_TEST_CASE()
+{
+// TODO: Should be empty on MSVC as well
+#ifndef _MSC_VER
+ STATIC_ASSERT_EMPTY(sum_init);
+#endif
+ BOOST_HOF_TEST_CHECK(3 == sum_init(1, 2));
+
+ BOOST_HOF_STATIC_TEST_CHECK(3 == sum_init(1, 2));
+}
+
+BOOST_HOF_STATIC_FUNCTION(sum_partial) = boost::hof::partial(sum_f());
+BOOST_HOF_TEST_CASE()
+{
+#ifndef _MSC_VER
+ STATIC_ASSERT_EMPTY(sum_partial);
+#endif
+ BOOST_HOF_TEST_CHECK(3 == sum_partial(1, 2));
+ BOOST_HOF_TEST_CHECK(3 == sum_partial(1)(2));
+
+ BOOST_HOF_STATIC_TEST_CHECK(3 == sum_partial(1, 2));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == sum_partial(1)(2));
+}
+
+}
+
+namespace test_static {
+
+struct sum_f
+{
+ template<class T, class U>
+ constexpr T operator()(T x, U y) const
+ {
+ return x+y;
+ }
+};
+
+struct add_one_f
+{
+ template<class T>
+ constexpr T operator()(T x) const
+ {
+ return x+1;
+ }
+};
+
+BOOST_HOF_STATIC_FUNCTION(sum_partial) = boost::hof::partial(sum_f());
+
+BOOST_HOF_TEST_CASE()
+{
+#ifndef _MSC_VER
+ STATIC_ASSERT_EMPTY(sum_partial);
+#endif
+ BOOST_HOF_TEST_CHECK(3 == sum_partial(1, 2));
+ BOOST_HOF_TEST_CHECK(3 == sum_partial(1)(2));
+}
+
+BOOST_HOF_STATIC_FUNCTION(add_one_pipable) = boost::hof::pipable(add_one_f());
+
+BOOST_HOF_TEST_CASE()
+{
+// TODO: Make this work on msvc
+#ifndef _MSC_VER
+ STATIC_ASSERT_EMPTY(add_one_pipable);
+#endif
+ BOOST_HOF_TEST_CHECK(3 == add_one_pipable(2));
+ BOOST_HOF_TEST_CHECK(3 == (2 | add_one_pipable));
+}
+
+BOOST_HOF_STATIC_FUNCTION(sum_infix) = boost::hof::infix(sum_f());
+
+BOOST_HOF_TEST_CASE()
+{
+// TODO: Make this work on msvc
+#ifndef _MSC_VER
+ STATIC_ASSERT_EMPTY(sum_infix);
+#endif
+ BOOST_HOF_TEST_CHECK(3 == (1 <sum_infix> 2));
+}
+
+}
diff --git a/src/boost/libs/hof/test/identity.cpp b/src/boost/libs/hof/test/identity.cpp
new file mode 100644
index 000000000..d19023f9d
--- /dev/null
+++ b/src/boost/libs/hof/test/identity.cpp
@@ -0,0 +1,68 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ identity.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/identity.hpp>
+#include <boost/hof/is_invocable.hpp>
+#include <boost/hof/detail/move.hpp>
+#include "test.hpp"
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::identity(10) == 10);
+ BOOST_HOF_TEST_CHECK(boost::hof::identity(10) == 10);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ int i = 3;
+ BOOST_HOF_TEST_CHECK(boost::hof::identity(i) == 3);
+ BOOST_HOF_TEST_CHECK(&boost::hof::identity(i) == &i);
+ static_assert(std::is_lvalue_reference<decltype(boost::hof::identity(i))>::value, "Not lvalue");
+ static_assert(!std::is_lvalue_reference<decltype(boost::hof::identity(3))>::value, "Not rvalue");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto ls = boost::hof::identity({1, 2, 3, 4});
+ std::vector<int> v{1, 2, 3, 4};
+ BOOST_HOF_TEST_CHECK(std::equal(ls.begin(), ls.end(), v.begin()));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(std::vector<int>(boost::hof::identity({1, 2, 3})) == std::vector<int>{1, 2, 3});
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(boost::hof::is_invocable<decltype(boost::hof::identity), int>::value, "Identiy callable");
+ static_assert(!boost::hof::is_invocable<decltype(boost::hof::identity), int, int>::value, "Identiy not callable");
+ static_assert(!boost::hof::is_invocable<decltype(boost::hof::identity)>::value, "Identiy not callable");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::identity({1, 2, 3})), "Noexcept identity");
+ static_assert(noexcept(boost::hof::identity(1)), "Noexcept identity");
+ int i = 5;
+ static_assert(noexcept(boost::hof::identity(i)), "Noexcept identity");
+}
+
+struct copy_throws
+{
+ copy_throws() {}
+ copy_throws(copy_throws const&) {}
+ copy_throws(copy_throws&&) noexcept {}
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ copy_throws ct{};
+ static_assert(noexcept(boost::hof::identity(ct)), "Noexcept identity");
+ static_assert(noexcept(boost::hof::identity(boost::hof::move(ct))), "Noexcept identity");
+ static_assert(!noexcept(boost::hof::identity(copy_throws{})), "Noexcept identity");
+}
+
diff --git a/src/boost/libs/hof/test/if.cpp b/src/boost/libs/hof/test/if.cpp
new file mode 100644
index 000000000..ee5a98fd1
--- /dev/null
+++ b/src/boost/libs/hof/test/if.cpp
@@ -0,0 +1,154 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ if.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/if.hpp>
+#include "test.hpp"
+
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/placeholders.hpp>
+
+
+struct is_5
+{
+ template<class T>
+ constexpr bool operator()(T i) const
+ {
+ return i == 5;
+ }
+};
+
+struct is_not_5
+{
+ template<class T>
+ constexpr bool operator()(T i) const
+ {
+ return i != 5;
+ }
+};
+
+template<class F>
+struct test_int
+{
+ template<class T>
+ constexpr bool operator()(T x) const
+ {
+ return boost::hof::first_of(
+ boost::hof::if_(std::is_integral<T>())(F()),
+ boost::hof::always(true)
+ )(x);
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(test_int<is_5>()(5));
+ BOOST_HOF_TEST_CHECK(test_int<is_5>()(5L));
+ BOOST_HOF_TEST_CHECK(test_int<is_5>()(5.0));
+ BOOST_HOF_TEST_CHECK(test_int<is_5>()(6.0));
+
+ BOOST_HOF_TEST_CHECK(test_int<is_not_5>()(6));
+ BOOST_HOF_TEST_CHECK(test_int<is_not_5>()(6L));
+ BOOST_HOF_TEST_CHECK(test_int<is_not_5>()(5.0));
+ BOOST_HOF_TEST_CHECK(test_int<is_not_5>()(6.0));
+
+ BOOST_HOF_STATIC_TEST_CHECK(test_int<is_5>()(5));
+ BOOST_HOF_STATIC_TEST_CHECK(test_int<is_5>()(5L));
+ BOOST_HOF_STATIC_TEST_CHECK(test_int<is_5>()(5.0));
+ BOOST_HOF_STATIC_TEST_CHECK(test_int<is_5>()(6.0));
+
+ BOOST_HOF_STATIC_TEST_CHECK(test_int<is_not_5>()(6));
+ BOOST_HOF_STATIC_TEST_CHECK(test_int<is_not_5>()(6L));
+ BOOST_HOF_STATIC_TEST_CHECK(test_int<is_not_5>()(5.0));
+ BOOST_HOF_STATIC_TEST_CHECK(test_int<is_not_5>()(6.0));
+}
+
+template<class F>
+struct test_int_c
+{
+ template<class T>
+ constexpr bool operator()(T x) const
+ {
+ return boost::hof::first_of(
+ boost::hof::if_c<std::is_integral<T>::value>(F()),
+ boost::hof::always(true)
+ )(x);
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(test_int_c<is_5>()(5));
+ BOOST_HOF_TEST_CHECK(test_int_c<is_5>()(5L));
+ BOOST_HOF_TEST_CHECK(test_int_c<is_5>()(5.0));
+ BOOST_HOF_TEST_CHECK(test_int_c<is_5>()(6.0));
+
+ BOOST_HOF_TEST_CHECK(test_int_c<is_not_5>()(6));
+ BOOST_HOF_TEST_CHECK(test_int_c<is_not_5>()(6L));
+ BOOST_HOF_TEST_CHECK(test_int_c<is_not_5>()(5.0));
+ BOOST_HOF_TEST_CHECK(test_int_c<is_not_5>()(6.0));
+
+ BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_5>()(5));
+ BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_5>()(5L));
+ BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_5>()(5.0));
+ BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_5>()(6.0));
+
+ BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_not_5>()(6));
+ BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_not_5>()(6L));
+ BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_not_5>()(5.0));
+ BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_not_5>()(6.0));
+}
+
+struct sum_f
+{
+ template<class T>
+ constexpr int operator()(T x, T y) const
+ {
+ return boost::hof::first_of(
+ boost::hof::if_(std::is_integral<T>())(boost::hof::_ + boost::hof::_),
+ boost::hof::always(0)
+ )(x, y);
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(sum_f()(1, 2) == 3);
+ BOOST_HOF_TEST_CHECK(sum_f()(1.0, 2.0) == 0);
+ BOOST_HOF_TEST_CHECK(sum_f()("", "") == 0);
+
+ BOOST_HOF_STATIC_TEST_CHECK(sum_f()(1, 2) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(sum_f()("", "") == 0);
+}
+
+
+struct sum_f_c
+{
+ template<class T>
+ constexpr int operator()(T x, T y) const
+ {
+ return boost::hof::first_of(
+ boost::hof::if_c<std::is_integral<T>::value>(boost::hof::_ + boost::hof::_),
+ boost::hof::always(0)
+ )(x, y);
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(sum_f_c()(1, 2) == 3);
+ BOOST_HOF_TEST_CHECK(sum_f_c()(1.0, 2.0) == 0);
+ BOOST_HOF_TEST_CHECK(sum_f_c()("", "") == 0);
+
+ BOOST_HOF_STATIC_TEST_CHECK(sum_f_c()(1, 2) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(sum_f_c()("", "") == 0);
+}
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::if_(std::is_integral<int>())(boost::hof::identity)(1)), "noexcept if");
+}
+#endif
diff --git a/src/boost/libs/hof/test/implicit.cpp b/src/boost/libs/hof/test/implicit.cpp
new file mode 100644
index 000000000..2f6624f4d
--- /dev/null
+++ b/src/boost/libs/hof/test/implicit.cpp
@@ -0,0 +1,56 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ implicit.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/implicit.hpp>
+#include "test.hpp"
+
+template<class T>
+struct auto_caster
+{
+ template<class U>
+ T operator()(U x)
+ {
+ return T(x);
+ }
+};
+
+template<class T>
+struct auto_caster_noexcept
+{
+ template<class U>
+ T operator()(U x) noexcept
+ {
+ return T(x);
+ }
+};
+
+struct auto_caster_foo
+{
+ int i;
+ explicit auto_caster_foo(int ip) : i(ip) {}
+
+};
+// TODO: Test template constraint on conversion operator
+static constexpr boost::hof::implicit<auto_caster> auto_cast = {};
+
+BOOST_HOF_TEST_CASE()
+{
+ float f = 1.5;
+ int i = auto_cast(f);
+ // auto_caster_foo x = 1;
+ auto_caster_foo x = auto_cast(1);
+ BOOST_HOF_TEST_CHECK(1 == i);
+ BOOST_HOF_TEST_CHECK(1 == x.i);
+
+}
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ boost::hof::implicit<auto_caster_noexcept> lauto_cast{};
+ float f = 1.5;
+ static_assert(noexcept(int(lauto_cast(f))), "noexcept implicit");
+}
+#endif
diff --git a/src/boost/libs/hof/test/indirect.cpp b/src/boost/libs/hof/test/indirect.cpp
new file mode 100644
index 000000000..b1e3e548f
--- /dev/null
+++ b/src/boost/libs/hof/test/indirect.cpp
@@ -0,0 +1,52 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ indirect.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/indirect.hpp>
+#include "test.hpp"
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::indirect(std::unique_ptr<binary_class>(new binary_class()))(1, 2));
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::reveal(boost::hof::indirect(std::unique_ptr<binary_class>(new binary_class())))(1, 2));
+
+ binary_class f;
+
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::indirect(&f)(1, 2));
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::reveal(boost::hof::indirect(&f))(1, 2));
+}
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ binary_class f;
+ static_assert(noexcept(boost::hof::indirect(&f)(1, 2)), "noexcept indirect");
+}
+#endif
+
+struct mutable_function
+{
+ mutable_function() : value(0) {}
+ void operator()(int a) { value += a; }
+ int value;
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ auto mf = mutable_function{};
+ boost::hof::indirect(&mf)(15);
+ boost::hof::indirect(&mf)(2);
+ BOOST_HOF_TEST_CHECK(mf.value == 17);
+}
+
+
+BOOST_HOF_TEST_CASE()
+{
+ auto mf = std::make_shared<mutable_function>();
+ boost::hof::indirect(mf)(15);
+ boost::hof::indirect(mf)(2);
+ BOOST_HOF_TEST_CHECK(mf->value == 17);
+}
+
+
diff --git a/src/boost/libs/hof/test/infix.cpp b/src/boost/libs/hof/test/infix.cpp
new file mode 100644
index 000000000..6b79489f4
--- /dev/null
+++ b/src/boost/libs/hof/test/infix.cpp
@@ -0,0 +1,115 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ infix.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/infix.hpp>
+#include <boost/hof/function.hpp>
+#include <boost/hof/lambda.hpp>
+#include <boost/hof/pipable.hpp>
+#include <boost/hof/placeholders.hpp>
+#include "test.hpp"
+
+struct sum_f
+{
+ template<class T, class U>
+ constexpr T operator()(T x, U y) const BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(x+y)
+ {
+ return x+y;
+ }
+};
+
+static constexpr boost::hof::infix_adaptor<sum_f> sum = {};
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(1 <sum> 2), "noexcept infix");
+ static_assert(!noexcept(std::string() <sum> std::string()), "noexcept infix");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == (1 <sum> 2));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == (1 <sum> 2));
+
+ BOOST_HOF_TEST_CHECK(3 == (sum(1, 2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == (sum(1, 2)));
+}
+
+BOOST_HOF_STATIC_FUNCTION(sum1) = boost::hof::infix(sum_f());
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == (1 <sum1> 2));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == (1 <sum1> 2));
+
+ BOOST_HOF_TEST_CHECK(3 == (sum1(1, 2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == (sum1(1, 2)));
+}
+
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(sum2) = boost::hof::infix([](int x, int y) { return x + y; });
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == (1 <sum2> 2));
+
+ BOOST_HOF_TEST_CHECK(3 == (sum2(1, 2)));
+}
+
+BOOST_HOF_STATIC_FUNCTION(sum3) = boost::hof::infix(boost::hof::_ + boost::hof::_);
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == (1 <sum3> 2));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == (1 <sum3> 2));
+
+ BOOST_HOF_TEST_CHECK(3 == (sum3(1, 2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == (sum3(1, 2)));
+}
+
+
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(sum4) = boost::hof::infix(boost::hof::infix([](int x, int y) { return x + y; }));
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == (1 <sum4> 2));
+
+ BOOST_HOF_TEST_CHECK(3 == (sum4(1, 2)));
+}
+
+BOOST_HOF_STATIC_FUNCTION(sum5) = boost::hof::infix(boost::hof::infix(boost::hof::_ + boost::hof::_));
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == (1 <sum5> 2));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == (1 <sum5> 2));
+
+ BOOST_HOF_TEST_CHECK(3 == (sum5(1, 2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == (sum5(1, 2)));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+#if (defined(__GNUC__) && !defined (__clang__))
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wparentheses"
+#endif
+ BOOST_HOF_TEST_CHECK(6 == (1 + 2 <sum> 3));
+ BOOST_HOF_TEST_CHECK(3 == 1 <sum> 2);
+#if (defined(__GNUC__) && !defined (__clang__))
+#pragma GCC diagnostic pop
+#endif
+}
+
+struct foo {};
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::infix([](int, int) { return foo{}; });
+ auto g = boost::hof::infix([](foo, foo) { return std::string("hello"); });
+ BOOST_HOF_TEST_CHECK((1 <f> 2 <g> foo{}) == "hello");
+
+}
diff --git a/src/boost/libs/hof/test/is_invocable.cpp b/src/boost/libs/hof/test/is_invocable.cpp
new file mode 100644
index 000000000..e65d49c15
--- /dev/null
+++ b/src/boost/libs/hof/test/is_invocable.cpp
@@ -0,0 +1,192 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ is_invocable.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/is_invocable.hpp>
+#include <ciso646>
+#include "test.hpp"
+
+template<int N>
+struct callable_rank : callable_rank<N-1>
+{};
+
+template<>
+struct callable_rank<0>
+{};
+
+BOOST_HOF_STATIC_TEST_CASE()
+{
+ struct is_callable_class
+ {
+ void operator()(int) const
+ {
+ }
+ };
+ struct callable_test_param {};
+
+ void is_callable_function(int)
+ {
+ }
+
+ struct is_callable_rank_class
+ {
+ void operator()(int, callable_rank<3>) const
+ {
+ }
+
+ void operator()(int, callable_rank<4>) const
+ {
+ }
+ };
+
+ static_assert(boost::hof::is_invocable<is_callable_class, int>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_class, long>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_class, double>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_class, const int&>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_class, const long&>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_class, const double&>::value, "Not callable");
+ static_assert(not boost::hof::is_invocable<is_callable_class, callable_test_param>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_class>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_class, int, int>::value, "callable failed");
+
+ typedef void (*is_callable_function_pointer)(int);
+ static_assert(boost::hof::is_invocable<is_callable_function_pointer, int>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_function_pointer, long>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_function_pointer, double>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_function_pointer, const int&>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_function_pointer, const long&>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_function_pointer, const double&>::value, "Not callable");
+ static_assert(not boost::hof::is_invocable<is_callable_function_pointer, callable_test_param>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_function_pointer>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_function_pointer, int, int>::value, "callable failed");
+
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, int, callable_rank<3>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, long, callable_rank<3>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, double, callable_rank<3>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, const int&, callable_rank<3>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, const long&, callable_rank<3>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, const double&, callable_rank<3>>::value, "Not callable");
+
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, int, callable_rank<4>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, long, callable_rank<4>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, double, callable_rank<4>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, const int&, callable_rank<4>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, const long&, callable_rank<4>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, const double&, callable_rank<4>>::value, "Not callable");
+
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, int, callable_rank<5>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, long, callable_rank<5>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, double, callable_rank<5>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, const int&, callable_rank<5>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, const long&, callable_rank<5>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, const double&, callable_rank<5>>::value, "Not callable");
+
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, int, callable_rank<6>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, long, callable_rank<6>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, double, callable_rank<6>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, const int&, callable_rank<6>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, const long&, callable_rank<6>>::value, "Not callable");
+ static_assert(boost::hof::is_invocable<is_callable_rank_class, const double&, callable_rank<6>>::value, "Not callable");
+
+ static_assert(not boost::hof::is_invocable<is_callable_rank_class, int, callable_rank<1>>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_rank_class, long, callable_rank<1>>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_rank_class, double, callable_rank<1>>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_rank_class, const int&, callable_rank<1>>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_rank_class, const long&, callable_rank<1>>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_rank_class, const double&, callable_rank<1>>::value, "callable failed");
+
+ static_assert(not boost::hof::is_invocable<is_callable_rank_class, callable_test_param, callable_test_param>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_rank_class, callable_rank<3>, callable_test_param>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_rank_class, callable_rank<4>, callable_test_param>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_rank_class, callable_test_param, callable_rank<3>>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_rank_class, callable_test_param, callable_rank<4>>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_rank_class>::value, "callable failed");
+ static_assert(not boost::hof::is_invocable<is_callable_rank_class, int, int>::value, "callable failed");
+};
+
+BOOST_HOF_STATIC_TEST_CASE()
+{
+ typedef int(callable_rank<0>::*fn)(int);
+
+ static_assert(boost::hof::is_invocable<fn, callable_rank<0>&, int>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fn, callable_rank<1>&, int>::value, "Failed");
+ static_assert(!boost::hof::is_invocable<fn, callable_rank<0>&>::value, "Failed");
+ static_assert(!boost::hof::is_invocable<fn, callable_rank<0> const&, int>::value, "Failed");
+};
+
+BOOST_HOF_STATIC_TEST_CASE()
+{
+ typedef int(callable_rank<0>::*fn)(int);
+
+ typedef callable_rank<0>* T;
+ typedef callable_rank<1>* DT;
+ typedef const callable_rank<0>* CT;
+ typedef std::unique_ptr<callable_rank<0>> ST;
+
+ static_assert(boost::hof::is_invocable<fn, T&, int>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fn, DT&, int>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fn, const T&, int>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fn, T&&, int>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fn, ST, int>::value, "Failed");
+ static_assert(!boost::hof::is_invocable<fn, CT&, int>::value, "Failed");
+
+};
+
+BOOST_HOF_STATIC_TEST_CASE()
+{
+ typedef int(callable_rank<0>::*fn);
+
+ static_assert(!boost::hof::is_invocable<fn>::value, "Failed");
+};
+
+BOOST_HOF_STATIC_TEST_CASE()
+{
+ typedef int(callable_rank<0>::*fn);
+
+ static_assert(boost::hof::is_invocable<fn, callable_rank<0>&>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fn, callable_rank<0>&&>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fn, const callable_rank<0>&>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fn, callable_rank<1>&>::value, "Failed");
+};
+
+BOOST_HOF_STATIC_TEST_CASE()
+{
+ typedef int(callable_rank<0>::*fn);
+
+ typedef callable_rank<0>* T;
+ typedef callable_rank<1>* DT;
+ typedef const callable_rank<0>* CT;
+ typedef std::unique_ptr<callable_rank<0>> ST;
+
+ static_assert(boost::hof::is_invocable<fn, T&>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fn, DT&>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fn, const T&>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fn, T&&>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fn, ST>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fn, CT&>::value, "Failed");
+
+};
+
+BOOST_HOF_STATIC_TEST_CASE()
+{
+ typedef void(*fp)(callable_rank<0>&, int);
+
+ static_assert(boost::hof::is_invocable<fp, callable_rank<0>&, int>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fp, callable_rank<1>&, int>::value, "Failed");
+ static_assert(!boost::hof::is_invocable<fp, const callable_rank<0>&, int>::value, "Failed");
+ static_assert(!boost::hof::is_invocable<fp>::value, "Failed");
+ static_assert(!boost::hof::is_invocable<fp, callable_rank<0>&>::value, "Failed");
+};
+
+BOOST_HOF_STATIC_TEST_CASE()
+{
+ typedef void(&fp)(callable_rank<0>&, int);
+
+ static_assert(boost::hof::is_invocable<fp, callable_rank<0>&, int>::value, "Failed");
+ static_assert(boost::hof::is_invocable<fp, callable_rank<1>&, int>::value, "Failed");
+ static_assert(!boost::hof::is_invocable<fp, const callable_rank<0>&, int>::value, "Failed");
+ static_assert(!boost::hof::is_invocable<fp>::value, "Failed");
+ static_assert(!boost::hof::is_invocable<fp, callable_rank<0>&>::value, "Failed");
+};
diff --git a/src/boost/libs/hof/test/issue8.cpp b/src/boost/libs/hof/test/issue8.cpp
new file mode 100644
index 000000000..08acb9a70
--- /dev/null
+++ b/src/boost/libs/hof/test/issue8.cpp
@@ -0,0 +1,48 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ issue8.cpp
+ 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)
+==============================================================================*/
+
+#include "test.hpp"
+#include <vector>
+#include <boost/hof/pipable.hpp>
+#include <boost/hof/placeholders.hpp>
+#include <algorithm>
+
+
+struct filter_fn
+{
+ template<class Input, class P>
+ Input operator()(Input input, P pred) const
+ {
+ Input output(input.size());
+ output.erase(
+ ::std::copy_if(
+ ::std::begin(input),
+ ::std::end(input),
+ ::std::begin(output),
+ pred
+ ),
+ ::std::end(output)
+ );
+ return output;
+ }
+};
+
+static constexpr boost::hof::pipable_adaptor<filter_fn> filter = {};
+
+BOOST_HOF_TEST_CASE()
+{
+ std::vector<int> data;
+ for(int i=0;i<6;i++)
+ {
+ data.push_back(i);
+ }
+ std::vector<int> r1 = data | filter(boost::hof::_1 > 1);
+ BOOST_HOF_TEST_CHECK(r1.size() == 4);
+
+ std::vector<int> r2 = filter(data, boost::hof::_1 > 1);
+ BOOST_HOF_TEST_CHECK(r2.size() == 4);
+}
diff --git a/src/boost/libs/hof/test/lambda.cpp b/src/boost/libs/hof/test/lambda.cpp
new file mode 100644
index 000000000..42e79959f
--- /dev/null
+++ b/src/boost/libs/hof/test/lambda.cpp
@@ -0,0 +1,103 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ lambda.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/lambda.hpp>
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/partial.hpp>
+#include <boost/hof/infix.hpp>
+#include <boost/hof/pipable.hpp>
+#include <memory>
+#include "test.hpp"
+
+
+static constexpr auto add_one = BOOST_HOF_STATIC_LAMBDA(int x)
+{
+ return x + 1;
+};
+
+template<class F>
+struct wrapper : F
+{
+ BOOST_HOF_INHERIT_CONSTRUCTOR(wrapper, F)
+};
+
+template<class T>
+constexpr wrapper<T> wrap(T x)
+{
+ return x;
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == add_one(2));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ constexpr auto add_one_again = add_one;
+ BOOST_HOF_TEST_CHECK(3 == add_one_again(2));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ constexpr auto add_one_again = wrap(add_one);
+ BOOST_HOF_TEST_CHECK(3 == add_one_again(2));
+}
+
+namespace test_static {
+
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(add_one) = [](int x)
+{
+ return x + 1;
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(add_one(2) == 3);
+}
+
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(sum_partial) = boost::hof::partial([](int x, int y)
+{
+ return x + y;
+});
+
+BOOST_HOF_TEST_CASE()
+{
+#ifndef _MSC_VER
+ STATIC_ASSERT_EMPTY(sum_partial);
+#endif
+ BOOST_HOF_TEST_CHECK(3 == sum_partial(1, 2));
+ BOOST_HOF_TEST_CHECK(3 == sum_partial(1)(2));
+}
+
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(add_one_pipable) = boost::hof::pipable([](int x)
+{
+ return x + 1;
+});
+
+BOOST_HOF_TEST_CASE()
+{
+#ifndef _MSC_VER
+ STATIC_ASSERT_EMPTY(add_one_pipable);
+#endif
+ BOOST_HOF_TEST_CHECK(3 == add_one_pipable(2));
+ BOOST_HOF_TEST_CHECK(3 == (2 | add_one_pipable));
+}
+
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(sum_infix) = boost::hof::infix([](int x, int y)
+{
+ return x + y;
+});
+
+BOOST_HOF_TEST_CASE()
+{
+#ifndef _MSC_VER
+ STATIC_ASSERT_EMPTY(sum_infix);
+#endif
+ BOOST_HOF_TEST_CHECK(3 == (1 <sum_infix> 2));
+}
+
+}
diff --git a/src/boost/libs/hof/test/lazy.cpp b/src/boost/libs/hof/test/lazy.cpp
new file mode 100644
index 000000000..bea58fe69
--- /dev/null
+++ b/src/boost/libs/hof/test/lazy.cpp
@@ -0,0 +1,713 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ lazy.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/lazy.hpp>
+#include <memory>
+#include "test.hpp"
+
+template<int N>
+struct test_placeholder
+{};
+
+namespace std {
+ template<int N>
+ struct is_placeholder<test_placeholder<N>>
+ : std::integral_constant<int, N>
+ {};
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ int i = 5;
+
+ static_assert(std::is_reference<decltype(boost::hof::detail::ref_transformer()(std::ref(i))(0,0,0))>::value, "Reference wrapper failed");
+ static_assert(std::is_reference<decltype(boost::hof::detail::pick_transformer(std::ref(i))(0,0,0))>::value, "Reference wrapper failed");
+ static_assert(std::is_reference<decltype(boost::hof::detail::lazy_transform(std::ref(i), boost::hof::pack_basic(0,0,0)))>::value, "Reference wrapper failed");
+
+ BOOST_HOF_TEST_CHECK(&boost::hof::detail::ref_transformer()(std::ref(i))(0,0,0) == &i);
+ BOOST_HOF_TEST_CHECK(&boost::hof::detail::pick_transformer(std::ref(i))(0,0,0) == &i);
+ BOOST_HOF_TEST_CHECK(&boost::hof::detail::lazy_transform(std::ref(i), boost::hof::pack_basic(0,0,0)) == &i);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ int i = 5;
+
+ BOOST_HOF_TEST_CHECK(boost::hof::detail::id_transformer()(i)(0,0,0) == i);
+ BOOST_HOF_TEST_CHECK(boost::hof::detail::pick_transformer(i)(0,0,0) == i);
+ BOOST_HOF_TEST_CHECK(boost::hof::detail::lazy_transform(i, boost::hof::pack_basic(0,0,0)) == i);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto id =[](int i){ return i;};
+ auto fi = std::bind(id, 5);
+
+ BOOST_HOF_TEST_CHECK(boost::hof::detail::bind_transformer()(fi)(0,0,0) == id(5));
+ BOOST_HOF_TEST_CHECK(boost::hof::detail::pick_transformer(fi)(0,0,0) == id(5));
+ BOOST_HOF_TEST_CHECK(boost::hof::detail::lazy_transform(fi, boost::hof::pack_basic(0,0,0)) == id(5));
+}
+
+struct f_0 {
+constexpr long operator()() const
+{
+ return 17041L;
+}
+};
+
+struct f_1 {
+constexpr long operator()(long a) const
+{
+ return a;
+}
+};
+
+struct f_2 {
+constexpr long operator()(long a, long b) const
+{
+ return a + 10 * b;
+}
+};
+
+static long global_result;
+
+struct fv_0 {
+void operator()() const
+{
+ global_result = 17041L;
+}
+};
+
+struct fv_1 {
+void operator()(long a) const
+{
+ global_result = a;
+}
+};
+
+struct fv_2 {
+void operator()(long a, long b) const
+{
+ global_result = a + 10 * b;
+}
+};
+
+struct Y
+{
+ short operator()(short & r) const { return ++r; }
+ int operator()(int a, int b) const { return a + 10 * b; }
+ long operator() (long a, long b, long c) const { return a + 10 * b + 100 * c; }
+ void operator() (long a, long b, long c, long d) const { global_result = a + 10 * b + 100 * c + 1000 * d; }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ short i(6);
+
+ int const k = 3;
+
+ BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( std::ref(i))() == 7 );
+ BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( std::ref(i))() == 8 );
+ BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( i,std::placeholders::_1)(k) == 38 );
+ BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( i,std::placeholders::_1, 9)(k) == 938 );
+
+ global_result = 0;
+ boost::hof::lazy(Y())( i,std::placeholders::_1, 9, 4)(k);
+ BOOST_HOF_TEST_CHECK( global_result == 4938 );
+
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ int const x = 1;
+ int const y = 2;
+
+ BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_1())(std::placeholders::_1))(x) == 1L );
+ BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_2())(std::placeholders::_1, std::placeholders::_2))(x, y) == 21L );
+ BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_2())( boost::hof::lazy(f_1())(std::placeholders::_1), boost::hof::lazy(f_1())(std::placeholders::_1))(x) == 11L );
+ BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_2())( boost::hof::lazy(f_1())(std::placeholders::_1), boost::hof::lazy(f_1())( std::placeholders::_2))(x, y) == 21L );
+ BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_0())())() == 17041L );
+
+ BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_1())(test_placeholder<1>()))(x) == 1L );
+ BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_2())(test_placeholder<1>(), test_placeholder<2>()))(x, y) == 21L );
+ BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_2())( boost::hof::lazy(f_1())(test_placeholder<1>()), boost::hof::lazy(f_1())(test_placeholder<1>()))(x) == 11L );
+ BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_2())( boost::hof::lazy(f_1())(test_placeholder<1>()), boost::hof::lazy(f_1())( test_placeholder<2>()))(x, y) == 21L );
+ BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_0())())() == 17041L );
+
+ BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_1())( boost::hof::lazy(f_1())(std::placeholders::_1))(x), (global_result == 1L)) );
+ BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_1())( boost::hof::lazy(f_2())(std::placeholders::_1, std::placeholders::_2))(x, y), (global_result == 21L)) );
+ BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_2())( boost::hof::lazy(f_1())(std::placeholders::_1), boost::hof::lazy(f_1())(std::placeholders::_1))(x), (global_result == 11L)) );
+ BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_2())( boost::hof::lazy(f_1())(std::placeholders::_1), boost::hof::lazy(f_1())( std::placeholders::_2))(x, y), (global_result == 21L)) );
+ BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_1())( boost::hof::lazy(f_0())())(), (global_result == 17041L)) );
+}
+
+
+struct X
+{
+ mutable unsigned int hash;
+
+ X(): hash(0) {}
+
+ int f0() { f1(17); return 0; }
+ int g0() const { g1(17); return 0; }
+
+ int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
+ int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
+
+ int f2(int a1, int a2) { f1(a1); f1(a2); return 0; }
+ int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; }
+
+ int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; }
+ int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; }
+
+ int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; }
+ int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; }
+
+ int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; }
+ int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; }
+
+ int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; }
+ int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); return 0; }
+
+ int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); return 0; }
+ int g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); return 0; }
+
+ int f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); return 0; }
+ int g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); return 0; }
+};
+
+struct V
+{
+ mutable unsigned int hash;
+
+ V(): hash(0) {}
+
+ void f0() { f1(17); }
+ void g0() const { g1(17); }
+
+ void f1(int a1) { hash = (hash * 17041 + a1) % 32768; }
+ void g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; }
+
+ void f2(int a1, int a2) { f1(a1); f1(a2); }
+ void g2(int a1, int a2) const { g1(a1); g1(a2); }
+
+ void f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); }
+ void g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); }
+
+ void f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); }
+ void g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); }
+
+ void f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); }
+ void g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); }
+
+ void f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); }
+ void g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); }
+
+ void f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); }
+ void g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); }
+
+ void f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); }
+ void g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+
+ X x;
+
+ // 0
+
+ boost::hof::lazy(&X::f0)(&x)();
+ boost::hof::lazy(&X::f0)(std::ref(x))();
+
+ boost::hof::lazy(&X::g0)(&x)();
+ boost::hof::lazy(&X::g0)(x)();
+ boost::hof::lazy(&X::g0)(std::ref(x))();
+
+ // 1
+
+ boost::hof::lazy(&X::f1)(&x, 1)();
+ boost::hof::lazy(&X::f1)(std::ref(x), 1)();
+
+ boost::hof::lazy(&X::g1)(&x, 1)();
+ boost::hof::lazy(&X::g1)(x, 1)();
+ boost::hof::lazy(&X::g1)(std::ref(x), 1)();
+
+ // 2
+
+ boost::hof::lazy(&X::f2)(&x, 1, 2)();
+ boost::hof::lazy(&X::f2)(std::ref(x), 1, 2)();
+
+ boost::hof::lazy(&X::g2)(&x, 1, 2)();
+ boost::hof::lazy(&X::g2)(x, 1, 2)();
+ boost::hof::lazy(&X::g2)(std::ref(x), 1, 2)();
+
+ // 3
+
+ boost::hof::lazy(&X::f3)(&x, 1, 2, 3)();
+ boost::hof::lazy(&X::f3)(std::ref(x), 1, 2, 3)();
+
+ boost::hof::lazy(&X::g3)(&x, 1, 2, 3)();
+ boost::hof::lazy(&X::g3)(x, 1, 2, 3)();
+ boost::hof::lazy(&X::g3)(std::ref(x), 1, 2, 3)();
+
+ // 4
+
+ boost::hof::lazy(&X::f4)(&x, 1, 2, 3, 4)();
+ boost::hof::lazy(&X::f4)(std::ref(x), 1, 2, 3, 4)();
+
+ boost::hof::lazy(&X::g4)(&x, 1, 2, 3, 4)();
+ boost::hof::lazy(&X::g4)(x, 1, 2, 3, 4)();
+ boost::hof::lazy(&X::g4)(std::ref(x), 1, 2, 3, 4)();
+
+ // 5
+
+ boost::hof::lazy(&X::f5)(&x, 1, 2, 3, 4, 5)();
+ boost::hof::lazy(&X::f5)(std::ref(x), 1, 2, 3, 4, 5)();
+
+ boost::hof::lazy(&X::g5)(&x, 1, 2, 3, 4, 5)();
+ boost::hof::lazy(&X::g5)(x, 1, 2, 3, 4, 5)();
+ boost::hof::lazy(&X::g5)(std::ref(x), 1, 2, 3, 4, 5)();
+
+ // 6
+
+ boost::hof::lazy(&X::f6)(&x, 1, 2, 3, 4, 5, 6)();
+ boost::hof::lazy(&X::f6)(std::ref(x), 1, 2, 3, 4, 5, 6)();
+
+ boost::hof::lazy(&X::g6)(&x, 1, 2, 3, 4, 5, 6)();
+ boost::hof::lazy(&X::g6)(x, 1, 2, 3, 4, 5, 6)();
+ boost::hof::lazy(&X::g6)(std::ref(x), 1, 2, 3, 4, 5, 6)();
+
+ // 7
+
+ boost::hof::lazy(&X::f7)(&x, 1, 2, 3, 4, 5, 6, 7)();
+ boost::hof::lazy(&X::f7)(std::ref(x), 1, 2, 3, 4, 5, 6, 7)();
+
+ boost::hof::lazy(&X::g7)(&x, 1, 2, 3, 4, 5, 6, 7)();
+ boost::hof::lazy(&X::g7)(x, 1, 2, 3, 4, 5, 6, 7)();
+ boost::hof::lazy(&X::g7)(std::ref(x), 1, 2, 3, 4, 5, 6, 7)();
+
+ // 8
+
+ boost::hof::lazy(&X::f8)(&x, 1, 2, 3, 4, 5, 6, 7, 8)();
+ boost::hof::lazy(&X::f8)(std::ref(x), 1, 2, 3, 4, 5, 6, 7, 8)();
+
+ boost::hof::lazy(&X::g8)(&x, 1, 2, 3, 4, 5, 6, 7, 8)();
+ boost::hof::lazy(&X::g8)(x, 1, 2, 3, 4, 5, 6, 7, 8)();
+ boost::hof::lazy(&X::g8)(std::ref(x), 1, 2, 3, 4, 5, 6, 7, 8)();
+
+ BOOST_HOF_TEST_CHECK( x.hash == 23558 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ V v;
+
+ // 0
+
+ boost::hof::lazy(&V::f0)(&v)();
+ boost::hof::lazy(&V::f0)(std::ref(v))();
+
+ boost::hof::lazy(&V::g0)(&v)();
+ boost::hof::lazy(&V::g0)(v)();
+ boost::hof::lazy(&V::g0)(std::ref(v))();
+
+ // 1
+
+ boost::hof::lazy(&V::f1)(&v, 1)();
+ boost::hof::lazy(&V::f1)(std::ref(v), 1)();
+
+ boost::hof::lazy(&V::g1)(&v, 1)();
+ boost::hof::lazy(&V::g1)(v, 1)();
+ boost::hof::lazy(&V::g1)(std::ref(v), 1)();
+
+ // 2
+
+ boost::hof::lazy(&V::f2)(&v, 1, 2)();
+ boost::hof::lazy(&V::f2)(std::ref(v), 1, 2)();
+
+ boost::hof::lazy(&V::g2)(&v, 1, 2)();
+ boost::hof::lazy(&V::g2)(v, 1, 2)();
+ boost::hof::lazy(&V::g2)(std::ref(v), 1, 2)();
+
+ // 3
+
+ boost::hof::lazy(&V::f3)(&v, 1, 2, 3)();
+ boost::hof::lazy(&V::f3)(std::ref(v), 1, 2, 3)();
+
+ boost::hof::lazy(&V::g3)(&v, 1, 2, 3)();
+ boost::hof::lazy(&V::g3)(v, 1, 2, 3)();
+ boost::hof::lazy(&V::g3)(std::ref(v), 1, 2, 3)();
+
+ // 4
+
+ boost::hof::lazy(&V::f4)(&v, 1, 2, 3, 4)();
+ boost::hof::lazy(&V::f4)(std::ref(v), 1, 2, 3, 4)();
+
+ boost::hof::lazy(&V::g4)(&v, 1, 2, 3, 4)();
+ boost::hof::lazy(&V::g4)(v, 1, 2, 3, 4)();
+ boost::hof::lazy(&V::g4)(std::ref(v), 1, 2, 3, 4)();
+
+ // 5
+
+ boost::hof::lazy(&V::f5)(&v, 1, 2, 3, 4, 5)();
+ boost::hof::lazy(&V::f5)(std::ref(v), 1, 2, 3, 4, 5)();
+
+ boost::hof::lazy(&V::g5)(&v, 1, 2, 3, 4, 5)();
+ boost::hof::lazy(&V::g5)(v, 1, 2, 3, 4, 5)();
+ boost::hof::lazy(&V::g5)(std::ref(v), 1, 2, 3, 4, 5)();
+
+ // 6
+
+ boost::hof::lazy(&V::f6)(&v, 1, 2, 3, 4, 5, 6)();
+ boost::hof::lazy(&V::f6)(std::ref(v), 1, 2, 3, 4, 5, 6)();
+
+ boost::hof::lazy(&V::g6)(&v, 1, 2, 3, 4, 5, 6)();
+ boost::hof::lazy(&V::g6)(v, 1, 2, 3, 4, 5, 6)();
+ boost::hof::lazy(&V::g6)(std::ref(v), 1, 2, 3, 4, 5, 6)();
+
+ // 7
+
+ boost::hof::lazy(&V::f7)(&v, 1, 2, 3, 4, 5, 6, 7)();
+ boost::hof::lazy(&V::f7)(std::ref(v), 1, 2, 3, 4, 5, 6, 7)();
+
+ boost::hof::lazy(&V::g7)(&v, 1, 2, 3, 4, 5, 6, 7)();
+ boost::hof::lazy(&V::g7)(v, 1, 2, 3, 4, 5, 6, 7)();
+ boost::hof::lazy(&V::g7)(std::ref(v), 1, 2, 3, 4, 5, 6, 7)();
+
+ // 8
+
+ boost::hof::lazy(&V::f8)(&v, 1, 2, 3, 4, 5, 6, 7, 8)();
+ boost::hof::lazy(&V::f8)(std::ref(v), 1, 2, 3, 4, 5, 6, 7, 8)();
+
+ boost::hof::lazy(&V::g8)(&v, 1, 2, 3, 4, 5, 6, 7, 8)();
+ boost::hof::lazy(&V::g8)(v, 1, 2, 3, 4, 5, 6, 7, 8)();
+ boost::hof::lazy(&V::g8)(std::ref(v), 1, 2, 3, 4, 5, 6, 7, 8)();
+
+ BOOST_HOF_TEST_CHECK( v.hash == 23558 );
+}
+
+struct id
+{
+ int operator()(int i) const
+ {
+ return i;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::lazy(id())(3)() == 3);
+}
+
+struct deref
+{
+ int operator()(const std::unique_ptr<int>& i) const
+ {
+ return *i;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::lazy(deref())(std::unique_ptr<int>(new int(3)))() == 3);
+}
+
+void fv1( std::unique_ptr<int> p1 )
+{
+ BOOST_HOF_TEST_CHECK( *p1 == 1 );
+}
+
+void fv2( std::unique_ptr<int> p1, std::unique_ptr<int> p2 )
+{
+ BOOST_HOF_TEST_CHECK( *p1 == 1 );
+ BOOST_HOF_TEST_CHECK( *p2 == 2 );
+}
+
+void fv3( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3 )
+{
+ BOOST_HOF_TEST_CHECK( *p1 == 1 );
+ BOOST_HOF_TEST_CHECK( *p2 == 2 );
+ BOOST_HOF_TEST_CHECK( *p3 == 3 );
+}
+
+void fv4( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4 )
+{
+ BOOST_HOF_TEST_CHECK( *p1 == 1 );
+ BOOST_HOF_TEST_CHECK( *p2 == 2 );
+ BOOST_HOF_TEST_CHECK( *p3 == 3 );
+ BOOST_HOF_TEST_CHECK( *p4 == 4 );
+}
+
+void fv5( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5 )
+{
+ BOOST_HOF_TEST_CHECK( *p1 == 1 );
+ BOOST_HOF_TEST_CHECK( *p2 == 2 );
+ BOOST_HOF_TEST_CHECK( *p3 == 3 );
+ BOOST_HOF_TEST_CHECK( *p4 == 4 );
+ BOOST_HOF_TEST_CHECK( *p5 == 5 );
+}
+
+void fv6( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5, std::unique_ptr<int> p6 )
+{
+ BOOST_HOF_TEST_CHECK( *p1 == 1 );
+ BOOST_HOF_TEST_CHECK( *p2 == 2 );
+ BOOST_HOF_TEST_CHECK( *p3 == 3 );
+ BOOST_HOF_TEST_CHECK( *p4 == 4 );
+ BOOST_HOF_TEST_CHECK( *p5 == 5 );
+ BOOST_HOF_TEST_CHECK( *p6 == 6 );
+}
+
+void fv7( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5, std::unique_ptr<int> p6, std::unique_ptr<int> p7 )
+{
+ BOOST_HOF_TEST_CHECK( *p1 == 1 );
+ BOOST_HOF_TEST_CHECK( *p2 == 2 );
+ BOOST_HOF_TEST_CHECK( *p3 == 3 );
+ BOOST_HOF_TEST_CHECK( *p4 == 4 );
+ BOOST_HOF_TEST_CHECK( *p5 == 5 );
+ BOOST_HOF_TEST_CHECK( *p6 == 6 );
+ BOOST_HOF_TEST_CHECK( *p7 == 7 );
+}
+
+void fv8( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5, std::unique_ptr<int> p6, std::unique_ptr<int> p7, std::unique_ptr<int> p8 )
+{
+ BOOST_HOF_TEST_CHECK( *p1 == 1 );
+ BOOST_HOF_TEST_CHECK( *p2 == 2 );
+ BOOST_HOF_TEST_CHECK( *p3 == 3 );
+ BOOST_HOF_TEST_CHECK( *p4 == 4 );
+ BOOST_HOF_TEST_CHECK( *p5 == 5 );
+ BOOST_HOF_TEST_CHECK( *p6 == 6 );
+ BOOST_HOF_TEST_CHECK( *p7 == 7 );
+ BOOST_HOF_TEST_CHECK( *p8 == 8 );
+}
+
+void fv9( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5, std::unique_ptr<int> p6, std::unique_ptr<int> p7, std::unique_ptr<int> p8, std::unique_ptr<int> p9 )
+{
+ BOOST_HOF_TEST_CHECK( *p1 == 1 );
+ BOOST_HOF_TEST_CHECK( *p2 == 2 );
+ BOOST_HOF_TEST_CHECK( *p3 == 3 );
+ BOOST_HOF_TEST_CHECK( *p4 == 4 );
+ BOOST_HOF_TEST_CHECK( *p5 == 5 );
+ BOOST_HOF_TEST_CHECK( *p6 == 6 );
+ BOOST_HOF_TEST_CHECK( *p7 == 7 );
+ BOOST_HOF_TEST_CHECK( *p8 == 8 );
+ BOOST_HOF_TEST_CHECK( *p9 == 9 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ std::unique_ptr<int> p1( new int(1) );
+
+ boost::hof::lazy( fv1 )( std::placeholders::_1 )( std::move( p1 ) );
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::unique_ptr<int> p1( new int(1) );
+ std::unique_ptr<int> p2( new int(2) );
+
+ boost::hof::lazy( fv2 )( std::placeholders::_1, std::placeholders::_2 )( std::move( p1 ), std::move( p2 ) );
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::unique_ptr<int> p1( new int(1) );
+ std::unique_ptr<int> p2( new int(2) );
+ std::unique_ptr<int> p3( new int(3) );
+
+ boost::hof::lazy( fv3 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3 )( std::move( p1 ), std::move( p2 ), std::move( p3 ) );
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::unique_ptr<int> p1( new int(1) );
+ std::unique_ptr<int> p2( new int(2) );
+ std::unique_ptr<int> p3( new int(3) );
+ std::unique_ptr<int> p4( new int(4) );
+
+ boost::hof::lazy( fv4 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ) );
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::unique_ptr<int> p1( new int(1) );
+ std::unique_ptr<int> p2( new int(2) );
+ std::unique_ptr<int> p3( new int(3) );
+ std::unique_ptr<int> p4( new int(4) );
+ std::unique_ptr<int> p5( new int(5) );
+
+ boost::hof::lazy( fv5 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ) );
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::unique_ptr<int> p1( new int(1) );
+ std::unique_ptr<int> p2( new int(2) );
+ std::unique_ptr<int> p3( new int(3) );
+ std::unique_ptr<int> p4( new int(4) );
+ std::unique_ptr<int> p5( new int(5) );
+ std::unique_ptr<int> p6( new int(6) );
+
+ boost::hof::lazy( fv6 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ) );
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::unique_ptr<int> p1( new int(1) );
+ std::unique_ptr<int> p2( new int(2) );
+ std::unique_ptr<int> p3( new int(3) );
+ std::unique_ptr<int> p4( new int(4) );
+ std::unique_ptr<int> p5( new int(5) );
+ std::unique_ptr<int> p6( new int(6) );
+ std::unique_ptr<int> p7( new int(7) );
+
+ boost::hof::lazy( fv7 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ), std::move( p7 ) );
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::unique_ptr<int> p1( new int(1) );
+ std::unique_ptr<int> p2( new int(2) );
+ std::unique_ptr<int> p3( new int(3) );
+ std::unique_ptr<int> p4( new int(4) );
+ std::unique_ptr<int> p5( new int(5) );
+ std::unique_ptr<int> p6( new int(6) );
+ std::unique_ptr<int> p7( new int(7) );
+ std::unique_ptr<int> p8( new int(8) );
+
+ boost::hof::lazy( fv8 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ), std::move( p7 ), std::move( p8 ) );
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::unique_ptr<int> p1( new int(1) );
+ std::unique_ptr<int> p2( new int(2) );
+ std::unique_ptr<int> p3( new int(3) );
+ std::unique_ptr<int> p4( new int(4) );
+ std::unique_ptr<int> p5( new int(5) );
+ std::unique_ptr<int> p6( new int(6) );
+ std::unique_ptr<int> p7( new int(7) );
+ std::unique_ptr<int> p8( new int(8) );
+ std::unique_ptr<int> p9( new int(9) );
+
+ boost::hof::lazy( fv9 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ), std::move( p7 ), std::move( p8 ), std::move( p9 ) );
+}
+
+
+struct X_ref
+{
+ int f( int x )
+ {
+ return x;
+ }
+
+ int g( int x ) const
+ {
+ return -x;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ X_ref x;
+
+ BOOST_HOF_TEST_CHECK( boost::hof::lazy( &X_ref::f )( std::ref( x ), std::placeholders::_1 )( 1 ) == 1 );
+ BOOST_HOF_TEST_CHECK( boost::hof::lazy( &X_ref::g )( std::cref( x ), std::placeholders::_1 )( 2 ) == -2 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto lazy_f_1 = boost::hof::lazy(f_1())(std::placeholders::_1);
+ static_assert(boost::hof::is_invocable<decltype(lazy_f_1), long>::value, "Invocable");
+ static_assert(boost::hof::is_invocable<decltype(lazy_f_1), long, long>::value, "Invocable");
+
+ auto lazy_f_2 = boost::hof::lazy(f_2())(std::placeholders::_1, std::placeholders::_2);
+ static_assert(boost::hof::is_invocable<decltype(lazy_f_2), long, long>::value, "Invocable");
+ static_assert(!boost::hof::is_invocable<decltype(lazy_f_2), long>::value, "Not SFINAE-friendly");
+}
+
+struct dummy_unary_fn
+{
+ template <typename S>
+ int operator()(S const &) const { return 0; }
+};
+
+struct bad_unary_fn
+{
+ template <typename S>
+ constexpr int operator()(S const &) const
+ {
+ static_assert(!std::is_same<S, S>::value, "Failure");
+ return 0;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ auto b = boost::hof::lazy(dummy_unary_fn())(bad_unary_fn());
+ b(0);
+}
+
+
+struct by_value_fn
+{
+ template<typename T, typename U>
+ void operator()(T &&, U &&) const
+ {
+ static_assert(std::is_same<U, int>::value, "");
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ boost::hof::lazy(by_value_fn{})(std::placeholders::_1, 42)("hello");
+}
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+struct copy_throws
+{
+ copy_throws() {}
+ copy_throws(copy_throws const&) {}
+ copy_throws(copy_throws&&) noexcept {}
+};
+
+struct no_throw_fo
+{
+ void operator()() const noexcept {}
+ void operator()(int) const noexcept {}
+ void operator()(copy_throws) const noexcept {}
+};
+
+struct throws_fo
+{
+ void operator()() const {}
+};
+
+struct member_obj
+{
+ int x;
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ no_throw_fo obj;
+ copy_throws arg;
+ static_assert(noexcept(boost::hof::lazy(no_throw_fo{})()()), "noexcept lazy");
+ static_assert(noexcept(boost::hof::lazy(obj)()()), "noexcept lazy");
+ static_assert(!noexcept(boost::hof::lazy(obj)(arg)()), "noexcept lazy");
+ static_assert(noexcept(boost::hof::lazy(obj)(1)()), "noexcept lazy");
+ static_assert(noexcept(boost::hof::lazy(obj)(std::placeholders::_1)), "noexcept lazy");
+ // static_assert(noexcept(boost::hof::lazy(obj)(std::placeholders::_1)()), "noexcept lazy");
+ static_assert(noexcept(boost::hof::lazy(obj)(std::placeholders::_1)(1)), "noexcept lazy");
+ static_assert(!noexcept(boost::hof::lazy(obj)(std::placeholders::_1)(arg)), "noexcept lazy");
+
+ static_assert(noexcept(boost::hof::lazy(obj)(std::move(arg))), "noexcept lazy");
+ static_assert(!noexcept(boost::hof::lazy(obj)(std::move(arg))()), "noexcept lazy");
+}
+BOOST_HOF_TEST_CASE()
+{
+ throws_fo obj;
+ static_assert(!noexcept(boost::hof::lazy(obj)()()), "noexcept lazy");
+}
+BOOST_HOF_TEST_CASE()
+{
+ member_obj obj{42};
+ static_assert(noexcept(boost::hof::lazy(&member_obj::x)(obj)()), "noexcept lazy");
+ static_assert(noexcept(boost::hof::lazy(&member_obj::x)(std::placeholders::_1)(obj)), "noexcept lazy");
+}
+#endif
diff --git a/src/boost/libs/hof/test/lift.cpp b/src/boost/libs/hof/test/lift.cpp
new file mode 100644
index 000000000..cae105783
--- /dev/null
+++ b/src/boost/libs/hof/test/lift.cpp
@@ -0,0 +1,58 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ lift.cpp
+ 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)
+==============================================================================*/
+#include "test.hpp"
+#include <boost/hof/lift.hpp>
+#include <boost/hof/function.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <tuple>
+#include <algorithm>
+
+template<class T, class U>
+constexpr T sum(T x, U y) BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(x+y)
+{
+ return x + y;
+}
+
+BOOST_HOF_LIFT_CLASS(max_f, std::max);
+BOOST_HOF_LIFT_CLASS(sum_f, sum);
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(sum_f()(1, 2)), "noexcept lift");
+ static_assert(!noexcept(sum_f()(std::string(), std::string())), "noexcept lift");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(max_f()(3, 4) == std::max(3, 4));
+
+ BOOST_HOF_TEST_CHECK(sum_f()(1, 2) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(sum_f()(1, 2) == 3);
+}
+
+#if BOOST_HOF_HAS_GENERIC_LAMBDA
+BOOST_HOF_TEST_CASE()
+{
+ auto my_max = BOOST_HOF_LIFT(std::max);
+ BOOST_HOF_TEST_CHECK(my_max(3, 4) == std::max(3, 4));
+
+ BOOST_HOF_TEST_CHECK(BOOST_HOF_LIFT(std::max)(3, 4) == std::max(3, 4));
+ BOOST_HOF_TEST_CHECK(BOOST_HOF_LIFT(sum)(1, 2) == 3);
+}
+
+BOOST_HOF_STATIC_FUNCTION(psum) = BOOST_HOF_LIFT(sum);
+BOOST_HOF_STATIC_FUNCTION(pmax) = BOOST_HOF_LIFT(std::max);
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(pmax(3, 4) == std::max(3, 4));
+
+ BOOST_HOF_TEST_CHECK(psum(1, 2) == 3);
+}
+#endif
diff --git a/src/boost/libs/hof/test/limit.cpp b/src/boost/libs/hof/test/limit.cpp
new file mode 100644
index 000000000..74697413e
--- /dev/null
+++ b/src/boost/libs/hof/test/limit.cpp
@@ -0,0 +1,49 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ limit.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/limit.hpp>
+#include <boost/hof/is_invocable.hpp>
+#include <boost/hof/pack.hpp>
+#include "test.hpp"
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::limit(std::integral_constant<int, 2>())(binary_class());
+ BOOST_HOF_TEST_CHECK(f(1, 2) == 3);
+ static_assert(boost::hof::function_param_limit<decltype(f)>::value == 2, "Function limit is 2");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::limit_c<2>(binary_class());
+ BOOST_HOF_TEST_CHECK(f(1, 2) == 3);
+ static_assert(boost::hof::function_param_limit<decltype(f)>::value == 2, "Function limit is 2");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::limit_c<2>(boost::hof::always(3));
+ BOOST_HOF_TEST_CHECK(f(1, 2) == 3);
+ BOOST_HOF_TEST_CHECK(f(1) == 3);
+ BOOST_HOF_TEST_CHECK(f() == 3);
+ static_assert(boost::hof::function_param_limit<decltype(f)>::value == 2, "Function limit is 2");
+ static_assert(boost::hof::is_invocable<decltype(f), int>::value, "Invocable");
+ static_assert(boost::hof::is_invocable<decltype(f), int, int>::value, "Invocable");
+ static_assert(!boost::hof::is_invocable<decltype(f), int, int, int>::value, "Not Invocable");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(!boost::hof::is_invocable<decltype(boost::hof::limit), int>::value, "Not integral constant");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(boost::hof::function_param_limit<decltype(boost::hof::pack())>::value == 0, "Failed limit on pack");
+ static_assert(boost::hof::function_param_limit<decltype(boost::hof::pack(1))>::value == 1, "Failed limit on pack");
+ static_assert(boost::hof::function_param_limit<decltype(boost::hof::pack(1, 2))>::value == 2, "Failed limit on pack");
+}
+
diff --git a/src/boost/libs/hof/test/match.cpp b/src/boost/libs/hof/test/match.cpp
new file mode 100644
index 000000000..0d09dfdf6
--- /dev/null
+++ b/src/boost/libs/hof/test/match.cpp
@@ -0,0 +1,193 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ match.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/match.hpp>
+#include <boost/hof/static.hpp>
+#include <boost/hof/lambda.hpp>
+#include <boost/hof/placeholders.hpp>
+#include <boost/hof/limit.hpp>
+#include "test.hpp"
+
+#include <memory>
+
+namespace test1
+{
+ struct int_class
+ {
+ int operator()(int) const
+ {
+ return 1;
+ }
+ };
+
+ struct foo
+ {};
+
+ struct foo_class
+ {
+ foo operator()(foo) const
+ {
+ return foo();
+ }
+ };
+
+ static constexpr boost::hof::static_<boost::hof::match_adaptor<int_class, foo_class> > fun = {};
+
+ static_assert(std::is_same<int, decltype(fun(1))>::value, "Failed match");
+ static_assert(std::is_same<foo, decltype(fun(foo()))>::value, "Failed match");
+}
+
+struct int_class
+{
+ constexpr int operator()(int) const
+ {
+ return 1;
+ }
+};
+
+struct foo
+{};
+
+struct foo_class
+{
+ constexpr int operator()(foo) const
+ {
+ return 2;
+ }
+};
+
+static constexpr boost::hof::match_adaptor<int_class, foo_class> fun = {};
+
+BOOST_HOF_TEST_CASE()
+{
+
+ BOOST_HOF_TEST_CHECK(fun(1) == 1);
+ BOOST_HOF_TEST_CHECK(fun(foo()) == 2);
+
+ BOOST_HOF_STATIC_TEST_CHECK(fun(1) == 1);
+ BOOST_HOF_STATIC_TEST_CHECK(fun(foo()) == 2);
+};
+
+BOOST_HOF_TEST_CASE()
+{
+
+ BOOST_HOF_TEST_CHECK(boost::hof::reveal(fun)(1) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::reveal(fun)(foo()) == 2);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reveal(fun)(1) == 1);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reveal(fun)(foo()) == 2);
+};
+
+BOOST_HOF_TEST_CASE()
+{
+
+ constexpr auto lam = boost::hof::match(
+ BOOST_HOF_STATIC_LAMBDA(int) { return 1; },
+ BOOST_HOF_STATIC_LAMBDA(foo) { return 2; }
+ );
+
+ BOOST_HOF_TEST_CHECK(lam(1) == 1);
+ BOOST_HOF_TEST_CHECK(lam(foo()) == 2);
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ int i = 0;
+ auto lam = boost::hof::match(
+ [&](int) { return i+1; },
+ [&](foo) { return i+2; }
+ );
+// Disable this check on msvc, since lambdas might be default constructible
+#ifndef _MSC_VER
+ STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(decltype(lam));
+#endif
+ BOOST_HOF_TEST_CHECK(lam(1) == 1);
+ BOOST_HOF_TEST_CHECK(lam(foo()) == 2);
+};
+
+
+BOOST_HOF_TEST_CASE()
+{
+ struct not_default_constructible
+ {
+ int i;
+ not_default_constructible(int x) : i(x)
+ {}
+ };
+ STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(not_default_constructible);
+ not_default_constructible ndc = not_default_constructible(0);
+ auto lam = boost::hof::match(
+ [&](int) { return ndc.i+1; },
+ [&](foo) { return ndc.i+2; }
+ );
+// Disable this check on msvc, since lambdas might be default constructible
+#ifndef _MSC_VER
+ STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(decltype(lam));
+#endif
+
+ BOOST_HOF_TEST_CHECK(lam(1) == 1);
+ BOOST_HOF_TEST_CHECK(lam(foo()) == 2);
+};
+
+
+struct int_move_class
+{
+ std::unique_ptr<int> i;
+ int_move_class() : i(new int(1))
+ {}
+ int operator()(int) const
+ {
+ return *i;
+ }
+};
+
+struct foo_move_class
+{
+ std::unique_ptr<int> i;
+ foo_move_class() : i(new int(2))
+ {}
+ int operator()(foo) const
+ {
+ return *i;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ auto fun_move = boost::hof::match(int_move_class(), foo_move_class());
+ BOOST_HOF_TEST_CHECK(fun_move(1) == 1);
+ BOOST_HOF_TEST_CHECK(fun_move(foo()) == 2);
+
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ const auto negate = (!boost::hof::_);
+ const auto sub = (boost::hof::_ - boost::hof::_);
+ BOOST_HOF_TEST_CHECK(boost::hof::match(negate, sub)(0) == negate(0));
+ BOOST_HOF_TEST_CHECK(boost::hof::match(negate, sub)(0, 1) == sub(0, 1));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ const auto negate = (!boost::hof::_1);
+ const auto sub = (boost::hof::_1 - boost::hof::_2);
+ BOOST_HOF_TEST_CHECK(boost::hof::match(negate, sub)(0) == negate(0));
+ // This is test is disabled because its invalid. It is valid to give more
+ // parameters than what are used by the placeholders. So negate(0, 1) is a
+ // valid call, which makes the following test fail with ambigous overload.
+ // BOOST_HOF_TEST_CHECK(boost::hof::match(negate, sub)(0, 1) == sub(0, 1));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ const auto negate = boost::hof::limit_c<1>(!boost::hof::_1);
+ const auto sub = boost::hof::limit_c<2>(boost::hof::_1 - boost::hof::_2);
+ BOOST_HOF_TEST_CHECK(boost::hof::match(negate, sub)(0) == negate(0));
+ // This test will pass because we have limited the number of parameters.
+ BOOST_HOF_TEST_CHECK(boost::hof::match(negate, sub)(0, 1) == sub(0, 1));
+}
+
diff --git a/src/boost/libs/hof/test/mutable.cpp b/src/boost/libs/hof/test/mutable.cpp
new file mode 100644
index 000000000..d071bc639
--- /dev/null
+++ b/src/boost/libs/hof/test/mutable.cpp
@@ -0,0 +1,72 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ mutable.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/mutable.hpp>
+#include <boost/hof/lazy.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <memory>
+#include "test.hpp"
+
+struct mutable_fun
+{
+ int x;
+ mutable_fun() noexcept
+ : x(1)
+ {}
+
+ int operator()(int i) noexcept
+ {
+ x+=i;
+ return x;
+ }
+};
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::mutable_(mutable_fun())(3)), "noexcept mutable_");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::mutable_(mutable_fun())(3) == 4);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto mut_fun = mutable_fun();
+ auto by_5 = boost::hof::lazy(boost::hof::mutable_(std::ref(mut_fun)))(5);
+ BOOST_HOF_TEST_CHECK(by_5() == 6);
+ BOOST_HOF_TEST_CHECK(by_5() == 11);
+}
+
+struct mutable_move_fun
+{
+ std::unique_ptr<int> x;
+ mutable_move_fun() : x(new int(1))
+ {}
+
+ int operator()(int i)
+ {
+ *x+=i;
+ return *x;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::mutable_(mutable_move_fun())(3) == 4);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto mut_fun = mutable_move_fun();
+ auto by_5 = boost::hof::lazy(boost::hof::mutable_(boost::hof::move(mut_fun)))(5);
+ BOOST_HOF_TEST_CHECK(by_5() == 6);
+ BOOST_HOF_TEST_CHECK(by_5() == 11);
+}
+
diff --git a/src/boost/libs/hof/test/pack.cpp b/src/boost/libs/hof/test/pack.cpp
new file mode 100644
index 000000000..ac64c39ca
--- /dev/null
+++ b/src/boost/libs/hof/test/pack.cpp
@@ -0,0 +1,395 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ pack.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/pack.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/identity.hpp>
+#include <memory>
+#include "test.hpp"
+
+BOOST_HOF_TEST_CASE()
+{
+ auto p1 = boost::hof::pack_basic(1, 2);
+ auto p2 = p1;
+ BOOST_HOF_TEST_CHECK(p2(binary_class()) == p1(binary_class()));
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic(1, 2)(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_basic(1, 2)(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack(1, 2)(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack(1, 2)(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_forward(1, 2)(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_forward(1, 2)(binary_class()) == 3 );
+}
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+struct copy_throws
+{
+ copy_throws() {}
+ copy_throws(copy_throws const&) {}
+ copy_throws(copy_throws&&) noexcept {}
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ int i = 1;
+ copy_throws ct{};
+ static_assert(!noexcept(boost::hof::pack(ct, ct)(boost::hof::always())), "noexcept pack");
+ static_assert(noexcept(boost::hof::pack(1, 2)(boost::hof::always())), "noexcept pack");
+ static_assert(noexcept(boost::hof::pack_forward(ct, ct)(boost::hof::always())), "noexcept pack");
+ static_assert(noexcept(boost::hof::pack_forward(i, i)(boost::hof::always())), "noexcept pack");
+ static_assert(noexcept(boost::hof::pack_forward(1, 2)(boost::hof::always())), "noexcept pack");
+ static_assert(noexcept(boost::hof::pack_basic(ct, ct)(boost::hof::always())), "noexcept pack");
+ static_assert(noexcept(boost::hof::pack_basic(i, i)(boost::hof::always())), "noexcept pack");
+ static_assert(noexcept(boost::hof::pack_basic(1, 2)(boost::hof::always())), "noexcept pack");
+
+ static_assert(noexcept(boost::hof::pack()(boost::hof::always())), "noexcept pack");
+ static_assert(noexcept(boost::hof::pack_forward()(boost::hof::always())), "noexcept pack");
+ static_assert(noexcept(boost::hof::pack_basic()(boost::hof::always())), "noexcept pack");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ copy_throws ct{};
+ static_assert(!noexcept(boost::hof::pack_join(boost::hof::pack(ct), boost::hof::pack(ct))(boost::hof::always())), "noexcept pack");
+ static_assert(noexcept(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(1))(boost::hof::always())), "noexcept pack");
+ static_assert(noexcept(boost::hof::pack_join(boost::hof::pack(), boost::hof::pack())(boost::hof::always())), "noexcept pack");
+ auto p = boost::hof::pack(1);
+ static_assert(noexcept(boost::hof::pack_join(p, boost::hof::pack())(boost::hof::always())), "noexcept pack");
+ static_assert(noexcept(boost::hof::pack_join(boost::hof::pack(), p)(boost::hof::always())), "noexcept pack");
+ static_assert(noexcept(boost::hof::pack_join(p, p)(boost::hof::always())), "noexcept pack");
+ auto pt = boost::hof::pack(ct);
+ static_assert(!noexcept(boost::hof::pack_join(pt, boost::hof::pack())(boost::hof::always())), "noexcept pack");
+ static_assert(!noexcept(boost::hof::pack_join(boost::hof::pack(), pt)(boost::hof::always())), "noexcept pack");
+ static_assert(!noexcept(boost::hof::pack_join(pt, pt)(boost::hof::always())), "noexcept pack");
+
+}
+#endif
+BOOST_HOF_TEST_CASE()
+{
+ static constexpr int x = 1;
+ static constexpr int y = 2;
+
+ auto p1 = boost::hof::pack_basic(x, y);
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p1)>::value, "Pack default constructible");
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic(x, y)(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_basic(x, y)(binary_class()) == 3 );
+
+ auto p2 = boost::hof::pack(std::ref(x), std::ref(y));
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p2)>::value, "Pack default constructible");
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack(x, y)(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack(std::ref(x), std::ref(y))(binary_class()) == 3 );
+
+ auto p3 = boost::hof::pack_forward(x, y);
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p3)>::value, "Pack default constructible");
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_forward(x, y)(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_forward(x, y)(binary_class()) == 3 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic()(boost::hof::always(3)) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_basic()(boost::hof::always(3)) == 3 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic(3)(boost::hof::identity) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_basic(3)(boost::hof::identity) == 3 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto p = boost::hof::pack(1);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(p, boost::hof::pack(2))(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(p, p)(binary_class()) == 2);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(p, p, boost::hof::pack())(binary_class()) == 2);
+
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1), boost::hof::pack_basic(2))(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1), boost::hof::pack_basic(2))(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(2))(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(2))(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1), boost::hof::pack_forward(2))(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1), boost::hof::pack_forward(2))(binary_class()) == 3 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(), boost::hof::pack_basic(1, 2))(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(), boost::hof::pack_basic(1, 2))(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(), boost::hof::pack(1, 2))(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(), boost::hof::pack(1, 2))(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(), boost::hof::pack_forward(1, 2))(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(), boost::hof::pack_forward(1, 2))(binary_class()) == 3 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1, 2), boost::hof::pack_basic())(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1, 2), boost::hof::pack_basic())(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1, 2), boost::hof::pack())(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1, 2), boost::hof::pack())(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1, 2), boost::hof::pack_forward())(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1, 2), boost::hof::pack_forward())(binary_class()) == 3 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1), boost::hof::pack_basic(), boost::hof::pack_basic(2))(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1), boost::hof::pack_basic(), boost::hof::pack_basic(2))(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(), boost::hof::pack(2))(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(), boost::hof::pack(2))(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1), boost::hof::pack_forward(), boost::hof::pack_forward(2))(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1), boost::hof::pack_forward(), boost::hof::pack_forward(2))(binary_class()) == 3 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(), boost::hof::pack_basic(1), boost::hof::pack_basic(), boost::hof::pack_basic(2))(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(), boost::hof::pack_basic(1), boost::hof::pack_basic(), boost::hof::pack_basic(2))(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(), boost::hof::pack(1), boost::hof::pack(), boost::hof::pack(2))(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(), boost::hof::pack(1), boost::hof::pack(), boost::hof::pack(2))(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(), boost::hof::pack_forward(1), boost::hof::pack_forward(), boost::hof::pack_forward(2))(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(), boost::hof::pack_forward(1), boost::hof::pack_forward(), boost::hof::pack_forward(2))(binary_class()) == 3 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1), boost::hof::pack_basic(), boost::hof::pack_basic(2), boost::hof::pack_basic())(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1), boost::hof::pack_basic(), boost::hof::pack_basic(2), boost::hof::pack_basic())(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(), boost::hof::pack(2), boost::hof::pack())(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(), boost::hof::pack(2), boost::hof::pack())(binary_class()) == 3 );
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1), boost::hof::pack_forward(), boost::hof::pack_forward(2), boost::hof::pack_forward())(binary_class()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1), boost::hof::pack_forward(), boost::hof::pack_forward(2), boost::hof::pack_forward())(binary_class()) == 3 );
+}
+
+struct deref
+{
+ int operator()(const std::unique_ptr<int>& i) const
+ {
+ return *i;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ std::unique_ptr<int> i(new int(3));
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_basic(i)(deref()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_basic(std::unique_ptr<int>(new int(3)))(deref()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_forward(std::unique_ptr<int>(new int(3)))(deref()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack(std::unique_ptr<int>(new int(3)))(deref()) == 3);
+ auto p = boost::hof::pack_basic(std::unique_ptr<int>(new int(3)));
+ BOOST_HOF_TEST_CHECK(p(deref()) == 3);
+
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(), boost::hof::pack_basic(std::unique_ptr<int>(new int(3))))(deref()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(), boost::hof::pack_forward(std::unique_ptr<int>(new int(3))))(deref()) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(), boost::hof::pack(std::unique_ptr<int>(new int(3))))(deref()) == 3);
+ // BOOST_HOF_TEST_CHECK(p(deref()) == 3);
+}
+
+struct move_rvalue
+{
+ void operator()(std::string&& s) const
+ {
+ std::string ss = std::move(s);
+ BOOST_HOF_TEST_CHECK(ss == "abcdef");
+ s = "00000";
+ }
+};
+
+struct check_rvalue
+{
+ void operator()(std::string&& s) const
+ {
+ BOOST_HOF_TEST_CHECK(s == "abcdef");
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ auto p = boost::hof::pack_basic(std::string{"abcdef"});
+ p(move_rvalue{});
+ p(check_rvalue{});
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto p = boost::hof::pack(std::string{"abcdef"});
+ p(move_rvalue{});
+ p(check_rvalue{});
+}
+
+struct empty1
+{};
+
+struct empty2
+{};
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(boost::hof::detail::is_default_constructible<empty1, empty2>::value, "Not default constructible");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static constexpr auto p = boost::hof::pack_basic(empty1());
+ BOOST_HOF_TEST_CHECK(p(boost::hof::always(0)) == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(p(boost::hof::always(0)) == 0);
+#ifndef _MSC_VER
+ static_assert(std::is_empty<decltype(p)>::value, "Pack not empty");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(p)>::value, "Not default constructible");
+
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static constexpr auto p = boost::hof::pack_basic(empty1(), empty2());
+ BOOST_HOF_TEST_CHECK(p(boost::hof::always(0)) == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(p(boost::hof::always(0)) == 0);
+#ifndef _MSC_VER
+ static_assert(std::is_empty<decltype(p)>::value, "Pack not empty");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(p)>::value, "Not default constructible");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static constexpr auto p = boost::hof::pack_basic(boost::hof::pack_basic(), boost::hof::pack_basic());
+ BOOST_HOF_TEST_CHECK(p(boost::hof::always(0)) == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(p(boost::hof::always(0)) == 0);
+#ifndef _MSC_VER
+ static_assert(std::is_empty<decltype(p)>::value, "Pack not empty");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(p)>::value, "Not default constructible");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static constexpr auto p = boost::hof::pack_basic(empty1(), empty2(), empty1());
+ BOOST_HOF_TEST_CHECK(p(boost::hof::always(0)) == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(p(boost::hof::always(0)) == 0);
+#ifndef _MSC_VER
+ static_assert(std::is_empty<decltype(p)>::value, "Pack not empty");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(p)>::value, "Not default constructible");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static constexpr auto p = boost::hof::pack_basic(empty1(), boost::hof::pack_basic(empty1(), empty2()));
+ BOOST_HOF_TEST_CHECK(p(boost::hof::always(0)) == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(p(boost::hof::always(0)) == 0);
+#ifndef _MSC_VER
+ static_assert(std::is_empty<decltype(p)>::value, "Pack not empty");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(p)>::value, "Not default constructible");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static constexpr auto p = boost::hof::pack_basic(boost::hof::pack_basic(), boost::hof::pack_basic(boost::hof::pack_basic()), empty1(), boost::hof::pack_basic(empty1(), empty2()));
+ BOOST_HOF_TEST_CHECK(p(boost::hof::always(0)) == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(p(boost::hof::always(0)) == 0);
+#ifndef _MSC_VER
+ static_assert(std::is_empty<decltype(p)>::value, "Pack not empty");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(p)>::value, "Not default constructible");
+}
+
+struct not_default_constructible
+{
+ int i;
+ constexpr not_default_constructible(int x) : i(x)
+ {}
+};
+
+struct select_i
+{
+ template<class T>
+ constexpr int operator()(T&& x) const
+ {
+ return x.i;
+ }
+
+ template<class T, class U>
+ constexpr int operator()(T&& x, U&& y) const
+ {
+ return x.i + y.i;
+ }
+
+ template<class T, class U, class V>
+ constexpr int operator()(T&& x, U&& y, V&& z) const
+ {
+ return x.i + y.i + z.i;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(!boost::hof::detail::is_default_constructible<not_default_constructible>::value, "Default constructible");
+ auto p = boost::hof::pack_basic(not_default_constructible(3));
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p)>::value, "Pack default constructible");
+ auto p1 = boost::hof::pack_forward(p);
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p1)>::value, "Packs default constructible");
+ auto p2 = boost::hof::pack_forward(p, p);
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p2)>::value, "Packs default constructible");
+ auto p3 = boost::hof::pack_forward(p, p, p);
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p3)>::value, "Packs default constructible");
+ BOOST_HOF_TEST_CHECK(p(select_i()) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic(not_default_constructible(3))(select_i()) == 3);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(!boost::hof::detail::is_default_constructible<not_default_constructible>::value, "Default constructible");
+ auto p = boost::hof::pack_basic(not_default_constructible(1), not_default_constructible(2));
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p)>::value, "Pack default constructible");
+ auto p1 = boost::hof::pack_forward(p);
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p1)>::value, "Packs default constructible");
+ auto p2 = boost::hof::pack_forward(p, p);
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p2)>::value, "Packs default constructible");
+ auto p3 = boost::hof::pack_forward(p, p, p);
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p3)>::value, "Packs default constructible");
+ BOOST_HOF_TEST_CHECK(p(select_i()) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic(not_default_constructible(1), not_default_constructible(2))(select_i()) == 3);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(!boost::hof::detail::is_default_constructible<not_default_constructible>::value, "Default constructible");
+ auto p = boost::hof::pack_basic(not_default_constructible(1), not_default_constructible(1), not_default_constructible(1));
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p)>::value, "Pack default constructible");
+ auto p1 = boost::hof::pack_forward(p);
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p1)>::value, "Packs default constructible");
+ auto p2 = boost::hof::pack_forward(p, p);
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p2)>::value, "Packs default constructible");
+ auto p3 = boost::hof::pack_forward(p, p, p);
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(p3)>::value, "Packs default constructible");
+ BOOST_HOF_TEST_CHECK(p(select_i()) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic(not_default_constructible(1), not_default_constructible(1), not_default_constructible(1))(select_i()) == 3);
+}
+
+
diff --git a/src/boost/libs/hof/test/partial.cpp b/src/boost/libs/hof/test/partial.cpp
new file mode 100644
index 000000000..bb4d5b75a
--- /dev/null
+++ b/src/boost/libs/hof/test/partial.cpp
@@ -0,0 +1,108 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ partial.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/partial.hpp>
+#include <boost/hof/limit.hpp>
+#include "test.hpp"
+
+static constexpr boost::hof::static_<boost::hof::partial_adaptor<binary_class> > binary_partial = {};
+
+static constexpr boost::hof::static_<boost::hof::partial_adaptor<unary_class> > unary_partial = {};
+
+static constexpr boost::hof::static_<boost::hof::partial_adaptor<mutable_class> > mutable_partial = {};
+
+static constexpr boost::hof::static_<boost::hof::partial_adaptor<void_class> > void_partial = {};
+
+static constexpr boost::hof::static_<boost::hof::partial_adaptor<mono_class> > mono_partial = {};
+
+static constexpr boost::hof::static_<boost::hof::partial_adaptor<move_class> > move_partial = {};
+
+constexpr boost::hof::partial_adaptor<binary_class> binary_partial_constexpr = {};
+
+constexpr boost::hof::partial_adaptor<unary_class> unary_partial_constexpr = {};
+
+constexpr boost::hof::partial_adaptor<void_class> void_partial_constexpr = {};
+
+constexpr boost::hof::partial_adaptor<mono_class> mono_partial_constexpr = {};
+
+BOOST_HOF_TEST_CASE()
+{
+ boost::hof::partial_adaptor<void_class>()(1);
+
+ void_partial(1);
+ void_partial()(1);
+ BOOST_HOF_TEST_CHECK(3 == binary_partial(1)(2));
+ BOOST_HOF_TEST_CHECK(3 == binary_partial(1, 2));
+ BOOST_HOF_TEST_CHECK(3 == unary_partial()(3));
+ BOOST_HOF_TEST_CHECK(3 == unary_partial(3));
+ BOOST_HOF_TEST_CHECK(3 == mono_partial(2));
+ BOOST_HOF_TEST_CHECK(3 == mono_partial()(2));
+
+ int i1 = 1;
+ BOOST_HOF_TEST_CHECK(3 == binary_partial(2)(i1));
+ BOOST_HOF_TEST_CHECK(3 == mutable_partial(std::ref(i1))(2));
+ BOOST_HOF_TEST_CHECK(3 == i1);
+ int i2 = 1;
+ BOOST_HOF_TEST_CHECK(3 == mutable_partial(i2, 2));
+ BOOST_HOF_TEST_CHECK(3 == i2);
+
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == (move_class()(1, 2)));
+ BOOST_HOF_TEST_CHECK(3 == (move_partial(1, 2)));
+ BOOST_HOF_TEST_CHECK(3 == (move_partial(1)(2)));
+ BOOST_HOF_TEST_CHECK(3 == (boost::hof::partial(move_class())(1)(2)));
+ BOOST_HOF_TEST_CHECK(3 == (boost::hof::partial(move_class())(1, 2)));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ void_partial_constexpr(1);
+ void_partial_constexpr()(1);
+ BOOST_HOF_STATIC_TEST_CHECK(3 == binary_partial_constexpr(1)(2));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == binary_partial_constexpr(1, 2));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == unary_partial_constexpr()(3));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == unary_partial_constexpr(3));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == mono_partial_constexpr(2));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == mono_partial_constexpr()(2));
+}
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::partial(binary_class{})(1)(2)), "noexcept partial");
+}
+#endif
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::partial(boost::hof::limit_c<2>(binary_class()));
+ static_assert(boost::hof::is_invocable<decltype(f), int>::value, "Passing the limit is not callable");
+ static_assert(boost::hof::is_invocable<decltype(f), int, int>::value, "Passing the limit is not callable");
+ static_assert(!boost::hof::is_invocable<decltype(f), int, int, int>::value, "Passing the limit is not callable");
+ static_assert(!boost::hof::is_invocable<decltype(f), int, int, int, int>::value, "Passing the limit is not callable");
+
+ auto g = f(0);
+ static_assert(boost::hof::is_invocable<decltype(g), int>::value, "Passing the limit is not callable");
+ static_assert(!boost::hof::is_invocable<decltype(g), int, int>::value, "Passing the limit is not callable");
+ static_assert(!boost::hof::is_invocable<decltype(g), int, int, int>::value, "Passing the limit is not callable");
+ static_assert(!boost::hof::is_invocable<decltype(g), int, int, int, int>::value, "Passing the limit is not callable");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::partial(binary_class());
+ static_assert(boost::hof::is_invocable<decltype(f), int>::value, "Passing the limit is not callable");
+ static_assert(boost::hof::is_invocable<decltype(f), int, int>::value, "Passing the limit is not callable");
+ static_assert(boost::hof::is_invocable<decltype(f), int, int, int>::value, "Passing the limit is not callable");
+ static_assert(boost::hof::is_invocable<decltype(f), int, int, int, int>::value, "Passing the limit is not callable");
+
+ auto g = f(0);
+ static_assert(boost::hof::is_invocable<decltype(g), int>::value, "Passing the limit is not callable");
+ static_assert(boost::hof::is_invocable<decltype(g), int, int>::value, "Passing the limit is not callable");
+ static_assert(boost::hof::is_invocable<decltype(g), int, int, int>::value, "Passing the limit is not callable");
+ static_assert(boost::hof::is_invocable<decltype(g), int, int, int, int>::value, "Passing the limit is not callable");
+}
diff --git a/src/boost/libs/hof/test/pipable.cpp b/src/boost/libs/hof/test/pipable.cpp
new file mode 100644
index 000000000..45bf7fdfa
--- /dev/null
+++ b/src/boost/libs/hof/test/pipable.cpp
@@ -0,0 +1,90 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ pipable.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/pipable.hpp>
+#include <boost/hof/static.hpp>
+#include <boost/hof/limit.hpp>
+#include "test.hpp"
+
+static constexpr boost::hof::static_<boost::hof::pipable_adaptor<binary_class> > binary_pipable = {};
+
+static constexpr boost::hof::static_<boost::hof::pipable_adaptor<unary_class> > unary_pipable = {};
+
+static constexpr boost::hof::static_<boost::hof::pipable_adaptor<mutable_class> > mutable_pipable = {};
+
+static constexpr boost::hof::static_<boost::hof::pipable_adaptor<void_class> > void_pipable = {};
+
+static constexpr boost::hof::static_<boost::hof::pipable_adaptor<mono_class> > mono_pipable = {};
+
+static constexpr boost::hof::static_<boost::hof::pipable_adaptor<move_class> > move_pipable = {};
+
+constexpr boost::hof::pipable_adaptor<void_class> void_pipable_constexpr = {};
+
+constexpr boost::hof::pipable_adaptor<binary_class> binary_pipable_constexpr = {};
+
+constexpr boost::hof::pipable_adaptor<unary_class> unary_pipable_constexpr = {};
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(1 | binary_pipable(2)), "noexcept pipable");
+ static_assert(noexcept(binary_pipable(1, 2)), "noexcept pipable");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ void_pipable(1);
+ 1 | void_pipable;
+ BOOST_HOF_TEST_CHECK(3 == (1 | binary_pipable(2)));
+ BOOST_HOF_TEST_CHECK(3 == (binary_pipable(1, 2)));
+ BOOST_HOF_TEST_CHECK(3 == (3 | unary_pipable));
+ BOOST_HOF_TEST_CHECK(3 == (3 | unary_pipable()));
+ BOOST_HOF_TEST_CHECK(3 == (unary_pipable(3)));
+ int i1 = 1;
+ BOOST_HOF_TEST_CHECK(3 == (2 | binary_pipable(i1)));
+ BOOST_HOF_TEST_CHECK(3 == (i1 | mutable_pipable(2)));
+ BOOST_HOF_TEST_CHECK(3 == (i1));
+ int i2 = 1;
+ BOOST_HOF_TEST_CHECK(3 == (mutable_pipable(i2, 2)));
+ BOOST_HOF_TEST_CHECK(3 == (i2));
+ BOOST_HOF_TEST_CHECK(3 == (mono_pipable(2)));
+ BOOST_HOF_TEST_CHECK(3 == (2| mono_pipable));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == (move_class()(1, 2)));
+ BOOST_HOF_TEST_CHECK(3 == (move_pipable(1, 2)));
+ BOOST_HOF_TEST_CHECK(3 == (1 | move_pipable(2)));
+ BOOST_HOF_TEST_CHECK(3 == (1 | boost::hof::pipable(move_class())(2)));
+ BOOST_HOF_TEST_CHECK(3 == (boost::hof::pipable(move_class())(1, 2)));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ void_pipable_constexpr(1);
+ 1 | void_pipable_constexpr;
+ BOOST_HOF_STATIC_TEST_CHECK(3 == (1 | binary_pipable_constexpr(2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == (binary_pipable_constexpr(1, 2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == (3 | unary_pipable_constexpr));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == (3 | unary_pipable_constexpr()));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == (unary_pipable_constexpr(3)));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::limit_c<2>(binary_pipable_constexpr)(1, 2));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::limit_c<2>(binary_pipable_constexpr)(1, 2));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::pipable(boost::hof::limit_c<2>(binary_class()));
+ static_assert(boost::hof::is_invocable<decltype(f), int, int>::value, "Passing the limit is not callable");
+ static_assert(!boost::hof::is_invocable<decltype(f), int, int, int>::value, "Passing the limit is not callable");
+ static_assert(!boost::hof::is_invocable<decltype(f), int, int, int, int>::value, "Passing the limit is not callable");
+}
diff --git a/src/boost/libs/hof/test/placeholders.cpp b/src/boost/libs/hof/test/placeholders.cpp
new file mode 100644
index 000000000..352230a8f
--- /dev/null
+++ b/src/boost/libs/hof/test/placeholders.cpp
@@ -0,0 +1,813 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ placeholders.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/placeholders.hpp>
+#include "test.hpp"
+#include <sstream>
+
+// TODO: Test assign operators
+
+#if BOOST_HOF_HAS_STATIC_TEST_CHECK
+#define BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR constexpr
+#else
+#define BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR
+#endif
+
+struct square
+{
+ template<class T>
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto operator()(T x) const BOOST_HOF_RETURNS(x*x);
+};
+
+#define CHECK_DEFAULT_CONSTRUCTION_OP(op, name) \
+ static_assert(boost::hof::detail::is_default_constructible<boost::hof::operators::name>::value, "Operator not default constructible");
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+#define PLACEHOLDER_CHECK(...) \
+ BOOST_HOF_STATIC_TEST_CHECK(__VA_ARGS__); \
+ BOOST_HOF_TEST_CHECK(__VA_ARGS__); \
+ static_assert(noexcept(__VA_ARGS__), "noexcept placeholders")
+#else
+#define PLACEHOLDER_CHECK(...) \
+ BOOST_HOF_STATIC_TEST_CHECK(__VA_ARGS__); \
+ BOOST_HOF_TEST_CHECK(__VA_ARGS__)
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(boost::hof::detail::is_default_constructible<boost::hof::placeholder<1>>::value, "Placeholder not default constructible");
+ static_assert(boost::hof::detail::is_default_constructible<boost::hof::placeholder<2>>::value, "Placeholder not default constructible");
+ static_assert(boost::hof::detail::is_default_constructible<boost::hof::placeholder<3>>::value, "Placeholder not default constructible");
+
+ BOOST_HOF_FOREACH_BINARY_OP(CHECK_DEFAULT_CONSTRUCTION_OP)
+ BOOST_HOF_FOREACH_ASSIGN_OP(CHECK_DEFAULT_CONSTRUCTION_OP)
+ BOOST_HOF_FOREACH_UNARY_OP(CHECK_DEFAULT_CONSTRUCTION_OP)
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto simple_print = boost::hof::reveal(std::ref(std::cout) << boost::hof::_);
+ simple_print("Hello");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ std::stringstream ss;
+ auto simple_print = boost::hof::reveal(std::ref(ss) << boost::hof::_);
+ simple_print("Hello");
+ BOOST_HOF_TEST_CHECK(ss.str() == "Hello");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ const auto x_square_add = 2 + (4*4);
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_square_add = boost::hof::_1 + boost::hof::lazy(square())(boost::hof::_2);
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_square_add)>::value, "Not copyable");
+#endif
+ PLACEHOLDER_CHECK(f_square_add(2, 4) == x_square_add);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_invoke_2 = boost::hof::_1(3);
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_invoke_2)>::value, "Not copyable");
+#endif
+ PLACEHOLDER_CHECK(f_invoke_2(square()) == 9);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ const auto x_add = 2 + 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_add = boost::hof::_1 + boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_add)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_add)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_add(2, 1) == x_add);
+
+ const auto x_subtract = 2 - 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_subtract = boost::hof::_1 - boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_subtract)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_subtract)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_subtract(2, 1) == x_subtract);
+
+ const auto x_multiply = 2 * 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_multiply = boost::hof::_1 * boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_multiply)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_multiply)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_multiply(2, 1) == x_multiply);
+
+ const auto x_divide = 2 / 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_divide = boost::hof::_1 / boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_divide)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_divide)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_divide(2, 1) == x_divide);
+
+ const auto x_remainder = 2 % 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_remainder = boost::hof::_1 % boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_remainder)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_remainder)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_remainder(2, 1) == x_remainder);
+
+ const auto x_shift_right = 2 >> 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_right = boost::hof::_1 >> boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_shift_right)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_shift_right)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_shift_right(2, 1) == x_shift_right);
+
+ const auto x_shift_left = 2 << 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_left = boost::hof::_1 << boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_shift_left)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_shift_left)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_shift_left(2, 1) == x_shift_left);
+
+ const auto x_greater_than = 2 > 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than = boost::hof::_1 > boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_greater_than)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_greater_than)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_greater_than(2, 1) == x_greater_than);
+
+ const auto x_less_than = 2 < 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than = boost::hof::_1 < boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_less_than)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_less_than)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_less_than(2, 1) == x_less_than);
+
+ const auto x_less_than_equal = 2 <= 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than_equal = boost::hof::_1 <= boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_less_than_equal)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_less_than_equal)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_less_than_equal(2, 1) == x_less_than_equal);
+
+ const auto x_greater_than_equal = 2 >= 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than_equal = boost::hof::_1 >= boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_greater_than_equal)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_greater_than_equal)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_greater_than_equal(2, 1) == x_greater_than_equal);
+
+ const auto x_equal = 2 == 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_equal = boost::hof::_1 == boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_equal)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_equal)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_equal(2, 1) == x_equal);
+
+ const auto x_not_equal = 2 != 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_equal = boost::hof::_1 != boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_not_equal)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_not_equal)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_not_equal(2, 1) == x_not_equal);
+
+ const auto x_bit_and = 2 & 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_and = boost::hof::_1 & boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_bit_and)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_bit_and)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_bit_and(2, 1) == x_bit_and);
+
+ const auto x_xor_ = 2 ^ 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_xor_ = boost::hof::_1 ^ boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_xor_)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_xor_)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_xor_(2, 1) == x_xor_);
+
+ const auto x_bit_or = 2 | 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_or = boost::hof::_1 | boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_bit_or)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_bit_or)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_bit_or(2, 1) == x_bit_or);
+
+ const auto x_and_ = true && false;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_and_ = boost::hof::_1 && boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_and_)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_and_)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_and_(true, false) == x_and_);
+
+ const auto x_or_ = true;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_or_ = boost::hof::_1 || boost::hof::_2;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_or_)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_or_)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_or_(true, false) == x_or_);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+
+ const auto x_not_ = !false;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_ = !boost::hof::_1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_not_)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_not_)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_not_(false) == x_not_);
+
+ const auto x_not_0 = !0;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_0 = !boost::hof::_1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_not_0)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_not_0)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_not_0(0) == x_not_0);
+
+ const auto x_compl_ = ~2;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_compl_ = ~boost::hof::_1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_compl_)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_compl_)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_compl_(2) == x_compl_);
+
+ const auto x_unary_plus = +2;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_unary_plus = +boost::hof::_1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_unary_plus)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_unary_plus)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_unary_plus(2) == x_unary_plus);
+
+ const auto x_unary_subtract = -2;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_unary_subtract = -boost::hof::_1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_unary_subtract)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_unary_subtract)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_unary_subtract(2) == x_unary_subtract);
+
+ const auto x_dereference = 2;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_dereference = *boost::hof::_1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_dereference)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_dereference)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_dereference(&x_dereference) == x_dereference);
+
+ // TODO: Test BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR increment and decrement
+#ifndef _MSC_VER
+ auto x_increment = 2;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_increment = ++boost::hof::_1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_increment)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_increment)>::value, "Not default constructible");
+ f_increment(x_increment);
+ BOOST_HOF_TEST_CHECK(x_increment == 3);
+
+ auto x_decrement = 2;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_decrement = --boost::hof::_1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_decrement)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_decrement)>::value, "Not default constructible");
+ f_decrement(x_decrement);
+ BOOST_HOF_TEST_CHECK(x_decrement == 1);
+#endif
+
+ // TODO: Test post increment and decrement
+}
+
+
+BOOST_HOF_TEST_CASE()
+{
+ const auto x_add = 2 + 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_add = boost::hof::_ + boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_add)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_add)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_add(2, 1) == x_add);
+
+ const auto x_subtract = 2 - 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_subtract = boost::hof::_ - boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_subtract)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_subtract)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_subtract(2, 1) == x_subtract);
+
+ const auto x_multiply = 2 * 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_multiply = boost::hof::_ * boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_multiply)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_multiply)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_multiply(2, 1) == x_multiply);
+
+ const auto x_divide = 2 / 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_divide = boost::hof::_ / boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_divide)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_divide)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_divide(2, 1) == x_divide);
+
+ const auto x_remainder = 2 % 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_remainder = boost::hof::_ % boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_remainder)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_remainder)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_remainder(2, 1) == x_remainder);
+
+ const auto x_shift_right = 2 >> 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_right = boost::hof::_ >> boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_shift_right)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_shift_right)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_shift_right(2, 1) == x_shift_right);
+
+ const auto x_shift_left = 2 << 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_left = boost::hof::_ << boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_shift_left)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_shift_left)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_shift_left(2, 1) == x_shift_left);
+
+ const auto x_greater_than = 2 > 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than = boost::hof::_ > boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_greater_than)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_greater_than)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_greater_than(2, 1) == x_greater_than);
+
+ const auto x_less_than = 2 < 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than = boost::hof::_ < boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_less_than)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_less_than)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_less_than(2, 1) == x_less_than);
+
+ const auto x_less_than_equal = 2 <= 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than_equal = boost::hof::_ <= boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_less_than_equal)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_less_than_equal)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_less_than_equal(2, 1) == x_less_than_equal);
+
+ const auto x_greater_than_equal = 2 >= 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than_equal = boost::hof::_ >= boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_greater_than_equal)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_greater_than_equal)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_greater_than_equal(2, 1) == x_greater_than_equal);
+
+ const auto x_equal = 2 == 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_equal = boost::hof::_ == boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_equal)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_equal)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_equal(2, 1) == x_equal);
+
+ const auto x_not_equal = 2 != 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_equal = boost::hof::_ != boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_not_equal)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_not_equal)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_not_equal(2, 1) == x_not_equal);
+
+ const auto x_bit_and = 2 & 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_and = boost::hof::_ & boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_bit_and)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_bit_and)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_bit_and(2, 1) == x_bit_and);
+
+ const auto x_xor_ = 2 ^ 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_xor_ = boost::hof::_ ^ boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_xor_)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_xor_)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_xor_(2, 1) == x_xor_);
+
+ const auto x_bit_or = 2 | 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_or = boost::hof::_ | boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_bit_or)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_bit_or)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_bit_or(2, 1) == x_bit_or);
+
+ const auto x_and_ = true && false;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_and_ = boost::hof::_ && boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_and_)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_and_)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_and_(true, false) == x_and_);
+
+ const auto x_or_ = true;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_or_ = boost::hof::_ || boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_or_)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_or_)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_or_(true, false) == x_or_);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ const auto x_add = 2 + 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_add = 2 + boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_add)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_add)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_add(1) == x_add);
+
+ const auto x_subtract = 2 - 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_subtract = 2 - boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_subtract)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_subtract)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_subtract(1) == x_subtract);
+
+ const auto x_multiply = 2 * 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_multiply = 2 * boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_multiply)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_multiply)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_multiply(1) == x_multiply);
+
+ const auto x_divide = 2 / 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_divide = 2 / boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_divide)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_divide)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_divide(1) == x_divide);
+
+ const auto x_remainder = 2 % 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_remainder = 2 % boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_remainder)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_remainder)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_remainder(1) == x_remainder);
+
+ const auto x_shift_right = 2 >> 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_right = 2 >> boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_shift_right)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_shift_right)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_shift_right(1) == x_shift_right);
+
+ const auto x_shift_left = 2 << 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_left = 2 << boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_shift_left)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_shift_left)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_shift_left(1) == x_shift_left);
+
+ const auto x_greater_than = 2 > 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than = 2 > boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_greater_than)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_greater_than)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_greater_than(1) == x_greater_than);
+
+ const auto x_less_than = 2 < 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than = 2 < boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_less_than)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_less_than)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_less_than(1) == x_less_than);
+
+ const auto x_less_than_equal = 2 <= 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than_equal = 2 <= boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_less_than_equal)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_less_than_equal)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_less_than_equal(1) == x_less_than_equal);
+
+ const auto x_greater_than_equal = 2 >= 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than_equal = 2 >= boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_greater_than_equal)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_greater_than_equal)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_greater_than_equal(1) == x_greater_than_equal);
+
+ const auto x_equal = 2 == 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_equal = 2 == boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_equal)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_equal)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_equal(1) == x_equal);
+
+ const auto x_not_equal = 2 != 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_equal = 2 != boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_not_equal)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_not_equal)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_not_equal(1) == x_not_equal);
+
+ const auto x_bit_and = 2 & 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_and = 2 & boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_bit_and)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_bit_and)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_bit_and(1) == x_bit_and);
+
+ const auto x_xor_ = 2 ^ 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_xor_ = 2 ^ boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_xor_)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_xor_)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_xor_(1) == x_xor_);
+
+ const auto x_bit_or = 2 | 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_or = 2 | boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_bit_or)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_bit_or)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_bit_or(1) == x_bit_or);
+
+ const auto x_and_ = true && false;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_and_ = true && boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_and_)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_and_)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_and_(false) == x_and_);
+
+ const auto x_or_ = true;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_or_ = true || boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_or_)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_or_)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_or_(false) == x_or_);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ const auto x_add = 2 + 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_add = boost::hof::_ + 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_add)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_add)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_add(2) == x_add);
+
+ const auto x_subtract = 2 - 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_subtract = boost::hof::_ - 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_subtract)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_subtract)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_subtract(2) == x_subtract);
+
+ const auto x_multiply = 2 * 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_multiply = boost::hof::_ * 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_multiply)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_multiply)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_multiply(2) == x_multiply);
+
+ const auto x_divide = 2 / 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_divide = boost::hof::_ / 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_divide)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_divide)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_divide(2) == x_divide);
+
+ const auto x_remainder = 2 % 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_remainder = boost::hof::_ % 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_remainder)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_remainder)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_remainder(2) == x_remainder);
+
+ const auto x_shift_right = 2 >> 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_right = boost::hof::_ >> 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_shift_right)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_shift_right)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_shift_right(2) == x_shift_right);
+
+ const auto x_shift_left = 2 << 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_left = boost::hof::_ << 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_shift_left)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_shift_left)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_shift_left(2) == x_shift_left);
+
+ const auto x_greater_than = 2 > 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than = boost::hof::_ > 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_greater_than)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_greater_than)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_greater_than(2) == x_greater_than);
+
+ const auto x_less_than = 2 < 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than = boost::hof::_ < 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_less_than)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_less_than)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_less_than(2) == x_less_than);
+
+ const auto x_less_than_equal = 2 <= 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than_equal = boost::hof::_ <= 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_less_than_equal)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_less_than_equal)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_less_than_equal(2) == x_less_than_equal);
+
+ const auto x_greater_than_equal = 2 >= 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than_equal = boost::hof::_ >= 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_greater_than_equal)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_greater_than_equal)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_greater_than_equal(2) == x_greater_than_equal);
+
+ const auto x_equal = 2 == 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_equal = boost::hof::_ == 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_equal)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_equal)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_equal(2) == x_equal);
+
+ const auto x_not_equal = 2 != 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_equal = boost::hof::_ != 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_not_equal)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_not_equal)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_not_equal(2) == x_not_equal);
+
+ const auto x_bit_and = 2 & 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_and = boost::hof::_ & 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_bit_and)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_bit_and)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_bit_and(2) == x_bit_and);
+
+ const auto x_xor_ = 2 ^ 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_xor_ = boost::hof::_ ^ 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_xor_)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_xor_)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_xor_(2) == x_xor_);
+
+ const auto x_bit_or = 2 | 1;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_or = boost::hof::_ | 1;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_bit_or)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_bit_or)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_bit_or(2) == x_bit_or);
+
+ const auto x_and_ = true && false;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_and_ = boost::hof::_ && false;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_and_)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_and_)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_and_(true) == x_and_);
+
+ const auto x_or_ = true;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_or_ = boost::hof::_ || false;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_or_)>::value, "Not copyable");
+#endif
+ static_assert(!boost::hof::detail::is_default_constructible<decltype(f_or_)>::value, "default constructible");
+ PLACEHOLDER_CHECK(f_or_(true) == x_or_);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+
+ const auto x_not_ = !false;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_ = !boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_not_)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_not_)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_not_(false) == x_not_);
+
+ const auto x_compl_ = ~2;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_compl_ = ~boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_compl_)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_compl_)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_compl_(2) == x_compl_);
+
+ const auto x_unary_plus = +2;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_unary_plus = +boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_unary_plus)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_unary_plus)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_unary_plus(2) == x_unary_plus);
+
+ const auto x_unary_subtract = -2;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_unary_subtract = -boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_unary_subtract)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_unary_subtract)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_unary_subtract(2) == x_unary_subtract);
+
+ const auto x_dereference = 2;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_dereference = *boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_dereference)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_dereference)>::value, "Not default constructible");
+ PLACEHOLDER_CHECK(f_dereference(&x_dereference) == x_dereference);
+
+ // TODO: Test constexpr increment and decrement
+#ifndef _MSC_VER
+ auto x_increment = 2;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_increment = ++boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_increment)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_increment)>::value, "Not default constructible");
+ f_increment(x_increment);
+ BOOST_HOF_TEST_CHECK(x_increment == 3);
+
+ auto x_decrement = 2;
+ BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_decrement = --boost::hof::_;
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6
+ static_assert(std::is_copy_constructible<decltype(f_decrement)>::value, "Not copyable");
+#endif
+ static_assert(boost::hof::detail::is_default_constructible<decltype(f_decrement)>::value, "Not default constructible");
+ f_decrement(x_decrement);
+ BOOST_HOF_TEST_CHECK(x_decrement == 1);
+#endif
+
+ // TODO: Test post increment and decrement
+}
+
diff --git a/src/boost/libs/hof/test/proj.cpp b/src/boost/libs/hof/test/proj.cpp
new file mode 100644
index 000000000..c544fc4bd
--- /dev/null
+++ b/src/boost/libs/hof/test/proj.cpp
@@ -0,0 +1,164 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ proj.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/proj.hpp>
+#include <boost/hof/placeholders.hpp>
+#include <boost/hof/mutable.hpp>
+#include "test.hpp"
+
+#include <memory>
+
+struct foo
+{
+ constexpr foo(int xp) : x(xp)
+ {}
+ int x;
+};
+
+struct select_x
+{
+ template<class T>
+ constexpr auto operator()(T&& x) const BOOST_HOF_RETURNS(x.x);
+};
+
+BOOST_HOF_TEST_CASE()
+{
+#ifndef _MSC_VER
+ constexpr
+#endif
+ auto add = boost::hof::_ + boost::hof::_;
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::proj(select_x(), add)(foo(1), foo(2)) == 3);
+ // Using mutable_ as a workaround on libc++, since mem_fn does not meet the
+ // requirements of a FunctionObject
+ BOOST_HOF_TEST_CHECK(boost::hof::proj(boost::hof::mutable_(std::mem_fn(&foo::x)), add)(foo(1), foo(2)) == 3);
+ static_assert(boost::hof::detail::is_default_constructible<decltype(boost::hof::proj(select_x(), add))>::value, "Not default constructible");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+#ifndef _MSC_VER
+ constexpr
+#endif
+ auto add = boost::hof::_ + boost::hof::_;
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::proj(select_x(), add)(foo(1), foo(2)) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::proj(&foo::x, add)(foo(1), foo(2)) == 3);
+ static_assert(boost::hof::detail::is_default_constructible<decltype(boost::hof::proj(select_x(), add))>::value, "Not default constructible");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto indirect_add = boost::hof::proj(*boost::hof::_, boost::hof::_ + boost::hof::_);
+ BOOST_HOF_TEST_CHECK(indirect_add(std::unique_ptr<int>(new int(1)), std::unique_ptr<int>(new int(2))) == 3);
+ static_assert(boost::hof::detail::is_default_constructible<decltype(indirect_add)>::value, "Not default constructible");
+}
+
+struct select_x_1
+{
+ std::unique_ptr<int> i;
+ select_x_1() : i(new int(2))
+ {}
+ template<class T>
+ auto operator()(T&& x) const BOOST_HOF_RETURNS(x.x * (*i));
+};
+
+struct sum_1
+{
+ std::unique_ptr<int> i;
+ sum_1() : i(new int(1))
+ {}
+ template<class T, class U>
+ auto operator()(T&& x, U&& y) const BOOST_HOF_RETURNS(x + y + *i);
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::proj(select_x_1(), sum_1())(foo(1), foo(2)) == 7);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ std::string s;
+ auto f = [&](const std::string& x)
+ {
+ s += x;
+ };
+ boost::hof::proj(f)("hello", "-", "world");
+ BOOST_HOF_TEST_CHECK(s == "hello-world");
+ boost::hof::proj(f)();
+ BOOST_HOF_TEST_CHECK(s == "hello-world");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ std::string s;
+ auto f = [&](const std::string& x)
+ {
+ s += x;
+ return s;
+ };
+ auto last = [](const std::string& x, const std::string& y, const std::string& z)
+ {
+ BOOST_HOF_TEST_CHECK(x == "hello");
+ BOOST_HOF_TEST_CHECK(y == "hello-");
+ BOOST_HOF_TEST_CHECK(z == "hello-world");
+ return z;
+ };
+ BOOST_HOF_TEST_CHECK(boost::hof::proj(f, last)("hello", "-", "world") == "hello-world");
+}
+
+template<bool B>
+struct bool_
+{
+ static const bool value = B;
+};
+
+struct constexpr_check
+{
+ template<class T>
+ constexpr int operator()(T) const
+ {
+ static_assert(T::value, "Failed");
+ return 0;
+ }
+};
+
+struct constexpr_check_each
+{
+ template<class T>
+ constexpr bool operator()(T x) const
+ {
+ return boost::hof::proj(constexpr_check())(x, x), true;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(constexpr_check_each()(bool_<true>()));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ boost::hof::proj(boost::hof::identity, boost::hof::identity)(0);
+}
+
+struct bar {};
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::proj(bar{});
+ static_assert(!boost::hof::is_invocable<decltype(f), int>::value, "Not sfinae friendly");
+ static_assert(!boost::hof::is_invocable<decltype(f), int, int>::value, "Not sfinae friendly");
+ static_assert(!boost::hof::is_invocable<decltype(f), int, int, int>::value, "Not sfinae friendly");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::proj(bar{}, bar{});
+ static_assert(!boost::hof::is_invocable<decltype(f), int>::value, "Not sfinae friendly");
+ static_assert(!boost::hof::is_invocable<decltype(f), int, int>::value, "Not sfinae friendly");
+ static_assert(!boost::hof::is_invocable<decltype(f), int, int, int>::value, "Not sfinae friendly");
+ static_assert(!boost::hof::is_invocable<decltype(f)>::value, "Not sfinae friendly");
+}
diff --git a/src/boost/libs/hof/test/protect.cpp b/src/boost/libs/hof/test/protect.cpp
new file mode 100644
index 000000000..3059572d1
--- /dev/null
+++ b/src/boost/libs/hof/test/protect.cpp
@@ -0,0 +1,302 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ protect.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/protect.hpp>
+#include <boost/hof/lazy.hpp>
+#include <boost/hof/placeholders.hpp>
+#include <memory>
+#include "test.hpp"
+
+#include <boost/hof/function.hpp>
+
+int f(int x)
+{
+ return x;
+}
+
+int& g(int& x)
+{
+ return x;
+}
+
+template<class T>
+const T& constify(const T& arg)
+{
+ return arg;
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ int i[9] = {0,1,2,3,4,5,6,7,8};
+
+ // non-const
+
+ // test nullary
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(1))() == 1);
+
+ // test lvalues
+
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0]) == &i[0]);
+
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1]) == &i[1]);
+
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2]) == &i[2]);
+
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2], i[3]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2], i[3]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2], i[3]) == &i[2]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4))(i[0], i[1], i[2], i[3]) == &i[3]);
+
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2], i[3], i[4]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2], i[3], i[4]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2], i[3], i[4]) == &i[2]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4))(i[0], i[1], i[2], i[3], i[4]) == &i[3]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5))(i[0], i[1], i[2], i[3], i[4]) == &i[4]);
+
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[2]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[3]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[4]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[5]);
+
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[2]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[3]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[4]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[5]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_7))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[6]);
+
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[2]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[3]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[4]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[5]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_7))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[6]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_8))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[7]);
+
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[2]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[3]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[4]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[5]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_7))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[6]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_8))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[7]);
+ BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_9))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[8]);
+
+ // test rvalues
+
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0) == 0);
+
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1) == 0);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1) == 1);
+
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2) == 0);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2) == 2);
+
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2, 3) == 0);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2, 3) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2, 3) == 2);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4))(0, 1, 2, 3) == 3);
+
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2, 3, 4) == 0);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2, 3, 4) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2, 3, 4) == 2);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4))(0, 1, 2, 3, 4) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5))(0, 1, 2, 3, 4) == 4);
+
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2, 3, 4, 5) == 0);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2, 3, 4, 5) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2, 3, 4, 5) == 2);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4))(0, 1, 2, 3, 4, 5) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5))(0, 1, 2, 3, 4, 5) == 4);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6))(0, 1, 2, 3, 4, 5) == 5);
+
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2, 3, 4, 5, 6) == 0);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2, 3, 4, 5, 6) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2, 3, 4, 5, 6) == 2);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4))(0, 1, 2, 3, 4, 5, 6) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5))(0, 1, 2, 3, 4, 5, 6) == 4);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6))(0, 1, 2, 3, 4, 5, 6) == 5);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_7))(0, 1, 2, 3, 4, 5, 6) == 6);
+
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2, 3, 4, 5, 6, 7) == 0);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2, 3, 4, 5, 6, 7) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2, 3, 4, 5, 6, 7) == 2);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4))(0, 1, 2, 3, 4, 5, 6, 7) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5))(0, 1, 2, 3, 4, 5, 6, 7) == 4);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6))(0, 1, 2, 3, 4, 5, 6, 7) == 5);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_7))(0, 1, 2, 3, 4, 5, 6, 7) == 6);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_8))(0, 1, 2, 3, 4, 5, 6, 7) == 7);
+
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 0);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 2);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 3);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 4);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 5);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_7))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 6);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_8))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 7);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_9))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 8);
+
+ // test mixed perfect forwarding
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(i[0], 1) == 0);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(i[0], 1) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, i[1]) == 0);
+ BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, i[1]) == 1);
+
+ // const
+
+ // test nullary
+ BOOST_HOF_TEST_CHECK(constify(constify(boost::hof::protect(boost::hof::lazy(f)(1))))() == 1);
+
+ // test lvalues
+ BOOST_HOF_TEST_CHECK(&constify(constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))))(i[0]) == &i[0]);
+
+ BOOST_HOF_TEST_CHECK(&constify(constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))))(i[0], i[1]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&constify(constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))))(i[0], i[1]) == &i[1]);
+
+ BOOST_HOF_TEST_CHECK(&constify(constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))))(i[0], i[1], i[2]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&constify(constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))))(i[0], i[1], i[2]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&constify(constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))))(i[0], i[1], i[2]) == &i[2]);
+
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1)))(i[0], i[1], i[2], i[3]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2)))(i[0], i[1], i[2], i[3]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3)))(i[0], i[1], i[2], i[3]) == &i[2]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4)))(i[0], i[1], i[2], i[3]) == &i[3]);
+
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1)))(i[0], i[1], i[2], i[3], i[4]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2)))(i[0], i[1], i[2], i[3], i[4]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3)))(i[0], i[1], i[2], i[3], i[4]) == &i[2]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4)))(i[0], i[1], i[2], i[3], i[4]) == &i[3]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5)))(i[0], i[1], i[2], i[3], i[4]) == &i[4]);
+
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[2]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[3]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[4]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[5]);
+
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[2]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[3]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[4]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[5]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_7)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[6]);
+
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[2]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[3]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[4]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[5]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_7)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[6]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_8)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[7]);
+
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[0]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[1]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[2]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[3]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[4]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[5]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_7)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[6]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_8)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[7]);
+ BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_9)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[8]);
+
+ // test rvalues
+
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0) == 0);
+
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1) == 0);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1) == 1);
+
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2) == 0);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2) == 1);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2) == 2);
+
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2, 3) == 0);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2, 3) == 1);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2, 3) == 2);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4)))(0, 1, 2, 3) == 3);
+
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2, 3, 4) == 0);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2, 3, 4) == 1);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2, 3, 4) == 2);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4)))(0, 1, 2, 3, 4) == 3);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5)))(0, 1, 2, 3, 4) == 4);
+
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2, 3, 4, 5) == 0);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2, 3, 4, 5) == 1);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2, 3, 4, 5) == 2);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4)))(0, 1, 2, 3, 4, 5) == 3);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5)))(0, 1, 2, 3, 4, 5) == 4);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6)))(0, 1, 2, 3, 4, 5) == 5);
+
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2, 3, 4, 5, 6) == 0);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2, 3, 4, 5, 6) == 1);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2, 3, 4, 5, 6) == 2);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4)))(0, 1, 2, 3, 4, 5, 6) == 3);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5)))(0, 1, 2, 3, 4, 5, 6) == 4);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6)))(0, 1, 2, 3, 4, 5, 6) == 5);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_7)))(0, 1, 2, 3, 4, 5, 6) == 6);
+
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2, 3, 4, 5, 6, 7) == 0);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2, 3, 4, 5, 6, 7) == 1);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2, 3, 4, 5, 6, 7) == 2);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4)))(0, 1, 2, 3, 4, 5, 6, 7) == 3);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5)))(0, 1, 2, 3, 4, 5, 6, 7) == 4);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6)))(0, 1, 2, 3, 4, 5, 6, 7) == 5);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_7)))(0, 1, 2, 3, 4, 5, 6, 7) == 6);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_8)))(0, 1, 2, 3, 4, 5, 6, 7) == 7);
+
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 0);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 1);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 2);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 3);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 4);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 5);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_7)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 6);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_8)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 7);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_9)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 8);
+
+ // test mixed perfect forwarding
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(i[0], 1) == 0);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(i[0], 1) == 1);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, i[1]) == 0);
+ BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, i[1]) == 1);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::lazy(boost::hof::apply)(boost::hof::protect(boost::hof::lazy(boost::hof::identity)(boost::hof::_1)), boost::hof::_1)(17) == 17);
+ BOOST_HOF_TEST_CHECK(boost::hof::lazy(boost::hof::apply)(boost::hof::protect(boost::hof::lazy(boost::hof::identity)(boost::hof::_1)), 17)() == 17);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::lazy(boost::hof::apply)(boost::hof::protect(boost::hof::lazy(boost::hof::identity)(boost::hof::_1)), boost::hof::_1)(17) == 17);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::lazy(boost::hof::apply)(boost::hof::protect(boost::hof::lazy(boost::hof::identity)(boost::hof::_1)), 17)() == 17);
+}
+
+namespace test1 {
+
+int id(int x)
+{
+ return x;
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::lazy(boost::hof::apply)(boost::hof::protect(boost::hof::lazy(id)(std::placeholders::_1)), std::placeholders::_1)(17) == 17);
+ BOOST_HOF_TEST_CHECK(boost::hof::lazy(boost::hof::apply)(boost::hof::protect(boost::hof::lazy(id)(std::placeholders::_1)), 17)() == 17);
+}
+
+}
diff --git a/src/boost/libs/hof/test/repeat.cpp b/src/boost/libs/hof/test/repeat.cpp
new file mode 100644
index 000000000..19b3b51d7
--- /dev/null
+++ b/src/boost/libs/hof/test/repeat.cpp
@@ -0,0 +1,66 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ repeat.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/repeat.hpp>
+#include <limits>
+#include "test.hpp"
+
+// TODO: Add tests for multiple parameters
+
+struct increment
+{
+ template<class T>
+ constexpr T operator()(T x) const noexcept
+ {
+ return x + 1;
+ }
+};
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::repeat(std::integral_constant<int, 5>())(increment())(1)), "noexcept repeat");
+ static_assert(noexcept(boost::hof::repeat(5)(increment())(1)), "noexcept repeat");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::repeat(std::integral_constant<int, 5>())(increment())(1) == 6);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::repeat(std::integral_constant<int, 5>())(increment())(1) == 6);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::repeat(5)(increment())(1) == 6);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::repeat(5)(increment())(1) == 6);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ int i = 5;
+ BOOST_HOF_TEST_CHECK(boost::hof::repeat(i)(increment())(1) == 6);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ static const int i = 5;
+ BOOST_HOF_TEST_CHECK(boost::hof::repeat(i)(increment())(1) == 6);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::repeat(i)(increment())(1) == 6);
+}
+
+// BOOST_HOF_TEST_CASE()
+// {
+// BOOST_HOF_TEST_CHECK(boost::hof::repeat(std::numeric_limits<int>::max()/4)(increment())(0) == std::numeric_limits<int>::max()/4);
+// }
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::repeat(BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4)(increment())(0) == BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4);
+#if BOOST_HOF_HAS_RELAXED_CONSTEXPR
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::repeat(BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4)(increment())(0) == BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4);
+#endif
+}
diff --git a/src/boost/libs/hof/test/repeat_while.cpp b/src/boost/libs/hof/test/repeat_while.cpp
new file mode 100644
index 000000000..3b1d9fc1f
--- /dev/null
+++ b/src/boost/libs/hof/test/repeat_while.cpp
@@ -0,0 +1,95 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ repeat_while.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/repeat_while.hpp>
+#include <boost/hof/reveal.hpp>
+#include "test.hpp"
+
+// TODO: Test default construction, and static initialization
+
+struct increment_constant
+{
+ template<class T>
+ constexpr std::integral_constant<int, T::value + 1> operator()(T) const noexcept
+ {
+ return std::integral_constant<int, T::value + 1>();
+ }
+};
+
+struct increment
+{
+ template<class T>
+ constexpr T operator()(T x) const noexcept
+ {
+ return x + 1;
+ }
+};
+
+struct not_6_constant
+{
+ template<class T>
+ constexpr std::integral_constant<bool, (T::value != 6)>
+ operator()(T) const noexcept
+ {
+ return std::integral_constant<bool, (T::value != 6)>();
+ }
+};
+
+struct not_6
+{
+ template<class T>
+ constexpr bool operator()(T x) const noexcept
+ {
+ return x != 6;
+ }
+};
+
+struct not_limit
+{
+ template<class T>
+ constexpr bool operator()(T x) const
+ {
+ return x != (BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4);
+ }
+};
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::repeat_while(not_6())(increment())(1)), "noexcept repeat_while");
+ static_assert(noexcept(boost::hof::repeat_while(not_6_constant())(increment_constant())(std::integral_constant<int, 1>())), "noexcept repeat_while");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ static_assert
+ (
+ std::is_same<
+ std::integral_constant<int, 6>,
+ decltype(boost::hof::repeat_while(not_6_constant())(increment_constant())(std::integral_constant<int, 1>()))
+ >::value,
+ "Error"
+ );
+
+ std::integral_constant<int, 6> x = boost::hof::repeat_while(not_6_constant())(increment_constant())(std::integral_constant<int, 1>());
+ boost::hof::test::unused(x);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::repeat_while(not_6())(increment())(1) == 6);
+ BOOST_HOF_TEST_CHECK(boost::hof::repeat_while(not_6())(increment())(1) == 6);
+ BOOST_HOF_TEST_CHECK(boost::hof::reveal(boost::hof::repeat_while(not_6())(increment()))(1) == 6);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::repeat_while(not_limit())(increment())(1) == BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4);
+#if BOOST_HOF_HAS_RELAXED_CONSTEXPR
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::repeat_while(not_limit())(increment())(1) == BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4);
+#endif
+}
diff --git a/src/boost/libs/hof/test/result.cpp b/src/boost/libs/hof/test/result.cpp
new file mode 100644
index 000000000..cae0bb78d
--- /dev/null
+++ b/src/boost/libs/hof/test/result.cpp
@@ -0,0 +1,26 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ result.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/result.hpp>
+#include <boost/hof/static.hpp>
+#include "test.hpp"
+
+
+static constexpr boost::hof::result_adaptor<int, unary_class> unary_int = {};
+
+BOOST_HOF_TEST_CASE()
+{
+ STATIC_ASSERT_SAME(decltype(unary_int(false)), int);
+ BOOST_HOF_TEST_CHECK(unary_int(false) == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(unary_int(false) == 0);
+}
+
+static constexpr boost::hof::result_adaptor<void, unary_class> unary_void = {};
+
+BOOST_HOF_TEST_CASE()
+{
+ STATIC_ASSERT_SAME(decltype(unary_void(false)), void);
+}
diff --git a/src/boost/libs/hof/test/returns.cpp b/src/boost/libs/hof/test/returns.cpp
new file mode 100644
index 000000000..aec77819b
--- /dev/null
+++ b/src/boost/libs/hof/test/returns.cpp
@@ -0,0 +1,56 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ returns.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/returns.hpp>
+#include "test.hpp"
+
+#if !defined (__GNUC__) || defined (__clang__)
+struct add_1
+{
+ int a;
+ add_1() : a(1) {}
+
+ BOOST_HOF_RETURNS_CLASS(add_1);
+
+ template<class T>
+ auto operator()(T x) const
+ BOOST_HOF_RETURNS(x+BOOST_HOF_CONST_THIS->a);
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == add_1()(2));
+}
+#endif
+// TODO: check noexcept
+struct id
+{
+ template<class T>
+ constexpr auto operator()(T x) const BOOST_HOF_RETURNS
+ (x);
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(id{}(3) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(id{}(3) == 3);
+}
+
+struct void_ {};
+constexpr void_ no_op() { return void_{}; }
+
+struct id_comma
+{
+ template<class T>
+ constexpr auto operator()(T&& x) const BOOST_HOF_RETURNS
+ (no_op(), boost::hof::forward<T>(x));
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(id_comma{}(3) == 3);
+ BOOST_HOF_STATIC_TEST_CHECK(id_comma{}(3) == 3);
+}
diff --git a/src/boost/libs/hof/test/reveal.cpp b/src/boost/libs/hof/test/reveal.cpp
new file mode 100644
index 000000000..9e7014d26
--- /dev/null
+++ b/src/boost/libs/hof/test/reveal.cpp
@@ -0,0 +1,157 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ reveal.cpp
+ 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)
+==============================================================================*/
+#include "test.hpp"
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/static.hpp>
+#include <boost/hof/lambda.hpp>
+#include <boost/hof/fix.hpp>
+
+namespace reveal_test {
+
+#define CONDITIONAL_FUNCTION(n) \
+struct t ## n {}; \
+struct f ## n \
+{ \
+ constexpr int operator()(t ## n) const \
+ { \
+ return n; \
+ } \
+};
+
+CONDITIONAL_FUNCTION(1)
+CONDITIONAL_FUNCTION(2)
+CONDITIONAL_FUNCTION(3)
+
+typedef boost::hof::first_of_adaptor<f1, f2, f3> f_type;
+static constexpr boost::hof::static_<f_type> f = {};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::reveal(f)(t1()) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::reveal(f)(t2()) == 2);
+ BOOST_HOF_TEST_CHECK(boost::hof::reveal(f)(t3()) == 3);
+
+
+ static_assert(boost::hof::is_invocable<boost::hof::reveal_adaptor<f_type>, t1>::value, "Invocable");
+ static_assert(boost::hof::is_invocable<boost::hof::reveal_adaptor<f_type>, t2>::value, "Invocable");
+ static_assert(boost::hof::is_invocable<boost::hof::reveal_adaptor<f_type>, t3>::value, "Invocable");
+
+ static_assert(!boost::hof::is_invocable<boost::hof::reveal_adaptor<f_type>, int>::value, "Invocable");
+ // boost::hof::reveal(f)(1);
+}
+
+#ifndef _MSC_VER
+static constexpr auto lam = boost::hof::first_of(
+ BOOST_HOF_STATIC_LAMBDA(t1)
+ {
+ return 1;
+ },
+ BOOST_HOF_STATIC_LAMBDA(t2)
+ {
+ return 2;
+ },
+ BOOST_HOF_STATIC_LAMBDA(t3)
+ {
+ return 3;
+ }
+);
+
+BOOST_HOF_TEST_CASE()
+{
+ STATIC_ASSERT_EMPTY(lam);
+ STATIC_ASSERT_EMPTY(boost::hof::reveal(lam));
+ BOOST_HOF_TEST_CHECK(boost::hof::reveal(lam)(t1()) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::reveal(lam)(t2()) == 2);
+ BOOST_HOF_TEST_CHECK(boost::hof::reveal(lam)(t3()) == 3);
+
+ // boost::hof::reveal(lam)(1);
+ // lam(1);
+}
+#endif
+
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(static_fun) = boost::hof::first_of(
+ [](t1)
+ {
+ return 1;
+ },
+ [](t2)
+ {
+ return 2;
+ },
+ [](t3)
+ {
+ return 3;
+ }
+);
+
+BOOST_HOF_TEST_CASE()
+{
+#ifndef _MSC_VER
+ STATIC_ASSERT_EMPTY(static_fun);
+ // STATIC_ASSERT_EMPTY(boost::hof::reveal(static_fun));
+#endif
+ BOOST_HOF_TEST_CHECK(boost::hof::reveal(static_fun)(t1()) == 1);
+ BOOST_HOF_TEST_CHECK(boost::hof::reveal(static_fun)(t2()) == 2);
+ BOOST_HOF_TEST_CHECK(boost::hof::reveal(static_fun)(t3()) == 3);
+
+ BOOST_HOF_TEST_CHECK(static_fun(t1()) == 1);
+ BOOST_HOF_TEST_CHECK(static_fun(t2()) == 2);
+ BOOST_HOF_TEST_CHECK(static_fun(t3()) == 3);
+
+ // boost::hof::reveal(static_fun)(1);
+}
+
+struct integral_type
+{
+ template<class T>
+ BOOST_HOF_USING_TYPENAME(failure_alias, std::enable_if<std::is_integral<T>::value>::type);
+
+ struct failure
+ : boost::hof::as_failure<failure_alias>
+ {};
+
+ template<class T, class=typename std::enable_if<std::is_integral<T>::value>::type>
+ constexpr T operator()(T x) const
+ {
+ return x;
+ }
+};
+struct foo {};
+struct dont_catch {};
+
+struct catch_all
+{
+ template<class T>
+ BOOST_HOF_USING_TYPENAME(failure_alias, std::enable_if<!std::is_same<T, dont_catch>::value>::type);
+
+ struct failure
+ : boost::hof::as_failure<failure_alias>
+ {};
+
+ template<class T, class=typename std::enable_if<!std::is_same<T, dont_catch>::value>::type>
+ constexpr int operator()(T) const
+ {
+ return -1;
+ }
+};
+
+static constexpr boost::hof::reveal_adaptor<boost::hof::first_of_adaptor<integral_type, catch_all>> check_failure = {};
+
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(check_failure(5) == 5);
+ BOOST_HOF_TEST_CHECK(check_failure(foo()) == -1);
+
+ static_assert(!boost::hof::is_invocable<decltype(check_failure), dont_catch>::value, "Invocable");
+ static_assert(!boost::hof::is_invocable<decltype(check_failure), int, int>::value, "Invocable");
+
+ // check_failure(dont_catch());
+}
+
+}
diff --git a/src/boost/libs/hof/test/reverse_fold.cpp b/src/boost/libs/hof/test/reverse_fold.cpp
new file mode 100644
index 000000000..9238e433e
--- /dev/null
+++ b/src/boost/libs/hof/test/reverse_fold.cpp
@@ -0,0 +1,93 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ reverse_fold.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/reverse_fold.hpp>
+#include "test.hpp"
+
+struct max_f
+{
+ template<class T, class U>
+ constexpr T operator()(T x, U y) const noexcept
+ {
+ return x > y ? x : y;
+ }
+};
+
+struct sum_f
+{
+ template<class T, class U>
+ constexpr T operator()(T x, U y) const BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(x+y)
+ {
+ return x + y;
+ }
+};
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::reverse_fold(max_f(), 0)(2, 3, 4, 5)), "noexcept reverse_fold");
+ static_assert(noexcept(boost::hof::reverse_fold(sum_f(), 0)(2, 3, 4, 5)), "noexcept reverse_fold");
+ static_assert(!noexcept(boost::hof::reverse_fold(sum_f(), std::string())("hello", "-", "world")), "noexcept reverse_fold");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(2, 3, 4, 5) == 5);
+ BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(5, 4, 3, 2) == 5);
+ BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(2, 3, 5, 4) == 5);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(2, 3, 4, 5) == 5);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(5, 4, 3, 2) == 5);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(2, 3, 5, 4) == 5);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)() == 0);
+ BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(5) == 5);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)() == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(5) == 5);
+}
+
+template<class... Ts>
+constexpr auto find_positive_max(Ts... xs) BOOST_HOF_RETURNS
+(
+ boost::hof::reverse_fold(max_f(), 0)(xs...)
+);
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(find_positive_max() == 0);
+ BOOST_HOF_TEST_CHECK(find_positive_max(5) == 5);
+
+ BOOST_HOF_STATIC_TEST_CHECK(find_positive_max() == 0);
+ BOOST_HOF_STATIC_TEST_CHECK(find_positive_max(5) == 5);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f())(5) == 5);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f())(5) == 5);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f())(2, 3, 4, 5) == 5);
+ BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f())(5, 4, 3, 2) == 5);
+ BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f())(2, 3, 5, 4) == 5);
+
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f())(2, 3, 4, 5) == 5);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f())(5, 4, 3, 2) == 5);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f())(2, 3, 5, 4) == 5);
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(sum_f(), std::string())("hello", "-", "world") == "world-hello");
+}
diff --git a/src/boost/libs/hof/test/rotate.cpp b/src/boost/libs/hof/test/rotate.cpp
new file mode 100644
index 000000000..13f15806d
--- /dev/null
+++ b/src/boost/libs/hof/test/rotate.cpp
@@ -0,0 +1,71 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ rotate.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/rotate.hpp>
+#include <boost/hof/placeholders.hpp>
+#include <boost/hof/compose.hpp>
+#include <boost/hof/repeat.hpp>
+#include "test.hpp"
+
+struct head
+{
+ template<class T, class... Ts>
+ constexpr T operator()(T x, Ts&&...) const
+ BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(x)
+ {
+ return x;
+ }
+};
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::rotate(head{})(1, 2, 3, 4)), "noexcept rotate");
+ static_assert(noexcept(boost::hof::repeat(std::integral_constant<int, 5>{})(boost::hof::rotate)(head{})(1, 2, 3, 4, 5, 6, 7, 8, 9)), "noexcept rotate");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(2 == boost::hof::rotate(head{})(1, 2, 3, 4));
+ BOOST_HOF_STATIC_TEST_CHECK(2 == boost::hof::rotate(head{})(1, 2, 3, 4));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::compose(boost::hof::rotate, boost::hof::rotate)(head{})(1, 2, 3, 4));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::compose(boost::hof::rotate, boost::hof::rotate)(head{})(1, 2, 3, 4));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(6 == boost::hof::repeat(std::integral_constant<int, 5>{})(boost::hof::rotate)(head{})(1, 2, 3, 4, 5, 6, 7, 8, 9));
+ BOOST_HOF_STATIC_TEST_CHECK(6 == boost::hof::repeat(std::integral_constant<int, 5>{})(boost::hof::rotate)(head{})(1, 2, 3, 4, 5, 6, 7, 8, 9));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::rotate(boost::hof::_ - boost::hof::_)(2, 5));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::rotate(boost::hof::_ - boost::hof::_)(2, 5));
+}
+
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define FINAL
+#else
+#define FINAL final
+#endif
+
+
+struct f FINAL {
+ int operator()(int i, void *) const {
+ return i;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::rotate(f())(nullptr, 2) == 2);
+}
diff --git a/src/boost/libs/hof/test/static.cpp b/src/boost/libs/hof/test/static.cpp
new file mode 100644
index 000000000..f718dd404
--- /dev/null
+++ b/src/boost/libs/hof/test/static.cpp
@@ -0,0 +1,24 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ static.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/static.hpp>
+#include "test.hpp"
+
+// TODO: Test infix
+
+static constexpr boost::hof::static_<binary_class> binary_static = {};
+
+static constexpr boost::hof::static_<void_class> void_static = {};
+
+static constexpr boost::hof::static_<mono_class> mono_static = {};
+
+
+BOOST_HOF_TEST_CASE()
+{
+ void_static(1);
+ BOOST_HOF_TEST_CHECK(3 == binary_static(1, 2));
+ BOOST_HOF_TEST_CHECK(3 == mono_static(2));
+}
diff --git a/src/boost/libs/hof/test/static_def/static_def.cpp b/src/boost/libs/hof/test/static_def/static_def.cpp
new file mode 100644
index 000000000..83e9c7978
--- /dev/null
+++ b/src/boost/libs/hof/test/static_def/static_def.cpp
@@ -0,0 +1,59 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ static_def.cpp
+ 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)
+==============================================================================*/
+
+#include <cstdio>
+#include "static_def.hpp"
+
+extern int f();
+
+extern void* f_sum_lambda_addr();
+extern void* f_sum_fo_addr();
+
+extern void* sum_lambda_addr();
+extern void* sum_fo_addr();
+
+extern void* f_sum_var_addr();
+extern void* f_sum_constexpr_fo_addr();
+
+extern void* sum_var_addr();
+extern void* sum_constexpr_fo_addr();
+
+void* sum_lambda_addr()
+{
+ return (void*)&fit_test::fit_sum_lambda;
+}
+void* sum_fo_addr()
+{
+ return (void*)&fit_test::fit_sum_fo;
+}
+
+void* sum_var_addr()
+{
+ return (void*)&fit_test::fit_sum_var;
+}
+void* sum_constexpr_fo_addr()
+{
+ return (void*)&fit_test::fit_sum_constexpr_fo;
+}
+
+int main()
+{
+ if (fit_test::fit_sum_fo(1, 2) != 3) printf("FAILED\n");
+ if (fit_test::fit_sum_lambda(1, 2) != 3) printf("FAILED\n");
+ if (fit_test::fit_sum(1, 2) != 3) printf("FAILED\n");
+
+#if BOOST_HOF_HAS_UNIQUE_STATIC_LAMBDA_FUNCTION_ADDR
+ if (sum_lambda_addr() != f_sum_lambda_addr()) printf("FAILED: Lambda\n");
+ if (sum_fo_addr() != f_sum_fo_addr()) printf("FAILED: Function object\n");
+#endif
+
+#if BOOST_HOF_HAS_UNIQUE_STATIC_VAR
+ if (sum_var_addr() != f_sum_var_addr()) printf("FAILED: Lambda\n");
+ if (sum_constexpr_fo_addr() != f_sum_constexpr_fo_addr()) printf("FAILED: Function object\n");
+#endif
+ return f();
+}
diff --git a/src/boost/libs/hof/test/static_def/static_def.hpp b/src/boost/libs/hof/test/static_def/static_def.hpp
new file mode 100644
index 000000000..10574c64d
--- /dev/null
+++ b/src/boost/libs/hof/test/static_def/static_def.hpp
@@ -0,0 +1,61 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ static_def.hpp
+ 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)
+==============================================================================*/
+
+#ifndef GUARD_STATIC_DEF
+#define GUARD_STATIC_DEF
+
+#include <boost/hof/function.hpp>
+#include <boost/hof/lambda.hpp>
+
+// MSVC seems to not support unique addressing at all
+#if defined (_MSC_VER)
+#define BOOST_HOF_HAS_UNIQUE_STATIC_VAR 0
+#define BOOST_HOF_HAS_UNIQUE_STATIC_LAMBDA_FUNCTION_ADDR 0
+// Gcc 4.6 only supports unique addressing for non-lambdas
+#elif defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define BOOST_HOF_HAS_UNIQUE_STATIC_VAR 1
+#define BOOST_HOF_HAS_UNIQUE_STATIC_LAMBDA_FUNCTION_ADDR 0
+#else
+#define BOOST_HOF_HAS_UNIQUE_STATIC_VAR 1
+#define BOOST_HOF_HAS_UNIQUE_STATIC_LAMBDA_FUNCTION_ADDR 1
+#endif
+
+namespace fit_test {
+
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(fit_sum_lambda) = [](int x, int y)
+{
+ return x + y;
+};
+
+struct fit_sum_f
+{
+ constexpr int operator()(int x, int y) const
+ {
+ return x + y;
+ }
+};
+
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(fit_sum_fo) = fit_sum_f();
+
+BOOST_HOF_STATIC_FUNCTION(fit_sum_constexpr_fo) = fit_sum_f();
+
+BOOST_HOF_DECLARE_STATIC_VAR(fit_sum_var, fit_sum_f);
+
+// BOOST_HOF_STATIC_FUNCTION(fit_sum) = [](auto x, auto y)
+// {
+// return x + y;
+// };
+
+template<class T>
+T fit_sum(T x, T y)
+{
+ return x + y;
+};
+
+}
+
+#endif
diff --git a/src/boost/libs/hof/test/static_def/static_def2.cpp b/src/boost/libs/hof/test/static_def/static_def2.cpp
new file mode 100644
index 000000000..b5e86e56c
--- /dev/null
+++ b/src/boost/libs/hof/test/static_def/static_def2.cpp
@@ -0,0 +1,58 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ static_def2.cpp
+ 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)
+==============================================================================*/
+
+#include <cstdio>
+#include "static_def.hpp"
+
+extern void* f_sum_lambda_addr();
+extern void* f_sum_fo_addr();
+
+extern void* sum_lambda_addr();
+extern void* sum_fo_addr();
+
+extern void* f_sum_var_addr();
+extern void* f_sum_constexpr_fo_addr();
+
+extern void* sum_var_addr();
+extern void* sum_constexpr_fo_addr();
+
+void* f_sum_lambda_addr()
+{
+ return (void*)&fit_test::fit_sum_lambda;
+}
+void* f_sum_fo_addr()
+{
+ return (void*)&fit_test::fit_sum_fo;
+}
+
+void* f_sum_var_addr()
+{
+ return (void*)&fit_test::fit_sum_var;
+}
+void* f_sum_constexpr_fo_addr()
+{
+ return (void*)&fit_test::fit_sum_constexpr_fo;
+}
+
+int f()
+{
+ if (fit_test::fit_sum_fo(1, 2) != 3) printf("FAILED\n");
+ if (fit_test::fit_sum_lambda(1, 2) != 3) printf("FAILED\n");
+ if (fit_test::fit_sum(1, 2) != 3) printf("FAILED\n");
+
+#if BOOST_HOF_HAS_UNIQUE_STATIC_LAMBDA_FUNCTION_ADDR
+ if (sum_lambda_addr() != f_sum_lambda_addr()) printf("FAILED: Lambda\n");
+ if (sum_fo_addr() != f_sum_fo_addr()) printf("FAILED: Function object\n");
+#endif
+
+#if BOOST_HOF_HAS_UNIQUE_STATIC_VAR
+ if (sum_var_addr() != f_sum_var_addr()) printf("FAILED: Lambda\n");
+ if (sum_constexpr_fo_addr() != f_sum_constexpr_fo_addr()) printf("FAILED: Function object\n");
+#endif
+ return 0;
+}
+
diff --git a/src/boost/libs/hof/test/tap.cpp b/src/boost/libs/hof/test/tap.cpp
new file mode 100644
index 000000000..25a92e4d0
--- /dev/null
+++ b/src/boost/libs/hof/test/tap.cpp
@@ -0,0 +1,25 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ tap.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/tap.hpp>
+#include "test.hpp"
+
+struct sum_f
+{
+ template<class T, class U>
+ constexpr T operator()(T x, U y) const
+ {
+ return x+y;
+ }
+};
+
+static constexpr boost::hof::pipable_adaptor<sum_f> sum = {};
+// TODO: Test constexpr
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == (1 | sum(2)));
+ BOOST_HOF_TEST_CHECK(5 == (1 | sum(2) | boost::hof::tap([](int i) { BOOST_HOF_TEST_CHECK(3 == i); }) | sum(2)));
+}
diff --git a/src/boost/libs/hof/test/test.hpp b/src/boost/libs/hof/test/test.hpp
new file mode 100644
index 000000000..17fbd3676
--- /dev/null
+++ b/src/boost/libs/hof/test/test.hpp
@@ -0,0 +1,190 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ test.hpp
+ 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)
+==============================================================================*/
+#ifndef GUARD_TEST_H
+#define GUARD_TEST_H
+
+#include <type_traits>
+#include <tuple>
+#include <iostream>
+#include <functional>
+#include <vector>
+#include <memory>
+#include <boost/hof/detail/forward.hpp>
+
+#ifndef BOOST_HOF_HAS_STATIC_TEST_CHECK
+#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7) || defined(_MSC_VER)
+#define BOOST_HOF_HAS_STATIC_TEST_CHECK 0
+#else
+#define BOOST_HOF_HAS_STATIC_TEST_CHECK 1
+#endif
+#endif
+
+
+#define BOOST_HOF_PP_CAT(x, y) BOOST_HOF_PP_PRIMITIVE_CAT(x, y)
+#define BOOST_HOF_PP_PRIMITIVE_CAT(x, y) x ## y
+
+namespace boost { namespace hof { namespace test {
+
+typedef std::function<void()> test_case;
+static std::vector<test_case> test_cases;
+
+struct auto_register
+{
+ auto_register(test_case tc)
+ {
+ test_cases.push_back(tc);
+ }
+};
+
+#define BOOST_HOF_DETAIL_TEST_CASE(name) \
+struct name \
+{ void operator()() const; }; \
+static boost::hof::test::auto_register BOOST_HOF_PP_CAT(name, _register) = boost::hof::test::auto_register(name()); \
+void name::operator()() const
+
+template<class T>
+T bare(const T&);
+
+template<class T>
+inline void unused(T&&) {}
+
+}}} // namespace boost::hof
+
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define BOOST_HOF_STATIC_AUTO constexpr auto
+#else
+#define BOOST_HOF_STATIC_AUTO const constexpr auto
+#endif
+
+#define STATIC_ASSERT_SAME(...) static_assert(std::is_same<__VA_ARGS__>::value, "Types are not the same")
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define STATIC_ASSERT_MOVE_ONLY(T)
+#else
+#define STATIC_ASSERT_MOVE_ONLY(T) static_assert(!std::is_copy_constructible<T>::value && std::is_move_constructible<T>::value, "Not movable")
+#endif
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(T)
+#else
+#define STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(T) static_assert(!std::is_default_constructible<T>::value, "Default constructible")
+#endif
+#define STATIC_ASSERT_EMPTY(x) static_assert(std::is_empty<decltype(boost::hof::test::bare(x))>::value, "Not empty");
+
+
+#define BOOST_HOF_TEST_CASE() BOOST_HOF_DETAIL_TEST_CASE(BOOST_HOF_PP_CAT(test_, __LINE__))
+#define BOOST_HOF_STATIC_TEST_CASE() struct BOOST_HOF_PP_CAT(test_, __LINE__)
+
+#define BOOST_HOF_TEST_TEMPLATE(...) typedef std::integral_constant<int, sizeof(__VA_ARGS__)> BOOST_HOF_PP_CAT(test_template_, __LINE__)
+
+#define BOOST_HOF_TEST_CHECK(...) if (!(__VA_ARGS__)) std::cout << "***** FAILED *****: " << #__VA_ARGS__ << "@" << __FILE__ << ": " << __LINE__ << std::endl
+#define BOOST_HOF_STRINGIZE(...) #__VA_ARGS__
+
+#if BOOST_HOF_HAS_STATIC_TEST_CHECK
+#define BOOST_HOF_STATIC_TEST_CHECK(...) static_assert(__VA_ARGS__, BOOST_HOF_STRINGIZE(__VA_ARGS__))
+#else
+#define BOOST_HOF_STATIC_TEST_CHECK(...)
+#endif
+
+#ifndef BOOST_HOF_HAS_CONSTEXPR_TUPLE
+#define BOOST_HOF_HAS_CONSTEXPR_TUPLE BOOST_HOF_HAS_STD_14
+#endif
+
+struct binary_class
+{
+ template<class T, class U>
+ constexpr T operator()(T x, U y) const noexcept
+ {
+ return x+y;
+ }
+
+};
+
+struct mutable_class
+{
+ template<class F>
+ struct result;
+
+ template<class F, class T, class U>
+ struct result<F(T&, U)>
+ {
+ typedef T type;
+ };
+
+ template<class T, class U>
+ T operator()(T & x, U y) const
+ {
+ return x+=y;
+ }
+
+};
+
+struct unary_class
+{
+ template<class T>
+ constexpr T&& operator()(T&& x) const noexcept
+ {
+ return boost::hof::forward<T>(x);
+ }
+
+};
+
+struct void_class
+{
+ template<class T>
+ void operator()(T) const
+ {
+ }
+};
+
+struct mono_class
+{
+ constexpr int operator()(int x) const
+ {
+ return x+1;
+ }
+};
+
+struct tuple_class
+{
+ // Note: Taking the tuple by value causes the compiler to ICE on gcc 4.7
+ // when called in a constexpr context.
+ template<class T>
+ constexpr int operator()(const T& t) const
+ {
+ return std::get<0>(t) + 1;
+ }
+};
+
+template<class R>
+struct explicit_class
+{
+ template<class T>
+ R operator()(T x)
+ {
+ return static_cast<R>(x);
+ }
+};
+
+struct move_class
+{
+ std::unique_ptr<int> i;
+ move_class() : i(new int(0))
+ {}
+
+ template<class T, class U>
+ constexpr T operator()(T x, U y) const
+ {
+ return x+y+*i;
+ }
+};
+
+int main()
+{
+ for(const auto& tc: boost::hof::test::test_cases) tc();
+ return 0;
+}
+
+#endif
diff --git a/src/boost/libs/hof/test/tuple_for_each.cpp b/src/boost/libs/hof/test/tuple_for_each.cpp
new file mode 100644
index 000000000..e784c1f2e
--- /dev/null
+++ b/src/boost/libs/hof/test/tuple_for_each.cpp
@@ -0,0 +1,247 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ tuple_for_each.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/unpack.hpp>
+#include <boost/hof/proj.hpp>
+#include <boost/hof/function.hpp>
+#include <boost/hof/reveal.hpp>
+#include "test.hpp"
+
+struct tuple_for_each_f
+{
+ template<class Sequence, class F>
+ constexpr auto operator()(Sequence&& s, F && f) const BOOST_HOF_RETURNS
+ (
+ boost::hof::unpack(boost::hof::proj(boost::hof::forward<F>(f)))(boost::hof::forward<Sequence>(s)), boost::hof::forward<F>(f)
+ );
+};
+
+BOOST_HOF_STATIC_FUNCTION(tuple_for_each) = tuple_for_each_f{};
+
+BOOST_HOF_TEST_CASE()
+{
+ std::tuple<int, short, char> tp{ 1, 2, 3 };
+
+ {
+ int s = 0;
+
+ tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 123 );
+ }
+
+ {
+ int s = 0;
+
+ tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 123 );
+ }
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::tuple<int, short, char> const tp{ 1, 2, 3 };
+
+ {
+ int s = 0;
+
+ tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 123 );
+ }
+
+ {
+ int s = 0;
+
+ tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 123 );
+ }
+}
+
+// #if defined( __clang_major__ ) && __clang_major__ == 3 && __clang_minor__ < 8
+// #else
+BOOST_HOF_TEST_CASE()
+{
+ std::tuple<std::unique_ptr<int>, std::unique_ptr<int>, std::unique_ptr<int>> tp{ std::unique_ptr<int>(new int(1)), std::unique_ptr<int>(new int(2)), std::unique_ptr<int>(new int(3)) };
+
+ int s = 0;
+
+ tuple_for_each( std::move(tp), [&]( std::unique_ptr<int> p ){ s = s * 10 + *p; } );
+
+ BOOST_HOF_TEST_CHECK( s == 123 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto tp = boost::hof::pack(1, 2, 3);
+
+ {
+ int s = 0;
+
+ tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 123 );
+ }
+
+ {
+ int s = 0;
+
+ tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 123 );
+ }
+}
+BOOST_HOF_TEST_CASE()
+{
+ const auto tp = boost::hof::pack(1, 2, 3);
+
+ {
+ int s = 0;
+
+ tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 123 );
+ }
+
+ {
+ int s = 0;
+
+ tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 123 );
+ }
+}
+// #endif
+BOOST_HOF_TEST_CASE()
+{
+ std::pair<int, short> tp{ 1, 2 };
+
+ {
+ int s = 0;
+
+ tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 12 );
+ }
+
+ {
+ int s = 0;
+
+ tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 12 );
+ }
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::pair<int, short> const tp{ 1, 2 };
+
+ {
+ int s = 0;
+
+ tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 12 );
+ }
+
+ {
+ int s = 0;
+
+ tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 12 );
+ }
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::array<int, 3> tp{{ 1, 2, 3 }};
+
+ {
+ int s = 0;
+
+ tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 123 );
+ }
+
+ {
+ int s = 0;
+
+ tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 123 );
+ }
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::array<int, 3> const tp{{ 1, 2, 3 }};
+
+ {
+ int s = 0;
+
+ tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 123 );
+ }
+
+ {
+ int s = 0;
+
+ tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
+
+ BOOST_HOF_TEST_CHECK( s == 123 );
+ }
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::tuple<> tp;
+
+ BOOST_HOF_TEST_CHECK( tuple_for_each( tp, 11 ) == 11 );
+ BOOST_HOF_TEST_CHECK( tuple_for_each( std::move( tp ), 12 ) == 12 );
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK( tuple_for_each( boost::hof::pack(), 11 ) == 11 );
+ BOOST_HOF_STATIC_TEST_CHECK( tuple_for_each( boost::hof::pack(), 11 ) == 11 );
+}
+BOOST_HOF_TEST_CASE()
+{
+ std::array<int, 0> tp;
+
+ BOOST_HOF_TEST_CHECK( tuple_for_each( tp, 11 ) == 11 );
+ BOOST_HOF_TEST_CHECK( tuple_for_each( std::move( tp ), 12 ) == 12 );
+}
+
+struct assert_is_integral
+{
+ template<class T> constexpr bool operator()( T ) const
+ {
+ BOOST_HOF_STATIC_TEST_CHECK( std::is_integral<T>::value );
+ return true;
+ }
+};
+
+BOOST_HOF_TEST_CASE()
+{
+#if !BOOST_HOF_HAS_CONSTEXPR_TUPLE
+ auto r = tuple_for_each( std::tuple<int, short, char>{1, 2, 3}, assert_is_integral() );
+#else
+ constexpr auto r = tuple_for_each( std::tuple<int, short, char>{1, 2, 3}, assert_is_integral() );
+#endif
+ (void)r;
+}
+
+BOOST_HOF_TEST_CASE()
+{
+#if !BOOST_HOF_HAS_CONSTEXPR_TUPLE
+ auto r = tuple_for_each( boost::hof::pack(1, 2, 3), assert_is_integral() );
+#else
+ constexpr auto r = tuple_for_each( boost::hof::pack(1, 2, 3), assert_is_integral() );
+#endif
+ (void)r;
+}
diff --git a/src/boost/libs/hof/test/tuple_transform.cpp b/src/boost/libs/hof/test/tuple_transform.cpp
new file mode 100644
index 000000000..d6aef66f4
--- /dev/null
+++ b/src/boost/libs/hof/test/tuple_transform.cpp
@@ -0,0 +1,90 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ tuple_transform.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/proj.hpp>
+#include <boost/hof/construct.hpp>
+#include <boost/hof/unpack.hpp>
+#include <boost/hof/function.hpp>
+#include <boost/hof/placeholders.hpp>
+#include <boost/hof/compose.hpp>
+// Disable static checks for gcc 4.7
+#ifndef BOOST_HOF_HAS_STATIC_TEST_CHECK
+#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 8)
+#define BOOST_HOF_HAS_STATIC_TEST_CHECK 0
+#endif
+#endif
+#include "test.hpp"
+
+struct tuple_transform_f
+{
+ template<class Sequence, class F>
+ constexpr auto operator()(Sequence&& s, F f) const BOOST_HOF_RETURNS
+ (
+ boost::hof::unpack(boost::hof::proj(f, boost::hof::construct<std::tuple>()))(boost::hof::forward<Sequence>(s))
+ );
+};
+
+struct pack_transform_f
+{
+ template<class Sequence, class F>
+ constexpr auto operator()(Sequence&& s, F f) const BOOST_HOF_RETURNS
+ (
+ boost::hof::unpack(boost::hof::proj(f, boost::hof::pack()))(boost::hof::forward<Sequence>(s))
+ );
+};
+
+BOOST_HOF_STATIC_FUNCTION(tuple_transform) = tuple_transform_f{};
+// BOOST_HOF_STATIC_FUNCTION(pack_transform) = pack_transform_f{};
+
+#if !BOOST_HOF_HAS_CONSTEXPR_TUPLE
+#define TUPLE_TRANSFORM_STATIC_CHECK(...)
+#else
+#define TUPLE_TRANSFORM_STATIC_CHECK BOOST_HOF_STATIC_TEST_CHECK
+
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ auto t = std::make_tuple(1, 2);
+ auto r = tuple_transform(t, [](int i) { return i*i; });
+ BOOST_HOF_TEST_CHECK(r == std::make_tuple(1, 4));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(std::make_tuple(1, 2), boost::hof::_1 * boost::hof::_1) == std::make_tuple(1, 4));
+}
+
+#define TUPLE_TRANSFORM_CHECK_ID(x) \
+BOOST_HOF_TEST_CHECK(tuple_transform(x, boost::hof::identity) == x); \
+TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(x, boost::hof::identity) == x);
+
+BOOST_HOF_TEST_CASE()
+{
+ TUPLE_TRANSFORM_CHECK_ID(std::make_tuple(1, 2));
+ TUPLE_TRANSFORM_CHECK_ID(std::make_tuple(1));
+ TUPLE_TRANSFORM_CHECK_ID(std::make_tuple());
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto x = tuple_transform(std::make_tuple(std::unique_ptr<int>(new int(3))), boost::hof::identity);
+ auto y = std::make_tuple(std::unique_ptr<int>(new int(3)));
+ BOOST_HOF_TEST_CHECK(x != y);
+ BOOST_HOF_TEST_CHECK(tuple_transform(x, *boost::hof::_1) == tuple_transform(y, *boost::hof::_1));
+}
+
+#define TUPLE_TRANSFORM_CHECK_COMPOSE(x, f, g) \
+BOOST_HOF_TEST_CHECK(tuple_transform(x, boost::hof::compose(f, g)) == tuple_transform(tuple_transform(x, g), f)); \
+TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(x, boost::hof::compose(f, g)) == tuple_transform(tuple_transform(x, g), f));
+
+BOOST_HOF_TEST_CASE()
+{
+ TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(1, 2, 3, 4), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1);
+ TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(1, 2, 3), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1);
+ TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(1), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1);
+ TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1);
+}
diff --git a/src/boost/libs/hof/test/unpack.cpp b/src/boost/libs/hof/test/unpack.cpp
new file mode 100644
index 000000000..8d1e948e0
--- /dev/null
+++ b/src/boost/libs/hof/test/unpack.cpp
@@ -0,0 +1,255 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ unpack.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/unpack.hpp>
+#include <boost/hof/static.hpp>
+#include <boost/hof/lambda.hpp>
+#include "test.hpp"
+
+#include <memory>
+
+static constexpr boost::hof::static_<boost::hof::unpack_adaptor<unary_class> > unary_unpack = {};
+static constexpr boost::hof::static_<boost::hof::unpack_adaptor<binary_class> > binary_unpack = {};
+
+BOOST_HOF_STATIC_AUTO unary_unpack_constexpr = boost::hof::unpack_adaptor<unary_class>();
+#if BOOST_HOF_HAS_CONSTEXPR_TUPLE
+BOOST_HOF_STATIC_AUTO binary_unpack_constexpr = boost::hof::unpack_adaptor<binary_class>();
+#endif
+
+BOOST_HOF_STATIC_AUTO unary_unpack_reveal = boost::hof::reveal_adaptor<boost::hof::unpack_adaptor<unary_class>>();
+BOOST_HOF_STATIC_AUTO binary_unpack_reveal = boost::hof::reveal_adaptor<boost::hof::unpack_adaptor<binary_class>>();
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+BOOST_HOF_TEST_CASE()
+{
+ static_assert(noexcept(boost::hof::unpack(unary_class())(boost::hof::pack(3))), "noexcept unpack");
+ static_assert(noexcept(unary_unpack(boost::hof::pack(3))), "noexcept unpack");
+ static_assert(noexcept(binary_unpack(boost::hof::pack(3), boost::hof::pack(2))), "noexcept unpack");
+}
+#endif
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(unary_class())(std::make_tuple(3)));
+ BOOST_HOF_TEST_CHECK(3 == unary_unpack(std::make_tuple(3)));
+ BOOST_HOF_TEST_CHECK(3 == unary_unpack_reveal(std::make_tuple(3)));
+ int ifu = 3;
+ BOOST_HOF_TEST_CHECK(3 == unary_unpack(std::tuple<int&>(ifu)));
+
+#if BOOST_HOF_HAS_CONSTEXPR_TUPLE
+ BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(unary_class())(std::make_tuple(3)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == unary_unpack_constexpr(std::make_tuple(3)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == unary_unpack_reveal(std::make_tuple(3)));
+#endif
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(unary_class())(boost::hof::pack(3)));
+ BOOST_HOF_TEST_CHECK(3 == unary_unpack(boost::hof::pack(3)));
+ BOOST_HOF_TEST_CHECK(3 == unary_unpack_reveal(boost::hof::pack(3)));
+ int ifu = 3;
+ BOOST_HOF_TEST_CHECK(3 == unary_unpack(boost::hof::pack_forward(ifu)));
+
+ BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(unary_class())(boost::hof::pack(3)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == unary_unpack_constexpr(boost::hof::pack(3)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == unary_unpack_reveal(boost::hof::pack(3)));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1, 2)));
+ BOOST_HOF_TEST_CHECK(3 == binary_unpack(std::make_tuple(1, 2)));
+ BOOST_HOF_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1, 2)));
+
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1), std::make_tuple(2)));
+ BOOST_HOF_TEST_CHECK(3 == binary_unpack(std::make_tuple(1), std::make_tuple(2)));
+ BOOST_HOF_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(2)));
+
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1), std::make_tuple(), std::make_tuple(2)));
+ BOOST_HOF_TEST_CHECK(3 == binary_unpack(std::make_tuple(1), std::make_tuple(), std::make_tuple(2)));
+ BOOST_HOF_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(), std::make_tuple(2)));
+
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2)));
+ BOOST_HOF_TEST_CHECK(3 == binary_unpack(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2)));
+ BOOST_HOF_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2)));
+
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple()));
+ BOOST_HOF_TEST_CHECK(3 == binary_unpack(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple()));
+ BOOST_HOF_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple()));
+
+#if BOOST_HOF_HAS_CONSTEXPR_TUPLE
+ BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1, 2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(1, 2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1, 2)));
+
+ BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1), std::make_tuple(2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(1), std::make_tuple(2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(2)));
+
+ BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1), std::make_tuple(), std::make_tuple(2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(1), std::make_tuple(), std::make_tuple(2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(), std::make_tuple(2)));
+
+ BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2)));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2)));
+
+ BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple()));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple()));
+ BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple()));
+#endif
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ auto p1 = boost::hof::pack_basic(1, 2);
+ static_assert(boost::hof::is_unpackable<decltype(p1)>::value, "Not unpackable");
+ static_assert(boost::hof::is_unpackable<decltype((p1))>::value, "Not unpackable");
+
+ auto p2 = boost::hof::pack_forward(1, 2);
+ static_assert(boost::hof::is_unpackable<decltype(p2)>::value, "Not unpackable");
+ static_assert(boost::hof::is_unpackable<decltype((p2))>::value, "Not unpackable");
+
+ auto p3 = boost::hof::pack(1, 2);
+ static_assert(boost::hof::is_unpackable<decltype(p3)>::value, "Not unpackable");
+ static_assert(boost::hof::is_unpackable<decltype((p3))>::value, "Not unpackable");
+
+ static_assert(boost::hof::is_unpackable<std::tuple<int>>::value, "Not unpackable");
+
+ static_assert(!boost::hof::is_unpackable<int>::value, "Unpackable");
+ static_assert(!boost::hof::is_unpackable<void>::value, "Unpackable");
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ typedef std::tuple<int, int> tuple_type;
+ static_assert(boost::hof::is_unpackable<tuple_type>::value, "Not unpackable");
+ static_assert(boost::hof::is_unpackable<tuple_type&>::value, "Not unpackable");
+ static_assert(boost::hof::is_unpackable<const tuple_type&>::value, "Not unpackable");
+ static_assert(boost::hof::is_unpackable<tuple_type&&>::value, "Not unpackable");
+
+}
+
+BOOST_HOF_STATIC_AUTO lambda_unary_unpack = boost::hof::unpack(BOOST_HOF_STATIC_LAMBDA(int x)
+{
+ return x;
+});
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == lambda_unary_unpack(std::make_tuple(3)));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == lambda_unary_unpack(boost::hof::pack(3)));
+}
+
+struct unary_move
+{
+ std::unique_ptr<int> i;
+ unary_move()
+ : i(new int(2))
+ {}
+
+ template<class T>
+ T operator()(T x) const
+ {
+ return x + *i;
+ }
+};
+
+static constexpr boost::hof::static_<boost::hof::unpack_adaptor<unary_move> > unary_move_unpack = {};
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(unary_move())(std::make_tuple(1)));
+ BOOST_HOF_TEST_CHECK(3 == unary_move_unpack(std::make_tuple(1)));
+}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(unary_move())(boost::hof::pack(1)));
+ BOOST_HOF_TEST_CHECK(3 == unary_move_unpack(boost::hof::pack(1)));
+}
+
+struct indirect_sum_f
+{
+ template<class T, class U>
+ auto operator()(T x, U y) const
+ BOOST_HOF_RETURNS(*x + *y);
+};
+
+#define MAKE_UNIQUE_PTR(x) std::unique_ptr<int>(new int(x))
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(indirect_sum_f())(boost::hof::pack_basic(MAKE_UNIQUE_PTR(1), MAKE_UNIQUE_PTR(2))));
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(indirect_sum_f())(boost::hof::pack_forward(MAKE_UNIQUE_PTR(1), MAKE_UNIQUE_PTR(2))));
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(indirect_sum_f())(boost::hof::pack(MAKE_UNIQUE_PTR(1), MAKE_UNIQUE_PTR(2))));
+ BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(indirect_sum_f())(std::make_tuple(MAKE_UNIQUE_PTR(1), MAKE_UNIQUE_PTR(2))));
+}
+
+template<class...>
+struct deduce_types
+{};
+
+struct deducer
+{
+ template<class... Ts>
+ deduce_types<Ts...> operator()(Ts&&...) const;
+};
+
+static constexpr boost::hof::unpack_adaptor<deducer> deduce = {};
+
+BOOST_HOF_TEST_CASE()
+{
+ STATIC_ASSERT_SAME(deduce_types<int, int>, decltype(deduce(std::make_tuple(1, 2))));
+ STATIC_ASSERT_SAME(deduce_types<int, int>, decltype(deduce(std::make_tuple(1), std::make_tuple(2))));
+ STATIC_ASSERT_SAME(deduce_types<int, int, int>, decltype(deduce(std::make_tuple(1), std::make_tuple(2), std::make_tuple(3))));
+ STATIC_ASSERT_SAME(std::tuple<int&&, int&&>, decltype(std::forward_as_tuple(1, 2)));
+ // Disable this test, it seems that rvalue references get swalllowed by type deduction
+ // STATIC_ASSERT_SAME(deduce_types<int&&, int&&>, decltype(deduce(std::forward_as_tuple(1, 2))));
+
+
+ STATIC_ASSERT_SAME(deduce_types<int, int>, decltype(deduce(boost::hof::pack_basic(1, 2))));
+ STATIC_ASSERT_SAME(deduce_types<int, int>, decltype(deduce(boost::hof::pack_basic(1), boost::hof::pack_basic(2))));
+ STATIC_ASSERT_SAME(deduce_types<int, int, int>, decltype(deduce(boost::hof::pack_basic(1), boost::hof::pack_basic(2), boost::hof::pack_basic(3))));
+ // STATIC_ASSERT_SAME(deduce_types<int&&, int&&>, decltype(deduce(boost::hof::pack_forward(1, 2))));
+}
+
+struct not_unpackable
+{};
+
+BOOST_HOF_TEST_CASE()
+{
+ auto f = boost::hof::unpack(boost::hof::always(1));
+
+ static_assert(!boost::hof::is_invocable<decltype(f), not_unpackable>::value, "SFINAE for unpack failed");
+}
+
+struct simple_unpackable
+{};
+
+namespace boost { namespace hof {
+
+template<>
+struct unpack_sequence<simple_unpackable>
+{
+ template<class F, class S>
+ constexpr static auto apply(F&& f, S&&) BOOST_HOF_RETURNS
+ (
+ f(1)
+ );
+};
+}} // namespace boost::hof
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::unpack(boost::hof::identity)(simple_unpackable{}) == 1);
+ BOOST_HOF_STATIC_TEST_CHECK(boost::hof::unpack(boost::hof::identity)(simple_unpackable{}) == 1);
+}
diff --git a/src/boost/libs/hof/test/virtual_base.cpp b/src/boost/libs/hof/test/virtual_base.cpp
new file mode 100644
index 000000000..b686b9762
--- /dev/null
+++ b/src/boost/libs/hof/test/virtual_base.cpp
@@ -0,0 +1,37 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ virtual_base.cpp
+ 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)
+==============================================================================*/
+#include <boost/hof/flip.hpp>
+#include <boost/hof/proj.hpp>
+#include <boost/hof/construct.hpp>
+#include <boost/hof/pipable.hpp>
+#include <boost/hof/rotate.hpp>
+#include "test.hpp"
+
+struct base {
+ base(int) {}
+ base(const base&) {}
+ virtual ~base();
+};
+
+base::~base() {}
+
+struct derived : virtual base {
+ derived() : base(1) {}
+ derived(const derived&) : base(1) {}
+ int operator()(int i, void *) const {
+ return i;
+ }
+ ~derived();
+};
+derived::~derived() {}
+
+BOOST_HOF_TEST_CASE()
+{
+ BOOST_HOF_TEST_CHECK(boost::hof::flip(derived())(nullptr, 2) == 2);
+ BOOST_HOF_TEST_CHECK(boost::hof::rotate(derived())(nullptr, 2) == 2);
+ BOOST_HOF_TEST_CHECK((2 | boost::hof::pipable(derived())(nullptr)) == 2);
+}