Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:01:44

0001 // Copyright 2008 Google Inc.
0002 // All Rights Reserved.
0003 //
0004 // Redistribution and use in source and binary forms, with or without
0005 // modification, are permitted provided that the following conditions are
0006 // met:
0007 //
0008 //     * Redistributions of source code must retain the above copyright
0009 // notice, this list of conditions and the following disclaimer.
0010 //     * Redistributions in binary form must reproduce the above
0011 // copyright notice, this list of conditions and the following disclaimer
0012 // in the documentation and/or other materials provided with the
0013 // distribution.
0014 //     * Neither the name of Google Inc. nor the names of its
0015 // contributors may be used to endorse or promote products derived from
0016 // this software without specific prior written permission.
0017 //
0018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0019 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0020 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0021 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0022 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0023 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0024 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0025 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0026 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0027 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0028 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0029 
0030 // Type utilities needed for implementing typed and type-parameterized
0031 // tests.
0032 
0033 // IWYU pragma: private, include "gtest/gtest.h"
0034 // IWYU pragma: friend gtest/.*
0035 // IWYU pragma: friend gmock/.*
0036 
0037 #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
0038 #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
0039 
0040 #include <string>
0041 #include <type_traits>
0042 #include <typeinfo>
0043 
0044 #include "gtest/internal/gtest-port.h"
0045 
0046 // #ifdef __GNUC__ is too general here.  It is possible to use gcc without using
0047 // libstdc++ (which is where cxxabi.h comes from).
0048 #if GTEST_HAS_CXXABI_H_
0049 #include <cxxabi.h>
0050 #elif defined(__HP_aCC)
0051 #include <acxx_demangle.h>
0052 #endif  // GTEST_HASH_CXXABI_H_
0053 
0054 namespace testing {
0055 namespace internal {
0056 
0057 // Canonicalizes a given name with respect to the Standard C++ Library.
0058 // This handles removing the inline namespace within `std` that is
0059 // used by various standard libraries (e.g., `std::__1`).  Names outside
0060 // of namespace std are returned unmodified.
0061 inline std::string CanonicalizeForStdLibVersioning(std::string s) {
0062   static const char prefix[] = "std::__";
0063   if (s.compare(0, strlen(prefix), prefix) == 0) {
0064     std::string::size_type end = s.find("::", strlen(prefix));
0065     if (end != s.npos) {
0066       // Erase everything between the initial `std` and the second `::`.
0067       s.erase(strlen("std"), end - strlen("std"));
0068     }
0069   }
0070 
0071   // Strip redundant spaces in typename to match MSVC
0072   // For example, std::pair<int, bool> -> std::pair<int,bool>
0073   static const char to_search[] = ", ";
0074   const char replace_char = ',';
0075   size_t pos = 0;
0076   while (true) {
0077     // Get the next occurrence from the current position
0078     pos = s.find(to_search, pos);
0079     if (pos == std::string::npos) {
0080       break;
0081     }
0082     // Replace this occurrence of substring
0083     s.replace(pos, strlen(to_search), 1, replace_char);
0084     ++pos;
0085   }
0086   return s;
0087 }
0088 
0089 #if GTEST_HAS_RTTI
0090 // GetTypeName(const std::type_info&) returns a human-readable name of type T.
0091 inline std::string GetTypeName(const std::type_info& type) {
0092   const char* const name = type.name();
0093 #if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
0094   int status = 0;
0095   // gcc's implementation of typeid(T).name() mangles the type name,
0096   // so we have to demangle it.
0097 #if GTEST_HAS_CXXABI_H_
0098   using abi::__cxa_demangle;
0099 #endif  // GTEST_HAS_CXXABI_H_
0100   char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
0101   const std::string name_str(status == 0 ? readable_name : name);
0102   free(readable_name);
0103   return CanonicalizeForStdLibVersioning(name_str);
0104 #elif defined(_MSC_VER)
0105   // Strip struct and class due to differences between
0106   // MSVC and other compilers. std::pair<int,bool> is printed as
0107   // "struct std::pair<int,bool>" when using MSVC vs "std::pair<int, bool>" with
0108   // other compilers.
0109   std::string s = name;
0110   // Only strip the leading "struct " and "class ", so uses rfind == 0 to
0111   // ensure that
0112   if (s.rfind("struct ", 0) == 0) {
0113     s = s.substr(strlen("struct "));
0114   } else if (s.rfind("class ", 0) == 0) {
0115     s = s.substr(strlen("class "));
0116   }
0117   return s;
0118 #else
0119   return name;
0120 #endif  // GTEST_HAS_CXXABI_H_ || __HP_aCC
0121 }
0122 #endif  // GTEST_HAS_RTTI
0123 
0124 // GetTypeName<T>() returns a human-readable name of type T if and only if
0125 // RTTI is enabled, otherwise it returns a dummy type name.
0126 // NB: This function is also used in Google Mock, so don't move it inside of
0127 // the typed-test-only section below.
0128 template <typename T>
0129 std::string GetTypeName() {
0130 #if GTEST_HAS_RTTI
0131   return GetTypeName(typeid(T));
0132 #else
0133   return "<type>";
0134 #endif  // GTEST_HAS_RTTI
0135 }
0136 
0137 // A unique type indicating an empty node
0138 struct None {};
0139 
0140 #define GTEST_TEMPLATE_ \
0141   template <typename T> \
0142   class
0143 
0144 // The template "selector" struct TemplateSel<Tmpl> is used to
0145 // represent Tmpl, which must be a class template with one type
0146 // parameter, as a type.  TemplateSel<Tmpl>::Bind<T>::type is defined
0147 // as the type Tmpl<T>.  This allows us to actually instantiate the
0148 // template "selected" by TemplateSel<Tmpl>.
0149 //
0150 // This trick is necessary for simulating typedef for class templates,
0151 // which C++ doesn't support directly.
0152 template <GTEST_TEMPLATE_ Tmpl>
0153 struct TemplateSel {
0154   template <typename T>
0155   struct Bind {
0156     typedef Tmpl<T> type;
0157   };
0158 };
0159 
0160 #define GTEST_BIND_(TmplSel, T) TmplSel::template Bind<T>::type
0161 
0162 template <GTEST_TEMPLATE_ Head_, GTEST_TEMPLATE_... Tail_>
0163 struct Templates {
0164   using Head = TemplateSel<Head_>;
0165   using Tail = Templates<Tail_...>;
0166 };
0167 
0168 template <GTEST_TEMPLATE_ Head_>
0169 struct Templates<Head_> {
0170   using Head = TemplateSel<Head_>;
0171   using Tail = None;
0172 };
0173 
0174 // Tuple-like type lists
0175 template <typename Head_, typename... Tail_>
0176 struct Types {
0177   using Head = Head_;
0178   using Tail = Types<Tail_...>;
0179 };
0180 
0181 template <typename Head_>
0182 struct Types<Head_> {
0183   using Head = Head_;
0184   using Tail = None;
0185 };
0186 
0187 // Helper metafunctions to tell apart a single type from types
0188 // generated by ::testing::Types
0189 template <typename... Ts>
0190 struct ProxyTypeList {
0191   using type = Types<Ts...>;
0192 };
0193 
0194 template <typename>
0195 struct is_proxy_type_list : std::false_type {};
0196 
0197 template <typename... Ts>
0198 struct is_proxy_type_list<ProxyTypeList<Ts...>> : std::true_type {};
0199 
0200 // Generator which conditionally creates type lists.
0201 // It recognizes if a requested type list should be created
0202 // and prevents creating a new type list nested within another one.
0203 template <typename T>
0204 struct GenerateTypeList {
0205  private:
0206   using proxy = typename std::conditional<is_proxy_type_list<T>::value, T,
0207                                           ProxyTypeList<T>>::type;
0208 
0209  public:
0210   using type = typename proxy::type;
0211 };
0212 
0213 }  // namespace internal
0214 
0215 template <typename... Ts>
0216 using Types = internal::ProxyTypeList<Ts...>;
0217 
0218 }  // namespace testing
0219 
0220 #endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_