-
Notifications
You must be signed in to change notification settings - Fork 48
Description
Description
We are using variant-lite in a project alongside tl::optional and other header-only C++11+ compatibility libraries. To provide a unified interface for downstream users, we expose them under a std_compat namespace:
namespace std_compat
{
template <class T>
using optional = tl::optional<T>;
using tl::bad_optional_access;
using tl::in_place_t;
using tl::in_place;
using tl::nullopt;
using tl::nullopt_t;
using tl::make_optional;
using tl::swap;
}namespace std_compat
{
template <class... Types>
using variant = nonstd::variant<Types...>;
using nonstd::bad_variant_access;
using nonstd::get;
using nonstd::get_if;
using nonstd::holds_alternative;
using nonstd::visit;
using nonstd::variant_npos;
using nonstd::variant_size;
using nonstd::variant_size_v;
using nonstd::variant_alternative;
using nonstd::variant_alternative_t;
}Problem
-
monostateconflicts:
Bothtl::optionaland variant-lite require a monostate type.
On MSVC 17.10.35122 (with C++17 enabled), the CRT also providesstd::monostate.
This results in three differentmonostatedefinitions that are not interchangeable, causing compilation errors when the libraries are used together. -
bad_variant_accessmismatch:
The MSVC CRT providesstd::bad_variant_access.
variant-lite uses its ownnonstd::bad_variant_access.
Third-party code using ourstd_compat::variantmust catch both exceptions to be safe, which is error-prone and unintuitive.
Proposed solution:
Add configuration macros to variant-lite to allow users to override the monostate and bad_variant_access implementations with their own (or the standard library’s) versions.
For example:
#ifdef variant_CONFIG_BAD_VARIANT_ACCESS
using variant_CONFIG_BAD_VARIANT_ACCESS;
#else
class variant_nodiscard bad_variant_access : public ::std::exception
{
public:
#if variant_CPP11_OR_GREATER
virtual const char* what() const variant_noexcept variant_override
#else
virtual const char* what() const throw()
#endif
{
return "bad variant access";
}
};
#endif#ifdef variant_CONFIG_MONOSTATE
using variant_CONFIG_MONOSTATE;
#else
class monostate {};
struct in_place_t {
explicit in_place_t() = default;
};
static constexpr in_place_t in_place{};
#endifBenefits:
- Avoids duplicate/conflicting type definitions when integrating with other compatibility libraries.
- Allows seamless use of the standard library’s
monostateandbad_variant_accesswhen available. - Reduces exception-handling boilerplate for downstream users.
- Keeps variant-lite flexible without breaking existing behavior.
If this approach does not conflict with any existing design decisions or constraints in variant-lite, I’m happy to prepare and submit the implementation as a PR.