diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index b51f2c55..1f89bfb4 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -67,13 +67,13 @@ jobs: } - { name: "macOS", - os: macos-13, + os: macos-latest, common_flags: "", debug_flags: "-DCMAKE_BUILD_TYPE=Debug", release_flags: "-DCMAKE_BUILD_TYPE=Release", build_flags: "", sdk: "/opt/ossia-sdk-x86_64", - pre_build: "sudo xcode-select -s /Applications/Xcode_15.0.app" + pre_build: "sudo xcode-select -s /Applications/Xcode_16.2.app" } steps: diff --git a/include/avnd/common/aggregates.hpp b/include/avnd/common/aggregates.hpp index b4586300..5646342e 100644 --- a/include/avnd/common/aggregates.hpp +++ b/include/avnd/common/aggregates.hpp @@ -3,9 +3,10 @@ /* SPDX-License-Identifier: GPL-3.0-or-later */ #include +#include +#include #include -#include namespace avnd { @@ -15,9 +16,21 @@ struct typelist }; } +// clang-format off +#if defined(__clang_major__) && (__clang_major__ < 21) +#define AVND_USE_BOOST_PFR 1 +#endif + +#if defined(_MSC_VER) +#define AVND_USE_BOOST_PFR 1 +#endif + #if !defined(AVND_USE_BOOST_PFR) +#if (__cpp_structured_bindings < 202403L) || (__cpp_pack_indexing < 202311L) || (__cplusplus < 202400L) #define AVND_USE_BOOST_PFR 1 #endif +#endif +// clang-format on #if AVND_USE_BOOST_PFR #include diff --git a/include/avnd/common/aggregates.p1061.hpp b/include/avnd/common/aggregates.p1061.hpp index 073731df..10d0e618 100644 --- a/include/avnd/common/aggregates.p1061.hpp +++ b/include/avnd/common/aggregates.p1061.hpp @@ -1,18 +1,15 @@ -#if __has_include() -#include -namespace tpl = tuplet; -#else -namespace tpl = std; -#endif + namespace avnd { namespace pfr { +AVND_INLINE constexpr auto structure_to_typelist(const auto& s) noexcept { const auto& [... elts] = s; return typelist...>{}; } +AVND_INLINE constexpr auto structure_to_tuple(const auto& s) noexcept { const auto& [... elts] = s; @@ -23,106 +20,39 @@ namespace detail { namespace sequence_tuple = ::tpl; template -constexpr auto tie_as_tuple(S&& s) noexcept +AVND_INLINE constexpr auto tie_as_tuple(S&& s) noexcept { auto&& [... elts] = static_cast(s); - return tpl::tie(elts...); + return tpl::tie(std::forward_like(elts)...); } } template -constexpr auto fields_count_impl(const T& t) noexcept +AVND_INLINE constexpr auto fields_count_impl(const T& t) noexcept { const auto& [... elts] = t; return avnd::num{}; } template -static constexpr const std::size_t tuple_size_v = fields_count(); +static constexpr const std::size_t tuple_size_v + = decltype(fields_count_impl(std::declval()))::value; template -constexpr auto& get(S&& s) noexcept +AVND_INLINE constexpr auto&& get(S&& s) noexcept { - if constexpr(I == 0) - { - auto&& [a, ... elts] = static_cast(s); - return a; - } - else if constexpr(I == 1) - { - auto&& [a, b, ... elts] = static_cast(s); - return b; - } - else if constexpr(I == 2) - { - auto&& [a, b, c, ... elts] = static_cast(s); - return c; - } - else if constexpr(I == 3) - { - auto&& [a, b, c, d, ... elts] = static_cast(s); - return d; - } - else if constexpr(I == 4) - { - auto&& [a, b, c, d, e, ... elts] = static_cast(s); - return e; - } - else if constexpr(I == 5) - { - auto&& [a, b, c, d, e, f, ... elts] = static_cast(s); - return f; - } - else if constexpr(I == 6) - { - auto&& [a, b, c, d, e, f, g, ... elts] = static_cast(s); - return g; - } - else if constexpr(I == 7) - { - auto&& [a, b, c, d, e, f, g, h, ... elts] = static_cast(s); - return h; - } - else if constexpr(I == 8) - { - auto&& [a, b, c, d, e, f, g, h, i, ... elts] = static_cast(s); - return i; - } - else if constexpr(I == 9) - { - auto&& [a, b, c, d, e, f, g, h, i, j, ... elts] = static_cast(s); - return j; - } - else if constexpr(I == 10) - { - auto&& [a, b, c, d, e, f, g, h, i, j, k, ... elts] = static_cast(s); - return k; - } - else if constexpr(I == 11) - { - auto&& [a, b, c, d, e, f, g, h, i, j, k, l, ... elts] = static_cast(s); - return l; - } - else if constexpr(I == 12) - { - auto&& [a, b, c, d, e, f, g, h, i, j, k, l, m, ... elts] = static_cast(s); - return m; - } - else if constexpr(I > 12) - { - auto&& [... elts] = static_cast(s); - return tpl::get(tpl::tie(elts...)); - } + auto&& [... elts] = static_cast(s); + return std::forward_like(elts...[I]); } template using tuple_element_t = std::decay_t(std::declval()))>; -template -constexpr auto for_each_field(S&& s, auto&& f) noexcept +template +AVND_INLINE constexpr auto for_each_field(S&& s, F&& f) noexcept { - auto&& [... elts] = std::forward(s); - (f(elts), ...); + auto&& [... elts] = static_cast(s); + ((static_cast(f)(std::forward_like(elts))), ...); } } diff --git a/include/avnd/common/for_nth.hpp b/include/avnd/common/for_nth.hpp index 771ed3cb..c3a4c1c9 100644 --- a/include/avnd/common/for_nth.hpp +++ b/include/avnd/common/for_nth.hpp @@ -23,7 +23,7 @@ constexpr void for_each_field_ref(T&& value, F&& func) #if AVND_USE_BOOST_PFR using namespace pfr; using namespace pfr::detail; - constexpr std::size_t fields_count_val + AVND_STATIC_CONSTEXPR std::size_t fields_count_val = boost::pfr::tuple_size_v>; auto t = boost::pfr::detail::tie_as_tuple( @@ -74,7 +74,7 @@ constexpr void for_each_field_ref(T&& value, F&& func) #if AVND_USE_BOOST_PFR using namespace pfr; using namespace pfr::detail; - constexpr std::size_t fields_count_val + AVND_STATIC_CONSTEXPR std::size_t fields_count_val = avnd::pfr::tuple_size_v>; auto t = avnd::pfr::detail::tie_as_tuple(value); @@ -97,9 +97,8 @@ constexpr void for_each_field_ref_n(T&& value, F&& func) #if AVND_USE_BOOST_PFR using namespace pfr; using namespace pfr::detail; - constexpr std::size_t fields_count_val + AVND_STATIC_CONSTEXPR std::size_t fields_count_val = avnd::pfr::tuple_size_v>; - auto t = avnd::pfr::detail::tie_as_tuple(value); [&](std::index_sequence) @@ -109,7 +108,9 @@ constexpr void for_each_field_ref_n(T&& value, F&& func) (std::make_index_sequence{}); #else auto&& [... elts] = value; - (func(elts), ...); + const auto [... Is] = field_indices(std::make_index_sequence{}); + + (func(elts, Is), ...); #endif } @@ -147,7 +148,7 @@ constexpr void for_each_field_function_table(T&& value, R func) #endif using namespace avnd::pfr; using namespace avnd::pfr::detail; - constexpr std::size_t fields_count_val + AVND_STATIC_CONSTEXPR std::size_t fields_count_val = avnd::pfr::tuple_size_v>; auto t = avnd::pfr::detail::tie_as_tuple(value); diff --git a/include/avnd/common/index.hpp b/include/avnd/common/index.hpp index 35c39d8c..67a18431 100644 --- a/include/avnd/common/index.hpp +++ b/include/avnd/common/index.hpp @@ -1,4 +1,6 @@ #pragma once +#include + #include #include @@ -23,6 +25,12 @@ struct field_reflection static const constexpr auto index = Idx; }; +template +static constexpr auto field_indices(std::index_sequence) +{ + return tpl::tuple...>{}; +} + template constexpr int index_of_element(const std::array& arr) noexcept { diff --git a/include/avnd/common/inline.hpp b/include/avnd/common/inline.hpp index 47c21908..caeee5a3 100644 --- a/include/avnd/common/inline.hpp +++ b/include/avnd/common/inline.hpp @@ -1,8 +1,15 @@ #pragma once -#if defined(__GNUC__) +#include +#if __cpp_constexpr >= 202211L +#define AVND_STATIC_CONSTEXPR static constexpr +#else +#define AVND_STATIC_CONSTEXPR constexpr +#endif + +#if defined(__clang__) #define AVND_INLINE inline __attribute__((always_inline)) -#elif defined(__clang__) +#elif defined(__GNUC__) #define AVND_INLINE inline __attribute__((always_inline)) #elif defined(_MSC_VER) #define AVND_INLINE inline __forceinline @@ -10,8 +17,12 @@ #define AVND_INLINE inline #endif -#if defined(__clang__) +#if defined __has_attribute +#if __has_attribute(flatten) #define AVND_INLINE_FLATTEN AVND_INLINE __attribute__((flatten)) -#else +#endif +#endif + +#if !defined(AVND_INLINE_FLATTEN) #define AVND_INLINE_FLATTEN AVND_INLINE #endif diff --git a/include/avnd/common/struct_reflection.hpp b/include/avnd/common/struct_reflection.hpp index 7567bfc5..c8c00fe6 100644 --- a/include/avnd/common/struct_reflection.hpp +++ b/include/avnd/common/struct_reflection.hpp @@ -85,7 +85,9 @@ struct fields_introspection #else // FIXME pass it the avnd::field_index auto&& [... elts] = fields; - (func(elts), ...); + const auto [... Is] = field_indices(std::make_index_sequence{}); + + (func(elts, Is), ...); #endif } @@ -117,7 +119,12 @@ struct fields_introspection template static inline constexpr auto field(type& unfiltered_fields) noexcept -> decltype(auto) { +#if AVND_USE_BOOST_PFR return pfr::get(unfiltered_fields); +#else + auto&& [... elts] = unfiltered_fields; + return std::forward_like(elts...[N]); +#endif } // Will stop if an error is encountered (func should return bool) @@ -125,6 +132,7 @@ struct fields_introspection { if constexpr(size > 0) { +#if AVND_USE_BOOST_PFR auto stack_size_helper = [&]() constexpr noexcept { return func(pfr::get(unfiltered_fields)); }; @@ -132,6 +140,10 @@ struct fields_introspection std::integer_sequence) { return (stack_size_helper.template operator()() && ...); }(indices_n{}); +#else + auto&& [... elts] = unfiltered_fields; + return (func(elts) && ...); +#endif } else { @@ -144,6 +156,7 @@ struct fields_introspection { if constexpr(size > 0) { +#if AVND_USE_BOOST_PFR auto stack_size_helper = [&]() constexpr noexcept { return func(pfr::get(unfiltered_fields)); }; @@ -151,6 +164,10 @@ struct fields_introspection std::integer_sequence) { return (stack_size_helper.template operator()() || ...); }(indices_n{}); +#else + auto&& [... elts] = unfiltered_fields; + return (func(elts) || ...); +#endif } else { @@ -283,14 +300,24 @@ struct predicate_introspection template static constexpr auto field(type& unfiltered_fields) noexcept -> decltype(auto) { +#if AVND_USE_BOOST_PFR return pfr::get(unfiltered_fields); +#else + auto& [... elts] = unfiltered_fields; + return std::forward_like(elts...[index_map[N]]); +#endif } // Gives std::tuple static constexpr auto tie(type& unfiltered_fields) { return [&](std::integer_sequence) { +#if AVND_USE_BOOST_PFR return tpl::tie(pfr::get(unfiltered_fields)...); +#else + auto&& [... elts] = unfiltered_fields; + return tpl::tie(elts...[Index]...); +#endif }(indices_n{}); } @@ -298,19 +325,31 @@ struct predicate_introspection static constexpr auto make_tuple(type& unfiltered_fields) { return [&](std::integer_sequence) { +#if AVND_USE_BOOST_PFR return tpl::make_tuple(pfr::get(unfiltered_fields)...); +#else + auto&& [... elts] = unfiltered_fields; + return tpl::make_tuple(elts...[Index]...); +#endif }(indices_n{}); } // Gives std::tuple static constexpr auto filter_tuple(type& unfiltered_fields, auto filter) { +#if AVND_USE_BOOST_PFR auto stack_size_helper = [&]() constexpr noexcept { return filter(pfr::get(unfiltered_fields)); }; return [&](std::integer_sequence) { return tpl::make_tuple(stack_size_helper.template operator()()...); }(indices_n{}); +#else + return [&](std::integer_sequence) { + auto&& [... elts] = unfiltered_fields; + return tpl::make_tuple(filter(elts...[Index])...); + }(indices_n{}); +#endif } static constexpr void for_all(type& unfiltered_fields, auto&& func) noexcept @@ -319,8 +358,13 @@ struct predicate_introspection { [&func, &unfiltered_fields](std::integer_sequence) { +#if AVND_USE_BOOST_PFR (func(pfr::get(unfiltered_fields)), ...); - }(indices_n{}); +#else + auto&& [... elts] = unfiltered_fields; + (func(elts...[Index]), ...); +#endif + }(indices_n{}); } } @@ -488,7 +532,12 @@ struct predicate_introspection if constexpr(size > 0) { [n, &func, &fields](std::integer_sequence) { +#if AVND_USE_BOOST_PFR (void)((Index == n && (func(pfr::get(fields)), true)) || ...); +#else + auto&& [... elts] = fields; + (void)((Index == n && (func(elts...[Index]), true)) || ...); +#endif }(indices_n{}); } } @@ -499,7 +548,12 @@ struct predicate_introspection { [k = index_map[n], &func, &fields](std::integer_sequence) { +#if AVND_USE_BOOST_PFR (void)((Index == k && (func(pfr::get(fields)), true)) || ...); +#else + auto&& [... elts] = fields; + (void)((Index == k && (func(elts...[Index]), true)) || ...); +#endif }(indices_n{}); } }