Line data Source code
1 : #pragma once 2 : 3 : // One of the clients of this library is Envoy, a service (HTTP) proxy. 4 : // 5 : // Envoy uses Abseil as its base C++ library, and additionally builds in C++17 6 : // mode. Abseil has a build option to forward its `std::string_view` and 7 : // `std::optional` equivalents to the actual standard types when C++17 is 8 : // available. 9 : // 10 : // Envoy does not use this Abseil build option, due to incomplete support for 11 : // the C++17 standard library on iOS 11. 12 : // 13 : // As a result, Envoy forbids use of `std::string_view` and `std::optional`, 14 : // instead preferring Abseil's `absl::string_view` and `absl::optional`. 15 : // 16 : // This presents a problem for this library, since we use `std::string_view` 17 : // and `std::optional` in the exported interface, i.e. in header files. 18 : // 19 : // As a workaround, Bazel (the build tool used by Envoy) builds of this library 20 : // will define the `DD_USE_ABSEIL_FOR_ENVOY` preprocessor macro. When this 21 : // macro is defined, the library-specific `StringView` and `Optional` aliases 22 : // will refer to the Abseil types. When the macro is not defined, the 23 : // library-specific aliases will refer to the standard types. 24 : // 25 : // This file defines `datadog::tracing::Optional`, a type template that is an 26 : // alias for either `std::optional` or `absl::optional`. 27 : 28 : #ifdef DD_USE_ABSEIL_FOR_ENVOY 29 : // Abseil examples, including usage in Envoy, include Abseil headers in quoted 30 : // style instead of angle bracket style, per Bazel's default build behavior. 31 : #include "absl/types/optional.h" 32 : #else 33 : #include <optional> 34 : #endif // defined DD_USE_ABSEIL_FOR_ENVOY 35 : 36 : #include <utility> // std::forward 37 : 38 : namespace datadog { 39 : namespace tracing { 40 : 41 : #ifdef DD_USE_ABSEIL_FOR_ENVOY 42 : template <typename Value> 43 : using Optional = absl::optional<Value>; 44 : inline constexpr auto nullopt = absl::nullopt; 45 : #else 46 : template <typename Value> 47 : using Optional = std::optional<Value>; 48 : inline constexpr auto nullopt = std::nullopt; 49 : #endif // defined DD_USE_ABSEIL_FOR_ENVOY 50 : 51 : // Return the first non-null argument value. The last argument must not be 52 : // `Optional`. 53 : template <typename Value> 54 1429 : auto value_or(Value&& value) { 55 1429 : return std::forward<Value>(value); 56 : } 57 : 58 : template <typename Value, typename... Rest> 59 4287 : auto value_or(Optional<Value> maybe, Rest&&... rest) { 60 4287 : return maybe.value_or(value_or(std::forward<Rest>(rest)...)); 61 : } 62 : 63 : } // namespace tracing 64 : } // namespace datadog