1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_TEMPLATE_UTIL_H_ 6*635a8641SAndroid Build Coastguard Worker #define BASE_TEMPLATE_UTIL_H_ 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker #include <stddef.h> 9*635a8641SAndroid Build Coastguard Worker #include <iosfwd> 10*635a8641SAndroid Build Coastguard Worker #include <iterator> 11*635a8641SAndroid Build Coastguard Worker #include <type_traits> 12*635a8641SAndroid Build Coastguard Worker #include <utility> 13*635a8641SAndroid Build Coastguard Worker #include <vector> 14*635a8641SAndroid Build Coastguard Worker 15*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h" 16*635a8641SAndroid Build Coastguard Worker 17*635a8641SAndroid Build Coastguard Worker // Some versions of libstdc++ have partial support for type_traits, but misses 18*635a8641SAndroid Build Coastguard Worker // a smaller subset while removing some of the older non-standard stuff. Assume 19*635a8641SAndroid Build Coastguard Worker // that all versions below 5.0 fall in this category, along with one 5.0 20*635a8641SAndroid Build Coastguard Worker // experimental release. Test for this by consulting compiler major version, 21*635a8641SAndroid Build Coastguard Worker // the only reliable option available, so theoretically this could fail should 22*635a8641SAndroid Build Coastguard Worker // you attempt to mix an earlier version of libstdc++ with >= GCC5. But 23*635a8641SAndroid Build Coastguard Worker // that's unlikely to work out, especially as GCC5 changed ABI. 24*635a8641SAndroid Build Coastguard Worker #define CR_GLIBCXX_5_0_0 20150123 25*635a8641SAndroid Build Coastguard Worker // `!defined(__clang__)` is a local android patch 26*635a8641SAndroid Build Coastguard Worker #if !defined(__clang__) && ((defined(__GNUC__) && __GNUC__ < 5) || \ 27*635a8641SAndroid Build Coastguard Worker (defined(__GLIBCXX__) && __GLIBCXX__ == CR_GLIBCXX_5_0_0)) 28*635a8641SAndroid Build Coastguard Worker #define CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX 29*635a8641SAndroid Build Coastguard Worker #endif 30*635a8641SAndroid Build Coastguard Worker 31*635a8641SAndroid Build Coastguard Worker // This hacks around using gcc with libc++ which has some incompatibilies. 32*635a8641SAndroid Build Coastguard Worker // - is_trivially_* doesn't work: https://llvm.org/bugs/show_bug.cgi?id=27538 33*635a8641SAndroid Build Coastguard Worker // TODO(danakj): Remove this when android builders are all using a newer version 34*635a8641SAndroid Build Coastguard Worker // of gcc, or the android ndk is updated to a newer libc++ that works with older 35*635a8641SAndroid Build Coastguard Worker // gcc versions. 36*635a8641SAndroid Build Coastguard Worker #if !defined(__clang__) && defined(_LIBCPP_VERSION) 37*635a8641SAndroid Build Coastguard Worker #define CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX 38*635a8641SAndroid Build Coastguard Worker #endif 39*635a8641SAndroid Build Coastguard Worker 40*635a8641SAndroid Build Coastguard Worker namespace base { 41*635a8641SAndroid Build Coastguard Worker 42*635a8641SAndroid Build Coastguard Worker template <class T> struct is_non_const_reference : std::false_type {}; 43*635a8641SAndroid Build Coastguard Worker template <class T> struct is_non_const_reference<T&> : std::true_type {}; 44*635a8641SAndroid Build Coastguard Worker template <class T> struct is_non_const_reference<const T&> : std::false_type {}; 45*635a8641SAndroid Build Coastguard Worker 46*635a8641SAndroid Build Coastguard Worker namespace internal { 47*635a8641SAndroid Build Coastguard Worker 48*635a8641SAndroid Build Coastguard Worker // Implementation detail of base::void_t below. 49*635a8641SAndroid Build Coastguard Worker template <typename...> 50*635a8641SAndroid Build Coastguard Worker struct make_void { 51*635a8641SAndroid Build Coastguard Worker using type = void; 52*635a8641SAndroid Build Coastguard Worker }; 53*635a8641SAndroid Build Coastguard Worker 54*635a8641SAndroid Build Coastguard Worker } // namespace internal 55*635a8641SAndroid Build Coastguard Worker 56*635a8641SAndroid Build Coastguard Worker // base::void_t is an implementation of std::void_t from C++17. 57*635a8641SAndroid Build Coastguard Worker // 58*635a8641SAndroid Build Coastguard Worker // We use |base::internal::make_void| as a helper struct to avoid a C++14 59*635a8641SAndroid Build Coastguard Worker // defect: 60*635a8641SAndroid Build Coastguard Worker // http://en.cppreference.com/w/cpp/types/void_t 61*635a8641SAndroid Build Coastguard Worker // http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1558 62*635a8641SAndroid Build Coastguard Worker template <typename... Ts> 63*635a8641SAndroid Build Coastguard Worker using void_t = typename ::base::internal::make_void<Ts...>::type; 64*635a8641SAndroid Build Coastguard Worker 65*635a8641SAndroid Build Coastguard Worker namespace internal { 66*635a8641SAndroid Build Coastguard Worker 67*635a8641SAndroid Build Coastguard Worker // Uses expression SFINAE to detect whether using operator<< would work. 68*635a8641SAndroid Build Coastguard Worker template <typename T, typename = void> 69*635a8641SAndroid Build Coastguard Worker struct SupportsOstreamOperator : std::false_type {}; 70*635a8641SAndroid Build Coastguard Worker template <typename T> 71*635a8641SAndroid Build Coastguard Worker struct SupportsOstreamOperator<T, 72*635a8641SAndroid Build Coastguard Worker decltype(void(std::declval<std::ostream&>() 73*635a8641SAndroid Build Coastguard Worker << std::declval<T>()))> 74*635a8641SAndroid Build Coastguard Worker : std::true_type {}; 75*635a8641SAndroid Build Coastguard Worker 76*635a8641SAndroid Build Coastguard Worker // Used to detech whether the given type is an iterator. This is normally used 77*635a8641SAndroid Build Coastguard Worker // with std::enable_if to provide disambiguation for functions that take 78*635a8641SAndroid Build Coastguard Worker // templatzed iterators as input. 79*635a8641SAndroid Build Coastguard Worker template <typename T, typename = void> 80*635a8641SAndroid Build Coastguard Worker struct is_iterator : std::false_type {}; 81*635a8641SAndroid Build Coastguard Worker 82*635a8641SAndroid Build Coastguard Worker template <typename T> 83*635a8641SAndroid Build Coastguard Worker struct is_iterator<T, 84*635a8641SAndroid Build Coastguard Worker void_t<typename std::iterator_traits<T>::iterator_category>> 85*635a8641SAndroid Build Coastguard Worker : std::true_type {}; 86*635a8641SAndroid Build Coastguard Worker 87*635a8641SAndroid Build Coastguard Worker } // namespace internal 88*635a8641SAndroid Build Coastguard Worker 89*635a8641SAndroid Build Coastguard Worker // is_trivially_copyable is especially hard to get right. 90*635a8641SAndroid Build Coastguard Worker // - Older versions of libstdc++ will fail to have it like they do for other 91*635a8641SAndroid Build Coastguard Worker // type traits. This has become a subset of the second point, but used to be 92*635a8641SAndroid Build Coastguard Worker // handled independently. 93*635a8641SAndroid Build Coastguard Worker // - An experimental release of gcc includes most of type_traits but misses 94*635a8641SAndroid Build Coastguard Worker // is_trivially_copyable, so we still have to avoid using libstdc++ in this 95*635a8641SAndroid Build Coastguard Worker // case, which is covered by CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX. 96*635a8641SAndroid Build Coastguard Worker // - When compiling libc++ from before r239653, with a gcc compiler, the 97*635a8641SAndroid Build Coastguard Worker // std::is_trivially_copyable can fail. So we need to work around that by not 98*635a8641SAndroid Build Coastguard Worker // using the one in libc++ in this case. This is covered by the 99*635a8641SAndroid Build Coastguard Worker // CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX define, and is discussed in 100*635a8641SAndroid Build Coastguard Worker // https://llvm.org/bugs/show_bug.cgi?id=27538#c1 where they point out that 101*635a8641SAndroid Build Coastguard Worker // in libc++'s commit r239653 this is fixed by libc++ checking for gcc 5.1. 102*635a8641SAndroid Build Coastguard Worker // - In both of the above cases we are using the gcc compiler. When defining 103*635a8641SAndroid Build Coastguard Worker // this ourselves on compiler intrinsics, the __is_trivially_copyable() 104*635a8641SAndroid Build Coastguard Worker // intrinsic is not available on gcc before version 5.1 (see the discussion in 105*635a8641SAndroid Build Coastguard Worker // https://llvm.org/bugs/show_bug.cgi?id=27538#c1 again), so we must check for 106*635a8641SAndroid Build Coastguard Worker // that version. 107*635a8641SAndroid Build Coastguard Worker // - When __is_trivially_copyable() is not available because we are on gcc older 108*635a8641SAndroid Build Coastguard Worker // than 5.1, we need to fall back to something, so we use __has_trivial_copy() 109*635a8641SAndroid Build Coastguard Worker // instead based on what was done one-off in bit_cast() previously. 110*635a8641SAndroid Build Coastguard Worker 111*635a8641SAndroid Build Coastguard Worker // TODO(crbug.com/554293): Remove this when all platforms have this in the std 112*635a8641SAndroid Build Coastguard Worker // namespace and it works with gcc as needed. 113*635a8641SAndroid Build Coastguard Worker #if defined(CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX) || \ 114*635a8641SAndroid Build Coastguard Worker defined(CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX) 115*635a8641SAndroid Build Coastguard Worker template <typename T> 116*635a8641SAndroid Build Coastguard Worker struct is_trivially_copyable { 117*635a8641SAndroid Build Coastguard Worker // TODO(danakj): Remove this when android builders are all using a newer version 118*635a8641SAndroid Build Coastguard Worker // of gcc, or the android ndk is updated to a newer libc++ that does this for 119*635a8641SAndroid Build Coastguard Worker // us. 120*635a8641SAndroid Build Coastguard Worker #if _GNUC_VER >= 501 121*635a8641SAndroid Build Coastguard Worker static constexpr bool value = __is_trivially_copyable(T); 122*635a8641SAndroid Build Coastguard Worker #else 123*635a8641SAndroid Build Coastguard Worker static constexpr bool value = 124*635a8641SAndroid Build Coastguard Worker __has_trivial_copy(T) && __has_trivial_destructor(T); 125*635a8641SAndroid Build Coastguard Worker #endif 126*635a8641SAndroid Build Coastguard Worker }; 127*635a8641SAndroid Build Coastguard Worker #else 128*635a8641SAndroid Build Coastguard Worker template <class T> 129*635a8641SAndroid Build Coastguard Worker using is_trivially_copyable = std::is_trivially_copyable<T>; 130*635a8641SAndroid Build Coastguard Worker #endif 131*635a8641SAndroid Build Coastguard Worker 132*635a8641SAndroid Build Coastguard Worker #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 7 133*635a8641SAndroid Build Coastguard Worker // Workaround for g++7 and earlier family. 134*635a8641SAndroid Build Coastguard Worker // Due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80654, without this 135*635a8641SAndroid Build Coastguard Worker // Optional<std::vector<T>> where T is non-copyable causes a compile error. 136*635a8641SAndroid Build Coastguard Worker // As we know it is not trivially copy constructible, explicitly declare so. 137*635a8641SAndroid Build Coastguard Worker template <typename T> 138*635a8641SAndroid Build Coastguard Worker struct is_trivially_copy_constructible 139*635a8641SAndroid Build Coastguard Worker : std::is_trivially_copy_constructible<T> {}; 140*635a8641SAndroid Build Coastguard Worker 141*635a8641SAndroid Build Coastguard Worker template <typename... T> 142*635a8641SAndroid Build Coastguard Worker struct is_trivially_copy_constructible<std::vector<T...>> : std::false_type {}; 143*635a8641SAndroid Build Coastguard Worker #else 144*635a8641SAndroid Build Coastguard Worker // Otherwise use std::is_trivially_copy_constructible as is. 145*635a8641SAndroid Build Coastguard Worker template <typename T> 146*635a8641SAndroid Build Coastguard Worker using is_trivially_copy_constructible = std::is_trivially_copy_constructible<T>; 147*635a8641SAndroid Build Coastguard Worker #endif 148*635a8641SAndroid Build Coastguard Worker 149*635a8641SAndroid Build Coastguard Worker } // namespace base 150*635a8641SAndroid Build Coastguard Worker 151*635a8641SAndroid Build Coastguard Worker #undef CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX 152*635a8641SAndroid Build Coastguard Worker #undef CR_USE_FALLBACKS_FOR_OLD_EXPERIMENTAL_GLIBCXX 153*635a8641SAndroid Build Coastguard Worker 154*635a8641SAndroid Build Coastguard Worker #endif // BASE_TEMPLATE_UTIL_H_ 155