Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #ifndef UtilityRoutines_hh_INCLUDED
49 : #define UtilityRoutines_hh_INCLUDED
50 :
51 : // C++ Headers
52 : #include <functional>
53 :
54 : // ObjexxFCL Headers
55 : #include <ObjexxFCL/Array1D.hh>
56 : #include <ObjexxFCL/Array1S.fwd.hh>
57 : #include <ObjexxFCL/MArray1.fwd.hh>
58 : #include <ObjexxFCL/Optional.hh>
59 : #include <ObjexxFCL/string.functions.hh>
60 :
61 : #include <GSL/span.h>
62 :
63 : // EnergyPlus Headers
64 : #include <EnergyPlus/Data/BaseData.hh>
65 : #include <EnergyPlus/DataGlobalConstants.hh>
66 : #include <EnergyPlus/DataGlobals.hh>
67 : #include <EnergyPlus/EnergyPlus.hh>
68 :
69 : namespace EnergyPlus {
70 :
71 : // Forward declarations
72 : class InputOutputFile;
73 : struct EnergyPlusData;
74 :
75 : int AbortEnergyPlus(EnergyPlusData &state);
76 :
77 : void CloseMiscOpenFiles(EnergyPlusData &state);
78 :
79 : void CloseOutOpenFiles();
80 :
81 : int EndEnergyPlus(EnergyPlusData &state);
82 :
83 : void ConvertCaseToUpper(std::string_view InputString, // Input string
84 : std::string &OutputString // Output string (in UpperCase)
85 : );
86 :
87 : void ConvertCaseToLower(std::string_view InputString, // Input string
88 : std::string &OutputString // Output string (in LowerCase)
89 : );
90 :
91 : std::string::size_type FindNonSpace(std::string const &String); // String to be scanned
92 :
93 12692 : template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>> inline constexpr T pow2(T x)
94 : {
95 12692 : return x * x;
96 : }
97 :
98 : template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>> inline constexpr T pow3(T x)
99 : {
100 : return x * x * x;
101 : }
102 :
103 4032 : template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>> inline constexpr T pow4(T x)
104 : {
105 4032 : T y(x * x);
106 4032 : return y * y;
107 : }
108 :
109 : template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>> inline constexpr T pow5(T x)
110 : {
111 : T y(x * x);
112 : y *= y;
113 : return y * x;
114 : }
115 :
116 : template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>> inline constexpr T pow6(T x)
117 : {
118 : T y(x * x);
119 : y *= y;
120 : return y * y;
121 : }
122 :
123 : template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>> inline constexpr T pow7(T x)
124 : {
125 : T y(x * x);
126 : y *= y;
127 : y *= y;
128 : return y * x;
129 : }
130 :
131 : bool env_var_on(std::string const &env_var_str);
132 :
133 : using OptionalOutputFileRef = Optional<std::reference_wrapper<EnergyPlus::InputOutputFile>>;
134 :
135 : void ShowFatalError(EnergyPlusData &state, std::string const &ErrorMessage, OptionalOutputFileRef OutUnit1 = _, OptionalOutputFileRef OutUnit2 = _);
136 :
137 : void ShowSevereError(EnergyPlusData &state, std::string const &ErrorMessage, OptionalOutputFileRef OutUnit1 = _, OptionalOutputFileRef OutUnit2 = _);
138 :
139 : void ShowSevereMessage(EnergyPlusData &state,
140 : std::string const &ErrorMessage,
141 : OptionalOutputFileRef OutUnit1 = _,
142 : OptionalOutputFileRef OutUnit2 = _);
143 :
144 : void ShowContinueError(EnergyPlusData &state, std::string const &Message, OptionalOutputFileRef OutUnit1 = _, OptionalOutputFileRef OutUnit2 = _);
145 :
146 : void ShowContinueErrorTimeStamp(EnergyPlusData &state,
147 : std::string const &Message,
148 : OptionalOutputFileRef OutUnit1 = _,
149 : OptionalOutputFileRef OutUnit2 = _);
150 :
151 : void ShowMessage(EnergyPlusData &state, std::string const &Message, OptionalOutputFileRef OutUnit1 = _, OptionalOutputFileRef OutUnit2 = _);
152 :
153 : void ShowWarningError(EnergyPlusData &state, std::string const &ErrorMessage, OptionalOutputFileRef OutUnit1 = _, OptionalOutputFileRef OutUnit2 = _);
154 :
155 : void ShowWarningMessage(EnergyPlusData &state,
156 : std::string const &ErrorMessage,
157 : OptionalOutputFileRef OutUnit1 = _,
158 : OptionalOutputFileRef OutUnit2 = _);
159 :
160 : void ShowRecurringSevereErrorAtEnd(EnergyPlusData &state,
161 : std::string const &Message, // Message automatically written to "error file" at end of simulation
162 : int &MsgIndex, // Recurring message index, if zero, next available index is assigned
163 : Optional<Real64 const> ReportMaxOf = _, // Track and report the max of the values passed to this argument
164 : Optional<Real64 const> ReportMinOf = _, // Track and report the min of the values passed to this argument
165 : Optional<Real64 const> ReportSumOf = _, // Track and report the sum of the values passed to this argument
166 : std::string const &ReportMaxUnits = "", // optional char string (<=15 length) of units for max value
167 : std::string const &ReportMinUnits = "", // optional char string (<=15 length) of units for min value
168 : std::string const &ReportSumUnits = "" // optional char string (<=15 length) of units for sum value
169 : );
170 :
171 : void ShowRecurringWarningErrorAtEnd(EnergyPlusData &state,
172 : std::string const &Message, // Message automatically written to "error file" at end of simulation
173 : int &MsgIndex, // Recurring message index, if zero, next available index is assigned
174 : Optional<Real64 const> ReportMaxOf = _, // Track and report the max of the values passed to this argument
175 : Optional<Real64 const> ReportMinOf = _, // Track and report the min of the values passed to this argument
176 : Optional<Real64 const> ReportSumOf = _, // Track and report the sum of the values passed to this argument
177 : std::string const &ReportMaxUnits = "", // optional char string (<=15 length) of units for max value
178 : std::string const &ReportMinUnits = "", // optional char string (<=15 length) of units for min value
179 : std::string const &ReportSumUnits = "" // optional char string (<=15 length) of units for sum value
180 : );
181 :
182 : void ShowRecurringContinueErrorAtEnd(EnergyPlusData &state,
183 : std::string const &Message, // Message automatically written to "error file" at end of simulation
184 : int &MsgIndex, // Recurring message index, if zero, next available index is assigned
185 : Optional<Real64 const> ReportMaxOf = _, // Track and report the max of the values passed to this argument
186 : Optional<Real64 const> ReportMinOf = _, // Track and report the min of the values passed to this argument
187 : Optional<Real64 const> ReportSumOf = _, // Track and report the sum of the values passed to this argument
188 : std::string const &ReportMaxUnits = "", // optional char string (<=15 length) of units for max value
189 : std::string const &ReportMinUnits = "", // optional char string (<=15 length) of units for min value
190 : std::string const &ReportSumUnits = "" // optional char string (<=15 length) of units for sum value
191 : );
192 :
193 : void StoreRecurringErrorMessage(EnergyPlusData &state,
194 : std::string const &ErrorMessage, // Message automatically written to "error file" at end of simulation
195 : int &ErrorMsgIndex, // Recurring message index, if zero, next available index is assigned
196 : Optional<Real64 const> ErrorReportMaxOf = _, // Track and report the max of the values passed to this argument
197 : Optional<Real64 const> ErrorReportMinOf = _, // Track and report the min of the values passed to this argument
198 : Optional<Real64 const> ErrorReportSumOf = _, // Track and report the sum of the values passed to this argument
199 : std::string const &ErrorReportMaxUnits = "", // Units for "max" reporting
200 : std::string const &ErrorReportMinUnits = "", // Units for "min" reporting
201 : std::string const &ErrorReportSumUnits = "" // Units for "sum" reporting
202 : );
203 :
204 : void ShowErrorMessage(EnergyPlusData &state, std::string const &ErrorMessage, OptionalOutputFileRef OutUnit1 = _, OptionalOutputFileRef OutUnit2 = _);
205 :
206 : void SummarizeErrors(EnergyPlusData &state);
207 :
208 : void ShowRecurringErrors(EnergyPlusData &state);
209 :
210 : namespace UtilityRoutines {
211 :
212 : static constexpr std::array<std::string_view, 12> MonthNamesCC{
213 : "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
214 :
215 : static constexpr std::array<std::string_view, 12> MonthNamesUC{
216 : "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"};
217 :
218 : template <class T> struct is_shared_ptr : std::false_type
219 : {
220 : };
221 : template <class T> struct is_shared_ptr<std::shared_ptr<T>> : std::true_type
222 : {
223 : };
224 :
225 : Real64 epElapsedTime();
226 :
227 : Real64 ProcessNumber(std::string_view String, bool &ErrorFlag);
228 :
229 : int FindItemInList(std::string_view const String, Array1_string const &ListOfItems, int NumItems);
230 :
231 1286 : inline int FindItemInList(std::string_view const String, Array1_string const &ListOfItems)
232 : {
233 1286 : return UtilityRoutines::FindItemInList(String, ListOfItems, ListOfItems.isize());
234 : }
235 :
236 : int FindItemInList(std::string_view const String, Array1S_string const ListOfItems, int NumItems);
237 :
238 2696 : template <typename InputIterator> int FindItemInList(std::string_view const str, InputIterator first, InputIterator last)
239 : {
240 2696 : auto it = std::find(first, last, str);
241 2696 : if (it != last) {
242 2696 : return std::distance(first, it) + 1;
243 : } else {
244 0 : return 0;
245 : }
246 : }
247 :
248 : inline int FindItemInList(std::string_view const String, Array1S_string const ListOfItems)
249 : {
250 : return UtilityRoutines::FindItemInList(String, ListOfItems, ListOfItems.isize());
251 : }
252 :
253 : template <typename A> inline int FindItemInList(std::string_view const String, MArray1<A, std::string> const &ListOfItems, int const NumItems)
254 : {
255 : for (int Count = 1; Count <= NumItems; ++Count) {
256 : if (String == ListOfItems(Count)) return Count;
257 : }
258 : return 0; // Not found
259 : }
260 :
261 : template <typename A> inline int FindItemInList(std::string_view const String, MArray1<A, std::string> const &ListOfItems)
262 : {
263 : return UtilityRoutines::FindItemInList(String, ListOfItems, ListOfItems.isize());
264 : }
265 :
266 : template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
267 : // Container needs and operator[i] and elements need Name
268 11769779 : inline int FindItemInList(std::string_view const String, Container const &ListOfItems, int const NumItems)
269 : {
270 265459467 : for (typename Container::size_type i = 0, e = NumItems; i < e; ++i) {
271 264913768 : if (String == ListOfItems[i].Name) return int(i + 1); // 1-based return index
272 : }
273 545699 : return 0; // Not found
274 : }
275 :
276 : template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
277 : // Container needs isize() and operator[i] and elements need Name
278 10984617 : inline int FindItemInList(std::string_view const String, Container const &ListOfItems)
279 : {
280 10984617 : return UtilityRoutines::FindItemInList(String, ListOfItems, ListOfItems.isize());
281 : }
282 :
283 : template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
284 : // Container needs operator[i] and value_type
285 : inline int
286 6601768 : FindItemInList(std::string_view const String, Container const &ListOfItems, std::string Container::value_type::*name_p, int const NumItems)
287 : {
288 2186979520 : for (typename Container::size_type i = 0, e = NumItems; i < e; ++i) {
289 2186506226 : if (String == ListOfItems[i].*name_p) return int(i + 1); // 1-based return index
290 : }
291 473294 : return 0; // Not found
292 : }
293 :
294 : template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
295 : // Container needs isize() and operator[i] and value_type
296 491538 : inline int FindItemInList(std::string_view const String, Container const &ListOfItems, std::string Container::value_type::*name_p)
297 : {
298 491538 : return UtilityRoutines::FindItemInList(String, ListOfItems, name_p, ListOfItems.isize());
299 : }
300 :
301 : int FindItemInSortedList(std::string_view const string, Array1S_string const ListOfItems, int NumItems);
302 :
303 : inline int FindItemInSortedList(std::string_view const String, Array1S_string const ListOfItems)
304 : {
305 : return FindItemInSortedList(String, ListOfItems, ListOfItems.isize());
306 : }
307 :
308 : template <typename A>
309 : inline int FindItemInSortedList(std::string_view const String, MArray1<A, std::string> const &ListOfItems, int const NumItems)
310 : {
311 : int Probe(0);
312 : int LBnd(0);
313 : int UBnd(NumItems + 1);
314 : bool Found(false);
315 : while ((!Found) || (Probe != 0)) {
316 : Probe = (UBnd - LBnd) / 2;
317 : if (Probe == 0) break;
318 : Probe += LBnd;
319 : if (equali(String, ListOfItems(Probe))) {
320 : Found = true;
321 : break;
322 : } else if (lessthani(String, ListOfItems(Probe))) {
323 : UBnd = Probe;
324 : } else {
325 : LBnd = Probe;
326 : }
327 : }
328 : return Probe;
329 : }
330 :
331 : template <typename A> inline int FindItemInSortedList(std::string_view const String, MArray1<A, std::string> const &ListOfItems)
332 : {
333 : return FindItemInSortedList(String, ListOfItems, ListOfItems.isize());
334 : }
335 :
336 : template <typename InputIterator> inline int FindItem(InputIterator first, InputIterator last, std::string_view const str, std::false_type)
337 : {
338 : using valueType = typename std::iterator_traits<InputIterator>::value_type;
339 : // static_assert( std::is_convertible< decltype( std::declval< valueType >() ), Named >::value, "Iterator value must inherit from class Named"
340 : // );
341 :
342 : auto const it = std::find_if(first, last, [&str](const valueType &s) { return s.name == str; });
343 : if (it != last) return it - first + 1; // 1-based return index
344 :
345 : auto const it2 = std::find_if(first, last, [&str](const valueType &s) { return equali(s.name, str); });
346 : if (it2 != last) return it2 - first + 1; // 1-based return index
347 :
348 : return 0; // Not found
349 : }
350 :
351 : template <typename InputIterator> inline int FindItem(InputIterator first, InputIterator last, std::string_view const str, std::true_type)
352 : {
353 : using valueType = typename std::iterator_traits<InputIterator>::value_type;
354 : // static_assert( std::is_convertible< decltype( *std::declval< valueType >() ), Named >::value, "Iterator value must inherit from class
355 : // Named" );
356 :
357 : auto const it = std::find_if(first, last, [&str](const valueType &s) { return s->name == str; });
358 : if (it != last) return it - first + 1; // 1-based return index
359 :
360 : auto const it2 = std::find_if(first, last, [&str](const valueType &s) { return equali(s->name, str); });
361 : if (it2 != last) return it2 - first + 1; // 1-based return index
362 :
363 : return 0; // Not found
364 : }
365 :
366 : template <typename InputIterator> inline int FindItem(InputIterator first, InputIterator last, std::string_view str)
367 : {
368 : return FindItem(first, last, str, is_shared_ptr<typename std::iterator_traits<InputIterator>::value_type>{});
369 : }
370 :
371 : int FindItem(std::string_view const String, Array1D_string const &ListOfItems, int const NumItems);
372 :
373 : inline int FindItem(std::string_view const String, Array1D_string const &ListOfItems)
374 : {
375 : return FindItem(String, ListOfItems, ListOfItems.isize());
376 : }
377 :
378 : int FindItem(std::string_view const String, Array1S_string const ListOfItems, int const NumItems);
379 :
380 : inline int FindItem(std::string_view const String, Array1S_string const ListOfItems)
381 : {
382 : return FindItem(String, ListOfItems, ListOfItems.isize());
383 : }
384 :
385 : template <typename A> inline int FindItem(std::string_view const String, MArray1<A, std::string> const &ListOfItems, int const NumItems)
386 : {
387 : int const item_number(UtilityRoutines::FindItemInList(String, ListOfItems, NumItems));
388 : if (item_number != 0) return item_number;
389 : for (int Count = 1; Count <= NumItems; ++Count) {
390 : if (equali(String, ListOfItems(Count))) return Count;
391 : }
392 : return 0; // Not found
393 : }
394 :
395 : template <typename A> inline int FindItem(std::string_view const String, MArray1<A, std::string> const &ListOfItems)
396 : {
397 : return FindItem(String, ListOfItems, ListOfItems.isize());
398 : }
399 :
400 : template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
401 : // Container needs size() and operator[i] and elements need Name
402 609387 : inline int FindItem(std::string_view const String, Container const &ListOfItems, int const NumItems)
403 : {
404 609387 : int const item_number(UtilityRoutines::FindItemInList(String, ListOfItems, NumItems));
405 609387 : if (item_number != 0) return item_number;
406 13864843 : for (typename Container::size_type i = 0, e = NumItems; i < e; ++i) {
407 13765248 : if (equali(String, ListOfItems[i].Name)) return i + 1; // 1-based return index
408 : }
409 99595 : return 0; // Not found
410 : }
411 :
412 : template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
413 : // Container needs size() and operator[i] and elements need Name
414 609331 : inline int FindItem(std::string_view const String, Container const &ListOfItems)
415 : {
416 609331 : return FindItem(String, ListOfItems, ListOfItems.isize());
417 : }
418 :
419 : template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
420 : // Container needs size() and operator[i] and value_type
421 8161 : inline int FindItem(std::string_view const String, Container const &ListOfItems, std::string Container::value_type::*name_p, int const NumItems)
422 : {
423 8161 : int const item_number(UtilityRoutines::FindItemInList(String, ListOfItems, name_p, NumItems));
424 8161 : if (item_number != 0) return item_number;
425 223421 : for (typename Container::size_type i = 0, e = NumItems; i < e; ++i) {
426 215308 : if (equali(String, ListOfItems[i].*name_p)) return i + 1; // 1-based return index
427 : }
428 8113 : return 0; // Not found
429 : }
430 :
431 : template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
432 : // Container needs size() and operator[i] and value_type
433 8161 : inline int FindItem(std::string_view const String, Container const &ListOfItems, std::string Container::value_type::*name_p)
434 : {
435 8161 : return FindItem(String, ListOfItems, name_p, ListOfItems.isize());
436 : }
437 :
438 8274364 : inline std::string MakeUPPERCase(std::string_view const InputString) // Input String
439 : {
440 :
441 : // FUNCTION INFORMATION:
442 : // AUTHOR Linda K. Lawrie
443 : // DATE WRITTEN September 1997
444 : // MODIFIED na
445 : // RE-ENGINEERED na
446 :
447 : // PURPOSE OF THIS SUBROUTINE:
448 : // This function returns the Upper Case representation of the InputString.
449 :
450 : // METHODOLOGY EMPLOYED:
451 : // Uses the Intrinsic SCAN function to scan the lowercase representation of
452 : // characters (DataStringGlobals) for each character in the given string.
453 :
454 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
455 :
456 8274364 : std::string ResultString(InputString);
457 :
458 198508936 : for (std::string::size_type i = 0, e = len(InputString); i < e; ++i) {
459 190234572 : int const curCharVal = int(InputString[i]);
460 190234572 : if ((97 <= curCharVal && curCharVal <= 122) || (224 <= curCharVal && curCharVal <= 255)) { // lowercase ASCII and accented characters
461 107178123 : ResultString[i] = char(curCharVal - 32);
462 : }
463 : }
464 :
465 8274364 : return ResultString;
466 : }
467 :
468 447216755 : constexpr bool SameString(std::string_view const s, std::string_view const t)
469 : {
470 : // case insensitive comparison
471 447216755 : return equali(s, t);
472 : }
473 :
474 : template <typename InputIterator>
475 : inline void VerifyName(EnergyPlusData &state,
476 : InputIterator first,
477 : InputIterator last,
478 : std::string const &NameToVerify,
479 : bool &ErrorFound,
480 : bool &IsBlank,
481 : std::string const &StringToDisplay)
482 : {
483 : IsBlank = false;
484 : ErrorFound = false;
485 : if (NameToVerify.empty()) {
486 : ShowSevereError(state, StringToDisplay + ", cannot be blank");
487 : ErrorFound = true;
488 : IsBlank = true;
489 : return;
490 : }
491 : int Found = FindItem(first, last, NameToVerify);
492 : if (Found != 0) {
493 : ShowSevereError(state, StringToDisplay + ", duplicate name=" + NameToVerify);
494 : ErrorFound = true;
495 : }
496 : }
497 :
498 : void VerifyName(EnergyPlusData &state,
499 : std::string const &NameToVerify,
500 : Array1D_string const &NamesList,
501 : int const NumOfNames,
502 : bool &ErrorFound,
503 : bool &IsBlank,
504 : std::string const &StringToDisplay);
505 :
506 : void VerifyName(EnergyPlusData &state,
507 : std::string const &NameToVerify,
508 : Array1S_string const NamesList,
509 : int const NumOfNames,
510 : bool &ErrorFound,
511 : bool &IsBlank,
512 : std::string const &StringToDisplay);
513 :
514 : template <typename A>
515 : inline void VerifyName(EnergyPlusData &state,
516 : std::string const &NameToVerify,
517 : MArray1<A, std::string> const &NamesList,
518 : int const NumOfNames,
519 : bool &ErrorFound,
520 : bool &IsBlank,
521 : std::string const &StringToDisplay)
522 : { // Overload for member arrays: Implemented here to avoid copy to Array_string to forward to other VerifyName
523 : ErrorFound = false;
524 : if (NumOfNames > 0) {
525 : int const Found = FindItem(NameToVerify, NamesList,
526 : NumOfNames); // Calls FindItem overload that accepts member arrays
527 : if (Found != 0) {
528 : ShowSevereError(state, StringToDisplay + ", duplicate name=" + NameToVerify);
529 : ErrorFound = true;
530 : }
531 : }
532 :
533 : if (NameToVerify.empty()) {
534 : ShowSevereError(state, StringToDisplay + ", cannot be blank");
535 : ErrorFound = true;
536 : IsBlank = true;
537 : } else {
538 : IsBlank = false;
539 : }
540 : }
541 :
542 : template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
543 : // Container needs size() and operator[i] and elements need Name
544 116 : inline void VerifyName(EnergyPlusData &state,
545 : std::string const &NameToVerify,
546 : Container const &NamesList,
547 : int const NumOfNames,
548 : bool &ErrorFound,
549 : bool &IsBlank,
550 : std::string const &StringToDisplay)
551 : {
552 116 : ErrorFound = false;
553 116 : if (NumOfNames > 0) {
554 52 : int const Found = FindItem(NameToVerify, NamesList,
555 : NumOfNames); // Calls FindItem overload that accepts member arrays
556 52 : if (Found != 0) {
557 0 : ShowSevereError(state, StringToDisplay + ", duplicate name=" + NameToVerify);
558 0 : ErrorFound = true;
559 : }
560 : }
561 :
562 116 : if (NameToVerify.empty()) {
563 0 : ShowSevereError(state, StringToDisplay + ", cannot be blank");
564 0 : ErrorFound = true;
565 0 : IsBlank = true;
566 : } else {
567 116 : IsBlank = false;
568 : }
569 116 : }
570 :
571 : template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
572 : // Container needs size() and operator[i] and value_type
573 : inline void VerifyName(EnergyPlusData &state,
574 : std::string const &NameToVerify,
575 : Container const &NamesList,
576 : std::string Container::value_type::*name_p,
577 : int const NumOfNames,
578 : bool &ErrorFound,
579 : bool &IsBlank,
580 : std::string const &StringToDisplay)
581 : {
582 : ErrorFound = false;
583 : if (NumOfNames > 0) {
584 : int const Found = FindItem(NameToVerify, NamesList, name_p, NumOfNames);
585 : if (Found != 0) {
586 : ShowSevereError(state, StringToDisplay + ", duplicate name=" + NameToVerify);
587 : ErrorFound = true;
588 : }
589 : }
590 :
591 : if (NameToVerify.empty()) {
592 : ShowSevereError(state, StringToDisplay + ", cannot be blank");
593 : ErrorFound = true;
594 : IsBlank = true;
595 : } else {
596 : IsBlank = false;
597 : }
598 : }
599 :
600 : bool IsNameEmpty(EnergyPlusData &state, std::string &NameToVerify, std::string_view StringToDisplay, bool &ErrorFound);
601 :
602 : // Two structs for case insensitive containers.
603 : // Eg: for unordered_map, we need to have a case insenstive hasher and a case insensitive comparator
604 : // (The default allocator for unordered_map is fine)
605 : // For map, you'd only need the comparator
606 : struct case_insensitive_hasher
607 : {
608 : using is_transparent = void;
609 : size_t operator()(std::string_view key) const noexcept;
610 : };
611 :
612 : struct case_insensitive_comparator
613 : {
614 : using is_transparent = void;
615 : bool operator()(std::string_view a, std::string_view b) const noexcept;
616 : };
617 :
618 : void appendPerfLog(EnergyPlusData &state, std::string const &colHeader, std::string const &colValue, bool finalColumn = false);
619 :
620 : bool ValidateFuelType(EnergyPlusData &state,
621 : std::string const &FuelTypeInput,
622 : std::string &FuelTypeOutput,
623 : bool &FuelTypeErrorsFound,
624 : bool AllowSteamAndDistrict = false);
625 :
626 : bool ValidateFuelTypeWithAssignResourceTypeNum(std::string const &FuelTypeInput,
627 : std::string &FuelTypeOutput,
628 : DataGlobalConstants::ResourceType &FuelTypeNum,
629 : bool &FuelTypeErrorsFound);
630 :
631 : } // namespace UtilityRoutines
632 :
633 1987496 : constexpr int getEnumerationValue(const gsl::span<const std::string_view> sList, const std::string_view s)
634 : {
635 160182661 : for (unsigned int i = 0; i < sList.size(); ++i) {
636 160182203 : if (sList[i] == s) return i;
637 : }
638 458 : return -1;
639 : }
640 :
641 204 : constexpr BooleanSwitch getYesNoValue(const std::string_view s)
642 : {
643 204 : constexpr std::array<std::string_view, 2> yesNo = {"NO", "YES"};
644 204 : return static_cast<BooleanSwitch>(getEnumerationValue(yesNo, s));
645 : }
646 :
647 771 : struct UtilityRoutinesData : BaseGlobalStruct
648 : {
649 :
650 : bool outputErrorHeader = true;
651 : std::string appendPerfLog_headerRow;
652 : std::string appendPerfLog_valuesRow;
653 : bool GetMatrixInputFlag = true;
654 :
655 0 : void clear_state() override
656 : {
657 0 : outputErrorHeader = true;
658 0 : appendPerfLog_headerRow.clear();
659 0 : appendPerfLog_valuesRow.clear();
660 0 : GetMatrixInputFlag = true;
661 0 : }
662 :
663 : // Default Constructor
664 771 : UtilityRoutinesData() = default;
665 : };
666 : } // namespace EnergyPlus
667 :
668 : #endif
|