$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r61825 - in sandbox/opaque: . boost boost/opaque libs libs/opaque libs/opaque/doc libs/opaque/example libs/opaque/test
From: vicente.botet_at_[hidden]
Date: 2010-05-06 14:09:39
Author: viboes
Date: 2010-05-06 14:09:36 EDT (Thu, 06 May 2010)
New Revision: 61825
URL: http://svn.boost.org/trac/boost/changeset/61825
Log:
Added Boost.Opaque
Added:
   sandbox/opaque/
   sandbox/opaque/boost/
   sandbox/opaque/boost/opaque/
   sandbox/opaque/boost/opaque/opaque.hpp   (contents, props changed)
   sandbox/opaque/libs/
   sandbox/opaque/libs/opaque/
   sandbox/opaque/libs/opaque/doc/
   sandbox/opaque/libs/opaque/doc/Jamfile.v2   (contents, props changed)
   sandbox/opaque/libs/opaque/doc/index.html   (contents, props changed)
   sandbox/opaque/libs/opaque/example/
   sandbox/opaque/libs/opaque/test/
   sandbox/opaque/libs/opaque/test/Jamfile.v2   (contents, props changed)
   sandbox/opaque/libs/opaque/test/test.cpp   (contents, props changed)
Added: sandbox/opaque/boost/opaque/opaque.hpp
==============================================================================
--- (empty file)
+++ sandbox/opaque/boost/opaque/opaque.hpp	2010-05-06 14:09:36 EDT (Thu, 06 May 2010)
@@ -0,0 +1,256 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2010.
+// 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/opaque for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_OPAQUE__HPP
+#define BOOST_OPAQUE__HPP
+
+#include <boost/config.hpp>
+#include <boost/operators.hpp>
+
+namespace boost {
+    template <typename Final, typename T, bool Convertible=true>
+    class opaque_type;
+
+
+    //~ *  totally_ordered<OT>
+    //~ * integer_arithmetic<OT>
+    //~ * bitwise<OT>
+    //~ * unit_steppable<OT>
+
+    //~ * totally_ordered<UT, OT>
+    //~ * integer_arithmetic<UT, OT>
+    //~ * bitwise<UT, OT>
+
+    template <typename Final, typename T>
+    class public_opaque_type
+        : boost::totally_ordered< Final
+        , boost::integer_arithmetic< Final
+        , boost::bitwise< Final
+        , boost::unit_steppable< Final
+        , boost::totally_ordered< T, Final  // public specific conversions
+        , boost::integer_arithmetic< T, Final // public specific conversions
+        , boost::bitwise< T, Final // public specific conversions
+        > > > > > > >
+    {
+    protected:
+        T val_;
+        typedef public_opaque_type opaque_type;
+    public:
+        typedef T underlying_type;
+        //~ Can instances of UT be explicitly converted to instances of OT?
+        //~ Proposed answer: yes.
+        //~ Can instances of UT be implicitly converted to instances of OT?
+        //~ Proposed answer: no.
+
+        explicit public_opaque_type(const T v)
+            : val_(v)
+        {};
+        public_opaque_type()
+        {};
+        public_opaque_type(const opaque_type & rhs)
+            : val_(rhs.val_)
+        {}
+        public_opaque_type & operator=(const opaque_type & rhs) {
+            val_ = rhs.val_; return *this;
+        }
+        public_opaque_type & operator=(const T rhs) {
+            val_ = rhs; return *this;
+        }
+
+        T const& underlying() const {
+            return val_;
+        }
+        T& underlying() {
+            return val_;
+        }
+
+        // public specific conversions
+        operator const T & () const {
+            return val_;
+        }
+        operator T & () {
+            return val_;
+        }
+#if 0
+        bool operator==(const opaque_type & rhs) const {
+            return val_ == rhs.val_;
+        }
+#endif
+        bool operator<(const Final & rhs) const {
+            return val_ < rhs.val_;
+        }
+        Final& operator+=(const Final & rhs) {
+            val_ += rhs.val_;
+            return static_cast<Final&>(*this);
+        }
+        Final& operator-=(const Final & rhs) {
+            val_ -= rhs.val_;
+            return static_cast<Final&>(*this);
+        }
+        Final& operator*=(const Final & rhs) {
+            val_ *= rhs.val_;
+            return static_cast<Final&>(*this);
+        }
+        Final& operator/=(const Final & rhs) {
+            val_ /= rhs.val_;
+            return static_cast<Final&>(*this);
+        }
+        Final& operator%=(const Final & rhs) {
+            val_ %= rhs.val_;
+            return static_cast<Final&>(*this);
+        }
+    };
+
+    template <typename Final, typename T>
+    class private_opaque_type
+        : boost::totally_ordered< Final
+        , boost::integer_arithmetic< Final
+        , boost::bitwise< Final
+        , boost::unit_steppable< Final
+        > > > >
+    {
+        T val_;
+        typedef private_opaque_type opaque_type;
+    public:
+        typedef T underlying_type;
+        //~ Can instances of UT be explicitly converted to instances of OT?
+        //~ Proposed answer: yes.
+        //~ Can instances of UT be implicitly converted to instances of OT?
+        //~ Proposed answer: no.
+
+        explicit private_opaque_type(const T v)
+            : val_(v)
+        {};
+        private_opaque_type()
+        {};
+        private_opaque_type(const opaque_type & rhs)
+            : val_(rhs.val_)
+        {}
+        private_opaque_type & operator=(const opaque_type & rhs) {
+            val_ = rhs.val_; return *this;
+        }
+
+        T underlying() const {
+            return val_;
+        }
+        T& underlying() {
+            return val_;
+        }
+        
+        //~ // public specific conversions
+        //~ operator const T & () const {
+            //~ return val_;
+        //~ }
+        //~ operator T & () {
+            //~ return val_;
+        //~ }
+        bool operator==(const Final & rhs) const {
+            return val_ == rhs.val_;
+        }
+        bool operator<(const Final & rhs) const {
+            return val_ < rhs.val_;
+        }
+        Final& operator+=(const Final & rhs) {
+            val_ += rhs.val_;
+            return static_cast<Final&>(*this);
+        }
+        Final& operator-=(const Final & rhs) {
+            val_ -= rhs.val_;
+            return static_cast<Final&>(*this);
+        }
+        Final& operator*=(const Final & rhs) {
+            val_ *= rhs.val_;
+            return static_cast<Final&>(*this);
+        }
+        Final& operator/=(const Final & rhs) {
+            val_ /= rhs.val_;
+            return static_cast<Final&>(*this);
+        }
+        Final& operator%=(const Final & rhs) {
+            val_ %= rhs.val_;
+            return static_cast<Final&>(*this);
+        }
+    };
+
+    template <typename T, typename U>
+    T opaque_static_cast(U v)    {
+        return static_castT<T>(v);
+    }
+    
+    template <typename T, typename UT, typename OT>
+    T opaque_static_cast<T, private_opaque_type<OT,UT> >(
+        private_opaque_type<OT,UT> const&ot)    {
+        return static_cast<T>(ot.underlying());
+    }
+    template <typename T, typename UT, typename OT>
+    private_opaque_type<OT,UT> opaque_static_cast<private_opaque_type<OT,UT>,T>(
+        T t)    {
+        return private_opaque_type<OT,UT>(static_cast<UT>(t));
+    }
+    
+    template <typename T, typename UT, typename OT>
+    T opaque_static_cast<UT,public_opaque_type<OT,UT>>(private_opaque_type<OT,UT> const&ot)    {
+        return static_cast<T>(ot.underlying());
+    }
+    
+    template <typename UT, typename OT>
+    UT opaque_static_cast<UT,private_opaque_type<OT,UT>>(private_opaque_type<OT,UT> const&ot)    {
+        return ot.underlying();
+    }
+    
+    template <typename X, typename Y>
+    OT opaque_dynamic_cast(Y y)    {
+        return dynamic_cast<X>(y);
+    }
+    template <typename X, typename UT, typename OT>
+    UT opaque_dynamic_cast<X,private_opaque_type<OT,UT> >(private_opaque_type<OT,UT> *ot)    {
+        return dynamic_cast<X>(&ot->underlying());
+    }
+    
+}
+
+#define BOOST_OPAQUE_PUBLIC_FORWARD_CONSTRUCTORS(OT, UT) \
+    OT(){}\
+    template <typename T> explicit OT(T v) : boost::public_opaque_type<OT, UT>(v) {}
+
+#define BOOST_OPAQUE_PUBLIC_OPERATIONS(OT, UT) \
+    BOOST_OPAQUE_FORWARD_CONSTRUCTORS(OT,OT);\
+    bool operator<(const OT & rhs) const {\
+        return val_ < rhs.val_;\
+    }\
+
+    //~ OT& operator+=(const OT & rhs) {
+        //~ val_ += rhs.val_;
+        //~ return *this;
+    //~ }
+
+#define BOOST_OPAQUE_PRIVATE_FORWARD_CONSTRUCTORS(OT, UT) \
+    OT(){}\
+    template <typename T> explicit OT(T v) : boost::private_opaque_type<OT, UT>(v) {}
+
+#define BOOST_OPAQUE_PRIVATE_OPERATIONS(OT, UT) \
+    BOOST_OPAQUE_PRIVATE_FORWARD_CONSTRUCTORS(OT, UT)
+
+#define BOOST_OPAQUE_PUBLIC_TYPEDEF(UT, OT) \
+struct OT: boost::public_opaque_type<OT, UT> \
+{\
+    BOOST_OPAQUE_PUBLIC_OPERATIONS(OT,UT);\
+}
+
+
+#define BOOST_OPAQUE_PRIVATE_TYPEDEF(UT, OT) \
+struct OT: boost::private_opaque_type<OT, UT> \
+{\
+    BOOST_OPAQUE_PRIVATE_OPERATIONS(OT,UT);\
+}
+
+#endif
Added: sandbox/opaque/libs/opaque/doc/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/opaque/libs/opaque/doc/Jamfile.v2	2010-05-06 14:09:36 EDT (Thu, 06 May 2010)
@@ -0,0 +1,72 @@
+#  Boost.LUID library documentation Jamfile  ---------------------------------
+#
+#  Copyright Vicente J. Botet Escriba 2009. Use, modification and
+#  distribution is 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)
+#
+#  See http://www.boost.org for updates, documentation, and revision history.
+
+#import doxygen ;
+import quickbook ;
+
+#doxygen autodoc
+#   :
+#      [ glob ../../../boost/interprocess/*.hpp ]
+#      [ glob ../../../boost/interprocess/allocators/*.hpp ]
+#   :
+#        <doxygen:param>EXTRACT_ALL=NO
+#        <doxygen:param>HIDE_UNDOC_MEMBERS=YES
+#        <doxygen:param>EXTRACT_PRIVATE=NO
+#        <doxygen:param>EXPAND_ONLY_PREDEF=YES
+#        <doxygen:param>PREDEFINED=BOOST_INTERPROCESS_DOXYGEN_INVOKED
+#        <xsl:param>"boost.doxygen.reftitle=Boost.Interprocess Reference"
+#   ;
+
+xml conversion : conversion.qbk ;
+
+boostbook standalone
+   :
+      conversion
+   :
+        # HTML options first:
+        # Use graphics not text for navigation:
+        <xsl:param>navig.graphics=1
+        # How far down we chunk nested sections, basically all of them:
+        <xsl:param>chunk.section.depth=2
+        # Don't put the first section on the same page as the TOC:
+        <xsl:param>chunk.first.sections=1
+        # How far down sections get TOC's
+        <xsl:param>toc.section.depth=4
+        # Max depth in each TOC:
+        <xsl:param>toc.max.depth=2
+        # How far down we go with TOC's
+        <xsl:param>generate.section.toc.level=10
+        # Path for links to Boost:
+        <xsl:param>boost.root=../../../..
+        # Path for libraries index:
+        <xsl:param>boost.libraries=../../../../libs/libraries.htm
+        # Use the main Boost stylesheet:
+        <xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
+
+        # PDF Options:
+        # TOC Generation: this is needed for FOP-0.9 and later:
+        #<xsl:param>fop1.extensions=1
+        # Or enable this if you're using XEP:
+        <xsl:param>xep.extensions=1
+        # TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9!
+        <xsl:param>fop.extensions=0
+        # No indent on body text:
+        <xsl:param>body.start.indent=0pt
+        # Margin size:
+        <xsl:param>page.margin.inner=0.5in
+        # Margin size:
+        <xsl:param>page.margin.outer=0.5in
+        # Yes, we want graphics for admonishments:
+        <xsl:param>admon.graphics=1
+        # Set this one for PDF generation *only*:
+        # default pnd graphics are awful in PDF form,
+        # better use SVG's instead:
+        <format>pdf:<xsl:param>admon.graphics.extension=".svg"
+        <format>pdf:<xsl:param>admon.graphics.path=$(boost-images)/
+   ;
Added: sandbox/opaque/libs/opaque/doc/index.html
==============================================================================
--- (empty file)
+++ sandbox/opaque/libs/opaque/doc/index.html	2010-05-06 14:09:36 EDT (Thu, 06 May 2010)
@@ -0,0 +1,9 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=html/index.html">
+</head>
+<body>
+Automatic redirection failed, please go to 
+../../doc/html/conversion.html
+</body>
+</html>
Added: sandbox/opaque/libs/opaque/test/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/opaque/libs/opaque/test/Jamfile.v2	2010-05-06 14:09:36 EDT (Thu, 06 May 2010)
@@ -0,0 +1,35 @@
+# Boost Chrono Library test Jamfile
+
+# Copyright Vicente Botet 2010
+
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt
+
+# See library home page at http://www.boost.org/libs/opaque
+
+# uncomment one if the above lines if you build outside the Boost release
+#local BOOST_ROOT = /boost_1_41_0 ;
+#local BOOST_ROOT = c:/cygwin/boost_1_41_0 ;
+
+if ! $(BOOST_ROOT)
+{
+    BOOST_ROOT = [ modules.peek : BOOST_ROOT ] ;
+}
+
+project
+    : requirements
+        <library>/boost/test//boost_unit_test_framework/<link>static
+        
+        # uncomment the line above if you build outside the Boost release
+        #<include>$(BOOST_ROOT) 
+        # uncomment the line above if you build outside the Boost release
+        #<include>../../..
+#        <toolset>msvc:<asynch-exceptions>on
+    ;
+
+   test-suite "public_opaque"
+       :
+         [ run test.cpp ]
+         ;
+
+
Added: sandbox/opaque/libs/opaque/test/test.cpp
==============================================================================
--- (empty file)
+++ sandbox/opaque/libs/opaque/test/test.cpp	2010-05-06 14:09:36 EDT (Thu, 06 May 2010)
@@ -0,0 +1,335 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2010. 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/opaque for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/opaque/opaque.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace boost;
+using namespace boost::unit_test;
+
+
+//~ struct game_score: public_opaque_type<game_score, unsigned>
+struct game_score: private_opaque_type<game_score, unsigned>
+{
+    // forward constructors
+    game_score(){}
+    template <typename T>
+    // explicit game_score(T v) : public_opaque_type<game_score, unsigned>(v) {}
+    explicit game_score(T v) : private_opaque_type<game_score, unsigned>(v) {}
+    //BOOST_OPAQUE_PRIVATE_OPERATIONS(game_score,unsigned);
+};    
+
+BOOST_OPAQUE_PRIVATE_TYPEDEF(unsigned,game_score);
+
+game_score accumulate( game_score g1, game_score g2 ) {
+ return g1 + g2;
+}
+
+struct serial_number: public_opaque_type<serial_number, unsigned>
+{
+    // forward constructors
+    serial_number(){}
+    template <typename T>
+    explicit serial_number(T v) : public_opaque_type<serial_number, unsigned>(v) {}
+};    
+//~ BOOST_OPAQUE_PUBLIC_TYPEDEF(unsigned,serial_number);
+    
+
+serial_number next_id( serial_number n ) {
+ //return static_cast<serial_number>(n + 1u);
+ // return opaque_static_cast<serial_number>(n + 1u);
+ return serial_number(n + 1u);
+}
+
+void accumulate_test() {
+    game_score gs1(1), gs2(2), res;
+    res= accumulate(gs1,gs2);
+    BOOST_CHECK(gs1<gs2);
+    BOOST_CHECK(gs1<=gs2);
+    BOOST_CHECK(gs2>=gs1);
+    BOOST_CHECK(res==game_score(3));
+    BOOST_CHECK(game_score(3)==res);
+    
+    game_score res2;
+    res2=res+res;
+    BOOST_CHECK(res+res==game_score(6));
+}
+
+void next_id_test() {
+    serial_number sn(1), res;
+    res= next_id(sn);
+    BOOST_CHECK(res==serial_number(2));
+    BOOST_CHECK(serial_number(2)==res);
+    
+    BOOST_CHECK(res+res==serial_number(4));
+    
+    BOOST_CHECK(sn<res);
+}
+
+//~ void mix_test_fail() {
+    //~ game_score sn(1), res;
+    //~ res= next_id(sn);
+    //~ BOOST_CHECK(serial_number(3)==game_score(3));
+//~ }
+
+
+BOOST_OPAQUE_PUBLIC_TYPEDEF(unsigned,public_unsigned);
+BOOST_OPAQUE_PUBLIC_TYPEDEF(unsigned,public_unsigned2);
+
+void public_assign_test() {
+    public_unsigned a, a2;
+    public_unsigned2 b;
+        
+    //~ a=b; // error
+    a=a2; // OK
+    
+    unsigned i;
+    
+    i=a;
+    i=b;
+    //~ a=i; // error
+    //~ b=i; // error
+}
+
+void public_eq_test() {
+    public_unsigned a(1), b(2), c(2);
+    BOOST_CHECK(b==c);
+    BOOST_CHECK((a==b)==false);
+    
+    unsigned u=1,v=2;
+    BOOST_CHECK(a==1u);
+    BOOST_CHECK(u==a);
+    BOOST_CHECK(a==u);
+    BOOST_CHECK((a==v)==false);
+    BOOST_CHECK((v==a)==false);
+}
+
+void public_lt_test() {
+    public_unsigned a(1), b(2), c(2);
+    BOOST_CHECK(a<b);
+    BOOST_CHECK((b<a)==false);
+    BOOST_CHECK((b<c)==false);
+}
+
+void public_gt_test() {
+    public_unsigned a(1), b(2), c(2);
+    BOOST_CHECK(b>a);
+    BOOST_CHECK((a>b)==false);
+    BOOST_CHECK((b>c)==false);
+}
+
+void public_le_test() {
+    public_unsigned a(1), b(2), c(2);
+    BOOST_CHECK(a<=b);
+    BOOST_CHECK((b<=a)==false);
+    BOOST_CHECK(b<=c);
+}
+void public_ge_test() {
+    public_unsigned a(1), b(2), c(2);
+    BOOST_CHECK(b>=a);
+    BOOST_CHECK((a>=b)==false);
+    BOOST_CHECK(b>=c);
+}
+
+void public_add_test() {
+    public_unsigned a(1), b(2), c(3),d(4);
+    BOOST_CHECK(a+b==c);
+    BOOST_CHECK(c==a+b);
+    BOOST_CHECK((a+b==d)==false);
+    BOOST_CHECK((d==a+b)==false);
+
+    public_unsigned2 x;
+    //~ a=a+x; // error
+    
+    unsigned u=3,v=0;
+    BOOST_CHECK(a+b==3u);
+    BOOST_CHECK(u==a+b);
+    BOOST_CHECK(a+b==u);
+    BOOST_CHECK((a+b==v)==false);
+    BOOST_CHECK((v==a+b)==false);
+    
+}
+
+void public_substract_test() {
+    public_unsigned a(1), b(2), c(3),d(4);
+    BOOST_CHECK(c-b==a);
+    BOOST_CHECK(a==c-b);
+    BOOST_CHECK((c-b==d)==false);
+    BOOST_CHECK((d==c-b)==false);
+
+    unsigned u=1,v=0;
+    BOOST_CHECK(c-b==1u);
+    BOOST_CHECK(u==c-b);
+    BOOST_CHECK(c-b==u);
+    BOOST_CHECK((c-b==v)==false);
+    BOOST_CHECK((v==c-b)==false);
+    
+}
+
+BOOST_OPAQUE_PRIVATE_TYPEDEF(unsigned,private_unsigned);
+BOOST_OPAQUE_PRIVATE_TYPEDEF(unsigned,private_unsigned2);
+
+void private_assign_test() {
+    private_unsigned a, a2;
+    private_unsigned2 b;
+        
+    //~ a=b; // error
+    a=a2; // OK
+    
+    unsigned i;
+    
+    i=opaque_static_cast(a);
+    //~ i=a; // error
+    
+    //~ i=b; // error
+    //~ a=i; // error
+    //~ b=i; // error
+}
+
+void private_eq_test() {
+    private_unsigned a(1), b(2), c(2);
+    BOOST_CHECK(b==c);
+    BOOST_CHECK((a==b)==false);
+}
+#if 0
+void private_eq_test_fails() {
+    private_unsigned a;
+    private_unsigned2 a2;
+    BOOST_CHECK(a==a2);
+}
+#endif
+void private_lt_test() {
+    private_unsigned a(1), b(2), c(2);
+    BOOST_CHECK(a<b);
+    BOOST_CHECK((b<a)==false);
+    BOOST_CHECK((b<c)==false);
+}
+
+void private_gt_test() {
+    private_unsigned a(1), b(2), c(2);
+    BOOST_CHECK(b>a);
+    BOOST_CHECK((a>b)==false);
+    BOOST_CHECK((b>c)==false);
+}
+
+void private_le_test() {
+    private_unsigned a(1), b(2), c(2);
+    BOOST_CHECK(a<=b);
+    BOOST_CHECK((b<=a)==false);
+    BOOST_CHECK(b<=c);
+}
+void private_ge_test() {
+    private_unsigned a(1), b(2), c(2);
+    BOOST_CHECK(b>=a);
+    BOOST_CHECK((a>=b)==false);
+    BOOST_CHECK(b>=c);
+}
+
+void private_add_test() {
+    public_unsigned a(1), b(2), c(3),d(4);
+    BOOST_CHECK(a+b==c);
+    BOOST_CHECK(c==a+b);
+    BOOST_CHECK((a+b==d)==false);
+    BOOST_CHECK((d==a+b)==false);
+
+    public_unsigned2 x;
+    //~ a=a+x; // error
+    
+    //~ unsigned u=3,v=0;
+    //~ BOOST_CHECK(a+b==3u);
+    //~ BOOST_CHECK(u==a+b);
+    //~ BOOST_CHECK(a+b==u);
+    //~ BOOST_CHECK((a+b==v)==false);
+    //~ BOOST_CHECK((v==a+b)==false);
+    
+}
+
+void private_substract_test() {
+    public_unsigned a(1), b(2), c(3),d(4);
+    BOOST_CHECK(c-b==a);
+    BOOST_CHECK(a==c-b);
+    BOOST_CHECK((c-b==d)==false);
+    BOOST_CHECK((d==c-b)==false);
+
+    //~ unsigned u=1,v=0;
+    //~ BOOST_CHECK(c-b==1u);
+    //~ BOOST_CHECK(u==c-b);
+    //~ BOOST_CHECK(c-b==u);
+    //~ BOOST_CHECK((c-b==v)==false);
+    //~ BOOST_CHECK((v==c-b)==false);
+    
+}
+
+// Listing 7
+BOOST_OPAQUE_PRIVATE_TYPEDEF(double,mass1_leng2_per_time2);
+BOOST_OPAQUE_PUBLIC_TYPEDEF(mass1_leng2_per_time2,energy);
+BOOST_OPAQUE_PUBLIC_TYPEDEF(energy,kinetic_energy);
+BOOST_OPAQUE_PUBLIC_TYPEDEF(energy,potential_energy);
+BOOST_OPAQUE_PUBLIC_TYPEDEF(energy,heat_energy);
+
+double sqrt(double d) { return d;}
+void public_multiple_levels_test() {
+    //~ double d;
+    mass1_leng2_per_time2 x;
+    energy e;
+    kinetic_energy k;
+    potential_energy p, q;
+      
+    p = p + q; // ok
+    e = p + q; // ok
+    //~ x = p + q; // error two levels
+    //~ test.cpp:287: error: no match for 'operator=' in 'x = boost::operator+(const potential_energy&, const potential_energy&)(((const potential_energy&)((const potential_energy*)(& q))))'
+    //~ test.cpp:270: note: candidates are: mass1_leng2_per_time2& mass1_leng2_per_time2::operator=(const mass1_leng2_per_time2&)
+    
+    //~ e = k + p; // ok!!! error
+    //~ test.cpp:287: error: ambiguous overload for 'operator+' in 'k + p'
+    //~ ..\..\../boost/operators.hpp:255: note: candidates are: energy boost::operator+(const energy&, const energy&)
+    //~ ..\..\../boost/operators.hpp:255: note:                 energy boost::operator+(const kinetic_energy&, const energy&)
+    //~ ..\..\../boost/operators.hpp:255: note:                 energy boost::operator+(const energy&, const potential_energy&)    
+    
+    //~ k = p + q; // error
+    //~ test.cpp:297: error: no match for 'operator=' in 'k = boost::operator+(const potential_energy&, const potential_energy&)(((const potential_energy&)((const potential_energy*)(& q))))'
+    //~ test.cpp:272: note: candidates are: kinetic_energy& kinetic_energy::operator=(const kinetic_energy&)
+    
+    //~ d = sqrt(e); // error
+    //~ test.cpp:302: error: cannot convert 'energy' to 'double' for argument '1' to 'double sqrt(double)'
+}
+
+test_suite* init_unit_test_suite(int, char*[])
+{
+  test_suite* test = BOOST_TEST_SUITE("ex1");
+  test->add(BOOST_TEST_CASE(&accumulate_test));
+  test->add(BOOST_TEST_CASE(&next_id_test));
+  test->add(BOOST_TEST_CASE(&public_multiple_levels_test));
+    
+  test->add(BOOST_TEST_CASE(&public_assign_test));
+  test->add(BOOST_TEST_CASE(&public_eq_test));
+  test->add(BOOST_TEST_CASE(&public_lt_test));
+  test->add(BOOST_TEST_CASE(&public_gt_test));
+  test->add(BOOST_TEST_CASE(&public_le_test));
+  test->add(BOOST_TEST_CASE(&public_ge_test));
+  test->add(BOOST_TEST_CASE(&public_add_test));
+  test->add(BOOST_TEST_CASE(&public_substract_test));
+
+    
+  test->add(BOOST_TEST_CASE(&private_assign_test));
+  test->add(BOOST_TEST_CASE(&private_eq_test));
+  test->add(BOOST_TEST_CASE(&private_lt_test));
+  test->add(BOOST_TEST_CASE(&private_gt_test));
+  test->add(BOOST_TEST_CASE(&private_le_test));
+  test->add(BOOST_TEST_CASE(&private_ge_test));
+  test->add(BOOST_TEST_CASE(&private_add_test));
+  test->add(BOOST_TEST_CASE(&private_substract_test));
+    
+  return test;
+}
+
+