|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r67437 - in trunk: boost/spirit/home/karma boost/spirit/home/karma/detail boost/spirit/home/karma/directive boost/spirit/home/qi boost/spirit/home/qi/directive boost/spirit/home/support boost/spirit/home/support/utree boost/spirit/include libs/spirit/test/karma libs/spirit/test/qi libs/spirit/test/support
From: admin_at_[hidden]
Date: 2010-12-23 16:14:52
Author: wash
Date: 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
New Revision: 67437
URL: http://svn.boost.org/trac/boost/changeset/67437
Log:
Added the as directive.
Added:
trunk/boost/spirit/home/karma/detail/as.hpp
- copied, changed from r67430, /trunk/boost/spirit/home/karma/detail/as_string.hpp
trunk/boost/spirit/home/karma/directive/as.hpp
- copied, changed from r67430, /trunk/boost/spirit/home/karma/directive/as_string.hpp
trunk/boost/spirit/home/qi/directive/as.hpp
- copied, changed from r67430, /trunk/boost/spirit/home/qi/directive/as_string.hpp
trunk/boost/spirit/include/karma_as.hpp
- copied, changed from r67430, /trunk/boost/spirit/include/karma_as_string.hpp
trunk/boost/spirit/include/qi_as.hpp
- copied, changed from r67430, /trunk/boost/spirit/include/qi_as_string.hpp
Removed:
trunk/boost/spirit/home/karma/detail/as_string.hpp
trunk/boost/spirit/home/karma/directive/as_string.hpp
trunk/boost/spirit/home/qi/directive/as_string.hpp
trunk/boost/spirit/include/karma_as_string.hpp
trunk/boost/spirit/include/qi_as_string.hpp
Text files modified:
trunk/boost/spirit/home/karma/detail/as.hpp | 47 +++++++++++++-----
trunk/boost/spirit/home/karma/directive.hpp | 2
trunk/boost/spirit/home/karma/directive/as.hpp | 72 +++++++++++++++++++--------
trunk/boost/spirit/home/qi/directive.hpp | 2
trunk/boost/spirit/home/qi/directive/as.hpp | 67 +++++++++++++++++++-------
trunk/boost/spirit/home/support/attributes_fwd.hpp | 18 ++++--
trunk/boost/spirit/home/support/common_terminals.hpp | 1
trunk/boost/spirit/home/support/utree/utree_traits.hpp | 101 ++++++++++++++++++++++++++++++++++++++-
trunk/boost/spirit/include/karma_as.hpp | 7 +-
trunk/boost/spirit/include/qi_as.hpp | 7 +-
trunk/libs/spirit/test/karma/utree.cpp | 38 ++++++++++++++
trunk/libs/spirit/test/qi/utree.cpp | 77 +++++++++++++++++++++++++++--
trunk/libs/spirit/test/support/utree_test.cpp | 52 +++++++++++++++++++
13 files changed, 409 insertions(+), 82 deletions(-)
Copied: trunk/boost/spirit/home/karma/detail/as.hpp (from r67430, /trunk/boost/spirit/home/karma/detail/as_string.hpp)
==============================================================================
--- /trunk/boost/spirit/home/karma/detail/as_string.hpp (original)
+++ trunk/boost/spirit/home/karma/detail/as.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -23,8 +23,8 @@
///////////////////////////////////////////////////////////////////////////
// This is the default case: the plain attribute values
- template <typename Attribute, typename Enable/*= void*/>
- struct attribute_as_string
+ template <typename T, typename Attribute, typename Enable/*= void*/>
+ struct attribute_as_xxx
{
typedef Attribute const& type;
@@ -32,38 +32,57 @@
{
return attr;
}
+
+ static bool is_valid(Attribute const& attr)
+ {
+ return true;
+ }
};
///////////////////////////////////////////////////////////////////////////
- template <typename Attribute>
- typename spirit::result_of::attribute_as_string<Attribute>::type
- as_string(Attribute const& attr)
+ template <typename T, typename Attribute>
+ inline typename spirit::result_of::attribute_as_xxx<T, Attribute>::type
+ as(Attribute const& attr)
{
- return attribute_as_string<Attribute>::call(attr);
+ return attribute_as_xxx<T, Attribute>::call(attr);
}
- inline unused_type as_string(unused_type)
+ template <typename T>
+ inline unused_type as(unused_type)
{
return unused;
}
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Attribute>
+ inline bool valid_as(Attribute const& attr)
+ {
+ return attribute_as_xxx<T, Attribute>::is_valid(attr);
+ }
+
+ template <typename T>
+ inline bool valid_as(unused_type)
+ {
+ return true;
+ }
}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace result_of
{
- template <typename Attribute>
- struct attribute_as_string
- : traits::attribute_as_string<Attribute>
+ template <typename T, typename Attribute>
+ struct attribute_as_xxx
+ : traits::attribute_as_xxx<T, Attribute>
{};
- template <>
- struct attribute_as_string<unused_type>
+ template <typename T>
+ struct attribute_as_xxx<T, unused_type>
{
typedef unused_type type;
};
- template <>
- struct attribute_as_string<unused_type const>
+ template <typename T>
+ struct attribute_as_xxx<T, unused_type const>
{
typedef unused_type type;
};
Deleted: trunk/boost/spirit/home/karma/detail/as_string.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/as_string.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
+++ (empty file)
@@ -1,72 +0,0 @@
-// Copyright (c) 2001-2010 Hartmut Kaiser
-//
-// 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)
-
-#if !defined(BOOST_SPIRIT_KARMA_AS_STRING_DEC_18_0644PM)
-#define BOOST_SPIRIT_KARMA_AS_STRING_DEC_18_0644PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/spirit/home/support/attributes_fwd.hpp>
-
-///////////////////////////////////////////////////////////////////////////////
-namespace boost { namespace spirit { namespace traits
-{
- ///////////////////////////////////////////////////////////////////////////
- // This file contains the attribute to string conversion utility. The
- // utility provided also accept spirit's unused_type; all no-ops. Compiler
- // optimization will easily strip these away.
- ///////////////////////////////////////////////////////////////////////////
-
- // This is the default case: the plain attribute values
- template <typename Attribute, typename Enable/*= void*/>
- struct attribute_as_string
- {
- typedef Attribute const& type;
-
- static type call(Attribute const& attr)
- {
- return attr;
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- template <typename Attribute>
- typename spirit::result_of::attribute_as_string<Attribute>::type
- as_string(Attribute const& attr)
- {
- return attribute_as_string<Attribute>::call(attr);
- }
-
- inline unused_type as_string(unused_type)
- {
- return unused;
- }
-}}}
-
-///////////////////////////////////////////////////////////////////////////////
-namespace boost { namespace spirit { namespace result_of
-{
- template <typename Attribute>
- struct attribute_as_string
- : traits::attribute_as_string<Attribute>
- {};
-
- template <>
- struct attribute_as_string<unused_type>
- {
- typedef unused_type type;
- };
-
- template <>
- struct attribute_as_string<unused_type const>
- {
- typedef unused_type type;
- };
-}}}
-
-#endif
Modified: trunk/boost/spirit/home/karma/directive.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive.hpp (original)
+++ trunk/boost/spirit/home/karma/directive.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -70,6 +70,6 @@
// as_string and as_wstring directives
// as_string[...], as_wstring[...]
///////////////////////////////////////////////////////////////////////////////
-#include <boost/spirit/home/karma/directive/as_string.hpp>
+#include <boost/spirit/home/karma/directive/as.hpp>
#endif
Copied: trunk/boost/spirit/home/karma/directive/as.hpp (from r67430, /trunk/boost/spirit/home/karma/directive/as_string.hpp)
==============================================================================
--- /trunk/boost/spirit/home/karma/directive/as_string.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/as.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,10 +1,11 @@
// Copyright (c) 2001-2010 Hartmut Kaiser
+// Copyright (c) 2010 Bryce Lelbach
//
// 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)
-#if !defined(SPIRIT_KARMA_AS_STRING_DEC_18_0510PM)
-#define SPIRIT_KARMA_AS_STRING_DEC_18_0510PM
+#if !defined(SPIRIT_KARMA_AS_DEC_18_0510PM)
+#define SPIRIT_KARMA_AS_DEC_18_0510PM
#if defined(_MSC_VER)
#pragma once
@@ -14,7 +15,7 @@
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
-#include <boost/spirit/home/karma/detail/as_string.hpp>
+#include <boost/spirit/home/karma/detail/as.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
@@ -22,18 +23,34 @@
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
+namespace boost { namespace spirit { namespace karma
+{
+ template <typename T>
+ struct as
+ : stateful_tag_type<T, tag::as>
+ {};
+}}}
+
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
+ // enables as_string[...]
template <>
- struct use_directive<karma::domain, tag::as_string> // enables as_string
+ struct use_directive<karma::domain, tag::as_string>
: mpl::true_ {};
+ // enables as_wstring[...]
template <>
- struct use_directive<karma::domain, tag::as_wstring> // enables as_wstring
+ struct use_directive<karma::domain, tag::as_wstring>
: mpl::true_ {};
+
+ // enables as<T>[...]
+ template <typename T>
+ struct use_directive<karma::domain, tag::stateful_tag<T, tag::as> >
+ : mpl::true_
+ {};
}}
namespace boost { namespace spirit { namespace karma
@@ -44,17 +61,17 @@
using spirit::as_wstring_type;
///////////////////////////////////////////////////////////////////////////
- // as_string_directive allows to hook custom conversions to string into the
+ // as_directive allows to hook custom conversions to string into the
// output generation process
///////////////////////////////////////////////////////////////////////////
- template <typename Subject, typename Char>
- struct as_string_directive
- : unary_generator<as_string_directive<Subject, Char> >
+ template <typename Subject, typename T>
+ struct as_directive
+ : unary_generator<as_directive<Subject, T> >
{
typedef Subject subject_type;
typedef typename subject_type::properties properties;
- as_string_directive(Subject const& subject)
+ as_directive(Subject const& subject)
: subject(subject) {}
template <typename Context, typename Iterator>
@@ -67,14 +84,17 @@
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
- return subject.generate(sink, ctx, d, traits::as_string(attr)) &&
- karma::delimit_out(sink, d); // always do post-delimiting
+ if (!traits::valid_as<T>(attr))
+ return false;
+ else
+ return subject.generate(sink, ctx, d, traits::as<T>(attr)) &&
+ karma::delimit_out(sink, d); // always do post-delimiting
}
template <typename Context>
info what(Context& context) const
{
- return info("as_string", subject.what(context));
+ return info("as", subject.what(context));
}
Subject subject;
@@ -86,8 +106,7 @@
template <typename Subject, typename Modifiers>
struct make_directive<tag::as_string, Subject, Modifiers>
{
- typedef as_string_directive<Subject, char> result_type;
-
+ typedef as_directive<Subject, std::string> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
@@ -98,8 +117,18 @@
template <typename Subject, typename Modifiers>
struct make_directive<tag::as_wstring, Subject, Modifiers>
{
- typedef as_string_directive<Subject, wchar_t> result_type;
-
+ typedef as_directive<Subject, std::wstring> result_type;
+ result_type operator()(unused_type, Subject const& subject
+ , unused_type) const
+ {
+ return result_type(subject);
+ }
+ };
+
+ template <typename T, typename Subject, typename Modifiers>
+ struct make_directive<tag::stateful_tag<T, tag::as>, Subject, Modifiers>
+ {
+ typedef as_directive<Subject, T> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
@@ -111,14 +140,13 @@
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
- template <typename Subject, typename Char>
- struct has_semantic_action<karma::as_string_directive<Subject, Char> >
+ template <typename Subject, typename T>
+ struct has_semantic_action<karma::as_directive<Subject, T> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
- template <typename Subject, typename Attribute, typename Char>
- struct handles_container<
- karma::as_string_directive<Subject, Char>, Attribute>
+ template <typename Subject, typename Attribute, typename T>
+ struct handles_container<karma::as_directive<Subject, T>, Attribute>
: mpl::false_ {}; // always dereference attribute if used in sequences
}}}
Deleted: trunk/boost/spirit/home/karma/directive/as_string.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/as_string.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
+++ (empty file)
@@ -1,125 +0,0 @@
-// Copyright (c) 2001-2010 Hartmut Kaiser
-//
-// 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)
-
-#if !defined(SPIRIT_KARMA_AS_STRING_DEC_18_0510PM)
-#define SPIRIT_KARMA_AS_STRING_DEC_18_0510PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/karma/meta_compiler.hpp>
-#include <boost/spirit/home/karma/generator.hpp>
-#include <boost/spirit/home/karma/domain.hpp>
-#include <boost/spirit/home/karma/detail/output_iterator.hpp>
-#include <boost/spirit/home/karma/detail/as_string.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/common_terminals.hpp>
-#include <boost/spirit/home/support/has_semantic_action.hpp>
-#include <boost/spirit/home/support/handles_container.hpp>
-#include <boost/spirit/home/karma/detail/attributes.hpp>
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_directive<karma::domain, tag::as_string> // enables as_string
- : mpl::true_ {};
-
- template <>
- struct use_directive<karma::domain, tag::as_wstring> // enables as_wstring
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace karma
-{
- using spirit::as_string;
- using spirit::as_string_type;
- using spirit::as_wstring;
- using spirit::as_wstring_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // as_string_directive allows to hook custom conversions to string into the
- // output generation process
- ///////////////////////////////////////////////////////////////////////////
- template <typename Subject, typename Char>
- struct as_string_directive
- : unary_generator<as_string_directive<Subject, Char> >
- {
- typedef Subject subject_type;
- typedef typename subject_type::properties properties;
-
- as_string_directive(Subject const& subject)
- : subject(subject) {}
-
- template <typename Context, typename Iterator>
- struct attribute
- : traits::attribute_of<subject_type, Context, Iterator>
- {};
-
- template <typename OutputIterator, typename Context, typename Delimiter
- , typename Attribute>
- bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
- , Attribute const& attr) const
- {
- return subject.generate(sink, ctx, d, traits::as_string(attr)) &&
- karma::delimit_out(sink, d); // always do post-delimiting
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- return info("as_string", subject.what(context));
- }
-
- Subject subject;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // Generator generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Subject, typename Modifiers>
- struct make_directive<tag::as_string, Subject, Modifiers>
- {
- typedef as_string_directive<Subject, char> result_type;
-
- result_type operator()(unused_type, Subject const& subject
- , unused_type) const
- {
- return result_type(subject);
- }
- };
-
- template <typename Subject, typename Modifiers>
- struct make_directive<tag::as_wstring, Subject, Modifiers>
- {
- typedef as_string_directive<Subject, wchar_t> result_type;
-
- result_type operator()(unused_type, Subject const& subject
- , unused_type) const
- {
- return result_type(subject);
- }
- };
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- ///////////////////////////////////////////////////////////////////////////
- template <typename Subject, typename Char>
- struct has_semantic_action<karma::as_string_directive<Subject, Char> >
- : unary_has_semantic_action<Subject> {};
-
- ///////////////////////////////////////////////////////////////////////////
- template <typename Subject, typename Attribute, typename Char>
- struct handles_container<
- karma::as_string_directive<Subject, Char>, Attribute>
- : mpl::false_ {}; // always dereference attribute if used in sequences
-}}}
-
-#endif
Modified: trunk/boost/spirit/home/qi/directive.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive.hpp (original)
+++ trunk/boost/spirit/home/qi/directive.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -11,7 +11,7 @@
#pragma once
#endif
-#include <boost/spirit/home/qi/directive/as_string.hpp>
+#include <boost/spirit/home/qi/directive/as.hpp>
#include <boost/spirit/home/qi/directive/encoding.hpp>
#include <boost/spirit/home/qi/directive/hold.hpp>
#include <boost/spirit/home/qi/directive/lexeme.hpp>
Copied: trunk/boost/spirit/home/qi/directive/as.hpp (from r67430, /trunk/boost/spirit/home/qi/directive/as_string.hpp)
==============================================================================
--- /trunk/boost/spirit/home/qi/directive/as_string.hpp (original)
+++ trunk/boost/spirit/home/qi/directive/as.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,11 +1,13 @@
/*=============================================================================
Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2001-2010 Hartmut Kaiser
+ Copyright (c) 2010 Bryce Lelbach
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)
=============================================================================*/
-#if !defined(SPIRIT_AS_STRING_DECEMBER_6_2010_1013AM)
-#define SPIRIT_AS_STRING_DECEMBER_6_2010_1013AM
+#if !defined(SPIRIT_AS_DECEMBER_6_2010_1013AM)
+#define SPIRIT_AS_DECEMBER_6_2010_1013AM
#if defined(_MSC_VER)
#pragma once
@@ -23,18 +25,34 @@
#include <boost/range/iterator_range.hpp>
#include <string>
+namespace boost { namespace spirit { namespace qi
+{
+ template <typename T>
+ struct as
+ : stateful_tag_type<T, tag::as>
+ {};
+}}}
+
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
+ // enables as_string[...]
template <>
- struct use_directive<qi::domain, tag::as_string> // enables as_string
+ struct use_directive<qi::domain, tag::as_string>
: mpl::true_ {};
+ // enables as_wstring[...]
template <>
- struct use_directive<qi::domain, tag::as_wstring> // enables as_wstring
+ struct use_directive<qi::domain, tag::as_wstring>
: mpl::true_ {};
+
+ // enables as<T>[...]
+ template <typename T>
+ struct use_directive<qi::domain, tag::stateful_tag<T, tag::as> >
+ : mpl::true_
+ {};
}}
namespace boost { namespace spirit { namespace qi
@@ -44,17 +62,17 @@
using spirit::as_wstring;
using spirit::as_wstring_type;
- template <typename Subject, typename Char>
- struct as_string_directive : unary_parser<as_string_directive<Subject, Char> >
+ template <typename Subject, typename T>
+ struct as_directive : unary_parser<as_directive<Subject, T> >
{
typedef Subject subject_type;
- as_string_directive(Subject const& subject)
+ as_directive(Subject const& subject)
: subject(subject) {}
template <typename Context, typename Iterator>
struct attribute
{
- typedef std::basic_string<Char> type;
+ typedef T type;
};
template <typename Iterator, typename Context
@@ -64,10 +82,10 @@
{
qi::skip_over(first, last, skipper);
Iterator i = first;
- std::basic_string<Char> str_attr;
- if (subject.parse(i, last, context, skipper, str_attr))
+ T as_attr;
+ if (subject.parse(i, last, context, skipper, as_attr))
{
- spirit::traits::assign_to(str_attr, attr);
+ spirit::traits::assign_to(as_attr, attr);
first = i;
return true;
}
@@ -77,7 +95,7 @@
template <typename Context>
info what(Context& context) const
{
- return info("as_string", subject.what(context));
+ return info("as", subject.what(context));
}
Subject subject;
@@ -89,8 +107,9 @@
template <typename Subject, typename Modifiers>
struct make_directive<tag::as_string, Subject, Modifiers>
{
- typedef as_string_directive<Subject, char> result_type;
- result_type operator()(unused_type, Subject const& subject, unused_type) const
+ typedef as_directive<Subject, std::string> result_type;
+ result_type operator()(unused_type, Subject const& subject
+ , unused_type) const
{
return result_type(subject);
}
@@ -99,8 +118,20 @@
template <typename Subject, typename Modifiers>
struct make_directive<tag::as_wstring, Subject, Modifiers>
{
- typedef as_string_directive<Subject, wchar_t> result_type;
- result_type operator()(unused_type, Subject const& subject, unused_type) const
+ typedef as_directive<Subject, std::wstring> result_type;
+ result_type operator()(unused_type, Subject const& subject
+ , unused_type) const
+ {
+ return result_type(subject);
+ }
+ };
+
+ template <typename T, typename Subject, typename Modifiers>
+ struct make_directive<tag::stateful_tag<T, tag::as>, Subject, Modifiers>
+ {
+ typedef as_directive<Subject, T> result_type;
+ result_type operator()(unused_type, Subject const& subject
+ , unused_type) const
{
return result_type(subject);
}
@@ -109,8 +140,8 @@
namespace boost { namespace spirit { namespace traits
{
- template <typename Subject, typename Char>
- struct has_semantic_action<qi::as_string_directive<Subject, Char> >
+ template <typename Subject, typename T>
+ struct has_semantic_action<qi::as_directive<Subject, T> >
: unary_has_semantic_action<Subject> {};
}}}
Deleted: trunk/boost/spirit/home/qi/directive/as_string.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/as_string.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
+++ (empty file)
@@ -1,117 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2010 Joel de Guzman
-
- 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)
-=============================================================================*/
-#if !defined(SPIRIT_AS_STRING_DECEMBER_6_2010_1013AM)
-#define SPIRIT_AS_STRING_DECEMBER_6_2010_1013AM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/skip_over.hpp>
-#include <boost/spirit/home/qi/parser.hpp>
-#include <boost/spirit/home/qi/detail/assign_to.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/common_terminals.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/spirit/home/support/has_semantic_action.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <string>
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_directive<qi::domain, tag::as_string> // enables as_string
- : mpl::true_ {};
-
- template <>
- struct use_directive<qi::domain, tag::as_wstring> // enables as_wstring
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace qi
-{
- using spirit::as_string;
- using spirit::as_string_type;
- using spirit::as_wstring;
- using spirit::as_wstring_type;
-
- template <typename Subject, typename Char>
- struct as_string_directive : unary_parser<as_string_directive<Subject, Char> >
- {
- typedef Subject subject_type;
- as_string_directive(Subject const& subject)
- : subject(subject) {}
-
- template <typename Context, typename Iterator>
- struct attribute
- {
- typedef std::basic_string<Char> type;
- };
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper, Attribute& attr) const
- {
- qi::skip_over(first, last, skipper);
- Iterator i = first;
- std::basic_string<Char> str_attr;
- if (subject.parse(i, last, context, skipper, str_attr))
- {
- spirit::traits::assign_to(str_attr, attr);
- first = i;
- return true;
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- return info("as_string", subject.what(context));
- }
-
- Subject subject;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Subject, typename Modifiers>
- struct make_directive<tag::as_string, Subject, Modifiers>
- {
- typedef as_string_directive<Subject, char> result_type;
- result_type operator()(unused_type, Subject const& subject, unused_type) const
- {
- return result_type(subject);
- }
- };
-
- template <typename Subject, typename Modifiers>
- struct make_directive<tag::as_wstring, Subject, Modifiers>
- {
- typedef as_string_directive<Subject, wchar_t> result_type;
- result_type operator()(unused_type, Subject const& subject, unused_type) const
- {
- return result_type(subject);
- }
- };
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- template <typename Subject, typename Char>
- struct has_semantic_action<qi::as_string_directive<Subject, Char> >
- : unary_has_semantic_action<Subject> {};
-}}}
-
-#endif
Modified: trunk/boost/spirit/home/support/attributes_fwd.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes_fwd.hpp (original)
+++ trunk/boost/spirit/home/support/attributes_fwd.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,6 +1,7 @@
/*=============================================================================
Copyright (c) 2001-2010 Hartmut Kaiser
Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2010 Bryce Lelbach
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)
@@ -25,8 +26,8 @@
template <typename Exposed, typename Attribute>
struct extract_from;
- template <typename Attribute>
- struct attribute_as_string;
+ template <typename T, typename Attribute>
+ struct attribute_as_xxx;
template <typename Exposed, typename Transformed, typename Domain>
struct pre_transform;
@@ -122,12 +123,15 @@
///////////////////////////////////////////////////////////////////////////
// Karma only
- template <typename Attribute, typename Enable = void>
- struct attribute_as_string;
+ template <typename T, typename Attribute, typename Enable = void>
+ struct attribute_as_xxx;
- template <typename Attribute>
- typename spirit::result_of::attribute_as_string<Attribute>::type
- as_string(Attribute const& attr);
+ template <typename T, typename Attribute>
+ typename spirit::result_of::attribute_as_xxx<T, Attribute>::type
+ as(Attribute const& attr);
+
+ template <typename T, typename Attribute>
+ bool valid_as(Attribute const& attr);
///////////////////////////////////////////////////////////////////////////
// return the type currently stored in the given variant
Modified: trunk/boost/spirit/home/support/common_terminals.hpp
==============================================================================
--- trunk/boost/spirit/home/support/common_terminals.hpp (original)
+++ trunk/boost/spirit/home/support/common_terminals.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -140,6 +140,7 @@
namespace tag
{
struct attr_cast {};
+ struct as {};
}
}}
Modified: trunk/boost/spirit/home/support/utree/utree_traits.hpp
==============================================================================
--- trunk/boost/spirit/home/support/utree/utree_traits.hpp (original)
+++ trunk/boost/spirit/home/support/utree/utree_traits.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -22,6 +22,8 @@
#include <boost/range/iterator_range.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
///////////////////////////////////////////////////////////////////////////////
@@ -240,15 +242,108 @@
///////////////////////////////////////////////////////////////////////////
// Karma only: convert utree node to string
- template <>
- struct attribute_as_string<utree>
- {
+ template <typename T>
+ struct attribute_as_xxx<T, utree,
+ typename enable_if<mpl::or_<
+ boost::is_same<T, std::string>
+ , boost::is_same<T, utf8_string_type>
+ , boost::is_same<T, utf8_string_range_type>
+ > >::type
+ > {
typedef utf8_string_range_type type;
static type call(utree const& attr)
{
return boost::get<utf8_string_range_type>(attr);
}
+
+ static bool is_valid(utree const& attr)
+ {
+ switch (attr.which())
+ {
+ case utree_type::reference_type:
+ {
+ return is_valid(attr.deref());
+ }
+ case utree_type::string_range_type:
+ case utree_type::string_type:
+ {
+ return true;
+ }
+ default:
+ {
+ return false;
+ }
+ }
+ }
+ };
+
+ template <typename T>
+ struct attribute_as_xxx<T, utree,
+ typename enable_if<mpl::or_<
+ boost::is_same<T, utf8_symbol_type>
+ , boost::is_same<T, utf8_symbol_range_type>
+ > >::type
+ > {
+ typedef utf8_symbol_range_type type;
+
+ static type call(utree const& attr)
+ {
+ return boost::get<utf8_symbol_range_type>(attr);
+ }
+
+ static bool is_valid(utree const& attr)
+ {
+ switch (attr.which())
+ {
+ case utree_type::reference_type:
+ {
+ return is_valid(attr.deref());
+ }
+ case utree_type::symbol_type:
+ {
+ return true;
+ }
+ default:
+ {
+ return false;
+ }
+ }
+ }
+ };
+
+ template <typename T>
+ struct attribute_as_xxx<T, utree,
+ typename enable_if<mpl::or_<
+ boost::is_same<T, binary_string_type>
+ , boost::is_same<T, binary_range_type>
+ > >::type
+ > {
+ typedef binary_range_type type;
+
+ static type call(utree const& attr)
+ {
+ return boost::get<binary_range_type>(attr);
+ }
+
+ static bool is_valid(utree const& attr)
+ {
+ switch (attr.which())
+ {
+ case utree_type::reference_type:
+ {
+ return is_valid(attr.deref());
+ }
+ case utree_type::binary_type:
+ {
+ return true;
+ }
+ default:
+ {
+ return false;
+ }
+ }
+ }
};
///////////////////////////////////////////////////////////////////////////
Copied: trunk/boost/spirit/include/karma_as.hpp (from r67430, /trunk/boost/spirit/include/karma_as_string.hpp)
==============================================================================
--- /trunk/boost/spirit/include/karma_as_string.hpp (original)
+++ trunk/boost/spirit/include/karma_as.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,18 +1,19 @@
/*=============================================================================
Copyright (c) 2001-2010 Joel de Guzman
Copyright (c) 2001-2010 Hartmut Kaiser
+ Copyright (c) 2010 Bryce Lelbach
http://spirit.sourceforge.net/
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_SPIRIT_INCLUDE_KARMA_AS_STRING
-#define BOOST_SPIRIT_INCLUDE_KARMA_AS_STRING
+#ifndef BOOST_SPIRIT_INCLUDE_KARMA_AS
+#define BOOST_SPIRIT_INCLUDE_KARMA_AS
#if defined(_MSC_VER)
#pragma once
#endif
-#include <boost/spirit/home/karma/directive/as_string.hpp>
+#include <boost/spirit/home/karma/directive/as.hpp>
#endif
Deleted: trunk/boost/spirit/include/karma_as_string.hpp
==============================================================================
--- trunk/boost/spirit/include/karma_as_string.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
+++ (empty file)
@@ -1,18 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2010 Joel de Guzman
- Copyright (c) 2001-2010 Hartmut Kaiser
- http://spirit.sourceforge.net/
-
- 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_SPIRIT_INCLUDE_KARMA_AS_STRING
-#define BOOST_SPIRIT_INCLUDE_KARMA_AS_STRING
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/karma/directive/as_string.hpp>
-
-#endif
Copied: trunk/boost/spirit/include/qi_as.hpp (from r67430, /trunk/boost/spirit/include/qi_as_string.hpp)
==============================================================================
--- /trunk/boost/spirit/include/qi_as_string.hpp (original)
+++ trunk/boost/spirit/include/qi_as.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,18 +1,19 @@
/*=============================================================================
Copyright (c) 2001-2010 Joel de Guzman
Copyright (c) 2001-2010 Hartmut Kaiser
+ Copyright (c) 2010 Bryce Lelbach
http://spirit.sourceforge.net/
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_SPIRIT_INCLUDE_QI_AS_STRING
-#define BOOST_SPIRIT_INCLUDE_QI_AS_STRING
+#ifndef BOOST_SPIRIT_INCLUDE_QI_AS
+#define BOOST_SPIRIT_INCLUDE_QI_AS
#if defined(_MSC_VER)
#pragma once
#endif
-#include <boost/spirit/home/qi/directive/as_string.hpp>
+#include <boost/spirit/home/qi/directive/as.hpp>
#endif
Deleted: trunk/boost/spirit/include/qi_as_string.hpp
==============================================================================
--- trunk/boost/spirit/include/qi_as_string.hpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
+++ (empty file)
@@ -1,18 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2010 Joel de Guzman
- Copyright (c) 2001-2010 Hartmut Kaiser
- http://spirit.sourceforge.net/
-
- 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_SPIRIT_INCLUDE_QI_AS_STRING
-#define BOOST_SPIRIT_INCLUDE_QI_AS_STRING
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/directive/as_string.hpp>
-
-#endif
Modified: trunk/libs/spirit/test/karma/utree.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/utree.cpp (original)
+++ trunk/libs/spirit/test/karma/utree.cpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,5 +1,6 @@
// Copyright (c) 2001-2010 Hartmut Kaiser
// Copyright (c) 2001-2010 Joel de Guzman
+// Copyright (c) 2010 Bryce Lelbach
//
// 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)
@@ -167,7 +168,8 @@
BOOST_TEST(test("", -char_, ut));
}
- {
+ // as_string
+ {
using boost::spirit::karma::digit;
using boost::spirit::karma::as_string;
@@ -183,6 +185,40 @@
BOOST_TEST(test("a,b1.2", as_string[~digit % ','] << double_, ut));
}
+ // as
+ {
+ using boost::spirit::karma::digit;
+ using boost::spirit::karma::as;
+
+ typedef as<std::string> as_string_type;
+ as_string_type const as_string = as_string_type();
+
+ typedef as<utf8_symbol_type> as_symbol_type;
+ as_symbol_type const as_symbol = as_symbol_type();
+
+ utree ut("xy");
+ BOOST_TEST(test("xy", string, ut));
+ BOOST_TEST(test("xy", as_string[*char_], ut));
+ BOOST_TEST(test("x,y", as_string[char_ << ',' << char_], ut));
+
+ ut.clear();
+ ut.push_back("ab");
+ ut.push_back(1.2);
+ BOOST_TEST(test("ab1.2", as_string[*~digit] << double_, ut));
+ BOOST_TEST(test("a,b1.2", as_string[~digit % ','] << double_, ut));
+
+ ut = utf8_symbol_type("xy");
+ BOOST_TEST(test("xy", string, ut));
+ BOOST_TEST(test("xy", as_symbol[*char_], ut));
+ BOOST_TEST(test("x,y", as_symbol[char_ << ',' << char_], ut));
+
+ ut.clear();
+ ut.push_back(utf8_symbol_type("ab"));
+ ut.push_back(1.2);
+ BOOST_TEST(test("ab1.2", as_symbol[*~digit] << double_, ut));
+ BOOST_TEST(test("a,b1.2", as_symbol[~digit % ','] << double_, ut));
+ }
+
// typed basic_string rules
{
utree ut("buzz");
Modified: trunk/libs/spirit/test/qi/utree.cpp
==============================================================================
--- trunk/libs/spirit/test/qi/utree.cpp (original)
+++ trunk/libs/spirit/test/qi/utree.cpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,5 +1,6 @@
// Copyright (c) 2001-2010 Hartmut Kaiser
// Copyright (c) 2001-2010 Joel de Guzman
+// Copyright (c) 2010 Bryce Lelbach
//
// 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)
@@ -18,7 +19,12 @@
{
std::stringstream s;
s << val;
- return s.str() == expected + " ";
+ if (s.str() == expected + " ")
+ return true;
+
+ std::cerr << "got result: " << s.str()
+ << ", expected: " << expected << std::endl;
+ return false;
}
int main()
@@ -30,13 +36,16 @@
using boost::spirit::utf8_symbol_type;
using boost::spirit::utf8_string_type;
+ using boost::spirit::qi::real_parser;
+ using boost::spirit::qi::strict_real_policies;
+ using boost::spirit::qi::digit;
using boost::spirit::qi::char_;
using boost::spirit::qi::string;
using boost::spirit::qi::int_;
using boost::spirit::qi::double_;
using boost::spirit::qi::space;
using boost::spirit::qi::rule;
- using boost::spirit::qi::as_string;
+ using boost::spirit::qi::as;
using boost::spirit::qi::lexeme;
// primitive data types
@@ -75,7 +84,7 @@
// sequences
{
- using boost::spirit::qi::digit;
+ using boost::spirit::qi::as_string;
utree ut;
BOOST_TEST(test_attr("xy", char_ >> char_, ut) &&
@@ -166,9 +175,6 @@
// alternatives
{
- using boost::spirit::qi::real_parser;
- using boost::spirit::qi::strict_real_policies;
-
typedef real_parser<double, strict_real_policies<double> >
strict_double_type;
strict_double_type const strict_double = strict_double_type();
@@ -212,7 +218,7 @@
// as_string
{
- using boost::spirit::qi::digit;
+ using boost::spirit::qi::as_string;
utree ut;
BOOST_TEST(test_attr("xy", as_string[char_ >> char_], ut) &&
@@ -244,5 +250,62 @@
ut.clear();
}
+ // as
+ {
+ typedef as<std::string> as_string_type;
+ as_string_type const as_string = as_string_type();
+
+ typedef as<utf8_symbol_type> as_symbol_type;
+ as_symbol_type const as_symbol = as_symbol_type();
+
+ utree ut;
+ BOOST_TEST(test_attr("xy", as_string[char_ >> char_], ut) &&
+ ut.which() == utree_type::string_type && check(ut, "\"xy\""));
+ ut.clear();
+
+ BOOST_TEST(test_attr("ab1.2", as_string[*~digit] >> double_, ut) &&
+ ut.which() == utree_type::list_type && check(ut, "( \"ab\" 1.2 )"));
+ ut.clear();
+
+ BOOST_TEST(test_attr("xy", as_string[*char_], ut) &&
+ ut.which() == utree_type::string_type && check(ut, "\"xy\""));
+ ut.clear();
+
+ BOOST_TEST(test_attr("x,y", as_string[char_ >> ',' >> char_], ut) &&
+ ut.which() == utree_type::string_type && check(ut, "\"xy\""));
+ ut.clear();
+
+ BOOST_TEST(test_attr("x,y", char_ >> ',' >> char_, ut) &&
+ ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )"));
+ ut.clear();
+
+ BOOST_TEST(test_attr("a,b1.2", as_string[~digit % ','] >> double_, ut) &&
+ ut.which() == utree_type::list_type && check(ut, "( \"ab\" 1.2 )"));
+ ut.clear();
+
+ BOOST_TEST(test_attr("a,b1.2", ~digit % ',' >> double_, ut) &&
+ ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" 1.2 )"));
+ ut.clear();
+
+ BOOST_TEST(test_attr("xy", as_symbol[char_ >> char_], ut) &&
+ ut.which() == utree_type::symbol_type && check(ut, "xy"));
+ ut.clear();
+
+ BOOST_TEST(test_attr("ab1.2", as_symbol[*~digit] >> double_, ut) &&
+ ut.which() == utree_type::list_type && check(ut, "( ab 1.2 )"));
+ ut.clear();
+
+ BOOST_TEST(test_attr("xy", as_symbol[*char_], ut) &&
+ ut.which() == utree_type::symbol_type && check(ut, "xy"));
+ ut.clear();
+
+ BOOST_TEST(test_attr("x,y", as_symbol[char_ >> ',' >> char_], ut) &&
+ ut.which() == utree_type::symbol_type && check(ut, "xy"));
+ ut.clear();
+ BOOST_TEST(test_attr("a,b1.2", as_symbol[~digit % ','] >> double_, ut) &&
+ ut.which() == utree_type::list_type && check(ut, "( ab 1.2 )"));
+ ut.clear();
+ }
+
return boost::report_errors();
}
Modified: trunk/libs/spirit/test/support/utree_test.cpp
==============================================================================
--- trunk/libs/spirit/test/support/utree_test.cpp (original)
+++ trunk/libs/spirit/test/support/utree_test.cpp 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,6 +1,7 @@
/*=============================================================================
Copyright (c) 2001-2010 Joel de Guzman
Copyright (c) 2001-2010 Hartmut Kaiser
+ Copyright (c) 2010 Bryce Lelbach
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)
@@ -19,7 +20,12 @@
{
std::stringstream s;
s << val;
- return (s.str() == expected + " ") ? true : false;
+ if (s.str() == expected + " ")
+ return true;
+
+ std::cerr << "got result: " << s.str()
+ << ", expected: " << expected << std::endl;
+ return false;
}
struct one_two_three
@@ -35,6 +41,8 @@
using boost::spirit::utree;
using boost::spirit::nil;
using boost::spirit::uninitialized;
+ using boost::spirit::utf8_symbol_type;
+ using boost::spirit::binary_string_type;
{
// test the size
@@ -62,6 +70,10 @@
// single element string
utree val('x');
BOOST_TEST(check(val, "\"x\""));
+
+ // empty string
+ utree val1("");
+ BOOST_TEST(check(val1, "\"\""));
}
{
@@ -69,7 +81,7 @@
BOOST_TEST(check(val, "123.456"));
}
- {
+ { // strings
utree val("Hello, World");
BOOST_TEST(check(val, "\"Hello, World\""));
utree val2;
@@ -87,6 +99,42 @@
BOOST_TEST(val4 < val6);
}
+ { // symbols
+ utree val(utf8_symbol_type("Hello, World"));
+ BOOST_TEST(check(val, "Hello, World"));
+ utree val2;
+ val2 = val;
+ BOOST_TEST(check(val2, "Hello, World"));
+ utree val3(utf8_symbol_type("Hello, World. Chuckie is back!!!"));
+ val = val3;
+ BOOST_TEST(check(val, "Hello, World. Chuckie is back!!!"));
+
+ utree val4(utf8_symbol_type("Apple"));
+ utree val5(utf8_symbol_type("Apple"));
+ BOOST_TEST(val4 == val5);
+
+ utree val6(utf8_symbol_type("ApplePie"));
+ BOOST_TEST(val4 < val6);
+ }
+
+ { // binary_strings
+ utree val(binary_string_type("\xDE#\xAD"));
+ BOOST_TEST(check(val, "#de23ad#" /* FIXME?: "#\xDE#\xAD#" */));
+ utree val2;
+ val2 = val;
+ BOOST_TEST(check(val2, "#de23ad#" /* FIXME?: "#\xDE#\xAD#" */));
+ utree val3(binary_string_type("\xDE\xAD\xBE\xEF"));
+ val = val3;
+ BOOST_TEST(check(val, "#deadbeef#" /* FIXME?: "#\xDE\xAD\xBE\xEF#" */));
+
+ utree val4(binary_string_type("\x01"));
+ utree val5(binary_string_type("\x01"));
+ BOOST_TEST(val4 == val5);
+
+ utree val6(binary_string_type("\x01\x02"));
+ BOOST_TEST(val4 < val6);
+ }
+
{
utree val;
val.push_back(123);
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