Boost logo

Boost-Commit :

From: joaquin_at_[hidden]
Date: 2008-09-01 11:55:28


Author: joaquin
Date: 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
New Revision: 48515
URL: http://svn.boost.org/trac/boost/changeset/48515

Log:
post-review version
Added:
   sandbox/flyweight/boost/flyweight/detail/default_value_policy.hpp (contents, props changed)
   sandbox/flyweight/boost/flyweight/detail/dyn_perfect_fwd.hpp (contents, props changed)
   sandbox/flyweight/boost/flyweight/detail/has_static_entry.hpp (contents, props changed)
   sandbox/flyweight/boost/flyweight/detail/perfect_fwd.hpp (contents, props changed)
   sandbox/flyweight/boost/flyweight/detail/pp_perfect_fwd.hpp (contents, props changed)
   sandbox/flyweight/boost/flyweight/detail/value_tag.hpp (contents, props changed)
   sandbox/flyweight/boost/flyweight/key_value.hpp (contents, props changed)
   sandbox/flyweight/boost/flyweight/key_value_fwd.hpp (contents, props changed)
   sandbox/flyweight/libs/flyweight/doc/memory.png (contents, props changed)
   sandbox/flyweight/libs/flyweight/doc/memory_gcc_344.png (contents, props changed)
   sandbox/flyweight/libs/flyweight/doc/memory_msvc_80.png (contents, props changed)
   sandbox/flyweight/libs/flyweight/doc/performance.html (contents, props changed)
   sandbox/flyweight/libs/flyweight/doc/reference/key_value.html (contents, props changed)
   sandbox/flyweight/libs/flyweight/doc/release_notes.html (contents, props changed)
   sandbox/flyweight/libs/flyweight/doc/time_gcc_344.png (contents, props changed)
   sandbox/flyweight/libs/flyweight/doc/time_msvc_80.png (contents, props changed)
   sandbox/flyweight/libs/flyweight/doc/tutorial/key_value.html (contents, props changed)
   sandbox/flyweight/libs/flyweight/example/fibonacci.cpp (contents, props changed)
   sandbox/flyweight/libs/flyweight/example/key_value.cpp (contents, props changed)
   sandbox/flyweight/libs/flyweight/test/heavy_objects.hpp (contents, props changed)

Added: sandbox/flyweight/boost/flyweight/detail/default_value_policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/flyweight/boost/flyweight/detail/default_value_policy.hpp 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,58 @@
+/* Copyright 2006-2008 Joaquin M Lopez Munoz.
+ * 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)
+ *
+ * See http://www.boost.org/libs/flyweight for library home page.
+ */
+
+#ifndef BOOST_FLYWEIGHT_DETAIL_DEFAULT_VALUE_POLICY_HPP
+#define BOOST_FLYWEIGHT_DETAIL_DEFAULT_VALUE_POLICY_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/flyweight/detail/value_tag.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+
+/* Default value policy: the key is the same as the value.
+ */
+
+namespace boost{
+
+namespace flyweights{
+
+namespace detail{
+
+template<typename Value>
+struct default_value_policy:value_marker
+{
+ typedef Value key_type;
+ typedef Value value_type;
+
+ struct rep_type
+ {
+ /* template ctors */
+
+#define BOOST_FLYWEIGHT_PERFECT_FWD_NAME explicit rep_type
+#define BOOST_FLYWEIGHT_PERFECT_FWD_BODY(n) \
+ :x(BOOST_PP_ENUM_PARAMS(n,t)){}
+#include <boost/flyweight/detail/perfect_fwd.hpp>
+
+ operator const value_type&()const{return x;}
+
+ value_type x;
+ };
+
+ static void construct_value(const rep_type&){}
+ static void copy_value(const rep_type&){}
+};
+
+} /* namespace flyweights::detail */
+
+} /* namespace flyweights */
+
+} /* namespace boost */
+
+#endif

Added: sandbox/flyweight/boost/flyweight/detail/dyn_perfect_fwd.hpp
==============================================================================
--- (empty file)
+++ sandbox/flyweight/boost/flyweight/detail/dyn_perfect_fwd.hpp 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,75 @@
+/* Copyright 2006-2008 Joaquin M Lopez Munoz.
+ * 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)
+ *
+ * See http://www.boost.org/libs/flyweight for library home page.
+ */
+
+/* no include guards */
+
+#include <boost/preprocessor/arithmetic/add.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/preprocessor/seq/elem.hpp>
+#include <boost/preprocessor/seq/for_each_product.hpp>
+#include <boost/preprocessor/seq/size.hpp>
+
+#define BOOST_FLYWEIGHT_CONST(b) BOOST_PP_CAT(BOOST_FLYWEIGHT_CONST,b)
+#define BOOST_FLYWEIGHT_CONST0
+#define BOOST_FLYWEIGHT_CONST1 const
+
+/* if mask[n]==0 --> Tn& tn
+ * if mask[n]==1 --> const Tn& tn
+ */
+
+#define BOOST_FLYWEIGHT_PERFECT_FWD_ARG(z,n,mask) \
+BOOST_FLYWEIGHT_CONST(BOOST_PP_SEQ_ELEM(n,mask)) \
+BOOST_PP_CAT(T,n)& BOOST_PP_CAT(t,n)
+
+/* overload accepting size(mask) args, where the template args are
+ * marked const or not according to the given mask (a seq of 0 or 1)
+ */
+
+#define BOOST_FLYWEIGHT_PERFECT_FWD(r,mask) \
+template<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(mask),typename T)> \
+BOOST_FLYWEIGHT_PERFECT_FWD_NAME( \
+ BOOST_PP_ENUM( \
+ BOOST_PP_SEQ_SIZE(mask),BOOST_FLYWEIGHT_PERFECT_FWD_ARG,mask)) \
+BOOST_FLYWEIGHT_PERFECT_FWD_BODY(BOOST_PP_SEQ_SIZE(mask))
+
+#define BOOST_FLYWEIGHT_01(z,n,_) ((0)(1))
+
+/* Perfect forwarding overloads accepting 1 to n args */
+
+#define BOOST_FLYWEIGHT_PERFECT_FWDS_N(z,n,_) \
+BOOST_PP_SEQ_FOR_EACH_PRODUCT( \
+ BOOST_FLYWEIGHT_PERFECT_FWD, \
+ BOOST_PP_REPEAT(n,BOOST_FLYWEIGHT_01,~))
+
+#define BOOST_FLYWEIGHT_PERFECT_FWD_OVERLOADS \
+BOOST_PP_REPEAT_FROM_TO( \
+ 1,BOOST_PP_ADD(BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS,1), \
+ BOOST_FLYWEIGHT_PERFECT_FWDS_N,~)
+
+/* generate the overloads */
+
+BOOST_FLYWEIGHT_PERFECT_FWD_OVERLOADS
+
+/* clean up */
+
+#undef BOOST_FLYWEIGHT_PERFECT_FWD_OVERLOADS
+#undef BOOST_FLYWEIGHT_01
+#undef BOOST_FLYWEIGHT_PERFECT_FWD
+#undef BOOST_FLYWEIGHT_PERFECT_FWD_ARG
+#undef BOOST_FLYWEIGHT_CONST1
+#undef BOOST_FLYWEIGHT_CONST0
+#undef BOOST_FLYWEIGHT_CONST
+
+/* user supplied argument macros */
+
+#undef BOOST_FLYWEIGHT_PERFECT_FWD_BODY
+#undef BOOST_FLYWEIGHT_PERFECT_FWD_NAME

Added: sandbox/flyweight/boost/flyweight/detail/has_static_entry.hpp
==============================================================================
--- (empty file)
+++ sandbox/flyweight/boost/flyweight/detail/has_static_entry.hpp 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,67 @@
+/* Copyright 2006-2008 Joaquin M Lopez Munoz.
+ * 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)
+ *
+ * See http://www.boost.org/libs/flyweight for library home page.
+ */
+
+#ifndef BOOST_FLYWEIGHT_DETAIL_HAS_STATIC_ENTRY_HPP
+#define BOOST_FLYWEIGHT_DETAIL_HAS_STATIC_ENTRY_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/mpl/bool.hpp>
+
+namespace boost{
+
+namespace flyweights{
+
+namespace detail{
+
+/* has_static_entry<Factory> tries to determine whether Factory::entry(h),
+ * with h a Factory::handle_type, is a valid expression.
+ * Cases where entry is not defined, not a memfun, is overloaded or is a
+ * member function template are tolerated, i.e. they do not trigger a
+ * compilation error.
+ * False negatives may occur, false positives will not.
+ */
+
+struct has_static_entry_helper
+{
+ typedef char& yes;
+ typedef char (&no)[2];
+
+ template <typename Entry,typename Handle,const Entry& (*)(const Handle&)>
+ struct pf1;
+ template <typename Entry,typename Handle,const Entry& (*)(Handle)>
+ struct pf2;
+
+ template<typename Factory,typename Entry,typename Handle>
+ static yes check(int,pf1<Entry,Handle,&Factory::entry>* =0);
+ template<typename Factory,typename Entry,typename Handle>
+ static yes check(char,pf2<Entry,Handle,&Factory::entry>* =0);
+ template<typename Factory,typename Entry,typename Handle>
+ static no check(...);
+};
+
+template<typename Factory,typename Entry>
+struct has_static_entry:
+ boost::mpl::bool_<
+ sizeof(
+ has_static_entry_helper::check<
+ Factory,Entry,typename Factory::handle_type
+ >(0))==
+ sizeof(has_static_entry_helper::yes)
+ >
+{};
+
+} /* namespace flyweights::detail */
+
+} /* namespace flyweights */
+
+} /* namespace boost */
+
+#endif

