4.6.0
Freundlich's C++ toolkit
Loading...
Searching...
No Matches
fcppt.strong_typedef

Description

The strong typedef class and helper macros.

Motivation

C++ offers typedefs to provide aliases (different names) for a type. Typedefs are useful to shorten complicated types and to make type usage consistent. However, they do not prevent accidental misuse. Consider:

void f(std::string const &first_name);
void g()
{
std::string const email_address{"a@b.com"};
f(email_address);
}

Accidents like this can be prevented by creating new types first_name and email_address that are wrappers around strings. Because both of them are distinct types, they cannot be implicitly converted into each other.

Strong typedefs are thin wrappers around types that are easy to define:

FCPPT_DECLARE_STRONG_TYPEDEF(std::string, first_name);
FCPPT_DECLARE_STRONG_TYPEDEF(std::string, email_address);
void f(first_name const &);
void g()
{
email_address const address{std::string{"a@b.com"}};
// f(address); error
}

Parameters

Strong typedefs are especially helpful to distinguish function parameters at the type level. Consider the following function:

void f(int vertex_count, bool enable_culling, char character);

Even with parameter names in the function's declaration, the interface is easy to misuse. For example, the following code will compile (possibly without any warnings):

// NOLINTNEXTLINE(readability-implicit-bool-conversion,modernize-use-bool-literals,bugprone-swapped-arguments)
f(true, 1, 'c');

Instead, we introduce strong typedefs for the parameters.

FCPPT_DECLARE_STRONG_TYPEDEF(int, vertex_count);
FCPPT_DECLARE_STRONG_TYPEDEF(bool, enable_culling);
void f(vertex_count, enable_culling, draw_char);

The correct function call then looks like this:

f(vertex_count(1), enable_culling(true), draw_char('c'));

Operations

The get function extracts the value of a strong typedef.

void f(first_name const &_name) { std::cout << _name.get() << '\n'; }

Strong typedef wraps almost all operators, which are found in their respective headers.

void f(distance const _d1, distance const _d2) { std::cout << (_d1 - _d2) << '\n'; }

Internals

When declaring two strong typedefs with the same underlying type, two distinct types need to be created:

static_assert(!std::is_same_v<first, second>, "Both types must be different");

To achieve that, the FCPPT_DECLARE_STRONG_TYPEDEF macro first creates an empty struct containing the name you specify as the first parameter. This is then used as the second parameter to fcppt::strong_typedef to make it a distinct type.

Header files

Header file Description
strong_typedef_fwd.hpp Contains fcppt::strong_typedef's declaration.
strong_typedef_decl.hpp Contains fcppt::strong_typedef's definition.
strong_typedef_impl.hpp Contains the definition of fcppt::strong_typedef's member functions.
strong_typedef.hpp Includes strong_typedef_impl.hpp, strong_typedef_operators.hpp and strong_typedef_std_hash.hpp.
strong_typedef_operators.hpp Includes strong_typedef_arithmetic.hpp, strong_typedef_assignment.hpp, strong_typedef_bitwise.hpp and strong_typedef_comparison.hpp.
strong_typedef_input.hpp Contains operator>>.
strong_typedef_output.hpp Contains operator<<.
declare_strong_typedef.hpp Contains FCPPT_DECLARE_STRONG_TYPEDEF.

Classes

struct  fcppt::is_strong_typedef< T >
 Tests if a type is an fcppt::strong_typedef. More...
 
class  fcppt::strong_typedef< T, Tag >
 Used to create strong typedefs. More...
 
struct  fcppt::strong_typedef_hash< fcppt::strong_typedef< Type, Alias > >
 Hash function object for strong typedefs. More...
 

Macros

#define FCPPT_DECLARE_STRONG_TYPEDEF(type, name)
 Creates a new strong typedef using fcppt::strong_typedef.
 

Typedefs

template<typename StrongTypedef >
using fcppt::strong_typedef_tag = typename fcppt::detail::strong_typedef_tag<StrongTypedef>::type
 The tag type of a strong typedef.
 

