ug_misc 0.1
Miscellaneous C++ header library
Loading...
Searching...
No Matches
int_finder.hpp File Reference

Obtain an integer type from its width. More...

#include <cstdint>
#include <limits>
#include <string_view>
#include <type_traits>
#include "ugmisc/bitops.hpp"
#include "ugmisc/features.hpp"
#include "ugmisc/member.hpp"
#include "ugmisc/quote.hpp"

Go to the source code of this file.

Classes

struct  ugmisc::get_int_types< N >
struct  ugmisc::get_int_types< 8 >
struct  ugmisc::get_int_types< 16 >
struct  ugmisc::get_int_types< 32 >
struct  ugmisc::get_int_types< 64 >

Macros

#define UGMISC_INT_FINDER_MAX_INT_WIDTH   (1U << 12);

Typedefs

template<unsigned N>
using ugmisc::exact_unsigned_type = typename intfind_::get_int_types<N>::unsigned_type
template<unsigned N>
using ugmisc::exact_signed_type = typename intfind_::get_int_types<N>::signed_type
template<unsigned N, int_sign S>
using ugmisc::exact_int_type
template<unsigned N, int_sign S>
using ugmisc::least_int_type
template<unsigned N>
using ugmisc::least_unsigned_type = least_int_type<N, UNSIGNED>
template<unsigned N>
using ugmisc::least_signed_type = least_int_type<N, SIGNED>
template<auto V, auto... S>
using ugmisc::least_required_int_type = decltype(as_least_required_int_type<V, S...>)

Enumerations

enum  ugmisc::int_sign { INVALID_SIGN = 0 , UNSIGNED = 1 , SIGNED = 2 }
 Used to select signed or unsigned types.
enum  ugmisc::sign_opt : std::uint8_t {
  SELECT_SIGN_OPTION_NONE = 0 , SELECT_UNSIGNED = 1 , SELECT_SIGNED = 2 , ugmisc::SELECT_TYPE_SIGN = 3 ,
  ugmisc::SELECT_VALUE_SIGN = 4 , SELECT_SIGN_OPTION_MAX = SELECT_VALUE_SIGN , SELECT_SIGN_OPTION_MASK = 7
}
enum  ugmisc::sign_flag : std::uint8_t { SELECT_SIGN_FLAGS_NONE , ugmisc::SELECT_SIGN_SMALLEST = 1 << 3 , ugmisc::SELECT_SIGN_ALLOW_VALUE_SIGN_LOSS = 1 << 4 , SELECT_SIGN_FLAGS_MASK = SELECT_SIGN_SMALLEST|SELECT_SIGN_ALLOW_VALUE_SIGN_LOSS }

Functions

constexpr int_sign ugmisc::flip (int_sign s)
constexpr std::string_view ugmisc::get_name (sign_opt opt)
template<class T>
constexpr int_sign ugmisc::sign (sign_opt opt, T v)
constexpr sign_flag ugmisc::operator~ (sign_flag f)
constexpr sign_flag ugmisc::operator| (sign_flag a, sign_flag b)
constexpr bool ugmisc::smallest (sign_flag s)
constexpr bool ugmisc::allow_value_sign_loss (sign_flag s)
constexpr std::string_view ugmisc::get_name (sign_flag flags)
template<bool IncludingSignBit, class T>
constexpr int_only< T, unsigned > ugmisc::signed_bitwidth (T v)

Variables

constexpr unsigned ugmisc::max_int_width = UGMISC_INT_FINDER_MAX_INT_WIDTH
template<unsigned N, int_sign Sign>
constexpr bool ugmisc::has_int_type
template<unsigned N>
constexpr bool ugmisc::has_unsigned_type
template<unsigned N>
constexpr bool ugmisc::has_signed_type = has_int_type<N, SIGNED>
template<unsigned N>
constexpr bool ugmisc::has_both_int_types
template<unsigned N>
constexpr bool ugmisc::has_either_int_type
template<auto V, auto... S>
constexpr auto ugmisc::as_least_required_int_type

Detailed Description

Obtain an integer type from its width.

To support non-standard ints (like a 128 bit int), just specialise ugmisc::get_int_types.

It has to have a member called "unsigned_type" and a member called "signed_type", if both are supported. You may provide just one of them if only the signed or unsigned type exists.

Utilities

Exact Integral Type

Using the ugmisc::exact_int_type template type alias, a type of a required number of bits and signedness can be obtained, if it exists, including types the user added by specialising ugmisc::get_int_types.

There are boolean template variables to determine if a type exists:

Least Integral Type

The ugmisc::least_int_type template type alias can be used to find a signed or unsigned integral type with at least a specified number of bits.

Required Integral Type

It is possible to find the smallest integral type which can encode a specified number, using ugmisc::least_required_int_type, or convert the value to the selected type using the template variable ugmisc::as_least_required_int_type.

These templates take one (or more, but that is redundant) ugmisc::sign_opt values as parameters, and any number of ugmisc::sign_flag values.

Macro Definition Documentation

◆ UGMISC_INT_FINDER_MAX_INT_WIDTH

#define UGMISC_INT_FINDER_MAX_INT_WIDTH   (1U << 12);

This may be predefined for testing purposes, but should normally be left alone.

Typedef Documentation

◆ exact_int_type

template<unsigned N, int_sign S>
using ugmisc::exact_int_type
Initial value:
typename intfind_::get_exact_int_type<N, S>::type

An integer type with exactly N bits.

◆ exact_signed_type

template<unsigned N>
using ugmisc::exact_signed_type = typename intfind_::get_int_types<N>::signed_type

