diff --git a/.github/matrix.json b/.github/matrix.json index fd30ac7b..5c816d1f 100644 --- a/.github/matrix.json +++ b/.github/matrix.json @@ -37,8 +37,6 @@ }, { "name": "Windows VS2022", - "compiler": "Visual Studio", - "version": "17.4", "os": "windows-2022", "cxxstd" : "17" } diff --git a/.github/workflows/adobe_source_libraries.yml b/.github/workflows/adobe_source_libraries.yml index 1cc14ce9..ae3390d8 100644 --- a/.github/workflows/adobe_source_libraries.yml +++ b/.github/workflows/adobe_source_libraries.yml @@ -7,6 +7,8 @@ on: - main jobs: + # Information on the runner matrix can be found in the `matrix.json` file. To find available + # versions of compilers, check https://github.com/actions/runner-images/. generate-matrix: name: Generate job matrix runs-on: ubuntu-22.04 diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 0d8d434f..f0ac00d4 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -9,7 +9,7 @@ "macFrameworkPath": [ "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks" ], - "compilerPath": "/usr/bin/clang", + "compilerPath": "/usr/bin/clang++", "cStandard": "c17", "cppStandard": "c++17", "intelliSenseMode": "macos-clang-arm64", @@ -17,4 +17,4 @@ } ], "version": 4 -} \ No newline at end of file +} diff --git a/.vscode/settings.json b/.vscode/settings.json index dacf4164..f58b1676 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ { "files.associations": { + "*.cpp": "cpp", "__bit_reference": "cpp", "__bits": "cpp", "__config": "cpp", @@ -128,6 +129,8 @@ "*.ipp": "cpp", "*.tcc": "cpp", "rope": "cpp", - "slist": "cpp" - } + "slist": "cpp", + "print": "cpp" + }, + "C_Cpp.default.compilerPath": "/usr/bin/clang++" } diff --git a/CMakePresets.json b/CMakePresets.json index dd00a8eb..fc2d88bb 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -24,13 +24,31 @@ } }, { - "name": "macos-debug", - "displayName": "macos-debug", + "name": "macos-debug-C++20", + "displayName": "macos-debug-C++20", "description": "Sets Ninja generator, build and install directory", "generator": "Ninja", "binaryDir": "${sourceDir}/build/${presetName}", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_CXX_STANDARD": "20", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": [ "macOS" ] + } + } + }, + { + "name": "macos-debug-C++17", + "displayName": "macos-debug-C++17", + "description": "Sets Ninja generator, build and install directory", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_CXX_STANDARD": "17", "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}" }, "vendor": { diff --git a/adobe/algorithm/reduce.hpp b/adobe/algorithm/reduce.hpp index 4f16d951..a5daad6d 100644 --- a/adobe/algorithm/reduce.hpp +++ b/adobe/algorithm/reduce.hpp @@ -113,7 +113,7 @@ reduce_balanced(I f, I l, Op op, ADOBE_VALUE_TYPE(I) z = adobe::identity_element ++f; } - return reduce_nonzeros(v.begin(), v.end(), f_transpose(op), z); + return reduce_nonzeros(v.begin(), v.end(), transpose(op), z); } /**************************************************************************************************/ diff --git a/adobe/functional.hpp b/adobe/functional.hpp index 40421869..6f5acd08 100644 --- a/adobe/functional.hpp +++ b/adobe/functional.hpp @@ -11,8 +11,9 @@ #include #include -#include #include +#include +#include #include @@ -124,42 +125,6 @@ pointed to by \c member. An adobe::mem_data_t function object. */ -/*! -\class adobe::indirect_t -\ingroup misc_functional - -\brief Adapter used to convert pointers to references. -*/ - -/*! -\defgroup bitwise_operators Bitwise Operations -\ingroup adobe_functional - -The library provides basic function object classes for all of the bitwise logical operators in the -language. -*/ - -/*! -\class adobe::bitwise_or -\ingroup bitwise_operators - -\brief \c operator() returns x | y. -*/ - -/*! -\class adobe::bitwise_and -\ingroup bitwise_operators - -\brief \c operator() returns x & y. -*/ - -/*! -\class adobe::bitwise_xor -\ingroup bitwise_operators - -\brief \c operator() returns x ^ y. -*/ - /*! \addtogroup misc_functional @{ @@ -301,7 +266,7 @@ struct sequence_t template struct compare_members_t { - compare_members_t(R T::*member, Compare compare) : compare_m(compare), member_m(member) {} + compare_members_t(R T::* member, Compare compare) : compare_m(compare), member_m(member) {} bool operator()(const T& x, const T& y) const { return compare_m(x.*member_m, y.*member_m); } @@ -315,16 +280,16 @@ struct compare_members_t { */ Compare compare_m; - R T::*member_m; + R T::* member_m; }; template -compare_members_t> compare_members(R T::*member) { +compare_members_t> compare_members(R T::* member) { return compare_members_t>(member, std::less()); } template -compare_members_t compare_members(R T::*member, Compare compare) { +compare_members_t compare_members(R T::* member, Compare compare) { return compare_members_t(member, compare); } @@ -334,28 +299,28 @@ template struct mem_data_t { mem_data_t() {} - explicit mem_data_t(R T::*member) : member_m(member) {} + explicit mem_data_t(R T::* member) : member_m(member) {} R& operator()(T& x) const { return x.*member_m; } const R& operator()(const T& x) const { return x.*member_m; } private: - R T::*member_m; + R T::* member_m; }; template struct mem_data_t { - explicit mem_data_t(R T::*member) : member_m(member) {} + explicit mem_data_t(R T::* member) : member_m(member) {} const R& operator()(const T& x) const { return x.*member_m; } private: - R T::*member_m; + R T::* member_m; }; template -mem_data_t mem_data(R T::*member) { +mem_data_t mem_data(R T::* member) { return mem_data_t(member); } @@ -377,24 +342,45 @@ struct equivalent { /**************************************************************************************************/ +/// A function object that transposes the arguments of a binary function. The call qualifiers are +/// preserved. template // F models a BinaryFunction -struct transposer { - typedef typename F::second_argument_type first_argument_type; - typedef typename F::first_argument_type second_argument_type; - typedef typename F::result_type result_type; +struct transpose { + F function; - F fun; + transpose() = default; + explicit transpose(F&& f) noexcept : function(std::move(f)) {} + explicit transpose(const F& f) : function(f) {} - transposer(const F& f) : fun(f) {} + transpose(const transpose& x) = default; + transpose(transpose&& x) noexcept = default; - result_type operator()(const first_argument_type& x, const second_argument_type& y) const { - return fun(y, x); + transpose& operator=(const transpose& x) = default; + transpose& operator=(transpose&& x) noexcept = default; + + template + auto operator()(T1&& x, T2&& y) const& noexcept(std::is_nothrow_invocable_v) { + return function(std::forward(y), std::forward(x)); + } + + template + auto operator()(T1&& x, T2&& y) & noexcept(std::is_nothrow_invocable_v) { + return function(std::forward(y), std::forward(x)); + } + + template + auto operator()(T1&& x, T2&& y) && noexcept(std::is_nothrow_invocable_v) { + return std::move(function)(std::forward(y), std::forward(x)); } }; +template // F models a BinaryFunction +using transposer [[deprecated("Use `adobe::transpose` instead.")]] = transpose; + + template // F models BinaryFunction -inline transposer f_transpose(F f) { - return transposer(f); +inline auto f_transpose [[deprecated("Use `adobe::transpose` instead.")]] (F f) -> transpose { + return transpose(f); } //!@} diff --git a/test/unit_tests/CMakeLists.txt b/test/unit_tests/CMakeLists.txt index 891e201e..b9966b20 100644 --- a/test/unit_tests/CMakeLists.txt +++ b/test/unit_tests/CMakeLists.txt @@ -6,5 +6,6 @@ add_subdirectory(enum_ops) add_subdirectory(equal_range) add_subdirectory(erase) add_subdirectory(forest) +add_subdirectory(functional) add_subdirectory(lower_bound) add_subdirectory(name) diff --git a/test/unit_tests/functional/CMakeLists.txt b/test/unit_tests/functional/CMakeLists.txt new file mode 100644 index 00000000..88f4f29c --- /dev/null +++ b/test/unit_tests/functional/CMakeLists.txt @@ -0,0 +1 @@ +asl_test(BOOST NAME functional_transpose SOURCES functional_test.cpp) diff --git a/test/unit_tests/functional/functional_test.cpp b/test/unit_tests/functional/functional_test.cpp new file mode 100644 index 00000000..bc2bae4f --- /dev/null +++ b/test/unit_tests/functional/functional_test.cpp @@ -0,0 +1,93 @@ +/* + Copyright 2013 Adobe + 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 // file be tested included first + +#include + +#include + +#define BOOST_TEST_MAIN + +// boost +#include + +/**************************************************************************************************/ + +using namespace std; +using namespace adobe; + +namespace { + +/// An enumeration of member function qualifiers as bit fields to identify or mask an overload. +enum member_function_qualifiers { + _none = 0, + _const_lvalue = 1 << 0, + _lvalue = 1 << 1, + _rvalue = 1 << 2, + _all = _const_lvalue | _lvalue | _rvalue +}; + +auto adobe_enable_bitmask_enum(member_function_qualifiers) -> std::true_type; + +/// An overload of a binary function that returns a tuple of its arguments and the qualifiers used. +/// Only the members specified by the noexcept_qualifier mask are noexcept. +template +struct test_binary_function { + auto operator()(int x, int y) const& noexcept((noexcept_qualifier & _const_lvalue) != _none) { + return tuple(x, y, _const_lvalue); + } + auto operator()(int x, int y) & noexcept((noexcept_qualifier & _lvalue) != _none) { + return tuple(x, y, _lvalue); + } + auto operator()(int x, int y) && noexcept((noexcept_qualifier & _rvalue) != _none) { + return tuple(x, y, _rvalue); + } +}; + +} // namespace + +/* + REVISIT(sean-parent) : The static casts are necessary to get this code to compile on VC++14. + It is unclear why the compiler is unable to find the enum operators. +*/ + + +BOOST_AUTO_TEST_CASE(functional_transpose) { + + // Test that the transpose functional object correctly transposes the arguments of a binary + // function. It also tests that the correct overload is selected and that the noexcept + // qualifier is correctly propagated. + + transpose lvalue{ + test_binary_function(_all ^ _lvalue)>{}}; + const transpose const_lvalue{ + test_binary_function(_all ^ _const_lvalue)>{}}; + transpose lvalue_noexcept{test_binary_function<_lvalue>{}}; + const transpose const_lvalue_noexcept{test_binary_function<_const_lvalue>{}}; + + BOOST_TEST((lvalue(1, 2) == tuple(2, 1, _lvalue))); + BOOST_TEST(!noexcept(lvalue(1, 2))); + + BOOST_TEST((const_lvalue(1, 2) == tuple(2, 1, _const_lvalue))); + BOOST_TEST(!noexcept(const_lvalue(1, 2))); + + BOOST_TEST((lvalue_noexcept(1, 2) == tuple(2, 1, _lvalue))); + BOOST_TEST(noexcept(lvalue_noexcept(1, 2))); + + BOOST_TEST((const_lvalue_noexcept(1, 2) == tuple(2, 1, _const_lvalue))); + BOOST_TEST(noexcept(const_lvalue_noexcept(1, 2))); + + BOOST_TEST( + (transpose(test_binary_function(_all ^ _rvalue)>{})( + 1, 2) == tuple(2, 1, _rvalue))); + BOOST_TEST(!noexcept(transpose( + test_binary_function(_all ^ _rvalue)>{})(1, 2))); + + BOOST_TEST((transpose(test_binary_function<_rvalue>{})(1, 2) == tuple(2, 1, _rvalue))); + BOOST_TEST(noexcept(transpose(test_binary_function<_rvalue>{})(1, 2))); +} diff --git a/test/unit_tests/functional/jamfile.jam b/test/unit_tests/functional/jamfile.jam new file mode 100644 index 00000000..d89d0a20 --- /dev/null +++ b/test/unit_tests/functional/jamfile.jam @@ -0,0 +1,5 @@ +# Jamfile for building functional test + +project adobe/functional ; + +run functional_test.cpp ;