1 //
2 // Copyright (c) 2006-2017 Benjamin Kaufmann
3 //
4 // This file is part of Clasp. See http://www.cs.uni-potsdam.de/clasp/
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 // IN THE SOFTWARE.
23 //
24 
25 #ifndef CLASP_POD_VECTOR_H_INCLUDED
26 #define CLASP_POD_VECTOR_H_INCLUDED
27 #include <clasp/config.h>
28 #include <clasp/util/pod_vector.h>
29 #include <vector>
30 #include <cassert>
31 
32 namespace Clasp {
33 
34 #if CLASP_USE_STD_VECTOR
35 	template <class Type>
36 	struct PodVector {
37 		typedef std::vector<Type> type;
destructPodVector38 		static void destruct(type& t) {t.clear();}
39 	};
40 #else
41 	//! Type selector for a vector type optimized for storing POD-types.
42 	template <class Type>
43 	struct PodVector {
44 		typedef bk_lib::pod_vector<Type> type;
45 		static void destruct(type& t) {
46 			for (typename type::size_type i = 0, end = t.size(); i != end; ++i) {
47 				t[i].~Type();
48 			}
49 			t.clear();
50 		}
51 	};
52 #endif
toU32(std::size_t x)53 inline uint32 toU32(std::size_t x) {
54 	assert(sizeof(std::size_t) <= sizeof(uint32) || x <= static_cast<uint64>(UINT32_MAX));
55 	return static_cast<uint32>(x);
56 }
57 template <class T>
sizeVec(const T & c)58 inline uint32 sizeVec(const T& c) { return toU32(c.size()); }
59 template <class T>
releaseVec(T & t)60 inline void releaseVec(T& t) {
61 	T().swap(t);
62 }
63 
64 template <class T>
shrinkVecTo(T & t,typename T::size_type j)65 inline void shrinkVecTo(T& t, typename T::size_type j) {
66 	t.erase(t.begin()+j, t.end());
67 }
68 
69 template <class T>
70 inline void growVecTo(T& vec, typename T::size_type j, const typename T::value_type& val = typename T::value_type()) {
71 	if (vec.size() < j) {
72 		if (vec.capacity() < j) { vec.reserve(j + j / 2); }
73 		vec.resize(j, val);
74 	}
75 }
76 
77 template <class T>
moveDown(T & t,typename T::size_type from,typename T::size_type to)78 void moveDown(T& t, typename T::size_type from, typename T::size_type to) {
79 	for (typename T::size_type end = t.size(); from != end;) {
80 		t[to++] = t[from++];
81 	}
82 	shrinkVecTo(t, to);
83 }
84 //! A simple vector-based fifo queue for storing POD-types.
85 template <class T>
86 struct PodQueue {
87 	typedef typename PodVector<T>::type  vec_type;
88 	typedef typename vec_type::size_type size_type;
PodQueuePodQueue89 	PodQueue() : qFront(0) {}
emptyPodQueue90 	bool      empty() const   { return qFront == vec.size(); }
sizePodQueue91 	size_type size()  const   { return vec.size() - qFront; }
frontPodQueue92 	const T&  front() const   { return vec[qFront]; }
backPodQueue93 	const T&  back()  const   { return vec.back(); }
frontPodQueue94 	T&        front()         { return vec[qFront]; }
backPodQueue95 	T&        back()          { return vec.back(); }
pushPodQueue96 	void      push(const T& x){ vec.push_back(x);  }
popPodQueue97 	void      pop()           { ++qFront; }
pop_retPodQueue98 	T         pop_ret()       { return vec[qFront++]; }
clearPodQueue99 	void      clear()         { vec.clear(); qFront = 0; }
rewindPodQueue100 	void      rewind()        { qFront = 0; }
101 	vec_type  vec;    // the underlying vector holding the items
102 	size_type qFront; // front position
103 };
104 
105 }
106 
107 #endif
108