diff --git a/include/essence/generator.hpp b/include/essence/generator.hpp index 1b08516..da49b28 100644 --- a/include/essence/generator.hpp +++ b/include/essence/generator.hpp @@ -43,7 +43,11 @@ namespace essence { } void operator delete(void* ptr, std::size_t size) { +#if __cpp_sized_deallocation >= 201309L ::operator delete(ptr, size); +#else + ::operator delete(ptr); +#endif } generator get_return_object() noexcept { diff --git a/include/essence/meta/struct.hpp b/include/essence/meta/struct.hpp index b8c2ee0..7541127 100644 --- a/include/essence/meta/struct.hpp +++ b/include/essence/meta/struct.hpp @@ -45,9 +45,9 @@ namespace essence::meta { std::index_sequence) -> generator { #if defined(__llvm__) && defined(__clang__) (co_yield (detail::parse_data_member_name(get_literal_string_v(detail::make_fake_object_wrapper( - detail::make_data_member_pointers(detail::make_fake_object_wrapper())))>()), - ...); + std::get(detail::make_fake_object_wrapper( + detail::make_data_member_pointers(detail::make_fake_object_wrapper())))>()), + ...)); #else (co_yield detail::parse_data_member_name(get_literal_string_v(detail::make_data_member_pointers(detail::make_fake_object_wrapper()))>()), diff --git a/include/essence/rational.hpp b/include/essence/rational.hpp index e99d9c9..ee23b54 100644 --- a/include/essence/rational.hpp +++ b/include/essence/rational.hpp @@ -29,35 +29,36 @@ #include #include -namespace essence::detail { - template - consteval auto rational_bindable_count(T obj) noexcept { - auto&& [a, b] = obj; - constexpr std::size_t type_1 = std::same_as, std::int64_t> ? 1U : 0U; - constexpr std::size_t type_2 = std::same_as, std::int64_t> ? 1U : 0U; - - return std::integral_constant{}; - } -} // namespace essence::detail - namespace essence { /** * @brief Checks if an object is similar to essence::rational. */ template - concept similar_rational = requires(std::int64_t a, std::int64_t b, T obj) { + concept similar_rational = requires(std::int64_t a, std::int64_t b) { T{a, b}; - { detail::rational_bindable_count(obj) } -> std::same_as>; + { + [](T inner) { + auto&& [x, y] = inner; + constexpr std::size_t type_1 = std::same_as, std::int64_t> ? 1U : 0U; + constexpr std::size_t type_2 = std::same_as, std::int64_t> ? 1U : 0U; + + return std::integral_constant{}; + }(T{}) + } -> std::same_as>; }; /** * @brief Represents a rational number consisting of its corresponding numerator and denominator. */ struct rational { - std::int64_t numerator; - std::int64_t denominator; + std::int64_t numerator{}; + std::int64_t denominator{}; - constexpr rational() noexcept : numerator{}, denominator{} {} + constexpr rational() noexcept = default; + + constexpr rational(const rational&) = default; + + constexpr rational(rational&&) noexcept = default; explicit constexpr rational(std::int64_t numerator) noexcept : rational{numerator, 1} {} @@ -68,21 +69,35 @@ namespace essence { template requires(std::is_aggregate_v> && similar_rational>) - explicit rational(T&& object) noexcept : rational{} { - auto&& [numerator, denominator] = std::forward(object); + explicit constexpr rational(T&& obj) noexcept : rational{} { + auto&& [numerator, denominator] = std::forward(obj); this->numerator = numerator; this->denominator = denominator; + simplify(); } + rational& operator=(const rational&) = default; + + rational& operator=(rational&&) noexcept = default; + /** * @brief Converts to a similar object. * @tparam T The type of the similar object. */ template - requires similar_rational - constexpr operator T() const noexcept(similar_rational) { // NOLINT(*-explicit-constructor) - return T{numerator, denominator}; + requires similar_rational> + constexpr operator T() const noexcept(similar_rational>) { // NOLINT(*-explicit-constructor) + return std::decay_t{numerator, denominator}; + } + + /** + * @brief Converts to a floating-point number. + * @tparam T The type of the floating-point number. + */ + template + explicit constexpr operator T() const noexcept { + return static_cast(numerator) / static_cast(denominator); } /** @@ -109,15 +124,6 @@ namespace essence { return rational{denominator, numerator}; } - /** - * @brief Converts to a floating-point number. - * @tparam T The type of the floating-point number. - */ - template - explicit constexpr operator T() const noexcept { - return static_cast(numerator) / static_cast(denominator); - } - constexpr bool operator<(const rational& right) const noexcept { return numerator * right.denominator < right.numerator * denominator; } diff --git a/test/meta_test.cpp b/test/meta_test.cpp new file mode 100644 index 0000000..c813418 --- /dev/null +++ b/test/meta_test.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 The RefValue Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include + +#include + +namespace test { + struct foo {}; +} // namespace test + +using namespace essence::meta; + +TEST(meta_test, identifiers) { +}