-
Notifications
You must be signed in to change notification settings - Fork 29
Add the ability to use external definitions for monostate and bad variant access #55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Introduced variant_CONFIG_MONOSTATE that users can set its value if they want variant-lite to use it instead of its own monostate class
Introduced variant_CONFIG_BAD_VARIANT_ACCESS that users can set its value if they want variant-lite to use it instead of its own bad_variant_access class
|
Note: continuation of optional-lite issue 82. |
|
@martinmoene |
|
Observations: MSVC VS2019, VS2022 do work locally using: It's not clear to me what difference there is with GitHub Actions VS2022 that result in the latter to error on compilation. Macros I'll continue later as to 'not disprove' the viability of the concept to myself. |
Added `variant_CONFIG_BAD_VARIANT_ACCESS` and `variant_CONFIG_MONOSTATE` to the Synopsis: Configuration macros section
I'm using VS2022 locally and i tried to run the tests the same way you mentioned and it is actually failing. specifically this is the error that i'm getting I can take a deeper look into this later if you want, for now i will just leave the full error message that i'm getting from MSVC here because for some reason it's more readable and way shorter than the one from the CI/CD pipeline If someone is already working on fixing this CI/CD issue then maybe i can help them since i can replicate the issue on my machine. |
|
You're right. Apparently I've been working on it without finishing. Locally I have changes adding It has been a long time since actively working on the -lite projects. Another thing that resurfaced (issue #54, PR #55), is that So the first thing I'm going to do is to correct this and create a sound base to work from. |
…s-for-monostate-and-bad_variant_access
|
My proofing sofar: // main.cpp
// mix C++17 std::monostate and std::bad_variant_access with nonstd::variant with configurable such types.
#define variant_CONFIG_SELECT_VARIANT variant_VARIANT_NONSTD
#define variant_CONFIG_MONOSTATE std::monostate
#define variant_CONFIG_BAD_VARIANT_ACCESS std::bad_variant_access
#include <iostream>
#include <string>
#include <utility> // std::monostate
#include <optional>
#include <variant>
#include "nonstd/variant.hpp"
namespace std_compat
{
using std::monostate;
using std::bad_variant_access;
}
namespace std_compat
{
template <class T>
using optional = std::optional<T>;
using std::bad_optional_access;
using std::in_place_t;
using std::in_place;
using std::nullopt;
using std::nullopt_t;
using std::make_optional;
using std::swap;
}
namespace std_compat
{
template <class... Types>
using variant = nonstd::variant<Types...>;
// using nonstd::bad_variant_access;
// using nonstd::monostate;
using nonstd::in_place_type_t;
using nonstd::in_place_type;
using nonstd::in_place_index_t;
using nonstd::in_place_index;
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;
}
int main()
{
// using namespace std_compat;
// use namespace std_compat explicitly, as to avoid 'invisible' parameter type-dependent (Koenig) lookup
auto opt = std_compat::optional<std::string>(std_compat::in_place, std::string("std::optional") );
auto var = std_compat::variant<int, std::string>(std_compat::in_place_type<std::string>, std::string("std::optional") );
try
{
auto result = std_compat::get<int>(var);
}
catch( std_compat::bad_variant_access const & e )
{
std::cout << "std_compat::bad_variant_access: '" << e.what() << "'";
}
}
// cl -nologo -EHsc -std:c++17 -I../../variant-lite/include main.cpp && main.exe
// g++ -std=c++17 -Wall -I../../variant-lite/include main.cpp -o main.exe && main.exe
#ifdef MSVC_OUTPUT
CMD> cl -nologo -EHsc -std:c++17 -I../../variant-lite/include -Dvariant_CONFIG_SELECT_VARIANT=variant_VARIANT_NONSTD main.cpp && main.exe
main.cpp
../../variant-lite/include\nonstd/variant.hpp(2723): error C2766: explicit specialization; 'std::hash<std::monostate>' has already been defined
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\variant(1706): note: see previous definition of 'std::hash<std::monostate>'
#endif
#ifdef GCC_OUTPUT
CMD> g++ -std=c++17 -Wall -I../../variant-lite/include main.cpp -o main.exe && main.exe
In file included from main.cpp:12:
../../variant-lite/include/nonstd/variant.hpp:2723:8: error: redefinition of 'struct std::hash<std::monostate>'
2723 | struct hash< nonstd::monostate >
| ^~~~~~~~~~~~~~~~~~~~~~~~~
In file included from main.cpp:11:
c:\mingw\include\c++\11.2.0\variant:1829:12: note: previous definition of 'struct std::hash<std::monostate>'
1829 | struct hash<monostate>
| ^~~~~~~~~~~~~~~
main.cpp: In function 'int main()':
main.cpp:67:14: warning: unused variable 'result' [-Wunused-variable]
67 | auto result = std_compat::get<int>(var);
| ^~~~~~
#endif |
|
@MostafaNanticock , Thanks for your contribution & efforts. |
|
@martinmoene // main.cpp
// mix C++17 std::monostate and std::bad_variant_access with nonstd::variant with configurable such types.
#define variant_CONFIG_SELECT_VARIANT variant_VARIANT_NONSTD
#define variant_CONFIG_MONOSTATE std::monostate
#define variant_CONFIG_BAD_VARIANT_ACCESS std::bad_variant_access
#include <iostream>
#include <string>
#include <utility> // std::monostate
#include <optional>
#include <variant>
#include "nonstd/variant.hpp"
namespace std_compat
{
using std::monostate;
using std::bad_variant_access;
}
namespace std_compat
{
template <class T>
using optional = std::optional<T>;
using std::bad_optional_access;
using std::in_place_t;
using std::in_place;
using std::nullopt;
using std::nullopt_t;
using std::make_optional;
using std::swap;
}
namespace std_compat
{
template <class... Types>
using variant = nonstd::variant<Types...>;
// using nonstd::bad_variant_access;
// using nonstd::monostate;
using nonstd::in_place_type_t;
using nonstd::in_place_type;
using nonstd::in_place_index_t;
using nonstd::in_place_index;
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;
}
int main()
{
// using namespace std_compat;
// use namespace std_compat explicitly, as to avoid 'invisible' parameter type-dependent (Koenig) lookup
auto opt = std_compat::optional<std::string>(std_compat::in_place, std::string("std::optional") );
auto var = std_compat::variant<int, std::string>(std_compat::in_place_type<std::string>, std::string("std::optional") );
try
{
auto result = std_compat::get<int>(var);
}
catch( std_compat::bad_variant_access const & e )
{
std::cout << "std_compat::bad_variant_access: '" << e.what() << "'";
}
}I can do that if you want |
|
@MostafaNanticock , It is indeed, thanks for mentioning it. I'll do that later today. |
…IG_OVERRIDE_MONOSTATE (PR #55)
|
@MostafaNanticock , the error you bring-up in this remark above for msvc 2022/17 using |



Description
We are using variant-lite in a project alongside
tl::optionaland other header-only C++11+ compatibility libraries. To provide a unified interface for downstream users, we expose them under astd_compatnamespace:Problem
monostateconflicts:Both
tl::optionaland variant-lite require a monostate type.On MSVC 17.10.35122 (with C++17 enabled), the CRT also provides
std::monostate.This results in three different
monostatedefinitions that are not interchangeable, causing compilation errors when the libraries are used together.bad_variant_accessmismatch:The MSVC CRT provides
std::bad_variant_access.variant-lite uses its own
nonstd::bad_variant_access.Third-party code using our
std_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
monostateandbad_variant_accessimplementations with their own (or the standard library’s) versions.For example:
Benefits:
monostateandbad_variant_accesswhen available.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.