UgMisc 0.3
Miscellaneous C++ header library
Loading...
Searching...
No Matches
int_finder.hpp File Reference

Obtain an integer type from its width, or from some values that must be representable. 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"
#include "ugmisc/sfinae_helpers.hpp"
#include "ugmisc/templated_callable_loop.hpp"
#include "ugmisc/typelist.hpp"

Go to the source code of this file.

Classes

struct  ugmisc::get_int_types< N >
class  ugmisc::least_required_int_type_finder< V1 >

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 Sign>
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>
using ugmisc::least_required_int_type
template<auto... V>
using ugmisc::least_required_int_type_multi = least_required_int_type<V...>
template<auto... V>
using ugmisc::least_required_int_std_sequence
template<auto... V>
using ugmisc::least_required_int_type_list

Enumerations

enum  ugmisc::int_sign { INVALID_SIGN = 0 , UNSIGNED = 1 , SIGNED = 2 }
 Used to select signed or unsigned types. More...
enum  ugmisc::sign_opt : std::uint8_t {
  SELECT_SIGN_OPTION_NONE = 0 , ugmisc::SELECT_UNSIGNED = 1 , ugmisc::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)
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)
std::string_view ugmisc::get_name (sign_flag flags)
template<bool IncludingSignBit, Int T>
constexpr unsigned ugmisc::signed_bitwidth (T v)
template<auto... V>
constexpr auto ugmisc::to_least_required_int_type ()

Variables

template<auto... FlagOpts>
constexpr auto ugmisc::combined = intfind_::combine_flags_opts<FlagOpts...>()
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<unsigned N, int_sign Sign>
constexpr bool ugmisc::has_sufficient_int_type
template<auto... V>
constexpr auto ugmisc::as_least_required_int_type

Detailed Description

Obtain an integer type from its width, or from some values that must be representable.

Note
The sample program int_finder demonstrates the use of this header.

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 all of a list of specified numbers, using ugmisc::least_required_int_type, or convert a single value to its selected type using the template variable ugmisc::as_least_required_int_type, or the template function ugmisc::to_least_required_int_type.

The numbers can be converted into a std::integer_sequence or a ugmisc::typelist containing std::integral_constant types, using ugmisc::least_required_int_std_sequence and ugmisc::least_required_int_type_list respectively.

Definition in file int_finder.hpp.

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.

Definition at line 467 of file int_finder.hpp.

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.

Definition at line 674 of file int_finder.hpp.

◆ exact_signed_type

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

Definition at line 638 of file int_finder.hpp.

◆ exact_unsigned_type

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

Definition at line 635 of file int_finder.hpp.

◆ least_int_type

template<unsigned N, int_sign Sign>
using ugmisc::least_int_type
Initial value:
decltype(
intfind_::template_callable_find<N, max_int_width, intfind_::type_finder<Sign>>()
)

A type with at least N bits.

See also
least_unsigned_type
least_signed_type
has_sufficient_int_type

Definition at line 727 of file int_finder.hpp.

◆ least_required_int_std_sequence

template<auto... V>
using ugmisc::least_required_int_std_sequence
Initial value:

Finds the type T = ugmisc::least_required_int_type<V...>, then returns a std::integer_sequence in which T is the integer type used, and the values are all of the V parameters which are integer values (rather than options and flags), cast to T.

Definition at line 1273 of file int_finder.hpp.

◆ least_required_int_type

template<auto... V>
using ugmisc::least_required_int_type
Initial value:

An integer type with enough bits to represent all the values in V.

Template Parameters
VIncludes values that must be representable, and the options and flags which determines 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.
See also
ugmisc::least_required_int_type_finder, ugmisc::sign_opt, ugmisc::sign_flag.

Definition at line 1254 of file int_finder.hpp.

◆ least_required_int_type_list

template<auto... V>
using ugmisc::least_required_int_type_list
Initial value:
::template type_list<V...>
Encapsulates a list of types.
Definition typelist.hpp:860

Finds the type T = ugmisc::least_required_int_type<V...>, then returns a ugmisc::type_list in which each type is a std::integral_constant<T, (T)value>, and each value is a V parameter which is an integer value (rather than an option or flag).

Definition at line 1285 of file int_finder.hpp.

◆ least_required_int_type_multi

template<auto... V>
using ugmisc::least_required_int_type_multi = least_required_int_type<V...>
Deprecated
This is now just an alias of ugmisc::least_required_int_type, since the latter works in a more versatile way now.

Definition at line 1263 of file int_finder.hpp.

◆ least_signed_type

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

Definition at line 754 of file int_finder.hpp.

◆ least_unsigned_type

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

Definition at line 747 of file int_finder.hpp.

Enumeration Type Documentation

◆ int_sign

Used to select signed or unsigned types.

Definition at line 72 of file int_finder.hpp.

◆ sign_flag

