Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r59640 - in sandbox/statistics/detail/assign: boost/assign boost/assign/detail libs/assign/example libs/assign/src libs/assign/test
From: erwann.rogard_at_[hidden]
Date: 2010-02-11 14:58:19


Author: e_r
Date: 2010-02-11 14:58:18 EST (Thu, 11 Feb 2010)
New Revision: 59640
URL: http://svn.boost.org/trac/boost/changeset/59640

Log:
m
Text files modified:
   sandbox/statistics/detail/assign/boost/assign/cref_list_of2.hpp | 27 +++++++--------
   sandbox/statistics/detail/assign/boost/assign/detail/assign_value.hpp | 14 ++++----
   sandbox/statistics/detail/assign/boost/assign/detail/ref_list_of_auto_size_copy_rebind.hpp | 24 ++++++++-----
   sandbox/statistics/detail/assign/boost/assign/ref_list_of_rebind.hpp | 28 ++++++++++-----
   sandbox/statistics/detail/assign/libs/assign/example/cref_list_of2.cpp | 67 ++++++++++++++++++++-------------------
   sandbox/statistics/detail/assign/libs/assign/example/cref_list_of2.h | 1
   sandbox/statistics/detail/assign/libs/assign/src/main.cpp | 2
   sandbox/statistics/detail/assign/libs/assign/test/cref_list_of2_speed.cpp | 40 +++++++++++-----------
   8 files changed, 109 insertions(+), 94 deletions(-)

Modified: sandbox/statistics/detail/assign/boost/assign/cref_list_of2.hpp
==============================================================================
--- sandbox/statistics/detail/assign/boost/assign/cref_list_of2.hpp (original)
+++ sandbox/statistics/detail/assign/boost/assign/cref_list_of2.hpp 2010-02-11 14:58:18 EST (Thu, 11 Feb 2010)
@@ -1,40 +1,39 @@
 //////////////////////////////////////////////////////////////////////////////
-// assign::ref_list_of_copy.hpp //
+// assign::ref_copy_list_of_copy.hpp //
 // //
 // (C) Copyright 2010 Erwann Rogard //
 // Use, modification and distribution are subject to 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_ASSIGN_REF_LIST_OF_COPY_ER_2010_HPP
-#define BOOST_ASSIGN_REF_LIST_OF_COPY_ER_2010_HPP
+#ifndef BOOST_ASSIGN_REF_COPY_LIST_OF_COPY_ER_2010_HPP
+#define BOOST_ASSIGN_REF_COPY_LIST_OF_COPY_ER_2010_HPP
 #include <boost/assign/detail/ref_list_of_auto_size_copy_rebind.hpp>
 
-// This is a variation on Boost.Assign's ref_list_of<> that deduces the number
-// of items and has copy semantics.
 // Usage 1:
-// std::vector<T> vec = cref_list_of(a)(b)(c);
+// std::vector<T> vec = cref_copy_list_of(a)(b)(c);
 // Usage 2:
-// boost::array<T,3> vec = cref_list_of(a)(b)(c);
+// boost::array<T,3> vec = cref_copy_list_of(a)(b)(c);
 // Usage 3:
 // boost::fill( ref_list_of(a)(b)(c), 0);
 //
