Skip to content

Latest commit

 

History

History
140 lines (103 loc) · 3.23 KB

201.md

File metadata and controls

140 lines (103 loc) · 3.23 KB
Info

Example

template<auto n> consteval auto sqr() {
  return sizeof(std::byte[n][n]);
}

static_assert(2*2 == sqr<2>());
static_assert(10*10 == sqr<10>());

https://godbolt.org/z/bsvKKT

Puzzle

  • Can you implement an exponent variable template which calculates the {x^n} only by leveraging sizeof operator?
template<auto X, auto N>
constexpr auto exponent = 0;

static_assert(1 == exponent<1, 1>);
static_assert(1*1*1*1 == exponent<1, 4>);
static_assert(2*2 == exponent<2, 2>);
static_assert(4*4 == exponent<4, 2>);
static_assert(5*5*5*5 == exponent<5, 4>);
static_assert(10*10*10 == exponent<10, 3>);

static_assert(0 != exponent<1, 2>);
static_assert(1 != exponent<2, 1>);
static_assert(2 != exponent<2, 2>);

https://godbolt.org/z/qqoGxs

Solutions

template<auto X, auto N>
constexpr auto dimensions(auto x) {
    if constexpr (N == 0) {
        return x;
    } else {
        return dimensions<X,N-1>(std::array<decltype(x), X>{});
    }
}

template<auto X, auto N>
constexpr auto exponent = sizeof(decltype(dimensions<X,N>(std::byte{})));

https://godbolt.org/z/j7Yh46

template <auto X, auto Y>
constexpr auto mult = sizeof(char[X][Y]);

template<auto X, auto N>
constexpr auto exponent = ((N & 1) == 0) ? mult<exponent<X, N/2>, exponent<X, N/2>> : mult<X, exponent<X, N-1>>;
template<auto X>
constexpr auto exponent<X, 0> = 1;

https://godbolt.org/z/ve6d1v

template<auto X, auto N>
constexpr auto exponent = sizeof( char[N % 2 ? X : 1][exponent<X, N / 2>][exponent<X, N / 2>] );

template<auto X>
constexpr auto exponent<X, 0> = 1;

https://godbolt.org/z/xh6xvf

template<size_t x, size_t n>
constexpr auto carr() {
    if constexpr(n==0)
        return std::array<char, 1>{};
    else
        return std::array< decltype(carr<x,n-1>()) , x>{};
}

template<auto x, auto n>
constexpr auto exponent = sizeof(carr<x,n>());

https://godbolt.org/z/19Yvs9

namespace detail {

template <auto Val>
[[nodiscard]] consteval auto mult() {
  return Val;
}

template <auto Val1, auto Val2, auto... Vals>
[[nodiscard]] consteval auto mult() {
  return mult<sizeof(std::byte[Val1][Val2]), Vals...>();
}

[[nodiscard]] consteval auto only_first(auto first, auto...) {
    return first;
}

template <auto Base, auto... PowerSequence>
[[nodiscard]] consteval auto exponent_impl(std::index_sequence<PowerSequence...>) {
  return mult<only_first(Base, PowerSequence)...>();
};

}  // namespace detail

template <auto X, auto N>
constexpr auto exponent =
    detail::exponent_impl<X>(std::make_index_sequence<N>{});

https://godbolt.org/z/zevEGe

template<class T, auto N, class U>
consteval auto operator,(std::array<T, N>, U) { return std::array<U, N>{}; }

template<auto X, auto N>
constexpr auto exponent = []<auto... Ns>(std::index_sequence<Ns...>){
  return sizeof((std::array<std::byte, (Ns, X)>{}, ...));
}(std::make_index_sequence<N>{});

https://godbolt.org/z/Yc9nY5