Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deducing the type of an integer by its compiletime value

Tags:

c++

c++20

Using C++14, 17 or 20, I am passing two template parameters to a templated class: TSize and MaxSize.

TSize is the type of MaxSize. Obviously, both are known at compile time. TSize needs to be big enough to fit MaxSize.

template <typename TSize = uint8_t, TSize MaxSize = 15>
class Foo {};

How can I automatically deduce TSize by the value of MaxSize, so I have it automatically by just setting the value of MaxSize? i.e.:

if MaxSize<256 -> TSize=uint8_t
if MaxSize<65536 && MaxSize>255 -> TSize=uint16_t

Many thanks for your help!

like image 480
Mihai Galos Avatar asked May 16 '20 18:05

Mihai Galos


People also ask

When to use type deduction in C++?

There are just too many contexts where type deduction takes place: in calls to function templates, in most situations where auto appears, in decltype expressions, and, as of C++14, where the enigmatic decltype (auto) construct is employed. This chapter provides the information about type deduction that every C++ developer requires.

What is the set of values for an integer type?

The set of values for a signed integer type is the (infinite) set of mathematical integers, though only values of the base range of the type are fully supported for run-time operations. The set of values for a modular integer type are the values from 0 to one less than the modulus, inclusive. 9

What is the use of int i in Java?

It is a type of String which will be parsed into an integer object. This is of integer type and used in converting the string object. Returns an Integer instance holding the value of the specified parameter int i. Returns an Integer instance holding the value represented by the string argument.

How are data types declared in C++ 11?

Before C++ 11, each data type needed to be explicitly declared at compile-time, limiting the values of an expression at runtime but after the new version of C++, many keywords are included which allows a programmer to leave the type deduction to the compiler itself.


2 Answers

You can use something like this:

template<uintmax_t n>
using FittingUIntT = std::conditional_t<
    n <= UINT8_MAX, uint8_t, std::conditional_t<
    n <= UINT16_MAX, uint16_t, std::conditional_t<
    n <= UINT32_MAX, uint32_t, uint64_t
>>>;

Demo

like image 113
Nelfeal Avatar answered Oct 30 '22 10:10

Nelfeal


You can use std::conditional to choose between two types based on a compiletime condition. And if you don't want to change Foo you'll need some indirection to pick the right type for Foo (maybe partial specialization would do as well):

#include<type_traits>

template <typename TSize = uint8_t, TSize MaxSize = 15>
class Foo {};

template <unsigned value>
using Size_t_impl = typename std::conditional<(value > 255),uint16_t,uint8_t>::type;

template <unsigned value>
using FooIndirect = Foo< Size_t_impl<value>,value>;
like image 31
463035818_is_not_a_number Avatar answered Oct 30 '22 12:10

463035818_is_not_a_number