]> git.lyx.org Git - lyx.git/blob - src/ShareContainer.h
Alfredo's second patch
[lyx.git] / src / ShareContainer.h
1 // -*- C++ -*-
2
3 #ifndef SHARECONTAINER_H
4 #define SHARECONTAINER_H
5
6 #include <boost/utility.hpp>
7 #include <boost/shared_ptr.hpp>
8
9 #include <vector>
10 #include <algorithm>
11 #include <functional>
12
13 /// Share objects between several users.
14 /**
15    This class can be used to reduce memory consuption when you have a lot
16    of equal objects used all over your code.
17
18    \author Lars Gullik Bjønnes
19 */
20 template<class Share>
21 class ShareContainer : boost::noncopyable {
22 public:
23         ///
24         typedef std::vector<boost::shared_ptr<Share> > Params;
25         ///
26         typedef typename Params::value_type value_type;
27         /// Return a shared_ptr that points to a element equal to ps.
28         value_type
29         get(Share const & ps) const {
30                 // First see if we already have this ps in the container
31                 typename Params::iterator it = std::find_if(params.begin(),
32                                                             params.end(),
33                                                             isEqual(ps));
34                 value_type tmp;
35                 if (it == params.end()) {
36                         // ok we don't have it so we should
37                         // insert it.
38                         tmp.reset(new Share(ps));
39                         params.push_back(tmp);
40                         // We clean here. This can cause us to have
41                         // some (one) unique elemements some times
42                         // but we should gain a lot in speed.
43                         clean();
44                 } else {
45                         // yes we have it already
46                         tmp = *it;
47                         // move it forward - optimization
48                         // makes the next find faster.
49                         if (it != params.begin())
50                                 std::swap(*it, *(it - 1));
51                 }
52                 return tmp;
53         }
54 private:
55         /// A functor returning true if the elements are equal.
56         struct isEqual {
57                 isEqual(Share const & s) : p_(s) {}
58                 bool operator()(value_type const & p1) const {
59                         return *p1.get() == p_;
60                 }
61         private:
62                 Share const & p_;
63         };
64         /// A functor returning true if the element is unique.
65         struct isUnique {
66                 bool operator()(value_type const & p) const {
67                         return p.unique();
68                 }
69         };
70
71         /** Remove all unique items.
72             This removes all elements from params that is only referenced
73             from the private container. This can be considered a memory
74             optimizaton.
75         */
76         void clean() const {
77                 typename Params::iterator it = std::remove_if(params.begin(),
78                                                               params.end(),
79                                                               isUnique());
80                 params.erase(it, params.end());
81         }
82
83         /// The actual container.
84         mutable Params params;
85 };
86 #endif