Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
list-diff-application.hpp
Go to the documentation of this file.
1/*
2 LIST-DIFF-APPLICATION.hpp - consume and apply a list diff
3
4 Copyright (C)
5 2014, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
30#ifndef LIB_DIFF_LIST_DIFF_APPLICATION_H
31#define LIB_DIFF_LIST_DIFF_APPLICATION_H
32
33
35#include "lib/format-string.hpp"
36
37#include <algorithm>
38#include <vector>
39#include <tuple>
40
41
42namespace lib {
43namespace diff{
44
45 using util::_Fmt;
46 using std::vector;
47 using std::move;
48
62 template<typename E, typename...ARGS>
63 class DiffApplicationStrategy<vector<E,ARGS...>>
64 : public ListDiffInterpreter<E>
65 {
66 using Vec = vector<E,ARGS...>;
67 using Iter = Vec::iterator;
68
72
73 bool
75 {
76 return pos_ == orig_.end();
77 }
78
79 void
80 __expect_in_target (E const& elm, Literal oper)
81 {
82 if (end_of_target())
83 throw error::State(_Fmt("Unable to %s element %s from target as demanded; "
84 "no (further) elements in target sequence") % oper % elm
85 , LERR_(DIFF_CONFLICT));
86 if (*pos_ != elm)
87 throw error::State(_Fmt("Unable to %s element %s from target as demanded; "
88 "found element %s on current target position instead")
89 % oper % elm % *pos_
90 , LERR_(DIFF_CONFLICT));
91 }
92
93 void
95 {
96 if (end_of_target())
97 throw error::State(_Fmt("Premature end of target sequence, still expecting element %s; "
98 "unable to apply diff further.") % elm
99 , LERR_(DIFF_CONFLICT));
100 }
101
102 void
103 __expect_found (E const& elm, Iter const& targetPos)
104 {
105 if (targetPos == orig_.end())
106 throw error::State(_Fmt("Premature end of sequence; unable to locate "
107 "element %s in the remainder of the target.") % elm
108 , LERR_(DIFF_CONFLICT));
109 }
110
111
112 /* == Implementation of the diff application primitives == */
113
114 void
115 ins (E const& elm) override
116 {
117 seq_.push_back(elm);
118 }
119
120 void
121 del (E const& elm) override
122 {
123 __expect_in_target(elm, "remove");
124 ++pos_;
125 }
126
127 void
128 pick (E const& elm) override
129 {
130 __expect_in_target(elm, "pick");
131 seq_.push_back (move(*pos_));
132 ++pos_;
133 }
134
135 void
136 skip (E const& elm) override
137 {
138 __expect_further_elements (elm);
139 ++pos_;
140 } // assume the actual content has been moved away by a previous find()
141
142 void
143 find (E const& elm) override
144 {
145 __expect_further_elements (elm);
146 Iter found = std::find(pos_, orig_.end(), elm);
147 __expect_found (elm, found);
148 seq_.push_back (move(*found));
149 } // consume and leave waste, expected to be cleaned-up by skip() later
150
151
152 public:
153 explicit
154 DiffApplicationStrategy(vector<E>& targetVector)
155 : seq_(targetVector)
156 { }
157
158 void
160 {
161 swap (seq_, orig_);
162 seq_.reserve (orig_.size() * 120 / 100); // heuristics for storage pre-allocation
163 pos_ = orig_.begin();
164 }
165
166 void
168 {
169 if (not end_of_target())
170 throw error::State(_Fmt("Not all source data consumed after diff application. "
171 "Element %s waiting to be consumed") % *pos_
172 , LERR_(DIFF_STRUCTURE));
173 // discard storage
174 orig_.clear();
175 }
176 };
177
178
179
180
181
182}} // namespace lib::diff
183#endif /*LIB_DIFF_LIST_DIFF_APPLICATION_H*/
Inline string literal.
Definition symbol.hpp:78
Interpreter interface to define the operations ("verbs"), which describe differences or changes in a ...
Definition list-diff.hpp:64
A front-end for using printf-style formatting.
#define LERR_(_NAME_)
Definition error.hpp:45
Front-end for printf-style string template interpolation.
A token language to represent changes in a list of elements.
Extension point: define how a specific diff language can be applied to elements in a concrete contain...
Implementation namespace for support and library code.
LumieraError< LERR_(STATE)> State
Definition error.hpp:209
constexpr IT find(IT, IT, V const &)