// Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 #pragma once #include "opentelemetry/version.h" #include #include #include #include OPENTELEMETRY_BEGIN_NAMESPACE // Standard Type aliases in nostd namespace namespace nostd { using std::get_if; using std::monostate; using std::variant_alternative_t; // nostd::variant<...> template using variant = std::variant<_Types...>; template using variant_size = std::variant_size<_Types...>; using monostate = std::monostate; #if defined(__APPLE__) && defined(_LIBCPP_USE_AVAILABILITY_APPLE) // Apple Platforms provide std::bad_variant_access only in newer versions of OS. // To keep API compatible with any version of OS - we are providing our own // implementation of nostd::bad_variant_access exception. # if __EXCEPTIONS // nostd::bad_variant_access class bad_variant_access : public std::exception { public: virtual const char *what() const noexcept override { return "bad_variant_access"; } }; [[noreturn]] inline void throw_bad_variant_access() { throw bad_variant_access{}; } # endif # if __EXCEPTIONS # define THROW_BAD_VARIANT_ACCESS throw_bad_variant_access() # else # define THROW_BAD_VARIANT_ACCESS std::terminate() # endif // // nostd::get<...> for Apple Clang // template constexpr auto get_type = [](auto &&t) constexpr -> decltype(auto) { auto v = t; auto result = std::get_if(&v); // TODO: optimize with std::forward(t) if t is not rvalue if (result) { return *result; } THROW_BAD_VARIANT_ACCESS; return *result; }; template constexpr auto get_index = [](auto &&t) constexpr -> decltype(auto) { auto v = t; auto result = std::get_if(&v); // TODO: optimize with std::forward(t) if t is not rvalue if (result) { return *result; } THROW_BAD_VARIANT_ACCESS; return *result; }; template constexpr std::variant_alternative_t> &get(std::variant &v) { return get_index(v); }; template constexpr std::variant_alternative_t> &&get(std::variant &&v) { return get_index(std::forward(v)); }; template constexpr const std::variant_alternative_t> &get( const std::variant &v) { return get_index(v); }; template constexpr const std::variant_alternative_t> &&get( const std::variant &&v) { return get_index(std::forward(v)); }; template constexpr T &get(std::variant &v) { return get_type(v); }; template constexpr T /*&&*/ get(std::variant &&v) { return get_type(v); }; template constexpr const T &get(const std::variant &v) { return get_type(v); }; template constexpr const T &&get(const std::variant &&v) { return get_type(std::forward(v)); }; template constexpr auto visit(_Callable &&_Obj, _Variants &&... _Args) { // Ref: // https://stackoverflow.com/questions/52310835/xcode-10-call-to-unavailable-function-stdvisit return std::__variant_detail::__visitation::__variant::__visit_value(_Obj, _Args...); }; #else using std::bad_variant_access; template constexpr std::variant_alternative_t> &get(std::variant &v) { return std::get(v); }; template constexpr std::variant_alternative_t> &&get(std::variant &&v) { return std::get(std::forward(v)); }; template constexpr const std::variant_alternative_t> &get( const std::variant &v) { return std::get(v); }; template constexpr const std::variant_alternative_t> &&get( const std::variant &&v) { return std::get(std::forward(v)); }; template constexpr T &get(std::variant &v) { return std::get(v); }; template constexpr T &&get(std::variant &&v) { return std::get(std::forward(v)); }; template constexpr const T &get(const std::variant &v) { return std::get(v); }; template constexpr const T &&get(const std::variant &&v) { return std::get(std::forward(v)); }; template constexpr auto visit(_Callable &&_Obj, _Variants &&... _Args) { return std::visit<_Callable, _Variants...>(static_cast<_Callable &&>(_Obj), static_cast<_Variants &&>(_Args)...); }; #endif /* # if _HAS_CXX20 template constexpr _Ret visit(_Callable &&_Obj, _Variants &&... _Args) { return std::visit<_Ret, _Callable, _Variants...>( static_cast<_Callable &&>(_Obj), static_cast<_Variants &&>(_Args)...); }; # endif */ // nostd::holds_alternative template inline constexpr bool holds_alternative(const variant &v) noexcept { return v.index() == I; } template inline constexpr bool holds_alternative(const variant &v) noexcept { return std::holds_alternative(v); } } // namespace nostd OPENTELEMETRY_END_NAMESPACE