Added: sandbox/flyweight/boost/flyweight/detail/perfect_fwd.hpp
==============================================================================
--- (empty file)
+++ sandbox/flyweight/boost/flyweight/detail/perfect_fwd.hpp 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,28 @@
+/* Copyright 2006-2008 Joaquin M Lopez Munoz.
+ * 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)
+ *
+ * See http://www.boost.org/libs/flyweight for library home page.
+ */
+
+/* Brute force implementation of perfect forwarding overloads.
+ * Usage: include after having defined the argument macros:
+ * BOOST_FLYWEIGHT_PERFECT_FWD_NAME
+ * BOOST_FLYWEIGHT_PERFECT_FWD_BODY
+ */
+
+/* This user_definable macro limits the maximum number of arguments to
+ * be perfect forwarded. Beware combinatorial explosion: manual perfect
+ * forwarding for n arguments produces 2^n distinct overloads.
+ */
+
+#if !defined(BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS)
+#define BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS 5
+#endif
+
+#if BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS<=5
+#include <boost/flyweight/detail/pp_perfect_fwd.hpp>
+#else
+#include <boost/flyweight/detail/dyn_perfect_fwd.hpp>
+#endif

Added: sandbox/flyweight/boost/flyweight/detail/pp_perfect_fwd.hpp
==============================================================================
--- (empty file)
+++ sandbox/flyweight/boost/flyweight/detail/pp_perfect_fwd.hpp 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,153 @@
+/* Copyright 2006-2008 Joaquin M Lopez Munoz.
+ * 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)
+ *
+ * See http://www.boost.org/libs/flyweight for library home page.
+ */
+
+/* no include guards */
+
+#if BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS>=1
+#define BOOST_FLYWEIGHT_PERFECT_FWDS_1 \
+template<typename T0> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(1)\
+template<typename T0> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(1)
+#endif
+
+#if BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS>=2
+#define BOOST_FLYWEIGHT_PERFECT_FWDS_2 \
+template<typename T0,typename T1> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(2)\
+template<typename T0,typename T1> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(2)\
+template<typename T0,typename T1> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(2)\
+template<typename T0,typename T1> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(2)
+#endif
+
+#if BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS>=3
+#define BOOST_FLYWEIGHT_PERFECT_FWDS_3 \
+template<typename T0,typename T1,typename T2> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,T2& t2)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(3)\
+template<typename T0,typename T1,typename T2> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,const T2& t2)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(3)\
+template<typename T0,typename T1,typename T2> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,T2& t2)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(3)\
+template<typename T0,typename T1,typename T2> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,const T2& t2)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(3)\
+template<typename T0,typename T1,typename T2> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,T2& t2)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(3)\
+template<typename T0,typename T1,typename T2> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,const T2& t2)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(3)\
+template<typename T0,typename T1,typename T2> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,T2& t2)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(3)\
+template<typename T0,typename T1,typename T2> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,const T2& t2)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(3)
+#endif
+
+#if BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS>=4
+#define BOOST_FLYWEIGHT_PERFECT_FWDS_4 \
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,T2& t2,T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,T2& t2,const T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,const T2& t2,T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,const T2& t2,const T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,T2& t2,T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,T2& t2,const T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,const T2& t2,T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,const T2& t2,const T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,T2& t2,T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,T2& t2,const T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,const T2& t2,T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,const T2& t2,const T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,T2& t2,T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,T2& t2,const T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,const T2& t2,T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)\
+template<typename T0,typename T1,typename T2,typename T3> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,const T2& t2,const T3& t3)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(4)
+#endif
+
+#if BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS>=5
+#define BOOST_FLYWEIGHT_PERFECT_FWDS_5 \
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,T2& t2,T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,T2& t2,T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,T2& t2,const T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,T2& t2,const T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,const T2& t2,T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,const T2& t2,T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,const T2& t2,const T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,T1& t1,const T2& t2,const T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,T2& t2,T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,T2& t2,T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,T2& t2,const T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,T2& t2,const T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,const T2& t2,T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,const T2& t2,T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,const T2& t2,const T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(T0& t0,const T1& t1,const T2& t2,const T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,T2& t2,T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,T2& t2,T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,T2& t2,const T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,T2& t2,const T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,const T2& t2,T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,const T2& t2,T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,const T2& t2,const T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,T1& t1,const T2& t2,const T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,T2& t2,T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,T2& t2,T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,T2& t2,const T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,T2& t2,const T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,const T2& t2,T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,const T2& t2,T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,const T2& t2,const T3& t3,T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)\
+template<typename T0,typename T1,typename T2,typename T3,typename T4> BOOST_FLYWEIGHT_PERFECT_FWD_NAME(const T0& t0,const T1& t1,const T2& t2,const T3& t3,const T4& t4)BOOST_FLYWEIGHT_PERFECT_FWD_BODY(5)
+#endif
+
+#if BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS==0
+#define BOOST_FLYWEIGHT_PERFECT_FWD_OVERLOADS
+#elif BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS==1
+#define BOOST_FLYWEIGHT_PERFECT_FWD_OVERLOADS \
+BOOST_FLYWEIGHT_PERFECT_FWDS_1
+#elif BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS==2
+#define BOOST_FLYWEIGHT_PERFECT_FWD_OVERLOADS \
+BOOST_FLYWEIGHT_PERFECT_FWDS_1 \
+BOOST_FLYWEIGHT_PERFECT_FWDS_2
+#elif BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS==3
+#define BOOST_FLYWEIGHT_PERFECT_FWD_OVERLOADS \
+BOOST_FLYWEIGHT_PERFECT_FWDS_1 \
+BOOST_FLYWEIGHT_PERFECT_FWDS_2 \
+BOOST_FLYWEIGHT_PERFECT_FWDS_3
+#elif BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS==4
+#define BOOST_FLYWEIGHT_PERFECT_FWD_OVERLOADS \
+BOOST_FLYWEIGHT_PERFECT_FWDS_1 \
+BOOST_FLYWEIGHT_PERFECT_FWDS_2 \
+BOOST_FLYWEIGHT_PERFECT_FWDS_3 \
+BOOST_FLYWEIGHT_PERFECT_FWDS_4
+#else /* BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS==5 */
+#define BOOST_FLYWEIGHT_PERFECT_FWD_OVERLOADS \
+BOOST_FLYWEIGHT_PERFECT_FWDS_1 \
+BOOST_FLYWEIGHT_PERFECT_FWDS_2 \
+BOOST_FLYWEIGHT_PERFECT_FWDS_3 \
+BOOST_FLYWEIGHT_PERFECT_FWDS_4 \
+BOOST_FLYWEIGHT_PERFECT_FWDS_5
+#endif
+
+/* generate the overloads */
+
+BOOST_FLYWEIGHT_PERFECT_FWD_OVERLOADS
+
+/* clean up */
+
+#undef BOOST_FLYWEIGHT_PERFECT_FWD_OVERLOADS
+
+#if BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS>=1
+#undef BOOST_FLYWEIGHT_PERFECT_FWDS_1
+#endif
+
+#if BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS>=2
+#undef BOOST_FLYWEIGHT_PERFECT_FWDS_2
+#endif
+
+#if BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS>=3
+#undef BOOST_FLYWEIGHT_PERFECT_FWDS_3
+#endif
+
+#if BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS>=4
+#undef BOOST_FLYWEIGHT_PERFECT_FWDS_4
+#endif
+
+#if BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS>=5
+#undef BOOST_FLYWEIGHT_PERFECT_FWDS_5
+#endif
+
+/* user supplied argument macros */
+
+#undef BOOST_FLYWEIGHT_PERFECT_FWD_NAME
+#undef BOOST_FLYWEIGHT_PERFECT_FWD_BODY

Added: sandbox/flyweight/boost/flyweight/detail/value_tag.hpp
==============================================================================
--- (empty file)
+++ sandbox/flyweight/boost/flyweight/detail/value_tag.hpp 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,50 @@
+/* Copyright 2006-2008 Joaquin M Lopez Munoz.
+ * 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)
+ *
+ * See http://www.boost.org/libs/flyweight for library home page.
+ */
+
+#ifndef BOOST_FLYWEIGHT_DETAIL_VALUE_TAG_HPP
+#define BOOST_FLYWEIGHT_DETAIL_VALUE_TAG_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/parameter/parameters.hpp>
+#include <boost/type_traits/is_base_and_derived.hpp>
+
+namespace boost{
+
+namespace flyweights{
+
+namespace detail{
+
+/* Three ways to indicate that a given class T is a value policy:
+ * 1. Make it derived from value_marker.
+ * 2. Specialize is_value to evaluate to boost::mpl::true_.
+ * 3. Pass it as value<T> when defining a flyweight type.
+ *
+ * For the time being the interface of value policies is not public.
+ */
+
+struct value_marker{};
+
+template<typename T>
+struct is_value:is_base_and_derived<value_marker,T>
+{};
+
+template<typename T=parameter::void_>
+struct value:parameter::template_keyword<value<>,T>
+{};
+
+} /* namespace flyweights::detail */
+
+} /* namespace flyweights */
+
+} /* namespace boost */
+
+#endif

Added: sandbox/flyweight/boost/flyweight/key_value.hpp
==============================================================================
--- (empty file)
+++ sandbox/flyweight/boost/flyweight/key_value.hpp 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,238 @@
+/* Copyright 2006-2008 Joaquin M Lopez Munoz.
+ * 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)
+ *
+ * See http://www.boost.org/libs/flyweight for library home page.
+ */
+
+#ifndef BOOST_FLYWEIGHT_KEY_VALUE_HPP
+#define BOOST_FLYWEIGHT_KEY_VALUE_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/flyweight/detail/value_tag.hpp>
+#include <boost/flyweight/key_value_fwd.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/type_traits/aligned_storage.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <new>
+
+/* key-value policy: flywewight lookup is based on Key, which also serves
+ * to construct Value only when needed (new factory entry). key_value is
+ * used to avoid the construction of temporary values when such construction
+ * is expensive.
+ * Optionally, KeyFromValue extracts the key from a value, which
+ * is needed in expressions like this:
+ *
+ * typedef flyweight<key_value<Key,Value> > fw_t;
+ * fw_t fw;
+ * Value v;
+ * fw=v; // no key explicitly given
+ *
+ * If no KeyFromValue is provided, this latter expression fails to compile.
+ */
+
+namespace boost{
+
+namespace flyweights{
+
+namespace detail{
+
+template<typename Key,typename Value,typename KeyFromValue>
+struct optimized_key_value:value_marker
+{
+ typedef Key key_type;
+ typedef Value value_type;
+
+ class rep_type
+ {
+ public:
+ /* template ctors */
+
+#define BOOST_FLYWEIGHT_PERFECT_FWD_NAME explicit rep_type
+#define BOOST_FLYWEIGHT_PERFECT_FWD_BODY(n) \
+ :value_ptr(0) \
+{ \
+ new(spc_ptr())key_type(BOOST_PP_ENUM_PARAMS(n,t)); \
+}
+#include <boost/flyweight/detail/perfect_fwd.hpp>
+
+ rep_type(const value_type& x):value_ptr(&x){}
+
+ rep_type(const rep_type& x):value_ptr(x.value_ptr)
+ {
+ if(!x.value_ptr)new(key_ptr())key_type(*x.key_ptr());
+ }
+
+ ~rep_type()
+ {
+ if(!value_ptr) key_ptr()->~key_type();
+ else if(value_cted())value_ptr->~value_type();
+ }
+
+ operator const key_type&()const
+ {
+ if(value_ptr)return key_from_value(*value_ptr);
+ else return *key_ptr();
+ }
+
+ operator const value_type&()const
+ {
+ /* This is always called after construct_value() or copy_value(),
+ * so we access spc directly rather than through value_ptr to
+ * save us an indirection.
+ */
+
+ return *static_cast<value_type*>(spc_ptr());
+ }
+
+ private:
+ friend struct optimized_key_value;
+
+ void* spc_ptr()const{return static_cast<void*>(&spc);}
+ bool value_cted()const{return value_ptr==spc_ptr();}
+
+ key_type* key_ptr()const
+ {
+ return static_cast<key_type*>(static_cast<void*>(&spc));
+ }
+
+ static const key_type& key_from_value(const value_type& x)
+ {
+ KeyFromValue k;
+ return k(x);
+ }
+
+ void construct_value()const
+ {
+ if(!value_cted()){
+ /* value_ptr must be ==0, oherwise copy_value would have been called */
+
+ key_type k(*key_ptr());
+ key_ptr()->~key_type();
+ value_ptr= /* guarantees key won't be re-dted at ~rep_type if the */
+ static_cast<value_type*>(spc_ptr())+1; /* next statement throws */
+ value_ptr=new(spc_ptr())value_type(k);
+ }
+ }
+
+ void copy_value()const
+ {
+ if(!value_cted())value_ptr=new(spc_ptr())value_type(*value_ptr);
+ }
+
+ mutable typename boost::aligned_storage<
+ (sizeof(key_type)>sizeof(value_type))?
+ sizeof(key_type):sizeof(value_type),
+ (boost::alignment_of<key_type>::value >
+ boost::alignment_of<value_type>::value)?
+ boost::alignment_of<key_type>::value:
+ boost::alignment_of<value_type>::value
+ >::type spc;
+ mutable const value_type* value_ptr;
+ };
+
+ static void construct_value(const rep_type& r)
+ {
+ r.construct_value();
+ }
+
+ static void copy_value(const rep_type& r)
+ {
+ r.copy_value();
+ }
+};
+
+template<typename Key,typename Value>
+struct regular_key_value:value_marker
+{
+ typedef Key key_type;
+ typedef Value value_type;
+
+ class rep_type
+ {
+ public:
+ /* template ctors */
+
+#define BOOST_FLYWEIGHT_PERFECT_FWD_NAME explicit rep_type
+#define BOOST_FLYWEIGHT_PERFECT_FWD_BODY(n) \
+ :key(BOOST_PP_ENUM_PARAMS(n,t)),value_ptr(0){}
+#include <boost/flyweight/detail/perfect_fwd.hpp>
+
+ rep_type(const value_type& x):key(no_key_from_value_failure()){}
+
+ rep_type(const rep_type& x):key(x.key),value_ptr(0){}
+
+ ~rep_type()
+ {
+ if(value_ptr)value_ptr->~value_type();
+ }
+
+ operator const key_type&()const{return key;}
+
+ operator const value_type&()const
+ {
+ /* This is always called after construct_value(),so we access spc
+ * directly rather than through value_ptr to save us an indirection.
+ */
+
+ return *static_cast<value_type*>(spc_ptr());
+ }
+
+ private:
+ friend struct regular_key_value;
+
+ void* spc_ptr()const{return static_cast<void*>(&spc);}
+
+ struct no_key_from_value_failure
+ {
+ BOOST_MPL_ASSERT_MSG(
+ false,
+ NO_KEY_FROM_VALUE_CONVERSION_PROVIDED,
+ (key_type,value_type));
+
+ operator const key_type&()const;
+ };
+
+ void construct_value()const
+ {
+ if(!value_ptr)value_ptr=new(spc_ptr())value_type(key);
+ }
+
+ key_type key;
+ mutable typename boost::aligned_storage<
+ sizeof(value_type),
+ boost::alignment_of<value_type>::value
+ >::type spc;
+ mutable const value_type* value_ptr;
+ };
+
+ static void construct_value(const rep_type& r)
+ {
+ r.construct_value();
+ }
+
+ static void copy_value(const rep_type&){}
+};
+
+} /* namespace flyweights::detail */
+
+template<typename Key,typename Value,typename KeyFromValue>
+struct key_value:
+ mpl::if_<
+ is_same<KeyFromValue,no_key_from_value>,
+ detail::regular_key_value<Key,Value>,
+ detail::optimized_key_value<Key,Value,KeyFromValue>
+ >::type
+{};
+
+} /* namespace flyweights */
+
+} /* namespace boost */
+
+#endif

Added: sandbox/flyweight/boost/flyweight/key_value_fwd.hpp
==============================================================================
--- (empty file)
+++ sandbox/flyweight/boost/flyweight/key_value_fwd.hpp 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,29 @@
+/* Copyright 2006-2008 Joaquin M Lopez Munoz.
+ * 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)
+ *
+ * See http://www.boost.org/libs/flyweight for library home page.
+ */
+
+#ifndef BOOST_FLYWEIGHT_KEY_VALUE_FWD_HPP
+#define BOOST_FLYWEIGHT_KEY_VALUE_FWD_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+namespace boost{
+
+namespace flyweights{
+
+struct no_key_from_value;
+
+template<typename Key,typename Value,typename KeyFromValue=no_key_from_value>
+struct key_value;
+
+} /* namespace flyweights */
+
+} /* namespace boost */
+
+#endif

Added: sandbox/flyweight/libs/flyweight/doc/memory.png
==============================================================================
Binary file. No diff available.

Added: sandbox/flyweight/libs/flyweight/doc/memory_gcc_344.png
==============================================================================
Binary file. No diff available.

Added: sandbox/flyweight/libs/flyweight/doc/memory_msvc_80.png
==============================================================================
Binary file. No diff available.

Added: sandbox/flyweight/libs/flyweight/doc/performance.html
==============================================================================
--- (empty file)
+++ sandbox/flyweight/libs/flyweight/doc/performance.html 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,472 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Boost.Flyweight Documentation - Performance</title>
+<link rel="stylesheet" href="style.css" type="text/css">
+<link rel="start" href="index.html">
+<link rel="prev" href="reference/tracking.html">
+<link rel="up" href="index.html">
+<link rel="next" href="examples.html">
+</head>
+
+<body>
+<h1><img src="../../../boost.png" alt="Boost logo" align=
+"middle" width="277" height="86">Boost.Flyweight Performance</h1>
+
+<div class="prev_link"><a href="reference/tracking.html"><img src="prev.gif" alt="tracking policies" border="0"><br>
+Tracking policies
+</a></div>
+<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
+Index
+</a></div>
+<div class="next_link"><a href="examples.html"><img src="next.gif" alt="examples" border="0"><br>
+Examples
+</a></div><br clear="all" style="clear: all;">
+<br clear="all" style="clear: all;">
+
+<hr>
+
+<h2>Contents</h2>
+
+<ul>
+ <li>Introduction</li>
+ <li>Memory consumption
+ <ul>
+ <li>Flyweight size</li>
+ <li>Entry size</li>
+ <li>Overall memory consumption</li>
+ </ul>
+ </li>
+ <li>Time efficiency
+ <ul>
+ <li>Initialization</li>
+ <li>Assignment</li>
+ <li>Equality comparison</li>
+ <li>Value access</li>
+ </ul>
+ </li>
+ <li>Experimental results
+ <ul>
+ <li>Microsoft Visual C++ 8.0
+ <ul>
+ <li>Memory</li>
+ <li>Execution time</li>
+ </ul>
+ </li>
+ <li>GCC 3.4.4
+ <ul>
+ <li>Memory</li>
+ <li>Execution time</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>Conclusions</li>
+</ul>
+
+<h2><a name="intro">Introduction</a></h2>
+
+<p>
+We show how to estimate the memory reduction obtained by the usage of
+Boost.Flyweight in a particular scenario and study the impact on the execution
+time for the different functional areas of <code>flyweight</code>.
+Some experimental results are provided.
+</p>
+
+<h2><a name="memory">Memory consumption</a></h2>
+
+<p>
+As we saw in the tutorial rationale,
+the flyweight pattern is based on two types of objects:
+<ul>
+ <li>The flyweight objects proper, which have very small size, typically
+ that of a pointer.
+ </li>
+ <li>The shared values, which are stored as internal <i>entries</i> into the
+ flyweight factory.
+ </li>
+</ul>
+The overall memory consumption is then a function of the size of the
+flyweight objects, the size of the entry objects and the degree of
+value redundancy.
+</p>
+
+<h3><a name="flyweight_size">Flyweight size</a></h3>
+
+<p>
+The only data member of a <code>flyweight</code> object is a so-called
+<i>handle</i>, an opaque object of small size provided by the internal
+flyweight factory to refer to the entries it stores. For the default
+hashed_factory,
+this handle is merely a pointer, so <code>sizeof(flyweight&lt;T&gt;)=sizeof(void*)</code>,
+4 bytes in typical 32-bit architectures.
+For other types of factories, the handle is an iterator to an internal
+container used in the implementation of the factory: again, its size
+is typically that of a pointer.
+</p>
+
+<h3><a name="entry_size">Entry size</a></h3>
+
+<p>
+The entries stored in the factory associated to <code>flyweight&lt;T,...&gt;</code>
+need not only hold a value of <code>T</code>, but also contain additional
+information related to the internal implementation of
+<code>flyweight&lt;T,...&gt;</code>:
+</p>
+
+<blockquote>
+<i>entry</i> = <code>sizeof(T)</code> + <i>overhead</i>.
+</blockquote>
+
+<p>
+For the current implementation of Boost.Flyweight, the following aspects
+contribute to <i>overhead</i>:
+<ul>
+ <li>Usage of key-value flyweights.</li>
+ <li>Internal overhead of the factory
+ container.
+ </li>
+ <li>Bookkeeping information associated to the
+ tracking mechanism.
+ </li>
+</ul>
+The table summarizes the separate contributions to <i>overhead</i> introduced
+by the different components taking part of the definition of
+a <code>flyweight</code> instantiation. Values are given in <i>words</i>,
+i.e. the size of a pointer, which is 4 bytes in a typical 32-bit architecture.
+Alignment may introduce additional overhead.
+</p>
+
+<p align="center">
+<table cellspacing="0">
+ <caption><b>Entry overhead of the components of Boost.Flyweight.</b></caption>
+<tr>
+ <th align="center"colspan="2">component</th>
+ <th align="center">overhead (words)</th>
+</tr>
+<tr>
+ <td align="center" rowspan="2">&nbsp;&nbsp;key_value&nbsp;&nbsp;</td>
+ <td align="center">&nbsp;&nbsp;with key extractor&nbsp;&nbsp;</td>
+ <td align="center">&nbsp;&nbsp;1<sup>(1)</sup>&nbsp;&nbsp;</td>
+</tr>
+<tr>
+ <td align="center">&nbsp;&nbsp;without key extractor&nbsp;&nbsp;</td>
+ <td align="center">&nbsp;&nbsp;1 + <code>sizeof(Key)&nbsp;&nbsp;</td>
+</tr>
+<tr class="odd_tr">
+ <td align="center" rowspan="3">&nbsp;&nbsp;factory&nbsp;&nbsp;</td>
+ <td align="center">&nbsp;&nbsp;hashed_factory&nbsp;&nbsp;</td>
+ <td align="center">&nbsp;&nbsp;~2.5&nbsp;&nbsp;</td>
+</tr>
+<tr class="odd_tr">
+ <td align="center">&nbsp;&nbsp;set_factory&nbsp;&nbsp;</td>
+ <td align="center">&nbsp;&nbsp;4<sup>(2)</sup>&nbsp;&nbsp;</td>
+</tr>
+<tr class="odd_tr">
+ <td align="center">&nbsp;&nbsp;assoc_container_factory&nbsp;&nbsp;</td>
+ <td align="center">&nbsp;&nbsp;depends on the container used&nbsp;&nbsp;</td>
+</tr>
+<tr>
+ <td align="center" rowspan="2">&nbsp;&nbsp;tracking mechanism&nbsp;&nbsp;</td>
+ <td align="center">&nbsp;&nbsp;refcounted&nbsp;&nbsp;</td>
+ <td align="center">&nbsp;&nbsp;1<sup>(3)</sup>&nbsp;&nbsp;</td>
+</tr>
+<tr>
+ <td align="center">&nbsp;&nbsp;no_tracking&nbsp;&nbsp;</td>
+ <td align="center">&nbsp;&nbsp;0&nbsp;&nbsp;</td>
+</tr>
+</table>
+<sup>(1)</sup> <small>Assuming that <code>sizeof(Key)&lt;=sizeof(Value)</code>.</small><br>
+<sup>(2)</sup> <small>For some implementations of <code>std::set</code> this overhead reduces to 3.</small><br>
+<sup>(3)</sup> <small>In some platforms this value can be 2.</small>
+</p>
+
+<p>
+For instance, for the default configuration parameters of <code>flyweight</code>,
+<i>overhead</i> is typically 2.5(<code>hashed_factory</code>) + 1(<code>refcounted</code>)
+= 3 words.
+</p>
+
+<h3><a name="overall_memory">Overall memory consumption</a></h3>
+
+<p>
+Consider a scenario where there are <i>N</i> different objects of type <code>T</code>
+jointly taking <i>M</i> different values. The objects consume then
+<i>S</i> = <i>N</i>&middot;<i>T</i> bytes, where <i>T</i> is defined as the
+average size of <code>T</code> (<code>sizeof(T)</code> plus dynamic
+memory allocated by <code>T</code> objects).
+If we now replace <code>T</code> by some instantiation
+<code>flyweight&lt;T,...&gt;</code>, the resulting memory consumption
+will be
+</p>
+
+<blockquote>
+<i>S<sub>F</sub></i> =
+<i>N</i>&middot;<i>P</i> + <i>M</i>&middot;(<i>T</i> + <i>overhead</i>),
+</blockquote>
+
+<p>
+where <i>P</i> is <code>sizeof(flyweight&lt;T,...&gt;)</code>, typically
+equal to <code>sizeof(void*)</code>, as seen before.
+The ratio <i>S<sub>F</sub></i> / <i>S</i> is then
+</p>
+
+<blockquote>
+<i>S<sub>F</sub></i> / <i>S</i> =
+(<i>P</i> / <i>T</i>)+ (<i>M</i> / <i>N</i>)(1 + <i>overhead</i> / <i>T</i>).
+</blockquote>
+
+<p>
+<i>S<sub>F</sub></i> / <i>S</i> tends to its minimum, <i>P</i> / <i>T</i>,
+as <i>M</i> / <i>N</i> tends to 0, i.e. when the degree of value redundancy
+among <code>T</code> objects grows higher. On the other hand, the worst possible case
+<i>S<sub>F</sub></i> / <i>S</i> = 1 + (<i>P</i> + <i>overhead</i>) / <i>T</i>
+happens when <i>M</i> / <i>N</i> = 1, that is, if there is no value redundancy at all; in this situation there is
+no point in applying the flyweight pattern in the first place.
+</p>
+
+<p align="center">
+<img src="memory.png" alt="relative memory consumption of Boost.Flyweight as a function of value diversity"
+width="446" height="411"><br>
+<b>Fig. 1: Relative memory consumption of Boost.Flyweight as a function of value diversity.</b>
+</p>
+
+<h2>
+<a name="time">Time efficiency</a>
+</h2>
+
+<p>
+The introduction of the flyweight pattern involves an extra level of indirection
+that, in general, results in some execution overhead when accessing the values. On
+the other hand, manipulation of flyweight objects is considerably faster than
+moving around the heavy values they stand for. We analyze qualitatively the
+execution overheads or improvements associated to the different usage contexts
+of Boost.Flyweight.
+</p>
+
+<h3><a name="initialization">Initialization</a></h3>
+
+<p>
+As compared with the initialization an object of type <code>T</code>, constructing
+a <code>flyweight&lt;T&gt;</code> performs important extra work like looking
+up the value in the flyweight factory and inserting it if it is not present.
+So, construction of flyweights (other than copy construction, which is
+cheap), is expected to be noticeably slower than the construction of the
+underlying type <code>T</code>. Much of the time spent at constructing
+the associated <code>T</code> value proper can be saved, however, by
+using key-value flyweights.
+</p>
+
+<h3><a name="assignment">Assignment</a></h3>
+
+<p>
+Assignment of flyweight objects is extremely fast, as it only involves
+assigning an internal handle type used to refer to the shared value. Moreover,
+assignment of <code>flyweight</code> objects never throws. Assignment time
+is influenced by the type of <a href="tutorial/configuration.html#tracking">tracking
+policy</a> used; in this regard,
+no_tracking
+is the fastest option.
+</p>
+
+<h3><a name="equality_comparison">Equality comparison</a></h3>
+
+<p>
+Comparing two <code>flyweight</code> objects for equality reduces to
+checking that the <i>addresses</i> of the values they are associated to
+are equal; in general, this operation is much faster than comparing the
+underlying values. This aspect is of particular relevance when the flyweight
+objects stand for complex values like those arising in the application of
+the composite pattern.
+</p>
+
+<h3><a name="value_access">Value access</a></h3>
+
+<p>
+The conversion from <code>flyweight&lt;T&gt;</code> to <code>const T&amp;</code>
+relies on a level of indirection relating the flyweight objects to the
+values they are associated to; so, value access is expected to be slower
+when using Boost.Flyweight as compared to using the associated values
+directly. This overhead, however, can be masked by an indirect improvement
+resulting from locality and cache effects: as the set of different <code>T</code>
+values handled by an instantiation of <code>flyweight&lt;T&gt;</code> is
+generally much smaller than the equivalent family of <code>T</code> objects
+when Boost.Flyweight is not used, active values can fit better
+into the processor cache.
+</p>
+
+<h2><a name="results">Experimental results</a></h2>
+
+<p>
+A profiling program was devised to test
+the space and time efficiency of different instantiations of <code>flyweight</code>
+against a base situation not using Boost.Flyweight. The profiled scenarios are:
+<ol>
+ <li><code>std::string</code>.</li>
+ <li><code>flyweight&lt;std::string&gt;</code> with default configuration aspects
+ (hashed_factory,
+ refcounted tracking,
+ simple_locking).
+ </li>
+ <li><code>flyweight&lt;std::string,no_tracking&gt;</code>.</li>
+ <li><code>flyweight&lt;std::string,set_factory&gt;</code>.</li>
+ <li><code>flyweight&lt;std::string,set_factory,no_tracking&gt;</code>.</li>
+</ol>
+</p>
+
+<p>
+Actually the types tested are not exactly those listed above, but instrumented
+versions that keep track of the allocated memory for profiling purposes.
+The program parses a text file into an array of words and then perform various
+manipulations involving the different context usages of Boost.Flyweight discussed
+previously. As our text file we have used the
+plain text
+version of Project Gutenberg edition of <a href="http://www.gutenberg.org/etext/2000"><i>Don
+Quijote</i></a> (2.04 MB).
+</p>
+
+<h3><a name="msvc_80">Microsoft Visual C++ 8.0</a></h3>
+
+<p>
+The program was built with default release settings and <code>_SECURE_SCL=0</code>.
+Tests were run under Windows XP in a machine equipped with an Intel Core 2 Duo T5500
+processor and 1 GB of RAM.
+</p>
+
+<h4><a name="msvc_80_memory">Memory</a></h4>
+
+<p align="center">
+<img src="memory_msvc_80.png" alt="memory consumption (MB), MSVC++ 8.0"
+width="798" height="322"><br>
+<b>Fig. 2: Memory consumption, MSVC++ 8.0. Values in MB.</b>
+</p>
+
+<p>
+The results show the memory consumption figures for the different profiled
+scenarios.
+The standard library implementation of MSVC++ 8.0 features the so-called
+small buffer optimization for strings, by which <code>std::string</code>
+objects hold a small buffer that can be used when the string is short,
+thus avoding dynamic allocations. This results in <code>sizeof(std::string)</code>
+being quite high, 28 bytes. In our particular test strings are almost always
+held in the small buffer, so the minimum SF / S
+achievable is 4/28 = 14.3%, which is quite close to the experimental
+results, given that the memory devoted to storage of shared values
+is residual (around 3% of total memory) due to the high word redundancy
+of the text source.
+</p>
+
+<h4><a name="msvc_80_time">Execution time</a></h4>
+
+<p align="center">
+<img src="time_msvc_80.png" alt="execution time (s), MSVC++ 8.0"
+width="820" height="324"><br>
+<b>Fig. 3: Execution time, MSVC++ 8.0. Values in seconds.</b>
+</p>
+
+<p>
+The figure displays execution times for the profiled scenarios in different
+usage contexts. In accordance with our previous
+qualitative analysis, initialization of <code>flyweight</code>s
+carries an important overhead with respect to the base case scenario (between 10% and 40%
+of additional execution time), while the other usage contexts
+(assignment, equality comparison and value access) have performance gains,
+with speedup factors of up to 14 in some cases. The use of a
+refcounted
+tracking policy introduces penalties with respect to
+no_tracking
+in initialization and assignment, but has no effect in equality comparison
+and value access.
+</p>
+
+<h3><a name="gcc_344">GNU GCC 3.4.4</a></h3>
+
+<p>
+The Cygwin/MinGW version of the compiler was used, with command options
+<code>-ftemplate-depth-128 -O3 -finline-functions -DNDEBUG</code>.
+Tests were run under a Cygwin terminal in the same machine as before.
+</p>
+
+<h4><a name="gcc_344_memory">Memory</a></h4>
+
+<p align="center">
+<img src="memory_gcc_344.png" alt="memory consumption (MB), GCC 3.4.4"
+width="798" height="322"><br>
+<b>Fig. 4: Memory consumption, GCC 3.4.4. Values in MB.</b>
+</p>
+
+<p>
+The standard library used by GCC 3.4.4 implements <code>std::string</code>
+using copy-on-write
+optimization techniques, which leads to very small value redundancy for
+some usage patterns. This explains why the memory reduction achieved
+by Boost.Flyweight is so poor in this case. Other contexts where assignment
+is much less used than direct construction will favor Boost.Flyweight
+over plain copy-on-write <code>std::string</code>s.
+</p>
+
+<h4><a name="gcc_344_time">Execution time</a></h4>
+
+<p align="center">
+<img src="time_gcc_344.png" alt="execution time (s), GCC 3.4.4"
+width="820" height="324"><br>
+<b>Fig. 5: Execution time, GCC 3.4.4. Values in seconds.</b>
+</p>
+
+<p>
+Relative performance figures are similar to those obtained for
+MSVC++ 8.0, although some of the
+speedups achieved by Boost.Flyweight are higher here (&times;25
+in equality comparison and up to &times;100 in assignment when
+no_tracking
+is in effect).
+</p>
+
+<h2><a name="conclusions">Conclusions</a></h2>
+
+<p>
+The introduction of Boost.Flyweight in application scenarios with very
+high value redundancy yields important reductions in memory consumption:
+this is especially relevant when data volume approaches the limits of
+physical memory in the machine, since Boost.Flyweight can avoid virtual
+memory thrashing thus making the application viable. We have shown
+how to estimate the achievable reduction in memory consumption from
+some basic value statistics and knowledge of the <code>flyweight</code>
+configuration aspects being used.
+</p>
+
+<p>
+Boost.Flyweight can also accelerate execution times in areas other than
+object initialization, due to the fastest manipulation of small
+flyweight objects and to locality and cache effects arising from the
+drastic reduction of the set of allocated values.
+</p>
+
+<hr>
+
+<div class="prev_link"><a href="reference/tracking.html"><img src="prev.gif" alt="tracking policies" border="0"><br>
+Tracking policies
+</a></div>
+<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
+Index
+</a></div>
+<div class="next_link"><a href="examples.html"><img src="next.gif" alt="examples" border="0"><br>
+Examples
+</a></div><br clear="all" style="clear: all;">
+<br clear="all" style="clear: all;">
+
+<br>
+
+<p>Revised August 27th 2008</p>
+
+<p>&copy; Copyright 2006-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
+Distributed under the Boost Software
+License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
+LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+http://www.boost.org/LICENSE_1_0.txt>)
+</p>
+
+</body>
+</html>

Added: sandbox/flyweight/libs/flyweight/doc/reference/key_value.html
==============================================================================
--- (empty file)
+++ sandbox/flyweight/libs/flyweight/doc/reference/key_value.html 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,126 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Boost.Flyweight Documentation - Key-value flyweights reference</title>
+<link rel="stylesheet" href="../style.css" type="text/css">
+<link rel="start" href="../index.html">
+<link rel="prev" href="flyweight.html">
+<link rel="up" href="index.html">
+<link rel="next" href="tags.html">
+</head>
+
+<body>
+<h1><img src="../../../../boost.png" alt="Boost logo" align=
+"middle" width="277" height="86">Key-value flyweights reference</h1>
+
+<div class="prev_link"><a href="flyweight.html"><img src="../prev.gif" alt="flyweight reference" border="0"><br>
+<code>flyweight</code> reference
+</a></div>
+<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.Flyweight reference" border="0"><br>
+Boost.Flyweight reference
+</a></div>
+<div class="next_link"><a href="tags.html"><img src="../next.gif" alt="tags" border="0"><br>
+Tags
+</a></div><br clear="all" style="clear: all;">
+
+<hr>
+
+<h2>Contents</h2>
+
+<ul>
+ <li>
Key extractors</li>
+ <li><a href="#key_value_fwd_synopsis">Header
+ <code>"boost/flyweight/key_value_fwd.hpp"</code> synopsis</a>
+ </li>
+ <li><a href="#synopsis">Header
+ <code>"boost/flyweight/key_value.hpp"</code> synopsis</a>
+ <ul>
+ <li>Class template key_value</li>
+ </ul>
+ </li>
+</ul>
+
+<h2><a name="key_extractor">Key extractors</a></h2>
+
+<p>
+Let <code>Key</code> be a type with some implicit equivalence relationship
+and <code>Value</code> an
+Assignable
+type constructible from <code>Key</code>.
+A <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html"><code>Default
+Constructible</code></a> type <code>KeyFromValue</code> is said
+to be a key extractor from <code>Value</code> to <code>Key</code> if
+<ol>
+ <li><code>kfv(cv)</code> is defined and have type <code>const Key&amp;</code>,</li>
+ <li><code>kfv(cv)</code> is equivalent to <code>kfv(Value(cv))</code>,</li>
+ <li><code>kfv(Value(k))</code> is equivalent to <code>k</code>,</li>
+</ol>
+for every <code>kfv</code> of type <code>const KeyFromValue</code>,
+<code>cv</code> of type <code>const Value</code> and
+<code>k</code> of type <code>Key</code>.
+</p>
+
+<h2><a name="key_value_fwd_synopsis">Header
+"boost/flyweight/key_value_fwd.hpp" synopsis</a></h2>
+
+<blockquote><pre>
+<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
+
+<span class=keyword>namespace</span> <span class=identifier>flyweights</span><span class=special>{</span>
+
+<span class=keyword>struct</span> <span class=identifier>no_key_from_value</span><span class=special>;</span>
+
+<span class=keyword>template</span><span class=special>&lt;</span>
+ <span class=keyword>typename</span> <span class=identifier>Key</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span>
+ <span class=keyword>typename</span> <span class=identifier>KeyFromValue</span><span class=special>=</span><span class=identifier>no_key_from_value</span>
+<span class=special>&gt;</span>
+<span class=keyword>struct</span> <span class=identifier>key_value</span><span class=special>;</span>
+
+<span class=special>}</span> <span class=comment>// namespace boost::flyweights</span>
+
+<span class=special>}</span> <span class=comment>// namespace boost</span>
+</pre></blockquote>
+
+<h2><a name="synopsis">Header
+"boost/flyweight/key_value.hpp" synopsis</a></h2>
+
+<h3><a name="key_value_construct">Class template <code>key_value</code></a></h3>
+
+<p>
+In flyweight instantiations
+of the form <code>flyweight&lt;T,...&gt;</code>, the associated
+<code>key_type</code> and <code>value_type</code> are both equal to <code>T</code>.
+Instantiations of the form <code>flyweight&lt;key_value&lt;Key,Value[,KeyFromValue]&gt;,...&gt;</code>
+allow to specify these types separately. <code>Key</code> and <code>Value</code>
+must be different types. When provided, <code>KeyFromValue</code>
+must be a Key Extractor from
+<code>Value</code> to <code>Key</code>.
+</p>
+
+<hr>
+
+<div class="prev_link"><a href="flyweight.html"><img src="../prev.gif" alt="flyweight reference" border="0"><br>
+<code>flyweight</code> reference
+</a></div>
+<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.Flyweight reference" border="0"><br>
+Boost.Flyweight reference
+</a></div>
+<div class="next_link"><a href="tags.html"><img src="../next.gif" alt="tags" border="0"><br>
+Tags
+</a></div><br clear="all" style="clear: all;">
+
+<br>
+
+<p>Revised August 14th 2008</p>
+
+<p>&copy; Copyright 2006-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
+Distributed under the Boost Software
+License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
+LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+http://www.boost.org/LICENSE_1_0.txt>)
+</p>
+
+</body>
+</html>

Added: sandbox/flyweight/libs/flyweight/doc/release_notes.html
==============================================================================
--- (empty file)
+++ sandbox/flyweight/libs/flyweight/doc/release_notes.html 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Boost.Flyweight Documentation - Release notes</title>
+<link rel="stylesheet" href="style.css" type="text/css">
+<link rel="start" href="index.html">
+<link rel="prev" href="future_work.html">
+<link rel="up" href="index.html">
+<link rel="next" href="acknowledgements.html">
+</head>
+
+<body>
+<h1><img src="../../../boost.png" alt="Boost logo" align=
+"middle" width="277" height="86">Boost.Flyweight Release notes</h1>
+
+<div class="prev_link"><a href="future_work.html"><img src="prev.gif" alt="future work" border="0"><br>
+Future work
+</a></div>
+<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
+Index
+</a></div>
+<div class="next_link"><a href="acknowledgements.html"><img src="next.gif" alt="acknowledgements" border="0"><br>
+Acknowledgements
+</a></div><br clear="all" style="clear: all;">
+<br clear="all" style="clear: all;">
+
+<hr>
+
+<h2>Contents</h2>
+
+<ul>
+ <li>
Boost 1.38 release</li>
+</ul>
+
+<h2><a name="boost_1_38">Boost 1.38 release</a></h2>
+
+<p>
+<ul>
+ <li>Initial release of Boost.Flyweight.</li>
+</ul>
+</p>
+
+<hr>
+
+<div class="prev_link"><a href="future_work.html"><img src="prev.gif" alt="future work" border="0"><br>
+Future work
+</a></div>
+<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
+Index
+</a></div>
+<div class="next_link"><a href="acknowledgements.html"><img src="next.gif" alt="acknowledgements" border="0"><br>
+Acknowledgements
+</a></div><br clear="all" style="clear: all;">
+<br clear="all" style="clear: all;">
+
+<br>
+
+<p>Revised August 27th 2008</p>
+
+<p>&copy; Copyright 2006-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
+Distributed under the Boost Software
+License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
+LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+http://www.boost.org/LICENSE_1_0.txt>)
+</p>
+
+</body>
+</html>

Added: sandbox/flyweight/libs/flyweight/doc/time_gcc_344.png
==============================================================================
Binary file. No diff available.

Added: sandbox/flyweight/libs/flyweight/doc/time_msvc_80.png
==============================================================================
Binary file. No diff available.

Added: sandbox/flyweight/libs/flyweight/doc/tutorial/key_value.html
==============================================================================
--- (empty file)
+++ sandbox/flyweight/libs/flyweight/doc/tutorial/key_value.html 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,231 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Boost.Flyweight Documentation - Tutorial - Key-value flyweights</title>
+<link rel="stylesheet" href="../style.css" type="text/css">
+<link rel="start" href="../index.html">
+<link rel="prev" href="basics.html">
+<link rel="up" href="index.html">
+<link rel="next" href="configuration.html">
+</head>
+
+<body>
+<h1><img src="../../../../boost.png" alt="Boost logo" align=
+"middle" width="277" height="86">Boost.Flyweight Tutorial: Key-value flyweights</h1>
+
+<div class="prev_link"><a href="basics.html"><img src="../prev.gif" alt="basics" border="0"><br>
+Basics
+</a></div>
+<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.Flyweight tutorial" border="0"><br>
+Boost.Flyweight tutorial
+</a></div>
+<div class="next_link"><a href="configuration.html"><img src="../next.gif" alt="configuring Boost.Flyweight" border="0"><br>
+Configuring Boost.Flyweight
+</a></div><br clear="all" style="clear: all;">
+
+<hr>
+
+<h2>Contents</h2>
+
+<ul>
+ <li>
Key-value flyweights
+ <ul>
+ <li>Key extractors</li>
+ <li>Type requirements</li>
+ </ul>
+ </li>
+</ul>
+
+<h2><a name="key_value">Key-value flyweights</a></h2>
+
+<p>
+Continuing with our online game example, suppose we have a huge class for
+handling rendering textures:
+</p>
+
+<blockquote><pre>
+<span class=keyword>class</span> <span class=identifier>texture</span>
+<span class=special>{</span>
+<span class=keyword>public</span><span class=special>:</span>
+ <span class=identifier>texture</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&amp;</span> <span class=identifier>filename</span><span class=special>){/*</span> <span class=identifier>loads</span> <span class=identifier>texture</span> <span class=identifier>file</span> <span class=special>*/}</span>
+
+ <span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&amp;</span> <span class=identifier>get_filename</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
+
+ <span class=comment>// rest of the interface</span>
+<span class=special>};</span>
+</pre></blockquote>
+
+<p>
+and we decide to use <code>flyweight&lt;texture&gt;</code> to ease the
+manipulation of these objects. Now consider this seemingly innocent
+expression:
+</p>
+
+<blockquote><pre>
+<span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>texture</span><span class=special>&gt;</span> <span class=identifier>fw</span><span class=special>(</span><span class=string>&quot;grass.texture&quot;</span><span class=special>);</span>
+</pre></blockquote>
+
+<p>
+Note that in order to construct <code>fw</code> we are implicitly
+constructing a full grass texture object. The expression is mostly
+equivalent to
+</p>
+
+<blockquote><pre>
+<span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>texture</span><span class=special>&gt;</span> <span class=identifier>fw</span><span class=special>(</span><span class=identifier>texture</span><span class=special>(</span><span class=string>&quot;grass.texture&quot;</span><span class=special>));</span>
+</pre></blockquote>
+
+<p>
+This is unnaceptably costly: we are constructing a massive temporary
+object just to throw it away in most cases, since Boost.Flyweight most
+likely already has an internal equivalent object to which <code>fw</code>
+will be bound --value sharing is the key feature behind the flyweight
+pattern after all. In this particular example, texture filenames act
+as a <i>key</i> to the actual texture objects: two texture objects
+constructed from the same filename are equivalent. So, we would like
+for filenames to be used for texture lookup and somehow be sure that
+the costly texture construction is only performed when no equivalent
+value has been found.
+</p>
+
+<p>
+<code>flyweight&lt;T&gt;</code> makes this distinction between key and value
+blurry because it uses <code>T</code> both as the key type and
+its associated value type. When this is inefficient, as in our texture
+example, we can explicity specify both types using the
+key_value
+construct:
+</p>
+
+<blockquote><pre>
+<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
+<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>/</span><span class=identifier>key_value</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
+<span class=special>...</span>
+<span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>key_value</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span><span class=identifier>texture</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=identifier>fw</span><span class=special>(</span><span class=string>&quot;grass.texture&quot;</span><span class=special>);</span>
+</pre></blockquote>
+
+<p>
+So called <i>key-value flyweights</i> have then the form
+<code>flyweight&lt;key_value&lt;K,T&gt; &gt;</code>: the key type <code>K</code> is
+used to do the internal lookup for the associated values of type <code>T</code>. Key-value
+flyweights guarantee that <code>T</code> values are not constructed except when
+no other equivalent value exists; such construction is done from the associated
+<code>K</code> value.
+</p>
+
+<h3><a name="key_extractor">Key extractors</a></h3>
+
+<p>
+Besides the key-based semantics on construction time, key-value flyweights
+behave much the same as regular flyweights, although some differences persist.
+Consider the following code, which poses no problems with regular
+flyweights:
+</p>
+
+<blockquote><pre>
+<span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>key_value</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span><span class=identifier>texture</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=identifier>fw</span><span class=special>;</span>
+<span class=special>...</span>
+<span class=identifier>fw</span><span class=special>=</span><span class=identifier>texture</span><span class=special>(</span><span class=string>&quot;sand.texture&quot;</span><span class=special>);</span>
+</pre></blockquote>
+
+<p>
+The assignment cannot possibly work, because a key of type <code>std::string</code>
+is needed to do the internal lookup whereas we are passing a full texture object.
+Indeed, the code produces the a compilation error similar to this:
+</p>
+
+<blockquote><pre>
+error: 'boost::mpl::assertion_failed' : cannot convert parameter 1 from
+'boost::mpl::failed ************(__thiscall boost::flyweights::detail::
+regular_key_value&lt;Key,Value&gt;::rep_type::no_key_from_value_failure::
+<b>NO_KEY_FROM_VALUE_CONVERSION_PROVIDED</b>::* ***********)(std::string,texture)'
+to 'boost::mpl::assert&lt;false&gt;::type'...
+</pre></blockquote>
+
+<p>
+It turns out that we can make the assignment work if only we provide a means
+to retrieve the key from the value. This is not always possible, but in
+our particular example the texture class does store the filename used for
+construction, as indicated by the <code>texture::get_filename</code>
+member function. We take advantage of this by specifying a
+suitable <a href="../reference/key_value.html#key_extractor"><i>key
+extractor</i></a> as part of the flyweight type definition:
+</p>
+
+<blockquote><pre>
+<span class=keyword>struct</span> <span class=identifier>texture_filename_extractor</span>
+<span class=special>{</span>
+ <span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>texture</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span>
+ <span class=special>{</span>
+ <span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>get_filename</span><span class=special>();</span>
+ <span class=special>}</span>
+<span class=special>};</span>
+
+<span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>key_value</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span><span class=identifier>texture</span><span class=special>,</span><span class=identifier>texture_filename_extractor</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=identifier>fw</span><span class=special>;</span>
+<span class=special>...</span>
+<span class=identifier>fw</span><span class=special>=</span><span class=identifier>texture</span><span class=special>(</span><span class=string>&quot;sand.texture&quot;</span><span class=special>);</span> <span class=comment>// OK now</span>
+</pre></blockquote>
+
+<p>
+The specification of a key extractor in the
+definition of a key-value flyweight results in internal space optimizations,
+as the keys need not be stored along the values but are retrieved from
+them instead. So, it is always a good idea to provide a key extractor when
+possible even if your program does not contain assignment statements like
+the one above.
+</p>
+
+<p>
+Examples 2 and
+5
+of the examples section make use of key-value flyweights.
+</p>
+
+<h3><a name="requirements">Type requirements</a></h3>
+
+<p>
+Many of the requirements imposed on <code>T</code> for
+regular flyweights move to the key
+type in the case of a key-value <code>flyweight&lt;key_value&lt;K,T&gt; &gt;</code>.
+Now it is <code>K</code> that must be
+Assignable,
+<a href="http://www.sgi.com/tech/stl/EqualityComparable.html"><code>Equality
+Comparable</code></a> and interoperate with
+Boost.Hash, where equality and
+hash compatibility are requirements imposed by the default internal factory of
+Boost.Flyweight and can change if this factory is further configured or replaced
+by the user. The only requisite retained on <code>T</code> is that it must be
+constructible from <code>K</code>; only in the case that a flyweight is directly
+assigned a <code>T</code> object is also <code>T</code> required to be
+Assignable.
+To serialize objects of type <code>flyweight&lt;key_value&lt;K,T&gt; &gt;</code>
+only <code>K</code> needs to be serializable.
+</p>
+
+<hr>
+
+<div class="prev_link"><a href="basics.html"><img src="../prev.gif" alt="basics" border="0"><br>
+Basics
+</a></div>
+<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.Flyweight tutorial" border="0"><br>
+Boost.Flyweight tutorial
+</a></div>
+<div class="next_link"><a href="configuration.html"><img src="../next.gif" alt="configuring Boost.Flyweight" border="0"><br>
+Configuring Boost.Flyweight
+</a></div><br clear="all" style="clear: all;">
+
+<br>
+
+<p>Revised August 14th 2008</p>
+
+<p>&copy; Copyright 2006-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
+Distributed under the Boost Software
+License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
+LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+http://www.boost.org/LICENSE_1_0.txt>)
+</p>
+
+</body>
+</html>

Added: sandbox/flyweight/libs/flyweight/example/fibonacci.cpp
==============================================================================
--- (empty file)
+++ sandbox/flyweight/libs/flyweight/example/fibonacci.cpp 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,58 @@
+/* Boost.Flyweight example of flyweight-based memoization.
+ *
+ * Copyright 2006-2008 Joaquin M Lopez Munoz.
+ * 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)
+ *
+ * See http://www.boost.org/libs/flyweight for library home page.
+ */
+
+#include <boost/flyweight.hpp>
+#include <boost/flyweight/key_value.hpp>
+#include <boost/flyweight/no_tracking.hpp>
+#include <boost/noncopyable.hpp>
+#include <iostream>
+
+using namespace boost::flyweights;
+
+/* Memoized calculation of Fibonacci numbers */
+
+/* This class takes an int n and calculates F(n) at construction time */
+
+struct compute_fibonacci;
+
+/* A Fibonacci number can be modeled as a key-value flyweight
+ * We choose the no_tracking policy so that the calculations
+ * persist for future use throughout the program. See
+ * Tutorial: Configuring Boost.Flyweight: Tracking policies for
+ * further information on tracking policies.
+ */
+
+typedef flyweight<key_value<int,compute_fibonacci>,no_tracking> fibonacci;
+
+/* Implementation of compute_fibonacci. Note that the construction
+ * of compute_fibonacci(n) uses fibonacci(n-1) and fibonacci(n-2),
+ * which effectively memoizes the computation.
+ */
+
+struct compute_fibonacci:private boost::noncopyable
+{
+ compute_fibonacci(int n):
+ result(n==0?0:n==1?1:fibonacci(n-2).get()+fibonacci(n-1).get())
+ {}
+
+ operator int()const{return result;}
+ int result;
+};
+
+int main()
+{
+ /* list some Fibonacci numbers */
+
+ for(int n=0;n<40;++n){
+ std::cout<<"F("<<n<<")="<<fibonacci(n)<<std::endl;
+ }
+
+ return 0;
+}

Added: sandbox/flyweight/libs/flyweight/example/key_value.cpp
==============================================================================
--- (empty file)
+++ sandbox/flyweight/libs/flyweight/example/key_value.cpp 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,99 @@
+/* Boost.Flyweight example of use of key-value flyweights.
+ *
+ * Copyright 2006-2008 Joaquin M Lopez Munoz.
+ * 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)
+ *
+ * See http://www.boost.org/libs/flyweight for library home page.
+ */
+
+#include <boost/array.hpp>
+#include <boost/flyweight.hpp>
+#include <boost/flyweight/key_value.hpp>
+#include <cstdlib>
+#include <iostream>
+#include <string>
+#include <vector>
+
+using namespace boost::flyweights;
+
+/* A class simulating a texture resource loaded from file */
+
+class texture
+{
+public:
+ texture(const std::string& filename):filename(filename)
+ {
+ std::cout<<"loaded "<<filename<<" file"<<std::endl;
+ }
+
+ texture(const texture& x):filename(x.filename)
+ {
+ std::cout<<"texture["<<filename<<"] copied"<<std::endl;
+ }
+
+ ~texture()
+ {
+ std::cout<<"unloaded "<<filename<<std::endl;
+ }
+
+ const std::string& get_filename()const{return filename;}
+
+ // rest of the interface
+
+private:
+ std::string filename;
+};
+
+/* key extractor of filename strings from textures */
+
+struct texture_filename_extractor
+{
+ const std::string& operator()(const texture& x)const
+ {
+ return x.get_filename();
+ }
+};
+
+/* texture flyweight */
+
+typedef flyweight<
+ key_value<std::string,texture,texture_filename_extractor>
+> texture_flyweight;
+
+int main()
+{
+ /* texture filenames */
+
+ const char* texture_filenames[]={
+ "grass.texture","sand.texture","water.texture","wood.texture",
+ "granite.texture","cotton.texture","concrete.texture","carpet.texture"
+ };
+ const int num_texture_filenames=
+ sizeof(texture_filenames)/sizeof(texture_filenames[0]);
+
+ /* create a massive vector of textures */
+
+ std::cout<<"creating flyweights...\n"<<std::endl;
+
+ std::vector<texture_flyweight> textures;
+ for(int i=0;i<50000;++i){
+ textures.push_back(
+ texture_flyweight(texture_filenames[std::rand()%num_texture_filenames]));
+ }
+
+ /* Just for the sake of making use of the key extractor,
+ * assign some flyweights with texture objects rather than strings.
+ */
+
+ for(int j=0;j<50000;++j){
+ textures.push_back(
+ texture_flyweight(
+ textures[std::rand()%textures.size()].get()));
+ }
+
+ std::cout<<"\n"<<textures.size()<<" flyweights created\n"<<std::endl;
+
+ return 0;
+}

Added: sandbox/flyweight/libs/flyweight/test/heavy_objects.hpp
==============================================================================
--- (empty file)
+++ sandbox/flyweight/libs/flyweight/test/heavy_objects.hpp 2008-09-01 11:55:26 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,87 @@
+/* Boost.Flyweight basic test template.
+ *
+ * Copyright 2006-2008 Joaquin M Lopez Munoz.
+ * 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)
+ *
+ * See http://www.boost.org/libs/flyweight for library home page.
+ */
+
+#ifndef BOOST_FLYWEIGHT_TEST_HEAVY_OBJECTS_HPP
+#define BOOST_FLYWEIGHT_TEST_HEAVY_OBJECTS_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/noncopyable.hpp>
+#include <iosfwd>
+#include <string>
+
+struct texture
+{
+ texture(const std::string& str=""):str(str){}
+
+ friend bool operator==(
+ const texture& x,const texture& y){return x.str==y.str;}
+ friend bool operator< (
+ const texture& x,const texture& y){return x.str< y.str;}
+ friend bool operator!=(
+ const texture& x,const texture& y){return x.str!=y.str;}
+ friend bool operator> (
+ const texture& x,const texture& y){return x.str> y.str;}
+ friend bool operator>=(
+ const texture& x,const texture& y){return x.str>=y.str;}
+ friend bool operator<=(
+ const texture& x,const texture& y){return x.str<=y.str;}
+
+ friend std::ostream& operator<<(std::ostream& os,const texture& x)
+ {
+ return os<<x.str;
+ }
+
+ friend std::istream& operator>>(std::istream& is,texture& x)
+ {
+ return is>>x.str;
+ }
+
+ std::string str;
+};
+
+struct from_texture_to_string
+{
+ const std::string& operator()(const texture& x)const{return x.str;}
+};
+
+struct factorization:private boost::noncopyable
+{
+ factorization(int n=0):n(n){}
+
+ friend bool operator==(
+ const factorization& x,const factorization& y){return x.n==y.n;}
+ friend bool operator< (
+ const factorization& x,const factorization& y){return x.n< y.n;}
+ friend bool operator!=(
+ const factorization& x,const factorization& y){return x.n!=y.n;}
+ friend bool operator> (
+ const factorization& x,const factorization& y){return x.n> y.n;}
+ friend bool operator>=(
+ const factorization& x,const factorization& y){return x.n>=y.n;}
+ friend bool operator<=(
+ const factorization& x,const factorization& y){return x.n<=y.n;}
+
+ friend std::ostream& operator<<(std::ostream& os,const factorization& x)
+ {
+ return os<<x.n;
+ }
+
+ friend std::istream& operator>>(std::istream& is,factorization& x)
+ {
+ return is>>x.n;
+ }
+
+ int n;
+};
+
+#endif


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