Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r78522 - in sandbox/association: boost/association libs/association/test
From: vicente.botet_at_[hidden]
Date: 2012-05-20 12:41:44


Author: viboes
Date: 2012-05-20 12:41:43 EDT (Sun, 20 May 2012)
New Revision: 78522
URL: http://svn.boost.org/trac/boost/changeset/78522

Log:
Association: document and modify a little bit the interface
Text files modified:
   sandbox/association/boost/association/association.hpp | 485 +++++++++++++++++++++++----------------
   sandbox/association/libs/association/test/basic_usage.cpp | 37 +-
   2 files changed, 304 insertions(+), 218 deletions(-)

Modified: sandbox/association/boost/association/association.hpp
==============================================================================
--- sandbox/association/boost/association/association.hpp (original)
+++ sandbox/association/boost/association/association.hpp 2012-05-20 12:41:43 EDT (Sun, 20 May 2012)
@@ -14,233 +14,313 @@
 #define BOOST_BIASSOCIATION__HPP
 
 #include <stddef.h>
+#include <boost/config.hpp>
 #include <boost/assert.hpp>
 #include <boost/utility/enable_if.hpp>
 #include <boost/mpl/if.hpp>
 #include <boost/type_traits/is_same.hpp>
-
-namespace boost {
-
-template <typename Type,typename Tag>
-struct tagged {
- typedef Type type;
- typedef Tag tag;
-};
-
-namespace member_at {
- struct left {};
- struct right {};
-}
-
-template <typename T>
-struct tagged_traits {
- typedef T type;
- typedef member_at::left tag;
-};
-
-template <typename T, typename Tag>
-struct tagged_traits<tagged<T,Tag> > {
- typedef T type;
- typedef Tag tag;
-};
-
-
-// specializations of get_field must define a static function apply
-// with the following prototype
-// typename TaggedType::type& apply(T&);
-
-template <typename TaggedType, typename T>
-struct get_field;
-
-// specializations of get_embeding must define a static function apply
-// with the following prototype
-// T& apply(FieldType&);
-
-template <typename T, typename Tag, typename FieldType>
-struct get_embeding;
-
-
-
-namespace association {
-
-
-template <typename T, typename U>
-class end_ptr {
-
-public:
- typedef typename tagged_traits<T>::type own_type;
- typedef typename tagged_traits<T>::tag own_tag;
- typedef typename tagged_traits<U>::type other_type;
- typedef typename tagged_traits<U>::tag other_tag;
-private:
- other_type* other_ptr_;
-
-public:
-
- typedef other_type element_type;
- typedef other_type value_type;
- typedef other_type * pointer;
-
- end_ptr() : other_ptr_(0) {}
-
- ~end_ptr()
- {
- disconnect();
- }
-
- element_type* get()
- {
- return other_ptr_;
- }
-
- const other_type* operator-> () const
- {
+//#include <boost/bimap.hpp>
+#include <boost/bimap/tags/tagged.hpp>
+#include <boost/bimap/relation/member_at.hpp>
+#include <boost/bimap/tags/support/default_tagged.hpp>
+
+namespace boost
+{
+ namespace association
+ {
+
+ // import bimaps directly to the association namespace
+
+ using ::boost::bimaps::tags::tagged;
+
+ namespace member_at = ::boost::bimaps::relation::member_at;
+
+ namespace detail
+ {
+
+ template <typename T>
+ struct left_tagged
+ {
+ typedef tagged<T, member_at::left> type;
+ };
+
+ template <typename T, typename Tag>
+ struct left_tagged<tagged<T, Tag> >
+ {
+ typedef tagged<T, Tag> type;
+ };
+
+ template <typename T>
+ struct right_tagged
+ {
+ typedef tagged<T, member_at::right> type;
+ };
+
+ template <typename T, typename Tag>
+ struct right_tagged<tagged<T, Tag> >
+ {
+ typedef tagged<T, Tag> type;
+ };
+ }
+
+ // specializations of get_field must define a static function apply
+ // with the following prototype
+ // typename TaggedType::type& apply(T&);
+
+ template <typename TaggedType, typename T>
+ struct get_field;
+
+ // specializations of get_embeding must define a static function apply
+ // with the following prototype
+ // T& apply(FieldType&);
+
+ template <typename T, typename Tag, typename FieldType>
+ struct get_embeding;
+
+ /**
+ * An association end pointer is an object that manages the consistency with the other association end pointer.
+ *
+ * More precisely, and end pointer is an object @c u that stores a pointer to a second object @c p and
+ * will disconnect both when @c u is destroyed.
+ * In this context @u is said to be connected to T.
+ *
+ * The mechanism by which @c u connects/disconnects to/from @c p
+ */
+ template <typename Entity, typename T>
+ class end_ptr
+ {
+
+ public:
+ typedef typename Entity::value_type entity_type;
+ typedef typename Entity::tag entity_tag;
+ typedef typename T::value_type element_type;
+ typedef typename T::tag element_tag;
+ private:
+ element_type* element_ptr_;
+ entity_type* entity_ptr_;
+
+ public:
+
+ //typedef element_type value_type;
+ typedef element_type * pointer;
+
+ /**
+ * @Effects Constructs a end_ptr object that is not associated, value-initializing the stored pointer.
+ * Postconditions: get() == nullptr.
+ */
+ BOOST_CONSTEXPR end_ptr(entity_type* entity_ptr) BOOST_NOEXCEPT :
+ element_ptr_(0),
+ entity_ptr_(entity_ptr)
+ {
+ }
+
+ ~end_ptr()
+ {
+ reset();
+ }
+
+ /**
+ * @Returns The stored pointer.
+ */
+ pointer get() const BOOST_NOEXCEPT
+ {
+ return element_ptr_;
+ }
+
+ /**
+ * @Requires get() != nullptr.
+ * @Returns get().
+ * @Note use typically requires that T be a complete type.
+ */
+ const element_type* operator->() const
+ {
         BOOST_ASSERT(get() != 0);
         return get();
- }
- other_type* operator-> ()
- {
+ }
+ pointer operator->()
+ {
         BOOST_ASSERT(get() != 0);
         return get();
- }
+ }
 
- other_type const& operator* () const
- {
+ /*
+ * @Requires get() != nullptr.
+ * @Returns *get().
+ */
+ element_type const& operator*() const
+ {
         BOOST_ASSERT(get() != 0);
         return *get();
- }
+ }
 
- other_type& operator* ()
- {
+ /*
+ * @Requires get() != nullptr.
+ * @Returns *get().
+ */
+ element_type& operator*()
+ {
         BOOST_ASSERT(get() != 0);
         return *get();
- }
+ }
 
- // C c; c.f=&u;
- end_ptr& operator=(other_type* ptr) {
- connect(ptr);
+ // C c; c.f=&u;
+ end_ptr& operator=(element_type* ptr)
+ {
+ reset(ptr);
         return *this;
- }
- end_ptr& operator=(end_ptr& rhs) {
- if (this!= &rhs) {
- disconnect();
- connect(rhs.other_ptr_);
+ }
+ end_ptr& operator=(end_ptr& rhs)
+ {
+ if (this != &rhs)
+ {
+ reset(rhs.element_ptr_);
         }
         return *this;
- }
-
- void swap(end_ptr& other)
- {
- U* own_u = other_ptr_;
- U* other_u = other.other_ptr_;
-
- connect(other_u);
- other.connect(own_u);
- }
-
- void connect(other_type* ptr)
- {
- if(ptr == other_ptr_) return;
- disconnect();
- if(ptr == 0) return;
- other_ptr_ = ptr;
- get_field<tagged<end_ptr<U,T>,own_tag>, other_type>::apply(*ptr).connect_one(
- &get_embeding<own_type, own_tag, end_ptr<T,U> >::apply(*this));
- }
-
- void disconnect()
- {
- if(other_ptr_==0) return;
- other_type* tmp = other_ptr_;
- other_ptr_= 0;
- get_field<tagged<end_ptr<U,T>,own_tag>, other_type>::apply(*tmp).disconnect_one();
- }
-
- friend class end_ptr<U, T>;
-
-protected:
+ }
 
- void connect_one(other_type* ptr)
- {
- if(ptr == other_ptr_) return;
- disconnect();
- other_ptr_ = ptr;
- }
-
- void disconnect_one()
- {
- if(other_ptr_==0) return;
- other_ptr_ = 0;
- }
-};
-
-template <typename T, typename U>
-class bidir {
-public:
- typedef typename tagged_traits<T>::type left_type;
- typedef typename tagged_traits<T>::tag left_tag;
- typedef typename tagged_traits<U>::type right_type;
- typedef typename tagged_traits<U>::tag right_tag;
- typedef end_ptr<T,U> left_end_point;
- typedef end_ptr<U,T> right_end_point;
-
-public:
- template <typename WTag>
- struct end_point {
- typedef typename mpl::if_<is_same<WTag,right_tag>, left_end_point,
- typename mpl::if_<is_same<WTag,left_tag>, right_end_point,
- void>::type
- >::type
- type;
+ void reset()
+ {
+ if (element_ptr_ == 0) return;
+ element_type* tmp = element_ptr_;
+ element_ptr_ = 0;
+ get_field<tagged<end_ptr<T, Entity> , entity_tag> , element_type>::apply(*tmp).disconnect_one();
+ }
+ /**
+ * Effects: assigns p to the stored pointer, and then if the old value of the stored pointer, old_p,
+ * was not equal to nullptr, calls get_deleter()(old_p).
+ * @Postconditions get() == p.
+ */
+ void reset(element_type* ptr)
+ {
+ if (ptr == element_ptr_) return;
+ reset();
+ if (ptr == 0) return;
+ element_ptr_ = ptr;
+ get_field<tagged<end_ptr<T, Entity> , entity_tag> , element_type>::apply(*ptr).connect_one(
+ get_entity());
+ //&get_embeding<entity_type, entity_tag, end_ptr<Entity, T> >::apply(*this));
+ }
+ void swap(end_ptr& other)
+ {
+ T* entity_u = element_ptr_;
+ T* element_u = other.element_ptr_;
+
+ reset(element_u);
+ other.reset(entity_u);
+ }
+ void connect(element_type* ptr) { reset(ptr); }
+ void disconnect() { reset(); }
+
+ friend class end_ptr<T, Entity> ;
+
+ protected:
+
+ entity_type* get_entity()
+ {
+ return entity_ptr_;
+ }
+ void connect_one(element_type* ptr)
+ {
+ if (ptr == element_ptr_) return;
+ reset();
+ element_ptr_ = ptr;
+ }
+
+ void disconnect_one()
+ {
+ element_ptr_ = 0;
+ }
     };
 
- static left_end_point& get_left_end_point(left_type& lptr) {
- return get_field<tagged<left_end_point, right_tag>, left_type>::apply(lptr);
- }
- static right_end_point& get_right_end_point(right_type& lptr) {
- return get_field<tagged<right_end_point, left_tag>, right_type>::apply(lptr);
- }
-
- template <typename WTag>
- static typename enable_if<is_same<WTag,right_tag>, right_type*>::type
- get(left_type& ptr)
+ template <typename T, typename U>
+ class intrinsic
     {
- return get_field<tagged<left_end_point, right_tag>, left_type>::apply(ptr).get();
- }
 
- template <typename WTag>
- static typename enable_if<is_same<WTag,left_tag>, left_type*> ::type
- get(right_type& ptr)
- {
- return get_field<tagged<right_end_point, left_tag>, right_type>::apply(ptr).get();
- }
-
- static void connect(left_type* lptr, right_type* rptr)
- {
- if (lptr!=0) {
- get_left_end_point(*lptr).connect(rptr);
- } else if(rptr!=0) {
- get_right_end_point(*rptr).connect(lptr);
+// typedef typename ::boost::bimaps::tags::support::default_tagged
+// <
+// typename left_set_type::user_type,
+// ::boost::bimaps::relation::member_at::left
+//
+// >::type left_tagged_type;
+//
+// typedef typename ::boost::bimaps::tags::support::default_tagged
+// <
+// typename right_set_type::user_type,
+// ::boost::bimaps::relation::member_at::right
+//
+// >::type right_tagged_type;
+
+ typedef typename detail::left_tagged<T>::type TTag;
+ typedef typename detail::right_tagged<U>::type UTag;
+ public:
+ typedef typename TTag::value_type left_type;
+ typedef typename TTag::tag left_tag;
+ typedef typename UTag::value_type right_type;
+ typedef typename UTag::tag right_tag;
+ typedef end_ptr<TTag, UTag> left_end_point;
+ typedef end_ptr<UTag, TTag> right_end_point;
+
+ public:
+ template <typename WTag>
+ struct end_point
+ {
+ typedef typename mpl::if_<is_same<WTag, right_tag> , left_end_point, typename mpl::if_<
+ is_same<WTag, left_tag> , right_end_point, void>::type>::type type;
+ };
+
+ static left_end_point& get_left_end_point(left_type& lptr)
+ {
+ return get_field<tagged<left_end_point, right_tag> , left_type>::apply(lptr);
+ }
+ static right_end_point& get_right_end_point(right_type& lptr)
+ {
+ return get_field<tagged<right_end_point, left_tag> , right_type>::apply(lptr);
+ }
+
+ template <typename WTag>
+ static typename enable_if<is_same<WTag, right_tag> , right_type*>::type get(left_type& ptr)
+ {
+ return get_field<tagged<left_end_point, right_tag> , left_type>::apply(ptr).get();
+ }
+
+ template <typename WTag>
+ static typename enable_if<is_same<WTag, left_tag> , left_type*>::type get(right_type& ptr)
+ {
+ return get_field<tagged<right_end_point, left_tag> , right_type>::apply(ptr).get();
+ }
+
+ static void connect(left_type* lptr, right_type* rptr)
+ {
+ if (lptr != 0)
+ {
+ get_left_end_point(*lptr).connect(rptr);
         }
- }
+ else if (rptr != 0)
+ {
+ get_right_end_point(*rptr).connect(lptr);
+ }
+ }
 
- template <typename WTag>
- static typename enable_if<is_same<WTag,left_tag>, void>::type
- disconnect(left_type& ptr)
- {
+ static void connect(left_type& lptr, right_type& rptr)
+ {
+ get_left_end_point(lptr).connect(&rptr);
+ }
+
+ template <typename WTag>
+ static typename enable_if<is_same<WTag, left_tag> , void>::type disconnect(left_type& ptr)
+ {
         get_left_end_point(ptr).disconnect();
- }
+ }
 
- template <typename WTag>
- static typename enable_if<is_same<WTag,right_tag>, void> ::type
- disconnect(right_type& ptr)
- {
+ template <typename WTag>
+ static typename enable_if<is_same<WTag, right_tag> , void>::type disconnect(right_type& ptr)
+ {
         get_right_end_point(ptr).disconnect();
- }
+ }
+
+ };
 
-};
-
-} // namespace association
+ } // namespace association
 } // namespace boost
 
 #define BOOST_GET_OBJECT(T, FIELD, VAR) \
@@ -248,6 +328,7 @@
 
 #define BOOST_ASSOCIATION_FIELD_DCL(A,ATAG, B, BTAG, FIELD)\
 namespace boost {\
+namespace association {\
 template <>\
 struct get_field<tagged<association::end_ptr<tagged<A,ATAG>,tagged<B,BTAG> >,BTAG>,A> {\
     static association::end_ptr<tagged<A,ATAG>,tagged<B,BTAG> >& apply(A&v) {\
@@ -255,17 +336,21 @@
     }\
 };\
    \
+}\
+}
+
+#if 0
 template <>\
 struct get_embeding<A,ATAG,association::end_ptr<tagged<A,ATAG>,tagged<B,BTAG> > > {\
     static A& apply(association::end_ptr<tagged<A,ATAG>,tagged<B,BTAG> >&v) {\
         return BOOST_GET_OBJECT(A, FIELD, v);\
     }\
 };\
-}
+
+#endif
 
 #define BOOST_ASSOCIATION_DCL(ASSOC, LEFT, RIGHT) \
 BOOST_ASSOCIATION_FIELD_DCL(ASSOC::left_type, ASSOC::left_tag, ASSOC::right_type, ASSOC::right_tag, RIGHT); \
 BOOST_ASSOCIATION_FIELD_DCL(ASSOC::right_type, ASSOC::right_tag, ASSOC::left_type, ASSOC::left_tag, LEFT)
 
-
 #endif

Modified: sandbox/association/libs/association/test/basic_usage.cpp
==============================================================================
--- sandbox/association/libs/association/test/basic_usage.cpp (original)
+++ sandbox/association/libs/association/test/basic_usage.cpp 2012-05-20 12:41:43 EDT (Sun, 20 May 2012)
@@ -14,6 +14,7 @@
 #include <iostream>
 
 using namespace boost;
+using namespace boost::association;
 
 class CBoy;
 class CGirl;
@@ -21,25 +22,25 @@
 struct boy {};
 struct girl {};
 
-typedef association::bidir<
+typedef association::intrinsic<
     tagged<CBoy, boy>,
- tagged<CGirl, girl>
-> friends;
-
+ tagged<CGirl, girl>
+> Friends;
+
 class CBoy {
 public:
- CBoy() {}
+ CBoy() : m_girlfriend(this) {}
     void GiveGirlfriendFlowers();
     void RecvSlap() {
         std::cout << "boy: ouch!" << '\n';
         m_girlfriend.disconnect();
     }
- friends::end_point<girl>::type m_girlfriend;
+ Friends::end_point<girl>::type m_girlfriend;
 };
 
 class CGirl {
 public:
- CGirl() {
+ CGirl() : m_boyfriend(this) {
     }
     void RecvFlowers() {
         std::cout << "girl: thank you for the flowers!" << '\n';
@@ -55,19 +56,19 @@
     void break_boyfriend() {
         std::cout << "girl: we broke up." << '\n';
     }
- friends::end_point<boy>::type m_boyfriend;
+ Friends::end_point<boy>::type m_boyfriend;
 };
 
 void CBoy::GiveGirlfriendFlowers() {
     //~ if(m_girlfriend.get())
         //~ m_girlfriend->RecvFlowers();
-
- if (friends::get<girl>(*this))
- friends::get<girl>(*this)->RecvFlowers();
+
+ if (Friends::get<girl>(*this))
+ Friends::get<girl>(*this)->RecvFlowers();
 
 }
 
-BOOST_ASSOCIATION_DCL(friends, m_boyfriend, m_girlfriend);
+BOOST_ASSOCIATION_DCL(Friends, m_boyfriend, m_girlfriend);
 
 
 int main()
@@ -76,14 +77,14 @@
     CGirl Sally;
 
     //~ Henry.m_girlfriend.connect(&Sally);
- friends::connect(&Henry,&Sally);
- friends::disconnect<boy>(Henry);
- friends::connect(&Henry,&Sally);
- friends::disconnect<girl>(Sally);
- friends::connect(&Henry,&Sally);
+ Friends::connect(Henry,Sally);
+ Friends::disconnect<boy>(Henry);
+ Friends::connect(Henry,Sally);
+ Friends::disconnect<girl>(Sally);
+ Friends::connect(Henry,Sally);
     Henry.GiveGirlfriendFlowers();
     //~ Sally.SlapBoyfriend();
- friends::get<girl>(Henry)->SlapBoyfriend();
+ Friends::get<girl>(Henry)->SlapBoyfriend();
 
     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