about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--CMake/AbseilHelpers.cmake16
-rw-r--r--CMake/AbseilInstallDirs.cmake2
-rw-r--r--CMake/abslConfig.cmake.in5
-rw-r--r--CMakeLists.txt28
-rw-r--r--absl/base/CMakeLists.txt11
-rw-r--r--absl/base/internal/cmake_thread_test.cc22
-rw-r--r--absl/container/inlined_vector.h53
-rw-r--r--absl/container/internal/raw_hash_set_test.cc4
-rw-r--r--absl/copts/AbseilConfigureCopts.cmake6
-rw-r--r--absl/synchronization/CMakeLists.txt2
-rw-r--r--absl/types/BUILD.bazel7
-rw-r--r--absl/types/CMakeLists.txt2
-rw-r--r--absl/types/internal/span.h126
-rw-r--r--absl/types/span.h100
14 files changed, 235 insertions, 149 deletions
diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake
index be9a0e9ccf37..58f98c8c3857 100644
--- a/CMake/AbseilHelpers.cmake
+++ b/CMake/AbseilHelpers.cmake
@@ -59,7 +59,7 @@ set(ABSL_IDE_FOLDER Abseil)
 #   SRCS
 #     "b.cc"
 #   DEPS
-#     absl_internal_awesome # not "awesome"!
+#     absl::awesome # not "awesome" !
 #   PUBLIC
 # )
 #
@@ -68,7 +68,7 @@ set(ABSL_IDE_FOLDER Abseil)
 #     main_lib
 #   ...
 #   DEPS
-#     absl::fantastic_lib # since fantastic_lib is public
+#     absl::fantastic_lib
 # )
 #
 # TODO: Implement "ALWAYSLINK"
@@ -80,8 +80,12 @@ function(absl_cc_library)
     ${ARGN}
   )
 
-  if (NOT ABSL_CC_LIB_TESTONLY OR ABSL_RUN_TESTS)
-    set(_NAME "${ABSL_CC_LIB_NAME}")
+  if(NOT ABSL_CC_LIB_TESTONLY OR ABSL_RUN_TESTS)
+    if(ABSL_ENABLE_INSTALL)
+      set(_NAME "${ABSL_CC_LIB_NAME}")
+    else()
+      set(_NAME "absl_${ABSL_CC_LIB_NAME}")
+    endif()
 
     # Check if this is a header-only library
     # Note that as of February 2019, many popular OS's (for example, Ubuntu
@@ -93,7 +97,7 @@ function(absl_cc_library)
         list(REMOVE_ITEM ABSL_CC_SRCS "${src_file}")
       endif()
     endforeach()
-    if ("${ABSL_CC_SRCS}" STREQUAL "")
+    if("${ABSL_CC_SRCS}" STREQUAL "")
       set(ABSL_CC_LIB_IS_INTERFACE 1)
     else()
       set(ABSL_CC_LIB_IS_INTERFACE 0)
@@ -155,7 +159,7 @@ function(absl_cc_library)
 
     # TODO currently we don't install googletest alongside abseil sources, so
     # installed abseil can't be tested.
-    if (NOT ABSL_CC_LIB_TESTONLY)
+    if(NOT ABSL_CC_LIB_TESTONLY AND ABSL_ENABLE_INSTALL)
       install(TARGETS ${_NAME} EXPORT ${PROJECT_NAME}Targets
             RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR}
             LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR}
diff --git a/CMake/AbseilInstallDirs.cmake b/CMake/AbseilInstallDirs.cmake
index 5b67008bc68c..b67272f830c1 100644
--- a/CMake/AbseilInstallDirs.cmake
+++ b/CMake/AbseilInstallDirs.cmake
@@ -6,7 +6,7 @@ include(GNUInstallDirs)
 # Abseil's internal Copybara (https://github.com/google/copybara) workflows and
 # isn't visible in the CMake buildsystem itself.
 
