### Build and install instrumented libc++ Source: https://github.com/abseil/abseil-cpp/blob/master/FAQ.md Build and install the configured libc++ runtime. This step ensures that the instrumented standard library is available for use. ```shell # Build and install it into ${HOME}/llvm-msan ninja -C build_msan install-cxx install-cxxabi install-unwind ``` -------------------------------- ### Install Abseil with CMake Source: https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md Install the Abseil library after building it. This command should be run from the build directory. ```bash cmake --build /temporary/build/abseil-cpp --target install ``` -------------------------------- ### Build and Install Google Test with CMake Source: https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md Build and install Google Test separately before configuring Abseil. Ensure CMAKE_INSTALL_PREFIX is set correctly. ```bash cmake -S /source/googletest -B /build/googletest -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/installation/dir -DBUILD_GMOCK=ON cmake --build /build/googletest --target install ``` -------------------------------- ### Enable Standard CMake Installation for Abseil Source: https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md CMake option to enable the standard installation procedure for Abseil. ```cmake -DABSL_ENABLE_INSTALL=ON ``` -------------------------------- ### CMakeLists.txt for Abseil Installation Test Source: https://github.com/abseil/abseil-cpp/blob/master/CMake/install_test_project/CMakeLists.txt This CMakeLists.txt file sets up a minimal C++ project that finds and links to the Abseil library. Ensure Abseil is installed correctly for this to work. ```cmake cmake_minimum_required(VERSION 3.16) project(absl_cmake_testing CXX) add_executable(simple simple.cc) find_package(absl REQUIRED) target_link_libraries(simple absl::strings absl::config) ``` -------------------------------- ### Configure and Build Abseil with External Google Test Source: https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md Configure and build Abseil, enabling installation and specifying the location of the pre-installed Google Test. CMAKE_PREFIX_PATH should point to the Google Test installation directory. ```bash cmake -S /source/abseil-cpp -B /build/abseil-cpp -DCMAKE_PREFIX_PATH=/installation/dir -DCMAKE_INSTALL_PREFIX=/installation/dir -DABSL_ENABLE_INSTALL=ON -DABSL_USE_EXTERNAL_GOOGLETEST=ON -DABSL_FIND_GOOGLETEST=ON cmake --build /temporary/build/abseil-cpp ``` -------------------------------- ### Configure and Build Abseil Tests with CMake Source: https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md Build Abseil tests using CMake, enabling testing and automatically downloading Googletest. This example assumes Abseil is in a subdirectory and uses a release build. ```bash cd path/to/abseil-cpp mkdir build cd build cmake -DABSL_BUILD_TESTING=ON -DABSL_USE_GOOGLETEST_HEAD=ON .. make -j ctest ``` -------------------------------- ### Generate and Install Pinned options.h Source: https://github.com/abseil/abseil-cpp/blob/master/CMakeLists.txt This CMake code checks if the generated options-pinned.h file needs to be updated by comparing its content with the existing file in the build directory. If an update is necessary, it generates the file and then installs it to the appropriate include directory, renaming it to options.h. ```cmake # If the file already exists, check if it matches the new contents. # This avoids writing the file if it is already up-to-date when the CMake # generation is triggered and triggering unnecessary rebuilds. set(ABSL_INTERNAL_OPTIONS_H_PINNED_NEEDS_UPDATE TRUE) if (EXISTS "${CMAKE_BINARY_DIR}/options-pinned.h") file(READ "${CMAKE_BINARY_DIR}/options-pinned.h" ABSL_INTERNAL_OPTIONS_PINNED_H_CONTENTS) if ("${ABSL_INTERNAL_OPTIONS_H_PINNED}" STREQUAL "${ABSL_INTERNAL_OPTIONS_PINNED_H_CONTENTS}") set(ABSL_INTERNAL_OPTIONS_H_PINNED_NEEDS_UPDATE FALSE) endif() endif() # If the file needs an update, generate it. if (ABSL_INTERNAL_OPTIONS_H_PINNED_NEEDS_UPDATE) file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/options-pinned.h" CONTENT "${ABSL_INTERNAL_OPTIONS_H_PINNED}") endif() install(FILES "${CMAKE_BINARY_DIR}/options-pinned.h" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/absl/base RENAME "options.h") ``` -------------------------------- ### Initialize Abseil Logging Source: https://context7.com/abseil/abseil-cpp/llms.txt Call `absl::InitializeLog()` once at the beginning of your application's `main` function to set up the logging system. ```cpp #include "absl/log/initialize.h" // Initialize logging (call once in main()) absl::InitializeLog(); ``` -------------------------------- ### Basic Abseil Logging Source: https://context7.com/abseil/abseil-cpp/llms.txt Use `LOG(severity)` macros for streaming log messages. Severity levels include INFO, WARNING, ERROR, and FATAL. FATAL logs also print a stack trace. ```cpp #include "absl/log/log.h" // Basic logging LOG(INFO) << "Server starting on port " << port; LOG(WARNING) << "Cache hit rate low: " << hit_rate << "%ствие"; LOG(ERROR) << "Failed to connect: " << status; LOG(FATAL) << "Unrecoverable error — terminating"; // also prints stack trace ``` -------------------------------- ### Set C++ Standard with Bazel via Command Line Source: https://github.com/abseil/abseil-cpp/blob/master/FAQ.md Use `--cxxopt=-std=c++17` to specify the C++ standard when building with Bazel. Ensure this is applied consistently across your project. ```bazel bazel build --cxxopt=-std=c++17 ... ``` -------------------------------- ### absl::BitGen and Distributions Source: https://context7.com/abseil/abseil-cpp/llms.txt Demonstrates how to use absl::BitGen for pseudorandom number generation with various standard and Abseil-defined distributions, including seeding for reproducibility. ```APIDOC ## `absl::BitGen` + distributions — Pseudorandom number generation `absl::BitGen` is a general-purpose URBG (Uniform Random Bit Generator) seeded non-deterministically by default. It is used with standard `` distributions or with Abseil's convenience `absl::Uniform`, `absl::Bernoulli`, `absl::Gaussian`, and `absl::Poisson` wrappers. `absl::InsecureBitGen` is a faster, less-random alternative. ```cpp #include "absl/random/random.h" #include "absl/random/distributions.h" // Create a non-deterministically seeded bit generator absl::BitGen gen; // Uniform integer in [1, 6] (inclusive) int die = absl::Uniform(absl::IntervalClosed, gen, 1, 6); // Uniform float in [0.0, 1.0) double prob = absl::Uniform(gen, 0.0, 1.0); // Bernoulli trial with given probability bool heads = absl::Bernoulli(gen, 0.5); // Gaussian (normal) distribution double sample = absl::Gaussian(gen, /*mean=*/0.0, /*stddev=*/1.0); // Poisson distribution int events = absl::Poisson(gen, /*mean=*/3.7); // Shuffle a container std::vector deck(52); std::iota(deck.begin(), deck.end(), 0); absl::c_shuffle(deck, gen); // Seeded for reproducibility (adds seed but mixes with entropy) std::seed_seq seq{42}; absl::BitGen seeded_gen(seq); ``` ``` -------------------------------- ### Set C++ Standard with Bazel via .bazelrc Source: https://github.com/abseil/abseil-cpp/blob/master/FAQ.md Add `build --cxxopt=-std=c++17` to your `.bazelrc` file for a persistent C++ standard configuration in Bazel builds. ```bazel build --cxxopt=-std=c++17 ``` -------------------------------- ### Abseil Time, Duration, and TimeZone Handling Source: https://context7.com/abseil/abseil-cpp/llms.txt Demonstrates arithmetic, formatting, parsing, and conversion operations for absolute time, time spans, and time zones. Requires including "absl/time/time.h" and "absl/time/civil_time.h". ```cpp #include "absl/time/time.h" #include "absl/time/civil_time.h" // Duration arithmetic absl::Duration d = absl::Hours(2) + absl::Minutes(30) + absl::Seconds(15); std::cout << absl::FormatDuration(d); // "2h30m15s" double secs = absl::ToDoubleSeconds(d); // 9015.0 // Absolute time operations absl::Time now = absl::Now(); absl::Time deadline = now + absl::Minutes(5); bool expired = absl::Now() > deadline; // Civil time and time zones absl::TimeZone nyc, syd; CHECK(absl::LoadTimeZone("America/New_York", &nyc)); CHECK(absl::LoadTimeZone("Australia/Sydney", &syd)); absl::CivilSecond flight_depart(2025, 3, 15, 8, 30, 0); absl::Time takeoff = absl::FromCivil(flight_depart, nyc); absl::Time landing = takeoff + absl::Hours(20) + absl::Minutes(15); std::string arrival = absl::FormatTime( "Arrives %Y-%m-%d at %H:%M %Z", landing, syd); // e.g., "Arrives 2025-03-16 at 14:45 AEDT" // Convert to/from Unix epoch int64_t unix_sec = absl::ToUnixSeconds(now); absl::Time from_unix = absl::FromUnixSeconds(unix_sec); // Parse time strings absl::Time parsed; std::string err; if (!absl::ParseTime(absl::RFC3339_full, "2025-01-15T10:30:00Z", &parsed, &err)) { LOG(ERROR) << "Parse failed: " << err; } // Duration from chrono absl::Duration from_chrono = absl::FromChrono(std::chrono::seconds(60)); ``` -------------------------------- ### Set C++ Standard with Bazel via Environment Variable Source: https://github.com/abseil/abseil-cpp/blob/master/FAQ.md Set the `BAZEL_CXXOPTS` environment variable to `-std=c++17` to configure the C++ standard for Bazel builds. This provides a project-wide setting. ```bash export BAZEL_CXXOPTS=-std=c++17 ``` -------------------------------- ### Run Abseil Tests with CTest Source: https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md Execute tests for the Abseil build using CTest. Ensure the test directory is correctly specified. ```bash ctest --test-dir /temporary/build/abseil-cpp ``` -------------------------------- ### Abseil Google Test Build Options Source: https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md CMake options for configuring Google Test integration. Set ABSL_BUILD_TESTING=ON to enable testing. ```cmake -DABSL_BUILD_TESTING=ON ``` ```cmake -DABSL_USE_EXTERNAL_GOOGLETEST=OFF ``` ```cmake -DABSL_USE_GOOGLETEST_HEAD=ON ``` ```cmake -DABSL_GOOGLETEST_DOWNLOAD_URL=https://.../version.zip ``` ```cmake -DABSL_LOCAL_GOOGLETEST_DIR=/path/to/googletest ``` ```cmake -DABSL_USE_EXTERNAL_GOOGLETEST=ON ``` ```cmake -DABSL_USE_EXTERNAL_GOOGLETEST=ON -DABSL_FIND_GOOGLETEST=ON ``` -------------------------------- ### Set Minimum Log Level at Runtime Source: https://context7.com/abseil/abseil-cpp/llms.txt Use `absl::SetMinLogLevel` to dynamically adjust the minimum severity level of logs that will be processed by the system. ```cpp #include "absl/log/globals.h" #include "absl/log/log.h" // Override log level at runtime absl::SetMinLogLevel(absl::LogSeverityAtLeast::kWarning); ``` -------------------------------- ### Test code with MemorySanitizer and instrumented libc++ using Bazel Source: https://github.com/abseil/abseil-cpp/blob/master/FAQ.md Build or test your code using Bazel with MemorySanitizer enabled and pointing to the instrumented libc++. This ensures all components are compiled with the same sanitizer configuration. ```shell # Then build (or test) your code like this: bazel test --repo_env=CC=clang --repo_env=BAZEL_CXXOPTS=nostdinc++ --repo_env=BAZEL_LINKOPTS=-L${HOME}/llvm-msan/lib:-lc++:-lc++abi:-lgcc_s:-lm:-Wl,-rpath=${HOME}/llvm-msan/lib --repo_env=CPLUS_INCLUDE_PATH=${HOME}/llvm-msan/include/c++/v1 --copt=-fsanitize=memory --linkopt=-fsanitize=memory --linkopt=-fsanitize-link-c++-runtime ... ``` -------------------------------- ### absl::Hash / AbslHashValue Source: https://context7.com/abseil/abseil-cpp/llms.txt Explains Abseil's extensible hashing framework, including how to use built-in support for common types and how to extend it to custom types using `AbslHashValue`. ```APIDOC ## Hashing ### `absl::Hash` / `AbslHashValue` — Extensible hashing framework `absl::Hash` is a functor-based hashing framework that randomizes hash values per-process to prevent hash flooding. Custom types opt in by defining a free function `AbslHashValue(H h, const T& v)`. `absl::HashOf(...)` provides a convenient shorthand for hashing a set of values. ```cpp #include "absl/hash/hash.h" // Built-in support for fundamental types and most Abseil types size_t h1 = absl::Hash{}(42); size_t h2 = absl::Hash{}("hello"); size_t h3 = absl::Hash>{}({1, 2}); // Extend hashing to custom types using AbslHashValue struct Address { std::string street; std::string city; int zip; template friend H AbslHashValue(H h, const Address& a) { return H::combine(std::move(h), a.street, a.city, a.zip); } }; // Now Address works with absl::flat_hash_map, absl::flat_hash_set, etc. absl::flat_hash_set
addresses; addresses.insert({"Main St", "Springfield", 12345}); // absl::HashOf — hash multiple values directly size_t combined = absl::HashOf(user_id, session_token, timestamp); // Use as a std::unordered_map hasher std::unordered_map> addr_map; ``` ``` -------------------------------- ### Library Project with C++ Standard Enforcement Source: https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md Configure a library project to enforce a minimum C++ standard for Abseil ABI compatibility. The top-level application is responsible for setting a consistent C++ standard. ```cmake cmake_minimum_required(VERSION 3.16) project(my_lib_project) # Leave C++ standard up to the root application, so set it only if this is the # current top-level CMake project. if(CMAKE_SOURCE_DIR STREQUAL my_lib_project_SOURCE_DIR) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) endif() add_subdirectory(abseil-cpp) add_library(my_lib source.cpp) target_link_libraries(my_lib absl::base absl::synchronization absl::strings) # Enforce that my_lib requires C++17. Important to document for clients that they # must set CMAKE_CXX_STANDARD to 17 or higher for proper Abseil ABI compatibility # (since otherwise, Abseil library targets could be compiled with a lower C++ # standard than my_lib). target_compile_features(my_lib PUBLIC cxx_std_17) if(CMAKE_CXX_STANDARD LESS 17) message(FATAL_ERROR "my_lib_project requires CMAKE_CXX_STANDARD >= 17 (got: ${CMAKE_CXX_STANDARD})") endif() ``` -------------------------------- ### Track Latest Abseil Commit with Bazel Bzlmod Source: https://github.com/abseil/abseil-cpp/blob/master/FAQ.md Use `git_override` in your `MODULE.bazel` file to track the latest commit of the Abseil C++ library. This ensures you are always using the most recent bug fixes and features. ```starlark bazel_dep(name = "abseil-cpp", version = "20260107.1") git_override( module_name = "abseil-cpp", remote = "https://github.com/abseil/abseil-cpp.git", # Replace the following line with the latest commit. commit = "6ec9964c325db0610a376b3cb81de073ea6ada90", ) ``` -------------------------------- ### Condition-Based Waiting with absl::Mutex Source: https://context7.com/abseil/abseil-cpp/llms.txt Utilize `absl::Mutex::Await` with `absl::Condition` for efficient waiting on predicates, eliminating the need for separate condition variables in many common scenarios. ```cpp #include "absl/synchronization/mutex.h" #include absl::Mutex queue_mu; std::queue work_queue; void Producer() { absl::MutexLock lock(&queue_mu); work_queue.push(42); } // wakes waiters automatically if their Condition becomes true void Consumer() { absl::MutexLock lock(&queue_mu); // Blocks until queue is non-empty — no explicit Signal() needed auto not_empty = absl::Condition( +[](std::queue* q) { return !q->empty(); }, &work_queue); queue_mu.Await(not_empty); int val = work_queue.front(); work_queue.pop(); } ``` -------------------------------- ### Abseil BitGen for Pseudorandom Number Generation Source: https://context7.com/abseil/abseil-cpp/llms.txt Use `absl::BitGen` for general-purpose pseudorandom number generation. It can be seeded non-deterministically by default or with a `std::seed_seq` for reproducible results. Works with standard `` distributions and Abseil's convenience wrappers. ```cpp #include "absl/random/random.h" #include "absl/random/distributions.h" // Create a non-deterministically seeded bit generator absl::BitGen gen; // Uniform integer in [1, 6] (inclusive) int die = absl::Uniform(absl::IntervalClosed, gen, 1, 6); // Uniform float in [0.0, 1.0) double prob = absl::Uniform(gen, 0.0, 1.0); // Bernoulli trial with given probability bool heads = absl::Bernoulli(gen, 0.5); // Gaussian (normal) distribution double sample = absl::Gaussian(gen, /*mean=*/0.0, /*stddev=*/1.0); // Poisson distribution int events = absl::Poisson(gen, /*mean=*/3.7); // Shuffle a container std::vector deck(52); std::iota(deck.begin(), deck.end(), 0); absl::c_shuffle(deck, gen); // Seeded for reproducibility (adds seed but mixes with entropy) std::seed_seq seq{42}; absl::BitGen seeded_gen(seq); ``` -------------------------------- ### Verbose Abseil Logging Source: https://context7.com/abseil/abseil-cpp/llms.txt Use `VLOG(level)` for detailed trace messages that are controlled by the `--v` command-line flag, allowing dynamic verbosity control. ```cpp #include "absl/log/log.h" // Verbose logging (controlled by --v flag) VLOG(1) << "Detailed trace: " << detail; ``` -------------------------------- ### Integrate Abseil into a CMake Project Source: https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md Include Abseil as a subdirectory and link against its targets. Ensure C++ standard compatibility. ```cmake cmake_minimum_required(VERSION 3.16) project(my_app_project) # Pick the C++ standard to compile with. # Abseil currently supports C++17 and C++20. set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_subdirectory(abseil-cpp) add_executable(my_exe source.cpp) target_link_libraries(my_exe absl::base absl::synchronization absl::strings) ``` -------------------------------- ### Configure libc++ for MemorySanitizer with CMake Source: https://github.com/abseil/abseil-cpp/blob/master/FAQ.md Configure libc++ to be instrumented with MSAN using CMake. This is a prerequisite for using MemorySanitizer with Abseil and other C++ code. ```shell # From the root of the LLVM source tree, configure libc++ to be instrumented with MSAN: cmake -G Ninja -S runtimes -B build_msan -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${HOME}/llvm-msan" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_USE_SANITIZER=MemoryWithOrigins -DLLVM_TARGETS_TO_BUILD="host" ``` -------------------------------- ### Custom Abseil Log Sink Source: https://context7.com/abseil/abseil-cpp/llms.txt Implement `absl::LogSink` to redirect log messages to custom destinations, such as in-memory storage or network services. ```cpp #include "absl/log/log.h" #include "absl/log/log_sink.h" class MyLogSink : public absl::LogSink { public: void Send(const absl::LogEntry& entry) override { my_storage.push_back(std::string(entry.text_message())); } }; MyLogSink sink; LOG(INFO).ToSinkAlso(&sink) << "Goes to both default and MyLogSink"; ``` -------------------------------- ### Abseil CMake Public Targets Source: https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md List of available Abseil CMake public targets that can be linked against. ```cmake absl::algorithm absl::base absl::debugging absl::flat_hash_map absl::flags absl::memory absl::meta absl::numeric absl::random_random absl::strings absl::synchronization absl::time absl::utility ``` -------------------------------- ### Conditional and Rate-Limited Abseil Logging Source: https://context7.com/abseil/abseil-cpp/llms.txt Use `LOG_IF` for logging based on a condition and `LOG_EVERY_N` to log at most once per N occurrences, useful for reducing log volume. ```cpp #include "absl/log/log.h" // Conditional logging LOG_IF(WARNING, latency_ms > 100) << "Slow request: " << latency_ms << "ms"; // Rate-limited logging (log at most once per N occurrences) LOG_EVERY_N(INFO, 1000) << "Processed request " << request_id; ``` -------------------------------- ### Conditional Compilation of options.h Source: https://github.com/abseil/abseil-cpp/blob/master/CMakeLists.txt This snippet demonstrates how to conditionally rewrite absl/base/options.h to use standard library features based on the C++ standard version detected by CMake. It iterates through features requiring C++20 and C++17, replacing specific preprocessor defines to enable standard library implementations. ```cmake file(READ "absl/base/options.h" ABSL_INTERNAL_OPTIONS_H_CONTENTS) # Handle features that require at least C++20. if (ABSL_INTERNAL_AT_LEAST_CXX20) foreach(FEATURE "ORDERING" "SOURCE_LOCATION") string(REPLACE "#define ABSL_OPTION_USE_STD_${FEATURE} 2" "#define ABSL_OPTION_USE_STD_${FEATURE} 1" ABSL_INTERNAL_OPTIONS_H_PINNED "${ABSL_INTERNAL_OPTIONS_H_CONTENTS}") set(ABSL_INTERNAL_OPTIONS_H_CONTENTS "${ABSL_INTERNAL_OPTIONS_H_PINNED}") endforeach() endif() # Handle features that require at least C++17. if (ABSL_INTERNAL_AT_LEAST_CXX17) foreach(FEATURE "ANY" "OPTIONAL" "STRING_VIEW" "VARIANT") string(REPLACE "#define ABSL_OPTION_USE_STD_${FEATURE} 2" "#define ABSL_OPTION_USE_STD_${FEATURE} 1" ABSL_INTERNAL_OPTIONS_H_PINNED "${ABSL_INTERNAL_OPTIONS_H_CONTENTS}") set(ABSL_INTERNAL_OPTIONS_H_CONTENTS "${ABSL_INTERNAL_OPTIONS_H_PINNED}") endforeach() endif() # Any feature that still has the value of 2 (because it was not handled above) # should be set to 0. string(REGEX REPLACE "#define ABSL_OPTION_USE_STD_([^ ]*) 2" "#define ABSL_OPTION_USE_STD_\1 0" ABSL_INTERNAL_OPTIONS_H_PINNED "${ABSL_INTERNAL_OPTIONS_H_CONTENTS}") ``` -------------------------------- ### Abseil Cleanup Guard for Scope-Exit Actions Source: https://context7.com/abseil/abseil-cpp/llms.txt Utilizes absl::Cleanup to ensure a callback is executed upon scope exit, similar to Go's defer. Supports early invocation and cancellation. Requires including "absl/cleanup/cleanup.h". ```cpp #include "absl/cleanup/cleanup.h" absl::Status ProcessFiles(const char* src, const char* dst) { FILE* src_file = fopen(src, "r"); if (!src_file) return absl::NotFoundError("source not found"); // Automatically closes src_file on any return path absl::Cleanup src_closer = [src_file] { fclose(src_file); }; FILE* dst_file = fopen(dst, "w"); if (!dst_file) { return absl::PermissionDeniedError("cannot create destination"); // src_closer fires here } absl::Cleanup dst_closer = [dst_file] { fclose(dst_file); }; // ... process data ... // Both cleanups fire on success too return absl::OkStatus(); } // Early invocation absl::Cleanup cleanup = [] { LOG(INFO) << "Cleanup ran"; }; std::move(cleanup).Invoke(); // runs now, won't run again at scope exit // Cancellation bool commit = false; absl::Cleanup rollback = [&db] { db.Rollback(); }; db.ExecuteTransaction(); commit = true; if (commit) std::move(rollback).Cancel(); // suppress rollback ``` -------------------------------- ### Set C++ Standard with CMake Source: https://github.com/abseil/abseil-cpp/blob/master/FAQ.md In CMake, set `CMAKE_CXX_STANDARD` to `17` in your top-level `CMakeLists.txt` for a project-wide C++ standard. For libraries, use `target_compile_features` for per-target minimum standards. ```cmake set(CMAKE_CXX_STANDARD 17) ``` -------------------------------- ### Abseil Status and StatusOr for Error Propagation Source: https://context7.com/abseil/abseil-cpp/llms.txt Use `absl::Status` for success or error codes and `absl::StatusOr` to wrap a value or an error. Factory functions like `absl::NotFoundError` and predicates like `absl::IsNotFound` aid in error handling. Payloads can be attached to `absl::Status` objects. ```cpp #include "absl/status/status.h" #include "absl/status/statusor.h" // Returning Status from a function absl::Status ValidateAge(int age) { if (age < 0 || age > 150) { return absl::InvalidArgumentError( absl::StrCat("Invalid age: ", age, " (must be 0-150)")); } return absl::OkStatus(); } // Returning StatusOr — value or error absl::StatusOr LoadUser(int id) { if (id <= 0) return absl::InvalidArgumentError("id must be positive"); if (id > 1000) return absl::NotFoundError(absl::StrCat("No user ", id)); return absl::StrCat("User_", id); // implicit conversion to StatusOr } // Consuming StatusOr absl::StatusOr result = LoadUser(42); if (result.ok()) { std::cout << "Loaded: " << *result << "\n"; // or result.value() } else { LOG(ERROR) << result.status(); // Inspect the code: if (absl::IsNotFound(result.status())) { /* handle missing */ } } // Attaching structured payloads to Status absl::Status s = absl::NotFoundError("config file missing"); s.SetPayload("type.googleapis.com/MyError", absl::Cord(R"({\"file\":\"/etc/app.conf\"})")); std::optional payload = s.GetPayload("type.googleapis.com/MyError"); // All StatusCode values // absl::StatusCode::kOk, kCancelled, kUnknown, kInvalidArgument, // kDeadlineExceeded, kNotFound, kAlreadyExists, kPermissionDenied, // kResourceExhausted, kFailedPrecondition, kAborted, kOutOfRange, // kUnimplemented, kInternal, kUnavailable, kDataLoss, kUnauthenticated ``` -------------------------------- ### Abseil Hash Framework for Extensible Hashing Source: https://context7.com/abseil/abseil-cpp/llms.txt Utilize `absl::Hash` for a process-randomized hashing framework to prevent hash flooding. Extend hashing to custom types by defining `AbslHashValue`. `absl::HashOf` provides a convenient way to hash multiple values. ```cpp #include "absl/hash/hash.h" // Built-in support for fundamental types and most Abseil types size_t h1 = absl::Hash{}(42); size_t h2 = absl::Hash{}("hello"); size_t h3 = absl::Hash>{}({1, 2}); // Extend hashing to custom types using AbslHashValue struct Address { std::string street; std::string city; int zip; template friend H AbslHashValue(H h, const Address& a) { return H::combine(std::move(h), a.street, a.city, a.zip); } }; // Now Address works with absl::flat_hash_map, absl::flat_hash_set, etc. absl::flat_hash_set
addresses; addresses.insert({"Main St", "Springfield", 12345}); // absl::HashOf — hash multiple values directly size_t combined = absl::HashOf(user_id, session_token, timestamp); // Use as a std::unordered_map hasher std::unordered_map> addr_map; ``` -------------------------------- ### Efficient String Concatenation with absl::StrCat Source: https://context7.com/abseil/abseil-cpp/llms.txt Use absl::StrCat for efficient string concatenation of various types without intermediate allocations. absl::StrAppend is preferred for appending to existing strings. ```cpp #include "absl/strings/str_cat.h" // Basic concatenation of mixed types std::string name = "Alice"; int age = 30; double score = 98.6; std::string result = absl::StrCat("Name: ", name, ", Age: ", age, ", Score: ", score); // result == "Name: Alice, Age: 30, Score: 98.6" // Hex formatting with zero-padding uint32_t addr = 0xDEADBEEF; std::string hex = absl::StrCat("Address: 0x", absl::Hex(addr, absl::kZeroPad8)); // hex == "Address: 0xdeadbeef" // Appending to an existing string (preferred over str = StrCat(str, ...)) std::string log; absl::StrAppend(&log, "[INFO] ", "Request ", 42, " processed"); // log == "[INFO] Request 42 processed" // Custom type support via AbslStringify struct Point { int x, y; template friend void AbslStringify(Sink& sink, const Point& p) { absl::Format(&sink, "(%v, %v)", p.x, p.y); } }; Point pt{3, 4}; std::string s = absl::StrCat("Point: ", pt); // s == "Point: (3, 4)" // High-precision float round-trip double pi = 3.141592653589793; std::string precise = absl::StrCat(absl::HighPrecision(pi)); // precise produces a string that converts back to the exact same double ``` -------------------------------- ### Abseil CHECK Macros for Assertions Source: https://context7.com/abseil/abseil-cpp/llms.txt Use `CHECK` macros for fatal runtime assertions that are active in both debug and release builds. They support custom error messages. ```cpp #include "absl/log/check.h" // CHECK — fatal if condition is false CHECK(!data.empty()) << "Expected non-empty data"; CHECK_EQ(expected, actual) << "Values differ"; CHECK_GE(size, 0) << "Size must be non-negative, got " << size; CHECK_LT(index, container.size()) << "Index out of bounds"; ``` -------------------------------- ### Use absl::Mutex for Thread-Safe Access Source: https://context7.com/abseil/abseil-cpp/llms.txt Employ `absl::Mutex` with RAII wrappers like `absl::MutexLock` and `absl::ReaderMutexLock` for exclusive and shared access to shared data, respectively. It includes deadlock detection. ```cpp #include "absl/synchronization/mutex.h" #include #include #include class ThreadSafeCache { public: std::optional Get(const std::string& key) { absl::ReaderMutexLock lock(&mu_); // shared/read lock auto it = data_.find(key); return it != data_.end() ? std::optional(it->second) : std::nullopt; } void Set(const std::string& key, std::string value) { absl::MutexLock lock(&mu_); // exclusive/write lock data_[key] = std::move(value); } private: absl::Mutex mu_; std::map data_ ABSL_GUARDED_BY(mu_); }; ``` -------------------------------- ### Abseil flat_hash_map and flat_hash_set Usage Source: https://context7.com/abseil/abseil-cpp/llms.txt Use `absl::flat_hash_map` and `absl::flat_hash_set` for high-performance unordered associative containers that offer improved cache locality. They support heterogeneous lookup and use `absl::Hash` by default. Custom hashers can be provided for user-defined types. ```cpp #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" // Basic usage — mirrors std::unordered_map API absl::flat_hash_map word_count; for (const auto& word : words) { ++word_count[word]; } // Heterogeneous lookup — find with string_view without allocating std::string absl::flat_hash_map m = {{"hello", 1}, {"world", 2}}; auto it = m.find(absl::string_view("hello")); // no allocation if (it != m.end()) std::cout << it->second; // 1 // try_emplace and insert_or_assign auto [iter, inserted] = m.try_emplace("new_key", 99); // flat_hash_set absl::flat_hash_set seen; std::vector deduped; for (int x : data) { if (seen.insert(x).second) deduped.push_back(x); } // Custom hash for user types struct MyKey { int id; std::string name; }; struct MyKeyHash { using is_transparent = void; // enable heterogeneous lookup size_t operator()(const MyKey& k) const { return absl::HashOf(k.id, k.name); } }; ``` -------------------------------- ### absl::Substitute: Positional string substitution Source: https://context7.com/abseil/abseil-cpp/llms.txt Use `absl::Substitute` for simple positional string replacement using `$0`, `$1`, etc. placeholders. It supports built-in types and `AbslStringify`-enabled custom types. An append variant is also available. ```cpp #include "absl/strings/substitute.h" // Positional arguments — $0 is first arg, $1 is second, etc. std::string s = absl::Substitute("$1 purchased $0 $2 for $$10. Thanks $1!", 5, "Bob", "Apples"); // s == "Bob purchased 5 Apples for $10. Thanks Bob!" ``` ```cpp // Append variant std::string msg = "Status: "; absl::SubstituteAndAppend(&msg, "user=$0 code=$1", "alice", 200); // msg == "Status: user=alice code=200" ``` ```cpp // Bool and pointer support bool ok = true; void* ptr = nullptr; std::string s2 = absl::Substitute("ok=$0 ptr=$1", ok, ptr); // s2 == "ok=true ptr=NULL" ``` -------------------------------- ### Timed Lock Attempt with absl::Mutex Source: https://context7.com/abseil/abseil-cpp/llms.txt Use `absl::Mutex::LockWhenWithTimeout` to attempt acquiring a mutex lock for a specified duration, returning true if successful within the timeout. ```cpp #include "absl/synchronization/mutex.h" #include "absl/time/time.h" absl::Mutex mu; if (mu.LockWhenWithTimeout(absl::Condition::kTrue, absl::Milliseconds(100))) { // acquired within 100ms mu.Unlock(); } ``` -------------------------------- ### Abseil Flags for Type-Safe Command-Line Arguments Source: https://context7.com/abseil/abseil-cpp/llms.txt Defines and accesses type-safe command-line flags using ABSL_FLAG, ABSL_DECLARE_FLAG, absl::GetFlag, and absl::SetFlag. Requires "absl/flags/declare.h", "absl/flags/flag.h", "absl/flags/parse.h", and "absl/flags/usage.h". ```cpp // === my_app.h === #include "absl/flags/declare.h" ABSL_DECLARE_FLAG(int, port); ABSL_DECLARE_FLAG(std::string, host); ABSL_DECLARE_FLAG(bool, verbose); // === my_app.cc === #include "absl/flags/flag.h" #include "absl/flags/parse.h" #include "absl/flags/usage.h" ABSL_FLAG(int, port, 8080, "Port number to listen on"); ABSL_FLAG(std::string, host, "localhost", "Hostname or IP address"); ABSL_FLAG(bool, verbose, false, "Enable verbose output"); int main(int argc, char** argv) { absl::SetProgramUsageMessage("Usage: my_app [options]"); absl::ParseCommandLine(argc, argv); int port = absl::GetFlag(FLAGS_port); std::string host = absl::GetFlag(FLAGS_host); bool verbose = absl::GetFlag(FLAGS_verbose); LOG(INFO) << "Listening on " << host << ":" << port; // Programmatic override absl::SetFlag(&FLAGS_port, 9090); return 0; } // Run as: ./my_app --port=443 --host=example.com --verbose ``` -------------------------------- ### Abseil btree_map and btree_set Usage Source: https://context7.com/abseil/abseil-cpp/llms.txt Employ `absl::btree_map` and `absl::btree_set` for sorted associative containers that provide better cache performance than `std::map` due to their B-tree node structure. Iterators support arithmetic operations, and `equal_range` is available for multimaps. ```cpp #include "absl/container/btree_map.h" #include "absl/container/btree_set.h" // Drop-in for std::map with better cache performance absl::btree_map scores; scores.emplace("Alice", 95); scores.emplace("Bob", 87); scores.emplace("Charlie", 91); // Range iteration (sorted order) for (const auto& [name, score] : scores) { std::cout << name << ": " << score << "\n"; } // Random access via iterator arithmetic (unique to btree) auto it = scores.begin(); it += 2; // jump directly to 3rd element // lower_bound / upper_bound for range queries auto lo = scores.lower_bound("B"); auto hi = scores.upper_bound("C"); // iterates "Bob" and "Charlie" // btree_multimap for duplicate keys absl::btree_multimap multi; multi.emplace(1, "one"); multi.emplace(1, "uno"); auto range = multi.equal_range(1); ``` -------------------------------- ### Avoid Per-Target C++ Standard Flags Source: https://github.com/abseil/abseil-cpp/blob/master/FAQ.md Applying C++ standard flags like -std=c++17 to individual targets can lead to ABI incompatibilities and ODR violations. Ensure consistent C++ standard settings across your entire build. ```bazel cc_library( name = "my_library", srcs = ["my_library.cc"], copts = ["-std=c++17"], # May create a mixed-mode compile! deps = ["@com_google_absl//absl/strings"], ) ``` -------------------------------- ### Flexible String Splitting with absl::StrSplit Source: https://context7.com/abseil/abseil-cpp/llms.txt Use absl::StrSplit for flexible string splitting with various delimiters and filtering options. It returns a lazy range convertible to STL containers. Options like SkipEmpty and MaxSplits can modify the splitting behavior. ```cpp #include "absl/strings/str_split.h" // Split into a vector by character std::vector v = absl::StrSplit("a,b,c,d", ','); // v == {"a", "b", "c", "d"} // Skip empty tokens std::vector v2 = absl::StrSplit(",a,,b,", ',', absl::SkipEmpty()); // v2 == {"a", "b"} // Split by any of several delimiters std::vector v3 = absl::StrSplit("a,b=c;d", absl::ByAnyChar(",=;")); // v3 == {"a", "b", "c", "d"} // Limit the number of splits std::vector v4 = absl::StrSplit("a:b:c:d", absl::MaxSplits(':', 2)); // v4 == {"a", "b", "c:d"} // Split into a std::set (automatic deduplication + sorted) std::set s = absl::StrSplit("c,a,b,a,c", ','); // s == {"a", "b", "c"} // Split into a map (alternating key/value pairs) std::map m = absl::StrSplit("k1=v1,k2=v2", ','); // (each comma-separated token is split again for key=value) // Split by whitespace, skipping empty std::vector words = absl::StrSplit( " hello world ", absl::ByAsciiWhitespace(), absl::SkipEmpty()); // words == {"hello", "world"} // Fixed-length chunks std::vector chunks = absl::StrSplit("abcdefgh", absl::ByLength(3)); // chunks == {"abc", "def", "gh"} // Parsing key=value pairs robustly std::map kv; for (absl::string_view pair : absl::StrSplit("a=1,b=2,c=3", ',')) { kv.insert(absl::StrSplit(pair, absl::MaxSplits('=', 1))); } // kv == {{"a","1"}, {"b","2"}, {"c","3"}} ``` -------------------------------- ### absl::Substitute Source: https://context7.com/abseil/abseil-cpp/llms.txt Performs positional substitution using $0–$9 placeholders without requiring type specifiers. Simpler than StrFormat when format control is not needed. ```APIDOC ## absl::Substitute — Positional string substitution ### Description `absl::Substitute` performs positional substitution using `$0`–`$9` placeholders without requiring type specifiers. It is simpler than `StrFormat` when format control is not needed and supports the same built-in types plus `AbslStringify`-enabled custom types. ### Usage Examples ```cpp #include "absl/strings/substitute.h" // Positional arguments — $0 is first arg, $1 is second, etc. std::string s = absl::Substitute("$1 purchased $0 $2 for $$10. Thanks $1!", 5, "Bob", "Apples"); // s == "Bob purchased 5 Apples for $10. Thanks Bob!" // Append variant std::string msg = "Status: "; absl::SubstituteAndAppend(&msg, "user=$0 code=$1", "alice", 200); // msg == "Status: user=alice code=200" // Bool and pointer support bool ok = true; void* ptr = nullptr; std::string s2 = absl::Substitute("ok=$0 ptr=$1", ok, ptr); // s2 == "ok=true ptr=NULL" ``` ``` -------------------------------- ### Abseil PCHECK for File Operation Assertions Source: https://context7.com/abseil/abseil-cpp/llms.txt Use `PCHECK` for assertions on system calls that can fail due to system errors; it automatically appends the `errno` description to the log message. ```cpp #include "absl/log/check.h" // PCHECK — appends errno description on failure int fd = open("/tmp/data", O_RDONLY); PCHECK(fd != -1) << "Failed to open file"; ``` -------------------------------- ### absl::StrCat Source: https://context7.com/abseil/abseil-cpp/llms.txt Efficiently concatenates any number of strings, string views, and other types into a single std::string without intermediate allocations. Supports custom type formatting via AbslStringify. ```APIDOC ## absl::StrCat — Efficient string concatenation ### Description `absl::StrCat` merges any number of strings, string views, integers, floats, bools, and hex/decimal-formatted numbers into a single `std::string` without intermediate allocations. The `AlphaNum` type handles type conversion automatically. Use `absl::StrAppend` to append to an existing string instead of reassigning. ### Usage Examples ```cpp #include "absl/strings/str_cat.h" // Basic concatenation of mixed types std::string name = "Alice"; int age = 30; double score = 98.6; std::string result = absl::StrCat("Name: ", name, ", Age: ", age, ", Score: ", score); // result == "Name: Alice, Age: 30, Score: 98.6" // Hex formatting with zero-padding uint32_t addr = 0xDEADBEEF; std::string hex = absl::StrCat("Address: 0x", absl::Hex(addr, absl::kZeroPad8)); // hex == "Address: 0xdeadbeef" // Appending to an existing string (preferred over str = StrCat(str, ...)) std::string log; absl::StrAppend(&log, "[INFO] ", "Request ", 42, " processed"); // log == "[INFO] Request 42 processed" // Custom type support via AbslStringify struct Point { int x, y; template friend void AbslStringify(Sink& sink, const Point& p) { absl::Format(&sink, "(%v, %v)", p.x, p.y); } }; Point pt{3, 4}; std::string s = absl::StrCat("Point: ", pt); // s == "Point: (3, 4)" // High-precision float round-trip double pi = 3.141592653589793; std::string precise = absl::StrCat(absl::HighPrecision(pi)); // precise produces a string that converts back to the exact same double ``` ```