LCOV - code coverage report
Current view: top level - EnergyPlus - UtilityRoutines.hh (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 83.8 % 80 67
Test Date: 2025-05-22 16:09:37 Functions: 58.1 % 446 259

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, 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              : #include <optional>
      54              : 
      55              : // ObjexxFCL Headers
      56              : #include <ObjexxFCL/Array1D.hh>
      57              : #include <ObjexxFCL/Array1S.fwd.hh>
      58              : #include <ObjexxFCL/MArray1.fwd.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            0 : template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>> inline constexpr T pow2(T x)
      94              : {
      95            0 :     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            0 : template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>> inline constexpr T pow4(T x)
     104              : {
     105            0 :     T y(x * x);
     106            0 :     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 = std::optional<std::reference_wrapper<EnergyPlus::InputOutputFile>>;
     134              : 
     135              : enum class ErrorMessageCategory
     136              : {
     137              :     Invalid = -1,
     138              :     Unclassified,
     139              :     Input_invalid,
     140              :     Input_field_not_found,
     141              :     Input_field_blank,
     142              :     Input_object_not_found,
     143              :     Input_cannot_find_object,
     144              :     Input_topology_problem,
     145              :     Input_unused,
     146              :     Input_fatal,
     147              :     Runtime_general,
     148              :     Runtime_flow_out_of_range,
     149              :     Runtime_temp_out_of_range,
     150              :     Runtime_airflow_network,
     151              :     Fatal_general,
     152              :     Developer_general,
     153              :     Developer_invalid_index,
     154              :     Num
     155              : };
     156              : void emitErrorMessage(EnergyPlusData &state, ErrorMessageCategory category, std::string const &msg, bool shouldFatal);
     157              : void emitErrorMessages(EnergyPlusData &state,
     158              :                        ErrorMessageCategory category,
     159              :                        std::initializer_list<std::string> const &msgs,
     160              :                        bool shouldFatal,
     161              :                        int zeroBasedTimeStampIndex = -1);
     162              : void emitWarningMessage(EnergyPlusData &state, ErrorMessageCategory category, std::string const &msg, bool countAsError = false);
     163              : void emitWarningMessages(EnergyPlusData &state,
     164              :                          ErrorMessageCategory category,
     165              :                          std::initializer_list<std::string> const &msgs,
     166              :                          bool countAsError = false);
     167              : 
     168              : void ShowFatalError(EnergyPlusData &state, std::string const &ErrorMessage, OptionalOutputFileRef OutUnit1 = {}, OptionalOutputFileRef OutUnit2 = {});
     169              : 
     170              : void ShowSevereError(EnergyPlusData &state,
     171              :                      std::string const &ErrorMessage,
     172              :                      OptionalOutputFileRef OutUnit1 = {},
     173              :                      OptionalOutputFileRef OutUnit2 = {});
     174              : 
     175              : void ShowSevereMessage(EnergyPlusData &state,
     176              :                        std::string const &ErrorMessage,
     177              :                        OptionalOutputFileRef OutUnit1 = {},
     178              :                        OptionalOutputFileRef OutUnit2 = {});
     179              : 
     180              : void ShowContinueError(EnergyPlusData &state, std::string const &Message, OptionalOutputFileRef OutUnit1 = {}, OptionalOutputFileRef OutUnit2 = {});
     181              : 
     182              : void ShowContinueErrorTimeStamp(EnergyPlusData &state,
     183              :                                 std::string const &Message,
     184              :                                 OptionalOutputFileRef OutUnit1 = {},
     185              :                                 OptionalOutputFileRef OutUnit2 = {});
     186              : 
     187              : void ShowMessage(EnergyPlusData &state, std::string const &Message, OptionalOutputFileRef OutUnit1 = {}, OptionalOutputFileRef OutUnit2 = {});
     188              : 
     189              : void ShowWarningError(EnergyPlusData &state,
     190              :                       std::string const &ErrorMessage,
     191              :                       OptionalOutputFileRef OutUnit1 = {},
     192              :                       OptionalOutputFileRef OutUnit2 = {});
     193              : 
     194              : void ShowWarningMessage(EnergyPlusData &state,
     195              :                         std::string const &ErrorMessage,
     196              :                         OptionalOutputFileRef OutUnit1 = {},
     197              :                         OptionalOutputFileRef OutUnit2 = {});
     198              : 
     199              : void ShowRecurringSevereErrorAtEnd(EnergyPlusData &state,
     200              :                                    std::string const &Message, // Message automatically written to "error file" at end of simulation
     201              :                                    int &MsgIndex,              // Recurring message index, if zero, next available index is assigned
     202              :                                    Real64 const val,           // Track and report the max of the values passed to this argument
     203              :                                    std::string const &units);
     204              : 
     205              : void ShowRecurringSevereErrorAtEnd(
     206              :     EnergyPlusData &state,
     207              :     std::string const &Message,                        // Message automatically written to "error file" at end of simulation
     208              :     int &MsgIndex,                                     // Recurring message index, if zero, next available index is assigned
     209              :     ObjexxFCL::Optional<Real64 const> ReportMaxOf = _, // Track and report the max of the values passed to this argument
     210              :     ObjexxFCL::Optional<Real64 const> ReportMinOf = _, // Track and report the min of the values passed to this argument
     211              :     ObjexxFCL::Optional<Real64 const> ReportSumOf = _, // Track and report the sum of the values passed to this argument
     212              :     std::string const &ReportMaxUnits = "",            // optional char string (<=15 length) of units for max value
     213              :     std::string const &ReportMinUnits = "",            // optional char string (<=15 length) of units for min value
     214              :     std::string const &ReportSumUnits = ""             // optional char string (<=15 length) of units for sum value
     215              : );
     216              : 
     217              : void ShowRecurringWarningErrorAtEnd(EnergyPlusData &state,
     218              :                                     std::string const &Message, // Message automatically written to "error file" at end of simulation
     219              :                                     int &MsgIndex,              // Recurring message index, if zero, next available index is assigned
     220              :                                     Real64 const val,
     221              :                                     std::string const &units // optional char string (<=15 length) of units for sum value
     222              : );
     223              : 
     224              : void ShowRecurringWarningErrorAtEnd(
     225              :     EnergyPlusData &state,
     226              :     std::string const &Message,                        // Message automatically written to "error file" at end of simulation
     227              :     int &MsgIndex,                                     // Recurring message index, if zero, next available index is assigned
     228              :     ObjexxFCL::Optional<Real64 const> ReportMaxOf = _, // Track and report the max of the values passed to this argument
     229              :     ObjexxFCL::Optional<Real64 const> ReportMinOf = _, // Track and report the min of the values passed to this argument
     230              :     ObjexxFCL::Optional<Real64 const> ReportSumOf = _, // Track and report the sum of the values passed to this argument
     231              :     std::string const &ReportMaxUnits = "",            // optional char string (<=15 length) of units for max value
     232              :     std::string const &ReportMinUnits = "",            // optional char string (<=15 length) of units for min value
     233              :     std::string const &ReportSumUnits = ""             // optional char string (<=15 length) of units for sum value
     234              : );
     235              : 
     236              : void ShowRecurringContinueErrorAtEnd(
     237              :     EnergyPlusData &state,
     238              :     std::string const &Message,                        // Message automatically written to "error file" at end of simulation
     239              :     int &MsgIndex,                                     // Recurring message index, if zero, next available index is assigned
     240              :     ObjexxFCL::Optional<Real64 const> ReportMaxOf = _, // Track and report the max of the values passed to this argument
     241              :     ObjexxFCL::Optional<Real64 const> ReportMinOf = _, // Track and report the min of the values passed to this argument
     242              :     ObjexxFCL::Optional<Real64 const> ReportSumOf = _, // Track and report the sum of the values passed to this argument
     243              :     std::string const &ReportMaxUnits = "",            // optional char string (<=15 length) of units for max value
     244              :     std::string const &ReportMinUnits = "",            // optional char string (<=15 length) of units for min value
     245              :     std::string const &ReportSumUnits = ""             // optional char string (<=15 length) of units for sum value
     246              : );
     247              : 
     248              : void StoreRecurringErrorMessage(
     249              :     EnergyPlusData &state,
     250              :     std::string const &ErrorMessage,                        // Message automatically written to "error file" at end of simulation
     251              :     int &ErrorMsgIndex,                                     // Recurring message index, if zero, next available index is assigned
     252              :     ObjexxFCL::Optional<Real64 const> ErrorReportMaxOf = _, // Track and report the max of the values passed to this argument
     253              :     ObjexxFCL::Optional<Real64 const> ErrorReportMinOf = _, // Track and report the min of the values passed to this argument
     254              :     ObjexxFCL::Optional<Real64 const> ErrorReportSumOf = _, // Track and report the sum of the values passed to this argument
     255              :     std::string const &ErrorReportMaxUnits = "",            // Units for "max" reporting
     256              :     std::string const &ErrorReportMinUnits = "",            // Units for "min" reporting
     257              :     std::string const &ErrorReportSumUnits = ""             // Units for "sum" reporting
     258              : );
     259              : 
     260              : void ShowErrorMessage(EnergyPlusData &state,
     261              :                       std::string const &ErrorMessage,
     262              :                       OptionalOutputFileRef OutUnit1 = {},
     263              :                       OptionalOutputFileRef OutUnit2 = {});
     264              : 
     265              : void SummarizeErrors(EnergyPlusData &state);
     266              : 
     267              : void ShowRecurringErrors(EnergyPlusData &state);
     268              : 
     269              : struct ErrorCountIndex
     270              : {
     271              :     int index = 0;
     272              :     int count = 0;
     273              : };
     274              : 
     275              : struct ErrorObjectHeader
     276              : {
     277              :     std::string_view routineName;
     278              :     std::string_view objectType;
     279              :     std::string_view objectName;
     280              : };
     281              : 
     282              : void ShowSevereDuplicateName(EnergyPlusData &state, ErrorObjectHeader const &eoh);
     283              : void ShowSevereEmptyField(EnergyPlusData &state,
     284              :                           ErrorObjectHeader const &eoh,
     285              :                           std::string_view fieldName,
     286              :                           std::string_view depFieldName = {},
     287              :                           std::string_view depFieldValue = {});
     288              : void ShowSevereItemNotFound(EnergyPlusData &state, ErrorObjectHeader const &eoh, std::string_view fieldName, std::string_view fieldValue);
     289              : void ShowSevereItemNotFoundAudit(EnergyPlusData &state, ErrorObjectHeader const &eoh, std::string_view fieldName, std::string_view fieldValue);
     290              : 
     291              : void ShowSevereDuplicateAssignment(
     292              :     EnergyPlusData &state, ErrorObjectHeader const &eoh, std::string_view fieldName, std::string_view fieldValue, std::string_view prevValue);
     293              : 
     294              : void ShowSevereInvalidKey(
     295              :     EnergyPlusData &state, ErrorObjectHeader const &eoh, std::string_view fieldName, std::string_view fieldValue, std::string_view msg = {});
     296              : void ShowSevereInvalidBool(EnergyPlusData &state, ErrorObjectHeader const &eoh, std::string_view fieldName, std::string_view fieldValue);
     297              : 
     298              : void ShowSevereCustom(EnergyPlusData &state, ErrorObjectHeader const &eoh, std::string_view msg);
     299              : void ShowSevereCustomField(
     300              :     EnergyPlusData &state, ErrorObjectHeader const &eoh, std::string_view fieldName, std::string_view fieldValue, std::string_view msg);
     301              : 
     302              : void ShowSevereCustomAudit(EnergyPlusData &state, ErrorObjectHeader const &eoh, std::string_view msg);
     303              : 
     304              : enum class Clusive
     305              : {
     306              :     Invalid = -1,
     307              :     In,
     308              :     Ex,
     309              :     Num
     310              : };
     311              : 
     312              : void ShowSevereBadMin(EnergyPlusData &state,
     313              :                       ErrorObjectHeader const &eoh,
     314              :                       std::string_view fieldName,
     315              :                       Real64 fieldVal,
     316              :                       Clusive cluMin,
     317              :                       Real64 minVal,
     318              :                       std::string_view msg = {});
     319              : void ShowSevereBadMax(EnergyPlusData &state,
     320              :                       ErrorObjectHeader const &eoh,
     321              :                       std::string_view fieldName,
     322              :                       Real64 fieldVal,
     323              :                       Clusive cluMin,
     324              :                       Real64 maxVal,
     325              :                       std::string_view msg = {});
     326              : void ShowSevereBadMinMax(EnergyPlusData &state,
     327              :                          ErrorObjectHeader const &eoh,
     328              :                          std::string_view fieldName,
     329              :                          Real64 fieldVal,
     330              :                          Clusive cluMin,
     331              :                          Real64 minVal,
     332              :                          Clusive cluMax,
     333              :                          Real64 maxVal,
     334              :                          std::string_view msg = {});
     335              : 
     336              : void ShowWarningDuplicateName(EnergyPlusData &state, ErrorObjectHeader const &eoh);
     337              : void ShowWarningEmptyField(EnergyPlusData &state,
     338              :                            ErrorObjectHeader const &eoh,
     339              :                            std::string_view fieldName,
     340              :                            std::string_view defaultValue = {},
     341              :                            std::string_view depFieldName = {},
     342              :                            std::string_view depFieldValue = {});
     343              : 
     344              : void ShowWarningNonEmptyField(EnergyPlusData &state,
     345              :                               ErrorObjectHeader const &eoh,
     346              :                               std::string_view fieldName,
     347              :                               std::string_view depFieldName = {},
     348              :                               std::string_view depFieldValue = {});
     349              : 
     350              : void ShowWarningItemNotFound(
     351              :     EnergyPlusData &state, ErrorObjectHeader const &eoh, std::string_view fieldName, std::string_view fieldValue, std::string_view defaultValue = {});
     352              : void ShowWarningInvalidKey(EnergyPlusData &state,
     353              :                            ErrorObjectHeader const &eoh,
     354              :                            std::string_view fieldName,
     355              :                            std::string_view fieldValue,
     356              :                            std::string_view defaultValue,
     357              :                            std::string_view msg = {});
     358              : void ShowWarningInvalidBool(
     359              :     EnergyPlusData &state, ErrorObjectHeader const &eoh, std::string_view fieldName, std::string_view fieldValue, std::string_view defaultValue);
     360              : void ShowWarningCustom(EnergyPlusData &state, ErrorObjectHeader const &eoh, std::string_view msg);
     361              : void ShowWarningCustomField(
     362              :     EnergyPlusData &state, ErrorObjectHeader const &eoh, std::string_view fieldName, std::string_view fieldValue, std::string_view msg);
     363              : 
     364              : namespace Util {
     365              : 
     366              :     static constexpr std::array<std::string_view, 12> MonthNamesCC{
     367              :         "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
     368              : 
     369              :     static constexpr std::array<std::string_view, 12> MonthNamesUC{
     370              :         "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"};
     371              : 
     372              :     template <class T> struct is_shared_ptr : std::false_type
     373              :     {
     374              :     };
     375              :     template <class T> struct is_shared_ptr<std::shared_ptr<T>> : std::true_type
     376              :     {
     377              :     };
     378              : 
     379              :     Real64 ProcessNumber(std::string_view String, bool &ErrorFlag);
     380              : 
     381              :     int FindItemInList(std::string_view const String, Array1_string const &ListOfItems, int NumItems);
     382              : 
     383          242 :     inline int FindItemInList(std::string_view const String, Array1_string const &ListOfItems)
     384              :     {
     385          242 :         return Util::FindItemInList(String, ListOfItems, ListOfItems.isize());
     386              :     }
     387              : 
     388              :     inline int FindIntInList(Array1_int &list, int item)
     389              :     {
     390              :         auto it = std::find(list.begin(), list.end(), item);
     391              :         return (it == list.end()) ? -1 : (it - list.begin());
     392              :     }
     393              : 
     394              :     inline int FindIntInList(std::vector<int> &list, int item)
     395              :     {
     396              :         auto it = std::find(list.begin(), list.end(), item);
     397              :         return (it == list.end()) ? -1 : (it - list.begin());
     398              :     }
     399              : 
     400              :     int FindItemInList(std::string_view const String, Array1S_string const ListOfItems, int NumItems);
     401              : 
     402            6 :     template <typename InputIterator> int FindItemInList(std::string_view const str, InputIterator first, InputIterator last)
     403              :     {
     404            6 :         auto it = std::find(first, last, str);
     405            6 :         if (it != last) {
     406            6 :             return std::distance(first, it) + 1;
     407              :         } else {
     408            0 :             return 0;
     409              :         }
     410              :     }
     411              : 
     412              :     inline int FindItemInList(std::string_view const String, Array1S_string const ListOfItems)
     413              :     {
     414              :         return Util::FindItemInList(String, ListOfItems, ListOfItems.isize());
     415              :     }
     416              : 
     417              :     template <typename A> inline int FindItemInList(std::string_view const String, MArray1<A, std::string> const &ListOfItems, int const NumItems)
     418              :     {
     419              :         for (int Count = 1; Count <= NumItems; ++Count) {
     420              :             if (String == ListOfItems(Count)) return Count;
     421              :         }
     422              :         return 0; // Not found
     423              :     }
     424              : 
     425              :     template <typename A> inline int FindItemInList(std::string_view const String, MArray1<A, std::string> const &ListOfItems)
     426              :     {
     427              :         return Util::FindItemInList(String, ListOfItems, ListOfItems.isize());
     428              :     }
     429              : 
     430              :     template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
     431              :     // Container needs and operator[i] and elements need Name
     432       108497 :     inline int FindItemInList(std::string_view const String, Container const &ListOfItems, int const NumItems)
     433              :     {
     434       237621 :         for (typename Container::size_type i = 0, e = NumItems; i < e; ++i) {
     435       227508 :             if (String == ListOfItems[i].Name) return int(i + 1); // 1-based return index
     436              :         }
     437        10113 :         return 0; // Not found
     438              :     }
     439              : 
     440              :     template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
     441              :     // Container needs isize() and operator[i] and elements need Name
     442       102885 :     inline int FindItemInList(std::string_view const String, Container const &ListOfItems)
     443              :     {
     444       102885 :         return Util::FindItemInList(String, ListOfItems, ListOfItems.isize());
     445              :     }
     446              : 
     447              :     template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
     448              :     // Container needs operator[i] and value_type
     449              :     inline int
     450       205537 :     FindItemInList(std::string_view const String, Container const &ListOfItems, std::string Container::value_type::*name_p, int const NumItems)
     451              :     {
     452       208025 :         for (typename Container::size_type i = 0, e = NumItems; i < e; ++i) {
     453       207213 :             if (String == ListOfItems[i].*name_p) return int(i + 1); // 1-based return index
     454              :         }
     455          812 :         return 0; // Not found
     456              :     }
     457              : 
     458              :     template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
     459              :     // Container needs isize() and operator[i] and value_type
     460       204746 :     inline int FindItemInList(std::string_view const String, Container const &ListOfItems, std::string Container::value_type::*name_p)
     461              :     {
     462       204746 :         return Util::FindItemInList(String, ListOfItems, name_p, ListOfItems.isize());
     463              :     }
     464              : 
     465              :     int FindItemInSortedList(std::string_view const string, Array1S_string const ListOfItems, int NumItems);
     466              : 
     467              :     inline int FindItemInSortedList(std::string_view const String, Array1S_string const ListOfItems)
     468              :     {
     469              :         return FindItemInSortedList(String, ListOfItems, ListOfItems.isize());
     470              :     }
     471              : 
     472              :     template <typename A>
     473              :     inline int FindItemInSortedList(std::string_view const String, MArray1<A, std::string> const &ListOfItems, int const NumItems)
     474              :     {
     475              :         int Probe(0);
     476              :         int LBnd(0);
     477              :         int UBnd(NumItems + 1);
     478              :         bool Found(false);
     479              :         while ((!Found) || (Probe != 0)) {
     480              :             Probe = (UBnd - LBnd) / 2;
     481              :             if (Probe == 0) break;
     482              :             Probe += LBnd;
     483              :             if (equali(String, ListOfItems(Probe))) {
     484              :                 Found = true;
     485              :                 break;
     486              :             } else if (lessthani(String, ListOfItems(Probe))) {
     487              :                 UBnd = Probe;
     488              :             } else {
     489              :                 LBnd = Probe;
     490              :             }
     491              :         }
     492              :         return Probe;
     493              :     }
     494              : 
     495              :     template <typename A> inline int FindItemInSortedList(std::string_view const String, MArray1<A, std::string> const &ListOfItems)
     496              :     {
     497              :         return FindItemInSortedList(String, ListOfItems, ListOfItems.isize());
     498              :     }
     499              : 
     500              :     template <typename InputIterator> inline int FindItem(InputIterator first, InputIterator last, std::string_view const str, std::false_type)
     501              :     {
     502              :         using valueType = typename std::iterator_traits<InputIterator>::value_type;
     503              :         // static_assert( std::is_convertible< decltype( std::declval< valueType >() ), Named >::value, "Iterator value must inherit from class Named"
     504              :         // );
     505              : 
     506              :         auto const it = std::find_if(first, last, [&str](const valueType &s) { return s.name == str; });
     507              :         if (it != last) return it - first + 1; // 1-based return index
     508              : 
     509              :         auto const it2 = std::find_if(first, last, [&str](const valueType &s) { return equali(s.name, str); });
     510              :         if (it2 != last) return it2 - first + 1; // 1-based return index
     511              : 
     512              :         return 0; // Not found
     513              :     }
     514              : 
     515              :     template <typename InputIterator> inline int FindItem(InputIterator first, InputIterator last, std::string_view const str, std::true_type)
     516              :     {
     517              :         using valueType = typename std::iterator_traits<InputIterator>::value_type;
     518              :         // static_assert( std::is_convertible< decltype( *std::declval< valueType >() ), Named >::value, "Iterator value must inherit from class
     519              :         // Named" );
     520              : 
     521              :         auto const it = std::find_if(first, last, [&str](const valueType &s) { return s->name == str; });
     522              :         if (it != last) return it - first + 1; // 1-based return index
     523              : 
     524              :         auto const it2 = std::find_if(first, last, [&str](const valueType &s) { return equali(s->name, str); });
     525              :         if (it2 != last) return it2 - first + 1; // 1-based return index
     526              : 
     527              :         return 0; // Not found
     528              :     }
     529              : 
     530              :     template <typename InputIterator> inline int FindItem(InputIterator first, InputIterator last, std::string_view str)
     531              :     {
     532              :         return FindItem(first, last, str, is_shared_ptr<typename std::iterator_traits<InputIterator>::value_type>{});
     533              :     }
     534              : 
     535              :     int FindItem(std::string_view const String, Array1D_string const &ListOfItems, int const NumItems);
     536              : 
     537              :     inline int FindItem(std::string_view const String, Array1D_string const &ListOfItems)
     538              :     {
     539              :         return FindItem(String, ListOfItems, ListOfItems.isize());
     540              :     }
     541              : 
     542              :     int FindItem(std::string_view const String, Array1S_string const ListOfItems, int const NumItems);
     543              : 
     544              :     inline int FindItem(std::string_view const String, Array1S_string const ListOfItems)
     545              :     {
     546              :         return FindItem(String, ListOfItems, ListOfItems.isize());
     547              :     }
     548              : 
     549              :     template <typename A> inline int FindItem(std::string_view const String, MArray1<A, std::string> const &ListOfItems, int const NumItems)
     550              :     {
     551              :         int const item_number(Util::FindItemInList(String, ListOfItems, NumItems));
     552              :         if (item_number != 0) return item_number;
     553              :         for (int Count = 1; Count <= NumItems; ++Count) {
     554              :             if (equali(String, ListOfItems(Count))) return Count;
     555              :         }
     556              :         return 0; // Not found
     557              :     }
     558              : 
     559              :     template <typename A> inline int FindItem(std::string_view const String, MArray1<A, std::string> const &ListOfItems)
     560              :     {
     561              :         return FindItem(String, ListOfItems, ListOfItems.isize());
     562              :     }
     563              : 
     564              :     template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
     565              :     // Container needs size() and operator[i] and elements need Name
     566          611 :     inline int FindItem(std::string_view const String, Container const &ListOfItems, int const NumItems)
     567              :     {
     568          611 :         int const item_number(Util::FindItemInList(String, ListOfItems, NumItems));
     569          611 :         if (item_number != 0) return item_number;
     570           24 :         for (typename Container::size_type i = 0, e = NumItems; i < e; ++i) {
     571           23 :             if (equali(String, ListOfItems[i].Name)) return i + 1; // 1-based return index
     572              :         }
     573            1 :         return 0; // Not found
     574              :     }
     575              : 
     576              :     template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
     577              :     // Container needs size() and operator[i] and elements need Name
     578          610 :     inline int FindItem(std::string_view const String, Container const &ListOfItems)
     579              :     {
     580          610 :         return FindItem(String, ListOfItems, ListOfItems.isize());
     581              :     }
     582              : 
     583              :     template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
     584              :     // Container needs size() and operator[i] and value_type
     585           29 :     inline int FindItem(std::string_view const String, Container const &ListOfItems, std::string Container::value_type::*name_p, int const NumItems)
     586              :     {
     587           29 :         int const item_number(Util::FindItemInList(String, ListOfItems, name_p, NumItems));
     588           29 :         if (item_number != 0) return item_number;
     589          153 :         for (typename Container::size_type i = 0, e = NumItems; i < e; ++i) {
     590          153 :             if (equali(String, ListOfItems[i].*name_p)) return i + 1; // 1-based return index
     591              :         }
     592            0 :         return 0; // Not found
     593              :     }
     594              : 
     595              :     template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
     596              :     // Container needs size() and operator[i] and value_type
     597           29 :     inline int FindItem(std::string_view const String, Container const &ListOfItems, std::string Container::value_type::*name_p)
     598              :     {
     599           29 :         return FindItem(String, ListOfItems, name_p, ListOfItems.isize());
     600              :     }
     601              : 
     602       513303 :     inline std::string makeUPPER(std::string_view const InputString) // Input String
     603              :     {
     604              : 
     605              :         // FUNCTION INFORMATION:
     606              :         //       AUTHOR         Linda K. Lawrie
     607              :         //       DATE WRITTEN   September 1997
     608              :         //       MODIFIED       na
     609              :         //       RE-ENGINEERED  na
     610              : 
     611              :         // PURPOSE OF THIS SUBROUTINE:
     612              :         // This function returns the Upper Case representation of the InputString.
     613              : 
     614              :         // METHODOLOGY EMPLOYED:
     615              :         // Uses the Intrinsic SCAN function to scan the lowercase representation of
     616              :         // characters (DataStringGlobals) for each character in the given string.
     617              : 
     618              :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
     619              : 
     620       513303 :         std::string ResultString(InputString);
     621              : 
     622     15407203 :         for (std::string::size_type i = 0, e = len(InputString); i < e; ++i) {
     623     14893900 :             int const curCharVal = int(InputString[i]);
     624     14893900 :             if ((97 <= curCharVal && curCharVal <= 122) || (224 <= curCharVal && curCharVal <= 255)) { // lowercase ASCII and accented characters
     625      9814278 :                 ResultString[i] = char(curCharVal - 32);
     626              :             }
     627              :         }
     628              : 
     629       513303 :         return ResultString;
     630            0 :     }
     631              : 
     632       989287 :     constexpr bool SameString(std::string_view const s, std::string_view const t)
     633              :     {
     634              :         // case insensitive comparison
     635       989287 :         return equali(s, t);
     636              :     }
     637              : 
     638              :     template <typename InputIterator>
     639              :     inline void VerifyName(EnergyPlusData &state,
     640              :                            InputIterator first,
     641              :                            InputIterator last,
     642              :                            std::string const &NameToVerify,
     643              :                            bool &ErrorFound,
     644              :                            bool &IsBlank,
     645              :                            std::string const &StringToDisplay)
     646              :     {
     647              :         IsBlank = false;
     648              :         ErrorFound = false;
     649              :         if (NameToVerify.empty()) {
     650              :             ShowSevereError(state, StringToDisplay + ", cannot be blank");
     651              :             ErrorFound = true;
     652              :             IsBlank = true;
     653              :             return;
     654              :         }
     655              :         int Found = FindItem(first, last, NameToVerify);
     656              :         if (Found != 0) {
     657              :             ShowSevereError(state, StringToDisplay + ", duplicate name=" + NameToVerify);
     658              :             ErrorFound = true;
     659              :         }
     660              :     }
     661              : 
     662              :     void VerifyName(EnergyPlusData &state,
     663              :                     std::string const &NameToVerify,
     664              :                     Array1D_string const &NamesList,
     665              :                     int const NumOfNames,
     666              :                     bool &ErrorFound,
     667              :                     bool &IsBlank,
     668              :                     std::string const &StringToDisplay);
     669              : 
     670              :     void VerifyName(EnergyPlusData &state,
     671              :                     std::string const &NameToVerify,
     672              :                     Array1S_string const NamesList,
     673              :                     int const NumOfNames,
     674              :                     bool &ErrorFound,
     675              :                     bool &IsBlank,
     676              :                     std::string const &StringToDisplay);
     677              : 
     678              :     template <typename A>
     679              :     inline void VerifyName(EnergyPlusData &state,
     680              :                            std::string const &NameToVerify,
     681              :                            MArray1<A, std::string> const &NamesList,
     682              :                            int const NumOfNames,
     683              :                            bool &ErrorFound,
     684              :                            bool &IsBlank,
     685              :                            std::string const &StringToDisplay)
     686              :     { // Overload for member arrays: Implemented here to avoid copy to Array_string to forward to other VerifyName
     687              :         ErrorFound = false;
     688              :         if (NumOfNames > 0) {
     689              :             int const Found = FindItem(NameToVerify, NamesList,
     690              :                                        NumOfNames); // Calls FindItem overload that accepts member arrays
     691              :             if (Found != 0) {
     692              :                 ShowSevereError(state, StringToDisplay + ", duplicate name=" + NameToVerify);
     693              :                 ErrorFound = true;
     694              :             }
     695              :         }
     696              : 
     697              :         if (NameToVerify.empty()) {
     698              :             ShowSevereError(state, StringToDisplay + ", cannot be blank");
     699              :             ErrorFound = true;
     700              :             IsBlank = true;
     701              :         } else {
     702              :             IsBlank = false;
     703              :         }
     704              :     }
     705              : 
     706              :     template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
     707              :     // Container needs size() and operator[i] and elements need Name
     708           44 :     inline void VerifyName(EnergyPlusData &state,
     709              :                            std::string const &NameToVerify,
     710              :                            Container const &NamesList,
     711              :                            int const NumOfNames,
     712              :                            bool &ErrorFound,
     713              :                            bool &IsBlank,
     714              :                            std::string const &StringToDisplay)
     715              :     {
     716           44 :         ErrorFound = false;
     717           44 :         if (NumOfNames > 0) {
     718            1 :             int const Found = FindItem(NameToVerify, NamesList,
     719              :                                        NumOfNames); // Calls FindItem overload that accepts member arrays
     720            1 :             if (Found != 0) {
     721            0 :                 ShowSevereError(state, StringToDisplay + ", duplicate name=" + NameToVerify);
     722            0 :                 ErrorFound = true;
     723              :             }
     724              :         }
     725              : 
     726           44 :         if (NameToVerify.empty()) {
     727            0 :             ShowSevereError(state, StringToDisplay + ", cannot be blank");
     728            0 :             ErrorFound = true;
     729            0 :             IsBlank = true;
     730              :         } else {
     731           44 :             IsBlank = false;
     732              :         }
     733           44 :     }
     734              : 
     735              :     template <typename Container, class = typename std::enable_if<!std::is_same<typename Container::value_type, std::string>::value>::type>
     736              :     // Container needs size() and operator[i] and value_type
     737              :     inline void VerifyName(EnergyPlusData &state,
     738              :                            std::string const &NameToVerify,
     739              :                            Container const &NamesList,
     740              :                            std::string Container::value_type::*name_p,
     741              :                            int const NumOfNames,
     742              :                            bool &ErrorFound,
     743              :                            bool &IsBlank,
     744              :                            std::string const &StringToDisplay)
     745              :     {
     746              :         ErrorFound = false;
     747              :         if (NumOfNames > 0) {
     748              :             int const Found = FindItem(NameToVerify, NamesList, name_p, NumOfNames);
     749              :             if (Found != 0) {
     750              :                 ShowSevereError(state, StringToDisplay + ", duplicate name=" + NameToVerify);
     751              :                 ErrorFound = true;
     752              :             }
     753              :         }
     754              : 
     755              :         if (NameToVerify.empty()) {
     756              :             ShowSevereError(state, StringToDisplay + ", cannot be blank");
     757              :             ErrorFound = true;
     758              :             IsBlank = true;
     759              :         } else {
     760              :             IsBlank = false;
     761              :         }
     762              :     }
     763              : 
     764              :     bool IsNameEmpty(EnergyPlusData &state, std::string &NameToVerify, std::string_view StringToDisplay, bool &ErrorFound);
     765              : 
     766              :     // Two structs for case insensitive containers.
     767              :     // Eg: for unordered_map, we need to have a case insenstive hasher and a case insensitive comparator
     768              :     // (The default allocator for unordered_map is fine)
     769              :     // For map, you'd only need the comparator
     770              :     struct case_insensitive_hasher
     771              :     {
     772              :         using is_transparent = void;
     773              :         size_t operator()(std::string_view key) const noexcept;
     774              :     };
     775              : 
     776              :     struct case_insensitive_comparator
     777              :     {
     778              :         using is_transparent = void;
     779              :         bool operator()(std::string_view a, std::string_view b) const noexcept;
     780              :     };
     781              : 
     782              :     void appendPerfLog(EnergyPlusData &state, std::string const &colHeader, std::string const &colValue, bool finalColumn = false);
     783              : 
     784              : } // namespace Util
     785              : 
     786        26096 : constexpr int getEnumValue(const gsl::span<const std::string_view> sList, const std::string_view s)
     787              : {
     788       972205 :     for (unsigned int i = 0; i < sList.size(); ++i) {
     789       972071 :         if (sList[i] == s) return i;
     790              :     }
     791          134 :     return -1;
     792              : }
     793              : 
     794              : constexpr std::array<std::string_view, 2> yesNoNames = {"No", "Yes"};
     795              : constexpr std::array<std::string_view, 2> yesNoNamesUC = {"NO", "YES"};
     796              : 
     797         1227 : constexpr BooleanSwitch getYesNoValue(const std::string_view s)
     798              : {
     799         1227 :     return static_cast<BooleanSwitch>(getEnumValue(yesNoNamesUC, s));
     800              : }
     801              : 
     802              : constexpr Real64 fclamp(Real64 v, Real64 min, Real64 max)
     803              : {
     804              :     return (v < min) ? min : ((v > max) ? max : v);
     805              : }
     806              : 
     807              : struct UtilityRoutinesData : BaseGlobalStruct
     808              : {
     809              : 
     810              :     bool outputErrorHeader = true;
     811              :     std::string appendPerfLog_headerRow;
     812              :     std::string appendPerfLog_valuesRow;
     813              :     bool GetMatrixInputFlag = true;
     814              : 
     815         2126 :     void init_constant_state([[maybe_unused]] EnergyPlusData &state) override
     816              :     {
     817         2126 :     }
     818              : 
     819         1152 :     void init_state([[maybe_unused]] EnergyPlusData &state) override
     820              :     {
     821         1152 :     }
     822              : 
     823         2100 :     void clear_state() override
     824              :     {
     825         2100 :         outputErrorHeader = true;
     826         2100 :         appendPerfLog_headerRow.clear();
     827         2100 :         appendPerfLog_valuesRow.clear();
     828         2100 :         GetMatrixInputFlag = true;
     829         2100 :     }
     830              : 
     831              :     // Default Constructor
     832         2129 :     UtilityRoutinesData() = default;
     833              : };
     834              : } // namespace EnergyPlus
     835              : 
     836              : #endif
        

Generated by: LCOV version 2.0-1