DetectorGraph  2.0
sequencecontainer-lite.hpp
Go to the documentation of this file.
1 // Copyright 2017 Nest Labs, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef DETECTORGRAPH_INCLUDE_SEQUENCECONTAINER_LITE_HPP_
16 #define DETECTORGRAPH_INCLUDE_SEQUENCECONTAINER_LITE_HPP_
17 
18 #include "dgassert.hpp"
19 #include "dgstdincludes.hpp"
20 
21 namespace DetectorGraph
22 {
23 
24 // Used for actually storing a number of stuff - stuff can be anything pretty
25 // much. This may be nice for storing TopicStates as it doesn't impose default
26 // constructibility (which ends up adding cost for nothing).
27 // But god knows how safe this is.
28 template <typename T, unsigned N>
30 {
31 #if defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_STATIC_ASSERTS)
32  static_assert(sizeof(T) % sizeof(uint32_t) == 0, "T must be uint32_t aligned");
33  static_assert(std::is_copy_constructible<T>::value, "Generic SequenceContainer copy-constructs T");
34 #endif
35 public:
36  SequenceContainer() : mNumElements()
37  {
38  }
39 
41  {
42  clear();
43  }
44 
45  void push_back(const T& v)
46  {
47  DG_ASSERT(mNumElements < N);
48 
49  uint8_t* storagePtr = &(mStorage[mNumElements * sizeof(T)]);
50  T* newElement = new(storagePtr) T(v); // Copy constructor
51  (void)newElement; // Otherwise it's unused in release builds.
52  DG_ASSERT((void*)newElement == (void*)&(Items()[mNumElements]));
53  mNumElements++;
54  }
55 
56  T (& Items())[N]
57  {
58  return reinterpret_cast<T(&)[N]>(mStorage);
59  }
60 
61  const T (& Items() const)[N]
62  {
63  return reinterpret_cast<const T(&)[N]>(mStorage);
64  }
65 
66  T& operator [](unsigned idx) {
67  DG_ASSERT(idx < N);
68  return Items()[idx];
69  }
70 
71  const T& operator [](unsigned idx) const {
72  DG_ASSERT(idx < N);
73  return Items()[idx];
74  }
75 
76  const size_t size() const
77  {
78  return mNumElements;
79  }
80 
81  void clear()
82  {
83  // TODO(DGRAPH-35): Both implementations below work fine. Sometimes the
84  // iterator generates smaller code, sometimes not. Sort this out.
85  // for (iterator it = begin(); it != end(); ++it)
86  // {
87  // it->~T();
88  // }
89  for (unsigned idx = 0; idx < mNumElements; ++idx)
90  {
91  Items()[idx].~T();
92  }
93  mNumElements = 0;
94  }
95 
96  const T& back() const
97  {
98  return Items()[mNumElements-1];
99  }
100 
101 
102  typedef T value_type;
103  enum { max_size = N };
104  typedef T * iterator;
105  typedef const T * const_iterator;
106  const_iterator begin() const { return &(Items()[0]); }
107  const_iterator end() const { return &(Items()[mNumElements]); }
108  iterator begin() { return &(Items()[0]); }
109  iterator end() { return &(Items()[mNumElements]); }
110  // Or if that makes anyone nervous:
111  // const_iterator end() const { return &(Items()[0]) + mNumElements; }
112 private:
113  uint8_t mStorage[N * sizeof(T)];
114  unsigned mNumElements;
115 };
116 
117 
118 // // This may be useful for storing single TopicStates (clobbering) but keeping
119 // // the same interface.
120 // template <typename T>
121 // class ClobberingStorage<T, 1>
122 // {
123 // static_assert(std::is_default_constructible<T>::value, "ClobberingStorage requires default constructor");
124 // static_assert(std::is_copy_constructible<T>::value, "ClobberingStorage requires copying");
125 // public:
126 // ClobberingStorage()
127 // {
128 // }
129 
130 // void push_back(const T& v)
131 // {
132 // mStorage[0] = v;
133 // }
134 
135 // T (& Items())[1]
136 // {
137 // return reinterpret_cast<T(&)[1]>(mStorage);
138 // }
139 
140 // const size_t GetSize() const
141 // {
142 // return 1;
143 // }
144 // private:
145 // T mStorage[1];
146 // };
147 
148 } // namespace DetectorGraph
149 
150 #endif // DETECTORGRAPH_INCLUDE_SEQUENCECONTAINER_LITE_HPP_
#define DG_ASSERT(condition)
Definition: dgassert.hpp:20