Skip to content

Commit

Permalink
Remove dependency on Boost.Any.
Browse files Browse the repository at this point in the history
  • Loading branch information
tzlaine committed Sep 20, 2020
1 parent 1ed3764 commit 113270d
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 15 deletions.
11 changes: 5 additions & 6 deletions include/boost/parser/parser.hpp
Expand Up @@ -861,18 +861,17 @@ namespace boost { namespace parser {
using trie_t = text::trie<std::vector<uint32_t>, T>;
symbol_table_tries_t & symbol_table_tries =
*context.symbol_table_tries_;
any & a = symbol_table_tries[(void *)&symbol_parser];
trie_t * trie_ptr = nullptr;
any_copyable & a = symbol_table_tries[(void *)&symbol_parser];
if (a.empty()) {
a = trie_t{};
trie_ptr = boost::any_cast<trie_t>(&a);
trie_t & trie = a.cast<trie_t>();
for (auto const & e : symbol_parser.initial_elements()) {
trie_ptr->insert(text::as_utf32(e.first), e.second);
trie.insert(text::as_utf32(e.first), e.second);
}
return trie;
} else {
trie_ptr = boost::any_cast<trie_t>(&a);
return a.cast<trie_t>();
}
return *trie_ptr;
}


Expand Down
67 changes: 64 additions & 3 deletions include/boost/parser/parser_fwd.hpp
Expand Up @@ -4,10 +4,9 @@
#include <boost/parser/config.hpp>
#include <boost/parser/error_handling_fwd.hpp>

#include <boost/any.hpp>

#include <cstdint>
#include <map>
#include <memory>


namespace boost { namespace parser {
Expand All @@ -22,7 +21,69 @@ namespace boost { namespace parser {
in_apply_parser = 1 << 3
};

using symbol_table_tries_t = std::map<void *, any, std::less<void *>>;
struct any_copyable
{
template<
typename T,
typename Enable = std::enable_if_t<!std::is_reference_v<T>>>
any_copyable(T && v) :
impl_(new holder<std::decay_t<T>>(std::move(v)))
{}
template<typename T>
any_copyable(T const & v) : impl_(new holder<T>(v))
{}

any_copyable() = default;
any_copyable(any_copyable const & other)
{
if (other.impl_)
impl_ = other.impl_->clone();
}
any_copyable & operator=(any_copyable const & other)
{
any_copyable temp(other);
swap(temp);
return *this;
}
any_copyable(any_copyable &&) = default;
any_copyable & operator=(any_copyable &&) = default;

bool empty() const { return impl_.get() == nullptr; }

template<typename T>
T & cast() const
{
BOOST_ASSERT(impl_);
BOOST_ASSERT(dynamic_cast<holder<T> *>(impl_.get()));
return static_cast<holder<T> *>(impl_.get())->value_;
}

void swap(any_copyable & other) { std::swap(impl_, other.impl_); }

private:
struct holder_base
{
virtual ~holder_base() {}
virtual std::unique_ptr<holder_base> clone() const = 0;
};
template<typename T>
struct holder : holder_base
{
holder(T && v) : value_(std::move(v)) {}
holder(T const & v) : value_(v) {}
virtual ~holder() {}
virtual std::unique_ptr<holder_base> clone() const
{
return std::unique_ptr<holder_base>(new holder<T>{value_});
}
T value_;
};

std::unique_ptr<holder_base> impl_;
};

using symbol_table_tries_t =
std::map<void *, any_copyable, std::less<void *>>;

template<typename Iter, typename Sentinel, typename ErrorHandler>
inline auto make_context(
Expand Down
6 changes: 3 additions & 3 deletions test/parser.cpp
Expand Up @@ -1430,7 +1430,7 @@ TEST(parser, combined_seq_and_or)
char_('x') >> char_('y') >> char_('z');
{
std::string str = "abc";
boost::any chars;
boost::parser::detail::any_copyable chars;
EXPECT_TRUE(parse(str, parser, chars));
}

Expand All @@ -1448,9 +1448,9 @@ TEST(parser, combined_seq_and_or)
#if 0 // TODO: Document why this assigns "c" instead of "abc" to the any.
{
std::string str = "abc";
boost::any chars;
boost::parser::detail::any_copyable chars;
EXPECT_TRUE(parse(str, parser, chars));
EXPECT_EQ(boost::any_cast<std::string>(chars), "abc");
EXPECT_EQ(chars.cast<std::string>(), "abc");
}
#endif

Expand Down
6 changes: 3 additions & 3 deletions test/parser_api.cpp
Expand Up @@ -1776,7 +1776,7 @@ TEST(parser, combined_seq_and_or)
char_('x') >> char_('y') >> char_('z');
{
char const * str = "abc";
boost::any chars;
boost::parser::detail::any_copyable chars;
EXPECT_TRUE(parse(str, parser, chars));
}

Expand All @@ -1794,9 +1794,9 @@ TEST(parser, combined_seq_and_or)
#if 0 // TODO: Document why this assigns "c" instead of "abc" to the any.
{
char const * str = "abc";
boost::any chars;
boost::parser::detail::any_copyable chars;
EXPECT_TRUE(parse(str, parser, chars));
EXPECT_EQ(boost::any_cast<std::string>(chars), "abc");
EXPECT_EQ(chars.cast<std::string>(), "abc");
}
#endif

Expand Down

0 comments on commit 113270d

Please sign in to comment.