-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
150e30d
commit 90770ed
Showing
4 changed files
with
136 additions
and
2 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
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 |
---|---|---|
@@ -0,0 +1,114 @@ | ||
#pragma once | ||
|
||
// An internal implementation of folly's enumerate: https://github.com/facebook/folly/blob/main/folly/container/Enumerate.h | ||
|
||
#include <iterator> | ||
#include <memory> | ||
|
||
#include <arcticdb/util/preprocess.hpp> | ||
|
||
namespace arcticdb { | ||
|
||
namespace detail { | ||
|
||
template <class T> | ||
struct MakeConst { | ||
using type = const T; | ||
}; | ||
template <class T> | ||
struct MakeConst<T&> { | ||
using type = const T&; | ||
}; | ||
template <class T> | ||
struct MakeConst<T*> { | ||
using type = const T*; | ||
}; | ||
|
||
template <class Iterator> | ||
class Enumerator { | ||
public: | ||
constexpr explicit Enumerator(Iterator it) : it_(std::move(it)) {} | ||
|
||
class Proxy { | ||
public: | ||
using difference_type = ssize_t; | ||
using value_type = typename std::iterator_traits<Iterator>::value_type; | ||
using reference = typename std::iterator_traits<Iterator>::reference; | ||
using pointer = typename std::iterator_traits<Iterator>::pointer; | ||
using iterator_category = std::input_iterator_tag; | ||
|
||
ARCTICDB_FORCE_INLINE constexpr explicit Proxy(const Enumerator& enumerator) | ||
: index(enumerator.idx_), element(*enumerator.it_) {} | ||
|
||
ARCTICDB_FORCE_INLINE constexpr reference operator*() { return element; } | ||
ARCTICDB_FORCE_INLINE constexpr pointer operator->() { | ||
return std::addressof(element); | ||
} | ||
|
||
ARCTICDB_FORCE_INLINE constexpr typename MakeConst<reference>::type | ||
operator*() const { | ||
return element; | ||
} | ||
ARCTICDB_FORCE_INLINE constexpr typename MakeConst<pointer>::type operator->() | ||
const { | ||
return std::addressof(element); | ||
} | ||
|
||
public: | ||
const size_t index; | ||
reference element; | ||
}; | ||
|
||
ARCTICDB_FORCE_INLINE constexpr Proxy operator*() const { return Proxy(*this); } | ||
|
||
ARCTICDB_FORCE_INLINE constexpr Enumerator& operator++() { | ||
++it_; | ||
++idx_; | ||
return *this; | ||
} | ||
|
||
template <typename OtherIterator> | ||
ARCTICDB_FORCE_INLINE constexpr bool operator==( | ||
const Enumerator<OtherIterator>& rhs) const { | ||
return it_ == rhs.it_; | ||
} | ||
|
||
template <typename OtherIterator> | ||
ARCTICDB_FORCE_INLINE constexpr bool operator!=( | ||
const Enumerator<OtherIterator>& rhs) const { | ||
return !(it_ == rhs.it_); | ||
} | ||
|
||
private: | ||
template <typename OtherIterator> | ||
friend class Enumerator; | ||
|
||
Iterator it_; | ||
size_t idx_ = 0; | ||
}; | ||
|
||
template <class RangeType> | ||
class RangeEnumerator { | ||
RangeType r_; | ||
using BeginIteratorType = decltype(std::declval<RangeType>().begin()); | ||
using EndIteratorType = decltype(std::declval<RangeType>().end()); | ||
|
||
public: | ||
constexpr explicit RangeEnumerator(RangeType&& r) : r_(std::forward<RangeType>(r)) {} | ||
|
||
constexpr Enumerator<BeginIteratorType> begin() { | ||
return Enumerator<BeginIteratorType>(r_.begin()); | ||
} | ||
constexpr Enumerator<EndIteratorType> end() { | ||
return Enumerator<EndIteratorType>(r_.end()); | ||
} | ||
}; | ||
|
||
} // namespace detail | ||
|
||
template <class RangeType> | ||
constexpr detail::RangeEnumerator<RangeType> enumerate(RangeType&& r) { | ||
return detail::RangeEnumerator<RangeType>(std::forward<RangeType>(r)); | ||
} | ||
|
||
} // namespace arcticdb |
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
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 |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#include <gtest/gtest.h> | ||
#include <arcticdb/util/enumerate.hpp> | ||
#include <arcticdb/log/log.hpp> | ||
|
||
TEST(Enumerate, Vector) { | ||
std::vector<int> vec = {1, 2, 3, 4}; | ||
|
||
using namespace arcticdb; | ||
|
||
for(auto&& [thing, index] : enumerate(vec)) { | ||
arcticdb::log::version().info("{} : {}", thing, index); | ||
} | ||
} | ||
|