diff --git a/include/cppast/cpp_function_types.hpp b/include/cppast/cpp_function_types.hpp new file mode 100644 index 0000000..00ab89a --- /dev/null +++ b/include/cppast/cpp_function_types.hpp @@ -0,0 +1,207 @@ +// Copyright (C) 2017 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_FUNCTION_TYPES_HPP_INCLUDED +#define CPPAST_CPP_FUNCTION_TYPES_HPP_INCLUDED + +#include + +namespace cppast +{ + /// A [cppast::cpp_type]() that is a function. + /// + /// A function pointer is created by wrapping it in [cppast::cpp_pointer_type](). + class cpp_function_type final : public cpp_type + { + public: + /// Builds a [cppast::cpp_function_type](). + class builder + { + public: + /// \effects Sets the return type. + explicit builder(std::unique_ptr return_type) + : func_(new cpp_function_type(std::move(return_type))) + { + } + + /// \effects Adds an argument type. + void add_argument(std::unique_ptr arg) + { + func_->arguments_.push_back(*func_, std::move(arg)); + } + + /// \effects Adds an ellipsis, marking it as variadic. + void variadic() + { + func_->variadic_ = true; + } + + /// \returns The finished [cppast::cpp_function_type](). + std::unique_ptr finish() + { + return std::move(func_); + } + + private: + std::unique_ptr func_; + }; + + /// \returns A reference to the return [cppast::cpp_type](). + const cpp_type& return_type() const noexcept + { + return *return_type_; + } + + /// \returns An iteratable object iterating over the argument types. + detail::iteratable_intrusive_list argument_types() const noexcept + { + return type_safe::ref(arguments_); + } + + /// \returns Whether or not the function is variadic (C-style ellipsis). + bool is_variadic() const noexcept + { + return variadic_; + } + + private: + cpp_function_type(std::unique_ptr return_type) + : return_type_(std::move(return_type)), variadic_(false) + { + } + + cpp_type_kind do_get_kind() const noexcept override + { + return cpp_type_kind::function; + } + + std::unique_ptr return_type_; + detail::intrusive_list arguments_; + bool variadic_; + }; + + /// A [cppast::cpp_type]() that is a member function. + /// + /// A member function with cv qualifier is created by wrapping it in [cppast::cpp_cv_qualified_type](). + /// A member function with reference qualifier is created by wrapping it in [cppast::cpp_reference_type](). + /// A member function pointer is created by wrapping it in [cppast::cpp_pointer_type](). + class cpp_member_function_type final : public cpp_type + { + public: + /// Builds a [cppast::cpp_member_function_type](). + class builder + { + public: + /// \effects Sets the class and return type. + builder(std::unique_ptr class_type, std::unique_ptr return_type) + : func_(new cpp_member_function_type(std::move(class_type), std::move(return_type))) + { + } + + /// \effects Adds an argument type. + void add_argument(std::unique_ptr arg) + { + func_->arguments_.push_back(*func_, std::move(arg)); + } + + /// \effects Adds an ellipsis, marking it as variadic. + void variadic() + { + func_->variadic_ = true; + } + + /// \returns The finished [cppast::cpp_member_function_type](). + std::unique_ptr finish() + { + return std::move(func_); + } + + private: + std::unique_ptr func_; + }; + + /// \returns A reference to the class [cppast::cpp_type](). + const cpp_type& class_type() const noexcept + { + return *class_type_; + } + + /// \returns A reference to the return [cppast::cpp_type](). + const cpp_type& return_type() const noexcept + { + return *object_type_; + } + + /// \returns An iteratable object iterating over the argument types. + detail::iteratable_intrusive_list argument_types() const noexcept + { + return type_safe::ref(arguments_); + } + + /// \returns Whether or not the function is variadic (C-style ellipsis). + bool is_variadic() const noexcept + { + return variadic_; + } + + private: + cpp_member_function_type(std::unique_ptr class_type, + std::unique_ptr return_type) + : class_type_(std::move(class_type)), object_type_(std::move(return_type)), variadic_(false) + { + } + + cpp_type_kind do_get_kind() const noexcept override + { + return cpp_type_kind::member_function; + } + + std::unique_ptr class_type_, object_type_; + detail::intrusive_list arguments_; + bool variadic_; + }; + + /// A [cppast::cpp_type]() that is a member object. + /// + /// A member object pointer is created by wrapping it in [cppast::cpp_pointer_type](). + class cpp_member_object_type final : public cpp_type + { + public: + /// \returns A newly created member object type. + static std::unique_ptr build(std::unique_ptr class_type, + std::unique_ptr object_type) + { + return std::unique_ptr( + new cpp_member_object_type(std::move(class_type), std::move(object_type))); + } + + /// \returns A reference to the class [cppast::cpp_type](). + const cpp_type& class_type() const noexcept + { + return *class_type_; + } + + /// \returns A reference to the object [cppast::cpp_type](). + const cpp_type& object_type() const noexcept + { + return *object_type_; + } + + private: + cpp_member_object_type(std::unique_ptr class_type, + std::unique_ptr object_type) + : class_type_(std::move(class_type)), object_type_(std::move(object_type)) + { + } + + cpp_type_kind do_get_kind() const noexcept override + { + return cpp_type_kind::member_object; + } + + std::unique_ptr class_type_, object_type_; + }; +} // namespace cppast + +#endif // CPPAST_CPP_FUNCTION_TYPES_HPP_INCLUDED diff --git a/include/cppast/cpp_type.hpp b/include/cppast/cpp_type.hpp index feb8d36..c9bae35 100644 --- a/include/cppast/cpp_type.hpp +++ b/include/cppast/cpp_type.hpp @@ -23,6 +23,9 @@ namespace cppast reference, array, + function, + member_function, + member_object, unexposed, }; diff --git a/include/cppast/detail/intrusive_list.hpp b/include/cppast/detail/intrusive_list.hpp index 20068d9..c7e0015 100644 --- a/include/cppast/detail/intrusive_list.hpp +++ b/include/cppast/detail/intrusive_list.hpp @@ -195,6 +195,36 @@ namespace cppast std::unique_ptr first_; type_safe::optional_ref last_; }; + + template + class iteratable_intrusive_list + { + public: + iteratable_intrusive_list(type_safe::object_ref> list) + : list_(list) + { + } + + bool empty() const noexcept + { + return list_->empty(); + } + + using iterator = typename intrusive_list::const_iterator; + + iterator begin() const noexcept + { + return list_->begin(); + } + + iterator end() const noexcept + { + return list_->end(); + } + + private: + type_safe::object_ref> list_; + }; } } // namespace cppast::detail