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