ED247 Library  VA2.3.0
Implementation of ED247-A standard
ed247_client_list.h
1 //
2 // Handle C-list (ed247.h)
3 // This classes contain both the list and its 'iterator'
4 //
5 // * client_list<T> inherit from an emty C struct (template class CBaseList)
6 // * client_list<T> is implemented by templace class client_list_container wich support various containers (vectors, maps, ...)
7 // * The underlayed container must hold std::shared_ptr<T>
8 //
9 #ifndef ED247_CLIENT_ITERATOR
10 #define ED247_CLIENT_ITERATOR
11 #include <memory>
12 #include <algorithm>
13 
14 
15 namespace ed247 {
16 
17  // Define iterator_shared_get() that call shared_ptr::get() on the provided iterator.
18  // Support vector-type and map-type iterators.
19  template <typename>
20  struct is_pair : std::false_type { };
21 
22  template <typename T, typename U>
23  struct is_pair<std::pair<T, U>> : std::true_type { };
24 
25  template<class Return, class Iterator, typename std::enable_if<!is_pair<typename Iterator::value_type>::value, bool>::type = true>
26  Return iterator_shared_get(Iterator& itr) {
27  return itr->get();
28  }
29  template<class Return, class Iterator, typename std::enable_if<is_pair<typename Iterator::value_type>::value, bool>::type = true>
30  Return iterator_shared_get(Iterator& itr) {
31  return itr->second.get();
32  }
33 
34  enum class ContextOwned { True, False };
35 
36  template <class CBaseList, typename T>
37  struct client_list : public CBaseList {
38  typedef T value_t;
39  typedef std::shared_ptr<T> container_value_t;
40 
41  virtual ~client_list() {}
42 
43  // Return true if this client_list is owned by ed247::Context. (i.e. shall not be free)
44  virtual bool is_context_owned() = 0;
45 
46  virtual uint32_t size() const = 0;
47 
48  virtual T* get_current() = 0;
49  virtual T* get_next() = 0; // Looping get: will return begin() after end().
50  virtual void reset_iterator() = 0;
51 
52  virtual void free() = 0;
53  };
54 
55  template <class CBaseList, typename T, class Container, ContextOwned context_owned = ContextOwned::False>
56  struct client_list_container : public client_list<CBaseList, T> {
57  typedef typename Container::iterator iterator_t;
58 
59  // Initialize iterator by wrapping provided container (container will not be freed)
60  static client_list_container* wrap(Container& container) {
61  return new client_list_container(&container, false);
62  }
63 
64  // Initialize iterator by copying provided container (the copy will be freed)
65  static client_list_container* copy(const Container& container) {
66  return new client_list_container(new Container(container), true);
67  }
68 
69  virtual bool is_context_owned() {
70  return context_owned == ContextOwned::True;
71  }
72 
73  uint32_t size() const override {
74  return _container->size();
75  }
76 
77  // Delete container if we are the owner
78  virtual void free() override {
79  if (_container && _container_owner) delete _container;
80  _container = nullptr;
81  }
82 
84  free();
85  }
86 
87  void reset_iterator() override {
88  _iterator = _container->end();
89  }
90 
91  T* get_current() override {
92  if (!_container) return nullptr;
93  if (_iterator == _container->end()) return nullptr;
94  return iterator_shared_get<T*>(_iterator);
95  }
96 
97  T* get_next() override {
98  if (!_container) return nullptr;
99  if (_iterator == _container->end()) {
100  _iterator = _container->begin();
101  } else {
102  _iterator++;
103  }
104  return get_current();
105  }
106 
107  protected:
108  client_list_container(Container* container, bool container_owner) :
109  _container(container), _container_owner(container_owner) {
110  _iterator = _container->end();
111  }
112 
113  Container* _container;
114  iterator_t _iterator;
115  bool _container_owner;
116  };
117 
118 }
119 
120 #endif
Definition: ed247_client_list.h:56
Definition: ed247_client_list.h:37
Definition: ed247_channel.cpp:37
Definition: ed247_client_list.h:20