See More

// Copyright (C) 2017-2019 Jonathan Müller // This file is subject to the license terms in the LICENSE file // found in the top-level directory of this distribution. #ifndef CPPAST_CPP_EXPRESSION_HPP_INCLUDED #define CPPAST_CPP_EXPRESSION_HPP_INCLUDED #include #include #include #include namespace cppast { /// The kind of a [cppast::cpp_expression](). enum class cpp_expression_kind { literal_t, unexposed_t, }; /// Base class for all C++ expressions. class cpp_expression { public: cpp_expression(const cpp_expression&) = delete; cpp_expression& operator=(const cpp_expression&) = delete; virtual ~cpp_expression() noexcept = default; /// \returns The [cppast::cpp_expression_kind](). cpp_expression_kind kind() const noexcept { return do_get_kind(); } /// \returns The type of the expression. const cpp_type& type() const noexcept { return *type_; } /// \returns The specified user data. void* user_data() const noexcept { return user_data_.load(); } /// \effects Sets some kind of user data. /// /// User data is just some kind of pointer, there are no requirements. /// The class will do no lifetime management. /// /// User data is useful if you need to store additional data for an entity without the need to /// maintain a registry. void set_user_data(void* data) const noexcept { user_data_ = data; } protected: /// \effects Creates it given the type. /// \requires The type must not be `nullptr`. cpp_expression(std::unique_ptr type) : type_(std::move(type)), user_data_(nullptr) { DEBUG_ASSERT(type_ != nullptr, detail::precondition_error_handler{}); } private: /// \returns The [cppast::cpp_expression_kind](). virtual cpp_expression_kind do_get_kind() const noexcept = 0; std::unique_ptr type_; mutable std::atomic user_data_; }; /// An unexposed [cppast::cpp_expression](). /// /// There is no further information than a string available. class cpp_unexposed_expression final : public cpp_expression { public: /// \returns A newly created unexposed expression. static std::unique_ptr build(std::unique_ptr type, cpp_token_string str) { return std::unique_ptr( new cpp_unexposed_expression(std::move(type), std::move(str))); } /// \returns The expression as a string. const cpp_token_string& expression() const noexcept { return str_; } private: cpp_unexposed_expression(std::unique_ptr type, cpp_token_string str) : cpp_expression(std::move(type)), str_(std::move(str)) {} cpp_expression_kind do_get_kind() const noexcept override { return cpp_expression_kind::unexposed_t; } cpp_token_string str_; }; /// A [cppast::cpp_expression]() that is a literal. class cpp_literal_expression final : public cpp_expression { public: /// \returns A newly created literal expression. static std::unique_ptr build(std::unique_ptr type, std::string value) { return std::unique_ptr( new cpp_literal_expression(std::move(type), std::move(value))); } /// \returns The value of the literal, as string. const std::string& value() const noexcept { return value_; } private: cpp_literal_expression(std::unique_ptr type, std::string value) : cpp_expression(std::move(type)), value_(std::move(value)) {} cpp_expression_kind do_get_kind() const noexcept override { return cpp_expression_kind::literal_t; } std::string value_; }; /// \exclude namespace detail { void write_expression(code_generator::output& output, const cpp_expression& expr); } // namespace detail } // namespace cppast #endif // CPPAST_CPP_EXPRESSION_HPP_INCLUDED