[/
Copyright 2018 Glen Joseph Fernandes
(glenjofe@gmail.com)

Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]

[section:empty_value empty_value]

[simplesect Authors]

* Glen Fernandes

[endsimplesect]

[section Overview]

The header <boost/core/empty_value.hpp> provides the class template
`boost::empty_value` for library authors to conveniently leverage the Empty
Base Optimization to store objects of potentially empty types.

[endsect]

[section Examples]

The following example shows `boost::empty_value` used to create a type that
stores a pointer, comparer, and allocator, where the comparer and allocator
could be empty types.

```
template<class Ptr, class Compare, class Allocator>
class storage
    : empty_value<Compare, 0>
    , empty_value<Allocator, 1> {
public:
    storage()
        : empty_value<Compare, 0>(empty_init_t())
        , empty_value<Allocator, 1>(empty_init_t())
        , ptr_() { }

    storage(const Compare& c, const Allocator& a)
        : empty_value<Compare, 0>(empty_init_t(), c)
        , empty_value<Allocator, 1>(empty_init_t(), a)
        , ptr_() { }

    const Ptr& pointer() const {
        return ptr_;
    }

    Ptr& pointer() {
        return ptr_;
    }

    const Compare& compare() const {
        return empty_value<Compare, 0>::get();
    }

    Compare& compare() {
        return empty_value<Compare, 0>::get();
    }

    const Allocator& allocator() const {
        return empty_value<Allocator, 1>::get();
    }

    Allocator& allocator() {
        return empty_value<Allocator, 1>::get();
    }

private:
    Ptr ptr_;
};
```

[endsect]

[section Reference]

```
namespace boost {

struct empty_init_t { };

template<class T, unsigned Index = 0, bool Empty = ``/see below/``>
class empty_value {
public:
    typedef T type;

    empty_value() = default;

    template<class... Args>
    constepxr empty_value(empty_init_t, Args&&... args);

    constepxr const T& get() const noexcept;

    constepxr T& get() noexcept;
};

inline constexpr empty_init_t empty_init{ };

} /* boost */
```

[section Template parameters]

[variablelist
[[`T`][The type of value to store]]
[[`Index`][Optional: Specify to create a distinct base type]]
[[`Empty`][Optional: Specify to force inheritance from type]]]

[endsect]

[section Member types]

[variablelist
[[`type`][The template parameter `T`]]]

[endsect]

[section Constructors]

[variablelist
[[`constepxr empty_value() = default;`][Default initialize the value]]
[[`template<class... Args>
constepxr empty_value(empty_init_t, Args&&... args);`]
[Initialize the value with `std::forward<Args>(args)...`]]]

[endsect]

[section Member functions]

[variablelist
[[`constepxr const T& get() const noexcept;`][Returns the value]]
[[`constepxr T& get() noexcept;`][Returns the value]]]

[endsect]

[endsect]

[endsect]
