Advertisement
Guest User

Untitled

a guest
Oct 18th, 2019
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.60 KB | None | 0 0
  1. #include <iostream>
  2. #include <type_traits>
  3.  
  4. namespace poyenc {
  5.  
  6. template <typename T> struct storage_t {
  7. using value_type = T;
  8.  
  9. value_type value;
  10. };
  11.  
  12. template <typename To, typename... From>
  13. struct is_all_convertible
  14. : std::integral_constant<bool, (std::is_convertible_v<From, To> && ...)> {};
  15.  
  16. template <typename To, typename... From>
  17. inline constexpr bool is_all_convertible_v =
  18. is_all_convertible<To, From...>::value;
  19.  
  20. template <typename Target, typename... Others>
  21. struct is_any_same
  22. : std::integral_constant<bool, (std::is_same_v<Target, Others> || ...)> {};
  23.  
  24. template <typename Target, typename... Others>
  25. inline constexpr bool is_any_same_v = is_any_same<Target, Others...>::value;
  26.  
  27. template <typename Storage, typename Derived, typename... From>
  28. struct implicit_conversion_from {
  29. using value_type = typename Storage::value_type;
  30.  
  31. static_assert(is_all_convertible_v<value_type, From...>);
  32.  
  33. Storage &storage_() { return static_cast<Derived &>(*this); }
  34.  
  35. template <typename T, typename = std::enable_if_t<
  36. is_any_same_v<std::decay_t<T>, From...>>>
  37. Derived &operator=(T &&value) {
  38. storage_().value = std::forward<T>(value);
  39. return static_cast<Derived &>(*this);
  40. }
  41. };
  42.  
  43. template <typename Storage, typename Derived, typename To>
  44. struct implicit_conversion_to {
  45. using value_type = typename Storage::value_type;
  46.  
  47. static_assert(std::is_convertible_v<value_type, To>);
  48.  
  49. const Storage &storage_() const {
  50. return static_cast<const Derived &>(*this);
  51. }
  52.  
  53. operator To() const { return storage_().value; }
  54. };
  55.  
  56. template <typename... Types> struct from_list {};
  57.  
  58. template <typename... Types> struct to_list {};
  59.  
  60. template <typename Value, typename FromList, typename ToList> struct abstract_t;
  61.  
  62. template <typename Value, typename... From, typename... To>
  63. struct abstract_t<Value, from_list<From...>, to_list<To...>>
  64. : storage_t<Value>,
  65. implicit_conversion_from<
  66. storage_t<Value>,
  67. abstract_t<Value, from_list<From...>, to_list<To...>>, From...>,
  68. implicit_conversion_to<
  69. storage_t<Value>,
  70. abstract_t<Value, from_list<From...>, to_list<To...>>, To>... {
  71. using implicit_conversion_from<
  72. storage_t<Value>, abstract_t<Value, from_list<From...>, to_list<To...>>,
  73. From...>::operator=;
  74. };
  75.  
  76. } // namespace poyenc
  77.  
  78. int main() {
  79. poyenc::abstract_t<float, poyenc::from_list<int, float>,
  80. poyenc::to_list<float, double>>
  81. f;
  82. static_assert(sizeof(f) == sizeof(float));
  83.  
  84. f = 1;
  85. f = 1.f;
  86. // f = 1.; // compilation error
  87.  
  88. // const int i = f; // compilation error
  89. const float f1 = f;
  90. const double d1 = f;
  91. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement