diff --git a/README.md b/README.md index 5a61537..56c6f7c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # meta.hpp -> C++20 tiny reflection library +> C++20 tiny dynamic reflection library [![linux][badge.linux]][linux] [![darwin][badge.darwin]][darwin] diff --git a/TODO.md b/TODO.md index 0632421..a602e7c 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,7 @@ # meta.hpp -- add debug type names -- add meta exception class -- add conversion of nullptr to any pointers -- add conversion of any pointers to void pointer ( identically cv-qualified ) +- add debug type names; +- add meta exception class; +- add conversion of nullptr to any pointers; +- add conversion of any pointers to void pointer ( identically cv-qualified ); +- add enum_type::create, number_type::create, and so on. diff --git a/untests/.clang-tidy b/untests/.clang-tidy index 76b1ec4..8762983 100644 --- a/untests/.clang-tidy +++ b/untests/.clang-tidy @@ -11,6 +11,7 @@ Checks: '-*, -cppcoreguidelines-special-member-functions, modernize-*, + -modernize-use-nodiscard, -modernize-use-trailing-return-type, portability-*, diff --git a/untests/examples/class_example.cpp b/untests/examples/class_example.cpp index f0cb81d..9a198e4 100644 --- a/untests/examples/class_example.cpp +++ b/untests/examples/class_example.cpp @@ -8,14 +8,12 @@ namespace { - constexpr double pi_v = 3.1415926536; - class shape { public: shape() = default; virtual ~shape() = default; - [[nodiscard]] virtual double area() const = 0; + virtual double area() const = 0; }; class circle : public shape { @@ -23,11 +21,11 @@ namespace explicit circle(double radius) : radius_{radius} {} - [[nodiscard]] double area() const override { - return pi_v * radius_ * radius_; + double area() const override { + return std::numbers::pi * radius_ * radius_; } - [[nodiscard]] double radius() const { + double radius() const { return radius_; } private: @@ -40,15 +38,15 @@ namespace : width_{width} , height_{height} {} - [[nodiscard]] double area() const override { + double area() const override { return width_ * height_; } - [[nodiscard]] double width() const { + double width() const { return width_; } - [[nodiscard]] double height() const { + double height() const { return height_; } private: @@ -84,7 +82,6 @@ TEST_CASE("meta/examples/class") { { const meta::class_type circle_type = geometry.get_class("circle"); - const meta::method radius_method = circle_type.get_method("radius"); const meta::value circle_v = circle_type.create(5.0).value(); @@ -98,11 +95,10 @@ TEST_CASE("meta/examples/class") { { const meta::class_type rectangle_type = geometry.get_class("rectangle"); - const meta::method width_method = rectangle_type.get_method("width"); const meta::method height_method = rectangle_type.get_method("height"); - const meta::value rectangle_v = rectangle_type(10.0, 20.0).value(); + const meta::value rectangle_v = rectangle_type.create(10.0, 20.0).value(); const meta::value rectangle_area_v = area_method(rectangle_v).value(); const meta::value rectangle_width_v = width_method(rectangle_v).value(); diff --git a/untests/examples/complex_example.cpp b/untests/examples/complex_example.cpp index 5bee1c3..e840873 100644 --- a/untests/examples/complex_example.cpp +++ b/untests/examples/complex_example.cpp @@ -16,15 +16,15 @@ namespace ivec2(int v) : x{v}, y{v} {} ivec2(int x, int y) : x{x}, y{y} {} - [[nodiscard]] int dot(const ivec2& other) const noexcept { + int dot(const ivec2& other) const { return x * other.x + y * other.y; } - [[nodiscard]] int length2() const noexcept { + int length2() const { return dot(*this); } - [[nodiscard]] friend bool operator==(const ivec2& l, const ivec2& r) noexcept { + friend bool operator==(const ivec2& l, const ivec2& r) { return l.x == r.x && l.y == r.y; } }; @@ -51,49 +51,49 @@ TEST_CASE("meta/examples/complex") { const meta::method ivec2_length2 = ivec2_type.get_method("length2"); { - const ivec2 v = ivec2_type.get_ctor_with<>().invoke().cast(); + const ivec2 v = ivec2_type()->cast(); CHECK(v == ivec2{}); - CHECK(ivec2_x.get(v) == 0); - CHECK(ivec2_y.get(v) == 0); + CHECK(ivec2_x(v) == 0); + CHECK(ivec2_y(v) == 0); } { - const ivec2 v = ivec2_type.get_ctor_with().invoke(3).cast(); + const ivec2 v = ivec2_type(3)->cast(); CHECK(v == ivec2{3}); - CHECK(ivec2_x.get(v) == 3); - CHECK(ivec2_y.get(v) == 3); + CHECK(ivec2_x(v) == 3); + CHECK(ivec2_y(v) == 3); } { - const meta::value v = ivec2_type.get_ctor_with().invoke(1, 2); + const meta::value v = ivec2_type(1, 2).value(); CHECK(v == ivec2{1, 2}); - CHECK(ivec2_x.get(v) == 1); - CHECK(ivec2_y.get(v) == 2); + CHECK(ivec2_x(v) == 1); + CHECK(ivec2_y(v) == 2); } { - meta::value v = ivec2_type.get_ctor_with().invoke(1, 2); + meta::value v = ivec2_type(1, 2).value(); - ivec2_x.set(v, 10); - ivec2_y.set(v, 20); + ivec2_x(v, 10); + ivec2_y(v, 20); - CHECK(ivec2_x.get(v) == 10); - CHECK(ivec2_y.get(v) == 20); + CHECK(ivec2_x(v) == 10); + CHECK(ivec2_y(v) == 20); } { - const meta::value v0 = ivec2_type.get_ctor_with().invoke(1, 2); - const meta::value v1 = ivec2_type.get_ctor_with().invoke(3, 4); + const meta::value v0 = ivec2_type(1, 2).value(); + const meta::value v1 = ivec2_type(3, 4).value(); - CHECK(ivec2_dot.invoke(v0, v1) == 1 * 3 + 2 * 4); + CHECK(ivec2_dot(v0, v1) == 1 * 3 + 2 * 4); } { - const meta::value v = ivec2_type.get_ctor_with().invoke(3, 4); + const meta::value v = ivec2_type(3, 4).value(); - CHECK(ivec2_length2.invoke(v) == 3 * 3 + 4 * 4); + CHECK(ivec2_length2(v) == 3 * 3 + 4 * 4); } } diff --git a/untests/examples/enum_example.cpp b/untests/examples/enum_example.cpp index 7402e25..653b322 100644 --- a/untests/examples/enum_example.cpp +++ b/untests/examples/enum_example.cpp @@ -26,11 +26,25 @@ TEST_CASE("meta/examples/enum") { .evalue_("white", color::white); meta::enum_type color_type = meta::resolve_type(); - REQUIRE(color_type); - CHECK(color_type.get_underlying_type() == meta::resolve_type()); + { + meta::number_type color_underlying_type = color_type.get_underlying_type(); - CHECK(color_type.get_evalue("green").get_index().name == "green"); - CHECK(color_type.get_evalue("green").get_value() == color::green); - CHECK_FALSE(color_type.get_evalue("yellow")); + CHECK(color_underlying_type.get_size() == 4); + CHECK(color_underlying_type.get_flags().has(meta::number_flags::is_unsigned)); + } + + { + meta::evalue green_evalue = color_type.get_evalue("green"); + + CHECK(green_evalue.get_name() == "green"); + CHECK(green_evalue.get_type() == color_type); + + CHECK(green_evalue.get_value() == color::green); + } + + { + CHECK(color_type.value_to_name(color::blue) == "blue"); + CHECK(color_type.name_to_value("white") == color::white); + } } diff --git a/untests/examples/member_example.cpp b/untests/examples/member_example.cpp index 7f239ee..f8c4f6a 100644 --- a/untests/examples/member_example.cpp +++ b/untests/examples/member_example.cpp @@ -8,7 +8,7 @@ namespace { - struct ivec2 final { + struct ivec2 { int x{}; int y{}; }; @@ -22,16 +22,16 @@ TEST_CASE("meta/examples/member") { .member_("y", &ivec2::y); const meta::class_type ivec2_type = meta::resolve_type(); - REQUIRE(ivec2_type); CHECK(ivec2_type.get_members().size() == 2); - const meta::member ivec2_x = ivec2_type.get_member("x"); - REQUIRE(ivec2_x); + { + const meta::member ivec2_x = ivec2_type.get_member("x"); - CHECK(ivec2_x.get_index().name == "x"); - CHECK(ivec2_x.get_type() == meta::resolve_type()); + CHECK(ivec2_x.get_name() == "x"); + CHECK(ivec2_x.get_type() == meta::resolve_type()); - CHECK(ivec2_x.get_type().get_owner_type() == meta::resolve_type()); - CHECK(ivec2_x.get_type().get_value_type() == meta::resolve_type()); + CHECK(ivec2_x.get_type().get_owner_type() == meta::resolve_type()); + CHECK(ivec2_x.get_type().get_value_type() == meta::resolve_type()); + } } diff --git a/untests/examples/method_example.cpp b/untests/examples/method_example.cpp index b51d70b..6153160 100644 --- a/untests/examples/method_example.cpp +++ b/untests/examples/method_example.cpp @@ -8,15 +8,15 @@ namespace { - struct ivec2 final { + struct ivec2 { int x{}; int y{}; - [[nodiscard]] int dot(const ivec2& other) const noexcept { + int dot(const ivec2& other) const { return x * other.x + y * other.y; } - [[nodiscard]] int length2() const noexcept { + int length2() const { return dot(*this); } }; @@ -32,17 +32,17 @@ TEST_CASE("meta/examples/method") { .method_("length2", &ivec2::length2); const meta::class_type ivec2_type = meta::resolve_type(); - REQUIRE(ivec2_type); CHECK(ivec2_type.get_methods().size() == 2); - const meta::method ivec2_dot = ivec2_type.get_method("dot"); - REQUIRE(ivec2_dot); + { + const meta::method ivec2_dot = ivec2_type.get_method("dot"); - CHECK(ivec2_dot.get_index().name == "dot"); - CHECK(ivec2_dot.get_type() == meta::resolve_type()); + CHECK(ivec2_dot.get_name() == "dot"); + CHECK(ivec2_dot.get_type() == meta::resolve_type()); - CHECK(ivec2_dot.get_type().get_arity() == 1); - CHECK(ivec2_dot.get_type().get_return_type() == meta::resolve_type()); - CHECK(ivec2_dot.get_type().get_argument_type(0) == meta::resolve_type()); + CHECK(ivec2_dot.get_type().get_arity() == 1); + CHECK(ivec2_dot.get_type().get_return_type() == meta::resolve_type()); + CHECK(ivec2_dot.get_type().get_argument_type(0) == meta::resolve_type()); + } } diff --git a/untests/examples/number_example.cpp b/untests/examples/number_example.cpp index 877dabc..f677b56 100644 --- a/untests/examples/number_example.cpp +++ b/untests/examples/number_example.cpp @@ -15,7 +15,6 @@ TEST_CASE("meta/examples/number") { { const meta::number_type int_type = meta::resolve_type(); - REQUIRE(int_type); CHECK(int_type.get_flags().has(meta::number_flags::is_signed)); CHECK(int_type.get_size() == sizeof(int)); @@ -23,7 +22,6 @@ TEST_CASE("meta/examples/number") { { const meta::number_type unsigned_type = meta::resolve_type(); - REQUIRE(unsigned_type); CHECK(unsigned_type.get_flags().has(meta::number_flags::is_unsigned)); CHECK(unsigned_type.get_size() == sizeof(unsigned)); diff --git a/untests/meta_tests.hpp b/untests/meta_tests.hpp index a4555fc..96ebd83 100644 --- a/untests/meta_tests.hpp +++ b/untests/meta_tests.hpp @@ -11,4 +11,5 @@ #include #include +#include #include