Question: This is probably simple but I'm not getting it right. I have a "bitmask" enum which has a value `all` that indicates that all bits are set. However, I can't get it to flip all bits using ~0. The following error appears:

```
<source>:11:16: error: enumerator value '-1' is outside the range of underlying type 'uint_fast8_t' {aka 'unsigned char'}
   11 |         all = ~0x0,
      |             

```

Which is strange because it should actually fit into uint8\_t no? Here is my code ([godbolt](https://godbolt.org/z/MYdnT7hbh)):

```
#include <iostream>

int main()
{
    enum mask_t : uint_fast8_t {
        first = 0x1,
        second = 0x2,
        all = ~0x0,
    } mask;

    mask = all;
}

```

Answer: 
You can get the maximum value with the help of some meta-programming tricks

```
#include <limits>
#include <type_traits>
#include <cstdint>

enum mask_t : uint_fast8_t {
  first = 0x1,
  second = 0x2,
  all = std::numeric_limits<std::underlying_type_t<mask_t>>::max()
} mask;

```

[Demo](https://godbolt.org/z/EcTqrj568)
By default, `0x0` is of type `int`. So if you try to flip all the bits you'll get `-1` which can't be assigned to the type your enumeration was defined to.

Even if you use a suffix for that literal value, like `u` for example. To indicate that the literal value is of unsigned type. As in `~0x0u`. You'd get the maximum of the `unsigned int` type. Which exceeds the range of the 8-bit integer type you're using. So this doesn't work either.

So you need to tell the language that you want the literal value to be of the type you need first. That can be achieved with a `static_cast` as demonstrated in other answers:

```cpp
static_cast<uint_fast8_t>( ~0x0 )

```

But using hardcoded types and values can get in the way sometimes if you decide to change the type of the enum later. So if you have c++14 available. You can use the `std::underlying_type` type-trait and make a generic utility like:

```cpp
template < class T > constexpr std::underlying_type_t< T > enum_max_v = ~static_cast< std::underlying_type_t< T > >(0);
// If you have c++17 available with the inline keyword
// template < class T > inline constexpr std::underlying_type_t< T > enum_max_v = ~static_cast< std::underlying_type_t< T > >(0);

```

And then used like:

```cpp
enum mask_t : uint_fast8_t {
    first = 0x1,
    second = 0x2,
    all = enum_max_v< mask_t >,
} mask;

```

Now you don't have to care about the underlying type of the enumeration.

You can even use `std::numeric_limits` if you want the right values instead of relying on flipping bits:

```cpp
template < class T > constexpr std::underlying_type_t< T > enum_max_v = std::numeric_limits< std::underlying_type_t< T > >::max();

```

Sky is the limit.