From e985c9714b14750b7ca4b067c59c1a9dc4f7e869 Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Mon, 13 Apr 2015 15:37:43 +0200 Subject: [PATCH] Squashed 'third_party/variant/' changes from 3b02ca0..bf485df bf485df Revert "pass F (functor) by ref/const ref" e031c53 Revert "pass by const ref in 'apply_const'" a3014f5 pass by const ref in 'apply_const' 2e0ce4a pass F (functor) by ref/const ref 5875195 add support for 'unwrapping' std::reference_wrapper and accessing std::reference_wrapper::type through get() + update test c53422f remove boost variant header 5a2d5c5 add reference_wrapper test git-subtree-dir: third_party/variant git-subtree-split: bf485dfb59aef26f3ef2183d7c8c1111ad97062b --- Jamroot | 14 +++++++ test/reference_wrapper_test.cpp | 74 +++++++++++++++++++++++++++++++++ variant.hpp | 43 +++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 test/reference_wrapper_test.cpp diff --git a/Jamroot b/Jamroot index abf312b9c..aead87091 100644 --- a/Jamroot +++ b/Jamroot @@ -59,3 +59,17 @@ exe unique-ptr-test -std=c++11 release:-march=native ; + + +exe reference_wrapper_test + : + test/reference_wrapper_test.cpp + .//system + .//timer + .//chrono + : + $(BOOST_DIR)/include + ./ + -std=c++11 + release:-march=native + ; diff --git a/test/reference_wrapper_test.cpp b/test/reference_wrapper_test.cpp new file mode 100644 index 000000000..2abf02784 --- /dev/null +++ b/test/reference_wrapper_test.cpp @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "variant.hpp" + +using namespace mapbox; + +namespace test { + +struct point +{ +public: + point (double x_, double y_) + : x(x_), y(y_) {} + double x; + double y; +}; + +struct line_string : std::vector {}; +struct polygon : std::vector {}; +using variant = util::variant, + std::reference_wrapper, + std::reference_wrapper>; + +struct print +{ + using result_type = void; + void operator() (point const& pt) const + { + std::cerr << "Point(" << pt.x << "," << pt.y << ")" << std::endl; + } + void operator() (line_string const& line) const + { + std::cerr << "Line("; + for (auto const& pt : line) + { + std::cerr << pt.x << " " << pt.y << ","; + } + std::cerr << ")" << std::endl; + } + template + void operator() (T const& val) const + { + std::cerr << typeid(T).name() << std::endl; + } +}; + + +} + +int main (int argc, char** argv) +{ + std::cerr << sizeof(test::polygon) << std::endl; + std::cerr << sizeof(test::variant) << std::endl; + test::point pt(123,456); + test::variant var = std::move(std::cref(pt)); + util::apply_visitor(test::print(), var); + test::line_string line; + line.push_back(pt); + line.push_back(pt); + line.push_back(test::point(999,333)); + var = std::move(std::cref(line)); + util::apply_visitor(test::print(), var); + std::cerr << "Is line (cref) ? " << var.is>() << std::endl; + auto const& line2 = var.get(); // accessing underlying type of std::reference_wrapper + test::print printer; + printer(line2); + return EXIT_SUCCESS; +} diff --git a/variant.hpp b/variant.hpp index a3cdea63a..837b162df 100644 --- a/variant.hpp +++ b/variant.hpp @@ -250,6 +250,17 @@ struct unwrapper> } }; +template +struct unwrapper> +{ + auto operator() (std::reference_wrapper const& obj) const + -> typename std::reference_wrapper::type const& + { + return obj.get(); + } + +}; + template struct dispatcher; @@ -660,6 +671,38 @@ public: throw std::runtime_error("in get()"); } } + + // get() - T stored as std::reference_wrapper + template , Types...>::index != detail::invalid_value) + >::type* = nullptr> + VARIANT_INLINE T& get() + { + if (type_index == detail::direct_type, Types...>::index) + { + return (*reinterpret_cast*>(&data)).get(); + } + else + { + throw std::runtime_error("in get()"); + } + } + + template , Types...>::index != detail::invalid_value) + >::type* = nullptr> + VARIANT_INLINE T const& get() const + { + if (type_index == detail::direct_type, Types...>::index) + { + return (*reinterpret_cast const*>(&data)).get(); + } + else + { + throw std::runtime_error("in get()"); + } + } + VARIANT_INLINE std::size_t get_type_index() const { return type_index;