optional.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //#define CXXOMFORT_NOTICES 2
  2. #define CXXOFLAG_optional_specialize_fundamentals
  3. #include <cxxomfort/cxxomfort.hpp>
  4. #include <cxxomfort/optional.hpp> // this makes use of cxxo::optional below C++17
  5. #include <cxxomfort/functional.hpp>
  6. #include <cxxomfort/cstd/optional>
  7. #include <string>
  8. #include <iostream>
  9. #include <iomanip>
  10. #include <cxxomfort/library/functional.hpp> // function_ref
  11. #include <print_traits.hpp>
  12. typedef float A;
  13. typedef std::pair<int,std::string> B;
  14. typedef std::optional<float> OF;
  15. // monadic transform
  16. struct I {
  17. //int v1 = 4;
  18. //float v2 = 0.2;
  19. #if (CXXOMFORT_CXX_STD >= 2011)
  20. I () = default;
  21. I (I const&) {}
  22. I (I&&) noexcept = default;
  23. virtual ~I () {}
  24. #endif
  25. };
  26. static bool istoolong(std::string const& s) {
  27. return s.length() > 9;
  28. }
  29. template <typename T>
  30. void show_optional (std::ostream& os, std::optional<T> const& o_) {
  31. using namespace std;
  32. os<< "optional< "<< cxxomfort::library::type_name<T>()<< " > "<< flush;
  33. os<< "[ state: "<< o_.has_value() << flush;
  34. os<< " value: ";
  35. if (o_.has_value()) { os<< *o_; }
  36. else { os<< "[None]"; }
  37. os<< " ]"<< flush;
  38. }
  39. int main () {
  40. using namespace std;
  41. cxxomfort::output_info(stdout); cout<< endl;
  42. try {
  43. print_traits< optional<float> >(cout);
  44. print_traits_construction< optional<float> >(cout);
  45. cout<< endl;
  46. print_traits< optional< string > >(cout);
  47. print_traits_construction< optional< string> >(cout);
  48. cout<< endl;
  49. print_traits< optional<bool> >(cout);
  50. print_traits_construction< optional<bool> >(cout);
  51. cout<< endl;
  52. print_traits< I >(cout);
  53. print_traits_construction< I >(cout);
  54. cout<< endl;
  55. //print_traits< std::string >(cout);
  56. cout<< "optional<int> : t1: empty optional; t2: nullopt; t3: default-constructed; t4: initialized"<< endl;
  57. optional<int> t1;
  58. optional<int> t2(nullopt);
  59. optional<int> t3(std::in_place);
  60. optional<int> t4(2);
  61. cout<< "t1.has_value(): "<< t1.has_value()<< endl;
  62. cout<< "t2.has_value(): "<< t2.has_value()<< endl;
  63. cout<< "t3.has_value(): "<< t3.has_value()<< endl;
  64. cout<< "t4.has_value(): "<< t4.has_value()<< endl;
  65. t2= t4; cout<< "t2 = t4"<< endl;
  66. cout<< "t2.has_value(): "<< t2.has_value()<< endl;
  67. cout<< "\nTesting optional<float>: \n";
  68. OF of1, of2(-4.4), of3;
  69. cout<< "of1 : "; show_optional(cout, of1); cout<< endl;
  70. cout<< "of2 : "; show_optional(cout, of2); cout<< endl;
  71. cout<< "of3 : "; show_optional(cout, of3); cout<< endl;
  72. cout<< "\nTesting make_optional<...>: "<< endl;
  73. cout<< "int "<< flush<< make_optional<int>().has_value()<< endl;
  74. cout<< "long "<< flush<< make_optional<long>(-31).value_or(0)<< endl;
  75. cout<< "string "<< make_optional<string>().value_or("[empty]")<< endl;
  76. cout<< "string "<< make_optional<string>(4u, '4').value_or("[empty]")<< endl;
  77. cout<< "*"<< endl;
  78. OF foo;
  79. cout<< "foo: "<< flush<< foo.has_value()<< endl;
  80. cout<< "foo: "<< flush;
  81. if ( explicit_cast<bool>(foo) ) {
  82. cout<< *foo<< endl;
  83. } else {
  84. cout<< "(nothing)"<< endl;
  85. }
  86. optional<string> os1, os2("A"), os3("3"), os4(os1);
  87. cout<< "os2.has_value(): "<< os2.has_value()<< endl;
  88. os2=os3;
  89. cout<< "os2.has_value(): "<< os2.has_value()<< endl;
  90. cout<< *os2<< endl;
  91. os2=os4;
  92. cout<< "os2.has_value(): "<< os2.has_value()<< endl;
  93. cout<< os2.value_or("?")<< endl;
  94. cout<< endl;
  95. cout<< "Testing optional::map_to, optional::map_or:"<< endl;
  96. optional<string> xs1, xs2("Hello World");
  97. optional<size_t> xz1= xs1.map_to<size_t>(cxxomfort::fix::mem_fn(&string::size));
  98. optional<size_t> xz2= xs2.map_to<size_t>(mem_fn(&string::size));
  99. cout<< xz1.value_or(0)<< endl;
  100. cout<< xz2.value_or(0)<< endl;
  101. #if (CXXOMFORT_CXX_STD>=2011)
  102. cout<< "Testing optional::map"<< endl;
  103. optional<size_t> xz3= xs1.map(mem_fn(&string::size) );
  104. auto xz4= xs2.map(mem_fn(&string::size) );
  105. //optional<int> xz5 = xz4;
  106. cout<< xz3.value_or(-1)<< endl;
  107. cout<< xz4.value_or(-1)<< endl;
  108. #endif
  109. cout<< endl;
  110. cout<< "Filter "<< *xs2<< endl;
  111. optional<string> xs3;
  112. xs3= xs2.filter(bind(istoolong, placeholders::_1));
  113. cout<< "Done"<< endl;
  114. cout<< xs3.has_value()<< endl;
  115. xs2= string("A");
  116. cout<< "xs2: "<< xs2.value_or("None")<< endl;
  117. cout<< "xs3: "<< xs3.value_or("None")<< endl;
  118. xs3= nullopt;
  119. cout<< "xs3: "<< xs3.value_or("None")<< endl;
  120. } catch (std::exception& E) {
  121. cerr<< E.what()<< endl;
  122. }
  123. }