This repository has been archived by the owner on Jan 3, 2024. It is now read-only.
forked from fnc12/sqlite_orm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathiterator.h
101 lines (82 loc) · 3.08 KB
/
iterator.h
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
#pragma once
#include <sqlite3.h>
#include <memory> // std::shared_ptr, std::unique_ptr, std::make_shared
#include <type_traits> // std::decay
#include <utility> // std::move
#include <iterator> // std::input_iterator_tag
#include <system_error> // std::system_error
#include <functional> // std::bind
#include "functional/cxx_universal.h"
#include "statement_finalizer.h"
#include "error_code.h"
#include "object_from_column_builder.h"
#include "storage_lookup.h"
#include "util.h"
namespace sqlite_orm {
namespace internal {
template<class V>
struct iterator_t {
using view_type = V;
using value_type = typename view_type::mapped_type;
protected:
/**
* shared_ptr is used over unique_ptr here
* so that the iterator can be copyable.
*/
std::shared_ptr<sqlite3_stmt> stmt;
// only null for the default constructed iterator
view_type* view = nullptr;
/**
* shared_ptr is used over unique_ptr here
* so that the iterator can be copyable.
*/
std::shared_ptr<value_type> current;
void extract_value() {
auto& dbObjects = obtain_db_objects(this->view->storage);
this->current = std::make_shared<value_type>();
object_from_column_builder<value_type> builder{*this->current, this->stmt.get()};
pick_table<value_type>(dbObjects).for_each_column(builder);
}
void next() {
this->current.reset();
if(sqlite3_stmt* stmt = this->stmt.get()) {
perform_step(stmt, std::bind(&iterator_t::extract_value, this));
if(!this->current) {
this->stmt.reset();
}
}
}
public:
using difference_type = ptrdiff_t;
using pointer = value_type*;
using reference = value_type&;
using iterator_category = std::input_iterator_tag;
iterator_t(){};
iterator_t(statement_finalizer stmt_, view_type& view_) : stmt{std::move(stmt_)}, view{&view_} {
next();
}
const value_type& operator*() const {
if(!this->stmt || !this->current) {
throw std::system_error{orm_error_code::trying_to_dereference_null_iterator};
}
return *this->current;
}
const value_type* operator->() const {
return &(this->operator*());
}
iterator_t<V>& operator++() {
next();
return *this;
}
void operator++(int) {
this->operator++();
}
bool operator==(const iterator_t& other) const {
return this->current == other.current;
}
bool operator!=(const iterator_t& other) const {
return !(*this == other);
}
};
}
}