Skip to content

Commit 8dee588

Browse files
committed
make apply_visitor_impl public, get rid of friend apply_visitor
allows to add noexcept annotation to apply_visitor
1 parent 55df236 commit 8dee588

File tree

2 files changed

+13
-21
lines changed

2 files changed

+13
-21
lines changed

include/strict_variant/variant.hpp

+10-18
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ class variant {
323323
*/
324324

325325
// Implementation details for apply_visitor
326-
private:
326+
// private:
327327
using dispatcher_t = detail::visitor_dispatch<detail::false_, 1 + sizeof...(Types)>;
328328

329329
#define APPLY_VISITOR_IMPL_BODY \
@@ -335,13 +335,14 @@ class variant {
335335
static auto apply_visitor_impl(Visitor && visitor,
336336
Visitable && visitable) noexcept(noexcept(APPLY_VISITOR_IMPL_BODY))
337337
-> decltype(APPLY_VISITOR_IMPL_BODY) {
338-
static_assert(std::is_same<const variant, const mpl::remove_reference_t<Visitable>>::value, "Misuse of apply_visitor_impl!");
338+
static_assert(std::is_same<const variant, const mpl::remove_reference_t<Visitable>>::value,
339+
"Misuse of apply_visitor_impl!");
339340
return APPLY_VISITOR_IMPL_BODY;
340341
}
341342

342343
#undef APPLY_VISITOR_IMPL_BODY
343344

344-
public:
345+
// public:
345346
// C++17 visit syntax
346347
template <typename V>
347348
auto visit(V && v)
@@ -364,27 +365,18 @@ class variant {
364365
-> decltype(apply_visitor_impl(std::forward<V>(v), std::move(*this))) {
365366
return apply_visitor_impl(std::forward<V>(v), std::move(*this));
366367
}
367-
368-
// Friend apply_visitor (boost::apply_visitor syntax)
369-
370-
#define APPLY_VISITOR_BODY \
371-
mpl::remove_reference_t<Visitable>::apply_visitor_impl(std::forward<Visitor>(visitor), \
372-
std::forward<Visitable>(visitable))
373-
374-
// TODO: Why doesn't noexcept annotation work here? It causes ICE in gcc and clang
375-
template <typename Visitor, typename Visitable>
376-
friend auto apply_visitor(Visitor && visitor,
377-
Visitable && visitable) /*noexcept(noexcept(APPLY_VISITOR_BODY)) */
378-
-> decltype(APPLY_VISITOR_BODY);
379368
};
380369

381370
/***
382-
* apply one visitor function. This is the basic version, used in implementation
383-
* of multivisitation.
371+
* apply one visitor function. `boost::variant` syntax.
372+
* This is the basic version, used in implementation of multivisitation.
384373
*/
374+
#define APPLY_VISITOR_BODY \
375+
mpl::remove_reference_t<Visitable>::apply_visitor_impl(std::forward<Visitor>(visitor), \
376+
std::forward<Visitable>(visitable))
385377
template <typename Visitor, typename Visitable>
386378
auto
387-
apply_visitor(Visitor && visitor, Visitable && visitable) /*noexcept(noexcept(APPLY_VISITOR_BODY))*/
379+
apply_visitor(Visitor && visitor, Visitable && visitable) noexcept(noexcept(APPLY_VISITOR_BODY))
388380
-> decltype(APPLY_VISITOR_BODY) {
389381
return APPLY_VISITOR_BODY;
390382
}

test/variant.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,11 @@ struct some_other_visitor {
229229
double operator()(float f) const noexcept(false) { return f; }
230230
};
231231

232-
// TODO: apply_visitor is not noexcept correct right now... see variant.hpp for code comment
232+
// TODO: Debug this
233233
// static_assert(noexcept(apply_visitor(some_visitor{}, std::declval<variant<int, float>>())),
234234
// "Apply visitor noexcept annotation not working!");
235-
// static_assert(!noexcept(apply_visitor(some_other_visitor{}, std::declval<variant<int,
236-
// float>>())), "Apply visitor noexcept annotation not working!");
235+
static_assert(!noexcept(apply_visitor(some_other_visitor{}, std::declval<variant<int, float>>())),
236+
"Apply visitor noexcept annotation not working!");
237237

238238
// Check that variant is resolving "ambiguous" constructions as expected
239239
UNIT_TEST(ambiguous_string) {

0 commit comments

Comments
 (0)