Last active
July 2, 2021 13:15
-
-
Save jpret/26c2482ebfbd2820c82f25b20339b082 to your computer and use it in GitHub Desktop.
Finding duplicate values in std::map at compile time - alternative using std::array
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <array> | |
| #include <cassert> | |
| #include <cstdlib> | |
| template<typename A, typename B> | |
| constexpr bool compare_equal(A a, B b) { | |
| return a == b; | |
| } | |
| template <> | |
| constexpr bool compare_equal(const char * a, const char * b) { | |
| return *a == *b && (*a == '\0' || compare_equal(a + 1, b + 1)); | |
| } | |
| #if __cplusplus >= 201402L /* C++14 And Above Version */ | |
| template<typename K, typename T, size_t N> | |
| constexpr bool has_duplicates(const std::array<std::pair<K, T>, N> *arr) { | |
| for (int i = 0; i < N - 1; i++) { | |
| for (int j = i + 1; j < N; j++) { | |
| if (compare_equal((*arr)[i].second,(*arr)[j].second) || | |
| compare_equal((*arr)[i].first, (*arr)[j].first)) return true; | |
| } | |
| } | |
| return false; | |
| } | |
| #else /* C++11 Version */ | |
| // Prototypes | |
| template<typename K, typename T, size_t N> | |
| constexpr bool has_duplicates(const std::array<std::pair<K, T>, N> *arr, size_t i, size_t j); | |
| template<typename K, typename T, size_t N> | |
| constexpr bool has_duplicates_outer(const std::array<std::pair<K, T>, N> *arr, size_t i, size_t j); | |
| template<typename K, typename T, size_t N> | |
| constexpr bool has_duplicates_inner(const std::array<std::pair<K, T>, N> *arr, size_t i, size_t j) { | |
| // Inner loop check for a match else go to the outer loop | |
| return (((compare_equal((*arr)[i].second, (*arr)[j].second) || | |
| compare_equal((*arr)[i].first, (*arr)[j].first))) && (i != j)) | |
| ? true : has_duplicates_outer(arr, i, j); | |
| } | |
| template<typename K, typename T, size_t N> | |
| constexpr bool has_duplicates_outer(const std::array<std::pair<K, T>, N> *arr, size_t i, size_t j) { | |
| // Outer loop increase the outer index | |
| return (i < N - 1 && j < N) ? has_duplicates(arr, i, j+1) : false; | |
| } | |
| template<typename K, typename T, size_t N> | |
| constexpr bool has_duplicates(const std::array<std::pair<K, T>, N> *arr, size_t i, size_t j) { | |
| return (i < N - 1 && j < N ? has_duplicates_inner(arr, i, j) : has_duplicates_outer(arr, i+1, i)); | |
| } | |
| template<typename K, typename T, size_t N> | |
| constexpr bool has_duplicates(const std::array<std::pair<K, T>, N> *arr) { | |
| return has_duplicates(arr, 0, 1); | |
| } | |
| #endif | |
| int main(int argc, char *argv[]) { | |
| constexpr std::array<std::pair<int, const char *>, 3> arr{{{1, "foo"}, | |
| {2, "bar"}, | |
| {3, "foobar"}}}; | |
| static_assert(!has_duplicates(&arr), "Duplicates Found!"); | |
| constexpr std::array<std::pair<int, const char *>, 3> arrd{{{1, "foo"}, | |
| {2, "bar"}, | |
| {3, "foobar"}}}; | |
| static_assert(!has_duplicates(&arrd), "Duplicates Found!"); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment