Обновить
2
0
Дамир@X-Ray_3D

Пользователь

Отправить сообщение

В функции get_members_inf() сортировка такая

std::ranges::sort(res, std::greater{}, &MemberInfo::align);

должна быть. Но и с возрастанием тесты тоже проходит...

Что-то такое будет примерно.

https://godbolt.org/z/j8qnfe98f

auto print = [](auto&& array) {
    for (auto&& [name, val] : array)
        std::println("{: <15}:{:13.6f}", name, val);
};
std::println("============ VPN ============");
std::println("Count          : {}", 131184);
std::println("\nFill");
print(Fill);
std::println("\nSearch");
print(Search);

Можно ещё и так хранилище объявить.

https://godbolt.org/z/4Y8o6fW7M

struct storage;
consteval {
    // Получаем всю необходимую нам информацию о типах
    constexpr auto info = get_members_info();
    meta::info members[sizeof...(Ts)];
    template for(constexpr std::size_t I: 
        std::define_static_array(std::views::iota(0u, sizeof...(Ts))))
        members[I] =
            meta::data_member_spec(^^Ts...[info[I].original_idx]);
    // Создаём поля структуры storage для хранения данных
    meta::define_aggregate(^^storage, members);
}
alignas(Ts...) storage data;

Ну раз уж речь пошла за С++26, то давайте мыслить ещё шире и глубже)) Порефлексируем немного)))

https://godbolt.org/z/4cfWxj54n

#include <meta>

namespace meta = std::meta;

template <typename... Ts>
class tuple {
    struct MemberInfo {
        std::size_t original_idx;
        std::size_t align;
    };

    consteval static auto get_members_info() {
        // Для каждого Ts сохраняем его исходный индекс относительно Ts...,
        // alignof
        std::size_t idx {};
        std::array res {
            MemberInfo { idx++, alignof(Ts) }...
        };

        // Сортируем полученный массив по требуемым выравниваниям, чтобы
        // получить оптимальное размещение
        std::ranges::sort(res, {}, &MemberInfo::align);
        return res;
    }

    struct storage;
    consteval {
        []<std::size_t... I>(std::index_sequence<I...> idx) {
            // Получаем всю необходимую нам информацию о членах
            constexpr static auto info = get_members_info();
            // Создаём поля структуры storage для хранения данных
            meta::define_aggregate(^^storage, 
                { meta::data_member_spec(^^Ts...[info[I].original_idx])... });
        }(std::make_index_sequence<sizeof...(Ts)>());
    }
    alignas(Ts...) storage data;

public:
    template <typename... Tas>
    constexpr tuple(Tas&&... args) {
        // Криво, не знаю, как сделать лучше.
        static_assert(sizeof...(Tas) <= sizeof...(Ts));
        template for (constexpr std::size_t I : std::define_static_array(std::views::iota(0u, sizeof...(Tas))))
            get<I>() = std::forward<Tas...[I]>(args...[I]);    }

    template <std::size_t I>
    constexpr auto&& get(this auto&& self) noexcept {
        constexpr static auto ctx = meta::access_context::unchecked();
        constexpr static auto data_members = std::define_static_array(meta::nonstatic_data_members_of(^^storage, ctx));
        constexpr static auto info = get_members_info();

        constexpr static auto it = std::ranges::find(info, I, &MemberInfo::original_idx);

        // Если его не оказалось — пользователь указал некорректный индекс
        // Выводим красивое сообщение об ошибке
        static_assert(it < info.end(), "get<I>() access out of bounds");
        return std::forward_like<decltype(self)>(
            self.data.[:data_members[std::distance(info.begin(), it)]:]);
    }

    constexpr ~tuple() = default;

    template <size_t I>
    friend auto get(tuple&& ty) { return ty.get<I>(); }
};

namespace std {

template <typename... Ts>
struct tuple_size<::tuple<Ts...>> : std::integral_constant<size_t, sizeof...(Ts)> { };

template <std::size_t I, typename... Ts>
struct tuple_element<I, ::tuple<Ts...>> { using type = Ts...[I]; };

} // namespace std

// Corner case: пустой tuple. 
// Проще всего реализовать его как специализацию
template <>
struct tuple<> { };

namespace Impl {

namespace ranges = std::ranges;
using std::array;
using std::string_view;

template <class Ty>
inline constexpr bool hasStrings = false;

template <class Ty>
inline constexpr Ty Tokens = Ty{};

template <auto EnumVal>
static consteval auto enumName() {
#ifdef _MSC_VER
    // MSVC: auto __cdecl Impl::enumName<align::CM>(void)
    constexpr string_view sv{__FUNCSIG__};
    constexpr size_t last = sv.find_last_of(">");
#else
    // clang: auto Impl::name() [E = align::CM]
    // gcc: consteval auto Impl::name() [with auto E = align::CM]
    constexpr string_view sv{__PRETTY_FUNCTION__};
    constexpr auto last = sv.find_last_of("]");
#endif
    constexpr size_t first = sv.find_last_of(":", last) + 1;
    array<char, last - first + 1> buf{}; // +1 '\0' tetminated c_str
    ranges::copy(string_view{sv.data() + first, last - first}, buf.begin());
    return buf;
}

template <auto EnumVal>
inline constexpr auto ENameArr{enumName<EnumVal>()};
template <auto EnumVal>
inline constexpr string_view EnumName{ENameArr<EnumVal>.data(), ENameArr<EnumVal>.size() - 1};

template <typename Enum, auto... Enums>
class Tokenizer {
    struct Data {
        string_view name;
        Enum value;
    };
    static constexpr array tokens{
        Data{EnumName<Enums>, Enums}
        ...
    };
    using Ty = std::underlying_type_t<Enum>;
    static constexpr Enum errorValue{static_cast<Enum>(std::numeric_limits<Ty>::max())};

public:
    static constexpr auto toString(Enum e) noexcept {
        auto it = ranges::find(tokens, e, &Data::value);
        return it == tokens.end() ? string_view{""} : it->name;
    }
    static constexpr Enum toEnum(string_view str) noexcept {
        auto it = ranges::find(tokens, str, &Data::name);
        return it == tokens.end() ? errorValue : it->value;
    }
};

} // namespace Impl

