| | 42 | '''[wiki:GSoCIdeaTemplate To any potential mentor adding a proposal HERE please use this template]''' |
| | 43 | |
| | 44 | |
| | 45 | === 1. Static map (`boost::static_map<Key, T, ConstExprHash = boost::constexpr_hash<Key>, Pred = boost::constexpr_equal_to<Key>>`) === |
| | 46 | Potential mentors: Niall Douglas |
| | 47 | |
| | 48 | ==== Background ==== |
| | 49 | |
| | 50 | Even with all of Boost's facilities ![1] and using C++ 14, this program represents the currently best available method |
| | 51 | of implementing a static constant associative map of keys to values |
| | 52 | ([http://melpon.org/wandbox/permlink/SEt61EAxVG4J5BnF play with it in an online compiler here]): |
| | 53 | |
| | 54 | {{{ |
| | 55 | #!c++ |
| | 56 | #include <initializer_list> |
| | 57 | #include <experimental/string_view> |
| | 58 | #include <map> |
| | 59 | #include <unordered_map> |
| | 60 | #include <iostream> |
| | 61 | |
| | 62 | using std::experimental::string_view; |
| | 63 | |
| | 64 | enum class weekday { sunday, monday, tuesday, wednesday, thursday, friday, saturday }; |
| | 65 | |
| | 66 | // initializer_list, pair and string_view are constexpr, so this list can be constexpr |
| | 67 | // (i.e. lives in the mind of the compiler only and has zero representation in generated code) |
| | 68 | #define STRING_VIEW(str) { str, sizeof(str)-1 } |
| | 69 | constexpr std::initializer_list<std::pair<const string_view, weekday>> string_to_weekday { |
| | 70 | { STRING_VIEW("sunday"), weekday::sunday }, |
| | 71 | { STRING_VIEW("monday"), weekday::monday }, |
| | 72 | { STRING_VIEW("tuesday"), weekday::tuesday }, |
| | 73 | { STRING_VIEW("wednesday"), weekday::wednesday }, |
| | 74 | { STRING_VIEW("thursday"), weekday::thursday }, |
| | 75 | { STRING_VIEW("friday"), weekday::friday }, |
| | 76 | { STRING_VIEW("saturday"), weekday::saturday } |
| | 77 | }; |
| | 78 | |
| | 79 | int main(void) |
| | 80 | { |
| | 81 | { |
| | 82 | // Calls malloc() at least 7 times |
| | 83 | static const std::map<string_view, weekday> to_weekday1 = string_to_weekday; |
| | 84 | std::cout << "'monday' maps to " << static_cast<int>(to_weekday1.at("monday")) << std::endl; |
| | 85 | std::cout << "'friday' maps to " << static_cast<int>(to_weekday1.at("friday")) << std::endl; |
| | 86 | // Calls free() at least 7 times |
| | 87 | } |
| | 88 | { |
| | 89 | // Calls malloc() at least 8 times |
| | 90 | static const std::unordered_map<string_view, weekday> to_weekday2 = string_to_weekday; |
| | 91 | std::cout << "'monday' maps to " << static_cast<int>(to_weekday2.at("monday")) << std::endl; |
| | 92 | std::cout << "'friday' maps to " << static_cast<int>(to_weekday2.at("friday")) << std::endl; |
| | 93 | // Calls free() at least 8 times |
| | 94 | } |
| | 95 | return 0; |
| | 96 | } |
| | 97 | }}} |
| | 98 | |
| | 99 | As you can see, we have either the choice of linearly scanning the associative array `string_to_weekday` |
| | 100 | for keys (which has linear complexity to number of items per lookup), or we can ''copy'' at runtime the |
| | 101 | associative array into an associative map which can thereafter be queried at runtime in either `O(log N)` |
| | 102 | or `O(1)` complexities respectively. |
| | 103 | |
| | 104 | Almost every seasoned C++ programmer has at least once (and often many times throughout a career) written |
| | 105 | a static constant associative map which is initialised once from static constant data usually at process |
| | 106 | start, and is thereafter never modified. Given that C++ 14 can very easily implement a static constant |
| | 107 | associative map container class, it would be a very worthwhile addition to Boost and C++ in general if |
| | 108 | we gained a high quality implementation of a static map class. |
| | 109 | |
| | 110 | ![1]: ''Probably'' Boost.Hana which is expected to enter Boost soon could be used to implement a |
| | 111 | static map which can be queried either at compile time or run time fairly easily. This project proposal |
| | 112 | does not require the use of Boost.Hana, though using it may be interesting. |
| | 113 | |
| | 114 | |
| | 115 | ==== GSoC project proposal ==== |
| | 116 | 1. To seek consensus from the Boost Developer's mailing list on a suitable design for a Boost `static_map` class. |
| | 117 | (The chances are high that the `static_map` class would be STL compliant much as other constexpr-capable STL |
| | 118 | containers such as `std::array<>` and `std::initializer_list<>`). |
| | 119 | |
| | 120 | 2. To implement a `static_map` class which runs on at least two major C++ compilers. |
| | 121 | - The class should be entirely a compile-time implementation via constexpr and generate no runtime overhead |
| | 122 | whatsoever. |
| | 123 | |
| | 124 | 3. To implement a comprehensive unit test suite for the `static_map` class, including tests ensuring no |
| | 125 | runtime overhead is generated. |
| | 126 | |
| | 127 | 4. To configure per-commit continuous integration for the unit test suite on at least one of the major public |
| | 128 | open source CI services (e.g. Travis, Appveyor). |
| | 129 | |
| | 130 | 5. To write documentation to Boost quality levels for the new container class, including time and space complexity |
| | 131 | guarantees and exception guarantees for each API and each use of each API. |
| | 132 | |
| | 133 | ==== Potential project extension funded by Boost ==== |
| | 134 | - `static_multimap` |
| | 135 | - `static_set` and `static_multiset` |
| | 136 | - `static_ordered_map` and `static_ordered_multimap` |
| | 137 | |
| | 138 | ==== Programming competency test ==== |
| | 139 | Write a function which uses one of the compile time string hashing techniques at https://stackoverflow.com/questions/2111667/compile-time-string-hashing |
| | 140 | to generate a constexpr `std::array<unsigned>` of its input strings. The function ought to have the following |
| | 141 | prototype: |
| | 142 | |
| | 143 | {{{ |
| | 144 | #!c++ |
| | 145 | template<class... Strings> constexpr std::array<unsigned, sizeof...(Strings)> hash_strings(Strings&&... strings); |
| | 146 | |
| | 147 | // Example of usage |
| | 148 | constexpr std::array<unsigned, 4> string_hashes = hash_strings("google", "summer", "of", "code"); |
| | 149 | }}} |
| | 150 | |
| | 151 | Submission of the programming test should be via copying and pasting the code you wrote into the end of the proposal you submit to Google Melange. |
| | 152 | |