|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r80601 - in sandbox/type_erasure: boost/type_erasure boost/type_erasure/detail libs/type_erasure/test
From: steven_at_[hidden]
Date: 2012-09-19 18:46:37
Author: steven_watanabe
Date: 2012-09-19 18:46:36 EDT (Wed, 19 Sep 2012)
New Revision: 80601
URL: http://svn.boost.org/trac/boost/changeset/80601
Log:
Implement BOOST_TYPE_ERASURE_FREE matching BOOST_TYPE_ERASURE_MEMBER.
Added:
sandbox/type_erasure/boost/type_erasure/detail/macro.hpp (contents, props changed)
sandbox/type_erasure/boost/type_erasure/free.hpp (contents, props changed)
sandbox/type_erasure/libs/type_erasure/test/test_free.cpp (contents, props changed)
Text files modified:
sandbox/type_erasure/boost/type_erasure/member.hpp | 54 +++++++++++----------------------------
sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam | 1
2 files changed, 16 insertions(+), 39 deletions(-)
Added: sandbox/type_erasure/boost/type_erasure/detail/macro.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/macro.hpp 2012-09-19 18:46:36 EDT (Wed, 19 Sep 2012)
@@ -0,0 +1,47 @@
+// Boost.TypeErasure library
+//
+// Copyright 2012 Steven Watanabe
+//
+// 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)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_MACRO_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_MACRO_HPP_INCLUDED
+
+#include <boost/preprocessor/dec.hpp>
+#include <boost/preprocessor/if.hpp>
+#include <boost/preprocessor/comparison/not_equal.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/seq/for_each.hpp>
+#include <boost/preprocessor/seq/pop_back.hpp>
+#include <boost/preprocessor/seq/size.hpp>
+#include <boost/preprocessor/tuple/eat.hpp>
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_OPEN_NAMESPACE_F(z, data, x) \
+ namespace x {
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_OPEN_NAMEPACE_I(seq)\
+ BOOST_PP_SEQ_FOR_EACH(BOOST_TYPE_ERASURE_OPEN_NAMESPACE_F, ~, BOOST_PP_SEQ_POP_BACK(seq))
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_OPEN_NAMESPACE(seq)\
+ BOOST_PP_IF(BOOST_PP_NOT_EQUAL(BOOST_PP_SEQ_SIZE(seq), 1), BOOST_TYPE_ERASURE_OPEN_NAMEPACE_I, BOOST_PP_TUPLE_EAT(1))(seq)
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(seq) \
+ BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq)), } BOOST_PP_TUPLE_EAT(3), ~)
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_QUALIFIED_NAME_F(z, data, x)\
+ ::x
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_QUALIFIED_NAME(seq) \
+ BOOST_PP_SEQ_FOR_EACH(BOOST_TYPE_ERASURE_QUALIFIED_NAME_F, ~, seq)
+
+#endif
Added: sandbox/type_erasure/boost/type_erasure/free.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/free.hpp 2012-09-19 18:46:36 EDT (Wed, 19 Sep 2012)
@@ -0,0 +1,157 @@
+// Boost.TypeErasure library
+//
+// Copyright 2012 Steven Watanabe
+//
+// 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)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_FREE_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_FREE_HPP_INCLUDED
+
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/next.hpp>
+#include <boost/type_erasure/detail/macro.hpp>
+#include <boost/type_erasure/config.hpp>
+#include <boost/type_erasure/derived.hpp>
+#include <boost/type_erasure/rebind_any.hpp>
+#include <boost/type_erasure/is_placeholder.hpp>
+#include <boost/type_erasure/call.hpp>
+#include <boost/type_erasure/concept_interface.hpp>
+
+namespace boost {
+namespace type_erasure {
+namespace detail {
+
+template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_TYPE_ERASURE_MAX_ARITY, class T, void)>
+struct first_placeholder {
+ typedef typename ::boost::mpl::eval_if<is_placeholder<T0>,
+ ::boost::mpl::identity<T0>,
+ first_placeholder<BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_TYPE_ERASURE_MAX_ARITY, T)>
+ >::type type;
+};
+
+template<>
+struct first_placeholder<> {};
+
+template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_TYPE_ERASURE_MAX_ARITY, class T, void)>
+struct first_placeholder_index :
+ ::boost::mpl::eval_if<is_placeholder<T0>,
+ ::boost::mpl::int_<0>,
+ ::boost::mpl::next<first_placeholder<BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_TYPE_ERASURE_MAX_ARITY, T)> >
+ >::type
+{};
+
+}
+}
+}
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_FREE_QUALIFIED_ID(seq, N) \
+ BOOST_TYPE_ERASURE_QUALIFIED_NAME(seq)<R(BOOST_PP_ENUM_PARAMS(N, T))>
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_FREE_UNQUALIFIED_PARAM_TYPE(z, n, data) \
+ typename ::boost::remove_cv<typename ::boost::remove_reference<BOOST_PP_CAT(T, n)>::type>::type
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_FREE_PARAM_TYPE(z, n, data) \
+ typename ::boost::mpl::eval_if_c<(_boost_type_erasure_free_p_idx::value == n), \
+ ::boost::type_erasure::derived<Base>, \
+ ::boost::type_erasure::rebind_any<Base, BOOST_PP_CAT(T, n)> \
+ >::type BOOST_PP_CAT(t, n)
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_FREE_II(qual_name, concept_name, function_name, N) \
+ BOOST_TYPE_ERASURE_OPEN_NAMESPACE(qual_name) \
+ \
+ template<class Sig> \
+ struct concept_name; \
+ \
+ template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)> \
+ struct concept_name<R(BOOST_PP_ENUM_PARAMS(N, T))> { \
+ static R apply(BOOST_PP_ENUM_BINARY_PARAMS(N, T, t)) \
+ { return function_name(BOOST_PP_ENUM_PARAMS(N, t)); } \
+ }; \
+ \
+ template<BOOST_PP_ENUM_PARAMS(N, class T)> \
+ struct concept_name<void(BOOST_PP_ENUM_PARAMS(N, T))> { \
+ static void apply(BOOST_PP_ENUM_BINARY_PARAMS(N, T, t)) \
+ { function_name(BOOST_PP_ENUM_PARAMS(N, t)); } \
+ }; \
+ \
+ BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(qual_name) \
+ \
+ namespace boost { \
+ namespace type_erasure { \
+ \
+ template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class Base> \
+ struct concept_interface< \
+ BOOST_TYPE_ERASURE_FREE_QUALIFIED_ID(qual_name, N), \
+ Base, \
+ typename ::boost::type_erasure::detail::first_placeholder< \
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FREE_UNQUALIFIED_PARAM_TYPE, ~)>::type \
+ > : Base { \
+ typedef typename ::boost::type_erasure::detail::first_placeholder_index< \
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FREE_UNQUALIFIED_PARAM_TYPE, ~)>::type \
+ _boost_type_erasure_free_p_idx; \
+ friend typename ::boost::type_erasure::rebind_any<Base, R>::type function_name( \
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FREE_PARAM_TYPE, ~)) \
+ { \
+ return ::boost::type_erasure::call( \
+ BOOST_TYPE_ERASURE_FREE_QUALIFIED_ID(qual_name, N)() \
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, t)); \
+ } \
+ }; \
+ \
+ } \
+ }
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_FREE_I(namespace_name, concept_name, function_name, N)\
+ BOOST_TYPE_ERASURE_FREE_II(namespace_name, concept_name, function_name, N)
+
+/**
+ * \brief Defines a primitive concept for a free function.
+ *
+ * \param qualified_name should be a preprocessor sequence
+ * of the form (namespace1)(namespace2)...(concept_name).
+ * \param function_name is the name of the function.
+ * \param N is the number of arguments of the function.
+ *
+ * The declaration of the concept is
+ * \code
+ * template<class Sig>
+ * struct ::namespace1::namespace2::...::concept_name;
+ * \endcode
+ * where Sig is a function type giving the
+ * signature of the member function.
+ *
+ * This macro can only be used in the global namespace.
+ *
+ * Example:
+ *
+ * \code
+ * BOOST_TYPE_ERASURE_FREE((boost)(has_to_string), to_string, 1)
+ * \endcode
+ */
+#define BOOST_TYPE_ERASURE_FREE(qualified_name, function_name, N) \
+ BOOST_TYPE_ERASURE_FREE_I( \
+ qualified_name, \
+ BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(qualified_name)), qualified_name), \
+ function_name, \
+ N)
+
+#endif
Modified: sandbox/type_erasure/boost/type_erasure/member.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/member.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/member.hpp 2012-09-19 18:46:36 EDT (Wed, 19 Sep 2012)
@@ -14,52 +14,28 @@
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/dec.hpp>
#include <boost/preprocessor/comma_if.hpp>
-#include <boost/preprocessor/if.hpp>
-#include <boost/preprocessor/comparison/not_equal.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
-#include <boost/preprocessor/seq/for_each.hpp>
-#include <boost/preprocessor/seq/pop_back.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/seq/elem.hpp>
-#include <boost/preprocessor/tuple/eat.hpp>
-
-/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_OPEN_NAMESPACE_F(z, data, x) \
- namespace x {
-
-/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_OPEN_NAMEPACE_I(seq)\
- BOOST_PP_SEQ_FOR_EACH(BOOST_TYPE_ERASURE_OPEN_NAMESPACE_F, ~, BOOST_PP_SEQ_POP_BACK(seq))
-
-/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_OPEN_NAMESPACE(seq)\
- BOOST_PP_IF(BOOST_PP_NOT_EQUAL(BOOST_PP_SEQ_SIZE(seq), 1), BOOST_TYPE_ERASURE_OPEN_NAMEPACE_I, BOOST_PP_TUPLE_EAT(1))(seq)
-
-/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(seq) \
- BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq)), } BOOST_PP_TUPLE_EAT(3), ~)
+#include <boost/type_erasure/detail/macro.hpp>
+#include <boost/type_erasure/rebind_any.hpp>
+#include <boost/type_erasure/placeholder.hpp>
+#include <boost/type_erasure/call.hpp>
+#include <boost/type_erasure/concept_interface.hpp>
/** INTERNAL ONLY */
#define BOOST_TYPE_ERASURE_MEMBER_ARG(z, n, data) \
typename ::boost::type_erasure::rebind_any<Base, BOOST_PP_CAT(A, n)>::type BOOST_PP_CAT(a, n)
/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_QUALIFIED_NAME_F(z, data, x)\
- ::x
-
-/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_QUALIFIED_NAME(seq) \
- BOOST_PP_SEQ_FOR_EACH(BOOST_TYPE_ERASURE_QUALIFIED_NAME_F, ~, seq)
-
-/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_QUALIFIED_ID(seq, N) \
+#define BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(seq, N) \
BOOST_TYPE_ERASURE_QUALIFIED_NAME(seq)<R(BOOST_PP_ENUM_PARAMS(N, A)), T>
/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_QUALIFIED_ID_C(seq, N) \
+#define BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(seq, N) \
BOOST_TYPE_ERASURE_QUALIFIED_NAME(seq)<R(BOOST_PP_ENUM_PARAMS(N, A)), const T>
/** INTERNAL ONLY */
@@ -84,7 +60,7 @@
class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class A), \
class T, class Base, class Enable> \
struct concept_interface< \
- BOOST_TYPE_ERASURE_QUALIFIED_ID(qual_name, N), \
+ BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N), \
Base, T, Enable> : Base \
{ \
typedef void BOOST_PP_CAT(_boost_type_erasure_has_member, member); \
@@ -92,7 +68,7 @@
BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_MEMBER_ARG, ~)) \
{ \
return ::boost::type_erasure::call( \
- BOOST_TYPE_ERASURE_QUALIFIED_ID(qual_name, N)(), \
+ BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N)(), \
*this BOOST_PP_ENUM_TRAILING_PARAMS(N, a)); \
} \
}; \
@@ -100,7 +76,7 @@
class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class A), \
class T, class Base, class Enable> \
struct concept_interface< \
- BOOST_TYPE_ERASURE_QUALIFIED_ID_C(qual_name, N), \
+ BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(qual_name, N), \
Base, T, Enable> : Base \
{ \
typedef void BOOST_PP_CAT(_boost_type_erasure_has_member, member); \
@@ -108,13 +84,13 @@
BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_MEMBER_ARG, ~)) const \
{ \
return ::boost::type_erasure::call( \
- BOOST_TYPE_ERASURE_QUALIFIED_ID_C(qual_name, N)(), \
+ BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(qual_name, N)(), \
*this BOOST_PP_ENUM_TRAILING_PARAMS(N, a)); \
} \
}; \
template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class A), class T, class Base> \
struct concept_interface< \
- BOOST_TYPE_ERASURE_QUALIFIED_ID(qual_name, N), \
+ BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N), \
Base, T, typename Base::BOOST_PP_CAT(_boost_type_erasure_has_member, member)> : Base \
{ \
using Base::member; \
@@ -122,13 +98,13 @@
BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_MEMBER_ARG, ~)) \
{ \
return ::boost::type_erasure::call( \
- BOOST_TYPE_ERASURE_QUALIFIED_ID(qual_name, N)(), \
+ BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N)(), \
*this BOOST_PP_ENUM_TRAILING_PARAMS(N, a)); \
} \
}; \
template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class A), class T, class Base> \
struct concept_interface< \
- BOOST_TYPE_ERASURE_QUALIFIED_ID_C(qual_name, N), \
+ BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(qual_name, N), \
Base, T, \
typename Base::BOOST_PP_CAT(_boost_type_erasure_has_member, member)> : Base \
{ \
@@ -137,7 +113,7 @@
BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_MEMBER_ARG, ~)) const \
{ \
return ::boost::type_erasure::call( \
- BOOST_TYPE_ERASURE_QUALIFIED_ID_C(qual_name, N)(), \
+ BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(qual_name, N)(), \
*this BOOST_PP_ENUM_TRAILING_PARAMS(N, a)); \
} \
}; \
Modified: sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam (original)
+++ sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam 2012-09-19 18:46:36 EDT (Wed, 19 Sep 2012)
@@ -35,6 +35,7 @@
run test_same_type.cpp /boost//unit_test_framework ;
run test_member.cpp /boost//unit_test_framework ;
run test_null.cpp /boost//unit_test_framework ;
+run test_free.cpp /boost//unit_test_framework ;
compile-fail fail_default_construct.cpp ;
compile-fail fail_construct_mismatch.cpp ;
Added: sandbox/type_erasure/libs/type_erasure/test/test_free.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_free.cpp 2012-09-19 18:46:36 EDT (Wed, 19 Sep 2012)
@@ -0,0 +1,99 @@
+// Boost.TypeErasure library
+//
+// Copyright 2012 Steven Watanabe
+//
+// 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)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/free.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+struct model {
+ explicit model(int v) : val(v) {}
+ int val;
+};
+
+int f1(model& m) { return m.val; }
+int f1(model& m, int i) { return m.val + i; }
+
+BOOST_TYPE_ERASURE_FREE((global_has_f1_1), f1, 1);
+
+BOOST_AUTO_TEST_CASE(test_global_has_f1_1) {
+ typedef ::boost::mpl::vector<
+ global_has_f1_1<int(_self&)>,
+ copy_constructible<> > concept_type;
+ model m(10);
+ any<concept_type> x(m);
+ BOOST_CHECK_EQUAL(f1(x), 10);
+}
+
+BOOST_TYPE_ERASURE_FREE((ns1)(ns2)(ns_has_f1_1), f1, 1);
+
+BOOST_AUTO_TEST_CASE(test_ns_has_f1_1) {
+ typedef ::boost::mpl::vector<
+ ns1::ns2::ns_has_f1_1<int(_self&)>,
+ copy_constructible<> > concept_type;
+ model m(10);
+ any<concept_type> x(m);
+ BOOST_CHECK_EQUAL(f1(x), 10);
+}
+
+struct model_const {
+ explicit model_const(int v) : val(v) {}
+ int val;
+};
+
+int f1(const model_const& m) { return m.val; }
+int f1(const model_const& m, int i) { return m.val + i; }
+
+BOOST_AUTO_TEST_CASE(test_global_has_f1_1_const) {
+ typedef ::boost::mpl::vector<
+ ns1::ns2::ns_has_f1_1<int(const _self&)>,
+ copy_constructible<> > concept_type;
+ model_const m(10);
+ any<concept_type> x(m);
+ BOOST_CHECK_EQUAL(f1(x), 10);
+}
+
+BOOST_AUTO_TEST_CASE(test_global_has_f1_1_void) {
+ typedef ::boost::mpl::vector<
+ global_has_f1_1<void(_self&)>,
+ copy_constructible<> > concept_type;
+ model m(10);
+ any<concept_type> x(m);
+ f1(x);
+}
+
+BOOST_TYPE_ERASURE_FREE((global_has_f1_2), f1, 2);
+
+BOOST_AUTO_TEST_CASE(test_global_has_f1_overload) {
+ typedef ::boost::mpl::vector<
+ global_has_f1_1<int(_self&)>,
+ global_has_f1_2<int(_self&, int)>,
+ copy_constructible<> > concept_type;
+ model m(10);
+ any<concept_type> x(m);
+ BOOST_CHECK_EQUAL(f1(x), 10);
+ BOOST_CHECK_EQUAL(f1(x, 5), 15);
+}
+
+BOOST_AUTO_TEST_CASE(test_global_has_f1_overload_const) {
+ typedef ::boost::mpl::vector<
+ global_has_f1_1<int(const _self&)>,
+ global_has_f1_2<int(const _self&, int)>,
+ copy_constructible<> > concept_type;
+ model_const m(10);
+ any<concept_type> x(m);
+ BOOST_CHECK_EQUAL(f1(x), 10);
+ BOOST_CHECK_EQUAL(f1(x, 5), 15);
+}
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