Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <boost/fusion/include/front.hpp>
#include <boost/fusion/include/back.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <iterator> // for std::make_move_iterator

namespace boost { namespace spirit { namespace x3 { namespace detail
{
Expand Down Expand Up @@ -99,7 +100,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
return false;

// push the parsed value into our attribute
traits::push_back(attr, val);
traits::push_back(attr, static_cast<value_type&&>(val));
return true;
}

Expand Down Expand Up @@ -262,7 +263,8 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
Attribute rest;
bool r = parser.parse(first, last, context, rcontext, rest);
if (r)
traits::append(attr, rest.begin(), rest.end());
traits::append(attr, std::make_move_iterator(rest.begin()),
std::make_move_iterator(rest.end()));
return r;
}

Expand Down
5 changes: 4 additions & 1 deletion include/boost/spirit/home/x3/operator/detail/sequence.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>

#include <iterator> // for std::make_move_iterator

namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
Expand Down Expand Up @@ -445,7 +447,8 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
{
return false;
}
traits::append(attr, traits::begin(attr_), traits::end(attr_));
traits::append(attr, std::make_move_iterator(traits::begin(attr_)),
std::make_move_iterator(traits::end(attr_)));
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion include/boost/spirit/home/x3/operator/optional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace boost { namespace spirit { namespace x3
value_type;

// create a local value
value_type val = value_type();
value_type val{};

if (this->subject.parse(first, last, context, rcontext, val))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,15 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename T>
static bool call(Container& c, T&& val)
{
c.insert(c.end(), std::move(val));
c.insert(c.end(), static_cast<T&&>(val));
return true;
}
};

template <typename Container, typename T>
inline bool push_back(Container& c, T&& val)
{
return push_back_container<Container>::call(c, std::move(val));
return push_back_container<Container>::call(c, static_cast<T&&>(val));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason behind such changes? Reducing use of standard library (compile time)?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed surprising move of lvalue. And yes, std::forward is not zero cost in terms of compile time (also a surprising thing).

}

template <typename Container>
Expand Down
50 changes: 28 additions & 22 deletions test/x3/container_support.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ auto const string_rule_def = x3::lexeme[*x3::alnum];
BOOST_SPIRIT_DEFINE(pair_rule, string_rule);

template <typename Container>
void test_map_support(Container&& container)
void test_map_support()
{
using spirit_test::test_attr;

Container container;
Container const compare {{"k1", "v1"}, {"k2", "v2"}};
auto const rule = pair_rule % x3::lit(',');

Expand All @@ -56,10 +57,11 @@ void test_map_support(Container&& container)
}

template <typename Container>
void test_multimap_support(Container&& container)
void test_multimap_support()
{
using spirit_test::test_attr;

Container container;
Container const compare {{"k1", "v1"}, {"k2", "v2"}, {"k2", "v3"}};
auto const rule = pair_rule % x3::lit(',');

Expand All @@ -79,10 +81,11 @@ void test_multimap_support(Container&& container)
}

template <typename Container>
void test_sequence_support(Container&& container)
void test_sequence_support()
{
using spirit_test::test_attr;

Container container;
Container const compare {"e1", "e2", "e2"};
auto const rule = string_rule % x3::lit(',');

Expand All @@ -102,10 +105,11 @@ void test_sequence_support(Container&& container)
}

template <typename Container>
void test_set_support(Container&& container)
void test_set_support()
{
using spirit_test::test_attr;

Container container;
Container const compare {"e1", "e2"};
auto const rule = string_rule % x3::lit(',');

Expand All @@ -125,10 +129,11 @@ void test_set_support(Container&& container)
}

template <typename Container>
void test_multiset_support(Container&& container)
void test_multiset_support()
{
using spirit_test::test_attr;

Container container;
Container const compare {"e1", "e2", "e2"};
auto const rule = string_rule % x3::lit(',');

Expand All @@ -148,10 +153,11 @@ void test_multiset_support(Container&& container)
}

template <typename Container>
void test_string_support(Container&& container)
void test_string_support()
{
using spirit_test::test_attr;

Container container;
Container const compare {"e1e2e2"};
auto const rule = string_rule % x3::lit(',');

Expand Down Expand Up @@ -216,27 +222,27 @@ main()

// ------------------------------------------------------------------

test_string_support(std::string());
test_string_support<std::string>();

test_sequence_support(std::vector<std::string>());
test_sequence_support(std::list<std::string>());
test_sequence_support(std::deque<std::string>());
test_sequence_support<std::vector<std::string>>();
test_sequence_support<std::list<std::string>>();
test_sequence_support<std::deque<std::string>>();

test_set_support(std::set<std::string>());
test_set_support(std::unordered_set<std::string>());
test_set_support(boost::unordered_set<std::string>());
test_set_support<std::set<std::string>>();
test_set_support<std::unordered_set<std::string>>();
test_set_support<boost::unordered_set<std::string>>();

test_multiset_support(std::multiset<std::string>());
test_multiset_support(std::unordered_multiset<std::string>());
test_multiset_support(boost::unordered_multiset<std::string>());
test_multiset_support<std::multiset<std::string>>();
test_multiset_support<std::unordered_multiset<std::string>>();
test_multiset_support<boost::unordered_multiset<std::string>>();

test_map_support(std::map<std::string,std::string>());
test_map_support(std::unordered_map<std::string,std::string>());
test_map_support(boost::unordered_map<std::string,std::string>());
test_map_support<std::map<std::string,std::string>>();
test_map_support<std::unordered_map<std::string,std::string>>();
test_map_support<boost::unordered_map<std::string,std::string>>();

test_multimap_support(std::multimap<std::string,std::string>());
test_multimap_support(std::unordered_multimap<std::string,std::string>());
test_multimap_support(boost::unordered_multimap<std::string,std::string>());
test_multimap_support<std::multimap<std::string,std::string>>();
test_multimap_support<std::unordered_multimap<std::string,std::string>>();
test_multimap_support<boost::unordered_multimap<std::string,std::string>>();

return boost::report_errors();
}
7 changes: 7 additions & 0 deletions test/x3/kleene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <string>
#include <iostream>
#include "test.hpp"
#include "utils.hpp"

struct x_attr
{
Expand Down Expand Up @@ -115,5 +116,11 @@ main()
test_attr("abcde", *char_, x);
}

{ // test move only types
std::vector<move_only> v;
BOOST_TEST(test_attr("sss", *synth_move_only, v));
BOOST_TEST_EQ(v.size(), 3);
}

return boost::report_errors();
}
7 changes: 7 additions & 0 deletions test/x3/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <string>
#include <iostream>
#include "test.hpp"
#include "utils.hpp"

using namespace spirit_test;

Expand Down Expand Up @@ -98,5 +99,11 @@ main()
BOOST_TEST(s == "abcdefgh");
}

{ // test move only types
std::vector<move_only> v;
BOOST_TEST(test_attr("s.s.s.s", synth_move_only % '.', v));
BOOST_TEST_EQ(v.size(), 4);
}

return boost::report_errors();
}
7 changes: 7 additions & 0 deletions test/x3/optional.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <iostream>
#include "test.hpp"
#include "utils.hpp"

