Export of internal Abseil changes
-- 20405fc394419d434d3ea09b2e62e4edcb282421 by Christian Blichmann <cblichmann@google.com>: Include `status` subdirectory in main `CMakeLists.txt` PiperOrigin-RevId: 297125966 -- 101087af9689612bdda679ee0869e5cde4472244 by Matt Kulukundis <kfm@google.com>: Fix typo PiperOrigin-RevId: 296991360 -- 55ff5bc6970d46214c0459d3a7a23973c7dc69b9 by Andy Getzendanner <durandal@google.com>: Extract logging's ErrnoSaver to absl::base_internal and use it in a couple other places. PiperOrigin-RevId: 296969168 -- b7cd7550297d53766576f751436617200c65831b by Abseil Team <absl-team@google.com>: Internal change PiperOrigin-RevId: 296951474 -- 8c04c73fc53f9a09c3e2400812b931157f35fe07 by Andy Soffer <asoffer@google.com>: Auto-generate list of files in the DLL, and add new build targets to the DLL. PiperOrigin-RevId: 296932061 -- 2f77829e196094f1addefd8ac2ac9e398c5b6100 by Andy Soffer <asoffer@google.com>: Fix bug introduced by DLL where we couldn't build shared libraries on non-windows platforms. Fixes #623 PiperOrigin-RevId: 296919347 -- b768163dbbff0c561b9dff0218a699e5e4fd33f3 by Abseil Team <absl-team@google.com>: typo: microprosessor PiperOrigin-RevId: 296904933 -- b185da0dac44c91855373f0723df9242cbfb3db3 by Matthew Brown <matthewbr@google.com>: Internal cleanup PiperOrigin-RevId: 296509711 GitOrigin-RevId: 20405fc394419d434d3ea09b2e62e4edcb282421 Change-Id: I55c8eba6f353ceb337455ae144ab743ea21edbef
This commit is contained in:
		
							parent
							
								
									b69c7d880c
								
							
						
					
					
						commit
						0d5ce2797e
					
				
					 20 changed files with 248 additions and 128 deletions
				
			
		|  | @ -16,6 +16,7 @@ set(ABSL_INTERNAL_DLL_FILES | |||
|   "base/internal/cycleclock.h" | ||||
|   "base/internal/direct_mmap.h" | ||||
|   "base/internal/endian.h" | ||||
|   "base/internal/errno_saver.h" | ||||
|   "base/internal/exponential_biased.cc" | ||||
|   "base/internal/exponential_biased.h" | ||||
|   "base/internal/hide_ptr.h" | ||||
|  | @ -108,6 +109,8 @@ set(ABSL_INTERNAL_DLL_FILES | |||
|   "debugging/internal/symbolize.h" | ||||
|   "debugging/internal/vdso_support.cc" | ||||
|   "debugging/internal/vdso_support.h" | ||||
|   "functional/internal/front_binder.h" | ||||
|   "functional/bind_front.h" | ||||
|   "functional/function_ref.h" | ||||
|   "functional/internal/function_ref.h" | ||||
|   "hash/hash.h" | ||||
|  | @ -169,18 +172,23 @@ set(ABSL_INTERNAL_DLL_FILES | |||
|   "random/uniform_int_distribution.h" | ||||
|   "random/uniform_real_distribution.h" | ||||
|   "random/zipf_distribution.h" | ||||
|   "status/status.h" | ||||
|   "status/status.cc" | ||||
|   "status/status_payload_printer.h" | ||||
|   "status/status_payload_printer.cc" | ||||
|   "strings/ascii.cc" | ||||
|   "strings/ascii.h" | ||||
|   "strings/charconv.cc" | ||||
|   "strings/charconv.h" | ||||
|   "strings/cord.cc" | ||||
|   "strings/cord.h" | ||||
|   "strings/escaping.cc" | ||||
|   "strings/escaping.h" | ||||
|   "strings/internal/cord_internal.h" | ||||
|   "strings/internal/charconv_bigint.cc" | ||||
|   "strings/internal/charconv_bigint.h" | ||||
|   "strings/internal/charconv_parse.cc" | ||||
|   "strings/internal/charconv_parse.h" | ||||
|   "strings/internal/escaping.cc" | ||||
|   "strings/internal/escaping.h" | ||||
|   "strings/internal/stl_type_traits.h" | ||||
|   "strings/match.cc" | ||||
|   "strings/match.h" | ||||
|  | @ -200,6 +208,8 @@ set(ABSL_INTERNAL_DLL_FILES | |||
|   "strings/substitute.cc" | ||||
|   "strings/substitute.h" | ||||
|   "strings/internal/char_map.h" | ||||
|   "strings/internal/escaping.h" | ||||
|   "strings/internal/escaping.cc" | ||||
|   "strings/internal/memutil.cc" | ||||
|   "strings/internal/memutil.h" | ||||
|   "strings/internal/ostringstream.cc" | ||||
|  | @ -308,6 +318,7 @@ set(ABSL_INTERNAL_DLL_TARGETS | |||
|   "memory" | ||||
|   "strings" | ||||
|   "strings_internal" | ||||
|   "cord" | ||||
|   "str_format" | ||||
|   "str_format_internal" | ||||
|   "pow10_helper" | ||||
|  | @ -377,6 +388,7 @@ set(ABSL_INTERNAL_DLL_TARGETS | |||
|   "random_internal_randen_hwaes" | ||||
|   "random_internal_randen_hwaes_impl" | ||||
|   "random_internal_uniform_helper" | ||||
|   "status" | ||||
|   "time" | ||||
|   "civil_time" | ||||
|   "time_zone" | ||||
|  |  | |||
|  | @ -108,14 +108,16 @@ function(absl_cc_library) | |||
|     set(ABSL_CC_LIB_IS_INTERFACE 0) | ||||
|   endif() | ||||
| 
 | ||||
|   # Determine this build target's relationship to the DLL. It's one of three things: | ||||
|   # Determine this build target's relationship to the DLL. It's one of four things: | ||||
|   # 1. "dll"     -- This target is part of the DLL | ||||
|   # 2. "dll_dep" -- This target is not part of the DLL, but depends on the DLL. | ||||
|   #                 Note that we assume any target not in the DLL depends on the | ||||
|   #                 DLL. This is not a technical necessity but a convenience | ||||
|   #                 which happens to be true, because nearly every target is | ||||
|   #                 part of the DLL. | ||||
|   # 3. "static"  -- This target does not depend on the DLL and should be built | ||||
|   # 3. "shared"  -- This is a shared library, perhaps on a non-windows platform | ||||
|   #                 where DLL doesn't make sense. | ||||
|   # 4. "static"  -- This target does not depend on the DLL and should be built | ||||
|   #                 statically. | ||||
|   if (${ABSL_BUILD_DLL}) | ||||
|     absl_internal_dll_contains(TARGET ${_NAME} OUTPUT _in_dll) | ||||
|  | @ -127,6 +129,8 @@ function(absl_cc_library) | |||
|       # Building a DLL, but this target is not part of the DLL | ||||
|       set(_build_type "dll_dep") | ||||
|     endif() | ||||
|   elseif(BUILD_SHARED_LIBS) | ||||
|     set(_build_type "shared") | ||||
|   else() | ||||
|     set(_build_type "static") | ||||
|   endif() | ||||
|  | @ -161,8 +165,8 @@ function(absl_cc_library) | |||
|           "${_gtest_link_define}" | ||||
|       ) | ||||
| 
 | ||||
|     elseif(${_build_type} STREQUAL "static") | ||||
|       add_library(${_NAME} STATIC "") | ||||
|     elseif(${_build_type} STREQUAL "static" OR ${_build_type} STREQUAL "shared") | ||||
|       add_library(${_NAME} "") | ||||
|       target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS}) | ||||
|       target_link_libraries(${_NAME} | ||||
|       PUBLIC ${ABSL_CC_LIB_DEPS} | ||||
|  |  | |||
|  | @ -25,6 +25,7 @@ add_subdirectory(memory) | |||
| add_subdirectory(meta) | ||||
| add_subdirectory(numeric) | ||||
| add_subdirectory(random) | ||||
| add_subdirectory(status) | ||||
| add_subdirectory(strings) | ||||
| add_subdirectory(synchronization) | ||||
| add_subdirectory(time) | ||||
|  |  | |||
|  | @ -40,6 +40,17 @@ cc_library( | |||
|     ], | ||||
| ) | ||||
| 
 | ||||
| cc_library( | ||||
|     name = "errno_saver", | ||||
|     hdrs = ["internal/errno_saver.h"], | ||||
|     copts = ABSL_DEFAULT_COPTS, | ||||
|     linkopts = ABSL_DEFAULT_LINKOPTS, | ||||
|     visibility = [ | ||||
|         "//absl:__subpackages__", | ||||
|     ], | ||||
|     deps = [":config"], | ||||
| ) | ||||
| 
 | ||||
| cc_library( | ||||
|     name = "log_severity", | ||||
|     srcs = ["log_severity.cc"], | ||||
|  | @ -87,6 +98,7 @@ cc_library( | |||
|     deps = [ | ||||
|         ":base_internal", | ||||
|         ":core_headers", | ||||
|         ":errno_saver", | ||||
|     ], | ||||
| ) | ||||
| 
 | ||||
|  | @ -287,6 +299,18 @@ cc_test( | |||
|     ], | ||||
| ) | ||||
| 
 | ||||
| cc_test( | ||||
|     name = "errno_saver_test", | ||||
|     size = "small", | ||||
|     srcs = ["internal/errno_saver_test.cc"], | ||||
|     copts = ABSL_TEST_COPTS, | ||||
|     linkopts = ABSL_DEFAULT_LINKOPTS, | ||||
|     deps = [ | ||||
|         ":errno_saver", | ||||
|         "@com_google_googletest//:gtest_main", | ||||
|     ], | ||||
| ) | ||||
| 
 | ||||
| cc_library( | ||||
|     name = "exception_testing", | ||||
|     testonly = 1, | ||||
|  |  | |||
|  | @ -28,6 +28,17 @@ absl_cc_library( | |||
|     ${ABSL_DEFAULT_COPTS} | ||||
| ) | ||||
| 
 | ||||
| absl_cc_library( | ||||
|   NAME | ||||
|     errno_saver | ||||
|   HDRS | ||||
|     "internal/errno_saver.h" | ||||
|   DEPS | ||||
|     absl::config | ||||
|   COPTS | ||||
|     ${ABSL_DEFAULT_COPTS} | ||||
| ) | ||||
| 
 | ||||
| absl_cc_library( | ||||
|   NAME | ||||
|     log_severity | ||||
|  | @ -73,6 +84,7 @@ absl_cc_library( | |||
|   DEPS | ||||
|     absl::base_internal | ||||
|     absl::core_headers | ||||
|     absl::errno_saver | ||||
| ) | ||||
| 
 | ||||
| absl_cc_library( | ||||
|  | @ -305,6 +317,19 @@ absl_cc_test( | |||
|     gtest_main | ||||
| ) | ||||
| 
 | ||||
| absl_cc_test( | ||||
|   NAME | ||||
|     errno_saver_test | ||||
|   SRCS | ||||
|     "internal/errno_saver_test.cc" | ||||
|   COPTS | ||||
|     ${ABSL_TEST_COPTS} | ||||
|   DEPS | ||||
|     absl::errno_saver | ||||
|     gmock | ||||
|     gtest_main | ||||
| ) | ||||
| 
 | ||||
| absl_cc_test( | ||||
|   NAME | ||||
|     throw_delegate_test | ||||
|  |  | |||
|  | @ -575,7 +575,7 @@ | |||
| // When applying ABSL_ATTRIBUTE_PACKED only to specific structure members the
 | ||||
| // natural alignment of structure members not annotated is preserved. Aligned
 | ||||
| // member accesses are faster than non-aligned member accesses even if the
 | ||||
| // targeted microprosessor supports non-aligned accesses.
 | ||||
| // targeted microprocessor supports non-aligned accesses.
 | ||||
| #if ABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__)) | ||||
| #define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__)) | ||||
| #else | ||||
|  |  | |||
							
								
								
									
										43
									
								
								absl/base/internal/errno_saver.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								absl/base/internal/errno_saver.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | |||
| // 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.
 | ||||
| 
 | ||||
| #ifndef ABSL_BASE_INTERNAL_ERRNO_SAVER_H_ | ||||
| #define ABSL_BASE_INTERNAL_ERRNO_SAVER_H_ | ||||
| 
 | ||||
| #include <cerrno> | ||||
| 
 | ||||
| #include "absl/base/config.h" | ||||
| 
 | ||||
| namespace absl { | ||||
| ABSL_NAMESPACE_BEGIN | ||||
| namespace base_internal { | ||||
| 
 | ||||
| // `ErrnoSaver` captures the value of `errno` upon construction and restores it
 | ||||
| // upon deletion.  It is used in low-level code and must be super fast.  Do not
 | ||||
| // add instrumentation, even in debug modes.
 | ||||
| class ErrnoSaver { | ||||
|  public: | ||||
|   ErrnoSaver() : saved_errno_(errno) {} | ||||
|   ~ErrnoSaver() { errno = saved_errno_; } | ||||
|   int operator()() const { return saved_errno_; } | ||||
| 
 | ||||
|  private: | ||||
|   const int saved_errno_; | ||||
| }; | ||||
| 
 | ||||
| }  // namespace base_internal
 | ||||
| ABSL_NAMESPACE_END | ||||
| }  // namespace absl
 | ||||
| 
 | ||||
| #endif  // ABSL_BASE_INTERNAL_ERRNO_SAVER_H_
 | ||||
							
								
								
									
										44
									
								
								absl/base/internal/errno_saver_test.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								absl/base/internal/errno_saver_test.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| // 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 "absl/base/internal/errno_saver.h" | ||||
| 
 | ||||
| #include <cerrno> | ||||
| 
 | ||||
| #include "gmock/gmock.h" | ||||
| #include "gtest/gtest.h" | ||||
| 
 | ||||
| namespace { | ||||
| using ::testing::Eq; | ||||
| 
 | ||||
| struct ErrnoPrinter { | ||||
|   int no; | ||||
| }; | ||||
| std::ostream &operator<<(std::ostream &os, ErrnoPrinter ep) { | ||||
|   return os << strerror(ep.no) << " [" << ep.no << "]"; | ||||
| } | ||||
| bool operator==(ErrnoPrinter one, ErrnoPrinter two) { return one.no == two.no; } | ||||
| 
 | ||||
| TEST(ErrnoSaverTest, Works) { | ||||
|   errno = EDOM; | ||||
|   { | ||||
|     absl::base_internal::ErrnoSaver errno_saver; | ||||
|     EXPECT_THAT(ErrnoPrinter{errno}, Eq(ErrnoPrinter{EDOM})); | ||||
|     errno = ERANGE; | ||||
|     EXPECT_THAT(ErrnoPrinter{errno}, Eq(ErrnoPrinter{ERANGE})); | ||||
|     EXPECT_THAT(ErrnoPrinter{errno_saver()}, Eq(ErrnoPrinter{EDOM})); | ||||
|   } | ||||
|   EXPECT_THAT(ErrnoPrinter{errno}, Eq(ErrnoPrinter{EDOM})); | ||||
| } | ||||
| }  // namespace
 | ||||
|  | @ -19,12 +19,12 @@ | |||
| #include <unistd.h>
 | ||||
| 
 | ||||
| #include <atomic>
 | ||||
| #include <cerrno>
 | ||||
| #include <climits>
 | ||||
| #include <cstdint>
 | ||||
| #include <ctime>
 | ||||
| 
 | ||||
| #include "absl/base/attributes.h"
 | ||||
| #include "absl/base/internal/errno_saver.h"
 | ||||
| 
 | ||||
| // The SpinLock lockword is `std::atomic<uint32_t>`. Here we assert that
 | ||||
| // `std::atomic<uint32_t>` is bitwise equivalent of the `int` expected
 | ||||
|  | @ -51,12 +51,11 @@ extern "C" { | |||
| ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( | ||||
|     std::atomic<uint32_t> *w, uint32_t value, int loop, | ||||
|     absl::base_internal::SchedulingMode) { | ||||
|   int save_errno = errno; | ||||
|   absl::base_internal::ErrnoSaver errno_saver; | ||||
|   struct timespec tm; | ||||
|   tm.tv_sec = 0; | ||||
|   tm.tv_nsec = absl::base_internal::SpinLockSuggestedDelayNS(loop); | ||||
|   syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, &tm); | ||||
|   errno = save_errno; | ||||
| } | ||||
| 
 | ||||
| ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake(std::atomic<uint32_t> *w, | ||||
|  |  | |||
|  | @ -15,10 +15,11 @@ | |||
| // This file is a Posix-specific part of spinlock_wait.cc
 | ||||
| 
 | ||||
| #include <sched.h>
 | ||||
| 
 | ||||
| #include <atomic>
 | ||||
| #include <ctime>
 | ||||
| #include <cerrno>
 | ||||
| 
 | ||||
| #include "absl/base/internal/errno_saver.h"
 | ||||
| #include "absl/base/internal/scheduling_mode.h"
 | ||||
| #include "absl/base/port.h"
 | ||||
| 
 | ||||
|  | @ -27,7 +28,7 @@ extern "C" { | |||
| ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( | ||||
|     std::atomic<uint32_t>* /* lock_word */, uint32_t /* value */, int loop, | ||||
|     absl::base_internal::SchedulingMode /* mode */) { | ||||
|   int save_errno = errno; | ||||
|   absl::base_internal::ErrnoSaver errno_saver; | ||||
|   if (loop == 0) { | ||||
|   } else if (loop == 1) { | ||||
|     sched_yield(); | ||||
|  | @ -37,7 +38,6 @@ ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( | |||
|     tm.tv_nsec = absl::base_internal::SpinLockSuggestedDelayNS(loop); | ||||
|     nanosleep(&tm, nullptr); | ||||
|   } | ||||
|   errno = save_errno; | ||||
| } | ||||
| 
 | ||||
| ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake( | ||||
|  |  | |||
|  | @ -134,6 +134,7 @@ cc_library( | |||
|         "//absl/base", | ||||
|         "//absl/base:config", | ||||
|         "//absl/base:core_headers", | ||||
|         "//absl/base:errno_saver", | ||||
|         "//absl/base:raw_logging_internal", | ||||
|     ], | ||||
| ) | ||||
|  | @ -174,6 +175,7 @@ cc_library( | |||
|         "//absl/base:config", | ||||
|         "//absl/base:core_headers", | ||||
|         "//absl/base:dynamic_annotations", | ||||
|         "//absl/base:errno_saver", | ||||
|         "//absl/base:raw_logging_internal", | ||||
|     ], | ||||
| ) | ||||
|  |  | |||
|  | @ -118,6 +118,7 @@ absl_cc_library( | |||
|     absl::base | ||||
|     absl::config | ||||
|     absl::core_headers | ||||
|     absl::errno_saver | ||||
|     absl::raw_logging_internal | ||||
|   PUBLIC | ||||
| ) | ||||
|  | @ -156,6 +157,7 @@ absl_cc_library( | |||
|     absl::core_headers | ||||
|     absl::config | ||||
|     absl::dynamic_annotations | ||||
|     absl::errno_saver | ||||
|     absl::raw_logging_internal | ||||
| ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -41,6 +41,7 @@ | |||
| #include <ctime> | ||||
| 
 | ||||
| #include "absl/base/attributes.h" | ||||
| #include "absl/base/internal/errno_saver.h" | ||||
| #include "absl/base/internal/raw_logging.h" | ||||
| #include "absl/base/internal/sysinfo.h" | ||||
| #include "absl/debugging/internal/examine_stack.h" | ||||
|  | @ -214,9 +215,8 @@ static void InstallOneFailureHandler(FailureSignalData* data, | |||
| #endif | ||||
| 
 | ||||
| static void WriteToStderr(const char* data) { | ||||
|   int old_errno = errno; | ||||
|   absl::base_internal::ErrnoSaver errno_saver; | ||||
|   absl::raw_logging_internal::SafeWriteToStderr(data, strlen(data)); | ||||
|   errno = old_errno; | ||||
| } | ||||
| 
 | ||||
| static void WriteSignalMessage(int signo, void (*writerfn)(const char*)) { | ||||
|  |  | |||
|  | @ -35,10 +35,12 @@ ABSL_NAMESPACE_END | |||
| #include <fcntl.h> | ||||
| #include <sys/syscall.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include <atomic> | ||||
| #include <cerrno> | ||||
| #include <cstdint> | ||||
| 
 | ||||
| #include "absl/base/internal/errno_saver.h" | ||||
| #include "absl/base/internal/raw_logging.h" | ||||
| 
 | ||||
| namespace absl { | ||||
|  | @ -67,7 +69,7 @@ static void Unpack(uint64_t x, int *pid, int *read_fd, int *write_fd) { | |||
| // This is a namespace-scoped variable for correct zero-initialization.
 | ||||
| static std::atomic<uint64_t> pid_and_fds;  // initially 0, an invalid pid.
 | ||||
| bool AddressIsReadable(const void *addr) { | ||||
|   int save_errno = errno; | ||||
|   absl::base_internal::ErrnoSaver errno_saver; | ||||
|   // We test whether a byte is readable by using write().  Normally, this would
 | ||||
|   // be done via a cached file descriptor to /dev/null, but linux fails to
 | ||||
|   // check whether the byte is readable when the destination is /dev/null, so
 | ||||
|  | @ -126,7 +128,6 @@ bool AddressIsReadable(const void *addr) { | |||
|                                           std::memory_order_relaxed); | ||||
|     } | ||||
|   } while (errno == EBADF); | ||||
|   errno = save_errno; | ||||
|   return bytes_written == 1; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -465,7 +465,7 @@ class FlagImpl { | |||
|   // Flag initialization called via absl::call_once.
 | ||||
|   void Init(); | ||||
|   // Attempts to parse supplied `value` std::string. If parsing is successful,
 | ||||
|   // returns new value. Otherwsie returns nullptr.
 | ||||
|   // returns new value. Otherwise returns nullptr.
 | ||||
|   std::unique_ptr<void, DynValueDeleter> TryParse(absl::string_view value, | ||||
|                                                   std::string* err) const | ||||
|       ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); | ||||
|  |  | |||
|  | @ -1,30 +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 <iostream> | ||||
| #include <random> | ||||
| 
 | ||||
| #include "absl/random/random.h" | ||||
| 
 | ||||
| // This program is used in integration tests.
 | ||||
| 
 | ||||
| int main() { | ||||
|   std::seed_seq seed_seq{1234}; | ||||
|   absl::BitGen rng(seed_seq); | ||||
|   constexpr size_t kSequenceLength = 8; | ||||
|   for (size_t i = 0; i < kSequenceLength; i++) { | ||||
|     std::cout << rng() << "\n"; | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
|  | @ -1,30 +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 <iostream> | ||||
| #include <random> | ||||
| 
 | ||||
| #include "absl/random/random.h" | ||||
| 
 | ||||
| // This program is used in integration tests.
 | ||||
| 
 | ||||
| int main() { | ||||
|   std::seed_seq seed_seq{}; | ||||
|   absl::BitGen rng(seed_seq); | ||||
|   constexpr size_t kSequenceLength = 8; | ||||
|   for (size_t i = 0; i < kSequenceLength; i++) { | ||||
|     std::cout << rng() << "\n"; | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
|  | @ -41,7 +41,7 @@ absl_cc_library( | |||
| absl_cc_test( | ||||
|   NAME | ||||
|     status_test | ||||
|   HDRS | ||||
|   SRCS | ||||
|    "status_test.cc" | ||||
|   COPTS | ||||
|     ${ABSL_TEST_COPTS} | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ std::string ConvToString(Conv conv) { | |||
|   std::string out; | ||||
| #define CONV_SET_CASE(c) \ | ||||
|   if (Contains(conv, Conv::c)) out += #c; | ||||
|   ABSL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, ) | ||||
|   ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, ) | ||||
| #undef CONV_SET_CASE | ||||
|   if (Contains(conv, Conv::star)) out += "*"; | ||||
|   return out; | ||||
|  |  | |||
|  | @ -137,7 +137,7 @@ struct Flags { | |||
| }; | ||||
| 
 | ||||
| // clang-format off
 | ||||
| #define ABSL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP) \ | ||||
| #define ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP) \ | ||||
|   /* text */ \ | ||||
|   X_VAL(c) X_SEP X_VAL(C) X_SEP X_VAL(s) X_SEP X_VAL(S) X_SEP \ | ||||
|   /* ints */ \ | ||||
|  | @ -161,11 +161,11 @@ enum class FormatConversionChar : uint8_t { | |||
| 
 | ||||
| inline FormatConversionChar FormatConversionCharFromChar(char c) { | ||||
|   switch (c) { | ||||
| #define X_VAL(id) \ | ||||
| #define ABSL_INTERNAL_X_VAL(id) \ | ||||
|   case #id[0]:                  \ | ||||
|     return FormatConversionChar::id; | ||||
|     ABSL_CONVERSION_CHARS_EXPAND_(X_VAL, ) | ||||
| #undef X_VAL | ||||
|     ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, ) | ||||
| #undef ABSL_INTERNAL_X_VAL | ||||
|   } | ||||
|   return FormatConversionChar::kNone; | ||||
| } | ||||
|  | @ -240,15 +240,16 @@ inline bool FormatConversionCharIsFloat(FormatConversionChar c) { | |||
| 
 | ||||
| inline char FormatConversionCharToChar(FormatConversionChar c) { | ||||
|   switch (c) { | ||||
| #define X_VAL(e)                \ | ||||
| #define ABSL_INTERNAL_X_VAL(e)  \ | ||||
|   case FormatConversionChar::e: \ | ||||
|     return #e[0]; | ||||
| #define X_SEP | ||||
|     ABSL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP) | ||||
| #define ABSL_INTERNAL_X_SEP | ||||
|     ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, | ||||
|                                            ABSL_INTERNAL_X_SEP) | ||||
|     case FormatConversionChar::kNone: | ||||
|       return '\0'; | ||||
| #undef X_VAL | ||||
| #undef X_SEP | ||||
| #undef ABSL_INTERNAL_X_VAL | ||||
| #undef ABSL_INTERNAL_X_SEP | ||||
|   } | ||||
|   return '\0'; | ||||
| } | ||||
|  | @ -262,11 +263,8 @@ inline std::ostream& operator<<(std::ostream& os, FormatConversionChar v) { | |||
| 
 | ||||
| struct FormatConversionSpecImplFriend; | ||||
| 
 | ||||
| class ConversionSpec { | ||||
| class FormatConversionSpec { | ||||
|  public: | ||||
|   // Deprecated (use has_x_flag() instead).
 | ||||
|   Flags flags() const { return flags_; } | ||||
| 
 | ||||
|   // Width and precison are not specified, no flags are set.
 | ||||
|   bool is_basic() const { return flags_.basic; } | ||||
|   bool has_left_flag() const { return flags_.left; } | ||||
|  | @ -275,10 +273,10 @@ class ConversionSpec { | |||
|   bool has_alt_flag() const { return flags_.alt; } | ||||
|   bool has_zero_flag() const { return flags_.zero; } | ||||
| 
 | ||||
|   FormatConversionChar conv() const { | ||||
|   FormatConversionChar conversion_char() const { | ||||
|     // Keep this field first in the struct . It generates better code when
 | ||||
|     // accessing it when ConversionSpec is passed by value in registers.
 | ||||
|     static_assert(offsetof(ConversionSpec, conv_) == 0, ""); | ||||
|     static_assert(offsetof(FormatConversionSpec, conv_) == 0, ""); | ||||
|     return conv_; | ||||
|   } | ||||
| 
 | ||||
|  | @ -289,6 +287,11 @@ class ConversionSpec { | |||
|   // negative value.
 | ||||
|   int precision() const { return precision_; } | ||||
| 
 | ||||
|   // Deprecated (use has_x_flag() instead).
 | ||||
|   Flags flags() const { return flags_; } | ||||
|   // Deprecated
 | ||||
|   FormatConversionChar conv() const { return conversion_char(); } | ||||
| 
 | ||||
|  private: | ||||
|   friend struct str_format_internal::FormatConversionSpecImplFriend; | ||||
|   FormatConversionChar conv_ = FormatConversionChar::kNone; | ||||
|  | @ -298,46 +301,57 @@ class ConversionSpec { | |||
| }; | ||||
| 
 | ||||
| struct FormatConversionSpecImplFriend final { | ||||
|   static void SetFlags(Flags f, ConversionSpec* conv) { conv->flags_ = f; } | ||||
|   static void SetConversionChar(FormatConversionChar c, ConversionSpec* conv) { | ||||
|   static void SetFlags(Flags f, FormatConversionSpec* conv) { | ||||
|     conv->flags_ = f; | ||||
|   } | ||||
|   static void SetConversionChar(FormatConversionChar c, | ||||
|                                 FormatConversionSpec* conv) { | ||||
|     conv->conv_ = c; | ||||
|   } | ||||
|   static void SetWidth(int w, ConversionSpec* conv) { conv->width_ = w; } | ||||
|   static void SetPrecision(int p, ConversionSpec* conv) { | ||||
|   static void SetWidth(int w, FormatConversionSpec* conv) { conv->width_ = w; } | ||||
|   static void SetPrecision(int p, FormatConversionSpec* conv) { | ||||
|     conv->precision_ = p; | ||||
|   } | ||||
|   static std::string FlagsToString(const ConversionSpec& spec) { | ||||
|   static std::string FlagsToString(const FormatConversionSpec& spec) { | ||||
|     return spec.flags_.ToString(); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| constexpr uint64_t FormatConversionCharToConvValue(char conv) { | ||||
|   return | ||||
| #define CONV_SET_CASE(c)                                                     \ | ||||
| #define ABSL_INTERNAL_CHAR_SET_CASE(c)                                       \ | ||||
|   conv == #c[0]                                                              \ | ||||
|       ? (uint64_t{1} << (1 + static_cast<uint8_t>(FormatConversionChar::c))) \ | ||||
|       : | ||||
|       ABSL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, ) | ||||
| #undef CONV_SET_CASE | ||||
|       ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, ) | ||||
| #undef ABSL_INTERNAL_CHAR_SET_CASE | ||||
|                   conv == '*' | ||||
|           ? 1 | ||||
|           : 0; | ||||
| } | ||||
| 
 | ||||
| enum class Conv : uint64_t { | ||||
| #define CONV_SET_CASE(c) c = FormatConversionCharToConvValue(#c[0]), | ||||
|   ABSL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, ) | ||||
| #undef CONV_SET_CASE | ||||
| enum class FormatConversionCharSet : uint64_t { | ||||
| #define ABSL_INTERNAL_CHAR_SET_CASE(c) \ | ||||
|   c = FormatConversionCharToConvValue(#c[0]), | ||||
|   ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, ) | ||||
| #undef ABSL_INTERNAL_CHAR_SET_CASE | ||||
| 
 | ||||
|   // Used for width/precision '*' specification.
 | ||||
|   star = FormatConversionCharToConvValue('*'), | ||||
| 
 | ||||
|   kStar = FormatConversionCharToConvValue('*'), | ||||
|   // Some predefined values:
 | ||||
|   integral = d | i | u | o | x | X, | ||||
|   floating = a | e | f | g | A | E | F | G, | ||||
|   numeric = integral | floating, | ||||
|   string = s, | ||||
|   pointer = p | ||||
|   kIntegral = d | i | u | o | x | X, | ||||
|   kFloating = a | e | f | g | A | E | F | G, | ||||
|   kNumeric = kIntegral | kFloating, | ||||
|   kString = s, | ||||
|   kPointer = p, | ||||
| 
 | ||||
|   // The following are deprecated
 | ||||
|   star = kStar, | ||||
|   integral = kIntegral, | ||||
|   floating = kFloating, | ||||
|   numeric = kNumeric, | ||||
|   string = kString, | ||||
|   pointer = kPointer | ||||
| }; | ||||
| 
 | ||||
| // Type safe OR operator.
 | ||||
|  | @ -345,36 +359,41 @@ enum class Conv : uint64_t { | |||
| //  1. operator| on enums makes them decay to integers and the result is an
 | ||||
| //     integer. We need the result to stay as an enum.
 | ||||
| //  2. We use "enum class" which would not work even if we accepted the decay.
 | ||||
| constexpr Conv operator|(Conv a, Conv b) { | ||||
|   return Conv(static_cast<uint64_t>(a) | static_cast<uint64_t>(b)); | ||||
| constexpr FormatConversionCharSet operator|(FormatConversionCharSet a, | ||||
|                                             FormatConversionCharSet b) { | ||||
|   return FormatConversionCharSet(static_cast<uint64_t>(a) | | ||||
|                                  static_cast<uint64_t>(b)); | ||||
| } | ||||
| 
 | ||||
| // Get a conversion with a single character in it.
 | ||||
| constexpr Conv ConversionCharToConv(char c) { | ||||
|   return Conv(FormatConversionCharToConvValue(c)); | ||||
| constexpr FormatConversionCharSet ConversionCharToConv(char c) { | ||||
|   return FormatConversionCharSet(FormatConversionCharToConvValue(c)); | ||||
| } | ||||
| 
 | ||||
| // Checks whether `c` exists in `set`.
 | ||||
| constexpr bool Contains(Conv set, char c) { | ||||
| constexpr bool Contains(FormatConversionCharSet set, char c) { | ||||
|   return (static_cast<uint64_t>(set) & FormatConversionCharToConvValue(c)) != 0; | ||||
| } | ||||
| 
 | ||||
| // Checks whether all the characters in `c` are contained in `set`
 | ||||
| constexpr bool Contains(Conv set, Conv c) { | ||||
| constexpr bool Contains(FormatConversionCharSet set, | ||||
|                         FormatConversionCharSet c) { | ||||
|   return (static_cast<uint64_t>(set) & static_cast<uint64_t>(c)) == | ||||
|          static_cast<uint64_t>(c); | ||||
| } | ||||
| 
 | ||||
| // Return type of the AbslFormatConvert() functions.
 | ||||
| // The Conv template parameter is used to inform the framework of what
 | ||||
| // conversion characters are supported by that AbslFormatConvert routine.
 | ||||
| template <Conv C> | ||||
| struct ConvertResult { | ||||
|   static constexpr Conv kConv = C; | ||||
| // The FormatConversionCharSet template parameter is used to inform the
 | ||||
| // framework of what conversion characters are supported by that
 | ||||
| // AbslFormatConvert routine.
 | ||||
| template <FormatConversionCharSet C> | ||||
| struct FormatConvertResult { | ||||
|   static constexpr FormatConversionCharSet kConv = C; | ||||
|   bool value; | ||||
| }; | ||||
| template <Conv C> | ||||
| constexpr Conv ConvertResult<C>::kConv; | ||||
| 
 | ||||
| template <FormatConversionCharSet C> | ||||
| constexpr FormatConversionCharSet FormatConvertResult<C>::kConv; | ||||
| 
 | ||||
| // Return capacity - used, clipped to a minimum of 0.
 | ||||
| inline size_t Excess(size_t used, size_t capacity) { | ||||
|  | @ -383,6 +402,10 @@ inline size_t Excess(size_t used, size_t capacity) { | |||
| 
 | ||||
| // Type alias for use during migration.
 | ||||
| using ConversionChar = FormatConversionChar; | ||||
| using ConversionSpec = FormatConversionSpec; | ||||
| using Conv = FormatConversionCharSet; | ||||
| template <FormatConversionCharSet C> | ||||
| using ConvertResult = FormatConvertResult<C>; | ||||
| 
 | ||||
| }  // namespace str_format_internal
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue