1// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
2// Distributed under MIT license, or public domain if desired and
3// recognized in your jurisdiction.
4// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5
6// included by json_value.cpp
7
8namespace Json {
9
10// //////////////////////////////////////////////////////////////////
11// //////////////////////////////////////////////////////////////////
12// //////////////////////////////////////////////////////////////////
13// class ValueIteratorBase
14// //////////////////////////////////////////////////////////////////
15// //////////////////////////////////////////////////////////////////
16// //////////////////////////////////////////////////////////////////
17
18ValueIteratorBase::ValueIteratorBase() : current_() {}
19
20ValueIteratorBase::ValueIteratorBase(
21    const Value::ObjectValues::iterator& current)
22    : current_(current), isNull_(false) {}
23
24Value& ValueIteratorBase::deref() { return current_->second; }
25const Value& ValueIteratorBase::deref() const { return current_->second; }
26
27void ValueIteratorBase::increment() { ++current_; }
28
29void ValueIteratorBase::decrement() { --current_; }
30
31ValueIteratorBase::difference_type
32ValueIteratorBase::computeDistance(const SelfType& other) const {
33#ifdef JSON_USE_CPPTL_SMALLMAP
34  return other.current_ - current_;
35#else
36  // Iterator for null value are initialized using the default
37  // constructor, which initialize current_ to the default
38  // std::map::iterator. As begin() and end() are two instance
39  // of the default std::map::iterator, they can not be compared.
40  // To allow this, we handle this comparison specifically.
41  if (isNull_ && other.isNull_) {
42    return 0;
43  }
44
45  // Usage of std::distance is not portable (does not compile with Sun Studio 12
46  // RogueWave STL,
47  // which is the one used by default).
48  // Using a portable hand-made version for non random iterator instead:
49  //   return difference_type( std::distance( current_, other.current_ ) );
50  difference_type myDistance = 0;
51  for (Value::ObjectValues::iterator it = current_; it != other.current_;
52       ++it) {
53    ++myDistance;
54  }
55  return myDistance;
56#endif
57}
58
59bool ValueIteratorBase::isEqual(const SelfType& other) const {
60  if (isNull_) {
61    return other.isNull_;
62  }
63  return current_ == other.current_;
64}
65
66void ValueIteratorBase::copy(const SelfType& other) {
67  current_ = other.current_;
68  isNull_ = other.isNull_;
69}
70
71Value ValueIteratorBase::key() const {
72  const Value::CZString czstring = (*current_).first;
73  if (czstring.data()) {
74    if (czstring.isStaticString())
75      return Value(StaticString(czstring.data()));
76    return Value(czstring.data(), czstring.data() + czstring.length());
77  }
78  return Value(czstring.index());
79}
80
81UInt ValueIteratorBase::index() const {
82  const Value::CZString czstring = (*current_).first;
83  if (!czstring.data())
84    return czstring.index();
85  return Value::UInt(-1);
86}
87
88String ValueIteratorBase::name() const {
89  char const* keey;
90  char const* end;
91  keey = memberName(&end);
92  if (!keey)
93    return String();
94  return String(keey, end);
95}
96
97char const* ValueIteratorBase::memberName() const {
98  const char* cname = (*current_).first.data();
99  return cname ? cname : "";
100}
101
102char const* ValueIteratorBase::memberName(char const** end) const {
103  const char* cname = (*current_).first.data();
104  if (!cname) {
105    *end = nullptr;
106    return nullptr;
107  }
108  *end = cname + (*current_).first.length();
109  return cname;
110}
111
112// //////////////////////////////////////////////////////////////////
113// //////////////////////////////////////////////////////////////////
114// //////////////////////////////////////////////////////////////////
115// class ValueConstIterator
116// //////////////////////////////////////////////////////////////////
117// //////////////////////////////////////////////////////////////////
118// //////////////////////////////////////////////////////////////////
119
120ValueConstIterator::ValueConstIterator() = default;
121
122ValueConstIterator::ValueConstIterator(
123    const Value::ObjectValues::iterator& current)
124    : ValueIteratorBase(current) {}
125
126ValueConstIterator::ValueConstIterator(ValueIterator const& other)
127    : ValueIteratorBase(other) {}
128
129ValueConstIterator& ValueConstIterator::
130operator=(const ValueIteratorBase& other) {
131  copy(other);
132  return *this;
133}
134
135// //////////////////////////////////////////////////////////////////
136// //////////////////////////////////////////////////////////////////
137// //////////////////////////////////////////////////////////////////
138// class ValueIterator
139// //////////////////////////////////////////////////////////////////
140// //////////////////////////////////////////////////////////////////
141// //////////////////////////////////////////////////////////////////
142
143ValueIterator::ValueIterator() = default;
144
145ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
146    : ValueIteratorBase(current) {}
147
148ValueIterator::ValueIterator(const ValueConstIterator& other)
149    : ValueIteratorBase(other) {
150  throwRuntimeError("ConstIterator to Iterator should never be allowed.");
151}
152
153ValueIterator::ValueIterator(const ValueIterator& other) = default;
154
155ValueIterator& ValueIterator::operator=(const SelfType& other) {
156  copy(other);
157  return *this;
158}
159
160} // namespace Json
161