enum ugmisc::sign_flag : std::uint8_t
See also
ugmisc::least_required_int_type, ugmisc::sign_opt
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 accommodate is negative. Space is still reserved for the sign bit regardless of this.

Definition at line 157 of file int_finder.hpp.

◆ sign_opt

enum ugmisc::sign_opt : std::uint8_t

Used to select signed or unsigned types based on values.

See also
ugmisc::least_required_int_type, ugmisc::sign_flag
Enumerator
SELECT_UNSIGNED 

Select an unsigned type.

SELECT_SIGNED 

Select a signed type.

SELECT_TYPE_SIGN 

Select a type with the same sign as the value type. If there are multiple values, select a signed type if at least one of the values' types is signed.

SELECT_VALUE_SIGN 

Select a signed type iff the value is negative. If there are multiple values, select a signed type if at least one of the values is negative.

Definition at line 89 of file int_finder.hpp.

Function Documentation

◆ allow_value_sign_loss()

bool ugmisc::allow_value_sign_loss ( sign_flag s)
constexpr

Definition at line 196 of file int_finder.hpp.

◆ flip()

int_sign ugmisc::flip ( int_sign s)
constexpr

Definition at line 77 of file int_finder.hpp.

◆ get_name() [1/2]

std::string_view ugmisc::get_name ( sign_flag flags)
inline

Definition at line 208 of file int_finder.hpp.

◆ get_name() [2/2]

std::string_view ugmisc::get_name ( sign_opt opt)
inline
Returns
The name of an ugmisc::sign_opt value.

This function is not declared constexpr because there wouldn't be much point while the other overload, ugmisc::get_name(sign_flag), is not allowed to be constexpr.

Definition at line 115 of file int_finder.hpp.

◆ operator|()

sign_flag ugmisc::operator| ( sign_flag a,
sign_flag b )
constexpr

Definition at line 186 of file int_finder.hpp.

◆ operator~()

sign_flag ugmisc::operator~ ( sign_flag f)
constexpr

Definition at line 181 of file int_finder.hpp.

◆ sign()

template<class T>
int_sign ugmisc::sign ( sign_opt opt,
T v )
constexpr

Definition at line 137 of file int_finder.hpp.

◆ signed_bitwidth()

template<bool IncludingSignBit, Int 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.

Definition at line 780 of file int_finder.hpp.

◆ smallest()

bool ugmisc::smallest ( sign_flag s)
constexpr

Definition at line 191 of file int_finder.hpp.

◆ to_least_required_int_type()

template<auto... V>
auto ugmisc::to_least_required_int_type ( )
constexpr
Parameters
vExactly one integral value and at least one ugmisc::sign_opt, plus any number of ugmisc::sign_flag values.
Returns
The single value cast to the type least_required_int_type<v...>.

Definition at line 1220 of file int_finder.hpp.

Variable Documentation

◆ as_least_required_int_type

template<auto... V>
auto ugmisc::as_least_required_int_type
inlineconstexpr
Initial value:
=
constexpr auto to_least_required_int_type()
See also
ugmisc::to_least_required_int_type

Definition at line 1235 of file int_finder.hpp.

◆ combined

template<auto... FlagOpts>
auto ugmisc::combined = intfind_::combine_flags_opts<FlagOpts...>()
constexpr

Combine ugmisc::sign_flag and ugmisc::sign_opt parameters into a single value which can be passed in their place.

See also
least_required_int_type, least_required_int_type_finder.

Definition at line 457 of file int_finder.hpp.

◆ has_both_int_types

template<unsigned N>
bool ugmisc::has_both_int_types
inlineconstexpr
Initial value:
=
constexpr bool has_unsigned_type
constexpr bool has_signed_type
See also
ugmisc::has_int_type

Definition at line 624 of file int_finder.hpp.

◆ has_either_int_type

template<unsigned N>
bool ugmisc::has_either_int_type
inlineconstexpr
Initial value:
See also
ugmisc::has_int_type

Definition at line 628 of file int_finder.hpp.

◆ has_int_type

template<unsigned N, int_sign Sign>
bool ugmisc::has_int_type
inlineconstexpr
Initial value:

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.

Definition at line 609 of file int_finder.hpp.

◆ has_signed_type

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

Definition at line 621 of file int_finder.hpp.

◆ has_sufficient_int_type

template<unsigned N, int_sign Sign>
bool ugmisc::has_sufficient_int_type
constexpr
Initial value:
=
intfind_::template_callable_find_success<N, max_int_width, intfind_::type_finder<Sign>>()

True if at least one int type of at least N bits and the requeseted sign exists.

See also
least_int_type

Definition at line 739 of file int_finder.hpp.

◆ has_unsigned_type

template<unsigned N>
bool ugmisc::has_unsigned_type
inlineconstexpr
Initial value:
=
constexpr bool has_int_type
See also
ugmisc::has_int_type

Definition at line 617 of file int_finder.hpp.

◆ 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.

Definition at line 474 of file int_finder.hpp.