Skip to content

Instantly share code, notes, and snippets.

@sthalik
Created October 30, 2022 18:20
Show Gist options
  • Save sthalik/0b8fbbafe084833b69ae25d88f73e6b7 to your computer and use it in GitHub Desktop.
Save sthalik/0b8fbbafe084833b69ae25d88f73e6b7 to your computer and use it in GitHub Desktop.
#include <type_traits>
namespace detail { template<typename To, typename From> struct Converter {}; }
struct Foo {
float x = 0, y = 0, z = 0, w = 0;
explicit constexpr Foo() noexcept = default;
explicit constexpr Foo(float x, float y, float z, float w) noexcept : x{x}, y{y}, z{z}, w{w} {}
explicit constexpr Foo(const Foo&) noexcept = default;
constexpr Foo& operator=(const Foo&) noexcept = default;
template<typename U, decltype(detail::Converter<Foo, U>::to(std::declval<U>()), void())** = nullptr>
explicit constexpr Foo(const U& other) : Foo{detail::Converter<Foo, U>::to(other)} {}
template<typename U, decltype(detail::Converter<Foo, U>::from(std::declval<Foo>()), void())** = nullptr>
explicit constexpr operator U() const { return detail::Converter<Foo, U>::from(*this); }
};
struct Derived {
float x = 0, y = 0, z = 0, w = 0;
};
namespace detail {
template<>
struct Converter<Foo, Derived> {
static constexpr auto to(const Derived& x) noexcept {
return Foo { x.x, x.y, x.z, x.w };
}
static constexpr auto from(const Foo& x) noexcept {
return Derived { x.x, x.y, x.z, x.w };
}
};
} // namespace detail
int main(void)
{
[[maybe_unused]] constexpr Derived a{1.f, 2.f, 3.f, 4.f};
[[maybe_unused]] constexpr Foo b(a);
[[maybe_unused]] constexpr Derived c(b);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment