Documentation of type_safe

( foonathan/type_safe)

Header file compact_optional.hpp

namespace type_safe
{
    template <class CompactPolicy>
    class compact_optional_storage;
    
    template <class CompactPolicy>
    using compact_optional = basic_optional<compact_optional_storage<CompactPolicy>>;
    
    template <typename Boolean>
    class compact_bool_policy;
    
    template <typename Integer, Integer Invalid>
    class compact_integer_policy;
    
    template <typename FloatingPoint>
    class compact_floating_point_policy;
    
    template <typename Enum, 'hidden' Invalid>
    class compact_enum_policy;
    
    template <class Container>
    class compact_container_policy;
}

Class template type_safe::compact_optional_storage [optional]

template <class CompactPolicy>
class compact_optional_storage
{
public:
    using value_type = typename std::remove_cv<typename CompactPolicy::value_type>::type;
    
    using storage_type = typename CompactPolicy::storage_type;
    
    using lvalue_reference = 'hidden';
    
    using const_lvalue_reference = 'hidden';
    
    using rvalue_reference = 'hidden';
    
    using const_rvalue_reference = 'hidden';
    
    template <typename U>
    using rebind = direct_optional_storage<U>;
    
    compact_optional_storage() noexcept;
    
    template <typename ... Args>
    void create_value(Args&&... args);
    
    void create_value(const compact_optional_storage& other);
    
    void create_value(compact_optional_storage&& other);
    
    void create_value_explicit();
    
    void copy_value(const compact_optional_storage& other);
    
    void copy_value(compact_optional_storage&& other);
    
    void swap_value(compact_optional_storage& other);
    
    void destroy_value() noexcept;
    
    bool has_value() const noexcept;
    
    lvalue_reference get_value() & noexcept;
    const_lvalue_reference get_value() const & noexcept;
    rvalue_reference get_value() && noexcept;
    const_rvalue_reference get_value() const && noexcept;
    
    template <typename U>
    value_type get_value_or(U&& u) const &;
    template <typename U>
    value_type get_value_or(U&& u) &&;
};

A StoragePolicy for ts::basic_optional that is more space efficient than ts::direct_optional_storage.

It is designed to have no space overhead compared to a regular object of the stored type. This is accomplished by marking one value of the stored type as invalid and using that in the empty state. What the invalid value is is controlled by the CompactPolicy. It must provide the following static member functions and typedefs:

  • value_type - the value that is being stored conceptually
  • storage_type - the actual type that is being stored
  • storage_type invalid_value() - returns the value that marks the optional as empty
  • bool is_invalid(const storage_type&) - returns true if the given value is invalid, false otherwise

In the cases where value_type and storage_type differ, the get_value() functions will not return references, but a copy instead. The implementation assumes that invalid_value() and is_invalid() are noexcept and cheap.

Notes: For a compact optional of pointer type, use ts::optional_ref.

Default constructor type_safe::compact_optional_storage::compact_optional_storage

compact_optional_storage() noexcept;

Effects: Initializes it in the state without value, i.e. sets the storage to the invalid value.

Function template type_safe::compact_optional_storage::create_value

template <typename ... Args>
void create_value(Args&&... args);

Effects: Creates a temporary value_type by perfectly forwarding args, converts that to the storage_type and assigns it. Afterwards has_value() will return true.

Throws: Anything thrown by the constructor of value_type/storage_type or its move assignment operator in which case has_value() is still false.

Requires: has_value() == false and the given value must not be invalid.

Notes: This function does not participate in overload resolution unless value_type is constructible from args.

Function type_safe::compact_optional_storage::create_value

void create_value(const compact_optional_storage& other);

Effects: Copy assigns the storage_type.

Function type_safe::compact_optional_storage::create_value

void create_value(compact_optional_storage&& other);

Effects: Move assigns the storage_type.

Function type_safe::compact_optional_storage::copy_value

void copy_value(const compact_optional_storage& other);

Effects: Copy assigns the storage_type.

Function type_safe::compact_optional_storage::copy_value

