Skip to content

Instantly share code, notes, and snippets.

@jpret
Last active July 2, 2021 13:15
Show Gist options
  • Select an option

  • Save jpret/26c2482ebfbd2820c82f25b20339b082 to your computer and use it in GitHub Desktop.

Select an option

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