1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard
5*3f982cf4SFabien Sanglard #ifndef UTIL_STD_UTIL_H_
6*3f982cf4SFabien Sanglard #define UTIL_STD_UTIL_H_
7*3f982cf4SFabien Sanglard
8*3f982cf4SFabien Sanglard #include <algorithm>
9*3f982cf4SFabien Sanglard #include <map>
10*3f982cf4SFabien Sanglard #include <string>
11*3f982cf4SFabien Sanglard #include <utility>
12*3f982cf4SFabien Sanglard #include <vector>
13*3f982cf4SFabien Sanglard
14*3f982cf4SFabien Sanglard // TODO: This header is included in the openscreen discovery public headers (dns_sd_instance.h),
15*3f982cf4SFabien Sanglard // which exposes this abseil header. Need to figure out a way to hide it.
16*3f982cf4SFabien Sanglard #if 0
17*3f982cf4SFabien Sanglard #include "absl/algorithm/container.h"
18*3f982cf4SFabien Sanglard #endif
19*3f982cf4SFabien Sanglard #include "util/stringprintf.h"
20*3f982cf4SFabien Sanglard
21*3f982cf4SFabien Sanglard namespace openscreen {
22*3f982cf4SFabien Sanglard
23*3f982cf4SFabien Sanglard template <typename T, size_t N>
countof(T (& array)[N])24*3f982cf4SFabien Sanglard constexpr size_t countof(T (&array)[N]) {
25*3f982cf4SFabien Sanglard return N;
26*3f982cf4SFabien Sanglard }
27*3f982cf4SFabien Sanglard
28*3f982cf4SFabien Sanglard // std::basic_string::data() has no mutable overload prior to C++17 [1].
29*3f982cf4SFabien Sanglard // Hence this overload is provided.
30*3f982cf4SFabien Sanglard // Note: str[0] is safe even for empty strings, as they are guaranteed to be
31*3f982cf4SFabien Sanglard // null-terminated [2].
32*3f982cf4SFabien Sanglard //
33*3f982cf4SFabien Sanglard // [1] http://en.cppreference.com/w/cpp/string/basic_string/data
34*3f982cf4SFabien Sanglard // [2] http://en.cppreference.com/w/cpp/string/basic_string/operator_at
35*3f982cf4SFabien Sanglard template <typename CharT, typename Traits, typename Allocator>
data(std::basic_string<CharT,Traits,Allocator> & str)36*3f982cf4SFabien Sanglard CharT* data(std::basic_string<CharT, Traits, Allocator>& str) {
37*3f982cf4SFabien Sanglard return std::addressof(str[0]);
38*3f982cf4SFabien Sanglard }
39*3f982cf4SFabien Sanglard
40*3f982cf4SFabien Sanglard std::string Join(const std::vector<std::string>& strings,
41*3f982cf4SFabien Sanglard const char* delimiter);
42*3f982cf4SFabien Sanglard
43*3f982cf4SFabien Sanglard template <typename Key, typename Value>
RemoveValueFromMap(std::map<Key,Value * > * map,Value * value)44*3f982cf4SFabien Sanglard void RemoveValueFromMap(std::map<Key, Value*>* map, Value* value) {
45*3f982cf4SFabien Sanglard for (auto it = map->begin(); it != map->end();) {
46*3f982cf4SFabien Sanglard if (it->second == value) {
47*3f982cf4SFabien Sanglard it = map->erase(it);
48*3f982cf4SFabien Sanglard } else {
49*3f982cf4SFabien Sanglard ++it;
50*3f982cf4SFabien Sanglard }
51*3f982cf4SFabien Sanglard }
52*3f982cf4SFabien Sanglard }
53*3f982cf4SFabien Sanglard
54*3f982cf4SFabien Sanglard #if 0
55*3f982cf4SFabien Sanglard template <typename ForwardIteratingContainer>
56*3f982cf4SFabien Sanglard bool AreElementsSortedAndUnique(const ForwardIteratingContainer& c) {
57*3f982cf4SFabien Sanglard return absl::c_is_sorted(c) && (absl::c_adjacent_find(c) == c.end());
58*3f982cf4SFabien Sanglard }
59*3f982cf4SFabien Sanglard #endif
60*3f982cf4SFabien Sanglard
61*3f982cf4SFabien Sanglard template <typename RandomAccessContainer>
SortAndDedupeElements(RandomAccessContainer * c)62*3f982cf4SFabien Sanglard void SortAndDedupeElements(RandomAccessContainer* c) {
63*3f982cf4SFabien Sanglard std::sort(c->begin(), c->end());
64*3f982cf4SFabien Sanglard const auto new_end = std::unique(c->begin(), c->end());
65*3f982cf4SFabien Sanglard c->erase(new_end, c->end());
66*3f982cf4SFabien Sanglard }
67*3f982cf4SFabien Sanglard
68*3f982cf4SFabien Sanglard // Append the provided elements together into a single vector. This can be
69*3f982cf4SFabien Sanglard // useful when creating a vector of variadic templates in the ctor.
70*3f982cf4SFabien Sanglard //
71*3f982cf4SFabien Sanglard // This is the base case for the recursion
72*3f982cf4SFabien Sanglard template <typename T>
Append(std::vector<T> && so_far)73*3f982cf4SFabien Sanglard std::vector<T>&& Append(std::vector<T>&& so_far) {
74*3f982cf4SFabien Sanglard return std::move(so_far);
75*3f982cf4SFabien Sanglard }
76*3f982cf4SFabien Sanglard
77*3f982cf4SFabien Sanglard // This is the recursive call. Depending on the number of remaining elements, it
78*3f982cf4SFabien Sanglard // either calls into itself or into the above base case.
79*3f982cf4SFabien Sanglard template <typename T, typename TFirst, typename... TOthers>
Append(std::vector<T> && so_far,TFirst && new_element,TOthers &&...new_elements)80*3f982cf4SFabien Sanglard std::vector<T>&& Append(std::vector<T>&& so_far,
81*3f982cf4SFabien Sanglard TFirst&& new_element,
82*3f982cf4SFabien Sanglard TOthers&&... new_elements) {
83*3f982cf4SFabien Sanglard so_far.push_back(std::move(new_element));
84*3f982cf4SFabien Sanglard return Append(std::move(so_far), std::move(new_elements)...);
85*3f982cf4SFabien Sanglard }
86*3f982cf4SFabien Sanglard
87*3f982cf4SFabien Sanglard // Creates an empty vector with |size| elements reserved. Intended to be used as
88*3f982cf4SFabien Sanglard // GetEmptyVectorOfSize<T>(sizeof...(variadic_input))
89*3f982cf4SFabien Sanglard template <typename T>
GetVectorWithCapacity(size_t size)90*3f982cf4SFabien Sanglard std::vector<T> GetVectorWithCapacity(size_t size) {
91*3f982cf4SFabien Sanglard std::vector<T> results;
92*3f982cf4SFabien Sanglard results.reserve(size);
93*3f982cf4SFabien Sanglard return results;
94*3f982cf4SFabien Sanglard }
95*3f982cf4SFabien Sanglard
96*3f982cf4SFabien Sanglard } // namespace openscreen
97*3f982cf4SFabien Sanglard
98*3f982cf4SFabien Sanglard #endif // UTIL_STD_UTIL_H_
99