CppGraph Application Framework©
Copyright © 2004-202x Geoff Goldberg
Named Types

Overview

A named type is a class that provides a new type by wrapping an existing type. This allows a generic type (such as int) to be restricted to a narrower type (such as mipmap_level_t). The named type ensures, at compile time, that values assigned to it are of the restricted type, while maintaining most operations and efficiencies that apply to the wrapped type.

The essential features provided by named types are:

Examples:

int kilometers = 5; // Compiles, but not type-safe.
kilometers_t distance = 5; // Compile error. Copy-initialization.
kilometers_t distance2 = 5_kilometers // Compiles. Type-safe.
auto distance3 = 5_kilometers; // Compiles. Type-safe.
kilometers_t distance4 { 5 }; // Compiles. By using the explicit constructor, the user acknowleges type-safety via static_cast.
kilometers_t distance5; // Initialized to 0.
kilometers_t distance6 = distance2; // Compiles.
kilometers_t distance7 { distance2 }; // Compiles.
int distance8 { distance7 }; // Compiles. Uses kilometers_t::operator int const &().

CppGraph© uses named types extensively. Pre-defned named types can be found in named types.

Advantages

Similarities

A named type is similar to its value type in the following ways:

Declaration

To declare a named type, call CPPGRAPH_DECLARE_NAMED_TYPE() (or CPPGRAPH_DECLARE_DERIVED_NAMED_TYPE()), from the desired namespace.

namespace foo
{
CPPGRAPH_DECLARE_NAMED_TYPE( bar, float ); // Declares bar_t as an instantiation of named_type_t< float >.
}
foo::bar_t b; // Declare a variable of type bar_t.

Derived Named Types

A named type can be derived from another named type. At most 1 level of derivation is allowed. The derived named type can be used in place of its base named type.

namespace foo
{
CPPGRAPH_DECLARE_NAMED_TYPE ( distance, float ); // Declares distance_t as an instantiation of named_type_t< float >.
CPPGRAPH_DECLARE_DERIVED_NAMED_TYPE ( kilometers, distance ); // Declares kilometers_t as an instantiation of derived_named_type_t< distance_t >.
}
void bar( distance_t const & distance );
foo::kilometers_t crow_flies{ 12_kilometers };
bar( crow_flies ); // OK

Named Type Names

To add a type name for a named type or derived named type, call CPPGRAPH_DECLARE_NAMED_TYPE_TYPENAME() from the cppgraph namespace.

namespace cppgraph
{
}

Named Type Literals

A named type or derived named type can have a corresponding literal suffix declared using the macro CPPGRAPH_DECLARE_LITERAL() from the cppgraph::literals namespace:

namespace foo
{
CPPGRAPH_DECLARE_NAMED_TYPE( bar, int64_t );
}
{
CPPGRAPH_DECLARE_LITERAL( foo, bar, unsigned long long )
}
auto foobar = 99_bar;

Pre-defined literal suffixes are literals.

Named Types as Properties

Named types can be used as properties. They are declared and accessed using the same macros and functions as built-in properties. Access is as efficient as that for built-in properties. Automatic serialization is performed for named type properties just as it is for built-in and user properties.

General Usage

Construction

Construction is type-safe. This is the purpose of named types. Named types are constructible in the following ways:

Value Access

The named_type_t class has been designed to provide easy and (where possible) transparent access to its value type in expressions. Some use cases and solutions are:

Conversions