ComponentKit/TransactionalDataSources/Common/CKIndexTransform.h (51 lines of code) (raw):
// Copyright 2004-present Facebook. All Rights Reserved.
#import <ComponentKit/CKDefines.h>
#if CK_NOT_SWIFT
#import <vector>
#import <Foundation/NSIndexSet.h>
#import <Foundation/NSRange.h>
namespace CK {
struct IndexTransform final {
explicit IndexTransform(NSIndexSet *indexes);
auto applyOffsetToIndex(NSInteger index) const -> NSInteger;
auto findRangeAndApplyOffsetToIndex(NSInteger index) const -> NSInteger;
private:
struct RangeOffset {
NSRange range;
NSInteger offset;
};
std::vector<RangeOffset> _rangeOffsets;
};
struct RemovalIndexTransform final {
explicit RemovalIndexTransform(NSIndexSet *indexes) : _t(indexes) {};
/**
Given an item index before applying a transform, returns a new index of the same item. For example, given a transform
created with indexes `{0, 1}` and an input index of 2, this method will return 0 since there were two items removed
before index 2.
@param index Item index before applying the trasform.
@return Item index after the transform is applied, or `NSNotFound` if the item is no longer present after applying
the transform.
*/
auto applyToIndex(NSInteger index) const -> NSInteger { return _t.applyOffsetToIndex(index); }
/**
Given an item index after applying the transform, returns an index the same item had before application. For example,
given a transform created with indexes `{0, 1}` and an input index of 0, this method will return 2 since there were
two items previously before index 0.
@param index Item index after applying the transform.
@return Item index before the transform was applied. This method never returns `NSNotFound`.
*/
auto applyInverseToIndex(NSInteger index) const -> NSInteger { return _t.findRangeAndApplyOffsetToIndex(index); }
private:
IndexTransform _t;
};
struct InsertionIndexTransform final {
explicit InsertionIndexTransform(NSIndexSet *indexes) : _t(indexes) {};
auto applyToIndex(NSInteger index) const -> NSInteger { return _t.findRangeAndApplyOffsetToIndex(index); }
auto applyInverseToIndex(NSInteger index) const -> NSInteger { return _t.applyOffsetToIndex(index); }
private:
IndexTransform _t;
};
template <typename T1, typename T2>
struct CompositeIndexTransform final {
CompositeIndexTransform(T1 &&t1, T2 &&t2)
: _t1(std::forward<T1>(t1)), _t2(std::forward<T2>(t2)) {}
auto applyToIndex(NSInteger index) const -> NSInteger
{
auto const i = _t1.applyToIndex(index);
return i != NSNotFound ? _t2.applyToIndex(i) : NSNotFound;
}
auto applyInverseToIndex(NSInteger index) const -> NSInteger { return _t2.applyInverseToIndex(_t1.applyInverseToIndex(index)); }
private:
T1 _t1;
T2 _t2;
};
template <typename T1, typename T2>
static auto makeCompositeIndexTransform(T1 &&t1, T2 &&t2) {
return CompositeIndexTransform<T1, T2>(std::forward<T1>(t1), std::forward<T2>(t2));
}
}
#endif