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