|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r60750 - in trunk/libs/spirit/example/scheme: . detail
From: joel_at_[hidden]
Date: 2010-03-21 13:14:48
Author: djowel
Date: 2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
New Revision: 60750
URL: http://svn.boost.org/trac/boost/changeset/60750
Log:
more refactoring
Text files modified:
trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp | 8 +
trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp | 195 ++++++++++++++++++++++++++++++++-------
trunk/libs/spirit/example/scheme/sexpr.hpp | 19 ---
trunk/libs/spirit/example/scheme/simple_print.hpp | 89 ------------------
trunk/libs/spirit/example/scheme/utree.hpp | 47 ++++++---
trunk/libs/spirit/example/scheme/utree_test.cpp | 4
6 files changed, 202 insertions(+), 160 deletions(-)
Modified: trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp (original)
+++ trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp 2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
@@ -32,8 +32,8 @@
bool_type,
int_type,
double_type,
- small_string_type,
- heap_string_type,
+ string_type,
+ binary_type,
list_type,
reference_type
};
@@ -117,6 +117,7 @@
void set_type(utree_type::info t);
int get_subtype() const;
void set_subtype(int t);
+ bool is_heap_allocated() const;
std::size_t size() const;
char const* str() const;
@@ -127,6 +128,9 @@
void swap(fast_string& other);
void free();
void copy(fast_string const& other);
+
+ char& info();
+ char info() const;
};
}}
Modified: trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp (original)
+++ trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp 2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
@@ -9,48 +9,55 @@
namespace scheme { namespace detail
{
+ inline char& fast_string::info()
+ {
+ return buff[small_string_size];
+ }
+
+ inline char fast_string::info() const
+ {
+ return buff[small_string_size];
+ }
+
inline utree_type::info fast_string::get_type() const
{
- return static_cast<utree_type::info>(buff[small_string_size] & 0x7);
+ return static_cast<utree_type::info>((info() & 0x0F) >> 1);
}
inline void fast_string::set_type(utree_type::info t)
{
- buff[small_string_size] = static_cast<char>(t)
- | (buff[small_string_size] & 0xF8);
+ info() = (static_cast<char>(t) << 1) | (info() & 0xF1);
}
inline int fast_string::get_subtype() const
{
- return buff[small_string_size] >> 3;
+ return info() >> 4;
}
inline void fast_string::set_subtype(int t)
{
- buff[small_string_size] = (t << 3)
- | (buff[small_string_size] & 0x7);
+ info() = (t << 4) | (info() & 0x0F);
}
- inline std::size_t fast_string::size() const
+ inline bool fast_string::is_heap_allocated() const
{
- BOOST_ASSERT(get_type() == utree_type::small_string_type
- || get_type() == utree_type::heap_string_type);
+ return info() & 0x01;
+ }
- if (get_type() == utree_type::small_string_type)
- return small_string_size - buff[small_string_size - 1];
- else
+ inline std::size_t fast_string::size() const
+ {
+ if (is_heap_allocated())
return heap.size;
+ else
+ return small_string_size - buff[small_string_size - 1];
}
inline char const* fast_string::str() const
{
- BOOST_ASSERT(get_type() == utree_type::small_string_type
- || get_type() == utree_type::heap_string_type);
-
- if (get_type() == utree_type::small_string_type)
- return buff;
- else
+ if (is_heap_allocated())
return heap.str;
+ else
+ return buff;
}
template <typename Iterator>
@@ -64,15 +71,17 @@
// of the string is placed in buff[small_string_size - 1]
str = buff;
buff[small_string_size - 1] = small_string_size - size;
- set_type(utree_type::small_string_type);
+ info() &= ~0x1;
}
else
{
+ BOOST_ASSERT(size < 200);
+
// else, store it in the heap
str = new char[size + 1]; // add one for the null char
heap.str = str;
heap.size = size;
- set_type(utree_type::heap_string_type);
+ info() |= 0x1;
}
for (std::size_t i = 0; i != size; ++i)
{
@@ -83,14 +92,12 @@
inline void fast_string::swap(fast_string& other)
{
- fast_string temp = other;
- other = *this;
- *this = temp;
+ std::swap(*this, other);
}
inline void fast_string::free()
{
- if (get_type() == utree_type::heap_string_type)
+ if (is_heap_allocated())
{
delete [] heap.str;
heap.str = 0;
@@ -352,7 +359,13 @@
return a == b;
}
- bool operator()(utree::nil, utree::nil) const
+ template <typename Base>
+ bool operator()(binary<Base> const& a, binary<Base> const& b) const
+ {
+ return false;
+ }
+
+ bool operator()(nil, nil) const
{
return true;
}
@@ -390,13 +403,94 @@
return a < b;
}
- bool operator()(utree::nil, utree::nil) const
+ template <typename Base>
+ bool operator()(binary<Base> const& a, binary<Base> const& b) const
+ {
+ BOOST_ASSERT(false);
+ return false; // no less than comparison for binary
+ }
+
+ bool operator()(nil, nil) const
{
BOOST_ASSERT(false);
return false; // no less than comparison for nil
}
};
+ struct utree_print
+ {
+ typedef void result_type;
+
+ std::ostream& out;
+ utree_print(std::ostream& out) : out(out) {}
+
+ void operator()(scheme::nil) const
+ {
+ out << "nil";
+ }
+
+ template <typename T>
+ void operator()(T val) const
+ {
+ out << val;
+ }
+
+ void operator()(bool b) const
+ {
+ out << (b ? "true" : "false");
+ }
+
+ template <typename Base>
+ void operator()(binary<Base> b) const
+ {
+ out << "b";
+ out.width(2);
+ out.fill('0');
+
+ typedef typename Base::const_iterator iterator;
+ for (iterator i = b.begin(); i != b.end(); ++i)
+ out << std::hex << int((unsigned char)*i);
+ out << std::dec;
+ }
+
+ template <typename Range> // for lists
+ void print_string_or_list(Range range, boost::mpl::false_) const
+ {
+ typedef typename Range::const_iterator iterator;
+ (*this)('(');
+ for (iterator i = range.begin(); i != range.end(); ++i)
+ {
+ if (i != range.begin())
+ (*this)(' ');
+ scheme::utree::visit(*i, *this);
+ }
+ (*this)(')');
+ }
+
+ template <typename Range> // for strings
+ void print_string_or_list(Range range, boost::mpl::true_) const
+ {
+ typedef typename Range::const_iterator iterator;
+ iterator i = range.begin();
+ bool const is_symbol = *i == '\0'; // a 0 byte at the beginning signifies a symbol
+ if (!is_symbol)
+ out << '"';
+ else
+ ++i;
+ for (; i != range.end(); ++i)
+ out << *i;
+ if (!is_symbol)
+ out << '"';
+ }
+
+ template <typename Iterator>
+ void operator()(boost::iterator_range<Iterator> const& range) const
+ {
+ // This code works for both strings and lists
+ print_string_or_list(range, boost::is_pointer<Iterator>());
+ }
+ };
+
template <typename UTreeX, typename UTreeY = UTreeX>
struct visit_impl
{
@@ -423,7 +517,7 @@
default:
BOOST_ASSERT(false); // can't happen
case type::nil_type:
- typename UTreeX::nil arg;
+ nil arg;
return f(arg);
case type::bool_type:
return f(x.b);
@@ -433,9 +527,10 @@
return f(x.d);
case type::list_type:
return f(list_range(iterator(x.l.first), iterator(0)));
- case type::heap_string_type:
- case type::small_string_type:
+ case type::string_type:
return f(string_range(x.s.str(), x.s.str() + x.s.size()));
+ case type::binary_type:
+ return f(binary_range(x.s.str(), x.s.size()));
case type::reference_type:
return apply(*x.p, f);
}
@@ -464,7 +559,7 @@
default:
BOOST_ASSERT(false); // can't happen
case type::nil_type:
- typename UTreeX::nil x_;
+ nil x_;
return visit_impl::apply(y, detail::bind(f, x_));
case type::bool_type:
return visit_impl::apply(y, detail::bind(f, x.b));
@@ -476,10 +571,12 @@
return visit_impl::apply(
y, detail::bind<F, list_range>(f,
list_range(iterator(x.l.first), iterator(0))));
- case type::heap_string_type:
- case type::small_string_type:
+ case type::string_type:
return visit_impl::apply(y, detail::bind(
f, string_range(x.s.str(), x.s.str() + x.s.size())));
+ case type::binary_type:
+ return visit_impl::apply(y, detail::bind(
+ f, binary_range(x.s.str(), x.s.size())));
case type::reference_type:
return apply(*x.p, y, f);
}
@@ -534,16 +631,26 @@
inline utree::utree(char const* str)
{
s.construct(str, str + strlen(str));
+ set_type(type::string_type);
}
inline utree::utree(char const* str, std::size_t len)
{
s.construct(str, str + len);
+ set_type(type::string_type);
}
inline utree::utree(std::string const& str)
{
s.construct(str.begin(), str.end());
+ set_type(type::string_type);
+ }
+
+ template <typename Base>
+ inline utree::utree(binary<Base> const& bin)
+ {
+ s.construct(bin.begin(), bin.end());
+ set_type(type::binary_type);
}
inline utree::utree(boost::reference_wrapper<utree> ref)
@@ -608,6 +715,7 @@
{
free();
s.construct(s_, s_ + strlen(s_));
+ set_type(type::string_type);
return *this;
}
@@ -615,6 +723,16 @@
{
free();
s.construct(s_.begin(), s_.end());
+ set_type(type::string_type);
+ return *this;
+ }
+
+ template <typename Base>
+ inline utree& utree::operator=(binary<Base> const& bin)
+ {
+ free();
+ s.construct(bin.begin(), bin.end());
+ set_type(type::binary_type);
return *this;
}
@@ -714,6 +832,12 @@
return !(a < b);
}
+ inline std::ostream& operator<<(std::ostream& out, utree const& x)
+ {
+ utree::visit(x, detail::utree_print(out));
+ return out;
+ }
+
template <typename T>
inline void utree::push_front(T const& val)
{
@@ -941,7 +1065,8 @@
{
switch (get_type())
{
- case type::heap_string_type:
+ case type::binary_type:
+ case type::string_type:
s.free();
break;
case type::list_type:
@@ -971,8 +1096,8 @@
case type::reference_type:
p = other.p;
break;
- case type::small_string_type:
- case type::heap_string_type:
+ case type::string_type:
+ case type::binary_type:
s.copy(other.s);
break;
case type::list_type:
Modified: trunk/libs/spirit/example/scheme/sexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/sexpr.hpp (original)
+++ trunk/libs/spirit/example/scheme/sexpr.hpp 2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
@@ -89,20 +89,6 @@
}
};
- struct push_binary
- {
- template <typename S, typename C>
- struct result { typedef void type; };
-
- void operator()(std::string& utf8, char byte) const
- {
- if (utf8.size() == 0)
- utf8 += '\1'; // mark a byte string with prefix 1
- // (a 1 byte at the beginning signifies a byte string)
- utf8 += byte;
- }
- };
-
struct push_esc
{
template <typename S, typename C>
@@ -161,7 +147,6 @@
real_parser<double, strict_real_policies<double> > strict_double;
uint_parser<unsigned char, 16, 2, 2> hex2;
function<detail::push_symbol> push_symbol;
- function<detail::push_binary> push_binary;
start = atom | list;
@@ -183,13 +168,13 @@
| int_ [_val = _1]
;
- byte_str = lexeme[no_case['b'] >> +(hex2 [push_binary(_val, _1)])];
+ byte_str = lexeme[no_case['b'] >> +hex2];
}
rule<Iterator, white_space<Iterator>, utree()> start, list;
rule<Iterator, utree()> atom, number;
rule<Iterator, std::string()> symbol;
- rule<Iterator, std::string()> byte_str;
+ rule<Iterator, binary_string()> byte_str;
scheme::string<Iterator> string;
};
}
Modified: trunk/libs/spirit/example/scheme/simple_print.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/simple_print.hpp (original)
+++ trunk/libs/spirit/example/scheme/simple_print.hpp 2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
@@ -6,96 +6,9 @@
namespace detail
{
- ///////////////////////////////////////////////////////////////////////////
- // simple utree printing facility prints the utree in a single line
- ///////////////////////////////////////////////////////////////////////////
-
- std::ostream& print(std::ostream& out, scheme::utree const& val);
- std::ostream& println(std::ostream& out, scheme::utree const& val);
-
- // simple_print visitor
- struct simple_print
- {
- typedef void result_type;
-
- std::ostream& out;
- simple_print(std::ostream& out) : out(out) {}
-
- void operator()(scheme::utree::nil) const
- {
- out << "nil";
- }
-
- template <typename T>
- void operator()(T val) const
- {
- out << val;
- }
-
- void operator()(bool b) const
- {
- out << (b ? "true" : "false");
- }
-
- template <typename Range> // for lists
- void print_string_or_list(Range range, boost::mpl::false_) const
- {
- typedef typename Range::const_iterator iterator;
- (*this)('(');
- for (iterator i = range.begin(); i != range.end(); ++i)
- {
- if (i != range.begin())
- (*this)(' ');
- scheme::utree::visit(*i, *this);
- }
- (*this)(')');
- }
-
- template <typename Range> // for strings
- void print_string_or_list(Range range, boost::mpl::true_) const
- {
- typedef typename Range::const_iterator iterator;
- iterator i = range.begin();
- if (*i == '\1') // a 1 byte at the beginning signifies a byte string
- {
- out << "b"; ++i;
- out.width(2);
- out.fill('0');
- for (; i != range.end(); ++i)
- out << std::hex << int((unsigned char)*i);
- out << std::dec;
- }
- else
- {
- bool const is_symbol = *i == '\0'; // a 0 byte at the beginning signifies a symbol
- if (!is_symbol)
- out << '"';
- else
- ++i;
- for (; i != range.end(); ++i)
- out << *i;
- if (!is_symbol)
- out << '"';
- }
- }
-
- template <typename Iterator>
- void operator()(boost::iterator_range<Iterator> const& range) const
- {
- // This code works for both strings and lists
- print_string_or_list(range, boost::is_pointer<Iterator>());
- }
- };
-
- inline std::ostream& print(std::ostream& out, scheme::utree const& val)
- {
- scheme::utree::visit(val, simple_print(out));
- return out;
- }
-
inline std::ostream& println(std::ostream& out, scheme::utree const& val)
{
- detail::print(out, val) << std::endl;
+ out << val << std::endl;
return out;
}
}
Modified: trunk/libs/spirit/example/scheme/utree.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree.hpp 2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
@@ -10,6 +10,8 @@
#include <cstddef>
#include <algorithm>
#include <string>
+#include <ostream>
+
#include <boost/assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/iterator/iterator_facade.hpp>
@@ -21,6 +23,11 @@
namespace scheme
{
+ struct nil {};
+
+ template <typename Base>
+ struct binary;
+
///////////////////////////////////////////////////////////////////////////
// The main utree (Universal Tree) class
// The utree is a hierarchical, dynamic type that can store:
@@ -28,7 +35,8 @@
// - a bool
// - an integer
// - a double
- // - a string (textual or binary)
+ // - a string
+ // - binary data
// - a (doubly linked) list of utree
// - a reference to a utree
//
@@ -48,16 +56,6 @@
typedef std::ptrdiff_t difference_type;
typedef std::size_t size_type;
- struct nil {};
-
- struct binary
- {
- binary(unsigned char bits[], std::size_t len)
- : bits(bits), len(len) {}
- unsigned char* bits;
- std::size_t len;
- };
-
utree();
explicit utree(bool b);
explicit utree(unsigned int i);
@@ -66,6 +64,9 @@
explicit utree(char const* str);
explicit utree(char const* str, std::size_t len);
explicit utree(std::string const& str);
+
+ template <typename Base>
+ explicit utree(binary<Base> const& bin);
explicit utree(boost::reference_wrapper<utree> ref);
utree(utree const& other);
@@ -78,6 +79,9 @@
utree& operator=(double d);
utree& operator=(char const* s);
utree& operator=(std::string const& s);
+
+ template <typename Base>
+ utree& operator=(binary<Base> const& bin);
utree& operator=(boost::reference_wrapper<utree> ref);
template <typename F>
@@ -181,14 +185,25 @@
bool operator>(utree const& a, utree const& b);
bool operator<=(utree const& a, utree const& b);
bool operator>=(utree const& a, utree const& b);
+ std::ostream& operator<<(std::ostream& out, utree const& x);
- ///////////////////////////////////////////////////////////////////////////
- // The ulist is a utility class for easy construction of utree lists
- ///////////////////////////////////////////////////////////////////////////
- struct ulist : utree
+ template <typename Base>
+ struct binary : Base
{
- ulist() : utree(construct_list()) {}
+ binary()
+ : Base() {}
+
+ template <typename Iterator>
+ binary(Iterator bits, std::size_t len)
+ : Base(bits, bits + len) {}
+
+ template <typename Iterator>
+ binary(Iterator first, Iterator last)
+ : Base(first, last) {}
};
+
+ typedef binary<boost::iterator_range<char const*> > binary_range;
+ typedef binary<std::string> binary_string;
}
#include "detail/utree_detail2.hpp"
Modified: trunk/libs/spirit/example/scheme/utree_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree_test.cpp (original)
+++ trunk/libs/spirit/example/scheme/utree_test.cpp 2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
@@ -108,7 +108,7 @@
a = 100.00;
BOOST_ASSERT(a < b);
- b = a = ulist();
+ b = a = utree();
BOOST_ASSERT(a == b);
a.push_back(1);
a.push_back("two");
@@ -123,7 +123,7 @@
}
{
- ulist a;
+ utree a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk