forked from fnc12/sqlite_orm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Circumvented Clang's buggy pack indexing expression evaluation
- Loading branch information
Showing
2 changed files
with
62 additions
and
62 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,61 @@ | ||
#pragma once | ||
|
||
#include <utility> // std::index_sequence | ||
|
||
namespace sqlite_orm { | ||
namespace internal { | ||
#if defined(SQLITE_ORM_PACK_INDEXING_SUPPORTED) | ||
/** | ||
* Get the index value of an `index_sequence` at a specific position. | ||
*/ | ||
template<size_t Pos, size_t... Idx> | ||
SQLITE_ORM_CONSTEVAL size_t index_sequence_value_at(std::index_sequence<Idx...>) { | ||
return Idx...[Pos]; | ||
} | ||
#elif defined(SQLITE_ORM_FOLD_EXPRESSIONS_SUPPORTED) | ||
/** | ||
* Get the index value of an `index_sequence` at a specific position. | ||
*/ | ||
template<size_t Pos, size_t... Idx> | ||
SQLITE_ORM_CONSTEVAL size_t index_sequence_value_at(std::index_sequence<Idx...>) { | ||
static_assert(Pos < sizeof...(Idx)); | ||
#ifdef SQLITE_ORM_CONSTEVAL_SUPPORTED | ||
size_t result; | ||
#else | ||
size_t result = 0; | ||
#endif | ||
size_t i = 0; | ||
// note: `(void)` cast silences warning 'expression result unused' | ||
(void)((result = Idx, i++ == Pos) || ...); | ||
return result; | ||
} | ||
#else | ||
/** | ||
* Get the index value of an `index_sequence` at a specific position. | ||
* `Pos` must always be `0`. | ||
*/ | ||
template<size_t Pos, size_t I, size_t... Idx> | ||
SQLITE_ORM_CONSTEVAL size_t index_sequence_value_at(std::index_sequence<I, Idx...>) { | ||
static_assert(Pos == 0, ""); | ||
return I; | ||
} | ||
#endif | ||
|
||
template<class... Seq> | ||
struct flatten_idxseq { | ||
using type = std::index_sequence<>; | ||
}; | ||
|
||
template<size_t... Ix> | ||
struct flatten_idxseq<std::index_sequence<Ix...>> { | ||
using type = std::index_sequence<Ix...>; | ||
}; | ||
|
||
template<size_t... As, size_t... Bs, class... Seq> | ||
struct flatten_idxseq<std::index_sequence<As...>, std::index_sequence<Bs...>, Seq...> | ||
: flatten_idxseq<std::index_sequence<As..., Bs...>, Seq...> {}; | ||
|
||
template<class... Seq> | ||
using flatten_idxseq_t = typename flatten_idxseq<Seq...>::type; | ||
} | ||
} | ||
#pragma once | ||
|
||
#include <utility> // std::index_sequence | ||
|
||
namespace sqlite_orm { | ||
namespace internal { | ||
#if defined(SQLITE_ORM_PACK_INDEXING_SUPPORTED) | ||
/** | ||
* Get the index value of an `index_sequence` at a specific position. | ||
*/ | ||
template<size_t Pos, size_t... Idx> | ||
SQLITE_ORM_CONSTEVAL auto index_sequence_value_at(std::index_sequence<Idx...>) { | ||
return Idx...[Pos]; | ||
} | ||
#elif defined(SQLITE_ORM_FOLD_EXPRESSIONS_SUPPORTED) | ||
/** | ||
* Get the index value of an `index_sequence` at a specific position. | ||
*/ | ||
template<size_t Pos, size_t... Idx> | ||
SQLITE_ORM_CONSTEVAL size_t index_sequence_value_at(std::index_sequence<Idx...>) { | ||
static_assert(Pos < sizeof...(Idx)); | ||
#ifdef SQLITE_ORM_CONSTEVAL_SUPPORTED | ||
size_t result; | ||
#else | ||
size_t result = 0; | ||
#endif | ||
size_t i = 0; | ||
// note: `(void)` cast silences warning 'expression result unused' | ||
(void)((result = Idx, i++ == Pos) || ...); | ||
return result; | ||
} | ||
#else | ||
/** | ||
* Get the index value of an `index_sequence` at a specific position. | ||
* `Pos` must always be `0`. | ||
*/ | ||
template<size_t Pos, size_t I, size_t... Idx> | ||
SQLITE_ORM_CONSTEVAL size_t index_sequence_value_at(std::index_sequence<I, Idx...>) { | ||
static_assert(Pos == 0, ""); | ||
return I; | ||
} | ||
#endif | ||
|
||
template<class... Seq> | ||
struct flatten_idxseq { | ||
using type = std::index_sequence<>; | ||
}; | ||
|
||
template<size_t... Ix> | ||
struct flatten_idxseq<std::index_sequence<Ix...>> { | ||
using type = std::index_sequence<Ix...>; | ||
}; | ||
|
||
template<size_t... As, size_t... Bs, class... Seq> | ||
struct flatten_idxseq<std::index_sequence<As...>, std::index_sequence<Bs...>, Seq...> | ||
: flatten_idxseq<std::index_sequence<As..., Bs...>, Seq...> {}; | ||
|
||
template<class... Seq> | ||
using flatten_idxseq_t = typename flatten_idxseq<Seq...>::type; | ||
} | ||
} |
This file contains 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