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