6 #ifndef SWIFT_MISC_SEQUENCE_H
7 #define SWIFT_MISC_SEQUENCE_H
11 #include <initializer_list>
13 #include <type_traits>
24 #define SWIFT_TEMPLATE_SEQUENCE_MIXINS(NS, T, List, Extern) \
29 namespace swift::misc::private_ns \
31 Extern template struct CValueObjectMetaInfo<NS::List>; \
32 Extern template struct CValueObjectMetaInfo<CSequence<NS::T>>; \
33 Extern template struct MetaTypeHelper<NS::List>; \
34 Extern template struct MetaTypeHelper<CSequence<NS::T>>; \
36 namespace swift::misc::mixin \
38 Extern template class MetaType<NS::List>; \
39 Extern template class MetaType<CSequence<NS::T>>; \
40 Extern template class DBusOperators<CSequence<NS::T>>; \
41 Extern template class JsonOperators<CSequence<NS::T>>; \
42 Extern template class String<CSequence<NS::T>>; \
43 Extern template class DataStreamOperators<CSequence<NS::T>>; \
44 Extern template class Icon<CSequence<NS::T>>; \
58 #if defined(Q_OS_WIN) && defined(Q_CC_GNU)
59 # define SWIFT_DECLARE_SEQUENCE_MIXINS(Namespace, T, List)
60 # define SWIFT_DEFINE_SEQUENCE_MIXINS(Namespace, T, List)
62 # define SWIFT_DECLARE_SEQUENCE_MIXINS(Namespace, T, List) SWIFT_TEMPLATE_SEQUENCE_MIXINS(Namespace, T, List, extern)
63 # define SWIFT_DEFINE_SEQUENCE_MIXINS(Namespace, T, List) SWIFT_TEMPLATE_SEQUENCE_MIXINS(Namespace, T, List, )
137 template <
typename It>
160 QVector<T>
toVector() && {
return std::move(m_impl); }
202 # pragma GCC diagnostic push
203 # pragma GCC diagnostic ignored "-Wstrict-overflow"
209 Q_ASSERT(index >= 0 && index < m_impl.size());
210 return m_impl[index];
216 Q_ASSERT(index >= 0 && index < m_impl.size());
217 return m_impl[index];
221 # pragma GCC diagnostic pop
228 return m_impl.front();
235 return m_impl.front();
242 return empty() ? def : m_impl.front();
252 return m_impl.back();
259 return m_impl.back();
266 return empty() ? def : m_impl.back();
279 QString
sizeString()
const {
return QString::number(m_impl.size()); }
282 bool empty()
const {
return m_impl.isEmpty(); }
305 void push_back(
const T &value) { m_impl.push_back(value); }
316 Q_ASSERT(maxElements > 1);
317 if (this->
size() >= (maxElements - 1)) { this->
truncate(maxElements - 1); }
324 Q_ASSERT(maxElements > 1);
325 while (this->
size() >= (maxElements - 1)) { this->
pop_front(); }
330 void push_back(T &&value) { m_impl.push_back(std::move(value)); }
340 void push_back(
CSequence &&other) { std::move(other.begin(), other.end(), std::back_inserter(*
this)); }
343 template <
typename I>
346 std::copy(range.
begin(), range.
end(), std::back_inserter(*
this));
358 template <
typename I>
397 template <
class Predicate>
401 for (
int i : private_ns::findIndices(
size(), [&p,
this](
int i) {
return p((*
this)[i]); }))
410 template <
class Predicate,
class VariantMap>
411 int applyIf(Predicate p,
const VariantMap &newValues,
bool skipEqualValues =
false)
414 for (
auto &value : *
this)
416 if (p(value) && !value.apply(newValues, skipEqualValues).isEmpty()) { count++; }
427 template <
class K1,
class V1,
class VariantMap>
428 int applyIf(K1 key1, V1 value1,
const VariantMap &newValues,
bool skipEqualValues =
false)
437 const auto newEnd = std::remove(
begin(),
end(),
object);
438 const auto count = std::distance(newEnd,
end());
445 template <
class Predicate>
448 const auto newEnd = std::remove_if(
begin(),
end(), p);
449 const auto count = std::distance(newEnd,
end());
455 template <
class K0,
class V0,
class... KeysValues>
456 int removeIf(K0 k0, V0 v0, KeysValues... keysValues)
459 return CSequence::CContainerBase::removeIf(k0, v0, keysValues...);
478 int replace(
const T &original,
const T &replacement)
481 for (
auto &element : *
this)
483 if (element == original)
485 element = replacement;
494 template <
class Predicate>
498 for (
auto &element : *
this)
502 element = replacement;
514 template <
class K1,
class V1>
533 for (
const T &replacement : replacements) { this->
replaceOrAdd(replacement, replacement); }
540 template <
class K1,
class V1>
559 template <
class Predicate>
563 temp.reserve(
size());
565 private_ns::sortIndices(
size(), [&p,
this](
int a,
int b) {
return p((*
this)[a], (*
this)[b]); }))
567 temp.push_back(std::move((*
this)[i]));
569 m_impl = std::move(temp);
575 template <
class K1,
class... Keys>
582 template <
class Predicate>
593 template <
class K1,
class... Keys>
600 template <
class Predicate>
610 template <
class K1,
class... Keys>
617 template <
class Predicate>
629 template <
class K1,
class... Keys>
637 template <
class U,
class Key0,
class... Keys>
641 if (
size() != other.size()) {
return false; }
646 template <
class Predicate>
651 std::stable_sort(copy.begin(), copy.end(), [p](
const T &a,
const T &b) { return p(a) < p(b); });
652 for (
auto it = copy.cbegin(); it != copy.cend();)
654 auto mid = std::adjacent_find(it, copy.cend(), [p](
const T &a,
const T &b) { return p(a) != p(b); });
665 return separateBy([k](
const T &v) {
return std::invoke(k, v); });
669 void detach() { m_impl.detach(); }
Base class for CCollection and CSequence adding mutating operations and CValueObject facility on top ...
bool equalsByKeys(const T &other, Key0 k0, Keys... keys) const
Return true if this container equals another container, considering only the given element members.
static bool equalPointers(const T *a, const U *b)
Efficiently compare addresses of two objects. Return false if types are not compatible.
bool contains(const T &object) const
Return true if there is an element equal to given object. Uses the most efficient implementation avai...
A range is a conceptual container which does not contain any elements of its own, but is constructed ...
const_iterator end() const
Begin and end iterators.
const_iterator begin() const
Begin and end iterators.
Generic sequential container with value semantics.
T value_type
STL compatilibty.
ptrdiff_t difference_type
STL compatibility.
void push_front(const CSequence &other)
Inserts all elements from another sequence at the beginning of this sequence.
const T * const_pointer
STL compatibility.
iterator erase(iterator pos)
Remove the element pointed to by the given iterator.
void push_back(T &&value)
Move-appends an element at the end of the sequence.
int applyIf(K1 key1, V1 value1, const VariantMap &newValues, bool skipEqualValues=false)
Modify by applying a value map to each element matching a particular key/value pair.
int removeIf(K0 k0, V0 v0, KeysValues... keysValues)
Remove elements matching some particular key/value pair(s).
CSequence sortedBy(K1 key1, Keys... keys) const
Return a copy sorted by some particular key(s).
CSequence(const QList< T > &list)
By QList of type T.
friend bool operator>(const CSequence &a, const CSequence &b)
Greater than operator.
int replaceIf(K1 key1, V1 value1, const T &replacement)
Replace elements matching a particular key/value pair.
size_type size() const
Returns number of elements in the sequence.
void sortBy(K1 key1, Keys... keys)
In-place sort by some particular key(s).
void push_front(T &&value)
Move-insert as first element.
Q_REQUIRED_RESULT CSequence partiallySorted(size_type n, Predicate p) const
Return a copy with the smallest n elements at the beginning and sorted.
void pop_back()
Removes an element at the end of the sequence.
~CSequence()=default
Destructor.
T & reference
STL compatibility.
CSequence(std::initializer_list< T > il)
Initializer list constructor.
CSequence()=default
Default constructor.
friend bool operator>=(const CSequence &a, const CSequence &b)
Greater or equal operator.
void unmarshalFromDataStream(QDataStream &stream)
Unmarshal a value from a QDataStream.
const_reverse_iterator crend() const
Returns const iterator at the end of the reversed sequence.
void partiallySortBy(size_type n, K1 key1, Keys... keys)
In-place partially sort by some particular key(s).
int replace(const T &original, const T &replacement)
Replace elements matching the given element with a replacement.
reference operator[](size_type index)
Access an element by its index.
iterator begin()
Returns iterator at the beginning of the sequence.
int replaceIf(Predicate p, const T &replacement)
Replace elements for which a given predicate returns true.
const_reference frontOrDefault() const
Access the first element, or a default-initialized value if the sequence is empty.
const_reverse_iterator crbegin() const
Returns const iterator at the beginning of the reversed sequence.
CSequence findBy(Predicate p) const
Return a copy containing only those elements for which a given predicate returns true.
void replaceOrAdd(const T &original, const T &replacement)
Replace elements matching the given element. If there is no match, push the new element on the end.
iterator erase(iterator it1, iterator it2)
Remove the range of elements between two iterators.
reverse_iterator rbegin()
Returns iterator at the beginning of the reversed sequence.
const_iterator find(const T &object) const
Return an iterator to the first element equal to the given object, or the end iterator if not found....
void truncate(size_type maxSize)
Changes the size of the sequence, if it is bigger than the given size.
void push_back(const CSequence &other)
Appends all elements from another sequence at the end of this sequence.
QVector< T >::const_reverse_iterator const_reverse_iterator
STL compatibility.
void push_back(CSequence &&other)
Appends all elements from another sequence at the end of this sequence. This version moves elements i...
CSequence partiallySortedBy(size_type n, K1 key1, Keys... keys) const
Return a copy partially sorted by some particular key(s).
QVector< T > toVector() &&
Copy of internal vector.
bool unorderedEqualsByKeys(const U &other, Key0 k0, Keys... keys) const
Return true if this container equals another container, considering only the given element members....
const_iterator end() const
Returns const iterator one past the end of the sequence.
Q_REQUIRED_RESULT CSequence sorted(Predicate p) const
Return a copy sorted by a given comparator predicate.
void removeIfInSubset(const CSequence &other)
Remove all elements if they are in other.
bool empty() const
Returns true if the sequence is empty.
CSequence(CSequence &&other)=default
Move constructor.
value_type backOrDefault(value_type def) const
Access the last element, or a default value if the sequence is empty.
QVector< T > toVector() const &
Copy of internal vector.
int size_type
STL compatibility.
friend bool operator<(const CSequence &a, const CSequence &b)
Less than operator.
QVector< T >::reverse_iterator reverse_iterator
STL compatibility.
iterator insert(iterator before, T &&value)
Moves an element into the sequence.
auto separate(Predicate p) const -> QMap< decltype(p(std::declval< T >())), CSequence >
Split up the sequence into subsequences for which the given predicate returns the same value.
value_type frontOrDefault(value_type def) const
Access the first element, or a default-initialized value if the sequence is empty.
friend bool operator==(const CSequence &a, const CSequence &b)
Equals operator.
int removeIf(Predicate p)
Remove elements for which a given predicate returns true.
void push_back(const T &value)
Appends an element at the end of the sequence.
const_reference back() const
Access the last element.
CSequence & operator=(const CSequence &other)=default
Copy assignment.
const_iterator cbegin() const
Returns const iterator at the beginning of the sequence.
friend bool operator<=(const CSequence &a, const CSequence &b)
Less or equal than operator.
friend bool operator!=(const CSequence &a, const CSequence &b)
Not equals operator.
CSequence(QList< T > &&list)
By QList of type T.
CSequence(const CSequence &other)=default
Copy constructor.
void marshalToDataStream(QDataStream &stream) const
Marshal a value to a QDataStream.
QVector< T >::iterator iterator
STL compatibility.
const_reverse_iterator rend() const
Returns const iterator at the end of the reversed sequence.
CSequence(It first, It last)
Range constructor.
void partiallySort(size_type n, Predicate p)
In-place move the smallest n elements to the beginning and sort them.
void swap(CSequence &other) noexcept
Swap this sequence with another.
CSequence join(const CRange< I > &range) const
Concatenates a sequence and a range and returns the result.
int applyIf(Predicate p, const VariantMap &newValues, bool skipEqualValues=false)
Modify by applying a value map to each element for which a given predicate returns true.
QVector< T >::const_iterator const_iterator
STL compatibility.
const_reference backOrDefault() const
Access the last element, or a default value if the sequence is empty.
void push_frontMaxElements(const T &value, int maxElements)
Insert as first element by keep maxElements.
T key_type
STL compatibility.
reference front()
Access the first element.
const_reference front() const
Access the first element.
void clear()
Removes all elements in the sequence.
reverse_iterator rend()
Returns iterator at the end of the reversed sequence.
QString sizeString() const
Convenience function.
iterator find(const T &object)
Return an iterator to the first element equal to the given object, or the end iterator if not found....
void push_front(const T &value)
Insert as first element.
reference back()
Access the last element.
void push_back(const CRange< I > &range)
Appends all elements from a range at the end of this sequence.
Q_REQUIRED_RESULT CSequence reversed() const
Reversed order.
void reverse()
In-place reverse.
int remove(const T &object)
Remove all elements equal to the given object, if it is contained.
CSequence & operator=(CSequence &&other)=default
Move assignment.
void replaceOrAdd(K1 key1, V1 value1, const T &replacement)
Replace elements matching a particular key/value pair. If there is no match, push the new element on ...
void replaceOrAdd(const T &replacement)
Replace elements matching the given element. If there is no match, push the new element on the end.
const_iterator cend() const
Returns const iterator one past the end of the sequence.
int removeIfIn(const CSequence &other)
Remove all elements if they are in other.
void push_backMaxElements(const T &value, int maxElements)
Insert as last element by keep maxElements.
bool isEmpty() const
Synonym for empty.
iterator insert(iterator before, const T &value)
Inserts an element into the sequence.
void replaceOrAdd(const CSequence< T > &replacements)
Replace or add given elements.
CSequence join(const CSequence &other) const
Concatenates two sequences and returns the result.
auto separateBy(Key k) const -> QMap< decltype(std::invoke(k, std::declval< T >())), CSequence >
Split up the sequence into subsequences of elements having the same value for the given key.
const_iterator begin() const
Returns const iterator at the beginning of the sequence.
iterator end()
Returns iterator one past the end of the sequence.
T * pointer
STL compatibility.
int sizeInt() const
Avoid compiler warnings when using with int.
const_reference operator[](size_type index) const
Access an element by its index.
void pop_front()
Removes an element at the front of the sequence.
const T & const_reference
STL compatibility.
void sort(Predicate p)
In-place sort by a given comparator predicate.
const_reverse_iterator rbegin() const
Returns const iterator at the beginning of the reversed sequence.
CRTP class template to generate non-member QDataStream streaming operators.
CRTP class template from which a derived class can inherit icon-related functions.
auto MemberEqual(Ts... vs)
Predicate which tests whether some member functions return some values.
auto MemberLess(Ts... vs)
Predicate which compares the return values of some member functions of two objects.
Free functions in swift::misc.
auto makeRange(I begin, I2 end) -> CRange< I >
Returns a CRange constructed from begin and end iterators of deduced types.
auto removeIfIn(I begin1, I end1, J begin2, J end2)
Removes those elements in range 1 that appear also in range 2 leaving only those that do not appear i...
#define SWIFT_NO_INLINE
Prevent function inlining.
#define SWIFT_MISC_EXPORT
Export a class or function from the library.