-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsingleton_iterator.hpp
76 lines (56 loc) · 2.23 KB
/
singleton_iterator.hpp
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
// Copyright Morten Bendiksen 2014 - 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MEDIASEQUENCER_PLUGIN_UTIL_XPATH_SINGLETON_ITERATOR
#define MEDIASEQUENCER_PLUGIN_UTIL_XPATH_SINGLETON_ITERATOR
#include <boost/iterator/iterator_facade.hpp>
#include <boost/range/iterator_range.hpp>
#include <memory>
namespace mediasequencer { namespace plugin { namespace util { namespace xpath {
// An iterator over a single node. It is given one node and the first increment
// will take it past the end.
template <typename Element>
class singleton_iterator : public boost::iterator_facade<singleton_iterator<Element>,
Element, boost::forward_traversal_tag> {
public:
singleton_iterator() {};
singleton_iterator(singleton_iterator const& other)
: context(other.context) {};
singleton_iterator(singleton_iterator&& other)
: context(std::move(other.context)) {};
singleton_iterator operator=(singleton_iterator const& other) {
context = other.context;
return *this;
}
singleton_iterator operator=(singleton_iterator&& other) {
context = std::move(other.context);
return *this;
}
explicit singleton_iterator(Element&& context)
: context(new Element(std::move(context))) {}
explicit singleton_iterator(Element const& context)
: context(new Element(context)) {}
private:
friend class boost::iterator_core_access;
void increment() {
context.reset();
}
bool equal(singleton_iterator const& other) const {
return this->context == other.context;
}
Element& dereference() const {
return *context;
}
std::shared_ptr<Element> context;
};
template <typename Element>
boost::iterator_range
<singleton_iterator<typename std::remove_reference<Element>::type> >
singleton(Element&& n) {
return boost::make_iterator_range
(singleton_iterator<typename std::remove_reference<Element>::type>(std::forward<Element>(n)),
singleton_iterator<typename std::remove_reference<Element>::type>());
}
}}}}
#endif // MEDIASEQUENCER_PLUGIN_UTIL_XPATH_SINGLETON_ITERATOR