Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r73906 - in trunk: boost/fusion/algorithm/iteration boost/fusion/algorithm/iteration/detail boost/fusion/algorithm/iteration/ext_ libs/fusion/test/algorithm libs/fusion/test/sequence
From: eric_at_[hidden]
Date: 2011-08-18 19:14:50


Author: eric_niebler
Date: 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
New Revision: 73906
URL: http://svn.boost.org/trac/boost/changeset/73906

Log:
make fold aware of segments
Added:
   trunk/boost/fusion/algorithm/iteration/accumulate_fwd.hpp (contents, props changed)
   trunk/boost/fusion/algorithm/iteration/detail/segmented_fold.hpp
      - copied, changed from r73898, /trunk/boost/fusion/algorithm/iteration/ext_/fold_s.hpp
   trunk/boost/fusion/algorithm/iteration/fold_fwd.hpp (contents, props changed)
   trunk/boost/fusion/algorithm/iteration/iter_fold_fwd.hpp (contents, props changed)
   trunk/boost/fusion/algorithm/iteration/reverse_fold_fwd.hpp (contents, props changed)
   trunk/boost/fusion/algorithm/iteration/reverse_iter_fold_fwd.hpp (contents, props changed)
Removed:
   trunk/boost/fusion/algorithm/iteration/ext_/
Text files modified:
   trunk/boost/fusion/algorithm/iteration/accumulate.hpp | 1
   trunk/boost/fusion/algorithm/iteration/detail/fold.hpp | 61 ++++++++++++++++++++++++++-------------
   trunk/boost/fusion/algorithm/iteration/detail/segmented_fold.hpp | 44 +++++++++++-----------------
   trunk/boost/fusion/algorithm/iteration/fold.hpp | 2 +
   trunk/boost/fusion/algorithm/iteration/iter_fold.hpp | 1
   trunk/boost/fusion/algorithm/iteration/reverse_fold.hpp | 1
   trunk/boost/fusion/algorithm/iteration/reverse_iter_fold.hpp | 1
   trunk/libs/fusion/test/algorithm/segmented_fold.cpp | 4 +-
   trunk/libs/fusion/test/sequence/segmented_iterator_range.cpp | 4 +-
   9 files changed, 69 insertions(+), 50 deletions(-)

Modified: trunk/boost/fusion/algorithm/iteration/accumulate.hpp
==============================================================================
--- trunk/boost/fusion/algorithm/iteration/accumulate.hpp (original)
+++ trunk/boost/fusion/algorithm/iteration/accumulate.hpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -7,6 +7,7 @@
 #if !defined(FUSION_ACCUMULATE_09172005_1032)
 #define FUSION_ACCUMULATE_09172005_1032
 
