#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
-#include <algorithm>
#include <cstddef>
#include <string>
#include <utility>
namespace boost { namespace spirit { namespace x3
{
+
+namespace detail
+{
+ template <typename Value, std::size_t N
+ , typename = std::make_index_sequence<N>>
+ struct array_helper;
+
+ template <typename Value, std::size_t N, std::size_t... Is>
+ struct array_helper<Value, N, std::index_sequence<Is...>>
+ {
+ constexpr array_helper(Value const (&value)[N])
+ : value_{ value[Is]... } {}
+
+ constexpr array_helper(Value (&&value)[N])
+ : value_{ static_cast<Value&&>(value[Is])... } {}
+
+ // silence MSVC warning C4512: assignment operator could not be generated
+ array_helper& operator= (array_helper const&) = delete;
+
+ Value value_[N];
+ };
+}
+
template <typename Value>
struct attr_parser : parser<attr_parser<Value>>
{
static bool const handles_container =
traits::is_container<attribute_type>::value;
- attr_parser(Value const& value)
+ constexpr attr_parser(Value const& value)
: value_(value) {}
- attr_parser(Value&& value)
+ constexpr attr_parser(Value&& value)
: value_(std::move(value)) {}
template <typename Iterator, typename Context
template <typename Value, std::size_t N>
struct attr_parser<Value[N]> : parser<attr_parser<Value[N]>>
+ , detail::array_helper<Value, N>
{
+ using detail::array_helper<Value, N>::array_helper;
+
typedef Value attribute_type[N];
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
static bool const handles_container = true;
-
- attr_parser(Value const (&value)[N])
- {
- std::copy(value + 0, value + N, value_ + 0);
- }
-
- attr_parser(Value (&&value)[N])
- {
- std::move(value + 0, value + N, value_ + 0);
- }
template <typename Iterator, typename Context
, typename RuleContext, typename Attribute>
, Context const& /* context */, RuleContext&, Attribute& attr_) const
{
// $$$ Change to copy_to once we have it $$$
- traits::move_to(value_ + 0, value_ + N, attr_);
+ traits::move_to(this->value_ + 0, this->value_ + N, attr_);
return true;
}
- Value value_[N];
-
// silence MSVC warning C4512: assignment operator could not be generated
attr_parser& operator= (attr_parser const&) = delete;
};
struct attr_gen
{
template <typename Value>
- attr_parser<typename remove_cv<
+ constexpr attr_parser<typename remove_cv<
typename remove_reference<Value>::type>::type>
operator()(Value&& value) const
{
return { std::forward<Value>(value) };
}
-
- template <typename Value, std::size_t N>
- attr_parser<typename remove_cv<Value>::type[N]>
- operator()(Value (&value)[N]) const
- {
- return { value };
- }
- template <typename Value, std::size_t N>
- attr_parser<typename remove_cv<Value>::type[N]>
- operator()(Value (&&value)[N]) const
- {
- return { value };
- }
};
- auto const attr = attr_gen{};
+ constexpr auto attr = attr_gen{};
}}}
#endif