Check contents of std :: initializer_list at compile time

I am trying to determine at compile time if all the values ​​in std::initializer_list unique. I managed to find a solution to evaluate the size in the list, but could not apply it to the content. I tried with both free features and constructors, but both approaches led to the following errors with GCC 4.7.2.

error: inconsistent condition for static statement
error: "begin" is not a constant expression

I understand that the members of std::initializer_list not declared constexpr , but I hope there is such a solution as size checking. Is it possible to check the contents at compile time using something like the following?

 #include <initializer_list> template<typename InputIterator> constexpr bool Validate(InputIterator begin, InputIterator end) { static_assert(*begin == *end, "begin and end are the same"); // The actual implemetnation is a single line recursive check. return true; } template<typename InputType> constexpr bool Validate(const std::initializer_list<InputType>& input) { // "-1" removed to simplify and eliminate potential cause of error return Validate(input.begin(), input.end() /* - 1 */); } int main() { Validate({1, 2, 1}); } 
+7
source share
1 answer

After some digging, it seems like using std::initializer_list not possible in GCC 4.7 due to the lack of constexpr in the declaration. It should work with GCC 4.8 since the <initializer_list> been updated to include constexpr . Unfortunately, using GCC 4.8 is currently not an option.

You can access array elements if at least a decaying pointer is passed by reference. This allows you to check as you wish, but still this is not quite the solution that I hope for. The following code is an acceptable solution for arrays. It still requires the size of the array to be passed to the validation function, but it's easy enough to fix it.

 #include <initializer_list> template<typename T> constexpr bool Compare(T& data, int size, int needleIndex, int haystackIndex) { return needleIndex == haystackIndex ? Compare(data, size, needleIndex + 1, haystackIndex) : needleIndex == size ? false : data[needleIndex] == data[haystackIndex] ? true : Compare(data, size, needleIndex + 1, haystackIndex); } template<typename T> constexpr bool Compare(T& data, int size, int index) { return index == size ? false : Compare(data, size, index + 1) ? true : Compare(data, size, 0, index); } template<typename T, int ArraySize> constexpr bool Validate(T(&input)[ArraySize], int size) { return !Compare(input, size, 0); } int main() { constexpr int initData0[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; constexpr int initData1[] = {1, 1, 2, 3, 4, 5, 6, 7, 8, 9}; constexpr int initData2[] = {2, 1, 2, 3, 4, 5, 6, 7, 8, 9}; constexpr int initData3[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 8}; constexpr int initData4[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 7}; constexpr int initData5[] = {0, 1, 0, 3, 4, 5, 6, 7, 8, 9}; constexpr int initData6[] = {0, 1, 2, 3, 4, 5, 6, 9, 8, 9}; static_assert(Validate(initData0, 10), "set 0 failed"); // <-- PASS static_assert(Validate(initData1, 10), "set 1 failed"); // <-- (and below) FAIL static_assert(Validate(initData2, 10), "set 2 failed"); static_assert(Validate(initData3, 10), "set 3 failed"); static_assert(Validate(initData4, 10), "set 4 failed"); static_assert(Validate(initData5, 10), "set 5 failed"); static_assert(Validate(initData6, 10), "set 6 failed"); } 

.

Build Log:

C: \ Source \ SwitchCaseString \ main.cpp: In the function 'int main ()':
C: \ Source \ SwitchCaseString \ main.cpp: 198: 2: error: static statement failed: failed to install 1
C: \ Source \ SwitchCaseString \ main.cpp: 199: 2: error: static statement failed: failed to install 2
C: \ Source \ SwitchCaseString \ main.cpp: 200: 2: error: static statement failed: failed to install 3
C: \ Source \ SwitchCaseString \ main.cpp: 201: 2: error: static statement failed: failed to install 4
C: \ Source \ SwitchCaseString \ main.cpp: 202: 2: error: static statement failed: failed to install 5
C: \ Source \ SwitchCaseString \ main.cpp: 203: 2: error: static statement failed: install 6 failed

+1
source

All Articles