summaryrefslogtreecommitdiff
path: root/absl/types
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2019-03-27 08:05:41 -0700
committerGravatar Gennadiy Civil <misterg@google.com>2019-03-27 12:14:39 -0400
commit5b65c4af5107176555b23a638e5947686410ac1f (patch)
treee1472a42cd71edb7bac59f39d3e9d95f5f0a7b59 /absl/types
parenteab2078b53c9e3d9d240135c09d27e3393acb50a (diff)
Export of internal Abseil changes.
-- f6c627ce4470a814adc377947b58346eef69a4c9 by Jon Cohen <cohenjon@google.com>: Don't create install rules when Abseil is used as a subdirectory. Fix #287 PiperOrigin-RevId: 240559825 -- a5d9b06fe736143068997988b654b5f66ec3266a by Matt Calabrese <calabrese@google.com>: Make absl::nullopt an inline constexpr variable, as specified in the standard (with a workaround for pre-c++17 compilers). PiperOrigin-RevId: 240552286 -- d7bee50cff745fbb8d1cdf56a200d9073d311c80 by Abseil Team <absl-team@google.com>: Internal Change PiperOrigin-RevId: 240425622 -- 828dd49d392d83dbeecd9d3e9cb14551ab265905 by Jon Cohen <cohenjon@google.com>: Add default link options to absl builds. Currently all this does is add -ignore:4221 to Abseil msvc builds, but the structure is all in place to add more link options when necessary Fix #277 Note: This CL changes tact for us in that it puts the default options in the helper function as opposed to the invocations of absl_cc_blah. The original intent of keeping these out of the helper functions was to make generating the CMakeLists.txt files have a smaller diff, but looking now that is a problem for the future, and small compared to making maintenance and use of our CMake buildsystem easier PiperOrigin-RevId: 240409463 -- 4aa120e9dcf76d29e9ca0008d0f6d4d9fa8abe8c by Matt Kulukundis <kfm@google.com>: Reduce flake rate for non-determistic test to < 1/10,000 PiperOrigin-RevId: 240370938 -- bc30e219531827bfbf90915b2067c7fb8160bb6d by Derek Mauro <dmauro@google.com>: Add Bazel caching on Kokoro for new linux targets. PiperOrigin-RevId: 240356556 -- c4e06d79a50d7bb211312b7845c4bd92c0761747 by Jon Cohen <cohenjon@google.com>: include AbseilInstallDirs instead of GNUInstallDirs. It worked before because global_CMakeLists.txt also included AbseilInstallDirs PiperOrigin-RevId: 240206409 -- c254dc6cade8a263f3f97fb1417d92fe5235ff32 by Jon Cohen <cohenjon@google.com>: Fix logic for when we create the variant_exception_safety_test in CMake. Currently we are only running in on gcc > 4.9, when we want it run on every compiler except gcc <= 4.8 PiperOrigin-RevId: 240194174 -- 01518006b351d3670ba1d349cfbcb7dd6f3a8b84 by CJ Johnson <johnsoncj@google.com>: Removes old implementation warning comment now that InlinedVector has an implementation detail file PiperOrigin-RevId: 240167265 -- eb05355ae8c7397752ab7a65afc9e0a99472ba9d by Jon Cohen <cohenjon@google.com>: Remove the forward declaration of Span PiperOrigin-RevId: 240156660 -- b7e75aa3933d6e79dd086821cf58d15e72f476f4 by Jon Cohen <cohenjon@google.com>: Prepare CMake install rule for LTS releases: * Remove the warning against installing in system install locations * Insert versioning to keep different LTS installs from colliding. Headers are installed in <prefix>/absl_$version/include, .a files in <prefix>/absl_$version/lib, and config files in <prefix>/absl_$version/lib/cmake PiperOrigin-RevId: 240153986 -- de63488ab6236e041f08260794b0b634a2b8ed16 by CJ Johnson <johnsoncj@google.com>: Reduce reader confusion by using std::addressof(...) even when the type is known to not overload operator&(...) PiperOrigin-RevId: 240131902 GitOrigin-RevId: f6c627ce4470a814adc377947b58346eef69a4c9 Change-Id: I95dbbacaaf65aceeeca9e9bee5fd9ea456225f62
Diffstat (limited to 'absl/types')
-rw-r--r--absl/types/BUILD.bazel31
-rw-r--r--absl/types/CMakeLists.txt6
-rw-r--r--absl/types/optional.cc24
-rw-r--r--absl/types/optional.h27
-rw-r--r--absl/types/optional_test.cc8
-rw-r--r--absl/types/span.h97
6 files changed, 90 insertions, 103 deletions
diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel
index 7da00030..a62522e4 100644
--- a/absl/types/BUILD.bazel
+++ b/absl/types/BUILD.bazel
@@ -17,6 +17,7 @@
load(
"//absl:copts/configure_copts.bzl",
"ABSL_DEFAULT_COPTS",
+ "ABSL_DEFAULT_LINKOPTS",
"ABSL_TEST_COPTS",
"ABSL_EXCEPTIONS_FLAG",
"ABSL_EXCEPTIONS_FLAG_LINKOPTS",
@@ -30,6 +31,7 @@ cc_library(
name = "any",
hdrs = ["any.h"],
copts = ABSL_DEFAULT_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":bad_any_cast",
"//absl/base:config",
@@ -43,6 +45,7 @@ cc_library(
name = "bad_any_cast",
hdrs = ["bad_any_cast.h"],
copts = ABSL_DEFAULT_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":bad_any_cast_impl",
"//absl/base:config",
@@ -56,7 +59,7 @@ cc_library(
"bad_any_cast.h",
],
copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS,
- linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
visibility = ["//visibility:private"],
deps = [
"//absl/base",
@@ -71,7 +74,7 @@ cc_test(
"any_test.cc",
],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
- linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
deps = [
":any",
"//absl/base",
@@ -89,6 +92,7 @@ cc_test(
"any_test.cc",
],
copts = ABSL_TEST_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":any",
"//absl/base",
@@ -103,7 +107,7 @@ cc_test(
name = "any_exception_safety_test",
srcs = ["any_exception_safety_test.cc"],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
- linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
deps = [
":any",
"//absl/base:exception_safety_testing",
@@ -115,6 +119,7 @@ cc_library(
name = "span",
hdrs = ["span.h"],
copts = ABSL_DEFAULT_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
"//absl/algorithm",
"//absl/base:core_headers",
@@ -128,7 +133,7 @@ cc_test(
size = "small",
srcs = ["span_test.cc"],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
- linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
deps = [
":span",
"//absl/base:config",
@@ -147,6 +152,7 @@ cc_test(
size = "small",
srcs = ["span_test.cc"],
copts = ABSL_TEST_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":span",
"//absl/base:config",
@@ -162,11 +168,12 @@ cc_test(
cc_library(
name = "optional",
- srcs = ["optional.cc"],
hdrs = ["optional.h"],
copts = ABSL_DEFAULT_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":bad_optional_access",
+ "//absl/base:base_internal",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/memory",
@@ -180,7 +187,7 @@ cc_library(
srcs = ["bad_optional_access.cc"],
hdrs = ["bad_optional_access.h"],
copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG,
- linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
deps = [
"//absl/base",
"//absl/base:config",
@@ -192,7 +199,7 @@ cc_library(
srcs = ["bad_variant_access.cc"],
hdrs = ["bad_variant_access.h"],
copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS,
- linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
deps = [
"//absl/base",
"//absl/base:config",
@@ -206,7 +213,7 @@ cc_test(
"optional_test.cc",
],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
- linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
deps = [
":optional",
"//absl/base",
@@ -223,7 +230,7 @@ cc_test(
"optional_exception_safety_test.cc",
],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
- linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
deps = [
":optional",
"//absl/base:exception_safety_testing",
@@ -236,6 +243,7 @@ cc_library(
srcs = ["internal/variant.h"],
hdrs = ["variant.h"],
copts = ABSL_DEFAULT_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":bad_variant_access",
"//absl/base:base_internal",
@@ -251,7 +259,7 @@ cc_test(
size = "small",
srcs = ["variant_test.cc"],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
- linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
deps = [
":variant",
"//absl/base:config",
@@ -269,6 +277,7 @@ cc_test(
"variant_benchmark.cc",
],
copts = ABSL_TEST_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
tags = ["benchmark"],
deps = [
":variant",
@@ -284,7 +293,7 @@ cc_test(
"variant_exception_safety_test.cc",
],
copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG,
- linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS,
+ linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS + ABSL_DEFAULT_LINKOPTS,
deps = [
":variant",
"//absl/base:config",
diff --git a/absl/types/CMakeLists.txt b/absl/types/CMakeLists.txt
index 8afde466..910c099a 100644
--- a/absl/types/CMakeLists.txt
+++ b/absl/types/CMakeLists.txt
@@ -172,12 +172,11 @@ absl_cc_library(
optional
HDRS
"optional.h"
- SRCS
- "optional.cc"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::bad_optional_access
+ absl::base_internal
absl::config
absl::core_headers
absl::memory
@@ -297,7 +296,8 @@ absl_cc_test(
)
# TODO(cohenjon,zhangxy) Figure out why this test is failing on gcc 4.8
-if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9)
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
+else()
absl_cc_test(
NAME
variant_exception_safety_test
diff --git a/absl/types/optional.cc b/absl/types/optional.cc
deleted file mode 100644
index 44ff8294..00000000
--- a/absl/types/optional.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2017 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.
-
-#include "absl/types/optional.h"
-
-#ifndef ABSL_HAVE_STD_OPTIONAL
-namespace absl {
-
-nullopt_t::init_t nullopt_t::init;
-extern const nullopt_t nullopt{nullopt_t::init};
-
-} // namespace absl
-#endif // ABSL_HAVE_STD_OPTIONAL
diff --git a/absl/types/optional.h b/absl/types/optional.h
index f0ae9a17..6806160d 100644
--- a/absl/types/optional.h
+++ b/absl/types/optional.h
@@ -61,6 +61,7 @@ using std::nullopt;
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/internal/inline_variable.h"
#include "absl/meta/type_traits.h"
#include "absl/types/bad_optional_access.h"
@@ -126,32 +127,30 @@ namespace absl {
template <typename T>
class optional;
+namespace optional_internal {
+
+// This tag type is used as a constructor parameter type for `nullopt_t`.
+struct init_t {
+ explicit init_t() = default;
+};
+
+} // namespace optional_internal
+
// nullopt_t
//
// Class type for `absl::nullopt` used to indicate an `absl::optional<T>` type
// that does not contain a value.
struct nullopt_t {
- struct init_t {};
- static init_t init;
-
// It must not be default-constructible to avoid ambiguity for opt = {}.
- // Note the non-const reference, which is to eliminate ambiguity for code
- // like:
- //
- // struct S { int value; };
- //
- // void Test() {
- // optional<S> opt;
- // opt = {{}};
- // }
- explicit constexpr nullopt_t(init_t& /*unused*/) {}
+ explicit constexpr nullopt_t(optional_internal::init_t) noexcept {}
};
// nullopt
//
// A tag constant of type `absl::nullopt_t` used to indicate an empty
// `absl::optional` in certain functions, such as construction or assignment.
-extern const nullopt_t nullopt;
+ABSL_INTERNAL_INLINE_CONSTEXPR(nullopt_t, nullopt,
+ nullopt_t(optional_internal::init_t()));
namespace optional_internal {
diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc
index 0665488e..897c183a 100644
--- a/absl/types/optional_test.cc
+++ b/absl/types/optional_test.cc
@@ -179,15 +179,7 @@ TEST(optionalTest, DefaultConstructor) {
TEST(optionalTest, nulloptConstructor) {
absl::optional<int> empty(absl::nullopt);
EXPECT_FALSE(empty);
-
-#ifdef ABSL_HAVE_STD_OPTIONAL
constexpr absl::optional<int> cempty{absl::nullopt};
-#else
- // Creating a temporary absl::nullopt_t object instead of using absl::nullopt
- // because absl::nullopt cannot be constexpr and have external linkage at the
- // same time.
- constexpr absl::optional<int> cempty{absl::nullopt_t(absl::nullopt_t::init)};
-#endif
static_assert(!cempty.has_value(), "");
EXPECT_TRUE((std::is_nothrow_constructible<absl::optional<int>,
absl::nullopt_t>::value));
diff --git a/absl/types/span.h b/absl/types/span.h
index d7f48d9f..e5c4fe1e 100644
--- a/absl/types/span.h
+++ b/absl/types/span.h
@@ -73,9 +73,6 @@
namespace absl {
-template <typename T>
-class Span;
-
namespace span_internal {
// A constexpr min function
constexpr size_t Min(size_t a, size_t b) noexcept { return a < b ? a : b; }
@@ -133,14 +130,16 @@ template <typename T>
using EnableIfMutable =
typename std::enable_if<!std::is_const<T>::value, int>::type;
-template <typename T>
-bool EqualImpl(Span<T> a, Span<T> b) {
+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 <typename T>
-bool LessThanImpl(Span<T> a, Span<T> b) {
+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());
}
@@ -165,8 +164,8 @@ 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 EnableIfConvertibleToSpanConst =
- typename std::enable_if<IsConvertible<From, Span<const To>>::value>::type;
+using EnableIfConvertibleTo =
+ typename std::enable_if<IsConvertible<From, To>::value>::type;
} // namespace span_internal
//------------------------------------------------------------------------------
@@ -551,25 +550,27 @@ const typename Span<T>::size_type Span<T>::npos;
// operator==
template <typename T>
bool operator==(Span<T> a, Span<T> b) {
- return span_internal::EqualImpl<const T>(a, b);
+ return span_internal::EqualImpl<Span, const T>(a, b);
}
template <typename T>
bool operator==(Span<const T> a, Span<T> b) {
- return span_internal::EqualImpl<const T>(a, b);
+ return span_internal::EqualImpl<Span, const T>(a, b);
}
template <typename T>
bool operator==(Span<T> a, Span<const T> b) {
- return span_internal::EqualImpl<const T>(a, b);
+ return span_internal::EqualImpl<Span, const T>(a, b);
}
-template <typename T, typename U,
- typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+ typename T, typename U,
+ typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
bool operator==(const U& a, Span<T> b) {
- return span_internal::EqualImpl<const T>(a, b);
+ return span_internal::EqualImpl<Span, const T>(a, b);
}
-template <typename T, typename U,
- typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+ typename T, typename U,
+ typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
bool operator==(Span<T> a, const U& b) {
- return span_internal::EqualImpl<const T>(a, b);
+ return span_internal::EqualImpl<Span, const T>(a, b);
}
// operator!=
@@ -585,13 +586,15 @@ template <typename T>
bool operator!=(Span<T> a, Span<const T> b) {
return !(a == b);
}
-template <typename T, typename U,
- typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+ typename T, typename U,
+ typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
bool operator!=(const U& a, Span<T> b) {
return !(a == b);
}
-template <typename T, typename U,
- typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+ typename T, typename U,
+ typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
bool operator!=(Span<T> a, const U& b) {
return !(a == b);
}
@@ -599,25 +602,27 @@ bool operator!=(Span<T> a, const U& b) {
// operator<
template <typename T>
bool operator<(Span<T> a, Span<T> b) {
- return span_internal::LessThanImpl<const T>(a, b);
+ return span_internal::LessThanImpl<Span, const T>(a, b);
}
template <typename T>
bool operator<(Span<const T> a, Span<T> b) {
- return span_internal::LessThanImpl<const T>(a, b);
+ return span_internal::LessThanImpl<Span, const T>(a, b);
}
template <typename T>
bool operator<(Span<T> a, Span<const T> b) {
- return span_internal::LessThanImpl<const T>(a, b);
+ return span_internal::LessThanImpl<Span, const T>(a, b);
}
-template <typename T, typename U,
- typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+ typename T, typename U,
+ typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
bool operator<(const U& a, Span<T> b) {
- return span_internal::LessThanImpl<const T>(a, b);
+ return span_internal::LessThanImpl<Span, const T>(a, b);
}
-template <typename T, typename U,
- typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+ typename T, typename U,
+ typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
bool operator<(Span<T> a, const U& b) {
- return span_internal::LessThanImpl<const T>(a, b);
+ return span_internal::LessThanImpl<Span, const T>(a, b);
}
// operator>
@@ -633,13 +638,15 @@ template <typename T>
bool operator>(Span<T> a, Span<const T> b) {
return b < a;
}
-template <typename T, typename U,
- typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+ typename T, typename U,
+ typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
bool operator>(const U& a, Span<T> b) {
return b < a;
}
-template <typename T, typename U,
- typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+ typename T, typename U,
+ typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
bool operator>(Span<T> a, const U& b) {
return b < a;
}
@@ -657,13 +664,15 @@ template <typename T>
bool operator<=(Span<T> a, Span<const T> b) {
return !(b < a);
}
-template <typename T, typename U,
- typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+ typename T, typename U,
+ typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
bool operator<=(const U& a, Span<T> b) {
return !(b < a);
}
-template <typename T, typename U,
- typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+ typename T, typename U,
+ typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
bool operator<=(Span<T> a, const U& b) {
return !(b < a);
}
@@ -681,13 +690,15 @@ template <typename T>
bool operator>=(Span<T> a, Span<const T> b) {
return !(a < b);
}
-template <typename T, typename U,
- typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+ typename T, typename U,
+ typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
bool operator>=(const U& a, Span<T> b) {
return !(a < b);
}
-template <typename T, typename U,
- typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
+template <
+ typename T, typename U,
+ typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
bool operator>=(Span<T> a, const U& b) {
return !(a < b);
}