+#include <boost/fusion/algorithm/iteration/accumulate_fwd.hpp>
 #include <boost/fusion/algorithm/iteration/fold.hpp>
 
 namespace boost { namespace fusion

Added: trunk/boost/fusion/algorithm/iteration/accumulate_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/fusion/algorithm/iteration/accumulate_fwd.hpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -0,0 +1,28 @@
+/*=============================================================================
+ Copyright (c) 2011 Eric Niebler
+
+ 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_FUSION_ACCUMULATE_FWD_HPP_INCLUDED)
+#define BOOST_FUSION_ACCUMULATE_FWD_HPP_INCLUDED
+
+namespace boost { namespace fusion
+{
+ namespace result_of
+ {
+ template <typename Sequence, typename State, typename F>
+ struct accumulate;
+ }
+
+ template <typename Sequence, typename State, typename F>
+ typename result_of::accumulate<Sequence, State const, F>::type
+ accumulate(Sequence& seq, State const& state, F f);
+
+ template <typename Sequence, typename State, typename F>
+ typename result_of::accumulate<Sequence const, State const, F>::type
+ accumulate(Sequence const& seq, State const& state, F f);
+}}
+
+#endif
+

Modified: trunk/boost/fusion/algorithm/iteration/detail/fold.hpp
==============================================================================
--- trunk/boost/fusion/algorithm/iteration/detail/fold.hpp (original)
+++ trunk/boost/fusion/algorithm/iteration/detail/fold.hpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -15,6 +15,7 @@
 #include <boost/fusion/sequence/intrinsic/end.hpp>
 #include <boost/fusion/sequence/intrinsic/empty.hpp>
 #include <boost/fusion/sequence/intrinsic/size.hpp>
+#include <boost/fusion/support/is_segmented.hpp>
 #include <boost/fusion/iterator/equal_to.hpp>
 #include <boost/fusion/iterator/deref.hpp>
 #include <boost/fusion/iterator/value_of.hpp>
@@ -347,53 +348,73 @@
             type;
         };
 
- template<int SeqSize, typename StateRef, typename It0, typename F>
+ template<int SeqSize, typename StateRef, typename Seq, typename F>
         struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)
         {
             typedef typename
                 BOOST_PP_CAT(
                     result_of_first_unrolled,BOOST_FUSION_FOLD_NAME)<
                     StateRef
- , BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(It0)
+ , BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(
+ typename result_of::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type
+ )
                   , F
                   , SeqSize
>::type
             type;
 
             static type
- call(StateRef state, It0 const& it0, F f)
+ call(StateRef state, Seq& seq, F f)
             {
- return BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<
- type
- , SeqSize
- >::call(state,BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(it0),f);
+ typedef
+ BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<
+ type
+ , SeqSize
+ >
+ unrolled_impl;
+
+ return unrolled_impl::call(
+ state,
+ BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(
+ fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq)),
+ f);
             }
         };
 
- template<typename StateRef, typename It0, typename F>
- struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)<0,StateRef,It0,F>
+ template<typename StateRef, typename Seq, typename F>
+ struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)<0,StateRef,Seq,F>
         {
             typedef StateRef type;
 
             static StateRef
- call(StateRef state, It0 const&, F)
+ call(StateRef state, Seq&, F)
             {
                 return static_cast<StateRef>(state);
             }
         };
+
+ template<typename Seq, typename State, typename F, bool IsSegmented>
+ struct BOOST_PP_CAT(result_of_, BOOST_FUSION_FOLD_NAME)
+ : BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)<
+ result_of::size<Seq>::value
+ , typename add_reference<
+ typename add_const<State>::type
+ >::type
+ , Seq
+ , F
+ >
+ {};
     }
 
     namespace result_of
     {
         template<typename Seq, typename State, typename F>
         struct BOOST_FUSION_FOLD_NAME
- : detail::BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)<
- size<Seq>::value
- , typename add_reference<
- typename add_const<State>::type
- >::type
- , typename BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type
+ : detail::BOOST_PP_CAT(result_of_, BOOST_FUSION_FOLD_NAME)<
+ Seq
+ , State
               , F
+ , traits::is_segmented<Seq>::type::value
>
         {};
     }
@@ -408,7 +429,7 @@
     {
         return result_of::BOOST_FUSION_FOLD_NAME<Seq,State const,F>::call(
             state,
- fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq),
+ seq,
             f);
     }
 
@@ -422,7 +443,7 @@
     {
         return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State const,F>::call(
             state,
- fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq),
+ seq,
             f);
     }
 
@@ -436,7 +457,7 @@
     {
         return result_of::BOOST_FUSION_FOLD_NAME<Seq,State,F>::call(
             state,
- fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq),
+ seq,
             f);
     }
 
@@ -450,7 +471,7 @@
     {
         return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State,F>::call(
             state,
- fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq),
+ seq,
             f);
     }
 }}

Copied: trunk/boost/fusion/algorithm/iteration/detail/segmented_fold.hpp (from r73898, /trunk/boost/fusion/algorithm/iteration/ext_/fold_s.hpp)
==============================================================================
--- /trunk/boost/fusion/algorithm/iteration/ext_/fold_s.hpp (original)
+++ trunk/boost/fusion/algorithm/iteration/detail/segmented_fold.hpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -7,7 +7,7 @@
 #if !defined(BOOST_FUSION_FOLD_S_HPP_INCLUDED)
 #define BOOST_FUSION_FOLD_S_HPP_INCLUDED
 
-#include <boost/fusion/algorithm/iteration/fold.hpp>
+#include <boost/fusion/algorithm/iteration/fold_fwd.hpp>
 #include <boost/fusion/support/segmented_fold_until.hpp>
 
 namespace boost { namespace fusion { namespace detail
@@ -33,35 +33,27 @@
             }
         };
     };
-}}}
 
-namespace boost { namespace fusion
-{
- namespace result_of
+ // The default implementation of this lives in detail/fold.hpp
+ template <typename Sequence, typename State, typename Fun, bool IsSegmented>
+ struct result_of_fold;
+
+ template <typename Sequence, typename State, typename Fun>
+ struct result_of_fold<Sequence, State, Fun, true>
     {
- template <typename Sequence, typename State, typename F>
- struct fold_s
- : result_of::segmented_fold_until<
+ typedef
+ typename result_of::segmented_fold_until<
                 Sequence,
                 State,
- detail::segmented_fold_fun<F>
- >
- {};
- }
-
- template <typename Sequence, typename State, typename F>
- typename result_of::fold_s<Sequence, State, F>::type
- fold_s(Sequence& seq, State const& state, F const& f)
- {
- return fusion::segmented_fold_until(seq, state, detail::segmented_fold_fun<F>(f));
- }
+ segmented_fold_fun<Fun>
+ >::type
+ type;
 
- template <typename Sequence, typename State, typename F>
- typename result_of::fold_s<Sequence const, State, F>::type
- fold_s(Sequence const& seq, State const& state, F const& f)
- {
- return fusion::segmented_fold_until(seq, state, detail::segmented_fold_fun<F>(f));
- }
-}}
+ static type call(State& state, Sequence& seq, Fun fun)
+ {
+ return fusion::segmented_fold_until(seq, state, segmented_fold_fun<Fun>(fun));
+ }
+ };
+}}}
 
 #endif

Modified: trunk/boost/fusion/algorithm/iteration/fold.hpp
==============================================================================
--- trunk/boost/fusion/algorithm/iteration/fold.hpp (original)
+++ trunk/boost/fusion/algorithm/iteration/fold.hpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -10,6 +10,8 @@
 #ifndef BOOST_FUSION_ALGORITHM_ITERATION_FOLD_HPP
 #define BOOST_FUSION_ALGORITHM_ITERATION_FOLD_HPP
 
+#include <boost/fusion/algorithm/iteration/fold_fwd.hpp>
 #include <boost/fusion/algorithm/iteration/detail/fold.hpp>
+#include <boost/fusion/algorithm/iteration/detail/segmented_fold.hpp>
 
 #endif

Added: trunk/boost/fusion/algorithm/iteration/fold_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/fusion/algorithm/iteration/fold_fwd.hpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -0,0 +1,52 @@
+/*=============================================================================
+ Copyright (c) 2011 Eric Niebler
+
+ 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_FUSION_ALGORITHM_ITERATION_FOLD_FWD_HPP
+#define BOOST_FUSION_ALGORITHM_ITERATION_FOLD_FWD_HPP
+
+namespace boost { namespace fusion
+{
+ namespace result_of
+ {
+ template<typename Seq, typename State, typename F>
+ struct fold;
+ }
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::fold<
+ Seq
+ , State const
+ , F
+ >::type
+ fold(Seq& seq, State const& state, F f);
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::fold<
+ Seq const
+ , State const
+ , F
+ >::type
+ fold(Seq const& seq, State const& state, F f);
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::fold<
+ Seq
+ , State const
+ , F
+ >::type
+ fold(Seq& seq, State& state, F f);
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::fold<
+ Seq const
+ , State const
+ , F
+ >::type
+ fold(Seq const& seq, State& state, F f);
+}}
+
+#endif

Modified: trunk/boost/fusion/algorithm/iteration/iter_fold.hpp
==============================================================================
--- trunk/boost/fusion/algorithm/iteration/iter_fold.hpp (original)
+++ trunk/boost/fusion/algorithm/iteration/iter_fold.hpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -10,6 +10,7 @@
 
 #define BOOST_FUSION_ITER_FOLD
 
+#include <boost/fusion/algorithm/iteration/iter_fold_fwd.hpp>
 #include <boost/fusion/algorithm/iteration/detail/fold.hpp>
 
 #undef BOOST_FUSION_ITER_FOLD

Added: trunk/boost/fusion/algorithm/iteration/iter_fold_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/fusion/algorithm/iteration/iter_fold_fwd.hpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -0,0 +1,52 @@
+/*=============================================================================
+ Copyright (c) 2011 Eric Niebler
+
+ 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_FUSION_ALGORITHM_ITERATION_ITER_FOLD_FWD_HPP
+#define BOOST_FUSION_ALGORITHM_ITERATION_ITER_FOLD_FWD_HPP
+
+namespace boost { namespace fusion
+{
+ namespace result_of
+ {
+ template<typename Seq, typename State, typename F>
+ struct iter_fold;
+ }
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::iter_fold<
+ Seq
+ , State const
+ , F
+ >::type
+ iter_fold(Seq& seq, State const& state, F f);
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::iter_fold<
+ Seq const
+ , State const
+ , F
+ >::type
+ iter_fold(Seq const& seq, State const& state, F f);
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::iter_fold<
+ Seq
+ , State const
+ , F
+ >::type
+ iter_fold(Seq& seq, State& state, F f);
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::iter_fold<
+ Seq const
+ , State const
+ , F
+ >::type
+ iter_fold(Seq const& seq, State& state, F f);
+}}
+
+#endif

Modified: trunk/boost/fusion/algorithm/iteration/reverse_fold.hpp
==============================================================================
--- trunk/boost/fusion/algorithm/iteration/reverse_fold.hpp (original)
+++ trunk/boost/fusion/algorithm/iteration/reverse_fold.hpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -10,6 +10,7 @@
 
 #define BOOST_FUSION_REVERSE_FOLD
 
+#include <boost/fusion/algorithm/iteration/reverse_fold_fwd.hpp>
 #include <boost/fusion/algorithm/iteration/detail/fold.hpp>
 
 #undef BOOST_FUSION_REVERSE_FOLD

Added: trunk/boost/fusion/algorithm/iteration/reverse_fold_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/fusion/algorithm/iteration/reverse_fold_fwd.hpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -0,0 +1,52 @@
+/*=============================================================================
+ Copyright (c) 2011 Eric Niebler
+
+ 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_FUSION_ALGORITHM_ITERATION_REVERSE_FOLD_FWD_HPP
+#define BOOST_FUSION_ALGORITHM_ITERATION_REVERSE_FOLD_FWD_HPP
+
+namespace boost { namespace fusion
+{
+ namespace result_of
+ {
+ template<typename Seq, typename State, typename F>
+ struct reverse_fold;
+ }
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::reverse_fold<
+ Seq
+ , State const
+ , F
+ >::type
+ reverse_fold(Seq& seq, State const& state, F f);
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::reverse_fold<
+ Seq const
+ , State const
+ , F
+ >::type
+ reverse_fold(Seq const& seq, State const& state, F f);
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::reverse_fold<
+ Seq
+ , State const
+ , F
+ >::type
+ reverse_fold(Seq& seq, State& state, F f);
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::reverse_fold<
+ Seq const
+ , State const
+ , F
+ >::type
+ reverse_fold(Seq const& seq, State& state, F f);
+}}
+
+#endif

Modified: trunk/boost/fusion/algorithm/iteration/reverse_iter_fold.hpp
==============================================================================
--- trunk/boost/fusion/algorithm/iteration/reverse_iter_fold.hpp (original)
+++ trunk/boost/fusion/algorithm/iteration/reverse_iter_fold.hpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -11,6 +11,7 @@
 #define BOOST_FUSION_REVERSE_FOLD
 #define BOOST_FUSION_ITER_FOLD
 
+#include <boost/fusion/algorithm/iteration/reverse_iter_fold_fwd.hpp>
 #include <boost/fusion/algorithm/iteration/detail/fold.hpp>
 
 #undef BOOST_FUSION_REVERSE_FOLD

Added: trunk/boost/fusion/algorithm/iteration/reverse_iter_fold_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/fusion/algorithm/iteration/reverse_iter_fold_fwd.hpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -0,0 +1,52 @@
+/*=============================================================================
+ Copyright (c) 2011 Eric Niebler
+
+ 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_FUSION_ALGORITHM_ITERATION_REVERSE_ITER_FOLD_FWD_HPP
+#define BOOST_FUSION_ALGORITHM_ITERATION_REVERSE_ITER_FOLD_FWD_HPP
+
+namespace boost { namespace fusion
+{
+ namespace result_of
+ {
+ template<typename Seq, typename State, typename F>
+ struct reverse_iter_fold;
+ }
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::reverse_iter_fold<
+ Seq
+ , State const
+ , F
+ >::type
+ reverse_iter_fold(Seq& seq, State const& state, F f);
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::reverse_iter_fold<
+ Seq const
+ , State const
+ , F
+ >::type
+ reverse_iter_fold(Seq const& seq, State const& state, F f);
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::reverse_iter_fold<
+ Seq
+ , State const
+ , F
+ >::type
+ reverse_iter_fold(Seq& seq, State& state, F f);
+
+ template<typename Seq, typename State, typename F>
+ typename result_of::reverse_iter_fold<
+ Seq const
+ , State const
+ , F
+ >::type
+ reverse_iter_fold(Seq const& seq, State& state, F f);
+}}
+
+#endif

Modified: trunk/libs/fusion/test/algorithm/segmented_fold.cpp
==============================================================================
--- trunk/libs/fusion/test/algorithm/segmented_fold.cpp (original)
+++ trunk/libs/fusion/test/algorithm/segmented_fold.cpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -9,7 +9,7 @@
 #include <iostream>
 #include <boost/detail/lightweight_test.hpp>
 #include <boost/fusion/container/vector/vector.hpp>
-#include <boost/fusion/algorithm/iteration/ext_/fold_s.hpp>
+#include <boost/fusion/algorithm/iteration/fold.hpp>
 #include <boost/fusion/container/generation/make_vector.hpp>
 #include "../sequence/tree.hpp"
 
@@ -31,7 +31,7 @@
     using namespace boost;
 
     std::stringstream str;
- fusion::fold_s(tree, &str, write_string());
+ fusion::fold(tree, &str, write_string());
     std::string res = str.str();
 
     BOOST_TEST_EQ(res, "a b c 1 2 3 100 e f 0 B 1 h i 4 5 6 j k l ");

Modified: trunk/libs/fusion/test/sequence/segmented_iterator_range.cpp
==============================================================================
--- trunk/libs/fusion/test/sequence/segmented_iterator_range.cpp (original)
+++ trunk/libs/fusion/test/sequence/segmented_iterator_range.cpp 2011-08-18 19:14:48 EDT (Thu, 18 Aug 2011)
@@ -7,7 +7,7 @@
 ==============================================================================*/
 #include <sstream>
 #include <boost/detail/lightweight_test.hpp>
-#include <boost/fusion/algorithm/iteration/ext_/for_each_s.hpp>
+#include <boost/fusion/algorithm/iteration/for_each.hpp>
 #include <boost/fusion/algorithm/query/find_if.hpp>
 #include <boost/fusion/container/vector/vector.hpp>
 #include <boost/fusion/container/generation/make_vector.hpp>
@@ -59,7 +59,7 @@
     slice_t slice(si, fi);
 
     std::stringstream sout;
- fusion::for_each_s(slice, ostream_fun(sout));
+ fusion::for_each(slice, ostream_fun(sout));
     BOOST_TEST((sout.str() == "100 e f 0 B "));
 }
 


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