1 // Copyright 2015, Tobias Hermann and the FunctionalPlus contributors. 2 // https://github.com/Dobiasd/FunctionalPlus 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 #include <doctest/doctest.h> 8 #include <fplus/fplus.hpp> 9 10 namespace { 11 std::string print_output; 12 print_int(int x)13 bool print_int(int x) 14 { 15 print_output = "int " + std::to_string(x); 16 return true; 17 } 18 print_double(double x)19 bool print_double(double x) 20 { 21 print_output = "double " + std::to_string(fplus::round(x)); 22 return true; 23 } 24 print_string(const std::string & str)25 bool print_string(const std::string& str) 26 { 27 print_output = "string " + str; 28 return true; 29 } 30 show_int(int x)31 std::string show_int(int x) 32 { 33 return fplus::show(x); 34 } 35 show_string(const std::string & str)36 std::string show_string(const std::string& str) 37 { 38 return fplus::show(str); 39 } 40 } 41 42 TEST_CASE("variant_test - visit_one") 43 { 44 using namespace fplus; 45 46 fplus::variant<int, double> int_or_double(3); 47 48 int_or_double.visit_one(print_int); 49 REQUIRE_EQ(print_output, "int 3"); 50 print_output.clear(); 51 52 int_or_double.visit_one(print_double); 53 REQUIRE_EQ(print_output, ""); 54 print_output.clear(); 55 56 int_or_double = 23.0; 57 58 int_or_double.visit_one(print_int); 59 REQUIRE_EQ(print_output, ""); 60 print_output.clear(); 61 62 int_or_double.visit_one(print_double); 63 REQUIRE_EQ(print_output, "double 23"); 64 print_output.clear(); 65 66 67 using float_or_double = fplus::variant<float, double>; 68 using nested = fplus::variant<int, float_or_double>; 69 nested int_or_float_double_variant(fplus::variant<float, double>(3.0)); 70 71 const auto print_nested_double = [&](const float_or_double& f_o_d) -> int __anon171960ca0202(const float_or_double& f_o_d) 72 { 73 f_o_d.visit_one(print_double); 74 return 0; 75 }; 76 77 int_or_float_double_variant.visit_one(print_nested_double); 78 REQUIRE_EQ(print_output, "double 3"); 79 print_output.clear(); 80 } 81 82 TEST_CASE("variant_test - equality_test") 83 { 84 using namespace fplus; 85 fplus::variant<int, std::string> int_or_string_i(3); 86 fplus::variant<int, std::string> int_or_string_s(std::string("hi")); 87 REQUIRE(int_or_string_i == int_or_string_i); 88 REQUIRE_FALSE(int_or_string_i == int_or_string_s); 89 } 90 91 TEST_CASE("variant_test - inequality_test") 92 { 93 using namespace fplus; 94 fplus::variant<int, std::string> int_or_string_i(3); 95 fplus::variant<int, std::string> int_or_string_s(std::string("hi")); 96 REQUIRE_FALSE(int_or_string_i != int_or_string_i); 97 REQUIRE(int_or_string_i != int_or_string_s); 98 } 99 100 TEST_CASE("variant_test - visit") 101 { 102 using namespace fplus; 103 104 // should not compile 105 //int_or_double.visit_one<std::string>(print_string); 106 107 fplus::variant<int, std::string> int_or_string(3); 108 109 REQUIRE(int_or_string.is<int>()); 110 REQUIRE_FALSE(int_or_string.is<std::string>()); 111 112 int_or_string.visit(print_int, print_string); 113 REQUIRE_EQ(print_output, "int 3"); 114 print_output.clear(); 115 116 const auto transform_result = 117 int_or_string.transform(show_int, show_string); 118 transform_result.visit_one(print_string); 119 REQUIRE_EQ(print_output, "string 3"); 120 print_output.clear(); 121 122 // should not compile 123 //std::cout << int_or_string.visit(show_int, show_float) << std::endl; 124 125 // should not compile 126 //std::cout << int_or_string.visit(show_int, show_int) << std::endl; 127 128 // should not compile 129 //std::cout << int_or_string.visit(show_int, show_string, show_double) << std::endl; 130 131 // should not compile 132 //std::cout << int_or_string.visit(show_int) << std::endl; 133 } 134