MSVC bug report: <url:
https://developercommunity.visualstudio.com/content/problem/1067774/ice-internal-compiler-error-on-constexpr-range-bas.html>
Since the msvc compiler crashes I have only g++'s word that the
following code is valid.
Is it?
---------------------------------------------------------------------------
#include <limits.h> // CHAR_BIT
#include <stdint.h> // int...
#include <bitset>
#include <initializer_list>
#include <iostream>
#include <string>
#include <type_traits>
template< class Type >
constexpr int bits_per_ = sizeof( Type )*CHAR_BIT;
namespace impl {
template< int n_bits > struct Int_t_;
template<> struct Int_t_<8>{ using T = int8_t; };
template<> struct Int_t_<16>{ using T = int16_t; };
template<> struct Int_t_<32>{ using T = int32_t; };
template<> struct Int_t_<64>{ using T = int64_t; };
// TODO: conditional definition for 128-bits.
} // namespace impl
template< int n_bits > using Int_ = typename impl::Int_t_<n_bits>::T;
template< int n_bits > using Unsigned_int_ =
std::make_unsigned_t<Int_<n_bits>>;
template<
class Enum,
int n_bits = bits_per_<void*>,
class = std::enable_if_t<std::is_enum_v<Enum>>
>
class Bitset
{
using Integer = std::underlying_type_t<Enum>;
using Bits = Unsigned_int_<n_bits>;
Bits m_bits;
public:
constexpr Bitset( const std::initializer_list<Enum>& values ):
m_bits()
{
for( const Enum v: values ) {
const auto i = static_cast<Integer>( v );
if( i < 0 or i > n_bits ) {
throw "Ugga bugga";
}
m_bits |= (Bits( 1 ) << i);
}
}
};
enum Values {one, two, three, five, seven};
auto main()
-> int
{
constexpr auto x = Bitset({ one, two, five });
// constexpr auto y = Bitset({ 1, 2, 5 });
(void) x;
}
#include <cppx-core-language/all.hpp>
#include <limits.h> // CHAR_BIT
#include <stdint.h> // int...
#include <bitset>
#include <initializer_list>
#include <iostream>
#include <string>
#include <type_traits>
template< class Type >
constexpr int bits_per_ = sizeof( Type )*CHAR_BIT;
namespace impl {
template< int n_bits > struct Int_t_;
template<> struct Int_t_<8>{ using T = int8_t; };
template<> struct Int_t_<16>{ using T = int16_t; };
template<> struct Int_t_<32>{ using T = int32_t; };
template<> struct Int_t_<64>{ using T = int64_t; };
// TODO: conditional definition for 128-bits.
} // namespace impl
template< int n_bits > using Int_ = typename impl::Int_t_<n_bits>::T;
template< int n_bits > using Unsigned_int_ =
std::make_unsigned_t<Int_<n_bits>>;
template<
class Enum,
int n_bits = bits_per_<void*>,
class = std::enable_if_t<std::is_enum_v<Enum>>
>
class Bitset
{
using Integer = std::underlying_type_t<Enum>;
using Bits = Unsigned_int_<n_bits>;
Bits m_bits;
public:
constexpr Bitset( const std::initializer_list<Enum>& values ):
m_bits()
{
for( const Enum v: values ) {
const auto i = static_cast<Integer>( v );
if( i < 0 or i > n_bits ) {
throw "Ugga bugga";
}
m_bits |= (Bits( 1 ) << i);
}
}
};
enum Values {one, two, three, five, seven};
auto main()
-> int
{
constexpr auto x = Bitset({ one, two, five });
// constexpr auto y = Bitset({ 1, 2, 5 });
(void) x;
}
---------------------------------------------------------------------------
- Alf