mirror of https://github.com/procxx/kepka.git
				
				
				
			
		
			
				
	
	
		
			139 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| 
 | |
| #include <algorithm>
 | |
| #include <cstdint>
 | |
| #include <cstdlib>
 | |
| #include <iostream>
 | |
| #include <sstream>
 | |
| #include <string>
 | |
| #include <type_traits>
 | |
| #include <utility>
 | |
| #include <vector>
 | |
| 
 | |
| #include <mapbox/variant.hpp>
 | |
| #include <mapbox/variant_io.hpp>
 | |
| 
 | |
| using namespace mapbox;
 | |
| 
 | |
| namespace test {
 | |
| 
 | |
| template <typename T>
 | |
| struct string_to_number
 | |
| {
 | |
| };
 | |
| 
 | |
| template <>
 | |
| struct string_to_number<double>
 | |
| {
 | |
|     double operator()(std::string const& str) const
 | |
|     {
 | |
|         return std::stod(str);
 | |
|     }
 | |
| };
 | |
| 
 | |
| template <>
 | |
| struct string_to_number<std::int64_t>
 | |
| {
 | |
|     std::int64_t operator()(std::string const& str) const
 | |
|     {
 | |
|         return std::stoll(str);
 | |
|     }
 | |
| };
 | |
| 
 | |
| template <>
 | |
| struct string_to_number<std::uint64_t>
 | |
| {
 | |
|     std::uint64_t operator()(std::string const& str) const
 | |
|     {
 | |
|         return std::stoull(str);
 | |
|     }
 | |
| };
 | |
| 
 | |
| template <>
 | |
| struct string_to_number<bool>
 | |
| {
 | |
|     bool operator()(std::string const& str) const
 | |
|     {
 | |
|         bool result;
 | |
|         std::istringstream(str) >> std::boolalpha >> result;
 | |
|         return result;
 | |
|     }
 | |
| };
 | |
| 
 | |
| struct javascript_equal_visitor
 | |
| {
 | |
|     template <typename T>
 | |
|     bool operator()(T lhs, T rhs) const
 | |
|     {
 | |
|         return lhs == rhs;
 | |
|     }
 | |
| 
 | |
|     template <typename T, class = typename std::enable_if<std::is_arithmetic<T>::value>::type>
 | |
|     bool operator()(T lhs, std::string const& rhs) const
 | |
|     {
 | |
|         return lhs == string_to_number<T>()(rhs);
 | |
|     }
 | |
| 
 | |
|     template <typename T, class = typename std::enable_if<std::is_arithmetic<T>::value>::type>
 | |
|     bool operator()(std::string const& lhs, T rhs) const
 | |
|     {
 | |
|         return string_to_number<T>()(lhs) == rhs;
 | |
|     }
 | |
| 
 | |
|     template <typename T0, typename T1>
 | |
|     bool operator()(T0 lhs, T1 rhs) const
 | |
|     {
 | |
|         return lhs == static_cast<T0>(rhs);
 | |
|     }
 | |
| };
 | |
| 
 | |
| template <typename T>
 | |
| struct javascript_equal
 | |
| {
 | |
|     javascript_equal(T const& lhs)
 | |
|         : lhs_(lhs) {}
 | |
| 
 | |
|     bool operator()(T const& rhs) const
 | |
|     {
 | |
|         return util::apply_visitor(test::javascript_equal_visitor(), lhs_, rhs);
 | |
|     }
 | |
|     T const& lhs_;
 | |
| };
 | |
| 
 | |
| } // namespace test
 | |
| 
 | |
| int main()
 | |
| {
 | |
|     typedef util::variant<bool, std::int64_t, std::uint64_t, double, std::string> variant_type;
 | |
|     variant_type v0(3.14159);
 | |
|     variant_type v1(std::string("3.14159"));
 | |
|     variant_type v2(std::uint64_t(1));
 | |
| 
 | |
|     std::cerr << v0 << " == " << v1 << " -> "
 | |
|               << std::boolalpha << util::apply_visitor(test::javascript_equal_visitor(), v0, v1) << std::endl;
 | |
| 
 | |
|     std::vector<variant_type> vec;
 | |
| 
 | |
|     vec.emplace_back(std::string("1"));
 | |
|     vec.push_back(variant_type(std::uint64_t(2)));
 | |
|     vec.push_back(variant_type(std::uint64_t(3)));
 | |
|     vec.push_back(std::string("3.14159"));
 | |
|     vec.emplace_back(3.14159);
 | |
| 
 | |
|     //auto itr = std::find_if(vec.begin(), vec.end(), [&v0](variant_type const& val) {
 | |
|     //        return util::apply_visitor(test::javascript_equal_visitor(), v0, val);
 | |
|     //    });
 | |
| 
 | |
|     auto itr = std::find_if(vec.begin(), vec.end(), test::javascript_equal<variant_type>(v2));
 | |
| 
 | |
|     if (itr != std::end(vec))
 | |
|     {
 | |
|         std::cout << "found " << *itr << std::endl;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         std::cout << "can't find " << v2 << '\n';
 | |
|     }
 | |
| 
 | |
|     return EXIT_SUCCESS;
 | |
| }
 |