8#ifndef file_stdSubDir_hpp
9#define file_stdSubDir_hpp
14#include <mx/mxlib.hpp>
15#include <mx/ioutils/stringUtils.hpp>
16#include "../common/exceptions.hpp"
18#include "../common/defaults.hpp"
25#ifdef XWCTEST_NAMESPACE
34template <
typename verboseT = XWC_DEFAULT_VERBOSITY>
41 mutable bool m_pathMade{
false };
45 bool m_valid{
false };
57 explicit stdSubDir(
const std::chrono::sys_days &sysday );
84 mx::error_t
ymd(
int year,
93 mx::error_t
path(
const std::string &subdir );
100 std::string
path( mx::error_t *errc =
nullptr )
const;
107 int year( mx::error_t *errc =
nullptr )
const;
114 unsigned int month( mx::error_t *errc =
nullptr )
const;
121 unsigned int day( mx::error_t *errc =
nullptr )
const;
185template <
typename verboseT>
191template <
typename verboseT>
197 #ifdef XWCTEST_STDSUBDIR_CTORSYSDAYS_BAD_ALLOC
198 throw std::bad_alloc();
201 #ifdef XWCTEST_STDSUBDIR_CTORSYSDAYS_EXCEPTION
202 throw std::exception();
209 catch(
const std::bad_alloc &e )
211 std::throw_with_nested(
xwcException(
"chrono operations", -6 ) );
213 catch(
const std::exception &e )
215 mx::error_report<verboseT>( mx::error_t::std_exception, std::string(
"chrono operations: " ) + e.what() );
219template <
typename verboseT>
222 ymd( year, month, day );
225template <
typename verboseT>
231template <
typename verboseT>
241 #ifdef XWCTEST_STDSUBDIR_YMD_BAD_ALLOC
242 throw std::bad_alloc();
245 #ifdef XWCTEST_STDSUBDIR_YMD_EXCEPTION
246 throw std::exception();
250 std::chrono::year_month_day ymd{
251 std::chrono::year( year ), std::chrono::month( month ), std::chrono::day( day ) };
256 return mx::error_t::noerror;
258 catch(
const std::bad_alloc &e )
260 std::throw_with_nested(
xwcException(
"chrono operations", -6 ) );
262 catch(
const std::exception &e )
264 return mx::error_report<verboseT>( mx::error_t::std_exception,
265 std::string(
"chrono operations: " ) + e.what() );
269template <
typename verboseT>
276 if( subdir.length() != 10 )
278 return mx::error_report<verboseT>( mx::error_t::invalidarg,
"subdir " + subdir +
" is not 10 chars long " );
281 for(
size_t n : { 4, 7 } )
283 if( subdir[n] !=
'_' )
285 return mx::error_report<verboseT>( mx::error_t::invalidarg,
"subdir " + subdir +
" is missing _ " );
289 for(
size_t n : { 0, 1, 2, 3, 5, 6, 8, 9 } )
291 if( !isdigit( subdir[n] ) )
293 return mx::error_report<verboseT>( mx::error_t::invalidarg,
294 "subdir " + subdir +
" has non-digit at " + std::to_string( n ) );
301 unsigned int month, day;
306 #ifdef XWCTEST_STDSUBDIR_SETPATH_BAD_ALLOC
307 throw std::bad_alloc();
310 #ifdef XWCTEST_STDSUBDIR_SETPATH_OUT_OF_RANGE
311 throw std::out_of_range(
"test");
314 #ifdef XWCTEST_STDSUBDIR_SETPATH_EXCEPTION
315 throw std::exception();
319 year = mx::ioutils::stoT<int>( subdir.substr( 0, 4 ), errc );
320 mx_error_check_code( errc );
322 month = mx::ioutils::stoT<unsigned int>( subdir.substr( 5, 2 ), errc );
323 mx_error_check_code( errc );
325 day = mx::ioutils::stoT<unsigned int>( subdir.substr( 8, 2 ), errc );
326 mx_error_check_code( errc );
328 catch(
const std::bad_alloc &e )
330 std::throw_with_nested(
xwcException(
"parsing subdir", -6 ) );
332 catch(
const std::out_of_range &e )
334 return mx::error_report<verboseT>( mx::error_t::std_out_of_range, std::string(
"parsing subdir" ) + e.what() );
336 catch(
const std::exception &e )
338 return mx::error_report<verboseT>( mx::error_t::std_exception, std::string(
"parsing subdir" ) + e.what() );
344 #ifdef XWCTEST_STDSUBDIR_SETPATH_BAD_ALLOC2
345 throw std::bad_alloc();
348 #ifdef XWCTEST_STDSUBDIR_SETPATH_EXCEPTION2
349 throw std::exception();
353 std::chrono::year_month_day ymd{
354 std::chrono::year( year ), std::chrono::month( month ), std::chrono::day( day ) };
363 return mx::error_t::noerror;
365 catch(
const std::bad_alloc &e )
367 std::throw_with_nested(
xwcException(
"chrono operations", -6 ) );
369 catch(
const std::exception &e )
371 return mx::error_report<verboseT>( mx::error_t::std_exception,
372 std::string(
"chrono operations: " ) + e.what() );
376template <
typename verboseT>
383 *errc = mx::error_t::invalidconfig;
385 mx::error_report<verboseT>( mx::error_t::invalidconfig,
"attempt to access path while invalid" );
394 #ifdef XWCTEST_STDSUBDIR_MAKEPATH_BAD_ALLOC
395 throw std::bad_alloc();
398 #ifdef XWCTEST_STDSUBDIR_MAKEPATH_FORMAT_ERROR
399 throw std::format_error(
"test");
402 #ifdef XWCTEST_STDSUBDIR_MAKEPATH_EXCEPTION
403 throw std::exception();
407 m_path = std::format(
"{:%Y_%m_%d}", m_sysday );
411 catch(
const std::bad_alloc &e )
413 std::throw_with_nested(
xwcException(
"bad_alloc from std::format", -12 ) );
415 catch(
const std::format_error &e )
419 *errc = mx::error_t::std_format_error;
421 mx::error_report<verboseT>( mx::error_t::std_format_error, std::string(
"from std::format: " ) + e.what() );
424 catch(
const std::exception &e )
428 *errc = mx::error_t::std_exception;
430 mx::error_report<verboseT>( mx::error_t::std_exception, std::string(
"from std::format: " ) + e.what() );
437 *errc = mx::error_t::noerror;
442template <
typename verboseT>
449 *errc = mx::error_t::invalidconfig;
451 mx::error_report<verboseT>( mx::error_t::invalidconfig,
"attempt to access year while invalid" );
452 return std::numeric_limits<int>::max();
458 #ifdef XWCTEST_STDSUBDIR_GYMD_BAD_ALLOC
459 throw std::bad_alloc();
462 #ifdef XWCTEST_STDSUBDIR_GYMD_EXCEPTION
463 throw std::exception();
467 std::chrono::year_month_day ymd{ m_sysday };
471 *errc = mx::error_t::noerror;
474 return static_cast<int>( ymd.year() );
476 catch(
const std::bad_alloc &e )
480 *errc = mx::error_t::std_bad_alloc;
482 std::throw_with_nested(
xwcException(
"chrono operations", -6 ) );
484 catch(
const std::exception &e )
488 *errc = mx::error_t::std_exception;
490 mx::error_report<verboseT>( mx::error_t::std_exception, std::string(
"chrono operations: " ) + e.what() );
491 return std::numeric_limits<int>::max();
495template <
typename verboseT>
502 *errc = mx::error_t::invalidconfig;
504 mx::error_report<verboseT>( mx::error_t::invalidconfig,
"attempt to access month while invalid" );
505 return std::numeric_limits<unsigned int>::max();
511 #ifdef XWCTEST_STDSUBDIR_GYMD_BAD_ALLOC
512 throw std::bad_alloc();
515 #ifdef XWCTEST_STDSUBDIR_GYMD_EXCEPTION
516 throw std::exception();
520 std::chrono::year_month_day ymd{ m_sysday };
524 *errc = mx::error_t::noerror;
526 return static_cast<unsigned>( ymd.month() );
528 catch(
const std::bad_alloc &e )
532 *errc = mx::error_t::std_bad_alloc;
534 std::throw_with_nested(
xwcException(
"chrono operations", -6 ) );
536 catch(
const std::exception &e )
540 *errc = mx::error_t::std_exception;
542 mx::error_report<verboseT>( mx::error_t::std_exception, std::string(
"chrono operations: " ) + e.what() );
543 return std::numeric_limits<unsigned int>::max();
547template <
typename verboseT>
554 *errc = mx::error_t::invalidconfig;
556 mx::error_report<verboseT>( mx::error_t::invalidconfig,
"attempt to access day while invalid" );
557 return std::numeric_limits<unsigned int>::max();
563 #ifdef XWCTEST_STDSUBDIR_GYMD_BAD_ALLOC
564 throw std::bad_alloc();
567 #ifdef XWCTEST_STDSUBDIR_GYMD_EXCEPTION
568 throw std::exception();
572 std::chrono::year_month_day ymd{ m_sysday };
576 *errc = mx::error_t::noerror;
578 return static_cast<unsigned>( ymd.day() );
580 catch(
const std::bad_alloc &e )
584 *errc = mx::error_t::std_bad_alloc;
586 std::throw_with_nested(
xwcException(
"chrono operations", -6 ) );
588 catch(
const std::exception &e )
592 *errc = mx::error_t::std_exception;
594 mx::error_report<verboseT>( mx::error_t::std_exception, std::string(
"chrono operations: " ) + e.what() );
595 return std::numeric_limits<unsigned int>::max();
599template <
typename verboseT>
605template <
typename verboseT>
610 return mx::error_report<verboseT>( mx::error_t::invalidconfig,
"attempt to access while invalid" );
616 #ifdef XWCTEST_STDSUBDIR_INC_BAD_ALLOC
617 throw std::bad_alloc();
620 #ifdef XWCTEST_STDSUBDIR_INC_EXCEPTION
621 throw std::exception();
628 catch(
const std::bad_alloc &e )
631 std::throw_with_nested(
xwcException(
"chrono operations", -6 ) );
633 catch(
const std::exception &e )
636 return mx::error_report<verboseT>( mx::error_t::std_exception,
637 std::string(
"chrono operations: " ) + e.what() );
640 return mx::error_t::noerror;
643template <
typename verboseT>
648 return mx::error_report<verboseT>( mx::error_t::invalidconfig,
"attempt to access while invalid" );
654 #ifdef XWCTEST_STDSUBDIR_INC_BAD_ALLOC
655 throw std::bad_alloc();
658 #ifdef XWCTEST_STDSUBDIR_INC_EXCEPTION
659 throw std::exception();
667 return mx::error_t::noerror;
669 catch(
const std::bad_alloc &e )
672 std::throw_with_nested(
xwcException(
"chrono operations", -6 ) );
674 catch(
const std::exception &e )
677 return mx::error_report<verboseT>( mx::error_t::std_exception,
678 std::string(
"chrono operations: " ) + e.what() );
682template <
typename verboseT>
689 *errc = mx::error_t::invalidconfig;
691 mx::error_report<verboseT>( mx::error_t::invalidconfig,
"attempt to access while invalid" );
698 #ifdef XWCTEST_STDSUBDIR_PREVFOLL_BAD_ALLOC
699 throw std::bad_alloc();
706 #ifdef XWCTEST_STDSUBDIR_PREV_INVAL
716 *errc = mx::error_t::error;
718 mx::error_report<verboseT>( mx::error_t::error,
"an error occurred creating new subdir" );
722 mx::error_t _errc = std.
subDay();
724 if( _errc != mx::error_t::noerror )
726 mx::error_report<verboseT>( _errc,
"from subDay" );
736 catch(
const std::bad_alloc &e )
740 *errc = mx::error_t::std_bad_alloc;
742 std::throw_with_nested(
xwcException(
"chrono operations", -6 ) );
748 *errc = mx::error_t::std_exception;
750 std::throw_with_nested(
xwcException(
"chrono operations", -6 ) );
754template <
typename verboseT>
761 *errc = mx::error_t::invalidconfig;
763 mx::error_report<verboseT>( mx::error_t::invalidconfig,
"attempt to access while invalid" );
770 #ifdef XWCTEST_STDSUBDIR_PREVFOLL_BAD_ALLOC
771 throw std::bad_alloc();
778 #ifdef XWCTEST_STDSUBDIR_PREV_INVAL
788 *errc = mx::error_t::error;
790 mx::error_report<verboseT>( mx::error_t::error,
"an error occurred creating new subdir" );
794 mx::error_t _errc = std.
addDay();
796 if( _errc != mx::error_t::noerror )
798 mx::error_report<verboseT>( _errc,
"from subDay" );
808 catch(
const std::bad_alloc &e )
812 *errc = mx::error_t::std_bad_alloc;
814 std::throw_with_nested(
xwcException(
"chrono operations", -6 ) );
820 *errc = mx::error_t::std_exception;
822 std::throw_with_nested(
xwcException(
"chrono operations", -6 ) );
826template <
typename verboseT>
829 return ( m_sysday == comp.
m_sysday );
832template <
typename verboseT>
835 return ( m_sysday != comp.
m_sysday );
838template <
typename verboseT>
841 return ( m_sysday < comp.
m_sysday );
844template <
typename verboseT>
847 return ( m_sysday <= comp.
m_sysday );
850template <
typename verboseT>
853 return ( m_sysday > comp.
m_sysday );
856template <
typename verboseT>
859 return ( m_sysday >= comp.
m_sysday );
862template <
typename verboseT>
871#ifndef XWCTEST_NAMESPACE
875#ifdef XWCTEST_NAMESPACE
#define XWCTEST_NAMESPACE
Manage a standard subdirectory.
bool operator<(const stdSubDir &comp) const
Compare two subdirectories for less-than by timestamp.
mx::error_t ymd(int year, unsigned month, unsigned day)
Setup from components.
std::string m_path
The path string. Only constructed on demand.
stdSubDir(int year, unsigned month, unsigned day)
Construct from components.
unsigned int day(mx::error_t *errc=nullptr) const
Get the current value of m_day.
mx::error_t path(const std::string &subdir)
Set the subdirectory.
void invalidate()
Invalidate this instance.
std::chrono::sys_days m_sysday
System time representation of the date of this sub directory.
unsigned int month(mx::error_t *errc=nullptr) const
Get the current value of m_month.
stdSubDir followingSubdir(mx::error_t *errc=nullptr)
Get the following day's subdirectory.
bool valid() const
Get the current value of m_valid.
int year(mx::error_t *errc=nullptr) const
Get the current value of m_year.
stdSubDir(const std::chrono::sys_days &sysday)
Construct from std::sys_days.
bool operator>=(const stdSubDir &comp) const
Compare two subdirectories for greater-than-or-equal by timestamp.
stdSubDir()
Default c'tor.
mx::error_t subDay()
Subtract a day from this subdirectory.
bool operator!=(const stdSubDir &comp) const
Compare two subdirectories for inequality by timestamp.
bool operator==(const stdSubDir &comp) const
Compare two subdirectories for equality by timestamp.
stdSubDir previousSubdir(mx::error_t *errc=nullptr)
Get the previous day's subdirectory.
bool operator>(const stdSubDir &comp) const
Compare two subdirectories for greater-than by timestamp.
stdSubDir(const std::string &subdir)
Construct from a string.
mx::error_t addDay()
Add a day to this subdirectory.
std::string path(mx::error_t *errc=nullptr) const
Get the current value of m_subDir.
bool operator<=(const stdSubDir &comp) const
Compare two subdirectories for less-than-or-equal by timestamp.
Augments an exception with the source file and line.