olp-cpp-sdk 1.24.0
Loading...
Searching...
No Matches
try_emplace.h
1/*
2 * Copyright (C) 2019 HERE Europe B.V.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * SPDX-License-Identifier: Apache-2.0
17 * License-Filename: LICENSE
18 */
19
20#pragma once
21
22#include <map>
23#include <type_traits>
24#include <unordered_map>
25#include <utility>
26
27/*
28 * Workaround for not having std::map::try_emplace and
29 * std::unordered_map::try_emplace
30 * until c++17 is available.
31 * Note - std::piecewise_construct and emplace are not supported by gcc 4.7
32 * therefore for this compiler first argument is not deduced as map::key_type
33 * and insert is used
34 * instead of emplace.
35 */
36
37namespace olp {
38namespace porting {
39#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ <= 7) && \
40 defined(__GLIBCXX__) && !defined(__clang__)
41
42template <typename MAP_TYPE_CONT, typename FIRST, typename SECOND>
43inline std::pair<typename MAP_TYPE_CONT::iterator, bool> try_emplace(
44 MAP_TYPE_CONT& map_type_cont, FIRST&& first, SECOND&& second) {
45 return map_type_cont.insert(
46 std::make_pair(std::forward<FIRST>(first), std::forward<SECOND>(second)));
47}
48
49template <typename MAP_TYPE_CONT, typename FIRST, typename SECOND,
50 typename... ARGS>
51inline std::pair<typename MAP_TYPE_CONT::iterator, bool> try_emplace(
52 MAP_TYPE_CONT& map_type_cont, FIRST&& first, SECOND&& second,
53 ARGS&&... args) {
54 return map_type_cont.insert(std::make_pair(
55 std::forward<FIRST>(first),
56 typename MAP_TYPE_CONT::mapped_type(std::forward<SECOND>(second),
57 std::forward<ARGS>(args)...)));
58}
59
60#else
61
62template <class T>
63struct IsMap : public std::false_type {};
64
65template <class... ARGS>
66struct IsMap<std::map<ARGS...> > : public std::true_type {};
67
68template <class T>
69struct IsUnorderedMap : public std::false_type {};
70
71template <class... ARGS>
72struct IsUnorderedMap<std::unordered_map<ARGS...> > : public std::true_type {};
73
74/**** For std::map ****/
75
76template <class MAP_TYPE_CONT, class... ARGS>
77inline typename std::enable_if<
79 std::pair<typename MAP_TYPE_CONT::iterator, bool> >::type
80try_emplace(MAP_TYPE_CONT& map_type_cont,
81 typename MAP_TYPE_CONT::key_type&& key, ARGS&&... args) {
82 auto it = map_type_cont.lower_bound(key);
83 if (it == map_type_cont.end() || map_type_cont.key_comp()(key, it->first)) {
84 return {map_type_cont.emplace_hint(
85 it, std::piecewise_construct,
86 std::forward_as_tuple(
87 std::forward<typename MAP_TYPE_CONT::key_type>(key)),
88 std::forward_as_tuple(std::forward<ARGS>(args)...)),
89 true};
90 }
91 return {it, false};
92}
93
94template <class MAP_TYPE_CONT, class... ARGS>
95inline typename std::enable_if<
96 IsMap<MAP_TYPE_CONT>::value,
97 std::pair<typename MAP_TYPE_CONT::iterator, bool> >::type
98try_emplace(MAP_TYPE_CONT& map_type_cont,
99 const typename MAP_TYPE_CONT::key_type& key, ARGS&&... args) {
100 auto it = map_type_cont.lower_bound(key);
101 if (it == map_type_cont.end() || map_type_cont.key_comp()(key, it->first)) {
102 return {map_type_cont.emplace_hint(
103 it, std::piecewise_construct, std::forward_as_tuple(key),
104 std::forward_as_tuple(std::forward<ARGS>(args)...)),
105 true};
106 }
107 return {it, false};
108}
109
110/**** For std::unordered_map ****/
111
112template <class MAP_TYPE_CONT, class... ARGS>
113inline typename std::enable_if<
114 IsUnorderedMap<MAP_TYPE_CONT>::value,
115 std::pair<typename MAP_TYPE_CONT::iterator, bool> >::type
116try_emplace(MAP_TYPE_CONT& map_type_cont,
117 typename MAP_TYPE_CONT::key_type&& key, ARGS&&... args) {
118 auto it = map_type_cont.find(key);
119 if (it == map_type_cont.end()) {
120 return map_type_cont.emplace(
121 std::piecewise_construct,
122 std::forward_as_tuple(
123 std::forward<typename MAP_TYPE_CONT::key_type>(key)),
124 std::forward_as_tuple(std::forward<ARGS>(args)...));
125 }
126 return {it, false};
127}
128
129template <class MAP_TYPE_CONT, class... ARGS>
130inline typename std::enable_if<
131 IsUnorderedMap<MAP_TYPE_CONT>::value,
132 std::pair<typename MAP_TYPE_CONT::iterator, bool> >::type
133try_emplace(MAP_TYPE_CONT& map_type_cont,
134 const typename MAP_TYPE_CONT::key_type& key, ARGS&&... args) {
135 auto it = map_type_cont.find(key);
136 if (it == map_type_cont.end()) {
137 return map_type_cont.emplace(
138 std::piecewise_construct, std::forward_as_tuple(key),
139 std::forward_as_tuple(std::forward<ARGS>(args)...));
140 }
141 return {it, false};
142}
143
144#endif
145} // namespace porting
146} // namespace olp
Rules all the other namespaces.
Definition AppleSignInProperties.h:24
Definition try_emplace.h:63
Definition try_emplace.h:69