Skip to content

Latest commit

 

History

History
167 lines (127 loc) · 3.57 KB

288.md

File metadata and controls

167 lines (127 loc) · 3.57 KB
Info

Example

void foo1(int*);
void foo2(int[42]);
void foo3(int[]);
void foo4(int(&)[42]);

int main() {
    int a[42]{};
    foo1(a); // ok
    foo2(a); // ok
    foo3(a); // ok
    foo4(a); // ok
}

https://godbolt.org/z/3qn8rM7Ee

Puzzle

  • Can you implement array_size which returns the size of given array?
[[nodiscard]] consteval auto array_size(auto); // TODO

static_assert(1uz == [] { bool a[]{{}}; return array_size(a); }());
static_assert(3uz == [] { int a[]{{}, {}, {}}; return array_size(a); }());
static_assert(42uz == [] { int a[42]{}; return array_size(a); }());

static_assert(0uz == array_size(std::array<bool, 0>{}));
static_assert(3uz == array_size(std::array<int, 3>{}));
static_assert(42uz == array_size(std::array<char, 42>{}));

static_assert(1uz == array_size(std::vector{1}));
static_assert(3uz == array_size(std::vector{1, 2, 3}));

https://godbolt.org/z/3Gec1YqM1

Solutions

[[nodiscard]] consteval auto array_size(auto&& x) {
    return std::size(x);
}

https://cpp_tip_of_the_week.godbolt.org/z/jWYnhnqos

template< typename T, size_t N > constexpr size_t array_size (T (&) [N]){ return N; }
template< typename T> constexpr auto array_size (T && t){ return t.size(); }

https://godbolt.org/z/1zY5Pdn8P

[[nodiscard]] consteval auto array_size(auto&& arr){
    if constexpr(std::is_array_v<std::remove_cvref_t<decltype(arr)>>) {
        return sizeof(arr) / sizeof(arr[0]);
    }
    else {
        return std::size(arr);
    }
}

https://godbolt.org/z/vdEn5Yf9x

template <typename T, auto N>
[[nodiscard]] consteval auto array_size(T(&)[N]) { return N; }

template <typename T>
requires requires { std::declval<T>().size(); }
[[nodiscard]] constexpr auto array_size(T&& t) {
  return t.size();
}

https://godbolt.org/z/1xdTY6aev

template <typename T, std::size_t N>
[[nodiscard]] consteval auto array_size(T(&)[N]) { return N; }

template <typename T>
requires requires { std::declval<const T &>().size(); }
[[nodiscard]] consteval auto array_size(const T& array) { return array.size(); }

https://godbolt.org/z/c9dds6MY6

[[nodiscard]] consteval auto array_size(const auto& t) {
    return std::size(t);
}

https://godbolt.org/z/81777x44Y

template<typename T, std::size_t N>
[[nodiscard]] consteval std::size_t array_size(T(&)[N]){
  return N;
}

[[nodiscard]] consteval std::size_t array_size(auto x){
  return std::size(x);
}

https://godbolt.org/z/bn9scvvrq

template <std::size_t sz>
[[nodiscard]] consteval auto array_size(const auto (& my_array)[sz])
{
    return sz;
}

template <class T, std::size_t sz>
[[nodiscard]] consteval auto array_size(const std::array<T, sz>&)
{
    return sz;
}

[[nodiscard]] consteval auto array_size(const auto& v)
{
    return std::size(v);
}

https://godbolt.org/z/ex5jhv3q1

template <class T, std::size_t N>
[[nodiscard]] consteval auto array_size(T (&)[N]){
  return N;
}
[[nodiscard]] consteval auto array_size(auto aa){
  if constexpr (requires { aa.size(); }) {
    return aa.size();
  }
}

https://godbolt.org/z/1b9x8dfPz

[[nodiscard]] consteval auto array_size(auto &&ar){
    if constexpr (requires {ar.size();})
        return ar.size();
    else
        return sizeof(ar) / sizeof(ar[0]);
}

https://godbolt.org/z/bGb7EzaGM