From f00c963459c5d90d60f7f8b97c7001dc63207a0d Mon Sep 17 00:00:00 2001 From: "Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com)" Date: Thu, 27 Jul 2017 01:07:14 +0100 Subject: [PATCH] Make includes not Boost path based. --- example/static_map.hpp | 659 ++++++++---------- include/boost/static_views/algorithm_base.hpp | 301 ++++---- .../boost/static_views/detail/find_first.hpp | 12 +- include/boost/static_views/detail/invoke.hpp | 97 ++- include/boost/static_views/detail/utils.hpp | 139 ++-- include/boost/static_views/detail/wrapper.hpp | 235 +++---- include/boost/static_views/drop.hpp | 185 +++-- include/boost/static_views/errors.hpp | 39 +- include/boost/static_views/hashed.hpp | 469 ++++++------- include/boost/static_views/lfold.hpp | 31 +- include/boost/static_views/raw_view.hpp | 263 ++++--- .../boost/static_views/sequence_traits.hpp | 236 +++---- include/boost/static_views/slice.hpp | 280 ++++---- include/boost/static_views/take.hpp | 182 +++-- include/boost/static_views/through.hpp | 200 +++--- include/boost/static_views/view_base.hpp | 553 +++++++-------- 16 files changed, 1768 insertions(+), 2113 deletions(-) diff --git a/example/static_map.hpp b/example/static_map.hpp index d5100a2..4f375e0 100644 --- a/example/static_map.hpp +++ b/example/static_map.hpp @@ -8,413 +8,354 @@ #include -#include -#include -#include -#include -#include - - +#include "../include/boost/static_views/detail/config.hpp" +#include "../include/boost/static_views/detail/find_first.hpp" +#include "../include/boost/static_views/detail/invoke.hpp" +#include "../include/boost/static_views/detail/utils.hpp" +#include "../include/boost/static_views/hashed.hpp" #if __cplusplus > 201402L #if defined(__has_include) -# if __has_include() -# include -# define BOOST_STATIC_VIEWS_HAVE_STRING_VIEW - BOOST_STATIC_VIEWS_BEGIN_NAMESPACE - template > - using basic_string_view = - std::basic_string_view; - using std::string_view; - using std::u16string_view; - using std::u32string_view; - using std::wstring_view; - BOOST_STATIC_VIEWS_END_NAMESPACE -# elif __has_include() -# include -# define BOOST_STATIC_VIEWS_HAVE_STRING_VIEW - BOOST_STATIC_VIEWS_BEGIN_NAMESPACE - template > - using basic_string_view = - std::experimental::basic_string_view; - using std::experimental::string_view; - using std::experimental::u16string_view; - using std::experimental::u32string_view; - using std::experimental::wstring_view; - BOOST_STATIC_VIEWS_END_NAMESPACE -# endif +#if __has_include() +#include +#define BOOST_STATIC_VIEWS_HAVE_STRING_VIEW +BOOST_STATIC_VIEWS_BEGIN_NAMESPACE +template > +using basic_string_view = std::basic_string_view; +using std::string_view; +using std::u16string_view; +using std::u32string_view; +using std::wstring_view; +BOOST_STATIC_VIEWS_END_NAMESPACE +#elif __has_include() +#include +#define BOOST_STATIC_VIEWS_HAVE_STRING_VIEW +BOOST_STATIC_VIEWS_BEGIN_NAMESPACE +template > +using basic_string_view = std::experimental::basic_string_view; +using std::experimental::string_view; +using std::experimental::u16string_view; +using std::experimental::u32string_view; +using std::experimental::wstring_view; +BOOST_STATIC_VIEWS_END_NAMESPACE +#endif #endif #endif - BOOST_STATIC_VIEWS_BEGIN_NAMESPACE namespace static_map { struct key_not_found_error : std::exception { - auto what() const noexcept -> char const* override - { - return _msg; - } + auto what() const noexcept -> char const * override { return _msg; } - private: - static constexpr char const* _msg = "Key not found."; +private: + static constexpr char const *_msg = "Key not found."; }; -constexpr char const* key_not_found_error::_msg; +constexpr char const *key_not_found_error::_msg; namespace detail { - template - using not_equal_t = decltype( std::declval() != std::declval() ); +template +using not_equal_t = decltype(std::declval() != std::declval()); - // clang-format off +// clang-format off template BOOST_STATIC_VIEWS_FORCEINLINE BOOST_STATIC_VIEWS_CONSTEXPR auto length_c(Char const* const str) noexcept -> std::size_t - // clang-format on - { - using boost::static_views::detail::is_detected; - static_assert(std::is_nothrow_default_constructible::value, - "`boost::static_views::static_map::detail::length_c` " - "requires `Char` to be nothrow default-constructible."); - static_assert(is_detected::value, - "`boost::static_views::static_map::detail::length_c` " - "requires `Char` to define `operator!=`."); - static_assert(noexcept(std::declval() != std::declval()), - "`boost::static_views::static_map::detail::length_c` " - "requires `Char`'s `operator!=` to be noexcept."); - - std::size_t i = 0; - while (str[i] != Char{}) { - ++i; - } - return (i == 0) ? 0 : (i - 1); - } +// clang-format on +{ + using boost::static_views::detail::is_detected; + static_assert(std::is_nothrow_default_constructible::value, + "`boost::static_views::static_map::detail::length_c` " + "requires `Char` to be nothrow default-constructible."); + static_assert(is_detected::value, + "`boost::static_views::static_map::detail::length_c` " + "requires `Char` to define `operator!=`."); + static_assert(noexcept(std::declval() != std::declval()), + "`boost::static_views::static_map::detail::length_c` " + "requires `Char`'s `operator!=` to be noexcept."); + + std::size_t i = 0; + while (str[i] != Char{}) { + ++i; + } + return (i == 0) ? 0 : (i - 1); +} - // This algorithm is "stolen" from the Internet. - // clang-format off +// This algorithm is "stolen" from the Internet. +// clang-format off template BOOST_STATIC_VIEWS_FORCEINLINE BOOST_STATIC_VIEWS_CONSTEXPR auto crc32_hash(Char const* const str) noexcept -> std::uint32_t - // clang-format on - { - static_assert(std::is_integral::value, - "`boost::static_views::static_map::detail::crc32_hash` " - "requires `Char` to be an integral type."); - constexpr std::uint32_t INITXOR = 0xFFFFFFFF; - constexpr std::uint32_t FINALXOR = 0xFFFFFFFF; - constexpr std::uint32_t CRCPOLY = 0xEDB88320; - - auto const l = length_c(str); - auto crcreg = INITXOR; - - for (std::size_t j = 0; j < l; ++j) { - auto b = static_cast>(str[j]); - for (std::size_t i = 0; i < 8 * sizeof(Char); ++i) { - if ((crcreg ^ b) & 1) { - crcreg = (crcreg >> 1) ^ CRCPOLY; - } - else { - crcreg >>= 1; - } - b >>= 1; - } - } - - return crcreg ^ FINALXOR; +// clang-format on +{ + static_assert(std::is_integral::value, + "`boost::static_views::static_map::detail::crc32_hash` " + "requires `Char` to be an integral type."); + constexpr std::uint32_t INITXOR = 0xFFFFFFFF; + constexpr std::uint32_t FINALXOR = 0xFFFFFFFF; + constexpr std::uint32_t CRCPOLY = 0xEDB88320; + + auto const l = length_c(str); + auto crcreg = INITXOR; + + for (std::size_t j = 0; j < l; ++j) { + auto b = static_cast>(str[j]); + for (std::size_t i = 0; i < 8 * sizeof(Char); ++i) { + if ((crcreg ^ b) & 1) { + crcreg = (crcreg >> 1) ^ CRCPOLY; + } else { + crcreg >>= 1; + } + b >>= 1; } + } + + return crcreg ^ FINALXOR; +} - // clang-format off +// clang-format off template BOOST_STATIC_VIEWS_FORCEINLINE BOOST_STATIC_VIEWS_CONSTEXPR auto simple_hash(Char const* const str) noexcept - // clang-format on - { - using boost::static_views::detail::is_detected; - static_assert( - std::is_nothrow_default_constructible::value, - "`boost::static_views::static_map::detail::simple_hash<" - "Char>` requires `Char` to be nothrow " - "default-constructible."); - static_assert(is_detected::value, - "`boost::static_views::static_map::detail::simple_hash<" - "Char>` requires `Char` to define `operator!=`."); - static_assert( - noexcept(std::declval() != std::declval()), - "`boost::static_views::static_map::detail::simple_hash<" - "Char>` requires `Char`'s `operator!=` to be noexcept."); - std::size_t hash = 0; - std::size_t i = 0; - while (str[i] != Char{}) { - hash = 37 * hash - + static_cast>(str[i]); - ++i; - } - return hash; - } +// clang-format on +{ + using boost::static_views::detail::is_detected; + static_assert(std::is_nothrow_default_constructible::value, + "`boost::static_views::static_map::detail::simple_hash<" + "Char>` requires `Char` to be nothrow " + "default-constructible."); + static_assert(is_detected::value, + "`boost::static_views::static_map::detail::simple_hash<" + "Char>` requires `Char` to define `operator!=`."); + static_assert(noexcept(std::declval() != std::declval()), + "`boost::static_views::static_map::detail::simple_hash<" + "Char>` requires `Char`'s `operator!=` to be noexcept."); + std::size_t hash = 0; + std::size_t i = 0; + while (str[i] != Char{}) { + hash = 37 * hash + static_cast>(str[i]); + ++i; + } + return hash; +} - template - struct hash_impl; +template struct hash_impl; - template - struct hash_impl::value>> { +template +struct hash_impl::value>> { - BOOST_STATIC_VIEWS_CONSTEXPR - auto operator()(T const x) const noexcept -> std::size_t - { - return static_cast(x); - } - }; + BOOST_STATIC_VIEWS_CONSTEXPR + auto operator()(T const x) const noexcept -> std::size_t { + return static_cast(x); + } +}; - template - struct hash_impl::value>> { +template +struct hash_impl::value>> { - BOOST_STATIC_VIEWS_CONSTEXPR - auto operator()(Char const* const x) const noexcept - -> std::size_t - { - return simple_hash(x); - // return static_cast(crc32_hash(x)); - } - }; + BOOST_STATIC_VIEWS_CONSTEXPR + auto operator()(Char const *const x) const noexcept -> std::size_t { + return simple_hash(x); + // return static_cast(crc32_hash(x)); + } +}; #if defined(BOOST_STATIC_VIEWS_HAVE_STRING_VIEW) - template - struct hash_impl> { +template struct hash_impl> { - BOOST_STATIC_VIEWS_CONSTEXPR auto operator()( - basic_string_view const x) const noexcept - -> std::size_t - { - return hash_impl{}(x.data()); - } - }; + BOOST_STATIC_VIEWS_CONSTEXPR auto + operator()(basic_string_view const x) const noexcept -> std::size_t { + return hash_impl{}(x.data()); + } +}; #endif } // namespace detail struct hash_c { - template - BOOST_STATIC_VIEWS_FORCEINLINE - BOOST_STATIC_VIEWS_CONSTEXPR - auto operator()(T&& x) const - BOOST_STATIC_VIEWS_NOEXCEPT_IF(noexcept( - detail::hash_impl>{}(std::forward(x)))) - -> std::size_t - { - return detail::hash_impl>{}(std::forward(x)); - } + template + BOOST_STATIC_VIEWS_FORCEINLINE BOOST_STATIC_VIEWS_CONSTEXPR auto + operator()(T &&x) const BOOST_STATIC_VIEWS_NOEXCEPT_IF( + noexcept(detail::hash_impl>{}(std::forward(x)))) + -> std::size_t { + return detail::hash_impl>{}(std::forward(x)); + } }; - namespace detail { +template +class static_map : private HashedView { + + // Make sure HashedView is actually a View. + static_assert(boost::static_views::detail::concepts::is_View(), + BOOST_STATIC_VIEWS_BUG_MESSAGE); + + // Make sure Pred is not a strange reference or something. + static_assert(std::is_same>::value, + BOOST_STATIC_VIEWS_BUG_MESSAGE); + + // Make sure Pred is a wrapper. + static_assert(boost::static_views::detail::is_wrapper::value, + BOOST_STATIC_VIEWS_BUG_MESSAGE); + + // Make sure GetKey is not a strange reference or something. + static_assert(std::is_same>::value, + BOOST_STATIC_VIEWS_BUG_MESSAGE); + + // Make sure GetKey is a wrapper. + static_assert(boost::static_views::detail::is_wrapper::value, + BOOST_STATIC_VIEWS_BUG_MESSAGE); + + // Make sure GetMapped is not a strange reference or something. + static_assert(std::is_same>::value, + BOOST_STATIC_VIEWS_BUG_MESSAGE); + + // Make sure GetMapped is a wrapper. + static_assert(boost::static_views::detail::is_wrapper::value, + BOOST_STATIC_VIEWS_BUG_MESSAGE); + +private: + using bucket_type = std::decay_t()[std::declval()])>; + + // Make sure buckets are actually Views. + static_assert(boost::static_views::detail::concepts::is_View(), + BOOST_STATIC_VIEWS_BUG_MESSAGE); + +public: + using type = static_map; + using value_type = std::remove_reference_t()[std::declval()])>; + using key_getter = typename GetKey::type; + using value_getter = typename GetMapped::type; + +private: + template + using callable_with_value_t = decltype(boost::static_views::invoke( + std::declval(), std::declval())); + + static_assert(boost::static_views::detail::is_detected::value, + BOOST_STATIC_VIEWS_BUG_MESSAGE); + static_assert(boost::static_views::detail::is_detected::value, + BOOST_STATIC_VIEWS_BUG_MESSAGE); + +public: + using key_type = std::remove_reference_t(), std::declval()))>; + using mapped_type = + std::remove_reference_t(), std::declval()))>; + using key_equal = typename Pred::type; + +private: + template + using callable_with_key_t = decltype(boost::static_views::invoke( + std::declval(), std::declval())); + + template + using callable_with_2_key_t = + decltype(boost::static_views::invoke(std::declval(), + std::declval(), + std::declval())); + + static_assert(boost::static_views::detail::is_detected::value, + BOOST_STATIC_VIEWS_BUG_MESSAGE); + +public: + using hasher = std::decay_t().hash_function()._hf.get())>; + static_assert( + std::is_convertible< + boost::static_views::detail::detected_t, + std::size_t>::value, + BOOST_STATIC_VIEWS_BUG_MESSAGE); + using difference_type = std::ptrdiff_t; + using size_type = std::size_t; + +private: + using view_type = HashedView; + + Pred _eq; + GetKey _get_key; + GetMapped _get_mapped; + + BOOST_STATIC_VIEWS_FORCEINLINE + BOOST_STATIC_VIEWS_CONSTEXPR + BOOST_STATIC_VIEWS_DECLTYPE_AUTO _hash_function() const { + return this->hash_function()._hf.get(); + } + + BOOST_STATIC_VIEWS_FORCEINLINE + BOOST_STATIC_VIEWS_CONSTEXPR + auto _lookup(key_type const &k) const -> value_type const * { + struct pred_equal { + key_getter const &get_key; + key_equal const &equal; + key_type const &x; + + BOOST_STATIC_VIEWS_CONSTEXPR + auto operator()(value_type const &y) -> bool { + return boost::static_views::invoke( + equal, x, boost::static_views::invoke(get_key, y)); + } + }; - template - class static_map : private HashedView { - - // Make sure HashedView is actually a View. - static_assert(boost::static_views::detail::concepts::is_View< - HashedView>(), - BOOST_STATIC_VIEWS_BUG_MESSAGE); - - // Make sure Pred is not a strange reference or something. - static_assert(std::is_same>::value, - BOOST_STATIC_VIEWS_BUG_MESSAGE); - - // Make sure Pred is a wrapper. - static_assert( - boost::static_views::detail::is_wrapper::value, - BOOST_STATIC_VIEWS_BUG_MESSAGE); - - // Make sure GetKey is not a strange reference or something. - static_assert( - std::is_same>::value, - BOOST_STATIC_VIEWS_BUG_MESSAGE); - - // Make sure GetKey is a wrapper. - static_assert( - boost::static_views::detail::is_wrapper::value, - BOOST_STATIC_VIEWS_BUG_MESSAGE); - - // Make sure GetMapped is not a strange reference or something. - static_assert( - std::is_same>::value, - BOOST_STATIC_VIEWS_BUG_MESSAGE); - - // Make sure GetMapped is a wrapper. - static_assert( - boost::static_views::detail::is_wrapper::value, - BOOST_STATIC_VIEWS_BUG_MESSAGE); - - private: - using bucket_type = std::decay_t()[std::declval()])>; - - // Make sure buckets are actually Views. - static_assert(boost::static_views::detail::concepts::is_View< - bucket_type>(), - BOOST_STATIC_VIEWS_BUG_MESSAGE); - - - public: - using type = static_map; - using value_type = - std::remove_reference_t()[std::declval()])>; - using key_getter = typename GetKey::type; - using value_getter = typename GetMapped::type; - - private: - template - using callable_with_value_t = decltype( - boost::static_views::invoke(std::declval(), - std::declval())); - - static_assert(boost::static_views::detail::is_detected< - callable_with_value_t, key_getter>::value, - BOOST_STATIC_VIEWS_BUG_MESSAGE); - static_assert(boost::static_views::detail::is_detected< - callable_with_value_t, value_getter>::value, - BOOST_STATIC_VIEWS_BUG_MESSAGE); - - public: - using key_type = std::remove_reference_t(), - std::declval()))>; - using mapped_type = std::remove_reference_t(), - std::declval()))>; - using key_equal = typename Pred::type; - - private: - template - using callable_with_key_t = decltype( - boost::static_views::invoke(std::declval(), - std::declval())); - - template - using callable_with_2_key_t = decltype( - boost::static_views::invoke(std::declval(), - std::declval(), - std::declval())); - - static_assert(boost::static_views::detail::is_detected< - callable_with_2_key_t, key_equal>::value, - BOOST_STATIC_VIEWS_BUG_MESSAGE); - - public: - using hasher = - std::decay_t() - .hash_function() - ._hf.get())>; - static_assert(std::is_convertible< - boost::static_views::detail::detected_t< - callable_with_key_t, hasher>, - std::size_t>::value, - BOOST_STATIC_VIEWS_BUG_MESSAGE); - using difference_type = std::ptrdiff_t; - using size_type = std::size_t; - - private: - using view_type = HashedView; - - Pred _eq; - GetKey _get_key; - GetMapped _get_mapped; - - - BOOST_STATIC_VIEWS_FORCEINLINE - BOOST_STATIC_VIEWS_CONSTEXPR - BOOST_STATIC_VIEWS_DECLTYPE_AUTO _hash_function() const - { - return this->hash_function()._hf.get(); - } - - BOOST_STATIC_VIEWS_FORCEINLINE - BOOST_STATIC_VIEWS_CONSTEXPR - auto _lookup(key_type const& k) const -> value_type const* - { - struct pred_equal { - key_getter const& get_key; - key_equal const& equal; - key_type const& x; - - BOOST_STATIC_VIEWS_CONSTEXPR - auto operator()(value_type const& y) -> bool - { - return boost::static_views::invoke( - equal, x, boost::static_views::invoke(get_key, y)); - } - }; - - // get all elements matching key k - auto const ys = - static_cast(this)->operator[]( - boost::static_views::invoke(_hash_function(), k)); - // search for the one that compares equal to k - auto const i = boost::static_views::find_first_i( - ys, pred_equal{_get_key.get(), _eq.get(), k}); - - return (i < ys.size()) ? &(ys[i]) : nullptr; - } - - public: - BOOST_STATIC_VIEWS_CONSTEXPR - static_map(view_type&& xs, Pred&& eq, GetKey&& get_key, - GetMapped&& get_mapped) - : view_type{std::move(xs)} - , _eq{std::move(eq)} - , _get_key{std::move(get_key)} - , _get_mapped{std::move(get_mapped)} - { - } - - BOOST_STATIC_VIEWS_CONSTEXPR - auto size() const -> size_type - { - return static_cast(this)->size(); - } - - BOOST_STATIC_VIEWS_FORCEINLINE - BOOST_STATIC_VIEWS_CONSTEXPR - auto find(key_type const& k) const -> value_type* - { - return _lookup(k); - } - - BOOST_STATIC_VIEWS_FORCEINLINE - BOOST_STATIC_VIEWS_CONSTEXPR - auto count(key_type const& k) const -> size_type - { - return _lookup(k) == nullptr ? 0 : 1; - } - - BOOST_STATIC_VIEWS_FORCEINLINE - BOOST_STATIC_VIEWS_CONSTEXPR - decltype(auto) at(key_type const& k) const - { - auto* x = _lookup(k); - if (x == nullptr) { - throw key_not_found_error{}; - } - return invoke(_get_mapped.get(), *x); - } + // get all elements matching key k + auto const ys = static_cast(this)->operator[]( + boost::static_views::invoke(_hash_function(), k)); + // search for the one that compares equal to k + auto const i = boost::static_views::find_first_i( + ys, pred_equal{_get_key.get(), _eq.get(), k}); + + return (i < ys.size()) ? &(ys[i]) : nullptr; + } + +public: + BOOST_STATIC_VIEWS_CONSTEXPR + static_map(view_type &&xs, Pred &&eq, GetKey &&get_key, + GetMapped &&get_mapped) + : view_type{std::move(xs)}, _eq{std::move(eq)}, + _get_key{std::move(get_key)}, _get_mapped{std::move(get_mapped)} {} + + BOOST_STATIC_VIEWS_CONSTEXPR + auto size() const -> size_type { + return static_cast(this)->size(); + } + + BOOST_STATIC_VIEWS_FORCEINLINE + BOOST_STATIC_VIEWS_CONSTEXPR + auto find(key_type const &k) const -> value_type * { return _lookup(k); } + + BOOST_STATIC_VIEWS_FORCEINLINE + BOOST_STATIC_VIEWS_CONSTEXPR + auto count(key_type const &k) const -> size_type { + return _lookup(k) == nullptr ? 0 : 1; + } + + BOOST_STATIC_VIEWS_FORCEINLINE + BOOST_STATIC_VIEWS_CONSTEXPR + decltype(auto) at(key_type const &k) const { + auto *x = _lookup(k); + if (x == nullptr) { + throw key_not_found_error{}; + } + return invoke(_get_mapped.get(), *x); + } - BOOST_STATIC_VIEWS_FORCEINLINE - BOOST_STATIC_VIEWS_CONSTEXPR - decltype(auto) operator[](key_type const& k) const - { - return at(k); - } - }; + BOOST_STATIC_VIEWS_FORCEINLINE + BOOST_STATIC_VIEWS_CONSTEXPR + decltype(auto) operator[](key_type const &k) const { return at(k); } +}; } // namespace detail @@ -469,10 +410,4 @@ auto make_static_map(View&& xs, GetKey&& get_key, GetMapped&& get_mapped, BOOST_STATIC_VIEWS_END_NAMESPACE - - - - - - #endif // BOOST_STATIC_VIEWS_STATIC_MAP_HPP diff --git a/include/boost/static_views/algorithm_base.hpp b/include/boost/static_views/algorithm_base.hpp index ee80812..2472f6d 100644 --- a/include/boost/static_views/algorithm_base.hpp +++ b/include/boost/static_views/algorithm_base.hpp @@ -6,13 +6,14 @@ #ifndef BOOST_STATIC_VIEWS_ALGORITHM_BASE_HPP #define BOOST_STATIC_VIEWS_ALGORITHM_BASE_HPP +#include "detail/config.hpp" +#include "detail/utils.hpp" +#include "detail/wrapper.hpp" +#include "view_base.hpp" + #include #include #include -#include -#include -#include -#include BOOST_STATIC_VIEWS_BEGIN_NAMESPACE @@ -22,8 +23,7 @@ BOOST_STATIC_VIEWS_BEGIN_NAMESPACE /// By deriving from :cpp:class:`algorithm_base`, you tell StaticView /// that the derived class models the :ref:`view ` /// concept. \endverbatim -struct algorithm_base { -}; +struct algorithm_base {}; /// \brief Checks whether `T` models the Algorithm concept. @@ -38,35 +38,31 @@ struct algorithm_base { /// {}; /// /// \endverbatim -template -struct is_algorithm : std::is_base_of { -}; +template struct is_algorithm : std::is_base_of {}; namespace detail { template struct algorithm_impl : algorithm_base { - private: - Function _func; - std::tuple...> _args; - - template - static constexpr auto is_noexcept_call_cref() noexcept -> bool - { - return noexcept(invoke(std::declval(), - make_wrapper(std::declval()), - std::declval()...)); - } - - template - static constexpr auto is_noexcept_call_move() noexcept -> bool - { - return noexcept(invoke(std::declval(), - make_wrapper(std::declval()), - std::declval()...)); - } - - // clang-format off +private: + Function _func; + std::tuple...> _args; + + template + static constexpr auto is_noexcept_call_cref() noexcept -> bool { + return noexcept(invoke(std::declval(), + make_wrapper(std::declval()), + std::declval()...)); + } + + template + static constexpr auto is_noexcept_call_move() noexcept -> bool { + return noexcept(invoke(std::declval(), + make_wrapper(std::declval()), + std::declval()...)); + } + + // clang-format off template BOOST_STATIC_VIEWS_FORCEINLINE BOOST_STATIC_VIEWS_CONSTEXPR @@ -78,21 +74,21 @@ struct algorithm_impl : algorithm_base { return invoke(_func, make_wrapper(std::forward(xs)), std::get(_args).get()...); } - // clang-format on - - /* // I think that this overload makes little sense - template - BOOST_FORCEINLINE - BOOST_STATIC_VIEWS_CONSTEXPR - BOOST_STATIC_VIEWS_DECLTYPE_AUTO call_impl(View&& xs, - std::index_sequence) & - { - return invoke(_func, make_wrapper(std::forward(xs)), - std::get(_args).get()...); - } - */ - - // clang-format off + // clang-format on + + /* // I think that this overload makes little sense + template + BOOST_FORCEINLINE + BOOST_STATIC_VIEWS_CONSTEXPR + BOOST_STATIC_VIEWS_DECLTYPE_AUTO call_impl(View&& xs, + std::index_sequence) & + { + return invoke(_func, make_wrapper(std::forward(xs)), + std::get(_args).get()...); + } + */ + + // clang-format off template BOOST_STATIC_VIEWS_FORCEINLINE BOOST_STATIC_VIEWS_CONSTEXPR @@ -105,39 +101,35 @@ struct algorithm_impl : algorithm_base { make_wrapper(std::forward(xs)), std::get(std::move(_args)).get()...); } - // clang-format on + // clang-format on - public: - - explicit BOOST_STATIC_VIEWS_CONSTEXPR algorithm_impl( - Function&& f, wrapper&&... args) +public: + explicit BOOST_STATIC_VIEWS_CONSTEXPR algorithm_impl(Function &&f, + wrapper &&... args) #if defined(BOOST_STATIC_VIEWS_NEGLECT_STD_TUPLE) - // std::tuple's constructor is not marked noexcept in most of - // the implementations. We "know", however, that the only - // thing std::tuple's move constructor needs is for each Args - // to be nothrow move constructible. Hence, we can "neglect" - // the fact that std::tuple's move constructor is not - // noexcept. - BOOST_STATIC_VIEWS_NOEXCEPT_IF( - utils::all(std::is_nothrow_move_constructible< - wrapper>::value..., - std::is_nothrow_move_constructible::value)) + // std::tuple's constructor is not marked noexcept in most of + // the implementations. We "know", however, that the only + // thing std::tuple's move constructor needs is for each Args + // to be nothrow move constructible. Hence, we can "neglect" + // the fact that std::tuple's move constructor is not + // noexcept. + BOOST_STATIC_VIEWS_NOEXCEPT_IF(utils::all( + std::is_nothrow_move_constructible>::value..., + std::is_nothrow_move_constructible::value)) #else - BOOST_STATIC_VIEWS_NOEXCEPT_IF( - utils::all(std::is_nothrow_move_constructible< - std::tuple...>>::value, - std::is_nothrow_move_constructible::value)) + BOOST_STATIC_VIEWS_NOEXCEPT_IF( + utils::all(std::is_nothrow_move_constructible< + std::tuple...>>::value, + std::is_nothrow_move_constructible::value)) #endif - : _func{std::move(f)}, _args{std::move(args)...} - { - } + : _func{std::move(f)}, _args{std::move(args)...} { + } -#define FAKE_CALL_IMPL(qualifiers) \ - std::declval().call_impl( \ - std::forward(xs), \ - std::make_index_sequence{}) +#define FAKE_CALL_IMPL(qualifiers) \ + std::declval().call_impl( \ + std::forward(xs), std::make_index_sequence{}) - // clang-format off + // clang-format off template BOOST_STATIC_VIEWS_FORCEINLINE BOOST_STATIC_VIEWS_CONSTEXPR @@ -148,23 +140,23 @@ struct algorithm_impl : algorithm_base { return call_impl(std::forward(xs), std::make_index_sequence{}); } - // clang-format on - - /* - template - BOOST_FORCEINLINE - BOOST_STATIC_VIEWS_CONSTEXPR - BOOST_STATIC_VIEWS_DECLTYPE_AUTO operator()(View&& xs) & - BOOST_STATIC_VIEWS_NOEXCEPT_IF(noexcept(FAKE_CALL_IMPL(&))) - { - static_assert(is_view>::value, - "`View` must model the View concept."); - return call_impl(std::forward(xs), - std::make_index_sequence{}); - } - */ - - // clang-format off + // clang-format on + + /* + template + BOOST_FORCEINLINE + BOOST_STATIC_VIEWS_CONSTEXPR + BOOST_STATIC_VIEWS_DECLTYPE_AUTO operator()(View&& xs) & + BOOST_STATIC_VIEWS_NOEXCEPT_IF(noexcept(FAKE_CALL_IMPL(&))) + { + static_assert(is_view>::value, + "`View` must model the View concept."); + return call_impl(std::forward(xs), + std::make_index_sequence{}); + } + */ + + // clang-format off template BOOST_STATIC_VIEWS_FORCEINLINE BOOST_STATIC_VIEWS_CONSTEXPR @@ -176,87 +168,79 @@ struct algorithm_impl : algorithm_base { std::forward(xs), std::make_index_sequence{}); } - // clang-format on +// clang-format on #undef FAKE_CALL_IMPL - BOOST_STATIC_VIEWS_CONSTEXPR - algorithm_impl(algorithm_impl const& other) + BOOST_STATIC_VIEWS_CONSTEXPR + algorithm_impl(algorithm_impl const &other) #if defined(BOOST_STATIC_VIEWS_NEGLECT_STD_TUPLE) - BOOST_STATIC_VIEWS_NOEXCEPT_IF(utils::all( - std::is_nothrow_copy_constructible::value, - std::is_nothrow_copy_constructible< - wrapper>::value...)) + BOOST_STATIC_VIEWS_NOEXCEPT_IF(utils::all( + std::is_nothrow_copy_constructible::value, + std::is_nothrow_copy_constructible>::value...)) #else - BOOST_STATIC_VIEWS_NOEXCEPT_IF(utils::all( - std::is_nothrow_copy_constructible::value, - std::is_nothrow_copy_constructible< - std::tuple...>>::value)) + BOOST_STATIC_VIEWS_NOEXCEPT_IF( + utils::all(std::is_nothrow_copy_constructible::value, + std::is_nothrow_copy_constructible< + std::tuple...>>::value)) #endif - : _func{other._func}, _args{other._args} - { - } + : _func{other._func}, _args{other._args} { + } - BOOST_STATIC_VIEWS_CONSTEXPR - algorithm_impl(algorithm_impl&& other) + BOOST_STATIC_VIEWS_CONSTEXPR + algorithm_impl(algorithm_impl &&other) #if defined(BOOST_STATIC_VIEWS_NEGLECT_STD_TUPLE) - BOOST_STATIC_VIEWS_NOEXCEPT_IF(utils::all( - std::is_nothrow_move_constructible::value, - std::is_nothrow_move_constructible< - wrapper>::value...)) + BOOST_STATIC_VIEWS_NOEXCEPT_IF(utils::all( + std::is_nothrow_move_constructible::value, + std::is_nothrow_move_constructible>::value...)) #else - BOOST_STATIC_VIEWS_NOEXCEPT_IF(utils::all( - std::is_nothrow_move_constructible::value, - std::is_nothrow_move_constructible< - std::tuple...>>::value)) + BOOST_STATIC_VIEWS_NOEXCEPT_IF( + utils::all(std::is_nothrow_move_constructible::value, + std::is_nothrow_move_constructible< + std::tuple...>>::value)) #endif - : _func{std::move(other._func)}, _args{std::move(other._args)} - { - } + : _func{std::move(other._func)}, _args{std::move(other._args)} { + } - BOOST_STATIC_VIEWS_CONSTEXPR - algorithm_impl& operator=(algorithm_impl const& other) + BOOST_STATIC_VIEWS_CONSTEXPR + algorithm_impl &operator=(algorithm_impl const &other) #if defined(BOOST_STATIC_VIEWS_NEGLECT_STD_TUPLE) - BOOST_STATIC_VIEWS_NOEXCEPT_IF(utils::all( - std::is_nothrow_copy_assignable::value, - std::is_nothrow_copy_assignable>::value...)) + BOOST_STATIC_VIEWS_NOEXCEPT_IF( + utils::all(std::is_nothrow_copy_assignable::value, + std::is_nothrow_copy_assignable>::value...)) #else - BOOST_STATIC_VIEWS_NOEXCEPT_IF(utils::all( - std::is_nothrow_copy_assignable::value, - std::is_nothrow_copy_assignable< - std::tuple...>>::value)) + BOOST_STATIC_VIEWS_NOEXCEPT_IF(utils::all( + std::is_nothrow_copy_assignable::value, + std::is_nothrow_copy_assignable...>>::value)) #endif - { - _func = other._func; - _args = other._args; - return *this; - } - - BOOST_STATIC_VIEWS_CONSTEXPR - algorithm_impl& operator=(algorithm_impl&& other) + { + _func = other._func; + _args = other._args; + return *this; + } + + BOOST_STATIC_VIEWS_CONSTEXPR + algorithm_impl &operator=(algorithm_impl &&other) #if defined(BOOST_STATIC_VIEWS_NEGLECT_STD_TUPLE) - BOOST_STATIC_VIEWS_NOEXCEPT_IF(utils::all( - std::is_nothrow_move_assignable::value, - std::is_nothrow_move_assignable>::value...)) + BOOST_STATIC_VIEWS_NOEXCEPT_IF( + utils::all(std::is_nothrow_move_assignable::value, + std::is_nothrow_move_assignable>::value...)) #else - BOOST_STATIC_VIEWS_NOEXCEPT_IF(utils::all( - std::is_nothrow_move_assignable::value, - std::is_nothrow_move_assignable< - std::tuple...>>::value)) + BOOST_STATIC_VIEWS_NOEXCEPT_IF(utils::all( + std::is_nothrow_move_assignable::value, + std::is_nothrow_move_assignable...>>::value)) #endif - { - _func = std::move(other._func); - _args = std::move(other._args); - return *this; - } - - ~algorithm_impl() = default; + { + _func = std::move(other._func); + _args = std::move(other._args); + return *this; + } + ~algorithm_impl() = default; }; -template -struct make_algorithm_impl { - // clang-format off +template struct make_algorithm_impl { + // clang-format off template BOOST_STATIC_VIEWS_FORCEINLINE BOOST_STATIC_VIEWS_CONSTEXPR @@ -274,19 +258,18 @@ struct make_algorithm_impl { return algorithm_impl( Function{}, make_wrapper(std::forward(args))...); } - // clang-format on + // clang-format on }; } // namespace detail -#define BOOST_STATIC_VIEWS_INLINE_ALGO_VARIABLE(type, name) \ - inline namespace { \ - BOOST_STATIC_VIEWS_CONSTEXPR auto const& name = \ - ::BOOST_STATIC_VIEWS_NAMESPACE::_static_const< \ - ::BOOST_STATIC_VIEWS_NAMESPACE::detail:: \ - make_algorithm_impl>; \ - } \ - /**/ +#define BOOST_STATIC_VIEWS_INLINE_ALGO_VARIABLE(type, name) \ + inline namespace { \ + BOOST_STATIC_VIEWS_CONSTEXPR auto const &name = \ + ::BOOST_STATIC_VIEWS_NAMESPACE::_static_const< \ + ::BOOST_STATIC_VIEWS_NAMESPACE::detail::make_algorithm_impl>; \ + } \ +/**/ BOOST_STATIC_VIEWS_END_NAMESPACE diff --git a/include/boost/static_views/detail/find_first.hpp b/include/boost/static_views/detail/find_first.hpp index cfda644..f17bdbb 100644 --- a/include/boost/static_views/detail/find_first.hpp +++ b/include/boost/static_views/detail/find_first.hpp @@ -8,15 +8,16 @@ #include #include -#include -#include + +#include "config.hpp" +#include "utils.hpp" BOOST_STATIC_VIEWS_BEGIN_NAMESPACE namespace detail { struct find_first_i_impl { - // clang-format off + // clang-format off template BOOST_STATIC_VIEWS_CONSTEXPR auto operator()(View&& xs, Predicate&& p = Predicate{}) const @@ -34,13 +35,12 @@ struct find_first_i_impl { } return i; } - // clang-format on + // clang-format on }; } // namespace detail -BOOST_STATIC_VIEWS_INLINE_VARIABLE( - detail::find_first_i_impl, find_first_i) +BOOST_STATIC_VIEWS_INLINE_VARIABLE(detail::find_first_i_impl, find_first_i) BOOST_STATIC_VIEWS_END_NAMESPACE diff --git a/include/boost/static_views/detail/invoke.hpp b/include/boost/static_views/detail/invoke.hpp index 62090f7..2a14d60 100644 --- a/include/boost/static_views/detail/invoke.hpp +++ b/include/boost/static_views/detail/invoke.hpp @@ -9,24 +9,21 @@ #ifndef BOOST_STATIC_VIEWS_DETAIL_INVOKE_HPP #define BOOST_STATIC_VIEWS_DETAIL_INVOKE_HPP +#include "config.hpp" + #include #include -#include BOOST_STATIC_VIEWS_BEGIN_NAMESPACE namespace detail { /// \brief Trait that determines whether `T` is a reference_wrapper. -template -struct is_reference_wrapper : std::false_type { -}; +template struct is_reference_wrapper : std::false_type {}; /// \cond template -struct is_reference_wrapper> - : std::true_type { -}; +struct is_reference_wrapper> : std::true_type {}; /// \endcond #if 0 // Current implementations of invoke are not constexpr. @@ -195,52 +192,46 @@ constexpr decltype(auto) invoke_nonmember // clang-format on struct invoke_impl { - private: - template ::value>> - BOOST_STATIC_VIEWS_FORCEINLINE static constexpr decltype(auto) - call_impl(Function(T::*f), Object&& obj) - BOOST_STATIC_VIEWS_NOEXCEPT_IF(noexcept( - invoke_member_data(f, std::forward(obj)))) - { - return invoke_member_data(f, std::forward(obj)); - } - - template ::value>> - BOOST_STATIC_VIEWS_FORCEINLINE static constexpr decltype(auto) - call_impl(Function(T::*f), Object&& obj, Args&&... args) - BOOST_STATIC_VIEWS_NOEXCEPT_IF(noexcept(invoke_member_func(f, - std::forward(obj), std::forward(args)...))) - { - return invoke_member_func(f, std::forward(obj), - std::forward(args)...); - } - - template >::value>> - BOOST_STATIC_VIEWS_FORCEINLINE static constexpr decltype(auto) - call_impl(Function&& f, Args&&... args) - BOOST_STATIC_VIEWS_NOEXCEPT_IF(noexcept(invoke_nonmember( - std::forward(f), std::forward(args)...))) - { - return invoke_nonmember( - std::forward(f), std::forward(args)...); - } - - public: - template - BOOST_STATIC_VIEWS_FORCEINLINE constexpr decltype(auto) - operator()(Function&& f, Args&&... args) const - BOOST_STATIC_VIEWS_NOEXCEPT_IF(noexcept(call_impl( - std::forward(f), std::forward(args)...))) - { - return call_impl( - std::forward(f), std::forward(args)...); - } +private: + template ::value>> + BOOST_STATIC_VIEWS_FORCEINLINE static constexpr decltype(auto) + call_impl(Function(T::*f), Object &&obj) BOOST_STATIC_VIEWS_NOEXCEPT_IF( + noexcept(invoke_member_data(f, std::forward(obj)))) { + return invoke_member_data(f, std::forward(obj)); + } + + template ::value>> + BOOST_STATIC_VIEWS_FORCEINLINE static constexpr decltype(auto) + call_impl(Function(T::*f), Object &&obj, Args &&... args) + BOOST_STATIC_VIEWS_NOEXCEPT_IF(noexcept(invoke_member_func( + f, std::forward(obj), std::forward(args)...))) { + return invoke_member_func(f, std::forward(obj), + std::forward(args)...); + } + + template >::value>> + BOOST_STATIC_VIEWS_FORCEINLINE static constexpr decltype(auto) + call_impl(Function &&f, Args &&... args) + BOOST_STATIC_VIEWS_NOEXCEPT_IF(noexcept(invoke_nonmember( + std::forward(f), std::forward(args)...))) { + return invoke_nonmember(std::forward(f), + std::forward(args)...); + } + +public: + template + BOOST_STATIC_VIEWS_FORCEINLINE constexpr decltype(auto) + operator()(Function &&f, Args &&... args) const + BOOST_STATIC_VIEWS_NOEXCEPT_IF(noexcept( + call_impl(std::forward(f), std::forward(args)...))) { + return call_impl(std::forward(f), std::forward(args)...); + } }; #endif // if C++17 diff --git a/include/boost/static_views/detail/utils.hpp b/include/boost/static_views/detail/utils.hpp index 3193760..ab01d22 100644 --- a/include/boost/static_views/detail/utils.hpp +++ b/include/boost/static_views/detail/utils.hpp @@ -6,43 +6,42 @@ #ifndef BOOST_STATIC_VIEWS_DETAIL_UTILS_HPP #define BOOST_STATIC_VIEWS_DETAIL_UTILS_HPP +#include "config.hpp" + #include #include -#include BOOST_STATIC_VIEWS_BEGIN_NAMESPACE namespace detail { namespace utils { - constexpr auto all() noexcept -> bool { return true; } +constexpr auto all() noexcept -> bool { return true; } - template - constexpr auto all(bool const x, Bools... xs) noexcept -> bool - { - return x && all(xs...); - } +template +constexpr auto all(bool const x, Bools... xs) noexcept -> bool { + return x && all(xs...); +} } // namespace utils #if defined(__cpp_lib_void_t) && __cpp_lib_void_t >= 201411 - using std::void_t; +using std::void_t; #else - template - using void_t = void; +template using void_t = void; #endif struct nonesuch { - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - nonesuch(nonesuch&&) = delete; - nonesuch& operator=(nonesuch const&) = delete; - nonesuch& operator=(nonesuch&&) = delete; + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const &) = delete; + nonesuch(nonesuch &&) = delete; + nonesuch &operator=(nonesuch const &) = delete; + nonesuch &operator=(nonesuch &&) = delete; }; struct not_copy_constructible { - // clang-format off + // clang-format off not_copy_constructible(not_copy_constructible const&) = delete; constexpr not_copy_constructible() @@ -53,11 +52,11 @@ struct not_copy_constructible { noexcept = default; constexpr not_copy_constructible& operator=(not_copy_constructible&&) noexcept = default; - // clang-format on + // clang-format on }; struct not_move_constructible { - // clang-format off + // clang-format off not_move_constructible(not_move_constructible&&) = delete; constexpr not_move_constructible() @@ -68,11 +67,11 @@ struct not_move_constructible { noexcept = default; constexpr not_move_constructible& operator=(not_move_constructible&&) noexcept = default; - // clang-format on + // clang-format on }; struct not_copy_assignable { - // clang-format off + // clang-format off not_copy_assignable& operator=(not_copy_assignable const&) = delete; constexpr not_copy_assignable() @@ -83,11 +82,11 @@ struct not_copy_assignable { noexcept = default; constexpr not_copy_assignable& operator=(not_copy_assignable&&) noexcept = default; - // clang-format on + // clang-format on }; struct not_move_assignable { - // clang-format off + // clang-format off not_move_assignable& operator=(not_move_assignable&&) = delete; constexpr not_move_assignable() @@ -98,71 +97,62 @@ struct not_move_assignable { noexcept = default; constexpr not_move_assignable& operator=(not_move_assignable const&) noexcept = default; - // clang-format on + // clang-format on }; -template -struct push_front; +template struct push_front; template