From b36014f326ad61ac0ffb74cd7bb8d31c53fe59b8 Mon Sep 17 00:00:00 2001 From: Martin Moene Date: Thu, 30 Jan 2025 14:24:56 +0100 Subject: [PATCH] Mark bad_variant_access as [[nodiscard]] (default), control via variant_CONFIG_NO_NODISCARD (nonstd-lite-project issue 74) Add configuration option `variant_CONFIG_NO_NODISCARD`. https://github.com/martinmoene/nonstd-lite-project/issues/74 --- README.md | 7 ++++++- include/nonstd/variant.hpp | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 98c0e71..8386ae5 100644 --- a/README.md +++ b/README.md @@ -212,7 +212,7 @@ Define this macro to override the auto-detection of the supported C++ standard, At default, *variant lite* uses `std::variant` if it is available and lets you use it via namespace `nonstd`. You can however override this default and explicitly request to use `std::variant` or variant lite's `nonstd::variant` as `nonstd::variant` via the following macros. -\-Dvariant\_CONFIG\_SELECT\_VARIANT=variant_VARIANT_DEFAULT +-Dvariant\_CONFIG\_SELECT\_VARIANT=variant_VARIANT_DEFAULT Define this to `variant_VARIANT_STD` to select `std::variant` as `nonstd::variant`. Define this to `variant_VARIANT_NONSTD` to select `nonstd::variant` as `nonstd::variant`. Default is undefined, which has the same effect as defining to `variant_VARIANT_DEFAULT`. #### Disable exceptions @@ -220,6 +220,11 @@ Define this to `variant_VARIANT_STD` to select `std::variant` as `nonstd::varian -Dvariant_CONFIG_NO_EXCEPTIONS=0 Define this to 1 if you want to compile without exceptions. If not defined, the header tries and detect if exceptions have been disabled (e.g. via `-fno-exceptions`). Default is undefined. +#### Disable \[\[nodiscard\]\] + +-Dvariant\_CONFIG\_NO\_NODISCARD=0 +Define this to 1 if you want to compile without \[\[nodiscard\]\]. Note that the default of marking `class bad_variant_access` with \[\[nodiscard\]\] is not part of the C++17 standard. The rationale to use \[\[nodiscard\]\] is that unnoticed discarded access error values may break the error handling flow. + #### Presence of `variant_size_V()` simulation macro \-Dvariant\_CONFIG\_OMIT\_VARIANT\_SIZE\_V\_MACRO=0 diff --git a/include/nonstd/variant.hpp b/include/nonstd/variant.hpp index d1fc7da..89dc959 100644 --- a/include/nonstd/variant.hpp +++ b/include/nonstd/variant.hpp @@ -47,6 +47,14 @@ # define variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO 0 #endif +// Control marking class bad_variant_access with [[nodiscard]]]: + +#if !defined(variant_CONFIG_NO_NODISCARD) +# define variant_CONFIG_NO_NODISCARD 0 +#else +# define variant_CONFIG_NO_NODISCARD 1 +#endif + // Control presence of exception handling (try and auto discover): #ifndef variant_CONFIG_NO_EXCEPTIONS @@ -364,7 +372,7 @@ namespace nonstd { // Presence of C++17 language features: -// no flag +#define variant_HAVE_NODISCARD variant_CPP17_000 // Presence of C++ library features: @@ -404,6 +412,12 @@ namespace nonstd { # define variant_nullptr NULL #endif +#if variant_HAVE_NODISCARD && !variant_CONFIG_NO_NODISCARD +# define variant_nodiscard [[nodiscard]] +#else +# define variant_nodiscard /*[[nodiscard]]*/ +#endif + #if variant_HAVE_OVERRIDE # define variant_override override #else @@ -1266,7 +1280,7 @@ static const std::size_t variant_npos = static_cast( -1 ); // 19.7.11 Class bad_variant_access -class bad_variant_access : public std::exception +class variant_nodiscard bad_variant_access : public std::exception { public: #if variant_CPP11_OR_GREATER