void copy_value(compact_optional_storage&& other);

Effects: Move assigns the storage_type.

Function type_safe::compact_optional_storage::swap_value

void swap_value(compact_optional_storage& other);

Effects: Swaps the storage_type.

Function type_safe::compact_optional_storage::destroy_value

void destroy_value() noexcept;

Effects: Destroys the value by setting it to the invalid storage value. Afterwards has_value() will return false.

Requires: has_value() == true.

Function type_safe::compact_optional_storage::has_value

bool has_value() const noexcept;

Returns: Whether or not there is a value stored, i.e. whether the stored value is not invalid.

Function type_safe::compact_optional_storage::get_value

(1)  lvalue_reference get_value() & noexcept;

(2)  const_lvalue_reference get_value() const & noexcept;

(3)  rvalue_reference get_value() && noexcept;

(4)  const_rvalue_reference get_value() const && noexcept;

Returns: A (suitable) reference to the stored value or a copy of the value depending on the policy.

Requires: has_value() == true.

Function template type_safe::compact_optional_storage::get_value_or

(1)  template <typename U>
     value_type get_value_or(U&& u) const &;

(2)  template <typename U>
     value_type get_value_or(U&& u) &&;

Returns: Either get_value() or u converted to value_type.

Requires: value_type must be copy (1)/move (2) constructible and u convertible to value_type.


Alias template type_safe::compact_optional [optional]

template <class CompactPolicy>
using compact_optional = basic_optional<compact_optional_storage<CompactPolicy>>;

An alias for ts::basic_optional using ts::compact_optional_storage with the given CompactPolicy.

Class template type_safe::compact_bool_policy [optional]

template <typename Boolean>
class compact_bool_policy
{
public:
    using value_type = Boolean;
    
    using storage_type = char;
    
    static storage_type invalid_value() noexcept;
    
    static bool is_invalid(storage_type storage) noexcept;
};

A CompactPolicy for ts::compact_optional_storage for boolean types.

It is designed for either bool or ts::boolean.

Notes: It uses a different storage_type and thus cannot return a reference to the stored value.

Class template type_safe::compact_integer_policy

template <typename Integer, Integer Invalid>
class compact_integer_policy
{
public:
    using value_type = Integer;
    
    using storage_type = Integer;
    
    static storage_type invalid_value() noexcept;
    
    static bool is_invalid(const storage_type& storage) noexcept;
};

A CompactPolicy for ts::compact_optional_storage for integer types.

The given Invalid value will be used to mark an empty optional.

Class template type_safe::compact_floating_point_policy [optional]

template <typename FloatingPoint>
class compact_floating_point_policy
{
public:
    using value_type = FloatingPoint;
    
    using storage_type = FloatingPoint;
    
    static storage_type invalid_value() noexcept;
    
    static bool is_invalid(const storage_type& storage) noexcept;
};

A CompactPolicy for ts::compact_optional_storage for floating point types.

NaN will be used to mark an empty optional.

Class template type_safe::compact_enum_policy [optional]

template <typename Enum, 'hidden' Invalid>
class compact_enum_policy
{
public:
    using value_type = Enum;
    
    using storage_type = 'hidden';
    
    static storage_type invalid_value() noexcept;
    
    static bool is_invalid(const storage_type& storage) noexcept;
};

A CompactPolicy for ts::compact_optional_storage for enumeration types.

It uses the given Invalid value of the underlying type to mark an empty optional.

Notes: It uses a different storage_type and thus cannot return a reference to the stored value.

Class template type_safe::compact_container_policy [optional]

template <class Container>
class compact_container_policy
{
public:
    using value_type = Container;
    
    using storage_type = Container;
    
    static storage_type invalid_value() noexcept;
    
    static bool is_invalid(const storage_type& storage) noexcept;
};

A CompactPolicy for ts::compact_optional_storage for container types.

A Container is a type with a cheap no-throwing default constructor initializing it empty, and either an empty() member function or ADL function that returns true if the container is empty, false otherwise. An empty container will be marked as an empty optional.