diff --git a/include/boost/parser/parser.hpp b/include/boost/parser/parser.hpp index 1c5585f3..8bee8ce0 100644 --- a/include/boost/parser/parser.hpp +++ b/include/boost/parser/parser.hpp @@ -1193,9 +1193,14 @@ namespace boost { namespace parser { constexpr bool is_range = is_detected_v && is_detected_v; +#if BOOST_PARSER_USE_CONCEPTS + template + concept has_push_back = requires(T & t) { t.push_back(*t.begin()); }; +#else template - using has_push_back = - decltype(std::declval().push_back(*std::declval().begin())); + using has_push_back = decltype( + std::declval().push_back(*std::declval().begin())); +#endif #if BOOST_PARSER_USE_CONCEPTS @@ -1457,7 +1462,11 @@ namespace boost { namespace parser { template void insert(Container & c, T && x) { +#if BOOST_PARSER_USE_CONCEPTS + if constexpr (has_push_back) { +#else if constexpr (is_detected_v) { +#endif c.push_back((T &&) x); } else { c.insert((T &&) x); diff --git a/test/compile_attribute.cpp b/test/compile_attribute.cpp index 1e9e0ac9..b114f58c 100644 --- a/test/compile_attribute.cpp +++ b/test/compile_attribute.cpp @@ -8,6 +8,48 @@ using namespace boost::parser; +#if defined(__cpp_explicit_this_parameter) +# define BOOST_PARSER_TEST_EXPLICIT_THIS 1 +#elif defined(__clang__) +# if __has_extension(cxx_explicit_this_parameter) +# define BOOST_PARSER_TEST_EXPLICIT_THIS 1 +# endif +#endif + +#if defined(BOOST_PARSER_TEST_EXPLICIT_THIS) +struct explicit_object_parameter_container +{ + using iterator = int *; + + iterator begin(this explicit_object_parameter_container & self) + { + return self.values_; + } + iterator end(this explicit_object_parameter_container & self) + { + return self.values_ + self.size_; + } + iterator insert(iterator pos, int value) + { + *pos = value; + return pos; + } + void push_back(this explicit_object_parameter_container & self, int value) + { + self.values_[self.size_++] = value; + } + + int values_[4] = {}; + int size_ = 0; +}; + +void compile_explicit_object_parameter_container() +{ + explicit_object_parameter_container result; + parse("1 2", +int_, ws, result); +} +#endif + void compile_attribute_non_unicode() { // range @@ -985,6 +1027,9 @@ void compile_attribute_sentinel() void compile_attribute() { +#if defined(BOOST_PARSER_TEST_EXPLICIT_THIS) + compile_explicit_object_parameter_container(); +#endif compile_attribute_non_unicode(); compile_attribute_unicode_utf8(); compile_attribute_unicode_utf32();