Skip to content

Commit

Permalink
Merge 'develop' into 'master' for Hana v1.4.0, aka Boost 1.67.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ldionne committed Feb 27, 2018
2 parents 5b1c2ad + bd60612 commit e53c547
Show file tree
Hide file tree
Showing 81 changed files with 1,424 additions and 1,695 deletions.
2 changes: 1 addition & 1 deletion .appveyor.yml
Expand Up @@ -36,7 +36,7 @@ install:
############################################################################
# Install a recent CMake
############################################################################
- set CMAKE_URL="https://cmake.org/files/v3.8/cmake-3.8.0-win64-x64.zip"
- set CMAKE_URL="https://cmake.org/files/v3.10/cmake-3.10.0-win64-x64.zip"
- appveyor DownloadFile %CMAKE_URL% -FileName cmake.zip
- 7z x cmake.zip -oC:\projects\deps > nul
- move C:\projects\deps\cmake-* C:\projects\deps\cmake # Move to a version-agnostic directory
Expand Down
187 changes: 75 additions & 112 deletions .travis.yml

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions CMakeLists.txt
Expand Up @@ -2,7 +2,7 @@
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

cmake_minimum_required(VERSION 3.8)
cmake_minimum_required(VERSION 3.9)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

##############################################################################
Expand Down Expand Up @@ -49,23 +49,22 @@ include(CheckCxxCompilerSupport)
##############################################################################
include(CheckCXXCompilerFlag)
add_library(hana INTERFACE)
target_include_directories(hana INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
$<INSTALL_INTERFACE:include>)
# With Clang on Windows, the -std=c++14 flag is incorrectly set and the compiler
# complains about the unknown option. TODO: Remove this workaround once the
# underlying bug is fixed in CMake: https://gitlab.kitware.com/cmake/cmake/issues/17015
if (NOT (MSVC AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
if (BOOST_HANA_ENABLE_CPP17)
target_compile_features(hana INTERFACE cxx_std_17)
else()
target_compile_features(hana INTERFACE cxx_std_14)
endif()
target_include_directories(hana INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>")
if (BOOST_HANA_ENABLE_CPP17)
target_compile_features(hana INTERFACE cxx_std_17)
else()
target_compile_features(hana INTERFACE cxx_std_14)
endif()

# Export the `hana` library into a HanaConfig.cmake file
install(TARGETS hana EXPORT HanaConfig)
install(EXPORT HanaConfig DESTINATION lib/cmake/hana)
install(DIRECTORY include/boost DESTINATION include FILES_MATCHING PATTERN "*.hpp")
install(TARGETS hana
EXPORT HanaConfig
INCLUDES DESTINATION include)
install(EXPORT HanaConfig
DESTINATION lib/cmake/hana)
install(DIRECTORY include/boost
DESTINATION include
FILES_MATCHING PATTERN "*.hpp")

# Also install an optional pkg-config file
configure_file(cmake/hana.pc.in hana.pc @ONLY)
Expand Down Expand Up @@ -121,7 +120,7 @@ endfunction()
##############################################################################
# Look for the rest of Boost, which is an optional dependency of some tests.
##############################################################################
find_package(Boost 1.59)
find_package(Boost 1.64)
if (NOT Boost_FOUND)
message(WARNING "The rest of Boost was not found; some tests and examples will be disabled.")
endif()
Expand Down Expand Up @@ -158,7 +157,8 @@ endfunction()
add_custom_target(check
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "Build and then run all the tests and examples.")
COMMENT "Build and then run all the tests and examples."
USES_TERMINAL)


##############################################################################
Expand Down
84 changes: 37 additions & 47 deletions cmake/TestHeaders.cmake
Expand Up @@ -3,32 +3,38 @@
# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#
#
# This CMake module provides a function generating unit tests to make sure
# This CMake module provides a function generating a unit test to make sure
# that every public header can be included on its own.
#
# When a C++ library or application has many header files, it can happen that
# a header does not include all the other headers it depends on. When this is
# the case, it can happen that including that header file on its own will
# break the compilation. This CMake module generates a dummy unit test for
# each header file considered public: this unit test is just a program of
# the form
# break the compilation. This CMake module generates a dummy executable
# comprised of many .cpp files, each of which includes a header file that
# is part of the public API. In other words, the executable is comprised
# of .cpp files of the form:
#
# #include <the/public/header.hpp>
# int main() { }
#
# If this succeeds to compile, it means that the header can be included on
# its own, which is what clients expect. Otherwise, you have a problem.
# Since writing these dumb unit tests by hand is tedious and repetitive,
# you can use this CMake module to automate this task.
# and then exactly one `main` function. If this succeeds to compile, it means
# that the header can be included on its own, which is what clients expect.
# Otherwise, you have a problem. Since writing these dumb unit tests by hand
# is tedious and repetitive, you can use this CMake module to automate this
# task.

# add_header_test(<target> [EXCLUDE_FROM_ALL] [EXCLUDE excludes...] HEADERS headers...)
#
# Generates header-inclusion unit tests for all the specified headers.
#
# For each specified header with path `xxx/yyy/zzz.hpp`, a target named
# `test.header.xxx.yyy.zzz` is created. This target builds the unit test
# including `xxx/yyy/zzz.hpp`.
# This function creates a target which builds a dummy executable including
# each specified header file individually. If this target builds successfully,
# it means that all the specified header files can be included individually.
#
# Parameters
# ----------
# <target>:
# The name of the target to generate.
#
# HEADERS headers:
# A list of header files to generate the inclusion tests for. All headers
# in this list must be represented as relative paths from the root of the
Expand Down Expand Up @@ -70,25 +76,14 @@
# generated. Basically, any header in the list specified by the `HEADERS`
# argument that matches anything in `EXCLUDE` will be skipped.
#
# [MASTER_TARGET target]:
# An optional target name that will be made a dependent of all the generated
# targets. This can be used to create a target that will build all the
# header-inclusion tests.
#
# [LINK_LIBRARIES libraries]:
# An optional list of libraries that should be linked into each generated
# executable. The libraries are linked into the target using the usual
# `target_link_libraries`.
#
# [EXCLUDE_FROM_ALL]:
# If provided, the generated targets are excluded from the 'all' target.
# If provided, the generated target is excluded from the 'all' target.
#
function(generate_standalone_header_tests)
cmake_parse_arguments(ARGS "EXCLUDE_FROM_ALL" # options
"MASTER_TARGET" # 1 value args
"HEADERS;EXCLUDE;LINK_LIBRARIES" # multivalued args
function(add_header_test target)
cmake_parse_arguments(ARGS "EXCLUDE_FROM_ALL" # options
"" # 1 value args
"HEADERS;EXCLUDE" # multivalued args
${ARGN})

if (NOT ARGS_HEADERS)
message(FATAL_ERROR "The `HEADERS` argument must be provided.")
endif()
Expand All @@ -114,25 +109,20 @@ function(generate_standalone_header_tests)
get_filename_component(filename "${header}" NAME_WE)
get_filename_component(directory "${header}" DIRECTORY)

if (NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/headers/${directory}/${filename}.cpp")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers/${directory}/${filename}.cpp" "
/* THIS FILE WAS AUTOMATICALLY GENERATED: DO NOT EDIT! */
#include <${header}>
int main() { }
")
endif()

string(REGEX REPLACE "/" "." target "${header}")
add_executable(test.header.${target}
${ARGS_EXCLUDE_FROM_ALL}
"${CMAKE_CURRENT_BINARY_DIR}/headers/${directory}/${filename}.cpp"
)
if (ARGS_LINK_LIBRARIES)
target_link_libraries(test.header.${target} ${ARGS_LINK_LIBRARIES})
endif()

if (ARGS_MASTER_TARGET)
add_dependencies(${ARGS_MASTER_TARGET} test.header.${target})
set(source "${CMAKE_CURRENT_BINARY_DIR}/headers/${directory}/${filename}.cpp")
if (NOT EXISTS "${source}")
file(WRITE "${source}" "#include <${header}>")
endif()
list(APPEND sources "${source}")
endforeach()

set(standalone_main "${CMAKE_CURRENT_BINARY_DIR}/headers/_standalone_main.cpp")
if (NOT EXISTS "${standalone_main}")
file(WRITE "${standalone_main}" "int main() { }")
endif()
add_executable(${target}
${ARGS_EXCLUDE_FROM_ALL}
${sources}
"${CMAKE_CURRENT_BINARY_DIR}/headers/_standalone_main.cpp"
)
endfunction()
9 changes: 4 additions & 5 deletions doc/tutorial.hpp
Expand Up @@ -82,11 +82,10 @@ environment for development in the [README][Hana.hacking].
a `HanaConfig.cmake` file for use with CMake and a `hana.pc` file for use with
[pkg-config][].
- Do not mix a system-wide installation of Hana with a system-wide installation
of Boost, because both installations will clash. You won't know which version of
Hana is being used, and that could break libraries that depend on the version of
Hana provided with Boost (or vice-versa). Generally speaking, you should favor
local installations whenever possible.
- Do not mix a standalone installation of Hana (i.e. Hana not installed through
Boost) with a full installation of Boost. The Hana provided within Boost and
the standalone one may clash, and you won't know which version is used where.
This is asking for trouble.
@subsection tutorial-installation-cmake Note for CMake users
Expand Down
4 changes: 4 additions & 0 deletions example/CMakeLists.txt
Expand Up @@ -48,6 +48,7 @@ list(REMOVE_ITEM EXAMPLES "" ${EXCLUDED_EXAMPLES})
# out all unused parameter names.
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-Wno-unused-parameter BOOST_HANA_HAS_WNO_UNUSED_PARAMETER)
check_cxx_compiler_flag(-Wno-unused-lambda-capture BOOST_HANA_HAS_WNO_UNUSED_LAMBDA_CAPTURE)

foreach(_file IN LISTS EXAMPLES)
boost_hana_target_name_for(_target "${_file}")
Expand All @@ -60,5 +61,8 @@ foreach(_file IN LISTS EXAMPLES)
if (BOOST_HANA_HAS_WNO_UNUSED_PARAMETER)
target_compile_options(${_target} PRIVATE -Wno-unused-parameter)
endif()
if (BOOST_HANA_HAS_WNO_UNUSED_LAMBDA_CAPTURE)
target_compile_options(${_target} PRIVATE -Wno-unused-lambda-capture)
endif()
add_dependencies(examples ${_target})
endforeach()
20 changes: 20 additions & 0 deletions example/string/from_c_str.cpp
@@ -0,0 +1,20 @@
// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#include <boost/hana/assert.hpp>
#include <boost/hana/core/to.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/string.hpp>
namespace hana = boost::hana;


constexpr char const hello[] = "hello";
auto hello_constant = hana::integral_constant<char const*, hello>{};

BOOST_HANA_CONSTANT_CHECK(
hana::to_string(hello_constant) == hana::string_c<'h', 'e', 'l', 'l', 'o'>
);

int main() { }
13 changes: 13 additions & 0 deletions example/take_back_c.cpp
@@ -0,0 +1,13 @@
// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#include <boost/hana/equal.hpp>
#include <boost/hana/take_back.hpp>
#include <boost/hana/tuple.hpp>
namespace hana = boost::hana;


static_assert(hana::take_back_c<2>(hana::make_tuple(1, '2', 3.3)) == hana::make_tuple('2', 3.3), "");

int main() { }
7 changes: 0 additions & 7 deletions include/boost/hana/config.hpp
Expand Up @@ -144,13 +144,6 @@ Distributed under the Boost Software License, Version 1.0.
# define BOOST_HANA_CONSTEXPR_LAMBDA /* nothing */
#endif

// The std::tuple adapter is broken on libc++ prior to the one shipped
// with Clang 3.7.0.
#if defined(BOOST_HANA_CONFIG_LIBCPP) && \
BOOST_HANA_CONFIG_LIBCPP < BOOST_HANA_CONFIG_VERSION(1, 0, 101)
# define BOOST_HANA_CONFIG_HAS_NO_STD_TUPLE_ADAPTER
#endif

// There's a bug in std::tuple_cat in libc++ right now.
// See http://llvm.org/bugs/show_bug.cgi?id=22806.
#if defined(BOOST_HANA_CONFIG_LIBCPP)
Expand Down
40 changes: 21 additions & 19 deletions include/boost/hana/core/to.hpp
Expand Up @@ -39,27 +39,29 @@ BOOST_HANA_NAMESPACE_BEGIN
namespace convert_detail {
struct no_conversion { };

template <typename ...>
struct is_valid { static constexpr bool value = true; };
}
template <typename To, typename From, typename = void>
struct maybe_static_cast : no_conversion {
template <typename X>
static constexpr auto apply(X const&) {
static_assert(detail::wrong<to_impl<To, From>, X>{},
"no conversion is available between the provided types");
}
};

template <typename To, typename From, bool condition>
struct to_impl<To, From, when<condition>> : convert_detail::no_conversion {
template <typename X>
static constexpr auto apply(X const&) {
static_assert(detail::wrong<to_impl<To, From>, X>{},
"no conversion is available between the provided types");
}
};
template <typename To, typename From>
struct maybe_static_cast<To, From, decltype((void)
static_cast<To>(std::declval<From>())
)> {
template <typename X>
static constexpr To apply(X&& x)
{ return static_cast<To>(static_cast<X&&>(x)); }
};
} // end namespace convert_detail

template <typename To, typename From>
struct to_impl<To, From, when<convert_detail::is_valid<
decltype(static_cast<To>(std::declval<From>()))
>::value>> {
template <typename X>
static constexpr To apply(X&& x)
{ return static_cast<To>(static_cast<X&&>(x)); }
};
template <typename To, typename From, bool condition>
struct to_impl<To, From, when<condition>>
: convert_detail::maybe_static_cast<To, From>
{ };

template <typename To>
struct to_impl<To, To> : embedding<> {
Expand Down

0 comments on commit e53c547

Please sign in to comment.