Created
January 12, 2026 15:14
-
-
Save camila314/180d6dc0afbc0abd581ef466f2b69bc3 to your computer and use it in GitHub Desktop.
CoW for c++20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <concepts> | |
| template <std::copy_constructible T> | |
| class cow { | |
| std::shared_ptr<T> data; | |
| void clone() { | |
| data = std::make_shared<T>(*data); | |
| } | |
| public: | |
| cow(cow const& c) : data(c.data) {} | |
| cow(cow&& c) : data(std::move(c.data)) {} | |
| cow(T const& t) : data(std::make_shared<T>(t)) {} | |
| template <typename ...Args> requires std::constructible_from<T, Args...> | |
| cow(Args... args) : data(std::make_shared<T>(std::forward<Args>(args)...)) {} | |
| cow(T&& t) : data(std::make_shared<T>(std::move(t))) {} | |
| template <typename Q> requires requires(T a, Q b) { a = b; } | |
| cow& operator=(Q&& t) { | |
| clone(); | |
| *data = std::forward<Q>(t); | |
| return *this; | |
| } | |
| #define OPS(op) \ | |
| auto operator op(T&& t) const { return (*data) op std::move(t); } \ | |
| auto operator op(T const& t) const { return (*data) op t; } \ | |
| auto operator op(cow const& t) const { return (*data) op (*t.data); } \ | |
| OPS(+) OPS(-) OPS(*) OPS(/) OPS(%) OPS(<=>) OPS(<<) OPS(>>) OPS(&) OPS(|) | |
| #undef OPS | |
| #define OPS(op) \ | |
| cow& operator op(T&& t) { clone(); (*data) op std::move(t); return *this; } \ | |
| cow& operator op(T const& t) { clone(); (*data) op t; return *this; } \ | |
| cow& operator op(cow const& t) { clone(); (*data) op (*t.data); return *this; } | |
| OPS(+=) OPS(-=) OPS(*=) OPS(/=) OPS(%=) OPS(<<=) OPS(>>=) OPS(&=) OPS(|=) | |
| #undef OPS | |
| cow& operator++() { | |
| clone(); | |
| (*data)++; | |
| return *this; | |
| } | |
| cow& operator--() { | |
| clone(); | |
| (*data)--; | |
| return *this; | |
| } | |
| operator T() const { | |
| return *data; | |
| } | |
| operator T const&() const { | |
| return *data; | |
| } | |
| operator T&() { | |
| clone(); | |
| return *data; | |
| } | |
| std::shared_ptr<T> const ptr() const { | |
| return data; | |
| } | |
| T const& inner() const { | |
| return *data; | |
| } | |
| bool operator==(cow const&) const = default; | |
| bool operator==(T const& t) const { | |
| return (*data) == t; | |
| } | |
| bool operator==(T&& t) const { | |
| return (*data) == std::move(t); | |
| } | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment