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