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
			
			
This commit is contained in:
		
							parent
							
								
									5b65c4af51
								
							
						
					
					
						commit
						2c8421e1c6
					
				
					 14 changed files with 235 additions and 149 deletions
				
			
		|  | @ -59,7 +59,7 @@ set(ABSL_IDE_FOLDER Abseil) | ||||||
| #   SRCS | #   SRCS | ||||||
| #     "b.cc" | #     "b.cc" | ||||||
| #   DEPS | #   DEPS | ||||||
| #     absl_internal_awesome # not "awesome"! | #     absl::awesome # not "awesome" ! | ||||||
| #   PUBLIC | #   PUBLIC | ||||||
| # ) | # ) | ||||||
| # | # | ||||||
|  | @ -68,7 +68,7 @@ set(ABSL_IDE_FOLDER Abseil) | ||||||
| #     main_lib | #     main_lib | ||||||
| #   ... | #   ... | ||||||
| #   DEPS | #   DEPS | ||||||
| #     absl::fantastic_lib # since fantastic_lib is public | #     absl::fantastic_lib | ||||||
| # ) | # ) | ||||||
| # | # | ||||||
| # TODO: Implement "ALWAYSLINK" | # TODO: Implement "ALWAYSLINK" | ||||||
|  | @ -81,7 +81,11 @@ function(absl_cc_library) | ||||||
|   ) |   ) | ||||||
| 
 | 
 | ||||||
|   if(NOT ABSL_CC_LIB_TESTONLY OR ABSL_RUN_TESTS) |   if(NOT ABSL_CC_LIB_TESTONLY OR ABSL_RUN_TESTS) | ||||||
|  |     if(ABSL_ENABLE_INSTALL) | ||||||
|       set(_NAME "${ABSL_CC_LIB_NAME}") |       set(_NAME "${ABSL_CC_LIB_NAME}") | ||||||
|  |     else() | ||||||
|  |       set(_NAME "absl_${ABSL_CC_LIB_NAME}") | ||||||
|  |     endif() | ||||||
| 
 | 
 | ||||||
|     # Check if this is a header-only library |     # Check if this is a header-only library | ||||||
|     # Note that as of February 2019, many popular OS's (for example, Ubuntu |     # Note that as of February 2019, many popular OS's (for example, Ubuntu | ||||||
|  | @ -155,7 +159,7 @@ function(absl_cc_library) | ||||||
| 
 | 
 | ||||||
|     # TODO currently we don't install googletest alongside abseil sources, so |     # TODO currently we don't install googletest alongside abseil sources, so | ||||||
|     # installed abseil can't be tested. |     # 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 |       install(TARGETS ${_NAME} EXPORT ${PROJECT_NAME}Targets | ||||||
|             RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR} |             RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR} | ||||||
|             LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR} |             LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR} | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| ## absl CMake configuration file.  Note that there is no corresponding | # absl CMake configuration file. | ||||||
| # abslConfigVersion.cmake since non-LTS Abseil isn't versioned. | 
 | ||||||
|  | include(FindThreads) | ||||||
| 
 | 
 | ||||||
| @PACKAGE_INIT@ | @PACKAGE_INIT@ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -86,18 +86,6 @@ if(${ABSL_RUN_TESTS}) | ||||||
|   enable_testing() |   enable_testing() | ||||||
| endif() | 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 | ## check targets | ||||||
| if(BUILD_TESTING) | if(BUILD_TESTING) | ||||||
| 
 | 
 | ||||||
|  | @ -122,6 +110,18 @@ endif() | ||||||
| add_subdirectory(absl) | 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 as a subdirectory only | ||||||
|   install(EXPORT ${PROJECT_NAME}Targets |   install(EXPORT ${PROJECT_NAME}Targets | ||||||
|     NAMESPACE absl:: |     NAMESPACE absl:: | ||||||
|  |  | ||||||
|  | @ -88,6 +88,7 @@ absl_cc_library( | ||||||
|     absl::core_headers |     absl::core_headers | ||||||
|     absl::dynamic_annotations |     absl::dynamic_annotations | ||||||
|     absl::spinlock_wait |     absl::spinlock_wait | ||||||
|  |     Threads::Threads | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| absl_cc_library( | absl_cc_library( | ||||||
|  | @ -134,6 +135,7 @@ absl_cc_library( | ||||||
|     absl::core_headers |     absl::core_headers | ||||||
|     absl::dynamic_annotations |     absl::dynamic_annotations | ||||||
|     absl::spinlock_wait |     absl::spinlock_wait | ||||||
|  |     Threads::Threads | ||||||
|   PUBLIC |   PUBLIC | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -438,3 +440,12 @@ absl_cc_test( | ||||||
|     absl::scoped_set_env |     absl::scoped_set_env | ||||||
|     gtest_main |     gtest_main | ||||||
| ) | ) | ||||||
|  | 
 | ||||||
|  | absl_cc_test( | ||||||
|  |   NAME | ||||||
|  |     cmake_thread_test | ||||||
|  |   SRCS | ||||||
|  |     "internal/cmake_thread_test.cc" | ||||||
|  |   DEPS | ||||||
|  |     absl::base | ||||||
|  | ) | ||||||
|  |  | ||||||
							
								
								
									
										22
									
								
								absl/base/internal/cmake_thread_test.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								absl/base/internal/cmake_thread_test.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -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; | ||||||
|  | } | ||||||
|  | @ -847,7 +847,7 @@ class InlinedVector { | ||||||
| 
 | 
 | ||||||
|  private: |  private: | ||||||
|   template <typename H, typename TheT, size_t TheN, typename TheA> |   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(); } |   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
 | // Swaps the contents of two inlined vectors. This convenience function
 | ||||||
| // simply calls `InlinedVector::swap()`.
 | // simply calls `InlinedVector::swap()`.
 | ||||||
| template <typename T, size_t N, typename A> | template <typename T, size_t N, typename A> | ||||||
| auto swap(InlinedVector<T, N, A>& a, | void swap(absl::InlinedVector<T, N, A>& a, | ||||||
|           InlinedVector<T, N, A>& b) noexcept(noexcept(a.swap(b))) -> void { |           absl::InlinedVector<T, N, A>& b) noexcept(noexcept(a.swap(b))) { | ||||||
|   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.
 | // Tests the equivalency of the contents of two inlined vectors.
 | ||||||
| template <typename T, size_t N, typename A> | template <typename T, size_t N, typename A> | ||||||
| auto operator==(const InlinedVector<T, N, A>& a, | bool operator==(const absl::InlinedVector<T, N, A>& a, | ||||||
|                 const InlinedVector<T, N, A>& b) -> bool { |                 const absl::InlinedVector<T, N, A>& b) { | ||||||
|   return absl::equal(a.begin(), a.end(), b.begin(), b.end()); |   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!=()`
 | // `operator!=()`
 | ||||||
| //
 | //
 | ||||||
| // Tests the inequality of the contents of two inlined vectors.
 | // Tests the inequality of the contents of two inlined vectors.
 | ||||||
| template <typename T, size_t N, typename A> | template <typename T, size_t N, typename A> | ||||||
| auto operator!=(const InlinedVector<T, N, A>& a, | bool operator!=(const absl::InlinedVector<T, N, A>& a, | ||||||
|                 const InlinedVector<T, N, A>& b) -> bool { |                 const absl::InlinedVector<T, N, A>& b) { | ||||||
|   return !(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
 | // Tests whether the contents of one inlined vector are less than the contents
 | ||||||
| // of another through a lexicographical comparison operation.
 | // of another through a lexicographical comparison operation.
 | ||||||
| template <typename T, size_t N, typename A> | template <typename T, size_t N, typename A> | ||||||
| auto operator<(const InlinedVector<T, N, A>& a, const InlinedVector<T, N, A>& b) | bool operator<(const absl::InlinedVector<T, N, A>& a, | ||||||
|     -> bool { |                const absl::InlinedVector<T, N, A>& b) { | ||||||
|   return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); |   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>()`
 | // `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
 | // Tests whether the contents of one inlined vector are greater than the
 | ||||||
| // contents of another through a lexicographical comparison operation.
 | // contents of another through a lexicographical comparison operation.
 | ||||||
| template <typename T, size_t N, typename A> | template <typename T, size_t N, typename A> | ||||||
| auto operator>(const InlinedVector<T, N, A>& a, const InlinedVector<T, N, A>& b) | bool operator>(const absl::InlinedVector<T, N, A>& a, | ||||||
|     -> bool { |                const absl::InlinedVector<T, N, A>& b) { | ||||||
|   return b < a; |   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
 | // Tests whether the contents of one inlined vector are less than or equal to
 | ||||||
| // the contents of another through a lexicographical comparison operation.
 | // the contents of another through a lexicographical comparison operation.
 | ||||||
| template <typename T, size_t N, typename A> | template <typename T, size_t N, typename A> | ||||||
| auto operator<=(const InlinedVector<T, N, A>& a, | bool operator<=(const absl::InlinedVector<T, N, A>& a, | ||||||
|                 const InlinedVector<T, N, A>& b) -> bool { |                 const absl::InlinedVector<T, N, A>& b) { | ||||||
|   return !(b < a); |   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
 | // Tests whether the contents of one inlined vector are greater than or equal to
 | ||||||
| // the contents of another through a lexicographical comparison operation.
 | // the contents of another through a lexicographical comparison operation.
 | ||||||
| template <typename T, size_t N, typename A> | template <typename T, size_t N, typename A> | ||||||
| auto operator>=(const InlinedVector<T, N, A>& a, | bool operator>=(const absl::InlinedVector<T, N, A>& a, | ||||||
|                 const InlinedVector<T, N, A>& b) -> bool { |                 const absl::InlinedVector<T, N, A>& b) { | ||||||
|   return !(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
 | // Provides `absl::Hash` support for inlined vectors. You do not normally call
 | ||||||
| // this function directly.
 | // this function directly.
 | ||||||
| template <typename H, typename TheT, size_t TheN, typename TheA> | template <typename H, typename TheT, size_t TheN, typename TheA> | ||||||
| auto AbslHashValue(H h, const InlinedVector<TheT, TheN, TheA>& v) -> H { | H AbslHashValue(H h, const absl::InlinedVector<TheT, TheN, TheA>& a) { | ||||||
|   auto p = v.data(); |   auto a_data = a.data(); | ||||||
|   auto n = v.size(); |   auto a_size = a.size(); | ||||||
|   return H::combine(H::combine_contiguous(std::move(h), p, n), n); |   return H::combine(H::combine_contiguous(std::move(h), a_data, a_size), | ||||||
|  |                     a_size); | ||||||
| } | } | ||||||
|  | 
 | ||||||
| }  // namespace absl
 | }  // namespace absl
 | ||||||
| 
 | 
 | ||||||
| #endif  // ABSL_CONTAINER_INLINED_VECTOR_H_
 | #endif  // ABSL_CONTAINER_INLINED_VECTOR_H_
 | ||||||
|  |  | ||||||
|  | @ -414,10 +414,10 @@ TEST(Table, Prefetch) { | ||||||
|   t.prefetch(2); |   t.prefetch(2); | ||||||
| 
 | 
 | ||||||
|   // Do not run in debug mode, when prefetch is not implemented, or when
 |   // 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) && \ | #if defined(NDEBUG) && defined(__GNUC__) && !defined(ADDRESS_SANITIZER) && \ | ||||||
|     !defined(MEMORY_SANITIZER) && !defined(THREAD_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(); }; |   const auto now = [] { return absl::base_internal::CycleClock::Now(); }; | ||||||
| 
 | 
 | ||||||
|   // Make size enough to not fit in L2 cache (16.7 Mb)
 |   // Make size enough to not fit in L2 cache (16.7 Mb)
 | ||||||
|  |  | ||||||
|  | @ -64,6 +64,7 @@ absl_cc_library( | ||||||
|     absl::stacktrace |     absl::stacktrace | ||||||
|     absl::symbolize |     absl::symbolize | ||||||
|     absl::time |     absl::time | ||||||
|  |     Threads::Threads | ||||||
|   PUBLIC |   PUBLIC | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -191,5 +192,4 @@ absl_cc_test( | ||||||
|     absl::synchronization |     absl::synchronization | ||||||
|     absl::base |     absl::base | ||||||
|     absl::core_headers |     absl::core_headers | ||||||
|     Threads::Threads |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | @ -117,7 +117,12 @@ cc_test( | ||||||
| 
 | 
 | ||||||
| cc_library( | cc_library( | ||||||
|     name = "span", |     name = "span", | ||||||
|     hdrs = ["span.h"], |     srcs = [ | ||||||
|  |         "internal/span.h", | ||||||
|  |     ], | ||||||
|  |     hdrs = [ | ||||||
|  |         "span.h", | ||||||
|  |     ], | ||||||
|     copts = ABSL_DEFAULT_COPTS, |     copts = ABSL_DEFAULT_COPTS, | ||||||
|     linkopts = ABSL_DEFAULT_LINKOPTS, |     linkopts = ABSL_DEFAULT_LINKOPTS, | ||||||
|     deps = [ |     deps = [ | ||||||
|  |  | ||||||
|  | @ -114,6 +114,8 @@ absl_cc_library( | ||||||
|     span |     span | ||||||
|   HDRS |   HDRS | ||||||
|     "span.h" |     "span.h" | ||||||
|  |   SRCS | ||||||
|  |     "internal/span.h" | ||||||
|   COPTS |   COPTS | ||||||
|     ${ABSL_DEFAULT_COPTS} |     ${ABSL_DEFAULT_COPTS} | ||||||
|   DEPS |   DEPS | ||||||
|  |  | ||||||
							
								
								
									
										126
									
								
								absl/types/internal/span.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								absl/types/internal/span.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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_
 | ||||||
|  | @ -60,114 +60,18 @@ | ||||||
| #include <cstddef> | #include <cstddef> | ||||||
| #include <initializer_list> | #include <initializer_list> | ||||||
| #include <iterator> | #include <iterator> | ||||||
| #include <string> |  | ||||||
| #include <type_traits> | #include <type_traits> | ||||||
| #include <utility> | #include <utility> | ||||||
| 
 | 
 | ||||||
| #include "absl/algorithm/algorithm.h" |  | ||||||
| #include "absl/base/internal/throw_delegate.h" | #include "absl/base/internal/throw_delegate.h" | ||||||
| #include "absl/base/macros.h" | #include "absl/base/macros.h" | ||||||
| #include "absl/base/optimization.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/meta/type_traits.h" | ||||||
|  | #include "absl/types/internal/span.h" | ||||||
| 
 | 
 | ||||||
| namespace absl { | 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
 | // Span
 | ||||||
| //------------------------------------------------------------------------------
 | //------------------------------------------------------------------------------
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue