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

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

[section:first_scalar first_scalar]

[simplesect Authors]

* Glen Fernandes

[endsimplesect]

[section Overview]

The header <boost/core/first_scalar.hpp> provides the function templates
`boost::first_scalar` that can be used to obtain a pointer to the first scalar
element of an array. Given a pointer of type `T*` they return a pointer of
type `remove_all_extents_t<T>*`. The functions are `constexpr` and can be used
in constant expressions.

[endsect]

[section Examples]

The following function uses an allocator to allocate an array of arrays and
constructs each scalar element in it.

```
#include <boost/alloc_construct.hpp>
#include <boost/first_scalar.hpp>

template<class A>
auto create(const A& allocator)
{
    typename std::allocator_traits<A>::template
        rebind_alloc<int[2][3]> other(allocator);
    auto ptr = other.allocate(4);
    try {
        boost::alloc_construct_n(other,
            boost::first_scalar(boost::to_address(ptr)), 24);
    } catch (...) {
        other.deallocate(ptr, 4);
        throw;
    }
    return ptr;
}
```

[endsect]

[section Reference]

```
namespace boost {

template<class T>
constexpr T* first_scalar(T* p) noexcept;

template<class T, std::size_t N>
constexpr auto first_scalar(T (*p)[N]) noexcept;

} /* boost */
```

[section Functions]

[variablelist
[[`template<class T> constexpr T* first_scalar(T* p) noexcept;`]
[[variablelist
[[Returns][`p`.]]]]]
[[`template<class T, std::size_t N> constexpr auto first_scalar(T (*p)[N])
noexcept;`]
[[variablelist
[[Returns][`first_scalar(&(*p)[0])`.]]]]]]

[endsect]

[endsect]

[section History]

Glen Fernandes implemented `first_scalar`. Peter Dimov suggested a change for
GCC to support an additional `constexpr` use.

[endsect]

[endsect]
