From 1c8b962f5ad7996302d8144e2765246fc7f911b7 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 1 Jul 2021 02:01:47 +0700 Subject: [PATCH] common type info class --- headers/meta.hpp/meta.hpp | 2 ++ headers/meta.hpp/meta_fwd.hpp | 3 ++ headers/meta.hpp/meta_type.hpp | 56 +++++++++++++++++++++++++++++++++ untests/meta_type_tests.cpp | 57 ++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 headers/meta.hpp/meta_type.hpp create mode 100644 untests/meta_type_tests.cpp diff --git a/headers/meta.hpp/meta.hpp b/headers/meta.hpp/meta.hpp index 420cd6b..c4d3df7 100644 --- a/headers/meta.hpp/meta.hpp +++ b/headers/meta.hpp/meta.hpp @@ -10,6 +10,8 @@ #include "meta_value.hpp" +#include "meta_type.hpp" + #include "meta_class.hpp" #include "meta_class_info.hpp" diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index f27f9c1..173d887 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -19,11 +19,14 @@ #include #include #include +#include namespace meta_hpp { class value; + class type; + class class_info; class data_info; class field_info; diff --git a/headers/meta.hpp/meta_type.hpp b/headers/meta.hpp/meta_type.hpp new file mode 100644 index 0000000..8f86765 --- /dev/null +++ b/headers/meta.hpp/meta_type.hpp @@ -0,0 +1,56 @@ +/******************************************************************************* + * This file is part of the "https://github.com/blackmatov/meta.hpp" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_class_info.hpp" +#include "meta_field_info.hpp" +#include "meta_function_info.hpp" +#include "meta_method_info.hpp" +#include "meta_namespace_info.hpp" +#include "meta_variable_info.hpp" + +namespace meta_hpp +{ + class type { + public: + type() = delete; + + type(type&&) = default; + type(const type&) = default; + + type& operator=(type&&) = default; + type& operator=(const type&) = default; + + template < typename Info > + type(Info&& info) + : info_(std::forward(info)) {} + + bool is_class() const noexcept { return std::holds_alternative(info_); } + bool is_field() const noexcept { return std::holds_alternative(info_); } + bool is_function() const noexcept { return std::holds_alternative(info_); } + bool is_method() const noexcept { return std::holds_alternative(info_); } + bool is_namespace() const noexcept { return std::holds_alternative(info_); } + bool is_variable() const noexcept { return std::holds_alternative(info_); } + + const class_info& get_class_info() const { return std::get(info_); } + const field_info& get_field_info() const { return std::get(info_); } + const function_info& get_function_info() const { return std::get(info_); } + const method_info& get_method_info() const { return std::get(info_); } + const namespace_info& get_namespace_info() const { return std::get(info_); } + const variable_info& get_variable_info() const { return std::get(info_); } + private: + std::variant< + class_info, + field_info, + function_info, + method_info, + namespace_info, + variable_info> info_; + }; +} diff --git a/untests/meta_type_tests.cpp b/untests/meta_type_tests.cpp new file mode 100644 index 0000000..f7e8585 --- /dev/null +++ b/untests/meta_type_tests.cpp @@ -0,0 +1,57 @@ +/******************************************************************************* + * This file is part of the "https://github.com/blackmatov/meta.hpp" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "doctest/doctest.hpp" + +namespace +{ + struct clazz { + int field{42}; + static int variable; + int method() const { return 42; } + static int function() { return 42; } + }; + + int clazz::variable{42}; +} + +TEST_CASE("meta/type") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + meta::type class_type = meta::class_("clazz").info(); + CHECK(class_type.is_class()); + CHECK(class_type.get_class_info().id() == "clazz"); + + meta::type field_type = meta::field_<&clazz::field>("field").info(); + CHECK(field_type.is_field()); + CHECK(field_type.get_field_info().id() == "field"); + + meta::type function_type = meta::function_<&clazz::function>("function").info(); + CHECK(function_type.is_function()); + CHECK(function_type.get_function_info().id() == "function"); + + meta::type method_type = meta::method_<&clazz::method>("method").info(); + CHECK(method_type.is_method()); + CHECK(method_type.get_method_info().id() == "method"); + + meta::type namespace_type = meta::namespace_("ns").info(); + CHECK(namespace_type.is_namespace()); + CHECK(namespace_type.get_namespace_info().id() == "ns"); + + meta::type variable_type = meta::variable_<&clazz::variable>("variable").info(); + CHECK(variable_type.is_variable()); + CHECK(variable_type.get_variable_info().id() == "variable"); +}