Edit: /usr/include/boost/hof/construct.hpp (8774B)
/*=============================================================================
Copyright (c) 2015 Paul Fultz II
construct.h
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef BOOST_HOF_GUARD_CONSTRUCT_H
#define BOOST_HOF_GUARD_CONSTRUCT_H
/// construct
/// =========
///
/// Description
/// -----------
///
/// The `construct` function returns a function object that will construct the
/// object when the called. A template can also be given, which it will deduce
/// the parameters to the template. The `construct_meta` can be used to
/// construct the object from a metafunction.
///
/// Synopsis
/// --------
///
/// // Construct by decaying each value
/// template
/// constexpr auto construct();
///
/// template class Template>
/// constexpr auto construct();
///
/// // Construct by deducing lvalues by reference and rvalue reference by reference
/// template
/// constexpr auto construct_forward();
///
/// template class Template>
/// constexpr auto construct_forward();
///
/// // Construct by deducing lvalues by reference and rvalues by value.
/// template
/// constexpr auto construct_basic();
///
/// template class Template>
/// constexpr auto construct_basic();
///
/// // Construct by deducing the object from a metafunction
/// template
/// constexpr auto construct_meta();
///
/// template class MetafunctionTemplate>
/// constexpr auto construct_meta();
///
/// Semantics
/// ---------
///
/// assert(construct()(xs...) == T(xs...));
/// assert(construct()(xs...) == Template(xs...));
/// assert(construct_meta()(xs...) == MetafunctionClass::apply(xs...));
/// assert(construct_meta()(xs...) == MetafunctionTemplate::type(xs...));
///
/// Requirements
/// ------------
///
/// MetafunctionClass must be a:
///
/// * [MetafunctionClass](MetafunctionClass)
///
/// MetafunctionTemplate must be a:
///
/// * [Metafunction](Metafunction)
///
/// T, Template, MetafunctionClass::apply, and
/// MetafunctionTemplate::type must be:
///
/// * MoveConstructible
///
/// Example
/// -------
///
/// #include
/// #include
/// #include
///
/// int main() {
/// auto v = boost::hof::construct>()(5, 5);
/// assert(v.size() == 5);
/// }
///
#include
#include
#include
#include
#include
#include
#include
namespace boost { namespace hof {
namespace detail {
template
struct construct_f
{
typedef typename std::aligned_storage::type storage;
struct storage_holder
{
storage * s;
storage_holder(storage* x) noexcept : s(x)
{}
T& data() noexcept
{
return *reinterpret_cast(s);
}
~storage_holder() noexcept(noexcept(std::declval().~T()))
{
this->data().~T();
}
};
constexpr construct_f() noexcept
{}
template
T operator()(Ts&&... xs) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, Ts&&...)
{
storage buffer{};
new(&buffer) T(BOOST_HOF_FORWARD(Ts)(xs)...);
storage_holder h(&buffer);
return boost::hof::move(h.data());
}
template&&)>
T operator()(std::initializer_list&& x) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, std::initializer_list&&)
{
storage buffer{};
new(&buffer) T(static_cast&&>(x));
storage_holder h(&buffer);
return h.data();
}
template&)>
T operator()(std::initializer_list& x) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, std::initializer_list&)
{
storage buffer{};
new(&buffer) T(x);
storage_holder h(&buffer);
return h.data();
}
template&)>
T operator()(const std::initializer_list& x) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, const std::initializer_list&)
{
storage buffer{};
new(&buffer) T(x);
storage_holder h(&buffer);
return h.data();
}
};
template
struct construct_f::type>
{
constexpr construct_f() noexcept
{}
template
constexpr T operator()(Ts&&... xs) const noexcept
{
return T(BOOST_HOF_FORWARD(Ts)(xs)...);
}
template&&)>
constexpr T operator()(std::initializer_list&& x) const noexcept
{
return T(static_cast&&>(x));
}
template&)>
constexpr T operator()(std::initializer_list& x) const noexcept
{
return T(x);
}
template&)>
constexpr T operator()(const std::initializer_list& x) const noexcept
{
return T(x);
}
};
template class Template, template class D>
struct construct_template_f
{
constexpr construct_template_f() noexcept
{}
template::type...),
BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(Result, Ts...)>
constexpr Result operator()(Ts&&... xs) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Result, Ts&&...)
{
return construct_f()(BOOST_HOF_FORWARD(Ts)(xs)...);
}
};
template
struct construct_meta_f
{
constexpr construct_meta_f() noexcept
{}
template
struct apply
: MetafunctionClass::template apply
{};
template
constexpr Result operator()(Ts&&... xs) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Result, Ts&&...)
{
return construct_f()(BOOST_HOF_FORWARD(Ts)(xs)...);
}
};
template class MetafunctionTemplate>
struct construct_meta_template_f
{
constexpr construct_meta_template_f() noexcept
{}
template
constexpr Result operator()(Ts&&... xs) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Result, Ts&&...)
{
return construct_f()(BOOST_HOF_FORWARD(Ts)(xs)...);
}
};
template
struct construct_id
{
typedef T type;
};
}
template
constexpr detail::construct_f construct() noexcept
{
return {};
}
// These overloads are provide for consistency
template
constexpr detail::construct_f construct_forward() noexcept
{
return {};
}
template
constexpr detail::construct_f construct_basic() noexcept
{
return {};
}
template class Template>
constexpr detail::construct_template_f construct() noexcept
{
return {};
}
template class Template>
constexpr detail::construct_template_f construct_forward() noexcept
{
return {};
}
template class Template>
constexpr detail::construct_template_f construct_basic() noexcept
{
return {};
}
template
constexpr detail::construct_meta_f construct_meta() noexcept
{
return {};
}
template class Template>
constexpr detail::construct_meta_template_f construct_meta() noexcept
{
return {};
}
}} // namespace boost::hof
#endif