diff options
author | Marc Chevrier <marc.chevrier@gmail.com> | 2020-04-13 10:11:31 (GMT) |
---|---|---|
committer | Marc Chevrier <marc.chevrier@gmail.com> | 2020-04-17 08:00:03 (GMT) |
commit | aacd4e4a90a3afb23d681063d2ecba719f1adab8 (patch) | |
tree | 7e1a884cb47519099bd5db178681773f82dad688 /Utilities | |
parent | 9a450bcfec5411169007d5ca5f1bd40e6f476ff4 (diff) | |
download | CMake-aacd4e4a90a3afb23d681063d2ecba719f1adab8.zip CMake-aacd4e4a90a3afb23d681063d2ecba719f1adab8.tar.gz CMake-aacd4e4a90a3afb23d681063d2ecba719f1adab8.tar.bz2 |
Refactoring: add cm::contains to <cmext/algorithm>
Diffstat (limited to 'Utilities')
-rw-r--r-- | Utilities/std/cmext/algorithm | 92 | ||||
-rw-r--r-- | Utilities/std/cmext/iterator | 20 | ||||
-rw-r--r-- | Utilities/std/cmext/type_traits | 2 |
3 files changed, 103 insertions, 11 deletions
diff --git a/Utilities/std/cmext/algorithm b/Utilities/std/cmext/algorithm index 44e61f4..251c89a 100644 --- a/Utilities/std/cmext/algorithm +++ b/Utilities/std/cmext/algorithm @@ -13,12 +13,11 @@ #include <cm/type_traits> #include <cmext/iterator> +#include <cmext/type_traits> #if defined(__SUNPRO_CC) && defined(__sparc) # include <list> # include <vector> -#else -# include <cmext/type_traits> #endif namespace cm { @@ -158,6 +157,95 @@ void append(T& v, U const& r) # endif #endif +#if defined(__SUNPRO_CC) +template <typename Iterator, typename Key> +auto contains(Iterator first, Iterator last, Key const& key, + detail::overload_selector<1>) -> decltype(first->first == key) +#else +template <typename Iterator, typename Key, + cm::enable_if_t< + cm::is_input_iterator<Iterator>::value && + std::is_convertible<Key, + typename std::iterator_traits< + Iterator>::value_type::first_type>::value, + int> = 0> +bool contains(Iterator first, Iterator last, Key const& key) +#endif +{ + return std::find_if( + first, last, + [&key]( + typename std::iterator_traits<Iterator>::value_type const& item) { + return item.first == key; + }) != last; +} + +#if defined(__SUNPRO_CC) +template <typename Iterator, typename Key> +bool contains(Iterator first, Iterator last, Key const& key, + detail::overload_selector<0>) +#else +template < + typename Iterator, typename Key, + cm::enable_if_t< + cm::is_input_iterator<Iterator>::value && + std::is_convertible< + Key, typename std::iterator_traits<Iterator>::value_type>::value, + int> = 0> +bool contains(Iterator first, Iterator last, Key const& key) +#endif +{ + return std::find(first, last, key) != last; +} + +#if defined(__SUNPRO_CC) +template <typename Iterator, typename Key> +bool contains(Iterator first, Iterator last, Key const& key) +{ + return contains(first, last, key, detail::overload_selector<1>{}); +} +#endif + +#if defined(__SUNPRO_CC) +template <typename Range, typename Key> +auto contains(Range const& range, Key const& key, detail::overload_selector<1>) + -> decltype(range.find(key) != range.end()) +#else +template < + typename Range, typename Key, + cm::enable_if_t<cm::is_associative_container<Range>::value || + cm::is_unordered_associative_container<Range>::value, + int> = 0> +bool contains(Range const& range, Key const& key) +#endif +{ + return range.find(key) != range.end(); +} + +#if defined(__SUNPRO_CC) +template <typename Range, typename Key> +bool contains(Range const& range, Key const& key, detail::overload_selector<0>) +#else +template < + typename Range, typename Key, + cm::enable_if_t<cm::is_input_range<Range>::value && + !(cm::is_associative_container<Range>::value || + cm::is_unordered_associative_container<Range>::value), + int> = 0> +bool contains(Range const& range, Key const& key) +#endif +{ + return std::find(std::begin(range), std::end(range), key) != std::end(range); +} + +#if defined(__SUNPRO_CC) +template <typename Range, typename Key> +bool contains(Range const& range, Key const& key) +{ + return contains(range, key, detail::overload_selector<1>{}); +} +#endif + } // namespace cm #endif diff --git a/Utilities/std/cmext/iterator b/Utilities/std/cmext/iterator index ffe94b1..ce9462f 100644 --- a/Utilities/std/cmext/iterator +++ b/Utilities/std/cmext/iterator @@ -23,25 +23,27 @@ using is_input_iterator = std::is_base_of<std::input_iterator_tag, typename std::iterator_traits<I>::iterator_category>; -// checks if a type is a range type: must have a difference_type type +// checks if a type is a range type: std::begin() and std::end() are supported template <typename Range> using is_range = cm::bool_constant< - cm::is_iterator<decltype(std::declval<const Range>().begin())>::value && - cm::is_iterator<decltype(std::declval<const Range>().end())>::value>; + cm::is_iterator<decltype(std::begin(std::declval<const Range>()))>::value && + cm::is_iterator<decltype(std::end(std::declval<const Range>()))>::value>; -// checks if a type is an input range type: must have methods begin() and end() +// checks if a type is an input range type: std::begin() and std::end() are // returning an input iterator template <typename Range> using is_input_range = #if defined(_MSC_VER) && _MSC_VER < 1920 // MS C++ is not able to evaluate complex type introspection, // so use a simplified version - cm::is_input_iterator<typename Range::const_iterator>; + cm::bool_constant<std::is_class<Range>::value || + std::is_pointer<Range>::value || + std::is_array<Range>::value>; #else - cm::bool_constant< - cm::is_input_iterator<decltype( - std::declval<const Range>().begin())>::value && - cm::is_input_iterator<decltype(std::declval<const Range>().end())>::value>; + cm::bool_constant<cm::is_input_iterator<decltype( + std::begin(std::declval<const Range>()))>::value && + cm::is_input_iterator<decltype( + std::end(std::declval<const Range>()))>::value>; #endif } // namespace cm diff --git a/Utilities/std/cmext/type_traits b/Utilities/std/cmext/type_traits index 00984cb..f02b488 100644 --- a/Utilities/std/cmext/type_traits +++ b/Utilities/std/cmext/type_traits @@ -6,6 +6,8 @@ #ifndef cmext_type_traits #define cmext_type_traits +#include <memory> + #include <cm/type_traits> namespace cm { |