// STLDeleteContainerPointers() // For a range within a container of pointers, calls delete // (non-array version) on these pointers. // NOTE: for these three functions, we could just implement a DeleteObject // functor and then call for_each() on the range and functor, but this // requires us to pull in all of algorithm.h, which seems expensive. // For hash_[multi]set, it is important that this deletes behind the iterator // because the hash_set may call the hash function on the iterator when it is // advanced, which could result in the hash function trying to deference a // stale pointer. template <class ForwardIterator> void STLDeleteContainerPointers(ForwardIterator begin,
ForwardIterator end) { while (begin != end) {
ForwardIterator temp = begin;
++begin; delete *temp;
}
}
// STLDeleteElements() deletes all the elements in an STL container and clears // the container. This function is suitable for use with a vector, set, // hash_set, or any other STL container which defines sensible begin(), end(), // and clear() methods. // // If container is null, this function is a no-op. // // As an alternative to calling STLDeleteElements() directly, consider // using a container of std::unique_ptr, which ensures that your container's // elements are deleted when the container goes out of scope. template <class T> void STLDeleteElements(T *container) { if (container != nullptr) {
STLDeleteContainerPointers(container->begin(), container->end());
container->clear();
}
}
// Given an STL container consisting of (key, value) pairs, STLDeleteValues // deletes all the "value" components and clears the container. Does nothing // in the case it's given a null pointer. template <class T> void STLDeleteValues(T *v) { if (v != nullptr) { for (typename T::iterator i = v->begin(); i != v->end(); ++i) { delete i->second;
}
v->clear();
}
}
// Deleter using free() for use with std::unique_ptr<>. See also UniqueCPtr<> below. struct FreeDelete { // NOTE: Deleting a const object is valid but free() takes a non-const pointer. voidoperator()(constvoid* ptr) const {
free(const_cast<void*>(ptr));
}
};
// Alias for std::unique_ptr<> that uses the C function free() to delete objects. template <typename T> using UniqueCPtr = std::unique_ptr<T, FreeDelete>;
// Find index of the first element with the specified value known to be in the container. template <typename Container, typename T>
size_t IndexOfElement(const Container& container, const T& value) { auto it = std::find(container.begin(), container.end(), value);
DCHECK(it != container.end()); // Must exist. return std::distance(container.begin(), it);
}
// Remove the first element with the specified value known to be in the container. template <typename Container, typename T> void RemoveElement(Container& container, const T& value) { auto it = std::find(container.begin(), container.end(), value);
DCHECK(it != container.end()); // Must exist.
container.erase(it);
}
// Replace the first element with the specified old_value known to be in the container. template <typename Container, typename T> void ReplaceElement(Container& container, const T& old_value, const T& new_value) { auto it = std::find(container.begin(), container.end(), old_value);
DCHECK(it != container.end()); // Must exist.
*it = new_value;
}
// Search for an element with the specified value and return true if it was found, false otherwise. template <typename Container, typename T> bool ContainsElement(const Container& container, const T& value, size_t start_pos = 0u) {
DCHECK_LE(start_pos, container.size()); auto start = container.begin();
std::advance(start, start_pos); auto it = std::find(start, container.end(), value); return it != container.end();
}
// 32-bit FNV-1a hash function suitable for std::unordered_map. // It can be used with any container which works with range-based for loop. // See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function template <typename Vector> struct FNVHash {
size_t operator()(const Vector& vector) const {
uint32_t hash = 2166136261u; for (constauto& value : vector) {
hash = (hash ^ value) * 16777619u;
} return hash;
}
};
// Returns a copy of the passed vector that doesn't memory-own its entries. template <typename T> inline std::vector<T*> MakeNonOwningPointerVector(const std::vector<std::unique_ptr<T>>& src) {
std::vector<T*> result;
result.reserve(src.size()); for (const std::unique_ptr<T>& t : src) {
result.push_back(t.get());
} return result;
}
template <typename IterLeft, typename IterRight> class ZipLeftIter { public: using iterator_category = std::forward_iterator_tag; using value_type = std::pair<typename IterLeft::value_type, typename IterRight::value_type>; using difference_type = ptrdiff_t; using pointer = void; using reference = void;
class CountIter { public: using iterator_category = std::forward_iterator_tag; using value_type = size_t; using difference_type = size_t; using pointer = void; using reference = void;
// Make an iteration range that returns a pair of the element and the index of the element. template <typename Container> inlineauto ZipCount(Container&& c) -> IterationRange<ZipLeftIter<decltype(c.begin()), CountIter>>{
static_assert(std::is_same_v<decltype(c.begin()), decltype(c.end())>, "Different iterator types"); return IterationRange(ZipLeftIter(c.begin(), CountIter(0)), ZipLeftIter(c.end(), CountIter(-1)));
}
// Make an iteration range that returns a pair of the outputs of two iterators. Stops when the first // (left) one is exhausted. The left iterator must be at least as long as the right one. template <typename IterLeft, typename IterRight> inline IterationRange<ZipLeftIter<IterLeft, IterRight>> ZipLeft(
IterationRange<IterLeft> iter_left, IterationRange<IterRight> iter_right) { return IterationRange(ZipLeftIter(iter_left.begin(), iter_right.begin()),
ZipLeftIter(iter_left.end(), iter_right.end()));
}
// Helper struct for iterating a split-string without allocation. struct SplitStringIter { public: using iterator_category = std::forward_iterator_tag; using value_type = std::string_view; using difference_type = ptrdiff_t; using pointer = void; using reference = void;
// Direct iterator constructor. The iteration state is only the current index. // We use that with the split char and the full string to get the current and // next segment.
SplitStringIter(size_t index, char split, std::string_view sv)
: cur_index_(index), split_on_(split), sv_(sv) {}
SplitStringIter(const SplitStringIter&) = default;
SplitStringIter(SplitStringIter&&) = default;
SplitStringIter& operator=(SplitStringIter&&) = default;
SplitStringIter& operator=(const SplitStringIter&) = default;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.