◆ exact_unsigned_type

template<unsigned N>
using ugmisc::exact_unsigned_type = typename intfind_::get_int_types<N>::unsigned_type

◆ least_int_type

template<unsigned N, int_sign S>
using ugmisc::least_int_type
Initial value:
std::enable_if_t<
intfind_::find_type<N, S>(),
decltype(intfind_::find_type<N, S>())
>

A type with at least N bits.

See also
least_unsigned_type
least_signed_type

◆ least_required_int_type

template<auto V, auto... S>
using ugmisc::least_required_int_type = decltype(as_least_required_int_type<V, S...>)

An integer type with enough bits to represent the value V.

Template Parameters
SDetermines how the type should be selected. This should include one ugmisc::sign_opt parameter and optionally some ugmisc::sign_flag parameters. sign_flag parameters may be provided separately or combined using the bitwise or operator.

◆ least_signed_type

template<unsigned N>
using ugmisc::least_signed_type = least_int_type<N, SIGNED>

◆ least_unsigned_type

template<unsigned N>
using ugmisc::least_unsigned_type = least_int_type<N, UNSIGNED>

Enumeration Type Documentation

◆ sign_flag

enum ugmisc::sign_flag : std::uint8_t
Enumerator
SELECT_SIGN_SMALLEST 

A flag which indicates finding a small type is the most important thing. This only matters if for some integer widths there is an unsigned type but not a signed type, or vice versa.

In this case the desired signedness will be abandoned if it allows a smaller type to be chosen, and if the requirements of the other flags can be satisfied.

SELECT_SIGN_ALLOW_VALUE_SIGN_LOSS 

Flag which allows a chosen type to be unsigned even when the value it needs to accomodate is negative. Space is still reserved for the sign bit regardless of this.

◆ sign_opt

enum ugmisc::sign_opt : std::uint8_t

Used to select signed or unsigned types based on values.

Usually the types ugmisc::sign_opt and ugmisc::sign_flag are used instead; when they are combined they can turn into one of these enum values, and can be initialised from them too.

See also
ugmisc::least_required_int_type
Enumerator
SELECT_TYPE_SIGN 

Select a type with the same sign as the value type.

SELECT_VALUE_SIGN 

Select a signed type iff the value is negative.

Function Documentation

◆ signed_bitwidth()

template<bool IncludingSignBit, class T>
int_only< T, unsigned > ugmisc::signed_bitwidth ( T v)
constexpr

Like ugmisc::bitwidth but also allows signed integer parameters.

This is useful for defining ugmisc::least_required_int_type, but is considered part of the public interface because it may be generally useful.

Template Parameters
IncludingSignBitIf true, and T is a signed type, the returned value will be one larger, to account for the space needed for a sign bit. Otherwise only the bits needed to distinguish one magnitude from another will be kept.
Note
This only works if there is an unsigned integral type of the same size as T or larger.
Returns
If T is negative, the number of bits on the right which, when sign extended to the whole width of T, will restore the original value of v, unless IncludingSignBit is false, in which case the sign bit will be omitted, so the result will be one less.

Variable Documentation

◆ as_least_required_int_type

template<auto V, auto... S>
auto ugmisc::as_least_required_int_type
inlineconstexpr
Initial value:
=
intfind_::as_least_required_type<V, S...>()

Converts V to a type determined by S and the value of V.

The trailing parameters are used to construct the option and flags which determine how to choose a type. If multiple options are provided, they must all be the same option. Multiple values of the ugmisc::sign_flag enum type may be combined with the | operator, or may be provided as separate template parameters.

Template Parameters
SAt least one (usually one) sign_opt and any number of sign_flag values, or alternatively a flag_opt_combo encapsulating both.
See also
ugmisc::least_required_int_type

◆ has_both_int_types

template<unsigned N>
bool ugmisc::has_both_int_types
inlineconstexpr
Initial value:
=
constexpr bool has_unsigned_type
Definition int_finder.hpp:585
constexpr bool has_signed_type
Definition int_finder.hpp:589
See also
ugmisc::has_int_type

◆ has_either_int_type

template<unsigned N>
bool ugmisc::has_either_int_type
inlineconstexpr

◆ has_int_type

template<unsigned N, int_sign Sign>
bool ugmisc::has_int_type
inlineconstexpr
Initial value:
=
Sign == UNSIGNED
? intfind_::has_member_type_unsigned_type< intfind_::get_int_types<N> >
: intfind_::has_member_type_signed_type< intfind_::get_int_types<N> >

Find out if a certain integral type is supported.

Template Parameters
NNumber of bits.
Signugmisc::UNSIGNED or ugmisc::SIGNED.

Support for an integral type is provided by specialising ugmisc::get_int_types. The standard 8, 16, 32, and 64 bit signed and unsigned types have support built in, but the user may add more.

Return values
trueThe type is supported.
falseThe type is not supported.

◆ has_signed_type

template<unsigned N>
bool ugmisc::has_signed_type = has_int_type<N, SIGNED>
inlineconstexpr

◆ has_unsigned_type

template<unsigned N>
bool ugmisc::has_unsigned_type
inlineconstexpr
Initial value:
=
constexpr bool has_int_type
Definition int_finder.hpp:577
See also
ugmisc::has_int_type

◆ max_int_width

unsigned ugmisc::max_int_width = UGMISC_INT_FINDER_MAX_INT_WIDTH
inlineconstexpr

This is usually 4096 bits. If you need more than that (or less, for testing) the macro UGMISC_INT_FINDER_MAX_INT_WIDTH may be predefined before including ugmisc/int_finder.hpp.