Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:31:57

0001 //
0002 // Copyright 2019 The Abseil Authors.
0003 //
0004 // Licensed under the Apache License, Version 2.0 (the "License");
0005 // you may not use this file except in compliance with the License.
0006 // You may obtain a copy of the License at
0007 //
0008 //      https://www.apache.org/licenses/LICENSE-2.0
0009 //
0010 // Unless required by applicable law or agreed to in writing, software
0011 // distributed under the License is distributed on an "AS IS" BASIS,
0012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013 // See the License for the specific language governing permissions and
0014 // limitations under the License.
0015 //
0016 #ifndef ABSL_TYPES_INTERNAL_SPAN_H_
0017 #define ABSL_TYPES_INTERNAL_SPAN_H_
0018 
0019 #include <algorithm>
0020 #include <cstddef>
0021 #include <string>
0022 #include <type_traits>
0023 
0024 #include "absl/algorithm/algorithm.h"
0025 #include "absl/base/internal/throw_delegate.h"
0026 #include "absl/meta/type_traits.h"
0027 
0028 namespace absl {
0029 ABSL_NAMESPACE_BEGIN
0030 
0031 template <typename T>
0032 class Span;
0033 
0034 namespace span_internal {
0035 // Wrappers for access to container data pointers.
0036 template <typename C>
0037 constexpr auto GetDataImpl(C& c, char) noexcept  // NOLINT(runtime/references)
0038     -> decltype(c.data()) {
0039   return c.data();
0040 }
0041 
0042 // Before C++17, std::string::data returns a const char* in all cases.
0043 inline char* GetDataImpl(std::string& s,  // NOLINT(runtime/references)
0044                          int) noexcept {
0045   return &s[0];
0046 }
0047 
0048 template <typename C>
0049 constexpr auto GetData(C& c) noexcept  // NOLINT(runtime/references)
0050     -> decltype(GetDataImpl(c, 0)) {
0051   return GetDataImpl(c, 0);
0052 }
0053 
0054 // Detection idioms for size() and data().
0055 template <typename C>
0056 using HasSize =
0057     std::is_integral<absl::decay_t<decltype(std::declval<C&>().size())>>;
0058 
0059 // We want to enable conversion from vector<T*> to Span<const T* const> but
0060 // disable conversion from vector<Derived> to Span<Base>. Here we use
0061 // the fact that U** is convertible to Q* const* if and only if Q is the same
0062 // type or a more cv-qualified version of U.  We also decay the result type of
0063 // data() to avoid problems with classes which have a member function data()
0064 // which returns a reference.
0065 template <typename T, typename C>
0066 using HasData =
0067     std::is_convertible<absl::decay_t<decltype(GetData(std::declval<C&>()))>*,
0068                         T* const*>;
0069 
0070 // Extracts value type from a Container
0071 template <typename C>
0072 struct ElementType {
0073   using type = typename absl::remove_reference_t<C>::value_type;
0074 };
0075 
0076 template <typename T, size_t N>
0077 struct ElementType<T (&)[N]> {
0078   using type = T;
0079 };
0080 
0081 template <typename C>
0082 using ElementT = typename ElementType<C>::type;
0083 
0084 template <typename T>
0085 using EnableIfMutable =
0086     typename std::enable_if<!std::is_const<T>::value, int>::type;
0087 
0088 template <template <typename> class SpanT, typename T>
0089 bool EqualImpl(SpanT<T> a, SpanT<T> b) {
0090   static_assert(std::is_const<T>::value, "");
0091   return std::equal(a.begin(), a.end(), b.begin(), b.end());
0092 }
0093 
0094 template <template <typename> class SpanT, typename T>
0095 bool LessThanImpl(SpanT<T> a, SpanT<T> b) {
0096   // We can't use value_type since that is remove_cv_t<T>, so we go the long way
0097   // around.
0098   static_assert(std::is_const<T>::value, "");
0099   return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
0100 }
0101 
0102 template <typename From, typename To>
0103 using EnableIfConvertibleTo =
0104     typename std::enable_if<std::is_convertible<From, To>::value>::type;
0105 
0106 // IsView is true for types where the return type of .data() is the same for
0107 // mutable and const instances. This isn't foolproof, but it's only used to
0108 // enable a compiler warning.
0109 template <typename T, typename = void, typename = void>
0110 struct IsView {
0111   static constexpr bool value = false;
0112 };
0113 
0114 template <typename T>
0115 struct IsView<
0116     T, absl::void_t<decltype(span_internal::GetData(std::declval<const T&>()))>,
0117     absl::void_t<decltype(span_internal::GetData(std::declval<T&>()))>> {
0118  private:
0119   using Container = std::remove_const_t<T>;
0120   using ConstData =
0121       decltype(span_internal::GetData(std::declval<const Container&>()));
0122   using MutData = decltype(span_internal::GetData(std::declval<Container&>()));
0123  public:
0124   static constexpr bool value = std::is_same<ConstData, MutData>::value;
0125 };
0126 
0127 // These enablers result in 'int' so they can be used as typenames or defaults
0128 // in template parameters lists.
0129 template <typename T>
0130 using EnableIfIsView = std::enable_if_t<IsView<T>::value, int>;
0131 
0132 template <typename T>
0133 using EnableIfNotIsView = std::enable_if_t<!IsView<T>::value, int>;
0134 
0135 }  // namespace span_internal
0136 ABSL_NAMESPACE_END
0137 }  // namespace absl
0138 
0139 #endif  // ABSL_TYPES_INTERNAL_SPAN_H_