Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <variant>
- #include <memory>
- template<typename T>
- class value_ptr {
- public:
- using element_type = T;
- using pointer = T*;
- value_ptr(element_type t) : m_ptr{std::make_unique<T>(std::move(t))} { }
- auto get() const noexcept -> T* { return m_ptr.get(); }
- auto operator*() const -> typename std::add_lvalue_reference<T>::type { return *m_ptr; }
- auto operator->() const noexcept -> T* { return m_ptr.operator->(); }
- private:
- std::unique_ptr<T> m_ptr;
- };
- template<typename T>
- auto operator==(value_ptr<T> const& lhs, value_ptr<T> const& rhs) -> bool { return *lhs == *rhs; }
- template<typename T>
- auto operator!=(value_ptr<T> const& lhs, value_ptr<T> const& rhs) -> bool { return *lhs != *rhs; }
- template<typename N>
- class add;
- template<typename N>
- using expr = std::variant<N, value_ptr<add<N>>>;
- //using expr = std::variant<N, std::unique_ptr<add<N>>>; // this works!
- template<typename N>
- class add {
- public:
- add(expr<N> lhs, expr<N> rhs) : m_lhs{std::move(lhs)}, m_rhs{std::move(lhs)} {}
- auto lhs() const& -> expr<N> const& { return m_lhs; }
- auto rhs() const& -> expr<N> const& { return m_rhs; }
- private:
- expr<N> m_lhs;
- expr<N> m_rhs;
- };
- template<typename N>
- auto operator==(add<N> const& lhs, add<N> const& rhs) -> bool {
- return lhs.lhs() == rhs.lhs() && lhs.rhs() == rhs.rhs();
- }
- template<typename N>
- auto operator+(expr<N>&& lhs, expr<N>&& rhs) -> expr<N> {
- return value_ptr<add<N>>{add<N>{std::move(lhs), std::move(rhs)}};
- // return std::make_unique<add<N>>(add<N>{std::move(lhs), std::move(rhs)}); // this works!
- }
- auto main() -> int {
- using ex = expr<double>;
- auto x = ex{0.5} + ex{1.5};
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement