diff --git a/.appveyor.yml b/.appveyor.yml index f62d43a..836d15f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -3,6 +3,7 @@ os: - Visual Studio 2017 build_script: + - git submodule update --init --recursive - mkdir build - cd build - cmake .. diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e6488b5 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "cmake/tl-cmake"] + path = cmake/tl-cmake + url = https://github.com/TartanLlama/tl-cmake.git diff --git a/.travis.yml b/.travis.yml index 5d485e1..a541aaf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: cpp -dist: trusty +dist: xenial sudo: false matrix: @@ -33,7 +33,7 @@ matrix: addons: apt: sources: - - llvm-toolchain-precise-3.5 + - llvm-toolchain-xenial-3.5 - ubuntu-toolchain-r-test packages: - clang++-3.5 @@ -43,7 +43,7 @@ matrix: addons: apt: sources: - - llvm-toolchain-precise-3.6 + - llvm-toolchain-xenial-3.6 - ubuntu-toolchain-r-test packages: - clang++-3.6 @@ -53,7 +53,7 @@ matrix: addons: apt: sources: - - llvm-toolchain-precise-3.7 + - llvm-toolchain-xenial-3.7 - ubuntu-toolchain-r-test packages: - clang++-3.7 @@ -63,7 +63,7 @@ matrix: addons: apt: sources: - - llvm-toolchain-precise-3.8 + - llvm-toolchain-xenial-3.8 - ubuntu-toolchain-r-test packages: - clang++-3.8 @@ -73,7 +73,7 @@ matrix: addons: apt: sources: - - sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.9 main" + - sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main" key_url: "http://apt.llvm.org/llvm-snapshot.gpg.key" - ubuntu-toolchain-r-test packages: diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a653d8..aa4cc31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,35 +1,40 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.11) -project(function_ref) +project(tl-function_ref VERSION 1.0.0 LANGUAGES CXX) -# Prepare "Catch" library for other executables -set(CATCH_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/test) -add_library(Catch INTERFACE) -target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR}) - -# Make test executable -set(TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/tests/main.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tests/constructors.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tests/call.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tests/issues.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tests/assignment.cpp) - -add_executable(tests ${TEST_SOURCES}) +option(FUNCTION_REF_ENABLE_TESTS "Enable tests." ON) -add_library(function_ref INTERFACE) -target_sources(function_ref INTERFACE ${CMAKE_SOURCE_DIR}/function_ref.hpp) -target_include_directories(function_ref INTERFACE ${CMAKE_SOURCE_DIR}) +include(FetchContent) +FetchContent_Declare( + tl_cmake + GIT_REPOSITORY https://github.com/TartanLlama/tl-cmake.git +) +FetchContent_GetProperties(tl_cmake) +if(NOT tl_cmake_POPULATED) + FetchContent_Populate(tl_cmake) + set(CMAKE_MODULE_PATH ${tl_cmake_SOURCE_DIR} ${CMAKE_MODULE_PATH}) +endif() +include(add-tl) -target_link_libraries(tests Catch function_ref) -set_property(TARGET tests PROPERTY CXX_STANDARD 14) +tl_add_library(function-ref SOURCES + include/tl/function_ref.hpp) +# Prepare "Catch" library for other executables +set(CATCH_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test) +add_library(Catch INTERFACE) +target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR}) -find_package(standardese) # find standardese after installation - -# generates a custom target that will run standardese to generate the documentation -if (standardese_FOUND) -standardese_generate(function_ref - INCLUDE_DIRECTORY . - CONFIG ${CMAKE_SOURCE_DIR}/standardese.config - INPUT function_ref.hpp) -endif () +if(FUNCTION_REF_ENABLE_TESTS) + # Make test executable + set(TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/tests/main.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tests/constructors.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tests/call.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tests/issues.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tests/assignment.cpp) + + add_executable(tests ${TEST_SOURCES}) + + target_link_libraries(tests Catch function-ref) + + set_property(TARGET tests PROPERTY CXX_STANDARD 14) +endif() \ No newline at end of file diff --git a/cmake/tl-cmake b/cmake/tl-cmake new file mode 160000 index 0000000..284c6a3 --- /dev/null +++ b/cmake/tl-cmake @@ -0,0 +1 @@ +Subproject commit 284c6a3f0f61823cc3871b0f193e8df699e2c4ce diff --git a/cmake/tl-function-ref-config.cmake.in b/cmake/tl-function-ref-config.cmake.in new file mode 100644 index 0000000..4408240 --- /dev/null +++ b/cmake/tl-function-ref-config.cmake.in @@ -0,0 +1,3 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/tl-function-ref-targets.cmake") \ No newline at end of file diff --git a/function_ref.hpp b/include/tl/function_ref.hpp similarity index 90% rename from function_ref.hpp rename to include/tl/function_ref.hpp index 60fbb15..4b90dbf 100644 --- a/function_ref.hpp +++ b/include/tl/function_ref.hpp @@ -14,8 +14,9 @@ #ifndef TL_FUNCTION_REF_HPP #define TL_FUNCTION_REF_HPP -#define TL_FUNCTION_REF_VERSION_MAJOR 0 -#define TL_FUNCTION_REF_VERSION_MINOR 3 +#define TL_FUNCTION_REF_VERSION_MAJOR 1 +#define TL_FUNCTION_REF_VERSION_MINOR 0 +#define TL_FUNCTION_REF_VERSION_PATCH 0 #if (defined(_MSC_VER) && _MSC_VER == 1900) /// \exclude @@ -62,8 +63,7 @@ namespace tl { namespace detail { -#ifndef TL_TRAITS_MUTEX -#define TL_TRAITS_MUTEX +namespace fnref { // C++14-style aliases for brevity template using remove_const_t = typename std::remove_const::type; template @@ -98,9 +98,9 @@ template struct invoke_result_impl; template struct invoke_result_impl< - F, decltype(invoke(std::declval(), std::declval()...), void()), + F, decltype(tl::detail::fnref::invoke(std::declval(), std::declval()...), void()), Us...> { - using type = decltype(invoke(std::declval(), std::declval()...)); + using type = decltype(tl::detail::fnref::invoke(std::declval(), std::declval()...)); }; template @@ -108,7 +108,6 @@ using invoke_result = invoke_result_impl; template using invoke_result_t = typename invoke_result::type; -#endif template struct is_invocable_r_impl : std::false_type {}; @@ -122,6 +121,7 @@ template using is_invocable_r = is_invocable_r_impl; } // namespace detail +} // namespace fnref /// A lightweight non-owning reference to a callable. /// @@ -147,13 +147,13 @@ template class function_ref { /// /// \synopsis template constexpr function_ref(F &&f) noexcept template , function_ref>::value && - detail::is_invocable_r::value> * = nullptr> + detail::fnref::enable_if_t< + !std::is_same, function_ref>::value && + detail::fnref::is_invocable_r::value> * = nullptr> TL_FUNCTION_REF_11_CONSTEXPR function_ref(F &&f) noexcept : obj_(const_cast(reinterpret_cast(std::addressof(f)))) { callback_ = [](void *obj, Args... args) -> R { - return detail::invoke( + return detail::fnref::invoke( *reinterpret_cast::type>(obj), std::forward(args)...); }; @@ -167,12 +167,12 @@ template class function_ref { /// /// \synopsis template constexpr function_ref &operator=(F &&f) noexcept; template ::value> + detail::fnref::enable_if_t::value> * = nullptr> TL_FUNCTION_REF_11_CONSTEXPR function_ref &operator=(F &&f) noexcept { obj_ = reinterpret_cast(std::addressof(f)); callback_ = [](void *obj, Args... args) { - return detail::invoke( + return detail::fnref::invoke( *reinterpret_cast::type>(obj), std::forward(args)...); }; diff --git a/tests/assignment.cpp b/tests/assignment.cpp index 6ff53c9..9673a6c 100644 --- a/tests/assignment.cpp +++ b/tests/assignment.cpp @@ -1,5 +1,5 @@ #include "catch.hpp" -#include "function_ref.hpp" +#include void f(){} struct b { diff --git a/tests/call.cpp b/tests/call.cpp index 11460a8..497156e 100644 --- a/tests/call.cpp +++ b/tests/call.cpp @@ -1,5 +1,5 @@ #include "catch.hpp" -#include "function_ref.hpp" +#include namespace { bool f_called = false; diff --git a/tests/constructors.cpp b/tests/constructors.cpp index 7fb5f9a..1d0a304 100644 --- a/tests/constructors.cpp +++ b/tests/constructors.cpp @@ -1,5 +1,5 @@ #include "catch.hpp" -#include "function_ref.hpp" +#include void foo(){} struct bar { diff --git a/tests/issues.cpp b/tests/issues.cpp index 12a8426..df40c1d 100644 --- a/tests/issues.cpp +++ b/tests/issues.cpp @@ -1,5 +1,5 @@ #include "catch.hpp" -#include "function_ref.hpp" +#include TEST_CASE("Issue #2") { const auto lam = [](int ) {}; @@ -19,4 +19,14 @@ tl::function_ref bar() TEST_CASE("Issue #9") { bar(); +} + +void foo(const tl::function_ref)>& func) { + REQUIRE(func({ 12 }) == 144); +} + +TEST_CASE("Issue #10") { + int z = 12; + auto f = [&](const std::vector i) { return i[0] * z; }; + foo(f); } \ No newline at end of file