#define XML_ENUM(Enum, ...)
    enum class Enum : int {                                                            \
        __VA_ARGS__                                                                    \
    };                                                                                 \
    inline auto operator+(Enum e) noexcept { return std::underlying_type_t<Enum>(e); } \
    namespace Impl {                                                                   \
    template <>                                                                        \
    inline constexpr auto hasStrings<Enum> = true;                                     \
    template <>                                                                        \
    inline constexpr auto Tokens<Enum> = [] {                                          \
        using enum Enum; /* using enum ↓  P1099R5 */                                 \
        return Tokenizer<Enum, __VA_ARGS__>{};                                         \
    }();                                                                               \
    }

template <typename E, typename Enum = std::remove_cvref_t<E>>
    requires Impl::hasStrings<Enum>
inline constexpr auto enumToString(E e) {
    return Impl::Tokens<Enum>.toString(e);
}

template <typename E, typename Enum = std::remove_cvref_t<E>>
    requires Impl::hasStrings<Enum>
inline constexpr E stringToEnum(std::string_view str) {
    return Impl::Tokens<Enum>.toEnum(str);
}

// Параметр надписей (ярлыков): способ выравнивания текста. Значение по умолчанию – CM.
XML_ENUM(align,
    CM, // по центру
    LT, // по левому верхнему углу
    CT, // по верхнему краю
    RT, // по правому верхнему углу
    LM, // по левому краю
    RM, // по правому краю
    LB, // по левому нижнему углу
    CB, // по нижнему краю
    RB  // по правому нижнему углу
)
  

Наконец-то без макродристни это по-человечески просто писать можно будет.

enum class align{
    CM, // по центру
    LT, // по левому верхнему углу
    CT, // по верхнему краю
    RT, // по правому верхнему углу
    LM, // по левому краю
    RM, // по правому краю
    LB, // по левому нижнему углу
    CB, // по нижнему краю
    RB  // по правому нижнему углу
};

Не удивительно, что у них постоянные опоздания и изменения в расписании))))

Чтобы было. Я так понял, комитет хочет всё в компайлтайме разрешить, чтобы разрабы голову не ломали, что можно, а что нельзя.

Лучше бы аннотацию к классу добавили, чтобы везде constexpr не расписывать по аналогии с final.

class Class constexpr {...};
struct Struct constexpr {...};

Если нужно именно mingw64, то проще из MSYS2 поставить.

boost::pfr умеет в имена полей с 1.85 по моему. Я на нём сериализатор xml с атрибутами и json в обе стороны писал. https://github.com/XRay3D/TopoR

Лучше что-нибудь из @ или $ выбрали бы.

MSYS2 под фоточками решило мои проблемы.

template <typename This, typename Widget, auto Func>
struct Helper {
    This* this_;
    auto& operator=(const auto& arg) const {
        auto widget = dynamic_cast<Widget*>(this_->parent());
        auto index = widget->indexOf(this_);
        if constexpr(requires { (widget->*Func)(index, arg); }) // <==
            (widget->*Func)(index, arg);
        else
            (widget->*Func)(index);
        return *this;
    }
};

Вы уже рефлексию ждёте, а я только недавно узнал, что в if constexpr requires-expression можно использовать.

https://www.erkon-nn.ru/catalog/nabory-rezistorov-deliteli/

Правда, политика оставляет желать лучшего. Упоротые совки в отделе продаж до сих пор. Цену не выудить. АО «ЭЛЕКОНД»‎ хоть за 22-й цены на обозрение выставил, а эти всё какие-то запросы ожидают.

Я обычно пишу:

bool function(Arg ... arg){
  bool result{};
  do {
    <...>
    if(cond) break;
    <...>
    if(cond) break;
    <...>
    if(cond) break;
    <...>
    result = true; // например
  } while(false);
  if(!result) {
    <...>
  }
  return result; 
}

ПыСы: товарищь сверху, оказывается, уже предложил. Коменты не дочитал)))

Пяток строчек на CMake и готово, а не вот это всё)))

С:\junkyard, а на латинице, чтобы ПО всякое мозги не выносило.

Поправьте в конце: «... а вот 2-3 мая прийти на московскую площадку лично».

Почти все мои питомцы Qt based ))) https://github.com/XRay3D/GERBER_X3

Видимо электричество на западе дорожает и они не хотят тратить его на тепло производимое мусорками и рефкоунтерами в разных языках)))

Информация

В рейтинге
Не участвует
Откуда
Зеленоград, Москва и Московская обл., Россия
Зарегистрирован
Активность