Boost logo

Boost-Commit :

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;
+}
+


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