The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

a/util: Add utility for lists of strings, like extension lists.

authored by

Ryan Pavlik and committed by
Jakob Bornecrantz
27a8ec67 ea38309c

+363
+3
src/xrt/auxiliary/CMakeLists.txt
··· 183 183 util/u_sink_queue.c 184 184 util/u_sink_quirk.c 185 185 util/u_sink_split.c 186 + util/u_string_list.cpp 187 + util/u_string_list.h 188 + util/u_string_list.hpp 186 189 util/u_template_historybuf.hpp 187 190 util/u_time.cpp 188 191 util/u_time.h
+113
src/xrt/auxiliary/util/u_string_list.cpp
··· 1 + // Copyright 2021, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief A collection of strings, like a list of extensions to enable 6 + * 7 + * @author Ryan Pavlik <ryan.pavlik@collabora.com> 8 + * @ingroup aux_util 9 + * 10 + */ 11 + 12 + #include "u_string_list.h" 13 + #include "u_string_list.hpp" 14 + 15 + using xrt::auxiliary::util::StringList; 16 + 17 + 18 + struct u_string_list 19 + { 20 + u_string_list() = default; 21 + u_string_list(StringList &&sl) : list(std::move(sl)) {} 22 + 23 + StringList list; 24 + }; 25 + 26 + struct u_string_list * 27 + u_string_list_create() 28 + { 29 + try { 30 + auto ret = std::make_unique<u_string_list>(); 31 + return ret.release(); 32 + } catch (std::exception const &) { 33 + return nullptr; 34 + } 35 + } 36 + 37 + 38 + struct u_string_list * 39 + u_string_list_create_with_capacity(uint32_t capacity) 40 + { 41 + 42 + try { 43 + auto ret = std::make_unique<u_string_list>(xrt::auxiliary::util::StringList{capacity}); 44 + return ret.release(); 45 + } catch (std::exception const &) { 46 + return nullptr; 47 + } 48 + } 49 + 50 + 51 + uint32_t 52 + u_string_list_get_size(const struct u_string_list *usl) 53 + { 54 + 55 + if (usl == nullptr) { 56 + return 0; 57 + } 58 + return usl->list.size(); 59 + } 60 + 61 + 62 + const char *const * 63 + u_string_list_get_data(const struct u_string_list *usl) 64 + { 65 + 66 + if (usl == nullptr) { 67 + return nullptr; 68 + } 69 + return usl->list.data(); 70 + } 71 + 72 + 73 + int 74 + u_string_list_append(struct u_string_list *usl, const char *str) 75 + { 76 + if (usl == nullptr) { 77 + return -1; 78 + } 79 + try { 80 + usl->list.push_back(str); 81 + return 1; 82 + } catch (std::exception const &) { 83 + return -1; 84 + } 85 + } 86 + 87 + int 88 + u_string_list_append_unique(struct u_string_list *usl, const char *str) 89 + { 90 + if (usl == nullptr) { 91 + return -1; 92 + } 93 + try { 94 + auto added = usl->list.push_back_unique(str); 95 + return added ? 1 : 0; 96 + } catch (std::exception const &) { 97 + return -1; 98 + } 99 + } 100 + 101 + void 102 + u_string_list_destroy(struct u_string_list **list_ptr) 103 + { 104 + if (list_ptr == nullptr) { 105 + return; 106 + } 107 + u_string_list *list = *list_ptr; 108 + if (list == nullptr) { 109 + return; 110 + } 111 + delete list; 112 + *list_ptr = nullptr; 113 + }
+99
src/xrt/auxiliary/util/u_string_list.h
··· 1 + // Copyright 2021, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief A collection of strings, like a list of extensions to enable 6 + * 7 + * @author Ryan Pavlik <ryan.pavlik@collabora.com> 8 + * @ingroup aux_util 9 + * 10 + */ 11 + #pragma once 12 + 13 + #include <stdint.h> 14 + 15 + #ifdef __cplusplus 16 + extern "C" { 17 + #endif 18 + 19 + 20 + /*! 21 + * @brief A collection of string literals (const char *), such as used for extension name lists. 22 + * 23 + * @see xrt::auxiliary::util::StringList 24 + */ 25 + struct u_string_list; 26 + 27 + /*! 28 + * @brief Create a string list with room for at least the given number of strings. 29 + * 30 + * @public @memberof u_string_list 31 + */ 32 + struct u_string_list * 33 + u_string_list_create(void); 34 + 35 + /*! 36 + * @brief Create a string list with room for at least the given number of strings. 37 + * 38 + * @public @memberof u_string_list 39 + */ 40 + struct u_string_list * 41 + u_string_list_create_with_capacity(uint32_t capacity); 42 + 43 + /*! 44 + * @brief Retrieve the number of elements in the list 45 + * 46 + * @public @memberof u_string_list 47 + */ 48 + uint32_t 49 + u_string_list_get_size(const struct u_string_list *usl); 50 + 51 + /*! 52 + * @brief Retrieve the data pointer of the list 53 + * 54 + * @public @memberof u_string_list 55 + */ 56 + const char *const * 57 + u_string_list_get_data(const struct u_string_list *usl); 58 + 59 + /*! 60 + * @brief Append a new string literal to the list. 61 + * 62 + * @param usl self pointer 63 + * @param str a non-null, null-terminated string that must live at least as long as the list, preferably a string 64 + * literal. 65 + * @return 1 if successfully added, negative for errors. 66 + * 67 + * @public @memberof u_string_list 68 + */ 69 + int 70 + u_string_list_append(struct u_string_list *usl, const char *str); 71 + 72 + /*! 73 + * @brief Append a new string literal to the list, if it's not the same as a string already in the list. 74 + * 75 + * (Comparing string contents, not just pointers) 76 + * 77 + * @param usl self pointer 78 + * @param str a non-null, null-terminated string that must live at least as long as the list, preferably a string 79 + * literal. 80 + * @return 1 if successfully added, 0 if already existing so not added, negative for errors. 81 + * 82 + * @public @memberof u_string_list 83 + */ 84 + int 85 + u_string_list_append_unique(struct u_string_list *usl, const char *str); 86 + 87 + /*! 88 + * @brief Destroy a string list. 89 + * 90 + * Performs null checks and sets your pointer to zero. 91 + * 92 + * @public @memberof u_string_list 93 + */ 94 + void 95 + u_string_list_destroy(struct u_string_list **list_ptr); 96 + 97 + #ifdef __cplusplus 98 + } // extern "C" 99 + #endif
+148
src/xrt/auxiliary/util/u_string_list.hpp
··· 1 + // Copyright 2021, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief A collection of strings, like a list of extensions to enable 6 + * 7 + * @author Ryan Pavlik <ryan.pavlik@collabora.com> 8 + * @ingroup aux_util 9 + * 10 + */ 11 + 12 + #pragma once 13 + 14 + #include "u_string_list.h" 15 + 16 + #include <memory> 17 + #include <vector> 18 + #include <limits> 19 + #include <stdexcept> 20 + #include <string> 21 + #include <algorithm> 22 + 23 + namespace xrt::auxiliary::util { 24 + 25 + /*! 26 + * @brief A collection of strings (const char *), like a list of extensions to enable. 27 + * 28 + * This version is only for use with strings that will outlive this object, preferably string literals. 29 + * 30 + * Size is limited to one less than the max value of uint32_t which shouldn't be a problem, 31 + * the size really should be much smaller (especially if you use push_back_unique()). 32 + */ 33 + class StringList 34 + { 35 + public: 36 + /// Construct a string list. 37 + StringList() = default; 38 + /// Construct a string list with the given capacity. 39 + StringList(uint32_t capacity) : vec(capacity, nullptr) 40 + { 41 + // best way I know to create with capacity 42 + vec.clear(); 43 + } 44 + StringList(StringList &&) = default; 45 + StringList(StringList const &) = default; 46 + 47 + StringList & 48 + operator=(StringList &&) = default; 49 + StringList & 50 + operator=(StringList const &) = default; 51 + 52 + /// Construct a string list with the given items 53 + template <uint32_t N> StringList(const char *(&arr)[N]) : StringList(N) 54 + { 55 + for (auto &&elt : arr) { 56 + push_back(elt); 57 + } 58 + } 59 + 60 + /*! 61 + * @brief Get the size of the array (the number of strings) 62 + */ 63 + uint32_t 64 + size() const noexcept 65 + { 66 + return static_cast<uint32_t>(vec.size()); 67 + } 68 + 69 + /*! 70 + * @brief Get the data pointer of the array 71 + */ 72 + const char *const * 73 + data() const noexcept 74 + { 75 + return vec.data(); 76 + } 77 + 78 + /*! 79 + * @brief Append a new string to the list. 80 + * 81 + * @param str a non-null, null-terminated string that must live at least as long as the list, 82 + * preferably a string literal. 83 + * 84 + * @throws std::out_of_range if you have a ridiculous number of strings in your list already, 85 + * std::invalid_argument if you pass a null pointer. 86 + */ 87 + void 88 + push_back(const char *str) 89 + { 90 + 91 + if (vec.size() > std::numeric_limits<uint32_t>::max() - 1) { 92 + throw std::out_of_range("Size limit reached"); 93 + } 94 + if (str == nullptr) { 95 + throw std::invalid_argument("Cannot pass a null pointer"); 96 + } 97 + vec.push_back(str); 98 + } 99 + 100 + /// Add all given items 101 + /// @throws the same as what push_back() throws 102 + template <uint32_t N> 103 + void 104 + push_back_all(const char *(&arr)[N]) 105 + { 106 + for (auto &&elt : arr) { 107 + push_back(elt); 108 + } 109 + } 110 + /*! 111 + * @brief Append a new string to the list if it doesn't match any existing string. 112 + * 113 + * (Comparing string contents, not just pointers) 114 + * 115 + * This does a simple linear search, because it is assumed that the size of this list is fairly small. 116 + * 117 + * @param str a non-null, null-terminated string that must live at least as long as the list, 118 + * preferably a string literal. 119 + * 120 + * @return true if we added it 121 + * 122 + * @throws std::out_of_range if you have a ridiculous number of strings in your list already, 123 + * std::invalid_argument if you pass a null pointer. 124 + */ 125 + bool 126 + push_back_unique(const char *str) 127 + { 128 + if (vec.size() > std::numeric_limits<uint32_t>::max() - 1) { 129 + throw std::out_of_range("Size limit reached"); 130 + } 131 + if (str == nullptr) { 132 + throw std::invalid_argument("Cannot pass a null pointer"); 133 + } 134 + std::string needle{str}; 135 + auto it = std::find_if(vec.begin(), vec.end(), [needle](const char *elt) { return needle == elt; }); 136 + if (it != vec.end()) { 137 + // already have it 138 + return false; 139 + } 140 + vec.push_back(str); 141 + return true; 142 + } 143 + 144 + private: 145 + std::vector<const char *> vec; 146 + }; 147 + 148 + } // namespace xrt::auxiliary::util