diff options
Diffstat (limited to 'third_party/libwebrtc/rtc_base/type_traits.h')
-rw-r--r-- | third_party/libwebrtc/rtc_base/type_traits.h | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_base/type_traits.h b/third_party/libwebrtc/rtc_base/type_traits.h new file mode 100644 index 0000000000..0cb899c47f --- /dev/null +++ b/third_party/libwebrtc/rtc_base/type_traits.h @@ -0,0 +1,140 @@ +/* + * Copyright 2016 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef RTC_BASE_TYPE_TRAITS_H_ +#define RTC_BASE_TYPE_TRAITS_H_ + +#include <cstddef> +#include <type_traits> + +namespace rtc { + +// Determines if the given class has zero-argument .data() and .size() methods +// whose return values are convertible to T* and size_t, respectively. +template <typename DS, typename T> +class HasDataAndSize { + private: + template < + typename C, + typename std::enable_if< + std::is_convertible<decltype(std::declval<C>().data()), T*>::value && + std::is_convertible<decltype(std::declval<C>().size()), + std::size_t>::value>::type* = nullptr> + static int Test(int); + + template <typename> + static char Test(...); + + public: + static constexpr bool value = std::is_same<decltype(Test<DS>(0)), int>::value; +}; + +namespace test_has_data_and_size { + +template <typename DR, typename SR> +struct Test1 { + DR data(); + SR size(); +}; +static_assert(HasDataAndSize<Test1<int*, int>, int>::value, ""); +static_assert(HasDataAndSize<Test1<int*, int>, const int>::value, ""); +static_assert(HasDataAndSize<Test1<const int*, int>, const int>::value, ""); +static_assert(!HasDataAndSize<Test1<const int*, int>, int>::value, + "implicit cast of const int* to int*"); +static_assert(!HasDataAndSize<Test1<char*, size_t>, int>::value, + "implicit cast of char* to int*"); + +struct Test2 { + int* data; + size_t size; +}; +static_assert(!HasDataAndSize<Test2, int>::value, + ".data and .size aren't functions"); + +struct Test3 { + int* data(); +}; +static_assert(!HasDataAndSize<Test3, int>::value, ".size() is missing"); + +class Test4 { + int* data(); + size_t size(); +}; +static_assert(!HasDataAndSize<Test4, int>::value, + ".data() and .size() are private"); + +} // namespace test_has_data_and_size + +namespace type_traits_impl { + +// Determines if the given type is an enum that converts implicitly to +// an integral type. +template <typename T> +struct IsIntEnum { + private: + // This overload is used if the type is an enum, and unary plus + // compiles and turns it into an integral type. + template <typename X, + typename std::enable_if< + std::is_enum<X>::value && + std::is_integral<decltype(+std::declval<X>())>::value>::type* = + nullptr> + static int Test(int); + + // Otherwise, this overload is used. + template <typename> + static char Test(...); + + public: + static constexpr bool value = + std::is_same<decltype(Test<typename std::remove_reference<T>::type>(0)), + int>::value; +}; + +} // namespace type_traits_impl + +// Determines if the given type is integral, or an enum that +// converts implicitly to an integral type. +template <typename T> +struct IsIntlike { + private: + using X = typename std::remove_reference<T>::type; + + public: + static constexpr bool value = + std::is_integral<X>::value || type_traits_impl::IsIntEnum<X>::value; +}; + +namespace test_enum_intlike { + +enum E1 { e1 }; +enum { e2 }; +enum class E3 { e3 }; +struct S {}; + +static_assert(type_traits_impl::IsIntEnum<E1>::value, ""); +static_assert(type_traits_impl::IsIntEnum<decltype(e2)>::value, ""); +static_assert(!type_traits_impl::IsIntEnum<E3>::value, ""); +static_assert(!type_traits_impl::IsIntEnum<int>::value, ""); +static_assert(!type_traits_impl::IsIntEnum<float>::value, ""); +static_assert(!type_traits_impl::IsIntEnum<S>::value, ""); + +static_assert(IsIntlike<E1>::value, ""); +static_assert(IsIntlike<decltype(e2)>::value, ""); +static_assert(!IsIntlike<E3>::value, ""); +static_assert(IsIntlike<int>::value, ""); +static_assert(!IsIntlike<float>::value, ""); +static_assert(!IsIntlike<S>::value, ""); + +} // namespace test_enum_intlike + +} // namespace rtc + +#endif // RTC_BASE_TYPE_TRAITS_H_ |