summaryrefslogtreecommitdiff
path: root/Utilities/std
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2020-04-13 12:11:31 +0200
committerMarc Chevrier <marc.chevrier@gmail.com>2020-04-17 10:00:03 +0200
commitaacd4e4a90a3afb23d681063d2ecba719f1adab8 (patch)
tree7e1a884cb47519099bd5db178681773f82dad688 /Utilities/std
parent9a450bcfec5411169007d5ca5f1bd40e6f476ff4 (diff)
downloadcmake-aacd4e4a90a3afb23d681063d2ecba719f1adab8.tar.gz
Refactoring: add cm::contains to <cmext/algorithm>
Diffstat (limited to 'Utilities/std')
-rw-r--r--Utilities/std/cmext/algorithm92
-rw-r--r--Utilities/std/cmext/iterator20
-rw-r--r--Utilities/std/cmext/type_traits2
3 files changed, 103 insertions, 11 deletions
diff --git a/Utilities/std/cmext/algorithm b/Utilities/std/cmext/algorithm
index 44e61f45dd..251c89a5fa 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 ffe94b17d5..ce9462f0a5 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 00984cba29..f02b4884e7 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 {