MPD  0.20.6
Cancellable.hxx
Go to the documentation of this file.
1 /*
2  * Copyright 2003-2017 The Music Player Daemon Project
3  * http://www.musicpd.org
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef MPD_NFS_CANCELLABLE_HXX
21 #define MPD_NFS_CANCELLABLE_HXX
22 
23 #include "Compiler.h"
24 
25 #include <boost/intrusive/list.hpp>
26 
27 #include <algorithm>
28 
29 #include <assert.h>
30 
31 template<typename T>
33  : public boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {
34 public:
35  typedef T *pointer_type;
36  typedef T &reference_type;
37  typedef const T &const_reference_type;
38 
39 private:
40  pointer_type p;
41 
42 public:
43  explicit CancellablePointer(reference_type _p):p(&_p) {}
44 
45  CancellablePointer(const CancellablePointer &) = delete;
46 
47  constexpr bool IsCancelled() const {
48  return p == nullptr;
49  }
50 
51  void Cancel() {
52  assert(!IsCancelled());
53 
54  p = nullptr;
55  }
56 
57  reference_type Get() {
58  assert(p != nullptr);
59 
60  return *p;
61  }
62 
63  constexpr bool Is(const_reference_type other) const {
64  return p == &other;
65  }
66 };
67 
68 template<typename T, typename CT=CancellablePointer<T>>
70 public:
71  typedef typename CT::reference_type reference_type;
72  typedef typename CT::const_reference_type const_reference_type;
73 
74 private:
75  typedef boost::intrusive::list<CT,
76  boost::intrusive::constant_time_size<false>> List;
77  typedef typename List::iterator iterator;
78  typedef typename List::const_iterator const_iterator;
79  List list;
80 
81  class MatchPointer {
82  const_reference_type p;
83 
84  public:
85  explicit constexpr MatchPointer(const_reference_type _p)
86  :p(_p) {}
87 
88  constexpr bool operator()(const CT &a) const {
89  return a.Is(p);
90  }
91  };
92 
93  gcc_pure
94  iterator Find(reference_type p) {
95  return std::find_if(list.begin(), list.end(), MatchPointer(p));
96  }
97 
98  gcc_pure
99  const_iterator Find(const_reference_type p) const {
100  return std::find_if(list.begin(), list.end(), MatchPointer(p));
101  }
102 
103  gcc_pure
104  iterator Find(CT &c) {
105  return list.iterator_to(c);
106  }
107 
108  gcc_pure
109  const_iterator Find(const CT &c) const {
110  return list.iterator_to(c);
111  }
112 
113 public:
114 #ifndef NDEBUG
115  gcc_pure
116  bool IsEmpty() const {
117  for (const auto &c : list)
118  if (!c.IsCancelled())
119  return false;
120 
121  return true;
122  }
123 #endif
124 
125  gcc_pure
126  bool Contains(const_reference_type p) const {
127  return Find(p) != list.end();
128  }
129 
130  template<typename... Args>
131  CT &Add(reference_type p, Args&&... args) {
132  assert(Find(p) == list.end());
133 
134  CT *c = new CT(p, std::forward<Args>(args)...);
135  list.push_back(*c);
136  return *c;
137  }
138 
139  void Remove(CT &ct) {
140  auto i = Find(ct);
141  assert(i != list.end());
142 
143  list.erase(i);
144  delete &ct;
145  }
146 
147  void Cancel(reference_type p) {
148  auto i = Find(p);
149  assert(i != list.end());
150 
151  i->Cancel();
152  }
153 
154  CT &Get(reference_type p) {
155  auto i = Find(p);
156  assert(i != list.end());
157 
158  return *i;
159  }
160 
161  template<typename F>
162  void ForEach(F &&f) {
163  for (CT &i : list)
164  f(i);
165  }
166 };
167 
168 #endif
const T & const_reference_type
Definition: Cancellable.hxx:37
void ForEach(F &&f)
reference_type Get()
Definition: Cancellable.hxx:57
CT::reference_type reference_type
Definition: Cancellable.hxx:71
gcc_pure bool IsEmpty() const
constexpr bool Is(const_reference_type other) const
Definition: Cancellable.hxx:63
void Cancel(reference_type p)
CancellablePointer(reference_type _p)
Definition: Cancellable.hxx:43
constexpr bool IsCancelled() const
Definition: Cancellable.hxx:47
CT & Get(reference_type p)
gcc_pure bool Contains(const_reference_type p) const
#define gcc_pure
Definition: Compiler.h:116
void Remove(CT &ct)
CT & Add(reference_type p, Args &&...args)
CT::const_reference_type const_reference_type
Definition: Cancellable.hxx:72