-// See detail/ref_list_of_auto_size_copy_rebind.hpp for detail
+// The name copy is to emphasize that copy semantics are used, in constrast to
+// ref_list_of() which uses rebind semantics.
 
 namespace boost{
 namespace assign{
 
     template<typename T>
- typename cref_list_of_impl::copy_first<const T>::type
- cref_list_of(const T& t){
- typedef typename cref_list_of_impl::copy_first<const T>::type expr_;
+ typename detail::auto_size::copy_first<const T>::type
+ cref_copy_list_of(const T& t){
+ typedef typename detail::auto_size::copy_first<const T>::type expr_;
         return expr_(t);
     }
 
     template<typename T>
- typename cref_list_of_impl::copy_first<T>::type
- ref_list_of(T& t){
- typedef typename cref_list_of_impl::copy_first<T>::type expr_;
+ typename detail::auto_size::copy_first<T>::type
+ ref_copy_list_of(T& t){
+ typedef typename detail::auto_size::copy_first<T>::type expr_;
         return expr_(t);
     }
 

Modified: sandbox/statistics/detail/assign/boost/assign/detail/assign_value.hpp
==============================================================================
--- sandbox/statistics/detail/assign/boost/assign/detail/assign_value.hpp (original)
+++ sandbox/statistics/detail/assign/boost/assign/detail/assign_value.hpp 2010-02-11 14:58:18 EST (Thu, 11 Feb 2010)
@@ -1,13 +1,13 @@
 //////////////////////////////////////////////////////////////////////////////
-// assign::detail::assign_value.hpp //
+// assign::detail::assign_reference_copy.hpp //
 // //
 // (C) Copyright 2010 M.P.G //
 // Use, modification and distribution are subject to 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_ASSIGN_DETAIL_ASSIGN_VALUE_MPG_2010_HPP
-#define BOOST_ASSIGN_DETAIL_ASSIGN_VALUE_MPG_2010_HPP
+#ifndef BOOST_ASSIGN_DETAIL_ASSIGN_REFERENCE_COPY_MPG_2010_HPP
+#define BOOST_ASSIGN_DETAIL_ASSIGN_REFERENCE_COPY_MPG_2010_HPP
 
 namespace boost{
 namespace assign_detail{
@@ -18,12 +18,12 @@
     // This is in contrast to assign_reference whose operator= rebinds the
     // address of the internal pointer. To that effect,here, call rebind()
         template< class T >
- struct assign_value
+ struct assign_reference_copy
     {
- assign_value()
+ assign_reference_copy()
         { /* intentionally empty */ }
 
- assign_value( T& r ) : ref_(&r)
+ assign_reference_copy( T& r ) : ref_(&r)
         { }
 
         void operator=( const T& r )
@@ -36,7 +36,7 @@
             return *ref_;
         }
 
- void swap( assign_value& r )
+ void swap( assign_reference_copy& r )
         {
             std::swap( *ref_, *r.ref_ );
         }

Modified: sandbox/statistics/detail/assign/boost/assign/detail/ref_list_of_auto_size_copy_rebind.hpp
==============================================================================
--- sandbox/statistics/detail/assign/boost/assign/detail/ref_list_of_auto_size_copy_rebind.hpp (original)
+++ sandbox/statistics/detail/assign/boost/assign/detail/ref_list_of_auto_size_copy_rebind.hpp 2010-02-11 14:58:18 EST (Thu, 11 Feb 2010)
@@ -19,8 +19,12 @@
 #include <boost/assign/list_of.hpp> // needed for assign_referene
 #include <boost/assign/detail/assign_value.hpp>
 
-// This is the implementation behind ref_list_of() and ref_list_rebind() which,
-// unlike ref_list_of<int>(), deduces the size of the number of items.
+// This is the implementation behind ref_list_of() and ref_copy_list_of().
+//
+// The motivation for this class was to improve upon ref_list_of<int>(), by
+// deducing the number of arguments at compile time, and allowing for either
+// of copy or rebind semantics, in case it is used as the lhs of an assignment;
+// the former (copy) being both safer and more common than the latter (rebind).
 //
 // Acknowledgement: The idea of this class was developed in collaboration
 // with M.P.G
@@ -36,7 +40,8 @@
 
 namespace boost{
 namespace assign{
-namespace cref_list_of_impl{
+namespace detail{
+namespace auto_size{
             
         typedef boost::mpl::void_ top_;
 
@@ -49,7 +54,7 @@
         // Copy semantics
     template<typename T>
     struct ref_value{
- typedef boost::assign_detail::assign_value<T> type;
+ typedef boost::assign_detail::assign_reference_copy<T> type;
     };
             
     template<typename T,int N,template<typename> class Ref>
@@ -183,17 +188,18 @@
             
     template<typename T>
     struct copy_first{
- typedef cref_list_of_impl::expr<
- cref_list_of_impl::top_,T,1,ref_value> type;
+ typedef detail::auto_size::expr<
+ detail::auto_size::top_,T,1,ref_value> type;
     };
 
     template<typename T>
     struct rebind_first{
- typedef cref_list_of_impl::expr<
- cref_list_of_impl::top_,T,1,ref_bind> type;
+ typedef detail::auto_size::expr<
+ detail::auto_size::top_,T,1,ref_bind> type;
     };
             
-}// cref_list_of_impl
+}// auto_size
+}// detail
 }// assign
 }// boost
 

Modified: sandbox/statistics/detail/assign/boost/assign/ref_list_of_rebind.hpp
==============================================================================
--- sandbox/statistics/detail/assign/boost/assign/ref_list_of_rebind.hpp (original)
+++ sandbox/statistics/detail/assign/boost/assign/ref_list_of_rebind.hpp 2010-02-11 14:58:18 EST (Thu, 11 Feb 2010)
@@ -10,26 +10,34 @@
 #define BOOST_ASSIGN_REF_LIST_OF_REBIND_ER_2010_HPP
 #include <boost/assign/detail/ref_list_of_auto_size_copy_rebind.hpp>
 
-// Same as ref_list_of() but has rebind rather than copy semantics
-// Usage:
-// BOOST_AUTO(tmp,ref_rebind_list_of(a)(b)(c)); boost::fill(tmp,d);
+
+// Usage 1:
+// std::vector<T> vec = cref_list_of(a)(b)(c);
+// Usage 2:
+// boost::array<T,3> vec = cref_list_of(a)(b)(c);
+// Usage 2:
+// BOOST_AUTO(tmp,ref_list_of(a)(b)(c)); boost::fill(tmp,d);
+//
+// Note that this function supersedes and has the same side effect as
+// ref_list_of<int>(), which still exists only for backward-compatibility.
 //
-// See detail/ref_list_of_auto_size_copy_rebind.hpp for detail
+// Unlike ref_copy_list_of, it has rebind semantics so that Usage 3 binds d to
+// a, b, c. If in doubt, ref_copy_list_of is the safer option.
 
 namespace boost{
 namespace assign{
 
     template<typename T>
- typename cref_list_of_impl::rebind_first<const T>::type
- cref_rebind_list_of(const T& t){
- typedef typename cref_list_of_impl::rebind_first<const T>::type expr_;
+ typename detail::auto_size::rebind_first<const T>::type
+ cref_list_of(const T& t){
+ typedef typename detail::auto_size::rebind_first<const T>::type expr_;
         return expr_(t);
     }
 
     template<typename T>
- typename cref_list_of_impl::rebind_first<T>::type
- ref_rebind_list_of(T& t){
- typedef typename cref_list_of_impl::rebind_first<T>::type expr_;
+ typename detail::auto_size::rebind_first<T>::type
+ ref_list_of(T& t){
+ typedef typename detail::auto_size::rebind_first<T>::type expr_;
         return expr_(t);
     }
 

Modified: sandbox/statistics/detail/assign/libs/assign/example/cref_list_of2.cpp
==============================================================================
--- sandbox/statistics/detail/assign/libs/assign/example/cref_list_of2.cpp (original)
+++ sandbox/statistics/detail/assign/libs/assign/example/cref_list_of2.cpp 2010-02-11 14:58:18 EST (Thu, 11 Feb 2010)
@@ -15,6 +15,22 @@
 #include <boost/assign/list_of.hpp>
 #include <libs/assign/example/cref_list_of2.h>
 
+struct Foo
+{
+ int i;
+ bool destroyed;
+ Foo(){}
+ Foo(int i) : i(i) { destroyed = false; }
+ ~Foo() { destroyed = true;}
+};
+std::ostream & operator<<(std::ostream & os, Foo const & i)
+{
+ if(i.destroyed)
+ return os << "You have a bug\n";
+ return os << i.i;
+}
+
+
 void example_cref_list_of(std::ostream& os)
 {
         os << "-> example_cref_listof2 : ";
@@ -29,24 +45,26 @@
             int a=1,b=2,c=3;
             ints_ ints;
     
+ // cref_list_of<int>
             ints = cref_list_of<3>(a)(b)(3);
                 BOOST_ASSERT(ints[0] == a);
                 BOOST_ASSERT(ints[1] == b);
                 BOOST_ASSERT(ints[2] == 3);
+
         array = array0;
                 array = cref_list_of<3>(a)(b)(3);
                 BOOST_ASSERT(array[0] == a);
                 BOOST_ASSERT(array[1] == b);
                 BOOST_ASSERT(array[2] == c);
         
- // cref_list_of
+ // cref_copy_list_of
             ints.clear();
- ints = cref_list_of(a)(b)(3);
+ ints = cref_copy_list_of(a)(b)(3);
                 BOOST_ASSERT(ints[0] == a);
                 BOOST_ASSERT(ints[1] == b);
                 BOOST_ASSERT(ints[2] == c);
         array = array0;
- array = cref_list_of(a)(b)(3);
+ array = cref_copy_list_of(a)(b)(3);
                 BOOST_ASSERT(array[0] == a);
                 BOOST_ASSERT(array[1] == b);
                 BOOST_ASSERT(array[2] == c);
@@ -54,7 +72,7 @@
                     ints.clear();
                 BOOST_AUTO(
                         tmp,
- cref_list_of(a)(b)(3)
+ cref_copy_list_of(a)(b)(3)
                 );
                 ints = ints_(boost::begin(tmp),boost::end(tmp));
                         BOOST_ASSERT(ints[0] == a);
@@ -62,39 +80,13 @@
                         BOOST_ASSERT(ints[2] == c);
                 }
 
- // ref_list_of
- ints.clear();
- ints = ref_list_of(a)(b)(c);
- BOOST_ASSERT(ints[0] == a);
- BOOST_ASSERT(ints[1] == b);
- BOOST_ASSERT(ints[2] == c);
- array = array0;
- array = cref_list_of(a)(b)(c);
- BOOST_ASSERT(array[0] == a);
- BOOST_ASSERT(array[1] == b);
- BOOST_ASSERT(array[2] == c);
- {
- ints.clear();
- BOOST_AUTO(
- tmp,
- ref_list_of(a)(b)(c)
- );
- ints = ints_(boost::begin(tmp),boost::end(tmp));
- BOOST_ASSERT(ints[0] == a);
- BOOST_ASSERT(ints[1] == b);
- BOOST_ASSERT(ints[2] == c);
- std::fill(boost::begin(tmp),boost::end(tmp),0);
- BOOST_ASSERT(a == 0);
- BOOST_ASSERT(b == 0);
- BOOST_ASSERT(c == 0);
- }
- // ref_list_of_rebind
+ // ref_list_of
                 {
             int a=1, b=2, c=3;
                     ints.clear();
                 BOOST_AUTO(
                 tmp,
- cref_rebind_list_of(a)(b)(c)
+ cref_list_of(a)(b)(c)
             );
             {
                         ints = tmp;
@@ -108,9 +100,17 @@
                                 BOOST_ASSERT(ints[1] == b);
                                 BOOST_ASSERT(ints[2] == c);
             }
-
             int d = 4;
             std::fill(boost::begin(tmp),boost::end(tmp),d);
+ d = 5;
+ // Prints 4, 4, 4 instead of 5, 5, 5. However, works with Foo.
+ // rvalue/lvalue?
+ std::copy(
+ boost::begin(tmp),
+ boost::end(tmp),
+ std::ostream_iterator<int>(os, "\n")
+ );
+/*
             {
                         ints = ints_(boost::begin(tmp),boost::end(tmp));
                                 BOOST_ASSERT(ints[0] == d);
@@ -124,6 +124,7 @@
                                 BOOST_ASSERT(ints[1] == d);
                                 BOOST_ASSERT(ints[2] == d);
             }
+*/
         }
         
     }

Modified: sandbox/statistics/detail/assign/libs/assign/example/cref_list_of2.h
==============================================================================
--- sandbox/statistics/detail/assign/libs/assign/example/cref_list_of2.h (original)
+++ sandbox/statistics/detail/assign/libs/assign/example/cref_list_of2.h 2010-02-11 14:58:18 EST (Thu, 11 Feb 2010)
@@ -10,6 +10,7 @@
 #define LIBS_ASSIGN_EXAMPLE_CREF_LIST_OF2_ER_2010_HPP
 #include <ostream>
 
+
 void example_cref_list_of(std::ostream&);
 
 #endif
\ No newline at end of file

Modified: sandbox/statistics/detail/assign/libs/assign/src/main.cpp
==============================================================================
--- sandbox/statistics/detail/assign/libs/assign/src/main.cpp (original)
+++ sandbox/statistics/detail/assign/libs/assign/src/main.cpp 2010-02-11 14:58:18 EST (Thu, 11 Feb 2010)
@@ -5,7 +5,7 @@
 int main (int argc, char * const argv[]) {
 
         example_cref_list_of(std::cout);
- test_cref_list_of_speed(std::cout);
+ //test_cref_list_of_speed(std::cout);
     
     return 0;
 }

Modified: sandbox/statistics/detail/assign/libs/assign/test/cref_list_of2_speed.cpp
==============================================================================
--- sandbox/statistics/detail/assign/libs/assign/test/cref_list_of2_speed.cpp (original)
+++ sandbox/statistics/detail/assign/libs/assign/test/cref_list_of2_speed.cpp 2010-02-11 14:58:18 EST (Thu, 11 Feb 2010)
@@ -1,5 +1,5 @@
 //////////////////////////////////////////////////////////////////////////////
-// test::cref_list_of_speed.cpp //
+// test::cref_copy_list_of_speed.cpp //
 // //
 //////////////////////////////////////////////////////////////////////////////
 #include <iostream>
@@ -35,7 +35,7 @@
     return result;
 }
 
-void test_cref_list_of_speed(std::ostream& os)
+void test_cref_copy_list_of_speed(std::ostream& os)
 {
         os << "-> test_cref_listof2_speed : " << std::endl;
 
@@ -58,12 +58,12 @@
             timer_ timer;
             for(int i = 0; i < n; ++i)
             {
- BOOST_AUTO(rng, boost::assign::cref_list_of(v[0]));
+ BOOST_AUTO(rng, boost::assign::cref_copy_list_of(v[0]));
                 int sz = (int)rng.size();
                 if(sz != N)
                     os << "ERROR\n";
             }
- os << "cref_list_of(" << N << ") => ";
+ os << "cref_copy_list_of(" << N << ") => ";
         }
         {
                          timer_ timer;
@@ -74,7 +74,7 @@
                 if(sz != N)
                     os << "ERROR\n";
             }
- os << "cref_list_of(" << N << ") => ";
+ os << "cref_copy_list_of(" << N << ") => ";
         }
     }
     {
@@ -84,12 +84,12 @@
                          timer_ timer;
             for(int i = 0; i < n; ++i)
             {
- BOOST_AUTO(rng, boost::assign::cref_list_of(v[0])(v[1])(v[2]));
+ BOOST_AUTO(rng, boost::assign::cref_copy_list_of(v[0])(v[1])(v[2]));
                 int sz = (int)rng.size();
                 if(sz != N)
                     os << "ERROR\n";
             }
- os << "cref_list_of(" << N << ") => ";
+ os << "cref_copy_list_of(" << N << ") => ";
         }
         {
                          timer_ timer;
@@ -100,7 +100,7 @@
                 if(sz != N)
                     os << "ERROR\n";
             }
- os << "cref_list_of(" << N << ") => ";
+ os << "cref_copy_list_of(" << N << ") => ";
         }
     }
     
@@ -111,12 +111,12 @@
                          timer_ timer;
             for(int i = 0; i < n; ++i)
             {
- BOOST_AUTO(rng, boost::assign::cref_list_of(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7])(v[8])(v[9]));
+ BOOST_AUTO(rng, boost::assign::cref_copy_list_of(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7])(v[8])(v[9]));
                 int sz = (int)rng.size();
                 if(sz != N)
                     os << "ERROR\n";
             }
- os << "cref_list_of(" << N << ") => ";
+ os << "cref_copy_list_of(" << N << ") => ";
         }
         {
                          timer_ timer;
@@ -127,7 +127,7 @@
                 if(sz != N)
                     os << "ERROR\n";
             }
- os << "cref_list_of(" << N << ") => ";
+ os << "cref_copy_list_of(" << N << ") => ";
         }
     }
     
