diff options
-rw-r--r-- | CMake/AbseilDll.cmake | 16 | ||||
-rw-r--r-- | CMake/AbseilHelpers.cmake | 12 | ||||
-rw-r--r-- | absl/CMakeLists.txt | 1 | ||||
-rw-r--r-- | absl/base/BUILD.bazel | 24 | ||||
-rw-r--r-- | absl/base/CMakeLists.txt | 25 | ||||
-rw-r--r-- | absl/base/attributes.h | 2 | ||||
-rw-r--r-- | absl/base/internal/errno_saver.h | 43 | ||||
-rw-r--r-- | absl/base/internal/errno_saver_test.cc | 44 | ||||
-rw-r--r-- | absl/base/internal/spinlock_linux.inc | 5 | ||||
-rw-r--r-- | absl/base/internal/spinlock_posix.inc | 6 | ||||
-rw-r--r-- | absl/debugging/BUILD.bazel | 2 | ||||
-rw-r--r-- | absl/debugging/CMakeLists.txt | 2 | ||||
-rw-r--r-- | absl/debugging/failure_signal_handler.cc | 4 | ||||
-rw-r--r-- | absl/debugging/internal/address_is_readable.cc | 5 | ||||
-rw-r--r-- | absl/flags/internal/flag.h | 2 | ||||
-rw-r--r-- | absl/random/internal/seed_salting_sequence_generator.cc | 30 | ||||
-rw-r--r-- | absl/random/internal/seed_salting_sequence_generator_empty_sequence.cc | 30 | ||||
-rw-r--r-- | absl/status/CMakeLists.txt | 2 | ||||
-rw-r--r-- | absl/strings/internal/str_format/checker_test.cc | 2 | ||||
-rw-r--r-- | absl/strings/internal/str_format/extension.h | 119 |
20 files changed, 248 insertions, 128 deletions
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake index 8184d500ba77..90c9f1f642d4 100644 --- a/CMake/AbseilDll.cmake +++ b/CMake/AbseilDll.cmake @@ -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" diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake index 7571ef1b15ce..86ff9eba2a89 100644 --- a/CMake/AbseilHelpers.cmake +++ b/CMake/AbseilHelpers.cmake @@ -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} diff --git a/absl/CMakeLists.txt b/absl/CMakeLists.txt index 26693eadaad2..fbfa7822b594 100644 --- a/absl/CMakeLists.txt +++ b/absl/CMakeLists.txt @@ -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) diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index c6948a272f35..bae79427ac4e 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -41,6 +41,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"], hdrs = ["log_severity.h"], @@ -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, diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index c21571be9b8c..14c52eabdfb3 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -30,6 +30,17 @@ absl_cc_library( absl_cc_library( NAME + errno_saver + HDRS + "internal/errno_saver.h" + DEPS + absl::config + COPTS + ${ABSL_DEFAULT_COPTS} +) + +absl_cc_library( + NAME log_severity HDRS "log_severity.h" @@ -73,6 +84,7 @@ absl_cc_library( DEPS absl::base_internal absl::core_headers + absl::errno_saver ) absl_cc_library( @@ -307,6 +319,19 @@ absl_cc_test( 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 SRCS "throw_delegate_test.cc" diff --git a/absl/base/attributes.h b/absl/base/attributes.h index 8f77db77d23a..ff138629d1f1 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -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 diff --git a/absl/base/internal/errno_saver.h b/absl/base/internal/errno_saver.h new file mode 100644 index 000000000000..251de510fc93 --- /dev/null +++ b/absl/base/internal/errno_saver.h @@ -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_ diff --git a/absl/base/internal/errno_saver_test.cc b/absl/base/internal/errno_saver_test.cc new file mode 100644 index 000000000000..b845e2dd1a0f --- /dev/null +++ b/absl/base/internal/errno_saver_test.cc @@ -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 diff --git a/absl/base/internal/spinlock_linux.inc b/absl/base/internal/spinlock_linux.inc index 28e29d191909..323edd62f464 100644 --- a/absl/base/internal/spinlock_linux.inc +++ b/absl/base/internal/spinlock_linux.inc @@ -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, diff --git a/absl/base/internal/spinlock_posix.inc b/absl/base/internal/spinlock_posix.inc index f025b5f8a373..fcd21b151b6e 100644 --- a/absl/base/internal/spinlock_posix.inc +++ b/absl/base/internal/spinlock_posix.inc @@ -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( diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index a01408910ac4..8f521bec4692 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel @@ -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", ], ) diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt index 66886c7a0949..77336159393d 100644 --- a/absl/debugging/CMakeLists.txt +++ b/absl/debugging/CMakeLists.txt @@ -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 ) diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc index cd141ecf5d32..1f69bfa84dd9 100644 --- a/absl/debugging/failure_signal_handler.cc +++ b/absl/debugging/failure_signal_handler.cc @@ -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*)) { diff --git a/absl/debugging/internal/address_is_readable.cc b/absl/debugging/internal/address_is_readable.cc index f45e59b3836a..65376063669f 100644 --- a/absl/debugging/internal/address_is_readable.cc +++ b/absl/debugging/internal/address_is_readable.cc @@ -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; } diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index c1beda8ebc00..35a148cf6602 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -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()); diff --git a/absl/random/internal/seed_salting_sequence_generator.cc b/absl/random/internal/seed_salting_sequence_generator.cc deleted file mode 100644 index 31fdcfe1db41..000000000000 --- a/absl/random/internal/seed_salting_sequence_generator.cc +++ /dev/null @@ -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; -} diff --git a/absl/random/internal/seed_salting_sequence_generator_empty_sequence.cc b/absl/random/internal/seed_salting_sequence_generator_empty_sequence.cc deleted file mode 100644 index 8797e2e7a6f2..000000000000 --- a/absl/random/internal/seed_salting_sequence_generator_empty_sequence.cc +++ /dev/null @@ -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; -} diff --git a/absl/status/CMakeLists.txt b/absl/status/CMakeLists.txt index 4f553867ac05..f05cee5e954d 100644 --- a/absl/status/CMakeLists.txt +++ b/absl/status/CMakeLists.txt @@ -41,7 +41,7 @@ absl_cc_library( absl_cc_test( NAME status_test - HDRS + SRCS "status_test.cc" COPTS ${ABSL_TEST_COPTS} diff --git a/absl/strings/internal/str_format/checker_test.cc b/absl/strings/internal/str_format/checker_test.cc index c309e20310a1..ea2a7681a62a 100644 --- a/absl/strings/internal/str_format/checker_test.cc +++ b/absl/strings/internal/str_format/checker_test.cc @@ -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; diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h index 16f6c0a4b205..d1665753d182 100644 --- a/absl/strings/internal/str_format/extension.h +++ b/absl/strings/internal/str_format/extension.h @@ -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) \ - case #id[0]: \ +#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 |