File: throwing_iterator.hpp

package info (click to toggle)
libpmemobj-cpp 1.12-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 8,388 kB
  • sloc: cpp: 136,076; sh: 1,022; perl: 381; ansic: 163; makefile: 13
file content (170 lines) | stat: -rw-r--r-- 3,237 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Copyright 2019, Intel Corporation
//
// Modified to test pmem::obj containers
//
#ifndef THROWING_ITERATOR_HPP
#define THROWING_ITERATOR_HPP

#include <iterator>

template <typename T>
struct throwing_it {
  typedef std::bidirectional_iterator_tag iterator_category;
  typedef std::ptrdiff_t difference_type;
  typedef const T value_type;
  typedef const T *pointer;
  typedef const T &reference;

  enum throwing_action {
	TAIncrement,
	TADecrement,
	TADereference,
	TAAssignment,
	TAComparison
  };

  //  Constructors
  throwing_it()
	  : begin_(nullptr),
		end_(nullptr),
		current_(nullptr),
		action_(TADereference),
		index_(0)
  {
  }
  throwing_it(const T *first, const T *last, size_t index = 0,
				   throwing_action action = TADereference)
	  : begin_(first),
		end_(last),
		current_(first),
		action_(action),
		index_(index)
  {
  }
  throwing_it(const throwing_it &rhs)
	  : begin_(rhs.begin_),
		end_(rhs.end_),
		current_(rhs.current_),
		action_(rhs.action_),
		index_(rhs.index_)
  {
  }
  throwing_it &
  operator=(const throwing_it &rhs)
  {
	if (action_ == TAAssignment) {
	  if (index_ == 0)
		throw std::runtime_error(
			"throw from iterator assignment");
	  else
		--index_;
	}
	begin_ = rhs.begin_;
	end_ = rhs.end_;
	current_ = rhs.current_;
	action_ = rhs.action_;
	index_ = rhs.index_;
	return *this;
  }

  //  iterator operations
  reference operator*() const
  {
	if (action_ == TADereference) {
	  if (index_ == 0)
		throw std::runtime_error(
			"throw from iterator dereference");
	  else
		--index_;
	}
	return *current_;
  }

  throwing_it &
  operator++()
  {
	if (action_ == TAIncrement) {
	  if (index_ == 0)
		throw std::runtime_error(
			"throw from iterator increment");
	  else
		--index_;
	}
	++current_;
	return *this;
  }

  throwing_it
  operator++(int)
  {
	throwing_it temp = *this;
	++(*this);
	return temp;
  }

  throwing_it &
  operator--()
  {
	if (action_ == TADecrement) {
	  if (index_ == 0)
		throw std::runtime_error(
			"throw from iterator decrement");
	  else
		--index_;
	}
	--current_;
	return *this;
  }

  throwing_it
  operator--(int)
  {
	throwing_it temp = *this;
	--(*this);
	return temp;
  }

  bool
  operator==(const throwing_it &rhs) const
  {
	if (action_ == TAComparison) {
	  if (index_ == 0)
		throw std::runtime_error(
			"throw from iterator comparison");
	  else
		--index_;
	}
	bool atEndL = current_ == end_;
	bool atEndR = rhs.current_ == rhs.end_;
	if (atEndL != atEndR)
	  return false; // one is at the end (or empty), the other
	// is not.
	if (atEndL)
	  return true; // both are at the end (or empty)
	return current_ == rhs.current_;
  }

  bool
  operator!=(const throwing_it &rhs) const
  {
	return !(*this == rhs);
  }

 private:
  const T *begin_;
  const T *end_;
  const T *current_;
  throwing_action action_;
  mutable size_t index_;
};

#endif /* THROWING_ITERATOR_HPP */