From 43112c3f055fa109f20b8e8e6e50d0a016da742a Mon Sep 17 00:00:00 2001 From: Nikita Kniazev Date: Fri, 23 Feb 2024 04:40:36 +0300 Subject: [PATCH] X3: Constrain `operator>` It might be instantiated for user types inherited from classes in x3 namespace. --- .../spirit/home/x3/operator/sequence.hpp | 1 + test/x3/Jamfile | 1 + test/x3/operators_adl.cpp | 49 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 test/x3/operators_adl.cpp diff --git a/include/boost/spirit/home/x3/operator/sequence.hpp b/include/boost/spirit/home/x3/operator/sequence.hpp index 9e6e1702fc..6557827d6b 100644 --- a/include/boost/spirit/home/x3/operator/sequence.hpp +++ b/include/boost/spirit/home/x3/operator/sequence.hpp @@ -59,6 +59,7 @@ namespace boost { namespace spirit { namespace x3 template constexpr auto operator>(Left const& left, Right const& right) + -> decltype(left >> expect[right]) { return left >> expect[right]; } diff --git a/test/x3/Jamfile b/test/x3/Jamfile index f2671e6ba1..9c8e80bda3 100644 --- a/test/x3/Jamfile +++ b/test/x3/Jamfile @@ -94,6 +94,7 @@ run omit.cpp ; run optional.cpp ; run plus.cpp ; run with.cpp ; +run operators_adl.cpp ; run raw.cpp ; run real1.cpp ; diff --git a/test/x3/operators_adl.cpp b/test/x3/operators_adl.cpp new file mode 100644 index 0000000000..a93a5315bf --- /dev/null +++ b/test/x3/operators_adl.cpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2024 Nikita Kniazev + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include + +#define OP(x) \ +template \ +auto adl_checker_impl(P& p, int) -> decltype(void(x)) { \ + static_assert(sizeof(P) == 0, #x " is unconstrained"); \ +} + +template +auto adl_checker_impl(T&, long) {} + +OP(p >> p) +#if defined(_MSC_VER) && _MSC_VER >= 1910 +OP(p > p) +OP(p | p) +OP(p - p) +OP(p % p) +OP(-p) +OP(!p) +OP(*p) +OP(+p) +//OP(&p) +#endif + +template +void adl_checker(P& p) +{ + adl_checker_impl(p, 0); +} + +namespace boost { namespace spirit { namespace x3 { + struct test_base {}; +}}} + +struct not_a_parser : boost::spirit::x3::test_base {}; + +int main() +{ + not_a_parser test; + adl_checker(test); +}