Skip to content

Latest commit

 

History

History
125 lines (95 loc) · 3.09 KB

363.md

File metadata and controls

125 lines (95 loc) · 3.09 KB
Info

Example

struct foo {
  std::size_t bar;
};

int main() {
  std::cout << std::meta::offset_of(^foo::bar); // 0
  std::cout << std::meta::size_of(^foo::bar); // 8
  std::cout << std::meta::alignment_of(^foo::bar); // 8
}

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

Puzzle

  • Can you implement layout function which returns a range of desc describing the layout for given type T?
struct foo {
  char a;
  int b;
  float c;
};

struct desc {
  std::size_t size{};
  std::size_t offset{};
  std::size_t alignment{};
  constexpr auto operator<=>(const desc&) const = default;
};

template<class T, class TDesc>
concept range_of = std::ranges::range<T> and std::same_as<std::ranges::range_value_t<T>, TDesc>;

template<class T>
[[nodiscard]] constexpr auto layout() -> range_of<desc> auto; // TODO

static_assert(std::array{desc{1u, 0u, 1u}, desc{4u, 4u, 4u}, desc{4u, 8u, 4u}} == layout<foo>());

https://godbolt.org/z/o5KKe9jhK

Solutions

struct foo {
 char a;
 int b;
 float c;
};

struct desc {
 std::size_t size{};
 std::size_t offset{};
 std::size_t alignment{};
 constexpr auto operator<=>(const desc&) const = default;
};

template<class T, class TDesc>
concept range_of = std::ranges::range<T> and std::same_as<std::ranges::range_value_t<T>, TDesc>;

consteval std::size_t vectorSize(auto vec) noexcept {                                                      
 return vec.size();             
}    

template <typename T>
[[nodiscard]] constexpr auto layout() noexcept -> range_of<desc> auto {
 std::array<desc, vectorSize(std::meta::nonstatic_data_members_of(^T))> layouts;
 int index = 0;
 [: expand(std::meta::nonstatic_data_members_of(^T)) :] >> [&layouts, &index]<auto t>() mutable {
     layouts[index] = desc {.size = size_of(t), .offset = offset_of(t), .alignment = alignment_of(t)};
     index ++;
 };
 return layouts;
}

https://godbolt.org/z/5aeG5xKaE

struct foo {
    char a;
    int b;
    float c;
};

struct desc {
    std::size_t size{};
    std::size_t offset{};
    std::size_t alignment{};
    constexpr auto operator<=>(const desc&) const = default;
};

template <class T, class TDesc>
concept range_of = std::ranges::range<T> and std::same_as<std::ranges::range_value_t<T>, TDesc>;

template <class T>
[[nodiscard]] constexpr auto layout() -> range_of<desc> auto {
    std::array<desc, std::size(nonstatic_data_members_of(^T))> layout{};
    [:expand(nonstatic_data_members_of(^T)):] >> [&, i = 0]<auto V>() mutable {
        layout[i++] = {.size = std::meta::size_of(V),
                       .offset = std::meta::offset_of(V),
                       .alignment = std::meta::alignment_of(V)};
    };
    return layout;
}

static_assert(std::array{desc{1u, 0u, 1u}, desc{4u, 4u, 4u}, desc{4u, 8u, 4u}} == layout<foo>());

https://godbolt.org/z/564szqv6M