Does C++17 (or earlier but not c++20) allow this?
I need a type_traited conditional class, like a bitset with an internal 32 or 64 unsigned integer storage, depending if the template argument N is lesser then 32 or greater (please forget about more than 64 bits).
But the constraint is to finally implement two and only two classes for all possible cases. Next source code defines the problem using static and running time asserts:
Coliru link: http://coliru.stacked-crooked.com/a/d53a5b00bd828fb5
#include <cassert>
#include <iostream>
#include <type_traits>
struct bitset32
{
bitset32() : bits(0) { }
bitset32(int _bits) : bits(_bits) { }
const int bits;
uint32_t value;
};
struct bitset64
{
bitset64() : bits(0) { }
bitset64(int _bits) : bits(_bits) { }
const int bits;
uint64_t value;
};
template <int N>
using bitset = std::conditional_t<(N<=32), bitset32, bitset64>;
int main ()
{
static_assert(std::is_same<bitset<1>, bitset<2>>::value);
static_assert(std::is_same<bitset<33>, bitset<34>>::value);
static_assert(!std::is_same<bitset<1>, bitset<33>>::value);
bitset<1> var1;
bitset<15> var2;
bitset<32> var3;
bitset<64> var4;
assert(var1.bits == 1);
assert(var2.bits == 15);
assert(var3.bits == 32);
assert(var4.bits == 64);
}
Any solution is welcomend even if it changes the basic types and uses inheritance or whatever other mechanism necessary, but please, do not offer using a template function returning an object in the style of template<int N> make_bitset { return Bitset<N>(N); }
because it is needed to implement variables using this constructo Bitset<N> variable_name
.
A new hypothesis, CTAD based
#include <cstdint>
#include <iostream>
#include <type_traits>
template <std::size_t>
struct BitSet;
template <>
struct BitSet<32u>
{
template <typename ... Ts>
BitSet (Ts...) {}
std::uint32_t value;
};
template <>
struct BitSet<64u>
{
template <typename ... Ts>
BitSet (Ts...) {}
std::uint64_t value;
};
template <typename ... Ts>
BitSet (Ts...) -> BitSet<(32 < sizeof...(Ts) ? 64u : 32u)>;
int main()
{
auto b1 = BitSet{1};
auto b2 = BitSet{2};
auto b3 = BitSet{0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
auto b4 = BitSet{0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49};
static_assert( std::is_same_v<decltype(b1), decltype(b2)> );
static_assert( std::is_same_v<decltype(b1), BitSet<32u>> );
static_assert( std::is_same_v<decltype(b3), decltype(b4)> );
static_assert( std::is_same_v<decltype(b3), BitSet<64u>> );
}