Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <type_traits>
- namespace poyenc {
- template <typename T> struct storage_t {
- using value_type = T;
- value_type value;
- };
- template <typename To, typename... From>
- struct is_all_convertible
- : std::integral_constant<bool, (std::is_convertible_v<From, To> && ...)> {};
- template <typename To, typename... From>
- inline constexpr bool is_all_convertible_v =
- is_all_convertible<To, From...>::value;
- template <typename Target, typename... Others>
- struct is_any_same
- : std::integral_constant<bool, (std::is_same_v<Target, Others> || ...)> {};
- template <typename Target, typename... Others>
- inline constexpr bool is_any_same_v = is_any_same<Target, Others...>::value;
- template <typename Storage, typename Derived, typename... From>
- struct implicit_conversion_from {
- using value_type = typename Storage::value_type;
- static_assert(is_all_convertible_v<value_type, From...>);
- Storage &storage_() { return static_cast<Derived &>(*this); }
- template <typename T, typename = std::enable_if_t<
- is_any_same_v<std::decay_t<T>, From...>>>
- Derived &operator=(T &&value) {
- storage_().value = std::forward<T>(value);
- return static_cast<Derived &>(*this);
- }
- };
- template <typename Storage, typename Derived, typename To>
- struct implicit_conversion_to {
- using value_type = typename Storage::value_type;
- static_assert(std::is_convertible_v<value_type, To>);
- const Storage &storage_() const {
- return static_cast<const Derived &>(*this);
- }
- operator To() const { return storage_().value; }
- };
- template <typename... Types> struct from_list {};
- template <typename... Types> struct to_list {};
- template <typename Value, typename FromList, typename ToList> struct abstract_t;
- template <typename Value, typename... From, typename... To>
- struct abstract_t<Value, from_list<From...>, to_list<To...>>
- : storage_t<Value>,
- implicit_conversion_from<
- storage_t<Value>,
- abstract_t<Value, from_list<From...>, to_list<To...>>, From...>,
- implicit_conversion_to<
- storage_t<Value>,
- abstract_t<Value, from_list<From...>, to_list<To...>>, To>... {
- using implicit_conversion_from<
- storage_t<Value>, abstract_t<Value, from_list<From...>, to_list<To...>>,
- From...>::operator=;
- };
- } // namespace poyenc
- int main() {
- poyenc::abstract_t<float, poyenc::from_list<int, float>,
- poyenc::to_list<float, double>>
- f;
- static_assert(sizeof(f) == sizeof(float));
- f = 1;
- f = 1.f;
- // f = 1.; // compilation error
- // const int i = f; // compilation error
- const float f1 = f;
- const double d1 = f;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement