$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: hervebronnimann_at_[hidden]
Date: 2007-07-12 09:19:13
Author: hervebronnimann
Date: 2007-07-12 09:19:12 EDT (Thu, 12 Jul 2007)
New Revision: 7414
URL: http://svn.boost.org/trac/boost/changeset/7414
Log:
More example.
Added:
   sandbox/SOC/2007/geometry/libs/hdstl/dev/halfedge_ds/facet_selectors.cpp
   sandbox/SOC/2007/geometry/libs/hdstl/dev/halfedge_ds/facet_selectors.t.cpp
Text files modified: 
   sandbox/SOC/2007/geometry/libs/hdstl/dev/halfedge_ds/facet_selectors.hpp |   270 ++++++++++++++++++++++++++++++++++++++- 
   1 files changed, 260 insertions(+), 10 deletions(-)
Added: sandbox/SOC/2007/geometry/libs/hdstl/dev/halfedge_ds/facet_selectors.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/geometry/libs/hdstl/dev/halfedge_ds/facet_selectors.cpp	2007-07-12 09:19:12 EDT (Thu, 12 Jul 2007)
@@ -0,0 +1,3 @@
+//facet_selectors.cpp   -*- C++ -*-
+
+#include <boost/hdstl/halfedge_ds/facet_selectors.hpp>
Modified: sandbox/SOC/2007/geometry/libs/hdstl/dev/halfedge_ds/facet_selectors.hpp
==============================================================================
--- sandbox/SOC/2007/geometry/libs/hdstl/dev/halfedge_ds/facet_selectors.hpp	(original)
+++ sandbox/SOC/2007/geometry/libs/hdstl/dev/halfedge_ds/facet_selectors.hpp	2007-07-12 09:19:12 EDT (Thu, 12 Jul 2007)
@@ -3,29 +3,279 @@
 //@PURPOSE: Provide selector classes for 'FacetS'.
 //
 //@CLASSES:
-//  'facetS':  defines configuration options for facet access
+//        'facetS':  defines configuration options for facet storage and access
+//  'stored_facet':  defines the storage for a given facet configuration
+//     'facet_gen':  defines the stored type and accessors for a facet configuration
 //  
 //@SEE_ALSO: {hds_concepts.hpp, halfedge_ds.hpp}
 //
