Line data Source code
1 :
2 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 : Copyright (c) 2025 The plumed team
4 : (see the PEOPLE file at the root of the distribution for a list of names)
5 :
6 : See http://www.plumed.org for more information.
7 :
8 : This file is part of plumed, version 2.
9 :
10 : plumed is free software: you can redistribute it and/or modify
11 : it under the terms of the GNU Lesser General Public License as published by
12 : the Free Software Foundation, either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : plumed is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU Lesser General Public License for more details.
19 :
20 : You should have received a copy of the GNU Lesser General Public License
21 : along with plumed. If not, see <http://www.gnu.org/licenses/>.
22 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
23 : #include "TokenizedLine.h"
24 :
25 : #include <iterator>
26 : #include <string>
27 : #include <algorithm>
28 :
29 : namespace PLMD {
30 1008845 : TokenizedLine::line wholeLineReplicas(const std::string& myLine) {
31 : //NOTE: as now (exactly like before this PR) a vector will not accept only the first element as replicas:
32 : // - @replicas:{1,2,3},4,5 do not work (KEY={@replicas:{1,2,3},4,5})
33 : // - @replicas:{1,4,5},{2,4,5},{3,4,5} works (KEY=@replicas:{{1,4,5},{2,4,5},{3,4,5}}), it should be equivalent to the line above
34 : // - 1,@replicas:{2,3,4},5 works (KEY={1,@replicas{2,3,4},5})
35 : // the problem will be solved by passing to TokenizedLine the line with the first parentheses not removed
36 : //
37 1008845 : if(Tools::startWith(myLine,Tools::replicaToken)) {
38 : auto tr = Tools::getWords(
39 136 : myLine.substr(Tools::replicaToken.length()),
40 68 : "\t\n ,");
41 68 : tr.insert(tr.begin(),myLine);
42 : return tr;
43 68 : } else {
44 2017554 : return {myLine};
45 : }
46 1008777 : }
47 :
48 : inline auto render(const TokenizedLine::line& l) {
49 316004 : return l[0];
50 : }
51 :
52 : template <typename IT>
53 66033 : auto mapCreator(IT k, IT const end) {
54 : TokenizedLine::mapType toret;
55 1098847 : for (; k!=end; ++k) {
56 1032814 : auto eqpos=k->find('=');
57 : // We do not want to modify the original line
58 1032814 : std::string key = k->substr(0,eqpos);
59 : std::transform(key.begin(),key.end(),key.begin(),::toupper);
60 1032814 : if(eqpos != std::string::npos) {
61 3026535 : toret[key]=wholeLineReplicas(k->substr(eqpos+1));
62 : } else {
63 : //is a flag
64 : //maybe giving it a special value to confirm that it is indeed a flag?
65 23969 : toret[key].emplace_back("");
66 : }
67 : }
68 66033 : return toret;
69 : }
70 :
71 0 : TokenizedLine::TokenizedLine(vectorIt begin, vectorIt end):
72 0 : tokens(mapCreator(begin, end)) {}
73 :
74 66033 : TokenizedLine::TokenizedLine(const_vectorIt begin,
75 66033 : const_vectorIt end):
76 66033 : tokens(mapCreator(begin, end)) {}
77 :
78 0 : TokenizedLine::TokenizedLine(const std::vector<std::string>& dataline):
79 0 : PLMD::TokenizedLine(dataline.begin(),dataline.end()) {}
80 :
81 16686 : std::string TokenizedLine::convertToString(bool alsoClear) {
82 : std::string output;
83 332687 : for(auto p=tokens.begin(); p!=tokens.end(); ++p) {
84 : auto tmp = render(p->second);
85 316001 : if( tmp.find(" " )!=std::string::npos ) {
86 1692 : output += " " + p->first+ "={" + tmp + "}";
87 : } else {
88 946311 : output += " "+ p->first+ "=" + tmp;
89 : }
90 : }
91 16686 : if(alsoClear) {
92 : tokens.clear();
93 : }
94 16686 : return output;
95 : }
96 :
97 2 : std::string TokenizedLine::keyList(std::string_view sep ) {
98 2 : std::string mylist="";
99 : int i=0;
100 2 : std::string separator = "";
101 4 : for(const auto & l:tokens) {
102 2 : mylist = mylist + separator + l.first;
103 2 : if(i==0) {
104 2 : separator = std::string(sep);
105 2 : ++i;
106 : }
107 : }
108 2 : return mylist;
109 4 : }
110 :
111 0 : std::size_t TokenizedLine::size() const {
112 0 : return tokens.size();
113 : }
114 :
115 84447 : bool TokenizedLine::empty() const {
116 84447 : return tokens.empty();
117 : }
118 :
119 3 : std::string TokenizedLine::getKeyword(std::string_view key) const {
120 : auto keyArg = tokens.find(key);
121 3 : if( keyArg != tokens.end()) {
122 6 : return std::string(key) +"="+ render(keyArg->second);
123 : }
124 0 : return "";
125 : }
126 :
127 158904 : bool TokenizedLine::readAndRemoveFlag(std::string_view key) {
128 : auto keytext = tokens.find(key);
129 158904 : if(keytext != tokens.end()) {
130 23962 : tokens.erase(keytext);
131 23962 : return true;
132 : }
133 : return false;
134 : }
135 :
136 4508 : bool TokenizedLine::renameKey(std::string_view key, std::string_view newkey) {
137 : auto keytext = tokens.find(key);
138 4519 : if(keytext == tokens.end() || tokens.find(newkey) != tokens.end()) {
139 4497 : return false;
140 : }
141 : auto value = std::move(keytext->second);
142 11 : tokens.erase(keytext);
143 22 : tokens.emplace(std::string(newkey),std::move(value));
144 : return true;
145 11 : }
146 :
147 0 : std::string TokenizedLine::getValue(std::string_view key, int rep) const {
148 : auto keyArg = tokens.find(key);
149 0 : rep = (rep<0) ? -1:rep;
150 0 : if( keyArg != tokens.end()) {
151 0 : if (keyArg->second.size() == 1) {
152 0 : return keyArg->second[0];
153 : } else {
154 0 : if (rep < static_cast<long long int>(keyArg->second.size())-1) {
155 0 : return keyArg->second[rep+1];
156 : }
157 : }
158 : }
159 0 : return "";
160 : }
161 692749 : std::string_view TokenizedLine::replica(const line& l,int rep) {
162 692749 : rep = (rep<0) ? -1:rep;
163 692749 : if (l.size() == 1) {
164 : return l[0];
165 : } else {
166 : //TODO: check that this does not go rep> l.size()
167 50 : return l[rep+1];
168 :
169 : }
170 : }
171 : } // namespace PLMD
172 :
|