@@ -138,14 +138,14 @@
                          timer_ timer;
             for(int i = 0; i < n; ++i)
             {
- BOOST_AUTO(rng, boost::assign::cref_list_of(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7])(v[8])(v[9])
+ BOOST_AUTO(rng, boost::assign::cref_copy_list_of(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7])(v[8])(v[9])
                            (v[10])(v[11])(v[12])(v[13])(v[14])(v[15])(v[16])(v[17])(v[18])(v[19])
                            (v[20])(v[21])(v[22])(v[23])(v[24])(v[25])(v[26])(v[27])(v[28])(v[29]));
                 int sz = (int)rng.size();
                 if(sz != N)
                     os << "ERROR\n";
             }
- os << "cref_list_of(" << N << ") => ";
+ os << "cref_copy_list_of(" << N << ") => ";
         }
         {
                          timer_ timer;
@@ -158,7 +158,7 @@
                 if(sz != N)
                     os << "ERROR\n";
             }
- os << "cref_list_of(" << N << ") => ";
+ os << "cref_copy_list_of(" << N << ") => ";
         }
     }
     
@@ -169,7 +169,7 @@
             timer_ timer;
             for(int i = 0; i < n; ++i)
             {
- BOOST_AUTO(rng, boost::assign::cref_list_of( v[0])( v[1])( v[2])( v[3])( v[4])( v[5])( v[6])( v[7])( v[8])( v[9])
+ BOOST_AUTO(rng, boost::assign::cref_copy_list_of( v[0])( v[1])( v[2])( v[3])( v[4])( v[5])( v[6])( v[7])( v[8])( v[9])
                            (v[10])(v[11])(v[12])(v[13])(v[14])(v[15])(v[16])(v[17])(v[18])(v[19])
                            (v[20])(v[21])(v[22])(v[23])(v[24])(v[25])(v[26])(v[27])(v[28])(v[29])
                            (v[30])(v[31])(v[32])(v[33])(v[34])(v[35])(v[36])(v[37])(v[38])(v[39])
@@ -181,7 +181,7 @@
                 if(sz != N)
                     os << "ERROR\n";
             }
- os << "cref_list_of(" << N << ") => ";
+ os << "cref_copy_list_of(" << N << ") => ";
         }
         {
                          timer_ timer;
@@ -199,7 +199,7 @@
                 if(sz != N)
                     os << "ERROR\n";
             }
- os << "cref_list_of(" << N << ") => ";
+ os << "cref_copy_list_of(" << N << ") => ";
         }
     }
     
@@ -210,7 +210,7 @@
                          timer_ timer;
             for(int i = 0; i < n; ++i)
             {
- BOOST_AUTO(rng, boost::assign::cref_list_of( v[0])( v[1])( v[2])( v[3])( v[4])( v[5])( v[6])( v[7])( v[8])( v[9])
+ BOOST_AUTO(rng, boost::assign::cref_copy_list_of( v[0])( v[1])( v[2])( v[3])( v[4])( v[5])( v[6])( v[7])( v[8])( v[9])
                            (v[10])(v[11])(v[12])(v[13])(v[14])(v[15])(v[16])(v[17])(v[18])(v[19])
                            (v[20])(v[21])(v[22])(v[23])(v[24])(v[25])(v[26])(v[27])(v[28])(v[29])
                            (v[30])(v[31])(v[32])(v[33])(v[34])(v[35])(v[36])(v[37])(v[38])(v[39])
@@ -230,7 +230,7 @@
                 if(sz != N)
                     os << "ERROR\n";
             }
- os << "cref_list_of(" << N << ") => ";
+ os << "cref_copy_list_of(" << N << ") => ";
         }
         {
                          timer_ timer;
@@ -256,7 +256,7 @@
                 if(sz != N)
                     os << "ERROR\n";
             }
- os << "cref_list_of(" << N << ") => ";
+ os << "cref_copy_list_of(" << N << ") => ";
         }
     }
         os << "<- " << std::endl;


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