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;
|
|
}
|