-if (absl_VERSION)
+if(absl_VERSION)
   set(ABSL_SUBDIR "${PROJECT_NAME}_${PROJECT_VERSION}")
   set(ABSL_INSTALL_BINDIR "${CMAKE_INSTALL_BINDIR}/${ABSL_SUBDIR}")
   set(ABSL_INSTALL_CONFIGDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${ABSL_SUBDIR}")
diff --git a/CMake/abslConfig.cmake.in b/CMake/abslConfig.cmake.in
index bf8c4f6a0ec9..60847fa7723f 100644
--- a/CMake/abslConfig.cmake.in
+++ b/CMake/abslConfig.cmake.in
@@ -1,5 +1,6 @@
-## absl CMake configuration file.  Note that there is no corresponding
-# abslConfigVersion.cmake since non-LTS Abseil isn't versioned.
+# absl CMake configuration file.
+
+include(FindThreads)
 
 @PACKAGE_INIT@
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ad55fa47c3df..dff46f910da8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -86,18 +86,6 @@ if(${ABSL_RUN_TESTS})
   enable_testing()
 endif()
 
-# absl:lts-remove-begin(system installation is supported for LTS releases)
-# We don't support system-wide installation
-list(APPEND SYSTEM_INSTALL_DIRS "/usr/local" "/usr" "/opt/" "/opt/local" "c:/Program Files/${PROJECT_NAME}")
-if(NOT DEFINED CMAKE_INSTALL_PREFIX OR CMAKE_INSTALL_PREFIX IN_LIST SYSTEM_INSTALL_DIRS)
-  message(WARNING "\
-The default and system-level install directories are unsupported except in LTS \
-releases of Abseil.  Please set CMAKE_INSTALL_PREFIX to install Abseil in your \
-source or build tree directly.\
-  ")
-endif()
-# absl:lts-remove-end
-
 ## check targets
 if(BUILD_TESTING)
 
@@ -121,7 +109,19 @@ endif()
 
 add_subdirectory(absl)
 
-if (ABSL_ENABLE_INSTALL)
+if(ABSL_ENABLE_INSTALL)
+  # absl:lts-remove-begin(system installation is supported for LTS releases)
+  # We don't support system-wide installation
+  list(APPEND SYSTEM_INSTALL_DIRS "/usr/local" "/usr" "/opt/" "/opt/local" "c:/Program Files/${PROJECT_NAME}")
+  if(NOT DEFINED CMAKE_INSTALL_PREFIX OR CMAKE_INSTALL_PREFIX IN_LIST SYSTEM_INSTALL_DIRS)
+    message(WARNING "\
+  The default and system-level install directories are unsupported except in LTS \
+  releases of Abseil.  Please set CMAKE_INSTALL_PREFIX to install Abseil in your \
+  source or build tree directly.\
+    ")
+  endif()
+  # absl:lts-remove-end
+
   # install as a subdirectory only
   install(EXPORT ${PROJECT_NAME}Targets
     NAMESPACE absl::
@@ -140,7 +140,7 @@ if (ABSL_ENABLE_INSTALL)
   # Abseil only has a version in LTS releases.  This mechanism is accomplished
   # Abseil's internal Copybara (https://github.com/google/copybara) workflows and
   # isn't visible in the CMake buildsystem itself.
-  if (absl_VERSION)
+  if(absl_VERSION)
     write_basic_package_version_file(
       "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
       COMPATIBILITY ExactVersion
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index d8a311c2f1fe..cd1ec4128539 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -88,6 +88,7 @@ absl_cc_library(
     absl::core_headers
     absl::dynamic_annotations
     absl::spinlock_wait
+    Threads::Threads
 )
 
 absl_cc_library(
@@ -134,6 +135,7 @@ absl_cc_library(
     absl::core_headers
     absl::dynamic_annotations
     absl::spinlock_wait
+    Threads::Threads
   PUBLIC
 )
 
@@ -438,3 +440,12 @@ absl_cc_test(
     absl::scoped_set_env
     gtest_main
 )
+
+absl_cc_test(
+  NAME
+    cmake_thread_test
+  SRCS
+    "internal/cmake_thread_test.cc"
+  DEPS
+    absl::base
+)
diff --git a/absl/base/internal/cmake_thread_test.cc b/absl/base/internal/cmake_thread_test.cc
new file mode 100644
index 000000000000..f70bb24eb7b4
--- /dev/null
+++ b/absl/base/internal/cmake_thread_test.cc
@@ -0,0 +1,22 @@
+// Copyright 2018 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 <iostream>
+#include "absl/base/internal/thread_identity.h"
+
+int main() {
+  auto* tid = absl::base_internal::CurrentThreadIdentityIfPresent();
+  // Make sure the above call can't be optimized out
+  std::cout << (void*)tid << std::endl;
+}
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index bd4ed6667ad2..0f066860623c 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -847,7 +847,7 @@ class InlinedVector {
 
  private:
   template <typename H, typename TheT, size_t TheN, typename TheA>
-  friend auto AbslHashValue(H h, const InlinedVector<TheT, TheN, TheA>& v) -> H;
+  friend H AbslHashValue(H h, const absl::InlinedVector<TheT, TheN, TheA>& a);
 
   const Tag& tag() const { return storage_.allocator_and_tag_.tag(); }
 
@@ -1231,8 +1231,8 @@ class InlinedVector {
 // Swaps the contents of two inlined vectors. This convenience function
 // simply calls `InlinedVector::swap()`.
 template <typename T, size_t N, typename A>
-auto swap(InlinedVector<T, N, A>& a,
-          InlinedVector<T, N, A>& b) noexcept(noexcept(a.swap(b))) -> void {
+void swap(absl::InlinedVector<T, N, A>& a,
+          absl::InlinedVector<T, N, A>& b) noexcept(noexcept(a.swap(b))) {
   a.swap(b);
 }
 
@@ -1240,17 +1240,21 @@ auto swap(InlinedVector<T, N, A>& a,
 //
 // Tests the equivalency of the contents of two inlined vectors.
 template <typename T, size_t N, typename A>
-auto operator==(const InlinedVector<T, N, A>& a,
-                const InlinedVector<T, N, A>& b) -> bool {
-  return absl::equal(a.begin(), a.end(), b.begin(), b.end());
+bool operator==(const absl::InlinedVector<T, N, A>& a,
+                const absl::InlinedVector<T, N, A>& b) {
+  auto a_data = a.data();
+  auto a_size = a.size();
+  auto b_data = b.data();
+  auto b_size = b.size();
+  return absl::equal(a_data, a_data + a_size, b_data, b_data + b_size);
 }
 
 // `operator!=()`
 //
 // Tests the inequality of the contents of two inlined vectors.
 template <typename T, size_t N, typename A>
-auto operator!=(const InlinedVector<T, N, A>& a,
-                const InlinedVector<T, N, A>& b) -> bool {
+bool operator!=(const absl::InlinedVector<T, N, A>& a,
+                const absl::InlinedVector<T, N, A>& b) {
   return !(a == b);
 }
 
@@ -1259,9 +1263,14 @@ auto operator!=(const InlinedVector<T, N, A>& a,
 // Tests whether the contents of one inlined vector are less than the contents
 // of another through a lexicographical comparison operation.
 template <typename T, size_t N, typename A>
-auto operator<(const InlinedVector<T, N, A>& a, const InlinedVector<T, N, A>& b)
-    -> bool {
-  return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
+bool operator<(const absl::InlinedVector<T, N, A>& a,
+               const absl::InlinedVector<T, N, A>& b) {
+  auto a_data = a.data();
+  auto a_size = a.size();
+  auto b_data = b.data();
+  auto b_size = b.size();
+  return std::lexicographical_compare(a_data, a_data + a_size, b_data,
+                                      b_data + b_size);
 }
 
 // `operator>()`
@@ -1269,8 +1278,8 @@ auto operator<(const InlinedVector<T, N, A>& a, const InlinedVector<T, N, A>& b)
 // Tests whether the contents of one inlined vector are greater than the
 // contents of another through a lexicographical comparison operation.
 template <typename T, size_t N, typename A>
-auto operator>(const InlinedVector<T, N, A>& a, const InlinedVector<T, N, A>& b)
-    -> bool {
+bool operator>(const absl::InlinedVector<T, N, A>& a,
+               const absl::InlinedVector<T, N, A>& b) {
   return b < a;
 }
 
@@ -1279,8 +1288,8 @@ auto operator>(const InlinedVector<T, N, A>& a, const InlinedVector<T, N, A>& b)
 // Tests whether the contents of one inlined vector are less than or equal to
 // the contents of another through a lexicographical comparison operation.
 template <typename T, size_t N, typename A>
-auto operator<=(const InlinedVector<T, N, A>& a,
-                const InlinedVector<T, N, A>& b) -> bool {
+bool operator<=(const absl::InlinedVector<T, N, A>& a,
+                const absl::InlinedVector<T, N, A>& b) {
   return !(b < a);
 }
 
@@ -1289,8 +1298,8 @@ auto operator<=(const InlinedVector<T, N, A>& a,
 // Tests whether the contents of one inlined vector are greater than or equal to
 // the contents of another through a lexicographical comparison operation.
 template <typename T, size_t N, typename A>
-auto operator>=(const InlinedVector<T, N, A>& a,
-                const InlinedVector<T, N, A>& b) -> bool {
+bool operator>=(const absl::InlinedVector<T, N, A>& a,
+                const absl::InlinedVector<T, N, A>& b) {
   return !(a < b);
 }
 
@@ -1299,11 +1308,13 @@ auto operator>=(const InlinedVector<T, N, A>& a,
 // Provides `absl::Hash` support for inlined vectors. You do not normally call
 // this function directly.
 template <typename H, typename TheT, size_t TheN, typename TheA>
-auto AbslHashValue(H h, const InlinedVector<TheT, TheN, TheA>& v) -> H {
-  auto p = v.data();
-  auto n = v.size();
-  return H::combine(H::combine_contiguous(std::move(h), p, n), n);
+H AbslHashValue(H h, const absl::InlinedVector<TheT, TheN, TheA>& a) {
+  auto a_data = a.data();
+  auto a_size = a.size();
+  return H::combine(H::combine_contiguous(std::move(h), a_data, a_size),
+                    a_size);
 }
+
 }  // namespace absl
 
 #endif  // ABSL_CONTAINER_INLINED_VECTOR_H_
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index 4d94f7853219..7d96ed90be9c 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -414,10 +414,10 @@ TEST(Table, Prefetch) {
   t.prefetch(2);
 
   // Do not run in debug mode, when prefetch is not implemented, or when
-  // sanitizers are enabled.
+  // sanitizers are enabled, or on WebAssembly.
 #if defined(NDEBUG) && defined(__GNUC__) && !defined(ADDRESS_SANITIZER) && \
     !defined(MEMORY_SANITIZER) && !defined(THREAD_SANITIZER) &&            \
-    !defined(UNDEFINED_BEHAVIOR_SANITIZER)
+    !defined(UNDEFINED_BEHAVIOR_SANITIZER) && !defined(__EMSCRIPTEN__)
   const auto now = [] { return absl::base_internal::CycleClock::Now(); };
 
   // Make size enough to not fit in L2 cache (16.7 Mb)
diff --git a/absl/copts/AbseilConfigureCopts.cmake b/absl/copts/AbseilConfigureCopts.cmake
index b2b3f88d5055..ae29d9e9a045 100644
--- a/absl/copts/AbseilConfigureCopts.cmake
+++ b/absl/copts/AbseilConfigureCopts.cmake
@@ -5,13 +5,13 @@ set(ABSL_LSAN_LINKOPTS "")
 set(ABSL_HAVE_LSAN OFF)
 set(ABSL_DEFAULT_LINKOPTS "")
 
-if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
   set(ABSL_DEFAULT_COPTS "${ABSL_GCC_FLAGS}")
   set(ABSL_TEST_COPTS "${ABSL_GCC_FLAGS};${ABSL_GCC_TEST_FLAGS}")
   set(ABSL_EXCEPTIONS_FLAG "${ABSL_GCC_EXCEPTIONS_FLAGS}")
 elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
   # MATCHES so we get both Clang and AppleClang
-  if (MSVC)
+  if(MSVC)
     # clang-cl is half MSVC, half LLVM
     set(ABSL_DEFAULT_COPTS "${ABSL_CLANG_CL_FLAGS}")
     set(ABSL_TEST_COPTS "${ABSL_CLANG_CL_FLAGS};${ABSL_CLANG_CL_TEST_FLAGS}")
@@ -21,7 +21,7 @@ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
     set(ABSL_TEST_COPTS "${ABSL_LLVM_FLAGS};${ABSL_LLVM_TEST_FLAGS}")
     set(ABSL_EXCEPTIONS_FLAG "${ABSL_LLVM_EXCEPTIONS_FLAGS}")
     set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}")
-    if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
       # AppleClang doesn't have lsan
       # https://developer.apple.com/documentation/code_diagnostics
       if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 3.5)
diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt
index 68473b735d34..9156f5ad1cd1 100644
--- a/absl/synchronization/CMakeLists.txt
+++ b/absl/synchronization/CMakeLists.txt
@@ -64,6 +64,7 @@ absl_cc_library(
     absl::stacktrace
     absl::symbolize
     absl::time
+    Threads::Threads
   PUBLIC
 )
 
@@ -191,5 +192,4 @@ absl_cc_test(
     absl::synchronization
     absl::base
     absl::core_headers
-    Threads::Threads
 )
diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel
index a62522e469dd..feac34b1c9f9 100644
--- a/absl/types/BUILD.bazel
+++ b/absl/types/BUILD.bazel
@@ -117,7 +117,12 @@ cc_test(
 
 cc_library(
     name = "span",
-    hdrs = ["span.h"],
+    srcs = [
+        "internal/span.h",
+    ],
+    hdrs = [
+        "span.h",
+    ],
     copts = ABSL_DEFAULT_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
diff --git a/absl/types/CMakeLists.txt b/absl/types/CMakeLists.txt
index 910c099a94ab..56f9fffd6f92 100644
--- a/absl/types/CMakeLists.txt
+++ b/absl/types/CMakeLists.txt
@@ -114,6 +114,8 @@ absl_cc_library(
     span
   HDRS
     "span.h"
+  SRCS
+    "internal/span.h"
   COPTS
     ${ABSL_DEFAULT_COPTS}
   DEPS
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_
diff --git a/absl/types/span.h b/absl/types/span.h
index e5c4fe1e4dc2..b007fc1fd3df 100644
--- a/absl/types/span.h
+++ b/absl/types/span.h
@@ -60,114 +60,18 @@
 #include <cstddef>
 #include <initializer_list>
 #include <iterator>
-#include <string>
 #include <type_traits>
 #include <utility>
 
-#include "absl/algorithm/algorithm.h"
 #include "absl/base/internal/throw_delegate.h"
 #include "absl/base/macros.h"
 #include "absl/base/optimization.h"
-#include "absl/base/port.h"
+#include "absl/base/port.h"    // TODO(strel): remove this include
 #include "absl/meta/type_traits.h"
+#include "absl/types/internal/span.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
-
 //------------------------------------------------------------------------------
 // Span
 //------------------------------------------------------------------------------