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<T> and accessing std::reference_wrapper<T>::type through get<T>() + update test c53422f remove boost variant header 5a2d5c5 add reference_wrapper test git-subtree-dir: third_party/variant git-subtree-split: bf485dfb59aef26f3ef2183d7c8c1111ad97062b
This commit is contained in:
		
							parent
							
								
									76674a3594
								
							
						
					
					
						commit
						e985c9714b
					
				
							
								
								
									
										14
									
								
								Jamroot
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								Jamroot
									
									
									
									
									
								
							| @ -59,3 +59,17 @@ exe unique-ptr-test | ||||
|     <cxxflags>-std=c++11 | ||||
|     <variant>release:<cxxflags>-march=native | ||||
|     ; | ||||
| 
 | ||||
| 
 | ||||
| exe reference_wrapper_test | ||||
|     : | ||||
|     test/reference_wrapper_test.cpp | ||||
|     .//system | ||||
|     .//timer | ||||
|     .//chrono | ||||
|     : | ||||
|     <include>$(BOOST_DIR)/include | ||||
|     <include>./ | ||||
|     <cxxflags>-std=c++11 | ||||
|     <variant>release:<cxxflags>-march=native | ||||
|     ; | ||||
|  | ||||
							
								
								
									
										74
									
								
								test/reference_wrapper_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								test/reference_wrapper_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,74 @@ | ||||
| #include <iostream> | ||||
| #include <vector> | ||||
| #include <thread> | ||||
| #include <string> | ||||
| #include <sstream> | ||||
| #include <utility> | ||||
| #include <type_traits> | ||||
| #include <boost/timer/timer.hpp> | ||||
| #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<point> {}; | ||||
| struct polygon : std::vector<line_string> {}; | ||||
| using variant = util::variant<std::reference_wrapper<const point>, | ||||
|                               std::reference_wrapper<const line_string>, | ||||
|                               std::reference_wrapper<const polygon>>; | ||||
| 
 | ||||
| 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 <typename T> | ||||
|     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::reference_wrapper<test::line_string const>>() << std::endl; | ||||
|     auto const& line2 = var.get<test::line_string>(); // accessing underlying type of std::reference_wrapper<T>
 | ||||
|     test::print printer; | ||||
|     printer(line2); | ||||
|     return EXIT_SUCCESS; | ||||
| } | ||||
							
								
								
									
										43
									
								
								variant.hpp
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								variant.hpp
									
									
									
									
									
								
							| @ -250,6 +250,17 @@ struct unwrapper<recursive_wrapper<T>> | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| template <typename T> | ||||
| struct unwrapper<std::reference_wrapper<T>> | ||||
| { | ||||
|     auto operator() (std::reference_wrapper<T> const& obj) const | ||||
|         -> typename std::reference_wrapper<T>::type const& | ||||
|     { | ||||
|         return obj.get(); | ||||
|     } | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| template <typename F, typename V, typename R, typename...Types> | ||||
| struct dispatcher; | ||||
| @ -660,6 +671,38 @@ public: | ||||
|             throw std::runtime_error("in get<T>()"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // get<T>() - T stored as std::reference_wrapper<T>
 | ||||
|     template <typename T, typename std::enable_if< | ||||
|                           (detail::direct_type<std::reference_wrapper<T>, Types...>::index != detail::invalid_value) | ||||
|                           >::type* = nullptr> | ||||
|     VARIANT_INLINE T& get() | ||||
|     { | ||||
|         if (type_index == detail::direct_type<std::reference_wrapper<T>, Types...>::index) | ||||
|         { | ||||
|             return (*reinterpret_cast<std::reference_wrapper<T>*>(&data)).get(); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             throw std::runtime_error("in get<T>()"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     template <typename T,typename std::enable_if< | ||||
|                          (detail::direct_type<std::reference_wrapper<T const>, Types...>::index != detail::invalid_value) | ||||
|                          >::type* = nullptr> | ||||
|     VARIANT_INLINE T const& get() const | ||||
|     { | ||||
|         if (type_index == detail::direct_type<std::reference_wrapper<T const>, Types...>::index) | ||||
|         { | ||||
|             return (*reinterpret_cast<std::reference_wrapper<T const> const*>(&data)).get(); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             throw std::runtime_error("in get<T>()"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     VARIANT_INLINE std::size_t get_type_index() const | ||||
|     { | ||||
|         return type_index; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user