-//@DESCRIPTION: This file provides the 'facetS' selector class for
-//configurations related to facet properties. 
+//@DESCRIPTION: This file provides the 'facetS' selector classes for
+// configurations related to facet properties.  These selector types are
+// suitable to use for the 'FacetS' template parameter to the 'halfedge_ds'
+// class template.  Currently, there are two facet selectors:
+//
+// - 'noFacetS': means that there should be no facets in the corresponding
+//   'hafedge_ds' data structure, and
+//
+// - 'facetS<ContainerS, HasfacetLink>': (where 'ContainerS' can be any of the
+//    types defined by the 'container_selectors' component, such as 'listS',
+//    'vecS', 'setS' or 'hashS') means that there should be facets stored in
+//    that kind of containers within the 'halfedge_ds' data structure, and
+//    whether the facets must have a link to one of the halfedges in their
+//    facet cycles or not.
+//
+// As a consequence, a 'halfedge_ds<..., ..., facetS<...> >' data structure
+// (where the actual selectors used in '...' do not matter) will model the
+// 'FacetListHDS' concept.
+//
+///Usage
+///-----
+// Supposed we want to design a stored facet from a facet selector.  A stored
+// facet needs to know:
+// - whether it stores a facet link or not.
+// - the halfedge descriptor:  in order to store the facet link.  Since it is
+//   not needed when the facet stores no facet link, we make it integer in that
+//   case.
+// - any extra properties that need to get contained by the facet as member. We
+//   make this a parameterized base class.
+//
+// We therefore have the following general implementation.
+//..
+//  template <typename Base,
+//            bool HasVertexLink = false, 
+//            typename HalfedgeDescriptor = int>
+//  struct stored_facet : public Base {
+//      // This 'struct' implements a stored facet, deriving from the
+//      // parameterized 'Base', and adding a facet link if 'HasFacetLink' is
+//      // true.
+//
+//      // DATA
+//      HalfedgeDescriptor m_facetLink;
+//
+//      // CREATORS
+//      stored_facet(Base const& base, HalfedgeDescriptor facetLink)
+//      : Base(base)
+//      , m_facetLink(facetLink) {}
+//  };
+//..
+// Since the facetLink is stored or not, we encapsulate this in a specialization.
+//..
+//  template <typename Base>
+//  struct stored_facet : public Base {
+//      // This specialization implements a stored facet, deriving from the
+//      // parameterized 'Base', but without storing a facet link although its
+//      // constructor accepts a null facet link for uniformity of the
+//      // interface with the general definition.
+//
+//      // CREATORS
+//      stored_facet(Base const& base, HalfedgeDescriptor = 0)
+//      : Base(base) {}
+//  };
+//..
+// Now, we can further define the facet generator: it takes a facet selector
+// and a halfedge descriptor, and uses the 'container_selectors' component to
+// define a suitable base for the 'halfedge_ds_gen' that implements all the
+// functionality of the 'halfedge_ds' related to the facets.
+//..
+//  template <typename HalfedgeDescriptor, typename FacetBase>
+//  struct facet_gen {
+//      // This 'struct' implements a facet generator.  The general definition does
+//      // nothing.
+//  };
+//..
+// The proper facet generator is defined only when 'FacetS' is of the form
+// 'facetS<...>':
+//..
+//  // SPECIALIZATIONS
+//  template <typename FacetS, typename HalfedgeDescriptor = void, typename FacetBase = void>
+//  struct facet_gen<facetS<ContainerS, HasFacetLink>, HalfedgeDescriptor, FacetBase> {
+//      // This specialization of a facet generator for 'facetS' takes a facet selector
+//      // and a halfedge descriptor, and uses the 'container_selectors' component
+//      // to define a suitable base for the 'halfedge_ds_gen' that implements all
+//      // the functionality of the 'halfedge_ds' related to the facets.
+//  
+//      // TYPES
+//      typedef container_gen<ContainerS>           ContainerGen;
+//          // The container generator for this facet generator.
+//
+//      typedef stored_facet<FacetBase, HasfacetLink, HalfedgeDescriptor>
+//                                                  facet_type;
+//          // The stored facet type for this facet generator.
+//  
+//      typedef typename container_gen<ContainerS, facet_type>::type
+//                                                  container_type;
+//          // The facet container type for this facet generator.
+//  
+//      typedef typename container_type::descriptor facet_descriptor;
+//          // The facet descriptor type for this facet generator.
+//
+//      typedef typename container_type::iterator   facet_iterator;
+//          // The facet iterator type for this facet generator.
+//  
+//      // DATA
+//      container_type m_container;
+//          // The actual container for the facets, from which facets can be obtained.
+//  };
+//..
+// and the supporting functions, required by the 'FacetListHDS' concept, are:
+//..
+//  // FREE FUNCTIONS
+//  template <typename FacetS, typename HalfedgeDescriptor, typename FacetBase>
+//  typename facet_gen<FacetS, HalfedgeDescriptor, FacetBase>::iterator
+//  facets_begin(facet_gen<FacetS, HalfedgeDescriptor, FacetBase> const& hds) {
+//      typedef typename facet_gen<FacetS,
+//                                 HalfedgeDescriptor,
+//                                 FacetBase>::container_gen_type ContainerGen;
+//      return ContainerGen::container_begin(hds.m_container);
+//  }
+//  
+//  template <typename FacetS, typename HalfedgeDescriptor, typename FacetBase>
+//  typename facet_gen<FacetS, HalfedgeDescriptor, FacetBase>::iterator
+//  facets_end(facet_gen<FacetS, HalfedgeDescriptor, FacetBase> const& hds) {
+//      typedef typename facet_gen<FacetS,
+//                                 HalfedgeDescriptor,
+//                                 FacetBase>::container_gen_type ContainerGen;
+//      return ContainerGen::container_end(hds.m_container);
+//  }
+//  
+//  template <typename FacetS, typename HalfedgeDescriptor, typename FacetBase>
+//  typename facet_gen<FacetS, HalfedgeDescriptor, FacetBase>::size_type;
+//  facets_end(facet_gen<FacetS, HalfedgeDescriptor, FacetBase> const& hds) {
+//      return hds.m_container.size();
+//  }
+//..
 
 #ifndef BOOST_HDSTL_FACET_SELECTORS_HPP
 #define BOOST_HDSTL_FACET_SELECTORS_HPP 1
 
-namespace boost;
-namespace hdstl;
+namespace boost {
+namespace hdstl {
 
-template<typename Selector>
+                 // ---------------------------
+                 // classes noFacetS and facetS
+                 // ---------------------------
+
+struct noFacetS {
+    // A selector that tells the 'halfedge_ds' that it should not store facets.
+};
+
+template<typename ContainerS, bool HasFacetLink = false>
 struct facetS {
-    typedef false_type is_rand_access;
+    // A selector that tells the 'halfedge_ds' that it should store facets in a
+    // container selected by the specified 'Selector', and that those facets
+    // should have a link to one of the halfedges in their facet cycle or not,
+    // depending on the specified 'HasFacetLink' boolean template parameter.
+
+    // TYPES
+    typedef ContainerS   container_selector;
+        // A selector (see the component 'container_selector') for the type of
+        // container that
+        // will be used to store the halfedge.
+
+    enum { has_facet_links = HasFacetLink };
+        // A boolean enumeration that tells whether the stored halfedge should
+        // contain a link to one of the halfedges in its fact cycle or not.
 };
 
-template<>
-struct facets<vecS> {
-    typedef true_type is_rand_access;
+                 // ------------------
+                 // class stored_facet
+                 // ------------------
+
+template <typename Base,
+          bool HasFacetLink = false, 
+          typename HalfedgeDescriptor = int>
+struct stored_facet : public Base {
+    // This 'struct' implements a stored facet, deriving from the
+    // parameterized 'Base', and adding a facet link if 'HasFacetLink' is
+    // true.
+
+    // DATA
+    HalfedgeDescriptor m_facetLink;
+
+    // CREATORS
+    stored_facet(Base const& base, HalfedgeDescriptor facetLink)
+    : Base(base)
+    , m_facetLink(facetLink) {}
+};
+
+template <typename Base, typename HalfedgeDescriptor>
+struct stored_facet<Base, false, HalfedgeDescriptor> : public Base {
+    // This partial specialization implements a stored facet, deriving from the
+    // parameterized 'Base', but without storing a facet link although its
+    // constructor accepts a null facet link for uniformity of the
+    // interface with the general definition.
+
+    // CREATORS
+    stored_facet(Base const& base, HalfedgeDescriptor = 0)
+    : Base(base) {}
+};
+
+                 // ---------------
+                 // class facet_gen
+                 // ---------------
+
+template <typename HalfedgeDescriptor, typename FacetBase>
+struct facet_gen {
+    // This 'struct' implements a facet generator.  The general definition does
+    // nothing.
+};
+
+// SPECIALIZATIONS
+template <typename FacetS, typename HalfedgeDescriptor = void, typename FacetBase = void>
+struct facet_gen<facetS<ContainerS, HasFacetLink>, HalfedgeDescriptor, FacetBase> {
+    // This specialization of a facet generator for 'facetS' takes a facet selector
+    // and a halfedge descriptor, and uses the 'container_selectors' component
+    // to define a suitable base for the 'halfedge_ds_gen' that implements all
+    // the functionality of the 'halfedge_ds' related to the facets.
+
+    // TYPES
+    typedef container_gen<ContainerS>           ContainerGen;
+        // The container generator for this facet generator.
+
+    typedef stored_facet<FacetBase, HasfacetLink, HalfedgeDescriptor>
+                                                facet_type;
+        // The stored facet type for this facet generator.
+
+    typedef typename container_gen<ContainerS, facet_type>::type
+                                                container_type;
+        // The facet container type for this facet generator.
+
+    typedef typename container_type::descriptor facet_descriptor;
+        // The facet descriptor type for this facet generator.
+
+    typedef typename container_type::iterator   facet_iterator;
+        // The facet iterator type for this facet generator.
+
+    // DATA
+    container_type m_container;
+        // The actual container for the facets, from which facets can be obtained.
 };
 
+// FREE FUNCTIONS
+template <typename FacetS, typename HalfedgeDescriptor, typename FacetBase>
+typename facet_gen<FacetS, HalfedgeDescriptor, FacetBase>::iterator
+facets_begin(facet_gen<FacetS, HalfedgeDescriptor, FacetBase> const& hds) {
+    typedef typename facet_gen<FacetS,
+                               HalfedgeDescriptor,
+                               FacetBase>::container_gen_type ContainerGen;
+    return ContainerGen::container_begin(hds.m_container);
+}
+
+template <typename FacetS, typename HalfedgeDescriptor, typename FacetBase>
+typename facet_gen<FacetS, HalfedgeDescriptor, FacetBase>::iterator
+facets_end(facet_gen<FacetS, HalfedgeDescriptor, FacetBase> const& hds) {
+    typedef typename facet_gen<FacetS,
+                               HalfedgeDescriptor,
+                               FacetBase>::container_gen_type ContainerGen;
+    return ContainerGen::container_end(hds.m_container);
+}
+
+template <typename FacetS, typename HalfedgeDescriptor, typename FacetBase>
+typename facet_gen<FacetS, HalfedgeDescriptor, FacetBase>::size_type;
+facets_end(facet_gen<FacetS, HalfedgeDescriptor, FacetBase> const& hds) {
+    return hds.m_container.size();
+}
+
 } // namespace hdstl
 } // namespace boost
 
Added: sandbox/SOC/2007/geometry/libs/hdstl/dev/halfedge_ds/facet_selectors.t.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/geometry/libs/hdstl/dev/halfedge_ds/facet_selectors.t.cpp	2007-07-12 09:19:12 EDT (Thu, 12 Jul 2007)
@@ -0,0 +1,216 @@
+//facet_selectors.hpp   -*- C++ -*-
+//
+//@OVERVIEW:  The component under test is a selector class.  We
+// must make sure that all selectors are suitably defined and that the
+// selection is done properly.
+//
+//@TEST_PLAN: First create an instance of all the selectors (to make sure they
+// exist, and verify that there are no more than tested).  Then instantiate the
+// 'container_gen<FacetS,ValueType>' for a given value type and all
+// selectors, and verify that its members have the expected types and
+// signatures.  Finally, verify that the usage example compiles and executes
+// without errors, when assert is replaced by BOOST_CHECK.
+
+#include <boost/hdstl/halfedge_ds/container_selectors.hpp>
+
+#include <boost/test/minimal.hpp>
+
+#include <set>
+#include <string>
+#include <vector>
+
+using namespace boost::hdstl;
+using namespace std;
+
+// ===========================================================================
+//                              SELECTOR CLASSES
+// ===========================================================================
+
+template <typename FacetS>
+bool selector_requirements(FacetS const&) {
+    return false;
+}
+
+bool selector_requirements(noFacetS const&) {
+    return true;
+}
+
+template <typename Base, typename HalfedgeDescriptor>
+bool selector_requirements(facetS<Base, false, HalfedgeDescriptor> const&) {
+    return true;
+}
+
+template <typename Base, typename HalfedgeDescriptor>
+bool selector_requirements(facetS<Base, true, HalfedgeDescriptor> const&) {
+    return true;
+}
+
+// ===========================================================================
+//                              CLASS CONTAINER_GEN
+// ===========================================================================
+
+template <typename FacetS>
+bool selection_requirements(FacetS const&) {
+    return false;
+}
+
+template <typename Base, typename HalfedgeDescriptor>
+bool selector_requirements(facetS<Base, false, HalfedgeDescriptor> const&f) {
+    return true;
+}
+
+template <typename Base, typename HalfedgeDescriptor>
+bool selector_requirements(facetS<Base, true, HalfedgeDescriptor> const&) {
+    return true;
+}
+
+template <class ContainerGen, typename ValueType, typename FacetS>
+bool container_gen_requirements() {
+    ValueType array[] = { 0, 1, 2, 3 };
+    typename ContainerGen::type container(array, array + 4);
+    
+    BOOST_CHECK(( selection_requirements(FacetS(), container) ));
+
+    // Types must exist.
+    typedef typename ContainerGen::descriptor descriptor;
+    typedef typename ContainerGen::iterator   iterator;
+
+    // Value type of iterator must be a descriptor.
+    iterator begin = ContainerGen::container_begin(container);
+    descriptor theBegin = *begin;
+
+    return true;
+}
+
+// ===========================================================================
+//                              USAGE EXAMPLE
+// ===========================================================================
+
+///Usage
+///-----
+// Suppose we want a data structure 'ElementCollection' containing instances of
+// a custom 'Element' type, stored in a container chosen by a selector given as
+// template parameter.  To make this picture more concrete, let us pick an
+// implementation:
+//..
+    struct Element {
+        int           userId;
+        std::string   familyName;
+        int           securityLevel;
+        Element(int uId, std::string name, int level)
+        : userId(uId), familyName(name), securityLevel(level) {}
+    };
+    bool operator<(const Element& lhs, const Element& rhs) {
+        return lhs.userId < rhs.userId;
+    }
+//..
+//  We can implement 'ElementCollection' using the 'container_gen' facility as
+//  follows.  We purposely keep the de
+//..
+    template <typename FacetS>
+    class ElementCollection {
+        // This class stores and gives access to a collection of 'Element'
+        // objects, using the container selected by the specified 'FacetS'
+        // selector.
+  
+      public:
+        // TYPES
+        typedef container_gen<FacetS, Element>       container_generator;
+        typedef typename container_generator::type       container_type;
+        typedef typename container_generator::descriptor descriptor;
+        typedef typename container_generator::iterator   iterator;
+  
+      private:
+        // DATA
+        container_type  m_collection;
+  
+      public:
+        // CREATORS
+        ElementCollection() {}
+            // Create an empty collection of 'Element' objects.
+  
+        template <typename Iterator>
+        ElementCollection(Iterator elementBegin, Iterator elementEnd)
+            // Create a collection of 'Element' objects initially containing
+            // the objects in the specified range '[elementBegin, elementEnd)'.
+        : m_collection(elementBegin, elementEnd) {}
+  
+        // MANIPULATORS
+        iterator begin() { return container_generator::container_begin(m_collection); }
+            // Return an iterator pointing to the beginning of this collection.
+  
+        iterator end() { return container_generator::container_end(m_collection); }
+            // Return an iterator pointing past the end of this collection.
+  
+        container_type& theContainer() { return m_collection; }
+            // Return the modifiable container underlying this collection.
+  
+        // ACCESSORS
+        const container_type& theContainer() const { return m_collection; }
+            // Return the non-modifiable container underlying this collection.
+    };
+//..
+// We can now use the collection as follows.  First let us create the
+// individual elements:
+//..
+    bool usageExample() {
+        Element george(632,  "Harrison",  +78);
+        Element john  (834,  "Lennon",    +255);
+        Element paul  (932,  "McCartney", +126);
+        Element ringo (1432, "Starr",     +123);
+        Element theBeatles[] = { george, john, paul, ringo };
+//..
+// We can use a collection as a searchable set:
+//..
+        ElementCollection<setS> setCollection(theBeatles, theBeatles + 4);
+        Element unknown(843, "Unkown",   +0);
+        BOOST_CHECK(( setCollection.theContainer().find(unknown) == setCollection.end() ));
+        BOOST_CHECK(( setCollection.theContainer().find(john)->familyName == "Lennon" ));
+//..
+// and access the iterators of the collection (here identical to the
+// iterators of the container):
+//..
+        BOOST_CHECK(( setCollection.begin()->familyName == "Harrison" ));
+        BOOST_CHECK(( (--setCollection.end())->familyName == "Starr" ));
+//..
+// or we can use the collection as an indexed array:
+//..
+        ElementCollection<vecS> vectorCollection(theBeatles, theBeatles + 4);
+        BOOST_CHECK(( vectorCollection.theContainer()[1].familyName == "Lennon" ));
+        BOOST_CHECK(( vectorCollection.theContainer()[3].familyName == "Starr" ));
+//..
+// and access the iterators of the collection (whose value type here is the
+// descriptor, not the same as the iterators of the container):
+//..
+        BOOST_CHECK( *vectorCollection.begin() == 0 );
+        BOOST_CHECK( *vectorCollection.end() == 4 );
+
+        return true;
+    }
+//..
+
+// ===========================================================================
+//                              BOOST TEST APPARATUS
+// ===========================================================================
+
+int test_main(int, char **)
+{
+    #if 0
+    BOOST_CHECK(( selector_requirements(hashS()) ));
+    #endif
+    BOOST_CHECK(( selector_requirements(listS()) ));
+    BOOST_CHECK(( selector_requirements(setS()) ));
+    BOOST_CHECK(( selector_requirements(vecS()) ));
+
+    #if 0
+    BOOST_CHECK(( selection_requirements<container_gen<hashS, int>, hashS>() ));
+    #endif
+    BOOST_CHECK(( container_gen_requirements<container_gen<listS, int>, int, listS>() ));
+    BOOST_CHECK(( container_gen_requirements<container_gen<setS, int>, int, setS>() ));
+    BOOST_CHECK(( container_gen_requirements<container_gen<vecS, int>, int, vecS>() ));
+
+    BOOST_CHECK(( usageExample() ));
+    
+    return 0;
+}
+