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