| 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 | |