Functions

template<typename Tag , typename Type >
fcppt::strong_typedef< std::remove_cvref_t< Type >, Tag > fcppt::make_strong_typedef (Type &&_value)
 Creates a new strong typedef given a tag and a value.
 
template<typename StrongTypedef1 , typename Function , typename... StrongTypedefs>
auto fcppt::strong_typedef_apply (Function const &_function, StrongTypedef1 &&_strong_typedef1, StrongTypedefs &&..._strong_typedefs) -> fcppt::strong_typedef< decltype(_function(fcppt::move_if_rvalue< StrongTypedef1 >(_strong_typedef1.get()), fcppt::move_if_rvalue< StrongTypedefs >(_strong_typedefs.get())...)), fcppt::strong_typedef_tag< std::remove_cvref_t< StrongTypedef1 > > >
 Applies a function to multiple strong typedefs.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator+ (fcppt::strong_typedef< T, Tag > const &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Add two strong typedefs.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator- (fcppt::strong_typedef< T, Tag > const &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Subtract two strong typedefs.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator* (fcppt::strong_typedef< T, Tag > const &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Multiply two strong typedefs.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator- (fcppt::strong_typedef< T, Tag > const &_value)
 Unary minus.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator++ (fcppt::strong_typedef< T, Tag > &_value)
 Preincrement operator.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator-- (fcppt::strong_typedef< T, Tag > &_value)
 Predecrement operator.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator++ (fcppt::strong_typedef< T, Tag > &_value, int)
 Postincrement operator.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator-- (fcppt::strong_typedef< T, Tag > &_value, int)
 Postdecrement operator.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator+= (fcppt::strong_typedef< T, Tag > &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Add and assign operator.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator-= (fcppt::strong_typedef< T, Tag > &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Subtract and assign operator.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator*= (fcppt::strong_typedef< T, Tag > &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Multiply and assign operator.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator&= (fcppt::strong_typedef< T, Tag > &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Bitwise and and assign operator.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator|= (fcppt::strong_typedef< T, Tag > &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Bitwise or and assign operator.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator^= (fcppt::strong_typedef< T, Tag > &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Bitwise xor and assign operator.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator& (fcppt::strong_typedef< T, Tag > const &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Bitwise and.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator| (fcppt::strong_typedef< T, Tag > const &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Bitwise or.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator^ (fcppt::strong_typedef< T, Tag > const &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Bitwise xor.
 
template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator~ (fcppt::strong_typedef< T, Tag > const &_value)
 Bitwise negation.
 
template<typename T , typename Tag >
bool fcppt::operator< (fcppt::strong_typedef< T, Tag > const &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Operator less.
 
template<typename T , typename Tag >
bool fcppt::operator<= (fcppt::strong_typedef< T, Tag > const &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Operator less equal.
 
template<typename T , typename Tag >
bool fcppt::operator> (fcppt::strong_typedef< T, Tag > const &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Operator greater.
 
template<typename T , typename Tag >
bool fcppt::operator>= (fcppt::strong_typedef< T, Tag > const &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Operator greater equal.
 
template<typename T , typename Tag >
bool fcppt::operator== (fcppt::strong_typedef< T, Tag > const &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Operator equal.
 
template<typename T , typename Tag >
bool fcppt::operator!= (fcppt::strong_typedef< T, Tag > const &_left, fcppt::strong_typedef< T, Tag > const &_right)
 Operator not equal.
 
template<typename StrongTypedef , typename Conv , typename Arg >
requires fcppt::is_strong_typedef<StrongTypedef>::value
constexpr StrongTypedef fcppt::strong_typedef_construct_cast (Arg const &_arg)
 Applies a cast from fcppt.cast and then construct the strong typedef.
 
template<typename Ch , typename Traits , typename T , typename Tag >
std::basic_istream< Ch, Traits > & fcppt::operator>> (std::basic_istream< Ch, Traits > &_stream, fcppt::strong_typedef< T, Tag > &_value)
 Input operator for strong typedefs.
 
template<typename StrongTypedef , typename Function >
auto fcppt::strong_typedef_map (StrongTypedef &&_input, Function const &_function) -> fcppt::strong_typedef< decltype(_function(fcppt::move_if_rvalue< StrongTypedef >(_input.get()))), fcppt::strong_typedef_tag< std::remove_cvref_t< StrongTypedef > > >
 Maps over a strong typedef.
 
template<typename Ch , typename Traits , typename T , typename Tag >
std::basic_ostream< Ch, Traits > & fcppt::operator<< (std::basic_ostream< Ch, Traits > &_stream, fcppt::strong_typedef< T, Tag > const &_value)
 Output operator for strong typedefs.
 

Macro Definition Documentation

◆ FCPPT_DECLARE_STRONG_TYPEDEF

#define FCPPT_DECLARE_STRONG_TYPEDEF ( type,
name )
Value:
struct fcppt_strong_typedef_##name##_tag \
{ \
}; \
\

Creates a new strong typedef using fcppt::strong_typedef.

Parameters
typeThe type to be wrapped.
nameThe name of the new typedef.
See also
Read fcppt.strong_typedef for more information.

Typedef Documentation

◆ strong_typedef_tag

template<typename StrongTypedef >
using fcppt::strong_typedef_tag = typename fcppt::detail::strong_typedef_tag<StrongTypedef>::type

The tag type of a strong typedef.

Template Parameters
StrongTypedefMust be an fcppt::strong_typedef.

Function Documentation

◆ make_strong_typedef()

template<typename Tag , typename Type >
fcppt::strong_typedef< std::remove_cvref_t< Type >, Tag > fcppt::make_strong_typedef ( Type && _value)
inlinenodiscard

Creates a new strong typedef given a tag and a value.

◆ operator!=()

template<typename T , typename Tag >
bool fcppt::operator!= ( fcppt::strong_typedef< T, Tag > const & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Operator not equal.

◆ operator&()

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator& ( fcppt::strong_typedef< T, Tag > const & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Bitwise and.

◆ operator&=()

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator&= ( fcppt::strong_typedef< T, Tag > & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Bitwise and and assign operator.

◆ operator*()

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator* ( fcppt::strong_typedef< T, Tag > const & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Multiply two strong typedefs.

◆ operator*=()

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator*= ( fcppt::strong_typedef< T, Tag > & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Multiply and assign operator.

◆ operator+()

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator+ ( fcppt::strong_typedef< T, Tag > const & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Add two strong typedefs.

◆ operator++() [1/2]

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator++ ( fcppt::strong_typedef< T, Tag > & _value)
inline

Preincrement operator.

◆ operator++() [2/2]

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator++ ( fcppt::strong_typedef< T, Tag > & _value,
int  )
inline

Postincrement operator.

◆ operator+=()

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator+= ( fcppt::strong_typedef< T, Tag > & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Add and assign operator.

◆ operator-() [1/2]

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator- ( fcppt::strong_typedef< T, Tag > const & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Subtract two strong typedefs.

◆ operator-() [2/2]

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator- ( fcppt::strong_typedef< T, Tag > const & _value)
inline

Unary minus.

◆ operator--() [1/2]

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator-- ( fcppt::strong_typedef< T, Tag > & _value)
inline

Predecrement operator.

◆ operator--() [2/2]

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator-- ( fcppt::strong_typedef< T, Tag > & _value,
int  )
inline

Postdecrement operator.

◆ operator-=()

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator-= ( fcppt::strong_typedef< T, Tag > & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Subtract and assign operator.

◆ operator<()

template<typename T , typename Tag >
bool fcppt::operator< ( fcppt::strong_typedef< T, Tag > const & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Operator less.

◆ operator<<()

template<typename Ch , typename Traits , typename T , typename Tag >
std::basic_ostream< Ch, Traits > & fcppt::operator<< ( std::basic_ostream< Ch, Traits > & _stream,
fcppt::strong_typedef< T, Tag > const & _value )
inline

Output operator for strong typedefs.

◆ operator<=()

template<typename T , typename Tag >
bool fcppt::operator<= ( fcppt::strong_typedef< T, Tag > const & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Operator less equal.

◆ operator==()

template<typename T , typename Tag >
bool fcppt::operator== ( fcppt::strong_typedef< T, Tag > const & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Operator equal.

◆ operator>()

template<typename T , typename Tag >
bool fcppt::operator> ( fcppt::strong_typedef< T, Tag > const & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Operator greater.

◆ operator>=()

template<typename T , typename Tag >
bool fcppt::operator>= ( fcppt::strong_typedef< T, Tag > const & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Operator greater equal.

◆ operator>>()

template<typename Ch , typename Traits , typename T , typename Tag >
std::basic_istream< Ch, Traits > & fcppt::operator>> ( std::basic_istream< Ch, Traits > & _stream,
fcppt::strong_typedef< T, Tag > & _value )

Input operator for strong typedefs.

◆ operator^()

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator^ ( fcppt::strong_typedef< T, Tag > const & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Bitwise xor.

◆ operator^=()

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator^= ( fcppt::strong_typedef< T, Tag > & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Bitwise xor and assign operator.

◆ operator|()

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator| ( fcppt::strong_typedef< T, Tag > const & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Bitwise or.

◆ operator|=()

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > & fcppt::operator|= ( fcppt::strong_typedef< T, Tag > & _left,
fcppt::strong_typedef< T, Tag > const & _right )
inline

Bitwise or and assign operator.

◆ operator~()

template<typename T , typename Tag >
fcppt::strong_typedef< T, Tag > fcppt::operator~ ( fcppt::strong_typedef< T, Tag > const & _value)
inline

Bitwise negation.

◆ strong_typedef_apply()

template<typename StrongTypedef1 , typename Function , typename... StrongTypedefs>
auto fcppt::strong_typedef_apply ( Function const & _function,
StrongTypedef1 && _strong_typedef1,
StrongTypedefs &&... _strong_typedefs ) -> fcppt::strong_typedef< decltype(_function( fcppt::move_if_rvalue<StrongTypedef1>(_strong_typedef1.get()), fcppt::move_if_rvalue<StrongTypedefs>(_strong_typedefs.get())...)), fcppt::strong_typedef_tag<std::remove_cvref_t<StrongTypedef1>>>
inline

Applies a function to multiple strong typedefs.

Returns a strong typedef with the same tag type and value _function(_strong_typedef.get(), _strongs_typedefs.get()...).

Template Parameters
StrongTypedef1Must be an fcppt::strong_typedef.
StrongTypedefsMust all be fcppt::strong_typedef.
FunctionMust be a function callable as R (StrongTypedef1::value_type, StrongTypedefs::value_type...), where R is the result type.

◆ strong_typedef_construct_cast()

template<typename StrongTypedef , typename Conv , typename Arg >
requires fcppt::is_strong_typedef<StrongTypedef>::value
StrongTypedef fcppt::strong_typedef_construct_cast ( Arg const & _arg)
constexpr

Applies a cast from fcppt.cast and then construct the strong typedef.

◆ strong_typedef_map()

template<typename StrongTypedef , typename Function >
auto fcppt::strong_typedef_map ( StrongTypedef && _input,
Function const & _function ) -> fcppt::strong_typedef< decltype(_function(fcppt::move_if_rvalue<StrongTypedef>(_input.get()))), fcppt::strong_typedef_tag<std::remove_cvref_t<StrongTypedef>>>
inline

Maps over a strong typedef.

Returns a strong typedef with the same tag type and value _function(_input.get()).

Template Parameters
StrongTypedefMust be an fcppt::strong_typedef.
FunctionMust be a function callable as R (StrongTypedef::value_type), where R is the result type.