struct adata
{
Expand Down Expand Up @@ -102,5 +103,11 @@ main()
2 == v[1].a && !v[1].b);
}

{ // test move only types
boost::optional<move_only> o;
BOOST_TEST(test_attr("s", -synth_move_only, o));
BOOST_TEST(o);
}

return boost::report_errors();
}
7 changes: 7 additions & 0 deletions test/x3/plus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <string>
#include <iostream>
#include "test.hpp"
#include "utils.hpp"

struct x_attr
{
Expand Down Expand Up @@ -129,5 +130,11 @@ main()
BOOST_TEST(boost::fusion::at_c<0>(fs) == "12345");
}

{ // test move only types
std::vector<move_only> v;
BOOST_TEST(test_attr("sss", +synth_move_only, v));
BOOST_TEST_EQ(v.size(), 3);
}

return boost::report_errors();
}
8 changes: 8 additions & 0 deletions test/x3/repeat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <string>
#include <iostream>
#include "test.hpp"
#include "utils.hpp"

int
main()
Expand Down Expand Up @@ -140,5 +141,12 @@ main()

BOOST_TEST(!test("1 2", int_ >> repeat(2)[int_], space));
}

{ // test move only types
std::vector<move_only> v;
BOOST_TEST(test_attr("sss", repeat(3)[synth_move_only], v));
BOOST_TEST_EQ(v.size(), 3);
}

return boost::report_errors();
}
8 changes: 8 additions & 0 deletions test/x3/sequence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <string>
#include <iostream>
#include "test.hpp"
#include "utils.hpp"

int
main()
Expand Down Expand Up @@ -491,5 +492,12 @@ main()
#endif
}

{ // test move only types
using boost::spirit::x3::eps;
std::vector<move_only> v;
BOOST_TEST(test_attr("ssszs", *synth_move_only >> 'z' >> synth_move_only, v));
BOOST_TEST_EQ(v.size(), 4);
}

return boost::report_errors();
}
47 changes: 47 additions & 0 deletions test/x3/utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*=============================================================================
Copyright (c) 2019 Nikita Kniazev

Use, modification and distribution is subject to 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)
=============================================================================*/
#if !defined(BOOST_SPIRIT_TEST_X3_UTILS_HPP)
#define BOOST_SPIRIT_TEST_X3_UTILS_HPP

#include <boost/spirit/home/x3/core/parser.hpp>

struct move_only
{
move_only(move_only&&) = default;
move_only& operator=(move_only&&) = default;
};


template <typename T>
struct synth_parser : boost::spirit::x3::parser<synth_parser<T>>
{
typedef T attribute_type;

static bool const has_attribute = true;
static bool const handles_container = false;

template <typename Iterator, typename Context,
typename RuleContext, typename Attribute>
bool parse(Iterator& iter, Iterator const& last, Context const&,
RuleContext&, Attribute& attr) const
{
if (iter != last && *iter == 's') {
++iter;
boost::spirit::x3::traits::move_to(attribute_type{}, attr);
return true;
}
return false;
}
};

template <typename T>
synth_parser<T> synth{};

synth_parser<move_only> const synth_move_only{};

#endif