Documentation of type_safe

( foonathan/type_safe)

Header file output_parameter.hpp

namespace type_safe
{
    template <typename T>
    class output_parameter;
    
    template <typename T>
    output_parameter<T> out(T& obj) noexcept;
    
    template <typename T>
    output_parameter<T> out(deferred_construction<T>& o) noexcept;
}

Class template type_safe::output_parameter

template <typename T>
class output_parameter
{
public:
    using parameter_type = T;
    
    output_parameter(T& obj) noexcept;
    
    output_parameter(const T&) = delete;
    output_parameter(T&&) = delete;
    output_parameter(const T&&) = delete;
    
    output_parameter(deferred_construction<T>& out) noexcept;
    
    output_parameter(const deferred_construction<T>&) = delete;
    output_parameter(deferred_construction<T>&&) = delete;
    output_parameter(const deferred_construction<T>&&) = delete;
    
    output_parameter(output_parameter&& other) noexcept;
    
    ~output_parameter() noexcept = default;
    
    output_parameter& operator=(const output_parameter&) = delete;
    output_parameter& operator=(output_parameter&&) = delete;
    
    template <typename U>
    parameter_type& operator=(U&& u);
    
    template <typename ... Args>
    T& assign(Args&&... args);
};

A tiny wrapper modelling an output parameter of a function.

An output paramater is a paramter that will be used to transport output of a function to its caller, like a return value does. Usually they are implemented with lvalue references. They have a couple of disadvantages though:

  • They require an already created object, i.e. a default constructor or similar.
  • It is not obvious when just looking at the call that the argument will be changed.
  • They make it easy to accidentally use them as regular parameters, i.e. reading their value, even though that was not intended.

If you use this class as your output parameter type, you do not have these disadvantages. The creation is explicit, you cannot read the value, and it works with ts::deferred_construction.

Notes: While you could use this class in other locations besides parameters, this is not recommended.

Constructor type_safe::output_parameter::output_parameter

output_parameter(T& obj) noexcept;

Effects: Creates it from an lvalue reference. All output will be assigned to the object referred by the reference.

Requires: The referred object must live as long as the function has not returned.

Constructor type_safe::output_parameter::output_parameter

(1)  output_parameter(const T&) = delete;

(2)  output_parameter(T&&) = delete;

(3)  output_parameter(const T&&) = delete;

Constructor type_safe::output_parameter::output_parameter

output_parameter(deferred_construction<T>& out) noexcept;

Effects: Creates it from a ts::deferred_construction object. All output will be assigned or created in the storage of the defer construction object, depending on wheter it is initialized.

Requires: The referred object must live as long as the function has not returned.

Constructor type_safe::output_parameter::output_parameter

(1)  output_parameter(const deferred_construction<T>&) = delete;

(2)  output_parameter(deferred_construction<T>&&) = delete;

(3)  output_parameter(const deferred_construction<T>&&) = delete;

Move constructor type_safe::output_parameter::output_parameter

output_parameter(output_parameter&& other) noexcept;

Effects: Moves an output parameter. This will put other in an invalid state, it must not be used afterwards.

Notes: This constructor is only there because guaranteed copy elision isn't available and otherwise the out() function could not be implemented. It is not intended to use it otherwise.

Assignment operator type_safe::output_parameter::operator=

(1)  output_parameter& operator=(const output_parameter&) = delete;

(2)  output_parameter& operator=(output_parameter&&) = delete;

Assignment operator type_safe::output_parameter::operator=

template <typename U>
parameter_type& operator=(U&& u);

Effects: Same as assign(std::forward<U>(u)).

Returns: A reference to the value that was assigned, not *this as normal "assignment" operators.

Requires: value_type must be constructible from U.


Function template type_safe::out

template <typename T>
output_parameter<T> out(T& obj) noexcept;

Returns: A new ts::output_parameter using the reference obj as output.

Function template type_safe::out

template <typename T>
output_parameter<T> out(deferred_construction<T>& o) noexcept;

Returns: A new ts::output_parameter using the ts::deferred_construction as output.