/* SPDX-FileCopyrightText: 2015 Ivan Cukic SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef QUICKCHECK_DATABASE_COMMON_H #define QUICKCHECK_DATABASE_COMMON_H struct PrimaryKeyOrdering { template bool operator()(const T &left, const T &right) const { return left.primaryKey() < right.primaryKey(); } }; #define TABLE(Table) std::set #define DECL_COLUMN(ColumnType, ColumnName) \ inline Column ColumnName() \ { \ return Column(&Item::ColumnName); \ } template class Column { typedef Column ThisType; public: Column(const ColumnType Type::*memberptr) : memberptr(memberptr) { } //_ Column comparator functor template class CompositeComparator { public: CompositeComparator(Comp1 comp1, Comp2 comp2) : comp1(comp1) , comp2(comp2) { } inline bool operator()(const Type &left, const Type &right) const { return comp1(left, right) ? true : comp1(right, left) ? false : comp2(left, right); } private: const Comp1 comp1; const Comp2 comp2; }; class Comparator { public: Comparator(const ColumnType Type::*memberptr, bool invert) : memberptr(memberptr) , invert(invert) { } inline bool operator()(const Type &left, const Type &right) const { return (invert) ? right.*memberptr < left.*memberptr // : left.*memberptr < right.*memberptr; } template CompositeComparator operator|(const Comp2 &comp2) { return CompositeComparator(*this, comp2); } private: const ColumnType Type::*memberptr; const bool invert; }; //^ inline Comparator asc() const { return Comparator(memberptr, false); } inline Comparator desc() const { return Comparator(memberptr, true); } //_ Column filtering functor enum ComparisonOperation { Less, LessOrEqual, Equal, GreaterOrEqual, Greater, }; template class Filterer { public: Filterer(const ColumnType Type::*memberptr, ComparisonOperation comparison, const T &value) : memberptr(memberptr) , comparison(comparison) , value(value) { } inline bool operator()(const Type &item) const { return comparison == Less ? item.*memberptr < value : comparison == LessOrEqual ? item.*memberptr <= value : comparison == Equal ? item.*memberptr == value : comparison == GreaterOrEqual ? item.*memberptr >= value : comparison == Greater ? item.*memberptr > value : false; } private: const ColumnType Type::*memberptr; const ComparisonOperation comparison; const T value; }; #define IMPLEMENT_COMPARISON_OPERATOR(OPERATOR, NAME) \ template \ inline Filterer operator OPERATOR(const T &value) const \ { \ return Filterer(memberptr, NAME, value); \ } //^ IMPLEMENT_COMPARISON_OPERATOR(<, Less) IMPLEMENT_COMPARISON_OPERATOR(<=, LessOrEqual) IMPLEMENT_COMPARISON_OPERATOR(==, Equal) IMPLEMENT_COMPARISON_OPERATOR(>=, GreaterOrEqual) IMPLEMENT_COMPARISON_OPERATOR(>, Greater) #undef IMPLEMENT_COMPARISON_OPERATOR // Column stuff private: const ColumnType Type::*memberptr; }; template inline auto groupBy(const Range &range, const ColumnMemberPointer &memberptr, const MergeFunction &merge) -> std::vector { std::vector result; for (const auto &item : range) { if (result.size() == 0 || result.back().*memberptr != item.*memberptr) { result.push_back(item); } else { merge(result.back(), item); } } return result; } #endif // QUICKCHECK_DATABASE_COMMON_H // vim: set foldmethod=marker: