symbolic
unique_vector.h
1 
10 #ifndef SYMBOLIC_UTILS_UNIQUE_VECTOR_H_
11 #define SYMBOLIC_UTILS_UNIQUE_VECTOR_H_
12 
13 #include <algorithm> // std::is_sorted, std::lower_bound, std::sort
14 #include <cassert> // assert
15 #include <vector> // std::vector
16 
17 namespace symbolic {
18 
22 template <typename T>
23 class UniqueVector : public std::vector<T> {
24  public:
25  UniqueVector() = default;
26 
27  UniqueVector(std::initializer_list<T> l);
28 
32  template<typename T_query>
33  bool contains(const T_query& val) const;
34 
39  template<typename T_query>
40  bool insert(const T_query& val);
41  bool insert(T&& val);
42 
47  template <class... Args>
48  bool emplace(Args&&... args) {
49  return insert(T(args...));
50  }
51 
56  template<typename T_query>
57  bool erase(const T_query& val);
58 
59  private:
60  using Base = std::vector<T>;
61 };
62 
63 template<typename T>
64 UniqueVector<T>::UniqueVector(std::initializer_list<T> l) : Base(l) {
65  std::sort(Base::begin(), Base::end());
66  auto last = std::unique(Base::begin(), Base::end());
67  Base::erase(last, Base::end());
68  assert(std::is_sorted(Base::begin(), Base::end()));
69 }
70 
71 template <typename T>
72 template<typename T_query>
73 bool UniqueVector<T>::contains(const T_query& val) const {
74  assert(std::is_sorted(Base::begin(), Base::end()));
75  const auto it = std::lower_bound(Base::begin(), Base::end(), val);
76  return it != Base::end() && *it == val;
77 }
78 
79 template <typename T>
80 template<typename T_query>
81 bool UniqueVector<T>::insert(const T_query& val) {
82  assert(std::is_sorted(Base::begin(), Base::end()));
83  const auto it = std::lower_bound(Base::begin(), Base::end(), val);
84  if (it != Base::end() && *it == val) return false;
85 
86  Base::emplace(it, val);
87  return true;
88 }
89 
90 template <typename T>
91 bool UniqueVector<T>::insert(T&& val) {
92  assert(std::is_sorted(Base::begin(), Base::end()));
93  const auto it = std::lower_bound(Base::begin(), Base::end(), val);
94  if (it != Base::end() && *it == val) return false;
95 
96  Base::insert(it, std::move(val));
97  return true;
98 }
99 
100 template <typename T>
101 template<typename T_query>
102 bool UniqueVector<T>::erase(const T_query& val) {
103  assert(std::is_sorted(Base::begin(), Base::end()));
104  const auto it = std::lower_bound(Base::begin(), Base::end(), val);
105  if (it == Base::end() || *it != val) return false;
106  Base::erase(it);
107  return true;
108 }
109 
110 } // namespace symbolic
111 
112 #endif // SYMBOLIC_UTILS_UNIQUE_VECTOR_H_
symbolic::UniqueVector::erase
bool erase(const T_query &val)
Definition: unique_vector.h:102
symbolic::UniqueVector::emplace
bool emplace(Args &&... args)
Definition: unique_vector.h:48
symbolic
Definition: action.cc:329
symbolic::UniqueVector::insert
bool insert(const T_query &val)
Definition: unique_vector.h:81
symbolic::UniqueVector::contains
bool contains(const T_query &val) const
Definition: unique_vector.h:73
symbolic::UniqueVector
Definition: unique_vector.h:23