summaryrefslogtreecommitdiffstats
path: root/Utilities
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities')
-rw-r--r--Utilities/std/cm/type_traits10
-rw-r--r--Utilities/std/cmext/memory10
-rw-r--r--Utilities/std/cmext/type_traits68
3 files changed, 87 insertions, 1 deletions
diff --git a/Utilities/std/cm/type_traits b/Utilities/std/cm/type_traits
index 4dfe17b..e32c2c6 100644
--- a/Utilities/std/cm/type_traits
+++ b/Utilities/std/cm/type_traits
@@ -33,6 +33,8 @@ using std::bool_constant;
using std::invoke_result;
using std::invoke_result_t;
+using std::void_t;
+
#else
// Helper classes
@@ -46,6 +48,14 @@ using invoke_result = std::result_of<F(ArgTypes...)>;
template <class F, typename... ArgTypes>
using invoke_result_t = typename invoke_result<F, ArgTypes...>::type;
+template <typename... ArgTypes>
+struct make_void
+{
+ typedef void type;
+};
+template <typename... ArgTypes>
+using void_t = typename make_void<ArgTypes...>::type;
+
#endif
} // namespace cm
diff --git a/Utilities/std/cmext/memory b/Utilities/std/cmext/memory
index 540a3de..50e79df 100644
--- a/Utilities/std/cmext/memory
+++ b/Utilities/std/cmext/memory
@@ -6,6 +6,8 @@
#ifndef cmext_memory
#define cmext_memory
+#include <typeinfo>
+
#include <cm/type_traits>
namespace cm {
@@ -24,7 +26,13 @@ template <typename T, typename O,
int> = 0>
T& dynamic_reference_cast(O& item)
{
- return *(dynamic_cast<T*>(item.get()));
+ auto p = dynamic_cast<T*>(item.get());
+
+ if (p == nullptr) {
+ throw std::bad_cast();
+ }
+
+ return *p;
}
} // namespace cm
diff --git a/Utilities/std/cmext/type_traits b/Utilities/std/cmext/type_traits
new file mode 100644
index 0000000..da6550d
--- /dev/null
+++ b/Utilities/std/cmext/type_traits
@@ -0,0 +1,68 @@
+// -*-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_type_traits
+#define cmext_type_traits
+
+#include <cm/type_traits>
+
+namespace cm {
+
+// type traits for managed pointer types
+template <typename>
+struct is_unique_ptr : std::false_type
+{
+};
+template <typename T>
+struct is_unique_ptr<std::unique_ptr<T>> : std::true_type
+{
+};
+
+// type traits for containers
+template <typename, typename = void_t<>>
+struct is_container : std::false_type
+{
+};
+template <typename T>
+struct is_container<
+ T,
+ cm::void_t<typename T::value_type, typename T::size_type,
+ typename T::difference_type, typename T::iterator>>
+ : std::true_type
+{
+};
+
+template <typename, typename = void_t<>>
+struct is_associative_container : std::false_type
+{
+};
+template <typename T>
+struct is_associative_container<
+ T, cm::void_t<typename T::key_type, typename T::key_compare>>
+ : cm::is_container<T>
+{
+};
+
+template <typename, typename = void_t<>>
+struct is_unordered_associative_container : std::false_type
+{
+};
+template <typename T>
+struct is_unordered_associative_container<
+ T,
+ cm::void_t<typename T::key_type, typename T::hasher, typename T::key_equal,
+ typename T::local_iterator>> : cm::is_container<T>
+{
+};
+
+template <typename T>
+using is_sequence_container =
+ cm::bool_constant<cm::is_container<T>::value &&
+ !cm::is_associative_container<T>::value &&
+ !cm::is_unordered_associative_container<T>::value>;
+
+} // namespace cm
+
+#endif