3.6.0
Freundlich's C++ toolkit
Classes | Functions
fcppt.literal

Description

Literals or polymorphic integer constants.

Motivation

In C++, most literals are polymorphic in a sense that they can be implicitly converted to different types. For example, 0 can be used in places where nullptr can or to initialize a float to 0.f. Using literals like this, however, doesn't work to initialize integer-like types with explicit constructors or types that require special factory functions. This can quickly become a problem in generic code. Consider a generic function that tries to divide its argument by two.

template<typename T>
T half(T const _value )
{
return
_value / 2;
}

A lot of types provide an operator/ but they can't be implicitly converted from literals, for example strong typedefs.

int,
strong_int
);
void
try_strong()
{
// Doesn't work
// half(strong_int(10));
}

Specializing literals

The code above obviously doesn't work, so you might conclude from this example that we should change the function half to say T{2} instead of 2. However, other types like units without quantities in Boost.Units can only be initialized by a special factory function. Therefore, fcppt provides a customization point which is used to create objects from literals. For example, we could have found the following type inside a library:

namespace mine
{
class custom_type
{
public:
static custom_type
make(int const _value)
{
return
custom_type{
_value
};
}
[[nodiscard]]
int get() const
{
return
this->value_;
}
private:
explicit
custom_type(int const _value)
:
value_{_value}
{
}
int value_;
};
inline custom_type
custom_type const _left,
custom_type const _right
)
{
return
_left.get() / _right.get()
);
}
}

To make fcppt::literal work with this type, we need to provide a specialization for fcppt::make_literal.

namespace fcppt
{
template<>
struct make_literal<mine::custom_type>
{
using decorated_type =
mine::custom_type;
template<typename Fundamental>
static mine::custom_type
get(Fundamental const _value)
{
static_assert(
std::is_same_v<Fundamental, int>,
"custom_types should be initialized by integers"
);
return
_value
);
}
};
}

Using literals

In order to make the half function work, we call fcppt::literal.

template<typename T>
T half_2(T const _value)
{
return
_value / fcppt::literal<T>(2);
}

We can then call our half_2 function with custom_type

void
literal_use()
{
// Prints 2
<< half_2(mine::custom_type::make(4)).get()
<< '\n';
}
Note
As a general rule of thumb, you should only use literals of type int with fcppt::literal but this isn't enforced by the type system because it might be too restrictive.

Classes

struct  fcppt::make_literal< Type, Enable >
 
struct  fcppt::strong_typedef< Type, Tag >>
 

Functions

template<typename Type , typename Arg >
constexpr fcppt::make_literal< Type >::decorated_type fcppt::literal (Arg const &&_integral) noexcept
 Creates a literal of a type. More...
 

Function Documentation

◆ literal()

template<typename Type , typename Arg >
constexpr fcppt::make_literal< Type>::decorated_type fcppt::literal ( Arg const &&  _integral)
constexprnoexcept

Creates a literal of a type.

Creates a literal of type Type from the value _integral, using fcppt::make_literal to do any conversions if necessary.

Template Parameters
TypeThe literal type to create. Must be a value type. See fcppt::type_traits::is_value.
ArgAn arithmetic type.
fcppt::parse::make_literal
fcppt::parse::basic_literal< Ch > make_literal(Ch const _ch)
Definition: make_literal.hpp:24
FCPPT_MAKE_STRONG_TYPEDEF
#define FCPPT_MAKE_STRONG_TYPEDEF(type, name)
Creates a new strong typedef using strong_typedef.
Definition: make_strong_typedef.hpp:21
fcppt::math::dim::operator/
fcppt::optional::object< fcppt::math::dim::static_< FCPPT_MATH_DETAIL_BINARY_TYPE(L,/, R), N >> operator/(fcppt::math::dim::object< L, N, S1 > const &_left, fcppt::math::dim::object< R, N, S2 > const &_right)
Divides a dim by a dim.
Definition: arithmetic.hpp:222
fcppt::container::array::make
std::array< ::metal::front< ::metal::list< fcppt::type_traits::remove_cv_ref_t< Args >... > >, sizeof...(Args)> make(Args &&... _args)
Make an array out of a parameter pack.
Definition: make.hpp:52
fcppt::io::cout
FCPPT_DETAIL_SYMBOL fcppt::io::ostream & cout()
Returns either std::cout or std::wcout, depending on fcppt::char_type.
fcppt
The top level namespace.
Definition: absurd.hpp:15
fcppt::io::get
fcppt::optional::object< Ch > get(std::basic_istream< Ch, Traits > &_stream)
Gets a character from a stream.
Definition: get.hpp:35