LCOV - code coverage report
Current view: top level - libMagAOX/file - stdSubDir.hpp (source / functions) Coverage Total Hit
Test: MagAOX Lines: 100.0 % 243 243
Test Date: 2026-01-03 21:03:39 Functions: 100.0 % 22 22

            Line data    Source code
       1              : /** \file stdSubDir.hpp
       2              :  * \brief The stdSubDir class for managing subdirectories
       3              :  *
       4              :  * \ingroup file_files
       5              :  *
       6              :  */
       7              : 
       8              : #ifndef file_stdSubDir_hpp
       9              : #define file_stdSubDir_hpp
      10              : 
      11              : #include <string>
      12              : #include <chrono>
      13              : 
      14              : #include <mx/mxlib.hpp>
      15              : #include <mx/ioutils/stringUtils.hpp>
      16              : #include "../common/exceptions.hpp"
      17              : 
      18              : #include "../common/defaults.hpp"
      19              : 
      20              : namespace MagAOX
      21              : {
      22              : namespace file
      23              : {
      24              : 
      25              : #ifdef XWCTEST_NAMESPACE
      26              : namespace XWCTEST_NAMESPACE
      27              : {
      28              : #endif
      29              : 
      30              : /// Manage a standard subdirectory
      31              : /** MagAO-X data storage subdirectories have the format YYYY_MM_DD
      32              :  *  This class provides parsing and date arithmetic.
      33              :  */
      34              : template <typename verboseT = XWC_DEFAULT_VERBOSITY>
      35              : class stdSubDir
      36              : {
      37              : 
      38              :   protected:
      39              :     std::chrono::sys_days m_sysday; ///< System time representation of the date of this sub directory
      40              : 
      41              :     mutable bool m_pathMade{ false }; ///< Whether or not the path string has been constructed
      42              : 
      43              :     mutable std::string m_path; ///< The path string.  Only constructed on demand.
      44              : 
      45              :     bool m_valid{ false }; ///< Whether or not the components are valid
      46              : 
      47              :   public:
      48              :     /// Default c'tor
      49              :     stdSubDir();
      50              : 
      51              :     /// Construct from std::sys_days
      52              :     /**
      53              :      * On success, sets `m_valid=true`
      54              :      *
      55              :      * On error, sets `m_valid=false`
      56              :      */
      57              :     explicit stdSubDir( const std::chrono::sys_days &sysday /**< [in] The new year*/ );
      58              : 
      59              :     /// Construct from components
      60              :     /**
      61              :      * On success, sets `m_valid=true`
      62              :      *
      63              :      * On error, sets `m_valid=false`
      64              :      */
      65              :     stdSubDir( int      year,  /**< [in] The new year*/
      66              :                unsigned month, /**< [in] The new month*/
      67              :                unsigned day    /**< [in] The new day*/
      68              :     );
      69              : 
      70              :     /// Construct from a string
      71              :     /**
      72              :      * On success, sets `m_valid=true`
      73              :      *
      74              :      * On error, sets `m_valid=false`
      75              :      */
      76              :     stdSubDir( const std::string &subdir /**< [in] The string of format YYYY_MM_DD*/ );
      77              : 
      78              :     /// Setup from components
      79              :     /**
      80              :      * On success, sets `m_valid=true`
      81              :      *
      82              :      * On error, sets `m_valid=false`
      83              :      */
      84              :     mx::error_t ymd( int      year,  /**< [in] The new year*/
      85              :                      unsigned month, /**< [in] The new month*/
      86              :                      unsigned day    /**< [in] The new day*/
      87              :     );
      88              : 
      89              :     /// Set the subdirectory
      90              :     /**
      91              :      * Parses the string and sets the time point
      92              :      */
      93              :     mx::error_t path( const std::string &subdir );
      94              : 
      95              :     /// Get the current value of m_subDir
      96              :     /**
      97              :      * \returns the current value of m_subDir if valid and path construction succeeds
      98              :      * \returns empty string "" if invalid or path construction fails
      99              :      */
     100              :     std::string path( mx::error_t *errc = nullptr /**< [in] [optional] error code set during path creation */ ) const;
     101              : 
     102              :     /// Get the current value of m_year
     103              :     /**
     104              :      * \returns the current value of m_year if valid
     105              :      * \returns std::numeric_limits<int>::max() if invalid
     106              :      */
     107              :     int year( mx::error_t *errc = nullptr /**< [in] [optional] error code set during path creation */ ) const;
     108              : 
     109              :     /// Get the current value of m_month
     110              :     /**
     111              :      * \returns the current value of m_month if valid
     112              :      * \returns std::numeric_limits<unsigned int>::max() if invalid
     113              :      */
     114              :     unsigned int month( mx::error_t *errc = nullptr /**< [in] [optional] error code set during path creation */ ) const;
     115              : 
     116              :     /// Get the current value of m_day
     117              :     /**
     118              :      * \returns the current value of m_day if valid
     119              :      * \returns std::numeric_limits<unsigned int>::max() if invalid
     120              :      */
     121              :     unsigned int day( mx::error_t *errc = nullptr /**< [in] [optional] error code set during path creation */ ) const;
     122              : 
     123              :     /// Get the current value of m_valid
     124              :     /**
     125              :      * \returns the current value of m_valid
     126              :      */
     127              :     bool valid() const;
     128              : 
     129              :     // Manipulations
     130              : 
     131              :     /// Add a day to this subdirectory
     132              :     mx::error_t addDay();
     133              : 
     134              :     /// Subtract a day from this subdirectory
     135              :     mx::error_t subDay();
     136              : 
     137              :     /// Get the previous day's subdirectory
     138              :     stdSubDir previousSubdir( mx::error_t *errc = nullptr /**< [in] [optional] error code set during path creation */ );
     139              : 
     140              :     /// Get the following day's subdirectory
     141              :     stdSubDir followingSubdir( mx::error_t *errc = nullptr /**< [in] [optional] error code set during path creation */
     142              :     );
     143              : 
     144              :     /// Compare two subdirectories for equality by timestamp
     145              :     /** Two subdirectories are equal if and only if their timestamps are equal
     146              :      *
     147              :      */
     148              :     bool operator==( const stdSubDir &comp ) const;
     149              : 
     150              :     /// Compare two subdirectories for inequality by timestamp
     151              :     /** Two subdirectories are equal if and only if their timestamps are equal
     152              :      *
     153              :      */
     154              :     bool operator!=( const stdSubDir &comp ) const;
     155              : 
     156              :     /// Compare two subdirectories for less-than by timestamp
     157              :     /** A subdirectory is less than if and only if its timestamp is less-than
     158              :      *
     159              :      */
     160              :     bool operator<( const stdSubDir &comp ) const;
     161              : 
     162              :     /// Compare two subdirectories for less-than-or-equal by timestamp
     163              :     /** A subdirectory is less than or equal if and only if its timestamp is less-than-or-equal
     164              :      *
     165              :      */
     166              :     bool operator<=( const stdSubDir &comp ) const;
     167              : 
     168              :     /// Compare two subdirectories for greater-than by timestamp
     169              :     /** A subdirectory is greater than if and only if its timestamp is greater-than
     170              :      *
     171              :      */
     172              :     bool operator>( const stdSubDir &comp ) const;
     173              : 
     174              :     /// Compare two subdirectories for greater-than-or-equal by timestamp
     175              :     /** A subdirectory is greater than if and only if its timestamp is greater-than-or-equal
     176              :      *
     177              :      */
     178              :     bool operator>=( const stdSubDir &comp ) const;
     179              : 
     180              :     /// Invalidate this instance
     181              :     void invalidate();
     182              : 
     183              : };
     184              : 
     185              : template <typename verboseT>
     186          146 : stdSubDir<verboseT>::stdSubDir()
     187              : {
     188          146 :     return;
     189              : }
     190              : 
     191              : template <typename verboseT>
     192            3 : stdSubDir<verboseT>::stdSubDir( const std::chrono::sys_days &sysday )
     193              : {
     194              :     try
     195              :     {
     196              :         // clang-format off
     197              :         #ifdef XWCTEST_STDSUBDIR_CTORSYSDAYS_BAD_ALLOC
     198              :             throw std::bad_alloc(); // LCOV_EXCL_LINE
     199              :         #endif
     200              : 
     201              :         #ifdef XWCTEST_STDSUBDIR_CTORSYSDAYS_EXCEPTION
     202              :             throw std::exception(); // LCOV_EXCL_LINE
     203              :         #endif
     204              :         // clang-format on
     205              : 
     206            1 :         m_sysday = sysday;
     207            1 :         m_valid  = true;
     208              :     }
     209            3 :     catch( const std::bad_alloc &e )
     210              :     {
     211            4 :         std::throw_with_nested( xwcException( "chrono operations", -6 ) );
     212              :     }
     213            2 :     catch( const std::exception &e )
     214              :     {
     215            3 :         mx::error_report<verboseT>( mx::error_t::std_exception, std::string( "chrono operations: " ) + e.what() );
     216              :     }
     217            3 : }
     218              : 
     219              : template <typename verboseT>
     220           58 : stdSubDir<verboseT>::stdSubDir( int year, unsigned month, unsigned day )
     221              : {
     222           58 :     ymd( year, month, day );
     223           58 : }
     224              : 
     225              : template <typename verboseT>
     226           20 : stdSubDir<verboseT>::stdSubDir( const std::string &subdir )
     227              : {
     228           20 :     path( subdir );
     229           20 : }
     230              : 
     231              : template <typename verboseT>
     232          145 : mx::error_t stdSubDir<verboseT>::ymd( int year, unsigned month, unsigned day )
     233              : {
     234              :     // we technically could be subtle about this and wait for changes to occur
     235              :     // but we'll just propagate any errors as invalidating this instance
     236          145 :     invalidate();
     237              : 
     238              :     try
     239              :     {
     240              :         // clang-format off
     241              :         #ifdef XWCTEST_STDSUBDIR_YMD_BAD_ALLOC
     242              :             throw std::bad_alloc(); // LCOV_EXCL_LINE
     243              :         #endif
     244              : 
     245              :         #ifdef XWCTEST_STDSUBDIR_YMD_EXCEPTION
     246              :             throw std::exception(); // LCOV_EXCL_LINE
     247              :         #endif
     248              :         // clang-format on
     249              : 
     250          141 :         std::chrono::year_month_day ymd{
     251          141 :             std::chrono::year( year ), std::chrono::month( month ), std::chrono::day( day ) };
     252              : 
     253          141 :         m_sysday = ymd;
     254              : 
     255          141 :         m_valid = true;
     256          141 :         return mx::error_t::noerror;
     257              :     }
     258            6 :     catch( const std::bad_alloc &e )
     259              :     {
     260            8 :         std::throw_with_nested( xwcException( "chrono operations", -6 ) );
     261              :     }
     262            4 :     catch( const std::exception &e )
     263              :     {
     264            4 :         return mx::error_report<verboseT>( mx::error_t::std_exception,
     265           10 :                                            std::string( "chrono operations: " ) + e.what() );
     266              :     }
     267              : }
     268              : 
     269              : template <typename verboseT>
     270           39 : mx::error_t stdSubDir<verboseT>::path( const std::string &subdir )
     271              : {
     272              :     // we technically could be subtle about this and wait for changes to occur
     273              :     // but we'll just propagate any errors as invalidating this instance
     274           39 :     invalidate();
     275              : 
     276           39 :     if( subdir.length() != 10 )
     277              :     {
     278            3 :         return mx::error_report<verboseT>( mx::error_t::invalidarg, "subdir " + subdir + " is not 10 chars long " );
     279              :     }
     280              : 
     281          105 :     for( size_t n : { 4, 7 } )
     282              :     {
     283           71 :         if( subdir[n] != '_' )
     284              :         {
     285            2 :             return mx::error_report<verboseT>( mx::error_t::invalidarg, "subdir " + subdir + " is missing _ " );
     286              :         }
     287              :     }
     288              : 
     289          270 :     for( size_t n : { 0, 1, 2, 3, 5, 6, 8, 9 } )
     290              :     {
     291          244 :         if( !isdigit( subdir[n] ) )
     292              :         {
     293           16 :             return mx::error_report<verboseT>( mx::error_t::invalidarg,
     294            8 :                                                "subdir " + subdir + " has non-digit at " + std::to_string( n ) );
     295              :         }
     296              :     }
     297              : 
     298              :     mx::error_t errc;
     299              : 
     300              :     int          year;
     301              :     unsigned int month, day;
     302              : 
     303              :     try
     304              :     {
     305              :         // clang-format off
     306              :         #ifdef XWCTEST_STDSUBDIR_SETPATH_BAD_ALLOC
     307              :             throw std::bad_alloc(); // LCOV_EXCL_LINE
     308              :         #endif
     309              : 
     310              :         #ifdef XWCTEST_STDSUBDIR_SETPATH_OUT_OF_RANGE
     311              :             throw std::out_of_range("test"); // LCOV_EXCL_LINE
     312              :         #endif
     313              : 
     314              :         #ifdef XWCTEST_STDSUBDIR_SETPATH_EXCEPTION
     315              :             throw std::exception(); // LCOV_EXCL_LINE
     316              :         #endif
     317              :         // clang-format on
     318              : 
     319           20 :         year = mx::ioutils::stoT<int>( subdir.substr( 0, 4 ), errc );
     320           20 :         mx_error_check_code( errc );
     321              : 
     322           20 :         month = mx::ioutils::stoT<unsigned int>( subdir.substr( 5, 2 ), errc );
     323           20 :         mx_error_check_code( errc );
     324              : 
     325           20 :         day = mx::ioutils::stoT<unsigned int>( subdir.substr( 8, 2 ), errc );
     326           20 :         mx_error_check_code( errc );
     327              :     }
     328            8 :     catch( const std::bad_alloc &e )
     329              :     {
     330            8 :         std::throw_with_nested( xwcException( "parsing subdir", -6 ) );
     331              :     }
     332            4 :     catch( const std::out_of_range &e )
     333              :     {
     334            6 :         return mx::error_report<verboseT>( mx::error_t::std_out_of_range, std::string( "parsing subdir" ) + e.what() );
     335              :     }
     336            4 :     catch( const std::exception &e )
     337              :     {
     338            6 :         return mx::error_report<verboseT>( mx::error_t::std_exception, std::string( "parsing subdir" ) + e.what() );
     339              :     }
     340              : 
     341              :     try
     342              :     {
     343              :         // clang-format off
     344              :         #ifdef XWCTEST_STDSUBDIR_SETPATH_BAD_ALLOC2
     345              :             throw std::bad_alloc(); // LCOV_EXCL_LINE
     346              :         #endif
     347              : 
     348              :         #ifdef XWCTEST_STDSUBDIR_SETPATH_EXCEPTION2
     349              :             throw std::exception(); // LCOV_EXCL_LINE
     350              :         #endif
     351              :         // clang-format on
     352              : 
     353           16 :         std::chrono::year_month_day ymd{
     354           16 :             std::chrono::year( year ), std::chrono::month( month ), std::chrono::day( day ) };
     355              : 
     356           16 :         m_sysday = ymd;
     357              : 
     358           16 :         m_path     = subdir;
     359           16 :         m_pathMade = true;
     360              : 
     361           16 :         m_valid = true;
     362              : 
     363           16 :         return mx::error_t::noerror;
     364              :     }
     365            6 :     catch( const std::bad_alloc &e )
     366              :     {
     367            8 :         std::throw_with_nested( xwcException( "chrono operations", -6 ) );
     368              :     }
     369            4 :     catch( const std::exception &e )
     370              :     {
     371            4 :         return mx::error_report<verboseT>( mx::error_t::std_exception,
     372           10 :                                            std::string( "chrono operations: " ) + e.what() );
     373              :     }
     374              : }
     375              : 
     376              : template <typename verboseT>
     377          475 : std::string stdSubDir<verboseT>::path( mx::error_t *errc ) const
     378              : {
     379          475 :     if( !m_valid )
     380              :     {
     381            4 :         if( errc )
     382              :         {
     383            2 :             *errc = mx::error_t::invalidconfig;
     384              :         }
     385            8 :         mx::error_report<verboseT>( mx::error_t::invalidconfig, "attempt to access path while invalid" );
     386            8 :         return "";
     387              :     }
     388              : 
     389          471 :     if( !m_pathMade )
     390              :     {
     391              :         try
     392              :         {
     393              :             // clang-format off
     394              :             #ifdef XWCTEST_STDSUBDIR_MAKEPATH_BAD_ALLOC
     395              :                 throw std::bad_alloc(); // LCOV_EXCL_LINE
     396              :             #endif
     397              : 
     398              :             #ifdef XWCTEST_STDSUBDIR_MAKEPATH_FORMAT_ERROR
     399              :                 throw std::format_error("test"); // LCOV_EXCL_LINE
     400              :             #endif
     401              : 
     402              :             #ifdef XWCTEST_STDSUBDIR_MAKEPATH_EXCEPTION
     403              :                 throw std::exception(); // LCOV_EXCL_LINE
     404              :             #endif
     405              :             // clang-format on
     406              : 
     407          445 :             m_path = std::format( "{:%Y_%m_%d}", m_sysday );
     408              : 
     409          445 :             m_pathMade = true;
     410              :         }
     411            4 :         catch( const std::bad_alloc &e )
     412              :         {
     413            4 :             std::throw_with_nested( xwcException( "bad_alloc from std::format", -12 ) );
     414              :         }
     415            1 :         catch( const std::format_error &e )
     416              :         {
     417            1 :             if( errc )
     418              :             {
     419            1 :                 *errc = mx::error_t::std_format_error;
     420              :             }
     421            3 :             mx::error_report<verboseT>( mx::error_t::std_format_error, std::string( "from std::format: " ) + e.what() );
     422            2 :             return "";
     423              :         }
     424            1 :         catch( const std::exception &e )
     425              :         {
     426            1 :             if( errc )
     427              :             {
     428            1 :                 *errc = mx::error_t::std_exception;
     429              :             }
     430            3 :             mx::error_report<verboseT>( mx::error_t::std_exception, std::string( "from std::format: " ) + e.what() );
     431            2 :             return "";
     432              :         }
     433              :     }
     434              : 
     435          468 :     if( errc )
     436              :     {
     437            1 :         *errc = mx::error_t::noerror;
     438              :     }
     439          468 :     return m_path;
     440              : }
     441              : 
     442              : template <typename verboseT>
     443           36 : int stdSubDir<verboseT>::year( mx::error_t *errc ) const
     444              : {
     445           36 :     if( !m_valid )
     446              :     {
     447            3 :         if( errc )
     448              :         {
     449            2 :             *errc = mx::error_t::invalidconfig;
     450              :         }
     451            6 :         mx::error_report<verboseT>( mx::error_t::invalidconfig, "attempt to access year while invalid" );
     452            3 :         return std::numeric_limits<int>::max();
     453              :     }
     454              : 
     455              :     try
     456              :     {
     457              :         // clang-format off
     458              :         #ifdef XWCTEST_STDSUBDIR_GYMD_BAD_ALLOC
     459              :             throw std::bad_alloc(); // LCOV_EXCL_LINE
     460              :         #endif
     461              : 
     462              :         #ifdef XWCTEST_STDSUBDIR_GYMD_EXCEPTION
     463              :             throw std::exception(); // LCOV_EXCL_LINE
     464              :         #endif
     465              :         // clang-format on
     466              : 
     467           31 :         std::chrono::year_month_day ymd{ m_sysday };
     468              : 
     469           31 :         if( errc )
     470              :         {
     471            4 :             *errc = mx::error_t::noerror;
     472              :         }
     473              : 
     474           31 :         return static_cast<int>( ymd.year() );
     475              :     }
     476            3 :     catch( const std::bad_alloc &e )
     477              :     {
     478            1 :         if( errc )
     479              :         {
     480            1 :             *errc = mx::error_t::std_bad_alloc;
     481              :         }
     482            4 :         std::throw_with_nested( xwcException( "chrono operations", -6 ) );
     483              :     }
     484            2 :     catch( const std::exception &e )
     485              :     {
     486            1 :         if( errc )
     487              :         {
     488            1 :             *errc = mx::error_t::std_exception;
     489              :         }
     490            3 :         mx::error_report<verboseT>( mx::error_t::std_exception, std::string( "chrono operations: " ) + e.what() );
     491            1 :         return std::numeric_limits<int>::max();
     492              :     }
     493              : }
     494              : 
     495              : template <typename verboseT>
     496           36 : unsigned int stdSubDir<verboseT>::month( mx::error_t *errc ) const
     497              : {
     498           36 :     if( !m_valid )
     499              :     {
     500            3 :         if( errc )
     501              :         {
     502            2 :             *errc = mx::error_t::invalidconfig;
     503              :         }
     504            6 :         mx::error_report<verboseT>( mx::error_t::invalidconfig, "attempt to access month while invalid" );
     505            3 :         return std::numeric_limits<unsigned int>::max();
     506              :     }
     507              : 
     508              :     try
     509              :     {
     510              :         // clang-format off
     511              :         #ifdef XWCTEST_STDSUBDIR_GYMD_BAD_ALLOC
     512              :             throw std::bad_alloc(); // LCOV_EXCL_LINE
     513              :         #endif
     514              : 
     515              :         #ifdef XWCTEST_STDSUBDIR_GYMD_EXCEPTION
     516              :             throw std::exception(); // LCOV_EXCL_LINE
     517              :         #endif
     518              :         // clang-format on
     519              : 
     520           31 :         std::chrono::year_month_day ymd{ m_sysday };
     521              : 
     522           31 :         if( errc )
     523              :         {
     524            4 :             *errc = mx::error_t::noerror;
     525              :         }
     526           31 :         return static_cast<unsigned>( ymd.month() );
     527              :     }
     528            3 :     catch( const std::bad_alloc &e )
     529              :     {
     530            1 :         if( errc )
     531              :         {
     532            1 :             *errc = mx::error_t::std_bad_alloc;
     533              :         }
     534            4 :         std::throw_with_nested( xwcException( "chrono operations", -6 ) );
     535              :     }
     536            2 :     catch( const std::exception &e )
     537              :     {
     538            1 :         if( errc )
     539              :         {
     540            1 :             *errc = mx::error_t::std_exception;
     541              :         }
     542            3 :         mx::error_report<verboseT>( mx::error_t::std_exception, std::string( "chrono operations: " ) + e.what() );
     543            1 :         return std::numeric_limits<unsigned int>::max();
     544              :     }
     545              : }
     546              : 
     547              : template <typename verboseT>
     548           36 : unsigned int stdSubDir<verboseT>::day( mx::error_t *errc ) const
     549              : {
     550           36 :     if( !m_valid )
     551              :     {
     552            3 :         if( errc )
     553              :         {
     554            2 :             *errc = mx::error_t::invalidconfig;
     555              :         }
     556            6 :         mx::error_report<verboseT>( mx::error_t::invalidconfig, "attempt to access day while invalid" );
     557            3 :         return std::numeric_limits<unsigned int>::max();
     558              :     }
     559              : 
     560              :     try
     561              :     {
     562              :         // clang-format off
     563              :         #ifdef XWCTEST_STDSUBDIR_GYMD_BAD_ALLOC
     564              :             throw std::bad_alloc(); // LCOV_EXCL_LINE
     565              :         #endif
     566              : 
     567              :         #ifdef XWCTEST_STDSUBDIR_GYMD_EXCEPTION
     568              :             throw std::exception(); // LCOV_EXCL_LINE
     569              :         #endif
     570              :         // clang-format on
     571              : 
     572           31 :         std::chrono::year_month_day ymd{ m_sysday };
     573              : 
     574           31 :         if( errc )
     575              :         {
     576            4 :             *errc = mx::error_t::noerror;
     577              :         }
     578           31 :         return static_cast<unsigned>( ymd.day() );
     579              :     }
     580            3 :     catch( const std::bad_alloc &e )
     581              :     {
     582            1 :         if( errc )
     583              :         {
     584            1 :             *errc = mx::error_t::std_bad_alloc;
     585              :         }
     586            4 :         std::throw_with_nested( xwcException( "chrono operations", -6 ) );
     587              :     }
     588            2 :     catch( const std::exception &e )
     589              :     {
     590            1 :         if( errc )
     591              :         {
     592            1 :             *errc = mx::error_t::std_exception;
     593              :         }
     594            3 :         mx::error_report<verboseT>( mx::error_t::std_exception, std::string( "chrono operations: " ) + e.what() );
     595            1 :         return std::numeric_limits<unsigned int>::max();
     596              :     }
     597              : }
     598              : 
     599              : template <typename verboseT>
     600          103 : bool stdSubDir<verboseT>::valid() const
     601              : {
     602          103 :     return m_valid;
     603              : }
     604              : 
     605              : template <typename verboseT>
     606          122 : mx::error_t stdSubDir<verboseT>::addDay()
     607              : {
     608          122 :     if( !m_valid )
     609              :     {
     610            2 :         return mx::error_report<verboseT>( mx::error_t::invalidconfig, "attempt to access while invalid" );
     611              :     }
     612              : 
     613              :     try
     614              :     {
     615              :         // clang-format off
     616              :         #ifdef XWCTEST_STDSUBDIR_INC_BAD_ALLOC
     617              :             throw std::bad_alloc(); // LCOV_EXCL_LINE
     618              :         #endif
     619              : 
     620              :         #ifdef XWCTEST_STDSUBDIR_INC_EXCEPTION
     621              :             throw std::exception(); // LCOV_EXCL_LINE
     622              :         #endif
     623              :         // clang-format on
     624              : 
     625          117 :         m_pathMade = false;
     626          117 :         ++m_sysday;
     627              :     }
     628            6 :     catch( const std::bad_alloc &e )
     629              :     {
     630            2 :         invalidate();
     631            8 :         std::throw_with_nested( xwcException( "chrono operations", -6 ) );
     632              :     }
     633            4 :     catch( const std::exception &e )
     634              :     {
     635            2 :         invalidate();
     636            4 :         return mx::error_report<verboseT>( mx::error_t::std_exception,
     637           10 :                                            std::string( "chrono operations: " ) + e.what() );
     638              :     }
     639              : 
     640          117 :     return mx::error_t::noerror;
     641              : }
     642              : 
     643              : template <typename verboseT>
     644          315 : mx::error_t stdSubDir<verboseT>::subDay()
     645              : {
     646          315 :     if( !m_valid )
     647              :     {
     648            2 :         return mx::error_report<verboseT>( mx::error_t::invalidconfig, "attempt to access while invalid" );
     649              :     }
     650              : 
     651              :     try
     652              :     {
     653              :         // clang-format off
     654              :         #ifdef XWCTEST_STDSUBDIR_INC_BAD_ALLOC
     655              :             throw std::bad_alloc(); // LCOV_EXCL_LINE
     656              :         #endif
     657              : 
     658              :         #ifdef XWCTEST_STDSUBDIR_INC_EXCEPTION
     659              :             throw std::exception(); // LCOV_EXCL_LINE
     660              :         #endif
     661              :         // clang-format on
     662              : 
     663          310 :         --m_sysday;
     664              : 
     665          310 :         m_pathMade = false;
     666              : 
     667          310 :         return mx::error_t::noerror;
     668              :     }
     669            6 :     catch( const std::bad_alloc &e )
     670              :     {
     671            2 :         invalidate();
     672            8 :         std::throw_with_nested( xwcException( "chrono operations", -6 ) );
     673              :     }
     674            4 :     catch( const std::exception &e )
     675              :     {
     676            2 :         invalidate();
     677            4 :         return mx::error_report<verboseT>( mx::error_t::std_exception,
     678           10 :                                            std::string( "chrono operations: " ) + e.what() );
     679              :     }
     680              : }
     681              : 
     682              : template <typename verboseT>
     683           10 : stdSubDir<verboseT> stdSubDir<verboseT>::previousSubdir( mx::error_t *errc )
     684              : {
     685           10 :     if( !m_valid )
     686              :     {
     687            1 :         if( errc )
     688              :         {
     689            1 :             *errc = mx::error_t::invalidconfig;
     690              :         }
     691            2 :         mx::error_report<verboseT>( mx::error_t::invalidconfig, "attempt to access while invalid" );
     692            1 :         return stdSubDir();
     693              :     }
     694              : 
     695              :     try
     696              :     {
     697              :         // clang-format off
     698              :         #ifdef XWCTEST_STDSUBDIR_PREVFOLL_BAD_ALLOC
     699              :             throw std::bad_alloc(); // LCOV_EXCL_LINE
     700              :         #endif
     701              :         // clang-format on
     702              : 
     703            8 :         stdSubDir std = *this;
     704              : 
     705              :         // clang-format off
     706              :         #ifdef XWCTEST_STDSUBDIR_PREV_INVAL
     707              :             // invalidate
     708              :             std.path(""); // LCOV_EXCL_LINE
     709              :         #endif
     710              :         // clang-format on
     711              : 
     712            8 :         if( !std.valid() )
     713              :         {
     714            1 :             if( errc )
     715              :             {
     716            1 :                 *errc = mx::error_t::error;
     717              :             }
     718            2 :             mx::error_report<verboseT>( mx::error_t::error, "an error occurred creating new subdir" );
     719            1 :             return stdSubDir();
     720              :         }
     721              : 
     722            7 :         mx::error_t _errc = std.subDay();
     723              : 
     724            6 :         if( _errc != mx::error_t::noerror )
     725              :         {
     726            2 :             mx::error_report<verboseT>( _errc, "from subDay" );
     727              :         }
     728              : 
     729            6 :         if( errc )
     730              :         {
     731            1 :             *errc = _errc;
     732              :         }
     733              : 
     734            6 :         return std;
     735            8 :     }
     736            3 :     catch( const std::bad_alloc &e )
     737              :     {
     738            1 :         if( errc )
     739              :         {
     740            1 :             *errc = mx::error_t::std_bad_alloc;
     741              :         }
     742            4 :         std::throw_with_nested( xwcException( "chrono operations", -6 ) );
     743              :     }
     744            2 :     catch( const xwcException &e )
     745              :     {
     746            1 :         if( errc )
     747              :         {
     748            1 :             *errc = mx::error_t::std_exception;
     749              :         }
     750            4 :         std::throw_with_nested( xwcException( "chrono operations", -6 ) );
     751              :     }
     752              : }
     753              : 
     754              : template <typename verboseT>
     755            9 : stdSubDir<verboseT> stdSubDir<verboseT>::followingSubdir( mx::error_t *errc )
     756              : {
     757            9 :     if( !m_valid )
     758              :     {
     759            1 :         if( errc )
     760              :         {
     761            1 :             *errc = mx::error_t::invalidconfig;
     762              :         }
     763            2 :         mx::error_report<verboseT>( mx::error_t::invalidconfig, "attempt to access while invalid" );
     764            1 :         return stdSubDir();
     765              :     }
     766              : 
     767              :     try
     768              :     {
     769              :         // clang-format off
     770              :         #ifdef XWCTEST_STDSUBDIR_PREVFOLL_BAD_ALLOC
     771              :             throw std::bad_alloc(); // LCOV_EXCL_LINE
     772              :         #endif
     773              :         // clang-format on
     774              : 
     775            7 :         stdSubDir std = *this;
     776              : 
     777              :         // clang-format off
     778              :         #ifdef XWCTEST_STDSUBDIR_PREV_INVAL
     779              :             // invalidate
     780              :             std.path(""); // LCOV_EXCL_LINE
     781              :         #endif
     782              :         // clang-format on
     783              : 
     784            7 :         if( !std.valid() )
     785              :         {
     786            1 :             if( errc )
     787              :             {
     788            1 :                 *errc = mx::error_t::error;
     789              :             }
     790            2 :             mx::error_report<verboseT>( mx::error_t::error, "an error occurred creating new subdir" );
     791            1 :             return stdSubDir();
     792              :         }
     793              : 
     794            6 :         mx::error_t _errc = std.addDay();
     795              : 
     796            5 :         if( _errc != mx::error_t::noerror )
     797              :         {
     798            2 :             mx::error_report<verboseT>( _errc, "from subDay" );
     799              :         }
     800              : 
     801            5 :         if( errc )
     802              :         {
     803            1 :             *errc = _errc;
     804              :         }
     805              : 
     806            5 :         return std;
     807            7 :     }
     808            3 :     catch( const std::bad_alloc &e )
     809              :     {
     810            1 :         if( errc )
     811              :         {
     812            1 :             *errc = mx::error_t::std_bad_alloc;
     813              :         }
     814            4 :         std::throw_with_nested( xwcException( "chrono operations", -6 ) );
     815              :     }
     816            2 :     catch( const xwcException &e )
     817              :     {
     818            1 :         if( errc )
     819              :         {
     820            1 :             *errc = mx::error_t::std_exception;
     821              :         }
     822            4 :         std::throw_with_nested( xwcException( "chrono operations", -6 ) );
     823              :     }
     824              : }
     825              : 
     826              : template <typename verboseT>
     827            7 : bool stdSubDir<verboseT>::operator==( const stdSubDir &comp ) const
     828              : {
     829            7 :     return ( m_sysday == comp.m_sysday );
     830              : }
     831              : 
     832              : template <typename verboseT>
     833            2 : bool stdSubDir<verboseT>::operator!=( const stdSubDir &comp ) const
     834              : {
     835            2 :     return ( m_sysday != comp.m_sysday );
     836              : }
     837              : 
     838              : template <typename verboseT>
     839           11 : bool stdSubDir<verboseT>::operator<( const stdSubDir &comp ) const
     840              : {
     841           11 :     return ( m_sysday < comp.m_sysday );
     842              : }
     843              : 
     844              : template <typename verboseT>
     845            3 : bool stdSubDir<verboseT>::operator<=( const stdSubDir &comp ) const
     846              : {
     847            3 :     return ( m_sysday <= comp.m_sysday );
     848              : }
     849              : 
     850              : template <typename verboseT>
     851            3 : bool stdSubDir<verboseT>::operator>( const stdSubDir &comp ) const
     852              : {
     853            3 :     return ( m_sysday > comp.m_sysday );
     854              : }
     855              : 
     856              : template <typename verboseT>
     857            3 : bool stdSubDir<verboseT>::operator>=( const stdSubDir &comp ) const
     858              : {
     859            3 :     return ( m_sysday >= comp.m_sysday );
     860              : }
     861              : 
     862              : template <typename verboseT>
     863          299 : void stdSubDir<verboseT>::invalidate()
     864              : {
     865          299 :     m_path.clear();
     866              : 
     867          299 :     m_pathMade = false;
     868          299 :     m_valid = false;
     869          299 : }
     870              : 
     871              : #ifndef XWCTEST_NAMESPACE
     872              : extern template class stdSubDir<XWC_DEFAULT_VERBOSITY>;
     873              : #endif
     874              : 
     875              : #ifdef XWCTEST_NAMESPACE
     876              : }
     877              : #endif
     878              : 
     879              : } // namespace file
     880              : } // namespace MagAOX
     881              : 
     882              : #endif // file_stdSubDir_hpp
        

Generated by: LCOV version 2.0-1