summaryrefslogtreecommitdiffstats
path: root/Utilities/std
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2019-12-05 16:10:23 (GMT)
committerMarc Chevrier <marc.chevrier@gmail.com>2019-12-17 09:43:58 (GMT)
commita38d04c0764b3550bd7d17b659945a38c1368f1e (patch)
tree67c5c928c47121a6646b5a666fe2a496c446b21f /Utilities/std
parentd082d0e109257ea2f1adce278658fa825a3f08a2 (diff)
downloadCMake-a38d04c0764b3550bd7d17b659945a38c1368f1e.zip
CMake-a38d04c0764b3550bd7d17b659945a38c1368f1e.tar.gz
CMake-a38d04c0764b3550bd7d17b659945a38c1368f1e.tar.bz2
Refactoring: introduce header cmext/algorithm with append functions
Diffstat (limited to 'Utilities/std')
-rw-r--r--Utilities/std/cm/type_traits7
-rw-r--r--Utilities/std/cmext/algorithm52
-rw-r--r--Utilities/std/cmext/iterator49
3 files changed, 108 insertions, 0 deletions
diff --git a/Utilities/std/cm/type_traits b/Utilities/std/cm/type_traits
index 6d7a2c0..4dfe17b 100644
--- a/Utilities/std/cm/type_traits
+++ b/Utilities/std/cm/type_traits
@@ -26,12 +26,19 @@ using enable_if_t = typename std::enable_if<B, T>::type;
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703)
+// Helper classes
+using std::bool_constant;
+
// Miscellaneous transformations
using std::invoke_result;
using std::invoke_result_t;
#else
+// Helper classes
+template <bool B>
+using bool_constant = std::integral_constant<bool, B>;
+
// Miscellaneous transformations
template <typename F, typename... ArgTypes>
using invoke_result = std::result_of<F(ArgTypes...)>;
diff --git a/Utilities/std/cmext/algorithm b/Utilities/std/cmext/algorithm
new file mode 100644
index 0000000..609860c
--- /dev/null
+++ b/Utilities/std/cmext/algorithm
@@ -0,0 +1,52 @@
+// -*-c++-*-
+// vim: set ft=cpp:
+
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmext_algorithm
+#define cmext_algorithm
+
+#include <algorithm>
+#include <iterator>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include <cm/type_traits>
+#include <cmext/iterator>
+
+namespace cm {
+
+template <typename T>
+void append(std::vector<std::unique_ptr<T>>& v,
+ std::vector<std::unique_ptr<T>>&& r)
+{
+ std::transform(r.begin(), r.end(), std::back_inserter(v),
+ [](std::unique_ptr<T>& item) { return std::move(item); });
+ r.clear();
+}
+
+template <typename T>
+void append(std::vector<T*>& v, std::vector<std::unique_ptr<T>> const& r)
+{
+ std::transform(r.begin(), r.end(), std::back_inserter(v),
+ [](const std::unique_ptr<T>& item) { return item.get(); });
+}
+
+template <typename T, typename InputIt,
+ cm::enable_if_t<cm::is_input_iterator<InputIt>::value, int> = 0>
+void append(std::vector<T>& v, InputIt first, InputIt last)
+{
+ v.insert(v.end(), first, last);
+}
+
+template <typename T, typename Range,
+ cm::enable_if_t<cm::is_input_range<Range>::value, int> = 0>
+void append(std::vector<T>& v, Range const& r)
+{
+ v.insert(v.end(), r.begin(), r.end());
+}
+
+} // namespace cm
+
+#endif
diff --git a/Utilities/std/cmext/iterator b/Utilities/std/cmext/iterator
new file mode 100644
index 0000000..ffe94b1
--- /dev/null
+++ b/Utilities/std/cmext/iterator
@@ -0,0 +1,49 @@
+// -*-c++-*-
+// vim: set ft=cpp:
+
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmext_iterator
+#define cmext_iterator
+
+#include <iterator>
+
+#include <cm/type_traits>
+
+namespace cm {
+
+// checks if a type is an iterator type
+template <typename I>
+using is_iterator =
+ std::is_integral<typename std::iterator_traits<I>::difference_type>;
+
+// checks if a type is an input iterator type
+template <typename I>
+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
+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>;
+
+// checks if a type is an input range type: must have methods begin() and end()
+// 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>;
+#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>;
+#endif
+
+} // namespace cm
+
+#endif