1 #ifndef BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP
2 #define BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP
3 
4 // MS compatible compilers support #pragma once
5 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
6 # pragma once
7 #endif
8 
9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
10 // helper_collection.hpp: archive support for run-time helpers
11 
12 // (C) Copyright 2002-2008 Robert Ramey and Joaquin M Lopez Munoz
13 // Use, modification and distribution is subject to the Boost Software
14 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
15 // http://www.boost.org/LICENSE_1_0.txt)
16 
17 //  See http://www.boost.org for updates, documentation, and revision history.
18 
19 #include <cstddef> // NULL
20 #include <vector>
21 #include <utility>
22 #include <memory>
23 #include <algorithm>
24 
25 #include <boost/config.hpp>
26 
27 #include <boost/smart_ptr/shared_ptr.hpp>
28 #include <boost/smart_ptr/make_shared.hpp>
29 
30 namespace boost {
31 
32 namespace archive {
33 namespace detail {
34 
35 class helper_collection
36 {
37     helper_collection(const helper_collection&);              // non-copyable
38     helper_collection& operator = (const helper_collection&); // non-copyable
39 
40     // note: we dont' actually "share" the function object pointer
41     // we only use shared_ptr to make sure that it get's deleted
42 
43     typedef std::pair<
44         const void *,
45         boost::shared_ptr<void>
46     > helper_value_type;
47     template<class T>
make_helper_ptr()48     boost::shared_ptr<void> make_helper_ptr(){
49         // use boost::shared_ptr rather than std::shared_ptr to maintain
50         // c++03 compatibility
51         return boost::make_shared<T>();
52     }
53 
54     typedef std::vector<helper_value_type> collection;
55     collection m_collection;
56 
57     struct predicate {
58         BOOST_DELETED_FUNCTION(predicate & operator=(const predicate & rhs))
59     public:
60         const void * const m_ti;
operator ()boost::archive::detail::helper_collection::predicate61         bool operator()(helper_value_type const &rhs) const {
62             return m_ti == rhs.first;
63         }
predicateboost::archive::detail::helper_collection::predicate64         predicate(const void * ti) :
65             m_ti(ti)
66         {}
67     };
68 protected:
helper_collection()69     helper_collection(){}
~helper_collection()70     ~helper_collection(){}
71 public:
72     template<typename Helper>
find_helper(void * const id=0)73     Helper& find_helper(void * const id = 0) {
74         collection::const_iterator it =
75             std::find_if(
76                 m_collection.begin(),
77                 m_collection.end(),
78                 predicate(id)
79             );
80 
81         void * rval = 0;
82         if(it == m_collection.end()){
83             m_collection.push_back(
84                 std::make_pair(id, make_helper_ptr<Helper>())
85             );
86             rval = m_collection.back().second.get();
87         }
88         else{
89             rval = it->second.get();
90         }
91         return *static_cast<Helper *>(rval);
92     }
93 };
94 
95 } // namespace detail
96 } // namespace serialization
97 } // namespace boost
98 
99 #endif // BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP
100