Skip to content

Commit

Permalink
Disallow wrapping input iterators.
Browse files Browse the repository at this point in the history
Iterator::Next() has this line:

  if (it_ != end(*self_)) return &*it_++;

The reference returned by *it_ doesn't have to be valid after the iterator is
incremented; input iterators might create these values on the fly (and don't
store them).

TGP: https://test.corp.google.com/ui#id=OCL:387627910:BASE:391752438:1629382590029:3d364c60

See also: http://g/c-users/xvDy7spjpeM

PiperOrigin-RevId: 392401203
  • Loading branch information
CLIF Team authored and Ralf W. Grosse-Kunstleve committed Aug 29, 2021
1 parent 253ad15 commit fbc9fcf
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 1 deletion.
6 changes: 6 additions & 0 deletions clif/python/stltypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ headers are included.
#include "Python.h"
#include <functional>
#include <deque>
#include <iterator>
#include <list>
#include <queue>
#include <stack>
Expand Down Expand Up @@ -284,6 +285,11 @@ class Iterator {
static_assert(std::is_same<T&,
typename std::iterator_traits<ContainerIter>::reference>::value,
"Iterators returning proxy refererence not currently supported.");
static_assert(
std::is_base_of_v<
std::forward_iterator_tag,
typename std::iterator_traits<ContainerIter>::iterator_category>,
"Input iterators are not currently supported.");

const T* Next() noexcept {
if (!self_) return nullptr;
Expand Down
4 changes: 3 additions & 1 deletion clif/testing/iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@
// It's using exceptions to demonstrate they are handled correctly by CLIF.

#include <array>
#include <iterator>

namespace clif_iterator_test {

template<typename T, size_t N>
class Ring {
public:
// Mimic std containers, so that Ring::const_iterator is a real thing.
class const_iterator: public std::iterator<std::input_iterator_tag, T> {
class const_iterator: public std::iterator<std::forward_iterator_tag, T> {
public:
// CLIF requires both or neither of copy/move constructors and copy/move
// copy assignment operators.
Expand Down Expand Up @@ -59,6 +60,7 @@ class Ring {
return start_ != o.start_ || offset_ != o.offset_;
}
const T& operator*() const { return *(start_+offset_); }
const T* operator->() const { return start_ + offset_; }

private:
size_t offset_; // Ring<T>::data_ current index.
Expand Down

0 comments on commit fbc9fcf

Please sign in to comment.