47d73ad9777c90ac5cb8866e5fde1c0425a48c83
[platform/core/uifw/vulkan-wsi-tizen.git] / util / unordered_map.hpp
1 /*
2  * Copyright (c) 2021 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
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 all
14  * 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 FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #pragma once
25
26 #include <unordered_map>
27 #include "custom_allocator.hpp"
28 #include "optional.hpp"
29
30 namespace util
31 {
32 /**
33  * @brief This utility class has the same purpose as std::unordered_map, but
34  *        ensures that the operations that could result in out of memory
35  *        exceptions don't throw them and also ensures that the memory can
36  *        only be allocated by an custom_allocator.
37  */
38 template <typename Key, typename Value,
39         typename Hash = std::hash<Key>,
40         typename Comparator = std::equal_to<Key>,
41         typename Allocator = util::custom_allocator<std::pair<const Key, Value>>>
42 class unordered_map : public std::unordered_map<Key, Value, Hash, Comparator, Allocator>
43 {
44    using base = std::unordered_map<Key, Value, Hash, Comparator, Allocator>;
45    using size_type = typename base::size_type;
46    using iterator = typename base::iterator;
47
48 public:
49    /**
50     * Delete all member functions that can cause allocation failure by throwing std::bad_alloc.
51     */
52    Value &operator[](const Key &key) = delete;
53    Value &operator[](Key &&key) = delete;
54
55    unordered_map(const unordered_map &) = delete;
56    unordered_map &operator=(const unordered_map &) = delete;
57
58    void insert() = delete;
59    void emplace() = delete;
60    void emplace_hint() = delete;
61    void reserve() = delete;
62    void rehash() = delete;
63
64    /**
65     * @brief Construct a new unordered map object with a custom allocator.
66     *
67     * @param allocator The allocator that will be used.
68     */
69    explicit unordered_map(util::custom_allocator<std::pair<const Key, Value>> allocator)
70       : base(allocator)
71    {
72    }
73
74    /**
75     * @brief Like std::unordered_map.insert but doesn't throw on out of memory errors.
76     *
77     * @param value The value to insert in the map.
78     * @return util::optional<std::pair<iterator,bool>> If successful, the optional will
79     *         contain the same return value as from std::unordered_map.insert, otherwise
80     *         if out of memory, optional will be empty.
81     */
82    util::optional<std::pair<iterator, bool>> try_insert(const std::pair<Key, Value> &value)
83    {
84       try
85       {
86          return { base::insert(value) };
87       }
88       catch(std::bad_alloc& e)
89       {
90          return {};
91       }
92    }
93
94    /**
95     * @brief Like std::unordered_map.reserve but doesn't throw on out of memory errors.
96     *
97     * @param size The new capacity of the container. Same as std::unordered_map.reserve.
98     * @return true If the container was resized successfuly.
99     * @return false If the host has run out of memory
100     */
101    bool try_reserve(size_type size)
102    {
103       try
104       {
105          base::reserve(size);
106          return true;
107       }
108       catch(std::bad_alloc& e)
109       {
110          return false;
111       }
112    }
113
114    /**
115     * @brief Like std::unordered_map.rehash but doesn't throw on out of memory errors.
116     *
117     * @param count Number of buckets. Same as std::unordered_map.rehash.
118     * @return true If the container was rehashed successfuly.
119     * @return false If the host has run out of memory
120     */
121    bool try_rehash(size_type count)
122    {
123       try
124       {
125          base::rehash(count);
126          return true;
127       }
128       catch(std::bad_alloc& e)
129       {
130          return false;
131       }
132    }
133 };
134 }