Skip to content

Commit

Permalink
Merge pull request #1150 from FireDaemon/issues/#1149
Browse files Browse the repository at this point in the history
Detect the absence of string_view's iterator range ctor differently.
  • Loading branch information
trueqbit committed Mar 8, 2023
2 parents 4038920 + d099e60 commit f05b74b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 23 deletions.
7 changes: 7 additions & 0 deletions dev/functional/cxx_compiler_quirks.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,10 @@
(defined(__clang__) && (__clang_major__ >= 12) && (__cplusplus >= 202002L))
#define SQLITE_ORM_CLASSTYPE_TEMPLATE_ARGS_SUPPORTED
#endif

// clang 10 chokes on concepts that don't depend on template parameters;
// when it tries to instantiate an expression in a requires expression, which results in an error,
// the compiler reports an error instead of dismissing the templated function.
#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && (defined(__clang__) && (__clang_major__ == 10))
#define SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS
#endif
20 changes: 13 additions & 7 deletions dev/serializing_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
#include <string>
#include <ostream>
#include <utility> // std::exchange, std::tuple_size
#if __cplusplus >= 202002L && __cpp_lib_concepts
#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && !defined(SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS)
#include <string_view>
#include <algorithm> // std::find
#endif

#include "functional/cxx_universal.h"
#include "functional/cxx_universal.h" // ::size_t
#include "functional/cxx_type_traits_polyfill.h"
#include "tuple_helper/tuple_iteration.h"
#include "error_code.h"
Expand All @@ -29,9 +29,14 @@ namespace sqlite_orm {
template<class T, class Ctx>
std::string serialize_order_by(const T& t, const Ctx& context);

#if __cplusplus >= 202002L && \
__cpp_lib_concepts // contiguous iterator ranges depend on contiguous_iterator, sized_sentinel_for in all major implementations
inline void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape) {
#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && !defined(SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS)
// optimized version when string_view's iterator range constructor is available
template<class SFINAE = void>
void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape)
requires requires {
std::string_view{str.cbegin(), str.cend()};
}
{
for(std::string::const_iterator it = str.cbegin(), next; true; it = next + 1) {
next = std::find(it, str.cend(), char2Escape);
os << std::string_view{it, next};
Expand All @@ -42,7 +47,9 @@ namespace sqlite_orm {
os << std::string(2, char2Escape);
}
}
#else

template<class SFINAE = void>
#endif
inline void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape) {
if(str.find(char2Escape) == str.npos) {
os << str;
Expand All @@ -55,7 +62,6 @@ namespace sqlite_orm {
}
}
}
#endif

inline void stream_identifier(std::ostream& ss,
const std::string& qualifier,
Expand Down
45 changes: 29 additions & 16 deletions include/sqlite_orm/sqlite_orm.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ using std::nullptr_t;
#define SQLITE_ORM_CLASSTYPE_TEMPLATE_ARGS_SUPPORTED
#endif

// clang 10 chokes on concepts that don't depend on template parameters;
// when it tries to instantiate an expression in a requires expression, which results in an error,
// the compiler reports an error instead of dismissing the templated function.
#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && (defined(__clang__) && (__clang_major__ == 10))
#define SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS
#endif

#if SQLITE_ORM_HAS_INCLUDE(<version>)
#include <version>
#endif
Expand Down Expand Up @@ -13191,13 +13198,13 @@ namespace sqlite_orm {
#include <string>
#include <ostream>
#include <utility> // std::exchange, std::tuple_size
#if __cplusplus >= 202002L && __cpp_lib_concepts
#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && !defined(SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS)
#include <string_view>
#include <algorithm> // std::find
#endif

// #include "functional/cxx_universal.h"

// ::size_t
// #include "functional/cxx_type_traits_polyfill.h"

// #include "tuple_helper/tuple_iteration.h"
Expand All @@ -13219,9 +13226,14 @@ namespace sqlite_orm {
template<class T, class Ctx>
std::string serialize_order_by(const T& t, const Ctx& context);

#if __cplusplus >= 202002L && \
__cpp_lib_concepts // contiguous iterator ranges depend on contiguous_iterator, sized_sentinel_for in all major implementations
inline void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape) {
#if defined(SQLITE_ORM_CONCEPTS_SUPPORTED) && !defined(SQLITE_ORM_BROKEN_NONTEMPLATE_CONCEPTS)
// optimized version when string_view's iterator range constructor is available
template<class SFINAE = void>
void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape)
requires requires {
std::string_view{str.cbegin(), str.cend()};
}
{
for(std::string::const_iterator it = str.cbegin(), next; true; it = next + 1) {
next = std::find(it, str.cend(), char2Escape);
os << std::string_view{it, next};
Expand All @@ -13232,20 +13244,21 @@ namespace sqlite_orm {
os << std::string(2, char2Escape);
}
}
#else
inline void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape) {
if(str.find(char2Escape) == str.npos) {
os << str;
} else {
for(char c: str) {
if(c == char2Escape) {
os << char2Escape;
}
os << c;

template<class SFINAE = void>
#endif
inline void stream_sql_escaped(std::ostream& os, const std::string& str, char char2Escape) {
if(str.find(char2Escape) == str.npos) {
os << str;
} else {
for(char c: str) {
if(c == char2Escape) {
os << char2Escape;
}
os << c;
}
}
#endif
}

inline void stream_identifier(std::ostream& ss,
const std::string& qualifier,
Expand Down

0 comments on commit f05b74b

Please sign in to comment.