diff options
author | Abseil Team <absl-team@google.com> | 2019-03-28T18·12-0700 |
---|---|---|
committer | Gennadiy Civil <misterg@google.com> | 2019-03-28T20·54-0400 |
commit | 2c8421e1c6cef0da9e8a20b01c15256ec9ec116d (patch) | |
tree | 3325b53470a6de6e08c3d2552233e19564d81c5f /absl/types/internal | |
parent | 5b65c4af5107176555b23a638e5947686410ac1f (diff) |
Export of internal Abseil changes.
-- fcf9d3facb12451964ad1850073cbfb6f9739379 by CJ Johnson <johnsoncj@google.com>: Makes it obvious to readers that the comparison operators do not branch more than needed PiperOrigin-RevId: 240811527 -- 680c586f81f805be68e96caffb28d5f46b6a6511 by Jon Cohen <cohenjon@google.com>: Consistently use "if(" instead of "if (" in CMake files PiperOrigin-RevId: 240621819 -- c4acc506648622389f33f564fd94f8dda08cb61a by Tom Manshreck <shreck@google.com>: Internal change PiperOrigin-RevId: 240619556 -- ddbc1894944aae96767c876a1ae8696ddaba42a2 by Jon Cohen <cohenjon@google.com>: Remove the warning about install prefixes when we aren't installing abseil PiperOrigin-RevId: 240614750 -- 086c4fad213d99e875038bc8a1c7268e28a7ebf3 by Abseil Team <absl-team@google.com>: Adjust some tests and test cases which fail on WebAssembly PiperOrigin-RevId: 240592367 -- 46c2c09723a37ef4911ae3c64aab92e3f0fdba79 by Abseil Team <absl-team@google.com>: CMake install target update - Add prefix absl_ to each target when install rule are disabled. - Disable all install commands when absl is used as subdirectory (Fix #287) PiperOrigin-RevId: 240575083 -- 8d88063ed5b16f982a91950693d37ca18fdd46d8 by Jon Cohen <cohenjon@google.com>: Correctly link to Threads::Threads for a few cmake targets which were missing it. PiperOrigin-RevId: 240574513 GitOrigin-RevId: fcf9d3facb12451964ad1850073cbfb6f9739379 Change-Id: I031c57de8cd88554348eb8bd1371d01d15ff1fc7
Diffstat (limited to 'absl/types/internal')
-rw-r--r-- | absl/types/internal/span.h | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/absl/types/internal/span.h b/absl/types/internal/span.h new file mode 100644 index 000000000000..d203aad59165 --- /dev/null +++ b/absl/types/internal/span.h @@ -0,0 +1,126 @@ +// +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef ABSL_TYPES_INTERNAL_SPAN_H_ +#define ABSL_TYPES_INTERNAL_SPAN_H_ + +#include <algorithm> +#include <cstddef> +#include <string> +#include <type_traits> + +#include "absl/algorithm/algorithm.h" +#include "absl/base/internal/throw_delegate.h" +#include "absl/meta/type_traits.h" + +namespace absl { + +namespace span_internal { +// A constexpr min function +constexpr size_t Min(size_t a, size_t b) noexcept { return a < b ? a : b; } + +// Wrappers for access to container data pointers. +template <typename C> +constexpr auto GetDataImpl(C& c, char) noexcept // NOLINT(runtime/references) + -> decltype(c.data()) { + return c.data(); +} + +// Before C++17, std::string::data returns a const char* in all cases. +inline char* GetDataImpl(std::string& s, // NOLINT(runtime/references) + int) noexcept { + return &s[0]; +} + +template <typename C> +constexpr auto GetData(C& c) noexcept // NOLINT(runtime/references) + -> decltype(GetDataImpl(c, 0)) { + return GetDataImpl(c, 0); +} + +// Detection idioms for size() and data(). +template <typename C> +using HasSize = + std::is_integral<absl::decay_t<decltype(std::declval<C&>().size())>>; + +// We want to enable conversion from vector<T*> to Span<const T* const> but +// disable conversion from vector<Derived> to Span<Base>. Here we use +// the fact that U** is convertible to Q* const* if and only if Q is the same +// type or a more cv-qualified version of U. We also decay the result type of +// data() to avoid problems with classes which have a member function data() +// which returns a reference. +template <typename T, typename C> +using HasData = + std::is_convertible<absl::decay_t<decltype(GetData(std::declval<C&>()))>*, + T* const*>; + +// Extracts value type from a Container +template <typename C> +struct ElementType { + using type = typename absl::remove_reference_t<C>::value_type; +}; + +template <typename T, size_t N> +struct ElementType<T (&)[N]> { + using type = T; +}; + +template <typename C> +using ElementT = typename ElementType<C>::type; + +template <typename T> +using EnableIfMutable = + typename std::enable_if<!std::is_const<T>::value, int>::type; + +template <template <typename> class SpanT, typename T> +bool EqualImpl(SpanT<T> a, SpanT<T> b) { + static_assert(std::is_const<T>::value, ""); + return absl::equal(a.begin(), a.end(), b.begin(), b.end()); +} + +template <template <typename> class SpanT, typename T> +bool LessThanImpl(SpanT<T> a, SpanT<T> b) { + // We can't use value_type since that is remove_cv_t<T>, so we go the long way + // around. + static_assert(std::is_const<T>::value, ""); + return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); +} + +// The `IsConvertible` classes here are needed because of the +// `std::is_convertible` bug in libcxx when compiled with GCC. This build +// configuration is used by Android NDK toolchain. Reference link: +// https://bugs.llvm.org/show_bug.cgi?id=27538. +template <typename From, typename To> +struct IsConvertibleHelper { + private: + static std::true_type testval(To); + static std::false_type testval(...); + + public: + using type = decltype(testval(std::declval<From>())); +}; + +template <typename From, typename To> +struct IsConvertible : IsConvertibleHelper<From, To>::type {}; + +// TODO(zhangxy): replace `IsConvertible` with `std::is_convertible` once the +// older version of libcxx is not supported. +template <typename From, typename To> +using EnableIfConvertibleTo = + typename std::enable_if<IsConvertible<From, To>::value>::type; +} // namespace span_internal +} // namespace absl + +#endif // ABSL_TYPES_INTERNAL_SPAN_H_ |