blob: 3cb959291cab86271bc138ff907c24fff6341727 (
plain)
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
|
/**
** \file parse/tweast.hxx
** \brief implements inline methods of parse/tweast.hh
*/
#pragma once
#include <algorithm>
#include <boost/algorithm/string/replace.hpp>
#include <misc/algorithm.hh>
#include <misc/error.hh>
#include <parse/tweast.hh>
namespace parse
{
template <typename T> T& Tweast::append_(unsigned&, T& data) const
{
return data;
}
template <typename T> Tweast& Tweast::operator<<(const T& t)
{
input_ << append_(count_, t);
return *this;
}
template <typename T> T* Tweast::take(unsigned s)
{
T* t = nullptr;
try
{
t = MetavarMap<T>::take_(s);
}
catch (const std::range_error& e)
{
// Print the contents of the Tweast before dying.
misc::error error;
error << e.what() << std::endl;
error << *this;
error.ice_here();
}
return t;
}
template <typename T>
void Tweast::move_metavars_(Tweast& tweast, std::string& input)
{
using metavars_type = MetavarMap<T>;
for (const typename metavars_type::map_type::value_type& var :
tweast.metavars_type::map_)
{
// Append the variable from VAR to the enclosing Tweast.
unsigned old_num = var.first;
// Warning, this is not thread-safe.
unsigned new_num = count_;
T* data = var.second;
metavars_type::map_[new_num] = data;
++count_;
// Rename metavariables according to the numbering scheme
// within the input string.
std::string old_str = metavars_type::show(old_num);
std::string new_str = metavars_type::show(new_num);
// FIXME: This is inefficient, since the string is viewed
// each time a metavariable is processed. Better store
// each (old_num, new_num) pair in a map, and process
// the string in a single pass.
boost::algorithm::replace_first(input, old_str, new_str);
}
tweast.metavars_type::map_.clear();
}
} // namespace parse
|