// // Copyright (c) 2023 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #ifndef BOOST_LOCALE_DETAIL_ANY_STRING_HPP_INCLUDED #define BOOST_LOCALE_DETAIL_ANY_STRING_HPP_INCLUDED #include #include #include #include #include #include /// \cond INTERNAL namespace boost { namespace locale { namespace detail { /// Type-erased std::basic_string class any_string { struct BOOST_SYMBOL_VISIBLE base { virtual ~base() = default; virtual base* clone() const = 0; protected: base() = default; base(const base&) = default; base(base&&) = delete; base& operator=(const base&) = default; base& operator=(base&&) = delete; }; template struct BOOST_SYMBOL_VISIBLE impl : base { explicit impl(const boost::basic_string_view value) : s(value) {} impl* clone() const override { return new impl(*this); } std::basic_string s; }; std::unique_ptr s_; public: any_string() = default; any_string(const any_string& other) : s_(other.s_ ? other.s_->clone() : nullptr) {} any_string(any_string&&) = default; any_string& operator=(any_string other) // Covers the copy and move assignment { s_.swap(other.s_); return *this; } template void set(const boost::basic_string_view s) { BOOST_ASSERT(!s.empty()); s_.reset(new impl(s)); } template std::basic_string get() const { if(!s_) throw std::bad_cast(); return dynamic_cast&>(*s_).s; } }; }}} // namespace boost::locale::detail /// \endcond #endif