diff --git a/furc/include/furc/handle.hpp b/furc/include/furc/handle.hpp deleted file mode 100644 index e0b9d2e..0000000 --- a/furc/include/furc/handle.hpp +++ /dev/null @@ -1,196 +0,0 @@ -#ifndef FURC_HANDLE_HPP -#define FURC_HANDLE_HPP - -#include "furc/diag.hpp" -#include "furlang/arena.hpp" - -#include -#include -#include -#include -#include - -namespace furc { - -template -class handle; - -template -class handle { - template - friend class handle; - - friend struct data; - - friend std::ostream& operator<<(std::ostream& os, const handle& result); -public: - using value_type = T; - using pointer = value_type*; - using const_pointer = const value_type*; - using reference = T&; - using const_reference = const T&; -public: - handle() = default; - - template >> - handle(location location, std::shared_ptr value) - : m_data(data(location, std::move(value))) {} - - template || std::is_base_of_v>> - handle(const handle& other) - : m_data(data{ other }) {} - - template >> - handle(location location, Args&&... args) - : m_data(data(location, std::forward(args)...)) {} - - template >> - handle(location location, furlang::arena& arena, Args&&... args) - : m_data(data(location, arena, std::forward(args)...)) {} - - handle(location location, Error&& error) - : m_data(data(location, std::move(error))) {} - - template - handle(const handle& error) - : m_data(data(error)) {} - - ~handle() = default; - - handle(handle&& other) noexcept - : m_data(std::move(other.m_data)) {} - - template >> - handle(handle&& other) noexcept - : m_data(data{ std::move(other) }) {} - - handle(const handle& other) - : m_data(other.m_data) {} - - handle& operator=(handle&& other) noexcept { - if (this == &other) return *this; - m_data = std::move(other.m_data); - return *this; - } - - handle& operator=(const handle& other) { - if (this == &other) return *this; - m_data = other.m_data; - return *this; - } -public: - location location() const { return m_data->location; } // NOLINT(bugprone-unchecked-optional-access) - - bool present() const { return m_data.has_value() && m_data->value != nullptr; } - bool has_error() const { return m_data.has_value() && m_data->value == nullptr; } - - std::shared_ptr shared() const { return m_data->value; } // NOLINT(bugprone-unchecked-optional-access) - Error error() const { return m_data->error; } // NOLINT(bugprone-unchecked-optional-access) - - reference operator*() { return *m_data->value; } // NOLINT(bugprone-unchecked-optional-access) - const_reference operator*() const { return *m_data->value; } // NOLINT(bugprone-unchecked-optional-access) - pointer operator->() { return m_data->value.get(); } // NOLINT(bugprone-unchecked-optional-access) - const_pointer operator->() const { return m_data->value.get(); } // NOLINT(bugprone-unchecked-optional-access) -public: - bool operator==(const handle& rhs) const { - if (present() != rhs.present() || error() != rhs.error()) return false; - if (present() && m_data->value != rhs.m_data->value) return false; // NOLINT(bugprone-unchecked-optional-access) - return true; - } - - bool operator==(const value_type& rhs) const { - return present() && *m_data->value == rhs; // NOLINT(bugprone-unchecked-optional-access) - } -public: - friend std::ostream& operator<<(std::ostream& os, const handle& result) { - if (!result.m_data.has_value()) return os << "handle empty"; - os << result.m_data->location << ": "; - if (result.m_data->value != nullptr) { - os << *result.m_data->value; - } else { - os << "ERROR: " << result.m_data->error; - } - return os; - } -private: - struct data { - struct location location; - std::shared_ptr value = nullptr; - Error error = {}; - - template >> - data(struct location location, std::shared_ptr value) - : location(location), value(std::move(value)) {} - - template || std::is_base_of_v>> - data(handle&& other) // NOLINT - : location(other.m_data->location) { // NOLINT(bugprone-unchecked-optional-access) - if constexpr (std::is_base_of_v) { - value = std::static_pointer_cast( - std::move(other.m_data->value)); // NOLINT(bugprone-unchecked-optional-access) - } else { - value = std::dynamic_pointer_cast( - std::move(other.m_data->value)); // NOLINT(bugprone-unchecked-optional-access) - } - } - - template || std::is_base_of_v>> - data(const handle& other) - : location(other.m_data->location) { // NOLINT(bugprone-unchecked-optional-access) - if constexpr (std::is_base_of_v) { - value = std::static_pointer_cast( - std::move(other.m_data->value)); // NOLINT(bugprone-unchecked-optional-access) - } else { - value = std::dynamic_pointer_cast( - std::move(other.m_data->value)); // NOLINT(bugprone-unchecked-optional-access) - } - } - - template >> - data(struct location location, Args&&... args) - : location(location), value(std::make_shared(std::forward(args)...)) {} - - template >> - data(struct location location, furlang::arena& arena, Args&&... args) - : location(location), value(arena.allocate_shared(std::forward(args)...)) {} - - data(struct location location, Error&& error) - : location(location), error(std::move(error)) {} - - template - data(const handle& error) - : location(error.location()), error(error.error()) {} - - ~data() = default; - - data(data&& other) noexcept - : location(other.location), value(std::move(other.value)), error(std::move(other.error)) {} - - data(const data& other) - : location(other.location), value(other.value), error(other.error) {} - - data& operator=(data&& other) noexcept { - if (this == &other) return *this; - location = other.location; - value = std::move(other.value); - error = std::move(other.error); - return *this; - } - - data& operator=(const data& other) noexcept { - if (this == &other) return *this; - location = other.location; - value = other.value; - error = other.error; - return *this; - } - }; - std::optional m_data = {}; -}; - -} // namespace furc - -#endif // FURC_HANDLE_HPP \ No newline at end of file