pax_global_header00006660000000000000000000000064140364345110014513gustar00rootroot0000000000000052 comment=6e921e1b1d21e84a5c82416ba7ecd98e33a436d0 date-3.0.1/000077500000000000000000000000001403643451100124315ustar00rootroot00000000000000date-3.0.1/.gitignore000066400000000000000000000057731403643451100144350ustar00rootroot00000000000000#ignore thumbnails created by windows Thumbs.db #Ignore files build by Visual Studio *.obj *.exe *.pdb *.user *.aps *.pch *.vspscc *_i.c *_p.c *.ncb *.suo *.tlb *.tlh *.bak *.cache *.ilk *.log [Bb]in [Dd]ebug*/ *.lib *.sbr obj/ [Rr]elease*/ _ReSharper*/ [Tt]est[Rr]esult* .idea/ *.opensdf ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. # User-specific files *.suo *.user *.userosscache *.sln.docstates # User-specific folders *.sln.ide/ # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ x64/ x86/ build/ bld/ [Bb]in/ [Oo]bj/ # Roslyn cache directories *.ide/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* #NUNIT *.VisualState.xml TestResult.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c *_i.c *_p.c *_i.h *.ilk *.meta *.obj *.pch *.pdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *.log *.vspscc *.vssscc .builds *.pidb *.svclog *.scc # Chutzpah Test files _Chutzpah* # Visual C++ cache files ipch/ *.aps *.ncb *.opensdf *.sdf *.cachefile # Visual Studio profiler *.psess *.vsp *.vspx # TFS 2012 Local Workspace $tf/ # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user # JustCode is a .NET coding addin-in .JustCode # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # NCrunch _NCrunch_* .*crunch*.local.xml # MightyMoose *.mm.* AutoTest.Net/ # Web workbench (sass) .sass-cache/ # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml # TODO: Comment the next line if you want to checkin your web deploy settings # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj # NuGet Packages *.nupkg # The packages folder can be ignored because of Package Restore **/packages/* # except build/, which is used as an MSBuild target. !**/packages/build/ # If using the old MSBuild-Integrated Package Restore, uncomment this: #!**/packages/repositories.config # Windows Azure Build Output csx/ *.build.csdef # Windows Store app package directory AppPackages/ # Others sql/ *.Cache ClientBin/ [Ss]tyle[Cc]op.* ~$* *~ *.dbmdl *.dbproj.schemaview *.pfx *.publishsettings node_modules/ bower_components/ # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file # to a newer Visual Studio version. Backup files are not needed, # because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm # SQL Server files *.mdf *.ldf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings # Microsoft Fakes FakesAssemblies/ *.suo *.vcxproj.filters *.npp CMakeFiles/* nbproject/* *.cd *.cd a.out cmake-build-debug/* date-3.0.1/.travis.yml000066400000000000000000000064231403643451100145470ustar00rootroot00000000000000language: cpp env: global: - CMAKE_EXTRA_CONF="-DCOMPILE_WITH_C_LOCALE=ON" - CTEST_OUTPUT_ON_FAILURE=1 matrix: include: - name: "Ubuntu 16.04 LTS (Xenial Xerus) GCC 7" os: linux dist: xenial addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-7 env: - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7" - name: "Ubuntu 16.04 LTS (Xenial Xerus) GCC 8" os: linux dist: xenial addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-8 env: - MATRIX_EVAL="CC=gcc-8 && CXX=g++-8" - name: "Ubuntu 16.04 LTS (Xenial Xerus) GCC 9" os: linux dist: xenial addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-9 env: - MATRIX_EVAL="CC=gcc-9 && CXX=g++-9" - name: "Ubuntu 18.04 LTS (Bionic Beaver) GCC 7" os: linux dist: bionic addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-7 env: - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7" - name: "Ubuntu 18.04 LTS (Bionic Beaver) GCC 8" os: linux dist: bionic addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-8 env: - MATRIX_EVAL="CC=gcc-8 && CXX=g++-8" - name: "Ubuntu 18.04 LTS (Bionic Beaver) Clang 6" os: linux dist: bionic addons: apt: sources: - llvm-toolchain-bionic-6.0 packages: - clang-6.0 env: - MATRIX_EVAL="CC=clang-6.0 && CXX=clang++-6.0" - name: "Ubuntu 18.04 LTS (Bionic Beaver) Clang 7" os: linux dist: bionic addons: apt: sources: - llvm-toolchain-bionic-7 packages: - clang-7 env: - MATRIX_EVAL="CC=clang-7 && CXX=clang++-7" - name: "Ubuntu 18.04 LTS (Bionic Beaver) Clang 8" os: linux dist: bionic addons: apt: sources: - llvm-toolchain-bionic-8 packages: - clang-8 env: - MATRIX_EVAL="CC=clang-8 && CXX=clang++-8" - &macos name: xcode10 os: osx osx_image: xcode10.2 env: - CMAKE_EXTRA_CONF="" addons: homebrew: packages: - bash - ninja - <<: *macos name: xcode9 # xcode 9 only works if we tell it to use c++14 explicitly env: - CMAKE_EXTRA_CONF="-DCMAKE_CXX_STANDARD=14" osx_image: xcode9.4 - <<: *macos osx_image: xcode11 name: xcode11 before_install: - eval "${MATRIX_EVAL}" - ci/install_cmake.sh 3.15.2 - export OPENSSL_ROOT=$(brew --prefix openssl@1.1) - if [ "$(uname)" = "Darwin" ] ; then export PATH="$HOME/cmake/CMake.app/Contents/bin:${PATH}"; fi - if [ "$(uname)" = "Linux" ] ; then export PATH="$HOME/cmake/bin:${PATH}"; fi cache: directories: - $HOME/cmake script: - mkdir -p build - cd build - eval cmake -DENABLE_DATE_TESTING=ON -DBUILD_SHARED_LIBS=ON ${CMAKE_EXTRA_CONF} .. - cmake --build . --parallel - cmake --build . --parallel --target testit date-3.0.1/CMakeLists.txt000066400000000000000000000250251403643451100151750ustar00rootroot00000000000000#[===================================================================[ date library by Howard Hinnant CMake projects that wish to use this library should consider something like the following : include( FetchContent ) FetchContent_Declare( date_src GIT_REPOSITORY https://github.com/HowardHinnant/date.git GIT_TAG v3.0.0 # adjust tag/branch/commit as needed ) FetchContent_MakeAvailable(date_src) ... target_link_libraries (my_target PRIVATE date::date) #]===================================================================] cmake_minimum_required( VERSION 3.7 ) project( date VERSION 3.0.0 ) set(ABI_VERSION 3) # used as SOVERSION, increment when ABI changes include( GNUInstallDirs ) get_directory_property( has_parent PARENT_DIRECTORY ) # Override by setting on CMake command line. set( CMAKE_CXX_STANDARD 17 CACHE STRING "The C++ standard whose features are requested." ) option( USE_SYSTEM_TZ_DB "Use the operating system's timezone database" OFF ) option( MANUAL_TZ_DB "User will set TZ DB manually by invoking set_install in their code" OFF ) option( USE_TZ_DB_IN_DOT "Save the timezone database in the current folder" OFF ) option( BUILD_SHARED_LIBS "Build a shared version of library" OFF ) option( ENABLE_DATE_TESTING "Enable unit tests" OFF ) option( DISABLE_STRING_VIEW "Disable string view" OFF ) option( COMPILE_WITH_C_LOCALE "define ONLY_C_LOCALE=1" OFF ) option( BUILD_TZ_LIB "build/install of TZ library" OFF ) if( ENABLE_DATE_TESTING AND NOT BUILD_TZ_LIB ) message(WARNING "Testing requested, bug BUILD_TZ_LIB not ON - forcing the latter") set (BUILD_TZ_LIB ON CACHE BOOL "required for testing" FORCE) endif( ) function( print_option OPT ) if ( NOT DEFINED PRINT_OPTION_CURR_${OPT} OR ( NOT PRINT_OPTION_CURR_${OPT} STREQUAL ${OPT} ) ) set( PRINT_OPTION_CURR_${OPT} ${${OPT}} CACHE BOOL "" ) mark_as_advanced(PRINT_OPTION_CURR_${OPT}) message( "# date: ${OPT} ${${OPT}}" ) endif( ) endfunction( ) print_option( USE_SYSTEM_TZ_DB ) print_option( MANUAL_TZ_DB ) print_option( USE_TZ_DB_IN_DOT ) print_option( BUILD_SHARED_LIBS ) print_option( ENABLE_DATE_TESTING ) print_option( DISABLE_STRING_VIEW ) #[===================================================================[ date (header only) library #]===================================================================] add_library( date INTERFACE ) add_library( date::date ALIAS date ) target_include_directories( date INTERFACE $ $ ) # adding header sources just helps IDEs target_sources( date INTERFACE $$/date/date.h # the rest of these are not currently part of the public interface of the library: $ $ $ $ ) if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.15) # public headers will get installed: set_target_properties( date PROPERTIES PUBLIC_HEADER include/date/date.h ) endif () # These used to be set with generator expressions, # # ONLY_C_LOCALE=$,1,0> # # which expand in the output target file to, e.g. # # ONLY_C_LOCALE=$,1,0> # # This string is then (somtimes?) not correctly interpreted. if ( COMPILE_WITH_C_LOCALE ) # To workaround libstdc++ issue https://github.com/HowardHinnant/date/issues/388 target_compile_definitions( date INTERFACE ONLY_C_LOCALE=1 ) else() target_compile_definitions( date INTERFACE ONLY_C_LOCALE=0 ) endif() if ( DISABLE_STRING_VIEW ) target_compile_definitions( date INTERFACE HAS_STRING_VIEW=0 -DHAS_DEDUCTION_GUIDES=0 ) endif() #[===================================================================[ tz (compiled) library #]===================================================================] if( BUILD_TZ_LIB ) add_library( date-tz ) target_sources( date-tz PUBLIC $$/date/tz.h PRIVATE include/date/tz_private.h src/tz.cpp ) if ( IOS ) target_sources( date-tz PUBLIC $$/date/ios.h PRIVATE src/ios.mm ) endif() add_library( date::date-tz ALIAS date-tz ) target_link_libraries( date-tz PUBLIC date ) target_include_directories( date-tz PUBLIC $ $ ) if ( USE_SYSTEM_TZ_DB OR MANUAL_TZ_DB ) target_compile_definitions( date-tz PRIVATE AUTO_DOWNLOAD=0 HAS_REMOTE_API=0 ) else() target_compile_definitions( date-tz PRIVATE AUTO_DOWNLOAD=1 HAS_REMOTE_API=1 ) endif() if ( USE_SYSTEM_TZ_DB AND NOT WIN32 AND NOT MANUAL_TZ_DB ) target_compile_definitions( date-tz PRIVATE INSTALL=. PUBLIC USE_OS_TZDB=1 ) else() target_compile_definitions( date-tz PUBLIC USE_OS_TZDB=0 ) endif() if ( WIN32 AND BUILD_SHARED_LIBS ) target_compile_definitions( date-tz PUBLIC DATE_BUILD_DLL=1 ) endif() set(TZ_HEADERS include/date/tz.h) if( IOS ) list(APPEND TZ_HEADERS include/date/ios.h) endif( ) set_target_properties( date-tz PROPERTIES POSITION_INDEPENDENT_CODE ON PUBLIC_HEADER "${TZ_HEADERS}" VERSION "${PROJECT_VERSION}" SOVERSION "${ABI_VERSION}" ) if( NOT MSVC ) find_package( Threads ) target_link_libraries( date-tz PUBLIC Threads::Threads ) endif( ) if( NOT USE_SYSTEM_TZ_DB AND NOT MANUAL_TZ_DB ) find_package( CURL REQUIRED ) target_include_directories( date-tz SYSTEM PRIVATE ${CURL_INCLUDE_DIRS} ) target_link_libraries( date-tz PRIVATE ${CURL_LIBRARIES} ) endif( ) endif( ) #[===================================================================[ installation #]===================================================================] set( version_config "${CMAKE_CURRENT_BINARY_DIR}/dateConfigVersion.cmake" ) include( CMakePackageConfigHelpers ) write_basic_package_version_file( "${version_config}" VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion ) install( TARGETS date EXPORT dateConfig PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/date ) export( TARGETS date NAMESPACE date:: FILE dateTargets.cmake ) if (CMAKE_VERSION VERSION_LESS 3.15) install( FILES include/date/date.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/date ) endif () if( BUILD_TZ_LIB ) install( TARGETS date-tz EXPORT dateConfig PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/date ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) # This is for Windows export( TARGETS date-tz NAMESPACE date:: APPEND FILE dateTargets.cmake ) endif( ) if( WIN32 AND NOT CYGWIN) set( CONFIG_LOC CMake ) else( ) set( CONFIG_LOC "${CMAKE_INSTALL_LIBDIR}/cmake/date" ) endif( ) install( EXPORT dateConfig FILE dateTargets.cmake NAMESPACE date:: DESTINATION ${CONFIG_LOC} ) install ( FILES cmake/dateConfig.cmake "${version_config}" DESTINATION ${CONFIG_LOC}) #[===================================================================[ testing #]===================================================================] if( ENABLE_DATE_TESTING ) enable_testing( ) add_custom_target( testit COMMAND ${CMAKE_CTEST_COMMAND} ) add_dependencies( testit date-tz ) function( add_pass_tests TEST_GLOB TEST_PREFIX ) file( GLOB_RECURSE FILENAMES ${TEST_GLOB} ) foreach( TEST_FILE ${FILENAMES} ) get_filename_component( TEST_NAME ${TEST_FILE} NAME_WE ) get_filename_component( TEST_EXT ${TEST_FILE} EXT ) if( NOT ${TEST_EXT} STREQUAL ".fail.cpp" ) set( PREFIX "${TEST_PREFIX}_pass_${TEST_NAME}" ) set( BIN_NAME ${PREFIX}_bin ) set( TST_NAME ${PREFIX}_test ) add_executable( ${BIN_NAME} EXCLUDE_FROM_ALL ${TEST_FILE} ) add_test( ${TST_NAME} ${BIN_NAME} ) target_link_libraries( ${BIN_NAME} date-tz ) # HACK: because the test files don't use FQ includes: target_include_directories( ${BIN_NAME} PRIVATE include/date ) add_dependencies( testit ${BIN_NAME} ) endif( ) endforeach( ) endfunction( ) function( add_fail_tests TEST_GLOB TEST_PREFIX ) file( GLOB_RECURSE FILENAMES ${TEST_GLOB} ) foreach( TEST_FILE ${FILENAMES} ) get_filename_component( TEST_NAME ${TEST_FILE} NAME_WE ) get_filename_component( TEST_EXT ${TEST_FILE} EXT ) set( TEST_TYPE "_fail" ) set( PREFIX "${TEST_PREFIX}_fail_${TEST_NAME}" ) set( BIN_NAME ${PREFIX}_bin ) set( TST_NAME ${PREFIX}_test ) set( TEST_BIN_NAME ${CMAKE_BINARY_DIR}/${BIN_NAME} ) add_custom_target( ${BIN_NAME} COMMAND ${PROJECT_SOURCE_DIR}/compile_fail.sh ${TEST_BIN_NAME} ${CMAKE_CXX_COMPILER} -std=c++14 -L${CMAKE_BINARY_DIR}/ -ldate-tz -I${PROJECT_SOURCE_DIR}/include -I${PROJECT_SOURCE_DIR}/include/date -o ${BIN_NAME} ${TEST_FILE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT ${TST_NAME} ) add_test( ${TST_NAME} "${PROJECT_SOURCE_DIR}/test_fail.sh" ${CMAKE_BINARY_DIR}/${BIN_NAME} WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/" ) #set_tests_properties( ${TST_NAME} PROPERTIES WILL_FAIL TRUE) add_dependencies( testit ${BIN_NAME} ) endforeach( ) endfunction( ) file( GLOB children RELATIVE "${PROJECT_SOURCE_DIR}/test" "${PROJECT_SOURCE_DIR}/test/*" ) foreach( child ${children} ) if( IS_DIRECTORY "${PROJECT_SOURCE_DIR}/test/${child}" ) set( CUR_FOLDER "${PROJECT_SOURCE_DIR}/test/${child}" ) add_pass_tests( "${CUR_FOLDER}/*.cpp" ${child} ) if( NOT WIN32 ) add_fail_tests( "${CUR_FOLDER}/*.fail.cpp" ${child} ) endif( ) endif( ) endforeach( ) endif( ) date-3.0.1/LICENSE.txt000066400000000000000000000031451403643451100142570ustar00rootroot00000000000000The source code in this project is released using the MIT License. There is no global license for the project because each file is licensed individually with different author names and/or dates. If you contribute to this project, please add your name to the license of each file you modify. If you have already contributed to this project and forgot to add your name to the license, please feel free to submit a new P/R to add your name to the license in each file you modified. For convenience, here is a copy of the MIT license found in each file except without author names or dates: The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. date-3.0.1/README.md000066400000000000000000000112131403643451100137060ustar00rootroot00000000000000# Date [![Build Status](https://travis-ci.org/HowardHinnant/date.svg?branch=master)](https://travis-ci.org/HowardHinnant/date) [![Join the chat at https://gitter.im/HowardHinnant/date](https://badges.gitter.im/HowardHinnant/date.svg)](https://gitter.im/HowardHinnant/date?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) --- **[Try it out on wandbox!](https://wandbox.org/permlink/oyXjibyF680HHoyS)** ## Summary This is actually several separate C++11/C++14/C++17 libraries: 1. `"date.h"` is a header-only library which builds upon ``. It adds some new `duration` types, and new `time_point` types. It also adds "field" types such as `year_month_day` which is a struct `{year, month, day}`. And it provides convenient means to convert between the "field" types and the `time_point` types. * Documentation: http://howardhinnant.github.io/date/date.html * Video: https://www.youtube.com/watch?v=tzyGjOm8AKo * Slides: http://schd.ws/hosted_files/cppcon2015/43/hinnant_dates.pdf 1. `"tz.h"` / `"tz.cpp"` are a timezone library built on top of the `"date.h"` library. This timezone library is a complete parser of the IANA timezone database. It provides for an easy way to access all of the data in this database, using the types from `"date.h"` and ``. The IANA database also includes data on leap seconds, and this library provides utilities to compute with that information as well. * Documentation: http://howardhinnant.github.io/date/tz.html * Video: https://www.youtube.com/watch?v=Vwd3pduVGKY * Slides: http://schd.ws/hosted_files/cppcon2016/0f/Welcome%20To%20The%20Time%20Zone%20-%20Howard%20Hinnant%20-%20CppCon%202016.pdf 1. `"iso_week.h"` is a header-only library built on top of the `"date.h"` library which implements the ISO week date calendar. * Documentation: http://howardhinnant.github.io/date/iso_week.html 1. `"julian.h"` is a header-only library built on top of the `"date.h"` library which implements a proleptic Julian calendar which is fully interoperable with everything above. * Documentation: http://howardhinnant.github.io/date/julian.html 1. `"islamic.h"` is a header-only library built on top of the `"date.h"` library which implements a proleptic Islamic calendar which is fully interoperable with everything above. * Documentation: http://howardhinnant.github.io/date/islamic.html ## Standardization Slightly modified versions of `"date.h"` and `"tz.h"` were voted into the C++20 working draft at the Jacksonville FL meeting on 2018-03-17: * http://howardhinnant.github.io/date/d0355r7.html ## Build & Test The recommended way to use any of these libraries besides `"tz.h"` is to just include it. These are header-only libraries (except `"tz.h"`). To use `"tz.h"`, there is a single source file (`src/tz.cpp`) that needs to be compiled. Here are the recommended directions: https://howardhinnant.github.io/date/tz.html#Installation. One can run tests by cd'ing into the `test` subdirectory and running `testit`. There are known failures on all platforms except for macOS. And even on macOS if C++11 is used. If any of these failures present problems for you, there exist workarounds. Additionally there is _unsupported_ support for [vcpkg](https://github.com/Microsoft/vcpkg) and [CMake](https://cmake.org/). I don't personally use or maintain these systems as for me they cause more problems than they solve (for this small project). If you would like to contribute to these build systems please feel free to file a PR. You can download and install Date using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager: git clone https://github.com/Microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.sh ./vcpkg integrate install vcpkg install date The Date port in vcpkg is updated by Microsoft team members and community contributors. If the version falls behind, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. You can optionally build using [CMake](https://cmake.org/). Here is a guide of how to build and test using the CMake Makefile generator. ```bash mkdir build cd build cmake -DENABLE_DATE_TESTING=ON -DBUILD_TZ_LIB=ON ../ cmake --build . --target testit # Consider '-- -j4' for multithreading ``` ## Projects using this library * www.safe.com * www.webtoolkit.eu/wt * https://github.com/ViewTouch/viewtouch * https://routinghub.com * https://github.com/valhalla * https://github.com/siodb/siodb * https://github.com/KomodoPlatform/atomicDEX-Pro * https://github.com/Kotlin/kotlinx-datetime * https://github.com/royalbee/jewish_date If you would like your project (or product) on this list, just let me know. date-3.0.1/ci/000077500000000000000000000000001403643451100130245ustar00rootroot00000000000000date-3.0.1/ci/install_cmake.sh000077500000000000000000000016621403643451100161760ustar00rootroot00000000000000#!/usr/bin/env bash set -e IFS=. read cm_maj cm_min cm_rel <<<"$1" : ${cm_rel:-0} CMAKE_ROOT=${2:-"${HOME}/cmake"} function cmake_version () { if [[ -d ${CMAKE_ROOT} ]] ; then local perms=$(test $(uname) = "Linux" && echo "/111" || echo "+111") local installed=$(find ${CMAKE_ROOT} -perm ${perms} -type f -name cmake) if [[ "${installed}" != "" ]] ; then echo "$(${installed} --version | head -1)" fi fi } installed=$(cmake_version) if [[ "${installed}" != "" && ${installed} =~ ${cm_maj}.${cm_min}.${cm_rel} ]] ; then echo "cmake already installed: ${installed}" exit fi pkgname="cmake-${cm_maj}.${cm_min}.${cm_rel}-$(uname)-x86_64.tar.gz" tmppkg="/tmp/cmake.tar.gz" wget --quiet https://cmake.org/files/v${cm_maj}.${cm_min}/${pkgname} -O ${tmppkg} mkdir -p ${CMAKE_ROOT} cd ${CMAKE_ROOT} tar --strip-components 1 -xf ${tmppkg} rm -f ${tmppkg} echo "installed: $(cmake_version)" date-3.0.1/cmake/000077500000000000000000000000001403643451100135115ustar00rootroot00000000000000date-3.0.1/cmake/dateConfig.cmake000066400000000000000000000005411403643451100165560ustar00rootroot00000000000000include( CMakeFindDependencyMacro ) include( "${CMAKE_CURRENT_LIST_DIR}/dateTargets.cmake" ) if( NOT MSVC AND TARGET date::date-tz ) find_dependency( Threads REQUIRED) get_target_property( _tzill date::date-tz INTERFACE_LINK_LIBRARIES ) if( _tzill AND "${_tzill}" MATCHES "libcurl" ) find_dependency( CURL ) endif( ) endif( ) date-3.0.1/compile_fail.sh000077500000000000000000000005461403643451100154200ustar00rootroot00000000000000#!/bin/bash export TEST_BIN_NAME=$1 #echo "Building ${TEST_BIN_NAME}" shift 1 export BUILD_COMMAND=$@ #echo "Build command: ${BUILD_COMMAND}" eval ${BUILD_COMMAND} >/dev/null 2>/dev/null if [ $? -eq 0 ]; then echo -ne "#!/bin/bash\nexit 1;" > ${TEST_BIN_NAME} else echo -ne "#!/bin/bash\nexit 0;" > ${TEST_BIN_NAME} fi chmod u+x ${TEST_BIN_NAME} exit 0; date-3.0.1/include/000077500000000000000000000000001403643451100140545ustar00rootroot00000000000000date-3.0.1/include/date/000077500000000000000000000000001403643451100147715ustar00rootroot00000000000000date-3.0.1/include/date/chrono_io.h000066400000000000000000000026731403643451100171310ustar00rootroot00000000000000#ifndef CHRONO_IO_H #define CHRONO_IO_H // The MIT License (MIT) // // Copyright (c) 2016, 2017 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // Our apologies. When the previous paragraph was written, lowercase had not yet // been invented (that would involve another several millennia of evolution). // We did not mean to shout. // This functionality has moved to "date.h" #include "date.h" #endif // CHRONO_IO_H date-3.0.1/include/date/date.h000066400000000000000000007150661403643451100160760ustar00rootroot00000000000000#ifndef DATE_H #define DATE_H // The MIT License (MIT) // // Copyright (c) 2015, 2016, 2017 Howard Hinnant // Copyright (c) 2016 Adrian Colomitchi // Copyright (c) 2017 Florian Dang // Copyright (c) 2017 Paul Thompson // Copyright (c) 2018, 2019 Tomasz Kamiński // Copyright (c) 2019 Jiangang Zhuang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // Our apologies. When the previous paragraph was written, lowercase had not yet // been invented (that would involve another several millennia of evolution). // We did not mean to shout. #ifndef HAS_STRING_VIEW # if __cplusplus >= 201703 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) # define HAS_STRING_VIEW 1 # else # define HAS_STRING_VIEW 0 # endif #endif // HAS_STRING_VIEW #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if HAS_STRING_VIEW # include #endif #include #include #ifdef __GNUC__ # pragma GCC diagnostic push # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 7) # pragma GCC diagnostic ignored "-Wpedantic" # endif # if __GNUC__ < 5 // GCC 4.9 Bug 61489 Wrong warning with -Wmissing-field-initializers # pragma GCC diagnostic ignored "-Wmissing-field-initializers" # endif #endif #ifdef _MSC_VER # pragma warning(push) // warning C4127: conditional expression is constant # pragma warning(disable : 4127) #endif namespace date { //---------------+ // Configuration | //---------------+ #ifndef ONLY_C_LOCALE # define ONLY_C_LOCALE 0 #endif #if defined(_MSC_VER) && (!defined(__clang__) || (_MSC_VER < 1910)) // MSVC # ifndef _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING # define _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING # endif # if _MSC_VER < 1910 // before VS2017 # define CONSTDATA const # define CONSTCD11 # define CONSTCD14 # define NOEXCEPT _NOEXCEPT # else // VS2017 and later # define CONSTDATA constexpr const # define CONSTCD11 constexpr # define CONSTCD14 constexpr # define NOEXCEPT noexcept # endif #elif defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x5150 // Oracle Developer Studio 12.6 and earlier # define CONSTDATA constexpr const # define CONSTCD11 constexpr # define CONSTCD14 # define NOEXCEPT noexcept #elif __cplusplus >= 201402 // C++14 # define CONSTDATA constexpr const # define CONSTCD11 constexpr # define CONSTCD14 constexpr # define NOEXCEPT noexcept #else // C++11 # define CONSTDATA constexpr const # define CONSTCD11 constexpr # define CONSTCD14 # define NOEXCEPT noexcept #endif #ifndef HAS_UNCAUGHT_EXCEPTIONS # if __cplusplus >= 201703 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) # define HAS_UNCAUGHT_EXCEPTIONS 1 # else # define HAS_UNCAUGHT_EXCEPTIONS 0 # endif #endif // HAS_UNCAUGHT_EXCEPTIONS #ifndef HAS_VOID_T # if __cplusplus >= 201703 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) # define HAS_VOID_T 1 # else # define HAS_VOID_T 0 # endif #endif // HAS_VOID_T // Protect from Oracle sun macro #ifdef sun # undef sun #endif // Work around for a NVCC compiler bug which causes it to fail // to compile std::ratio_{multiply,divide} when used directly // in the std::chrono::duration template instantiations below namespace detail { template using ratio_multiply = decltype(std::ratio_multiply{}); template using ratio_divide = decltype(std::ratio_divide{}); } // namespace detail //-----------+ // Interface | //-----------+ // durations using days = std::chrono::duration , std::chrono::hours::period>>; using weeks = std::chrono::duration , days::period>>; using years = std::chrono::duration , days::period>>; using months = std::chrono::duration >>; // time_point template using sys_time = std::chrono::time_point; using sys_days = sys_time; using sys_seconds = sys_time; struct local_t {}; template using local_time = std::chrono::time_point; using local_seconds = local_time; using local_days = local_time; // types struct last_spec { explicit last_spec() = default; }; class day; class month; class year; class weekday; class weekday_indexed; class weekday_last; class month_day; class month_day_last; class month_weekday; class month_weekday_last; class year_month; class year_month_day; class year_month_day_last; class year_month_weekday; class year_month_weekday_last; // date composition operators CONSTCD11 year_month operator/(const year& y, const month& m) NOEXCEPT; CONSTCD11 year_month operator/(const year& y, int m) NOEXCEPT; CONSTCD11 month_day operator/(const day& d, const month& m) NOEXCEPT; CONSTCD11 month_day operator/(const day& d, int m) NOEXCEPT; CONSTCD11 month_day operator/(const month& m, const day& d) NOEXCEPT; CONSTCD11 month_day operator/(const month& m, int d) NOEXCEPT; CONSTCD11 month_day operator/(int m, const day& d) NOEXCEPT; CONSTCD11 month_day_last operator/(const month& m, last_spec) NOEXCEPT; CONSTCD11 month_day_last operator/(int m, last_spec) NOEXCEPT; CONSTCD11 month_day_last operator/(last_spec, const month& m) NOEXCEPT; CONSTCD11 month_day_last operator/(last_spec, int m) NOEXCEPT; CONSTCD11 month_weekday operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT; CONSTCD11 month_weekday operator/(int m, const weekday_indexed& wdi) NOEXCEPT; CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT; CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, int m) NOEXCEPT; CONSTCD11 month_weekday_last operator/(const month& m, const weekday_last& wdl) NOEXCEPT; CONSTCD11 month_weekday_last operator/(int m, const weekday_last& wdl) NOEXCEPT; CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, const month& m) NOEXCEPT; CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, int m) NOEXCEPT; CONSTCD11 year_month_day operator/(const year_month& ym, const day& d) NOEXCEPT; CONSTCD11 year_month_day operator/(const year_month& ym, int d) NOEXCEPT; CONSTCD11 year_month_day operator/(const year& y, const month_day& md) NOEXCEPT; CONSTCD11 year_month_day operator/(int y, const month_day& md) NOEXCEPT; CONSTCD11 year_month_day operator/(const month_day& md, const year& y) NOEXCEPT; CONSTCD11 year_month_day operator/(const month_day& md, int y) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const year_month& ym, last_spec) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const year& y, const month_day_last& mdl) NOEXCEPT; CONSTCD11 year_month_day_last operator/(int y, const month_day_last& mdl) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const month_day_last& mdl, const year& y) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const month_day_last& mdl, int y) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const year& y, const month_weekday& mwd) NOEXCEPT; CONSTCD11 year_month_weekday operator/(int y, const month_weekday& mwd) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const month_weekday& mwd, const year& y) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const month_weekday& mwd, int y) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(int y, const month_weekday_last& mwdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) NOEXCEPT; // Detailed interface // day class day { unsigned char d_; public: day() = default; explicit CONSTCD11 day(unsigned d) NOEXCEPT; CONSTCD14 day& operator++() NOEXCEPT; CONSTCD14 day operator++(int) NOEXCEPT; CONSTCD14 day& operator--() NOEXCEPT; CONSTCD14 day operator--(int) NOEXCEPT; CONSTCD14 day& operator+=(const days& d) NOEXCEPT; CONSTCD14 day& operator-=(const days& d) NOEXCEPT; CONSTCD11 explicit operator unsigned() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator!=(const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator< (const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator> (const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator<=(const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator>=(const day& x, const day& y) NOEXCEPT; CONSTCD11 day operator+(const day& x, const days& y) NOEXCEPT; CONSTCD11 day operator+(const days& x, const day& y) NOEXCEPT; CONSTCD11 day operator-(const day& x, const days& y) NOEXCEPT; CONSTCD11 days operator-(const day& x, const day& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const day& d); // month class month { unsigned char m_; public: month() = default; explicit CONSTCD11 month(unsigned m) NOEXCEPT; CONSTCD14 month& operator++() NOEXCEPT; CONSTCD14 month operator++(int) NOEXCEPT; CONSTCD14 month& operator--() NOEXCEPT; CONSTCD14 month operator--(int) NOEXCEPT; CONSTCD14 month& operator+=(const months& m) NOEXCEPT; CONSTCD14 month& operator-=(const months& m) NOEXCEPT; CONSTCD11 explicit operator unsigned() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator!=(const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator< (const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator> (const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator<=(const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator>=(const month& x, const month& y) NOEXCEPT; CONSTCD14 month operator+(const month& x, const months& y) NOEXCEPT; CONSTCD14 month operator+(const months& x, const month& y) NOEXCEPT; CONSTCD14 month operator-(const month& x, const months& y) NOEXCEPT; CONSTCD14 months operator-(const month& x, const month& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month& m); // year class year { short y_; public: year() = default; explicit CONSTCD11 year(int y) NOEXCEPT; CONSTCD14 year& operator++() NOEXCEPT; CONSTCD14 year operator++(int) NOEXCEPT; CONSTCD14 year& operator--() NOEXCEPT; CONSTCD14 year operator--(int) NOEXCEPT; CONSTCD14 year& operator+=(const years& y) NOEXCEPT; CONSTCD14 year& operator-=(const years& y) NOEXCEPT; CONSTCD11 year operator-() const NOEXCEPT; CONSTCD11 year operator+() const NOEXCEPT; CONSTCD11 bool is_leap() const NOEXCEPT; CONSTCD11 explicit operator int() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; static CONSTCD11 year min() NOEXCEPT { return year{-32767}; } static CONSTCD11 year max() NOEXCEPT { return year{32767}; } }; CONSTCD11 bool operator==(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator!=(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator< (const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator> (const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator<=(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator>=(const year& x, const year& y) NOEXCEPT; CONSTCD11 year operator+(const year& x, const years& y) NOEXCEPT; CONSTCD11 year operator+(const years& x, const year& y) NOEXCEPT; CONSTCD11 year operator-(const year& x, const years& y) NOEXCEPT; CONSTCD11 years operator-(const year& x, const year& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year& y); // weekday class weekday { unsigned char wd_; public: weekday() = default; explicit CONSTCD11 weekday(unsigned wd) NOEXCEPT; CONSTCD14 weekday(const sys_days& dp) NOEXCEPT; CONSTCD14 explicit weekday(const local_days& dp) NOEXCEPT; CONSTCD14 weekday& operator++() NOEXCEPT; CONSTCD14 weekday operator++(int) NOEXCEPT; CONSTCD14 weekday& operator--() NOEXCEPT; CONSTCD14 weekday operator--(int) NOEXCEPT; CONSTCD14 weekday& operator+=(const days& d) NOEXCEPT; CONSTCD14 weekday& operator-=(const days& d) NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; CONSTCD11 unsigned c_encoding() const NOEXCEPT; CONSTCD11 unsigned iso_encoding() const NOEXCEPT; CONSTCD11 weekday_indexed operator[](unsigned index) const NOEXCEPT; CONSTCD11 weekday_last operator[](last_spec) const NOEXCEPT; private: static CONSTCD14 unsigned char weekday_from_days(int z) NOEXCEPT; friend CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT; friend CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; friend CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT; template friend std::basic_ostream& operator<<(std::basic_ostream& os, const weekday& wd); friend class weekday_indexed; }; CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday& x, const weekday& y) NOEXCEPT; CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT; CONSTCD14 weekday operator+(const days& x, const weekday& y) NOEXCEPT; CONSTCD14 weekday operator-(const weekday& x, const days& y) NOEXCEPT; CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday& wd); // weekday_indexed class weekday_indexed { unsigned char wd_ : 4; unsigned char index_ : 4; public: weekday_indexed() = default; CONSTCD11 weekday_indexed(const date::weekday& wd, unsigned index) NOEXCEPT; CONSTCD11 date::weekday weekday() const NOEXCEPT; CONSTCD11 unsigned index() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_indexed& wdi); // weekday_last class weekday_last { date::weekday wd_; public: explicit CONSTCD11 weekday_last(const date::weekday& wd) NOEXCEPT; CONSTCD11 date::weekday weekday() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_last& wdl); namespace detail { struct unspecified_month_disambiguator {}; } // namespace detail // year_month class year_month { date::year y_; date::month m_; public: year_month() = default; CONSTCD11 year_month(const date::year& y, const date::month& m) NOEXCEPT; CONSTCD11 date::year year() const NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; template CONSTCD14 year_month& operator+=(const months& dm) NOEXCEPT; template CONSTCD14 year_month& operator-=(const months& dm) NOEXCEPT; CONSTCD14 year_month& operator+=(const years& dy) NOEXCEPT; CONSTCD14 year_month& operator-=(const years& dy) NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator< (const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator> (const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_month& x, const year_month& y) NOEXCEPT; template CONSTCD14 year_month operator+(const year_month& ym, const months& dm) NOEXCEPT; template CONSTCD14 year_month operator+(const months& dm, const year_month& ym) NOEXCEPT; template CONSTCD14 year_month operator-(const year_month& ym, const months& dm) NOEXCEPT; CONSTCD11 months operator-(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 year_month operator+(const year_month& ym, const years& dy) NOEXCEPT; CONSTCD11 year_month operator+(const years& dy, const year_month& ym) NOEXCEPT; CONSTCD11 year_month operator-(const year_month& ym, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month& ym); // month_day class month_day { date::month m_; date::day d_; public: month_day() = default; CONSTCD11 month_day(const date::month& m, const date::day& d) NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; CONSTCD11 date::day day() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator< (const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator> (const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator<=(const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator>=(const month_day& x, const month_day& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_day& md); // month_day_last class month_day_last { date::month m_; public: CONSTCD11 explicit month_day_last(const date::month& m) NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator< (const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator> (const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_day_last& mdl); // month_weekday class month_weekday { date::month m_; date::weekday_indexed wdi_; public: CONSTCD11 month_weekday(const date::month& m, const date::weekday_indexed& wdi) NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday& mwd); // month_weekday_last class month_weekday_last { date::month m_; date::weekday_last wdl_; public: CONSTCD11 month_weekday_last(const date::month& m, const date::weekday_last& wd) NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday_last& mwdl); // class year_month_day class year_month_day { date::year y_; date::month m_; date::day d_; public: year_month_day() = default; CONSTCD11 year_month_day(const date::year& y, const date::month& m, const date::day& d) NOEXCEPT; CONSTCD14 year_month_day(const year_month_day_last& ymdl) NOEXCEPT; CONSTCD14 year_month_day(sys_days dp) NOEXCEPT; CONSTCD14 explicit year_month_day(local_days dp) NOEXCEPT; template CONSTCD14 year_month_day& operator+=(const months& m) NOEXCEPT; template CONSTCD14 year_month_day& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_day& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_day& operator-=(const years& y) NOEXCEPT; CONSTCD11 date::year year() const NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; CONSTCD11 date::day day() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; private: static CONSTCD14 year_month_day from_days(days dp) NOEXCEPT; CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator< (const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator> (const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT; template CONSTCD14 year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT; template CONSTCD14 year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT; template CONSTCD14 year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT; CONSTCD11 year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT; CONSTCD11 year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT; CONSTCD11 year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day& ymd); // year_month_day_last class year_month_day_last { date::year y_; date::month_day_last mdl_; public: CONSTCD11 year_month_day_last(const date::year& y, const date::month_day_last& mdl) NOEXCEPT; template CONSTCD14 year_month_day_last& operator+=(const months& m) NOEXCEPT; template CONSTCD14 year_month_day_last& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_day_last& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_day_last& operator-=(const years& y) NOEXCEPT; CONSTCD11 date::year year() const NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; CONSTCD11 date::month_day_last month_day_last() const NOEXCEPT; CONSTCD14 date::day day() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator< (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator> (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; template CONSTCD14 year_month_day_last operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; template CONSTCD14 year_month_day_last operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT; CONSTCD11 year_month_day_last operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; CONSTCD11 year_month_day_last operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT; template CONSTCD14 year_month_day_last operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; CONSTCD11 year_month_day_last operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day_last& ymdl); // year_month_weekday class year_month_weekday { date::year y_; date::month m_; date::weekday_indexed wdi_; public: year_month_weekday() = default; CONSTCD11 year_month_weekday(const date::year& y, const date::month& m, const date::weekday_indexed& wdi) NOEXCEPT; CONSTCD14 year_month_weekday(const sys_days& dp) NOEXCEPT; CONSTCD14 explicit year_month_weekday(const local_days& dp) NOEXCEPT; template CONSTCD14 year_month_weekday& operator+=(const months& m) NOEXCEPT; template CONSTCD14 year_month_weekday& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_weekday& operator-=(const years& y) NOEXCEPT; CONSTCD11 date::year year() const NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; CONSTCD11 date::weekday weekday() const NOEXCEPT; CONSTCD11 unsigned index() const NOEXCEPT; CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; private: static CONSTCD14 year_month_weekday from_days(days dp) NOEXCEPT; CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; template CONSTCD14 year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; template CONSTCD14 year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT; CONSTCD11 year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; CONSTCD11 year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT; template CONSTCD14 year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; CONSTCD11 year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi); // year_month_weekday_last class year_month_weekday_last { date::year y_; date::month m_; date::weekday_last wdl_; public: CONSTCD11 year_month_weekday_last(const date::year& y, const date::month& m, const date::weekday_last& wdl) NOEXCEPT; template CONSTCD14 year_month_weekday_last& operator+=(const months& m) NOEXCEPT; template CONSTCD14 year_month_weekday_last& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator-=(const years& y) NOEXCEPT; CONSTCD11 date::year year() const NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; CONSTCD11 date::weekday weekday() const NOEXCEPT; CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; private: CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; template CONSTCD14 year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; template CONSTCD14 year_month_weekday_last operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; CONSTCD11 year_month_weekday_last operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT; template CONSTCD14 year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; CONSTCD11 year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl); #if !defined(_MSC_VER) || (_MSC_VER >= 1900) inline namespace literals { CONSTCD11 date::day operator "" _d(unsigned long long d) NOEXCEPT; CONSTCD11 date::year operator "" _y(unsigned long long y) NOEXCEPT; } // inline namespace literals #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) // CONSTDATA date::month January{1}; // CONSTDATA date::month February{2}; // CONSTDATA date::month March{3}; // CONSTDATA date::month April{4}; // CONSTDATA date::month May{5}; // CONSTDATA date::month June{6}; // CONSTDATA date::month July{7}; // CONSTDATA date::month August{8}; // CONSTDATA date::month September{9}; // CONSTDATA date::month October{10}; // CONSTDATA date::month November{11}; // CONSTDATA date::month December{12}; // // CONSTDATA date::weekday Sunday{0u}; // CONSTDATA date::weekday Monday{1u}; // CONSTDATA date::weekday Tuesday{2u}; // CONSTDATA date::weekday Wednesday{3u}; // CONSTDATA date::weekday Thursday{4u}; // CONSTDATA date::weekday Friday{5u}; // CONSTDATA date::weekday Saturday{6u}; #if HAS_VOID_T template > struct is_clock : std::false_type {}; template struct is_clock> : std::true_type {}; template inline constexpr bool is_clock_v = is_clock::value; #endif // HAS_VOID_T //----------------+ // Implementation | //----------------+ // utilities namespace detail { template> class save_istream { protected: std::basic_ios& is_; CharT fill_; std::ios::fmtflags flags_; std::streamsize precision_; std::streamsize width_; std::basic_ostream* tie_; std::locale loc_; public: ~save_istream() { is_.fill(fill_); is_.flags(flags_); is_.precision(precision_); is_.width(width_); is_.imbue(loc_); is_.tie(tie_); } save_istream(const save_istream&) = delete; save_istream& operator=(const save_istream&) = delete; explicit save_istream(std::basic_ios& is) : is_(is) , fill_(is.fill()) , flags_(is.flags()) , precision_(is.precision()) , width_(is.width(0)) , tie_(is.tie(nullptr)) , loc_(is.getloc()) { if (tie_ != nullptr) tie_->flush(); } }; template> class save_ostream : private save_istream { public: ~save_ostream() { if ((this->flags_ & std::ios::unitbuf) && #if HAS_UNCAUGHT_EXCEPTIONS std::uncaught_exceptions() == 0 && #else !std::uncaught_exception() && #endif this->is_.good()) this->is_.rdbuf()->pubsync(); } save_ostream(const save_ostream&) = delete; save_ostream& operator=(const save_ostream&) = delete; explicit save_ostream(std::basic_ios& os) : save_istream(os) { } }; template struct choose_trunc_type { static const int digits = std::numeric_limits::digits; using type = typename std::conditional < digits < 32, std::int32_t, typename std::conditional < digits < 64, std::int64_t, #ifdef __SIZEOF_INT128__ __int128 #else std::int64_t #endif >::type >::type; }; template CONSTCD11 inline typename std::enable_if < !std::chrono::treat_as_floating_point::value, T >::type trunc(T t) NOEXCEPT { return t; } template CONSTCD14 inline typename std::enable_if < std::chrono::treat_as_floating_point::value, T >::type trunc(T t) NOEXCEPT { using std::numeric_limits; using I = typename choose_trunc_type::type; CONSTDATA auto digits = numeric_limits::digits; static_assert(digits < numeric_limits::digits, ""); CONSTDATA auto max = I{1} << (digits-1); CONSTDATA auto min = -max; const auto negative = t < T{0}; if (min <= t && t <= max && t != 0 && t == t) { t = static_cast(static_cast(t)); if (t == 0 && negative) t = -t; } return t; } template struct static_gcd { static const std::intmax_t value = static_gcd::value; }; template struct static_gcd { static const std::intmax_t value = Xp; }; template <> struct static_gcd<0, 0> { static const std::intmax_t value = 1; }; template struct no_overflow { private: static const std::intmax_t gcd_n1_n2 = static_gcd::value; static const std::intmax_t gcd_d1_d2 = static_gcd::value; static const std::intmax_t n1 = R1::num / gcd_n1_n2; static const std::intmax_t d1 = R1::den / gcd_d1_d2; static const std::intmax_t n2 = R2::num / gcd_n1_n2; static const std::intmax_t d2 = R2::den / gcd_d1_d2; #ifdef __cpp_constexpr static const std::intmax_t max = std::numeric_limits::max(); #else static const std::intmax_t max = LLONG_MAX; #endif template struct mul // overflow == false { static const std::intmax_t value = Xp * Yp; }; template struct mul { static const std::intmax_t value = 1; }; public: static const bool value = (n1 <= max / d2) && (n2 <= max / d1); typedef std::ratio::value, mul::value> type; }; } // detail // trunc towards zero template CONSTCD11 inline typename std::enable_if < detail::no_overflow::value, To >::type trunc(const std::chrono::duration& d) { return To{detail::trunc(std::chrono::duration_cast(d).count())}; } template CONSTCD11 inline typename std::enable_if < !detail::no_overflow::value, To >::type trunc(const std::chrono::duration& d) { using std::chrono::duration_cast; using std::chrono::duration; using rep = typename std::common_type::type; return To{detail::trunc(duration_cast(duration_cast>(d)).count())}; } #ifndef HAS_CHRONO_ROUNDING # if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023918 || (_MSC_FULL_VER >= 190000000 && defined (__clang__))) # define HAS_CHRONO_ROUNDING 1 # elif defined(__cpp_lib_chrono) && __cplusplus > 201402 && __cpp_lib_chrono >= 201510 # define HAS_CHRONO_ROUNDING 1 # elif defined(_LIBCPP_VERSION) && __cplusplus > 201402 && _LIBCPP_VERSION >= 3800 # define HAS_CHRONO_ROUNDING 1 # else # define HAS_CHRONO_ROUNDING 0 # endif #endif // HAS_CHRONO_ROUNDING #if HAS_CHRONO_ROUNDING == 0 // round down template CONSTCD14 inline typename std::enable_if < detail::no_overflow::value, To >::type floor(const std::chrono::duration& d) { auto t = trunc(d); if (t > d) return t - To{1}; return t; } template CONSTCD14 inline typename std::enable_if < !detail::no_overflow::value, To >::type floor(const std::chrono::duration& d) { using rep = typename std::common_type::type; return floor(floor>(d)); } // round to nearest, to even on tie template CONSTCD14 inline To round(const std::chrono::duration& d) { auto t0 = floor(d); auto t1 = t0 + To{1}; if (t1 == To{0} && t0 < To{0}) t1 = -t1; auto diff0 = d - t0; auto diff1 = t1 - d; if (diff0 == diff1) { if (t0 - trunc(t0/2)*2 == To{0}) return t0; return t1; } if (diff0 < diff1) return t0; return t1; } // round up template CONSTCD14 inline To ceil(const std::chrono::duration& d) { auto t = trunc(d); if (t < d) return t + To{1}; return t; } template ::is_signed >::type> CONSTCD11 std::chrono::duration abs(std::chrono::duration d) { return d >= d.zero() ? d : -d; } // round down template CONSTCD11 inline std::chrono::time_point floor(const std::chrono::time_point& tp) { using std::chrono::time_point; return time_point{date::floor(tp.time_since_epoch())}; } // round to nearest, to even on tie template CONSTCD11 inline std::chrono::time_point round(const std::chrono::time_point& tp) { using std::chrono::time_point; return time_point{round(tp.time_since_epoch())}; } // round up template CONSTCD11 inline std::chrono::time_point ceil(const std::chrono::time_point& tp) { using std::chrono::time_point; return time_point{ceil(tp.time_since_epoch())}; } #else // HAS_CHRONO_ROUNDING == 1 using std::chrono::floor; using std::chrono::ceil; using std::chrono::round; using std::chrono::abs; #endif // HAS_CHRONO_ROUNDING namespace detail { template CONSTCD14 inline typename std::enable_if < !std::chrono::treat_as_floating_point::value, To >::type round_i(const std::chrono::duration& d) { return round(d); } template CONSTCD14 inline typename std::enable_if < std::chrono::treat_as_floating_point::value, To >::type round_i(const std::chrono::duration& d) { return d; } template CONSTCD11 inline std::chrono::time_point round_i(const std::chrono::time_point& tp) { using std::chrono::time_point; return time_point{round_i(tp.time_since_epoch())}; } } // detail // trunc towards zero template CONSTCD11 inline std::chrono::time_point trunc(const std::chrono::time_point& tp) { using std::chrono::time_point; return time_point{trunc(tp.time_since_epoch())}; } // day CONSTCD11 inline day::day(unsigned d) NOEXCEPT : d_(static_cast(d)) {} CONSTCD14 inline day& day::operator++() NOEXCEPT {++d_; return *this;} CONSTCD14 inline day day::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline day& day::operator--() NOEXCEPT {--d_; return *this;} CONSTCD14 inline day day::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline day& day::operator+=(const days& d) NOEXCEPT {*this = *this + d; return *this;} CONSTCD14 inline day& day::operator-=(const days& d) NOEXCEPT {*this = *this - d; return *this;} CONSTCD11 inline day::operator unsigned() const NOEXCEPT {return d_;} CONSTCD11 inline bool day::ok() const NOEXCEPT {return 1 <= d_ && d_ <= 31;} CONSTCD11 inline bool operator==(const day& x, const day& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const day& x, const day& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const day& x, const day& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const day& x, const day& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const day& x, const day& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const day& x, const day& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline days operator-(const day& x, const day& y) NOEXCEPT { return days{static_cast(static_cast(x) - static_cast(y))}; } CONSTCD11 inline day operator+(const day& x, const days& y) NOEXCEPT { return day{static_cast(x) + static_cast(y.count())}; } CONSTCD11 inline day operator+(const days& x, const day& y) NOEXCEPT { return y + x; } CONSTCD11 inline day operator-(const day& x, const days& y) NOEXCEPT { return x + -y; } namespace detail { template std::basic_ostream& low_level_fmt(std::basic_ostream& os, const day& d) { detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.width(2); os << static_cast(d); return os; } } // namespace detail template inline std::basic_ostream& operator<<(std::basic_ostream& os, const day& d) { detail::low_level_fmt(os, d); if (!d.ok()) os << " is not a valid day"; return os; } // month CONSTCD11 inline month::month(unsigned m) NOEXCEPT : m_(static_cast(m)) {} CONSTCD14 inline month& month::operator++() NOEXCEPT {*this += months{1}; return *this;} CONSTCD14 inline month month::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline month& month::operator--() NOEXCEPT {*this -= months{1}; return *this;} CONSTCD14 inline month month::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline month& month::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline month& month::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD11 inline month::operator unsigned() const NOEXCEPT {return m_;} CONSTCD11 inline bool month::ok() const NOEXCEPT {return 1 <= m_ && m_ <= 12;} CONSTCD11 inline bool operator==(const month& x, const month& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const month& x, const month& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const month& x, const month& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const month& x, const month& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const month& x, const month& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const month& x, const month& y) NOEXCEPT { return !(x < y); } CONSTCD14 inline months operator-(const month& x, const month& y) NOEXCEPT { auto const d = static_cast(x) - static_cast(y); return months(d <= 11 ? d : d + 12); } CONSTCD14 inline month operator+(const month& x, const months& y) NOEXCEPT { auto const mu = static_cast(static_cast(x)) + y.count() - 1; auto const yr = (mu >= 0 ? mu : mu-11) / 12; return month{static_cast(mu - yr * 12 + 1)}; } CONSTCD14 inline month operator+(const months& x, const month& y) NOEXCEPT { return y + x; } CONSTCD14 inline month operator-(const month& x, const months& y) NOEXCEPT { return x + -y; } namespace detail { template std::basic_ostream& low_level_fmt(std::basic_ostream& os, const month& m) { if (m.ok()) { CharT fmt[] = {'%', 'b', 0}; os << format(os.getloc(), fmt, m); } else os << static_cast(m); return os; } } // namespace detail template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month& m) { detail::low_level_fmt(os, m); if (!m.ok()) os << " is not a valid month"; return os; } // year CONSTCD11 inline year::year(int y) NOEXCEPT : y_(static_cast(y)) {} CONSTCD14 inline year& year::operator++() NOEXCEPT {++y_; return *this;} CONSTCD14 inline year year::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline year& year::operator--() NOEXCEPT {--y_; return *this;} CONSTCD14 inline year year::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline year& year::operator+=(const years& y) NOEXCEPT {*this = *this + y; return *this;} CONSTCD14 inline year& year::operator-=(const years& y) NOEXCEPT {*this = *this - y; return *this;} CONSTCD11 inline year year::operator-() const NOEXCEPT {return year{-y_};} CONSTCD11 inline year year::operator+() const NOEXCEPT {return *this;} CONSTCD11 inline bool year::is_leap() const NOEXCEPT { return y_ % 4 == 0 && (y_ % 100 != 0 || y_ % 400 == 0); } CONSTCD11 inline year::operator int() const NOEXCEPT {return y_;} CONSTCD11 inline bool year::ok() const NOEXCEPT { return y_ != std::numeric_limits::min(); } CONSTCD11 inline bool operator==(const year& x, const year& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const year& x, const year& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year& x, const year& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const year& x, const year& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year& x, const year& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year& x, const year& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline years operator-(const year& x, const year& y) NOEXCEPT { return years{static_cast(x) - static_cast(y)}; } CONSTCD11 inline year operator+(const year& x, const years& y) NOEXCEPT { return year{static_cast(x) + y.count()}; } CONSTCD11 inline year operator+(const years& x, const year& y) NOEXCEPT { return y + x; } CONSTCD11 inline year operator-(const year& x, const years& y) NOEXCEPT { return year{static_cast(x) - y.count()}; } namespace detail { template std::basic_ostream& low_level_fmt(std::basic_ostream& os, const year& y) { detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::internal); os.width(4 + (y < year{0})); os.imbue(std::locale::classic()); os << static_cast(y); return os; } } // namespace detail template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year& y) { detail::low_level_fmt(os, y); if (!y.ok()) os << " is not a valid year"; return os; } // weekday CONSTCD14 inline unsigned char weekday::weekday_from_days(int z) NOEXCEPT { auto u = static_cast(z); return static_cast(z >= -4 ? (u+4) % 7 : u % 7); } CONSTCD11 inline weekday::weekday(unsigned wd) NOEXCEPT : wd_(static_cast(wd != 7 ? wd : 0)) {} CONSTCD14 inline weekday::weekday(const sys_days& dp) NOEXCEPT : wd_(weekday_from_days(dp.time_since_epoch().count())) {} CONSTCD14 inline weekday::weekday(const local_days& dp) NOEXCEPT : wd_(weekday_from_days(dp.time_since_epoch().count())) {} CONSTCD14 inline weekday& weekday::operator++() NOEXCEPT {*this += days{1}; return *this;} CONSTCD14 inline weekday weekday::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline weekday& weekday::operator--() NOEXCEPT {*this -= days{1}; return *this;} CONSTCD14 inline weekday weekday::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline weekday& weekday::operator+=(const days& d) NOEXCEPT { *this = *this + d; return *this; } CONSTCD14 inline weekday& weekday::operator-=(const days& d) NOEXCEPT { *this = *this - d; return *this; } CONSTCD11 inline bool weekday::ok() const NOEXCEPT {return wd_ <= 6;} CONSTCD11 inline unsigned weekday::c_encoding() const NOEXCEPT { return unsigned{wd_}; } CONSTCD11 inline unsigned weekday::iso_encoding() const NOEXCEPT { return unsigned{((wd_ == 0u) ? 7u : wd_)}; } CONSTCD11 inline bool operator==(const weekday& x, const weekday& y) NOEXCEPT { return x.wd_ == y.wd_; } CONSTCD11 inline bool operator!=(const weekday& x, const weekday& y) NOEXCEPT { return !(x == y); } CONSTCD14 inline days operator-(const weekday& x, const weekday& y) NOEXCEPT { auto const wdu = x.wd_ - y.wd_; auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7; return days{wdu - wk * 7}; } CONSTCD14 inline weekday operator+(const weekday& x, const days& y) NOEXCEPT { auto const wdu = static_cast(static_cast(x.wd_)) + y.count(); auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7; return weekday{static_cast(wdu - wk * 7)}; } CONSTCD14 inline weekday operator+(const days& x, const weekday& y) NOEXCEPT { return y + x; } CONSTCD14 inline weekday operator-(const weekday& x, const days& y) NOEXCEPT { return x + -y; } namespace detail { template std::basic_ostream& low_level_fmt(std::basic_ostream& os, const weekday& wd) { if (wd.ok()) { CharT fmt[] = {'%', 'a', 0}; os << format(fmt, wd); } else os << wd.c_encoding(); return os; } } // namespace detail template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday& wd) { detail::low_level_fmt(os, wd); if (!wd.ok()) os << " is not a valid weekday"; return os; } #if !defined(_MSC_VER) || (_MSC_VER >= 1900) inline namespace literals { CONSTCD11 inline date::day operator "" _d(unsigned long long d) NOEXCEPT { return date::day{static_cast(d)}; } CONSTCD11 inline date::year operator "" _y(unsigned long long y) NOEXCEPT { return date::year(static_cast(y)); } #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) CONSTDATA date::last_spec last{}; CONSTDATA date::month jan{1}; CONSTDATA date::month feb{2}; CONSTDATA date::month mar{3}; CONSTDATA date::month apr{4}; CONSTDATA date::month may{5}; CONSTDATA date::month jun{6}; CONSTDATA date::month jul{7}; CONSTDATA date::month aug{8}; CONSTDATA date::month sep{9}; CONSTDATA date::month oct{10}; CONSTDATA date::month nov{11}; CONSTDATA date::month dec{12}; CONSTDATA date::weekday sun{0u}; CONSTDATA date::weekday mon{1u}; CONSTDATA date::weekday tue{2u}; CONSTDATA date::weekday wed{3u}; CONSTDATA date::weekday thu{4u}; CONSTDATA date::weekday fri{5u}; CONSTDATA date::weekday sat{6u}; #if !defined(_MSC_VER) || (_MSC_VER >= 1900) } // inline namespace literals #endif CONSTDATA date::month January{1}; CONSTDATA date::month February{2}; CONSTDATA date::month March{3}; CONSTDATA date::month April{4}; CONSTDATA date::month May{5}; CONSTDATA date::month June{6}; CONSTDATA date::month July{7}; CONSTDATA date::month August{8}; CONSTDATA date::month September{9}; CONSTDATA date::month October{10}; CONSTDATA date::month November{11}; CONSTDATA date::month December{12}; CONSTDATA date::weekday Monday{1}; CONSTDATA date::weekday Tuesday{2}; CONSTDATA date::weekday Wednesday{3}; CONSTDATA date::weekday Thursday{4}; CONSTDATA date::weekday Friday{5}; CONSTDATA date::weekday Saturday{6}; CONSTDATA date::weekday Sunday{7}; // weekday_indexed CONSTCD11 inline weekday weekday_indexed::weekday() const NOEXCEPT { return date::weekday{static_cast(wd_)}; } CONSTCD11 inline unsigned weekday_indexed::index() const NOEXCEPT {return index_;} CONSTCD11 inline bool weekday_indexed::ok() const NOEXCEPT { return weekday().ok() && 1 <= index_ && index_ <= 5; } #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wconversion" #endif // __GNUC__ CONSTCD11 inline weekday_indexed::weekday_indexed(const date::weekday& wd, unsigned index) NOEXCEPT : wd_(static_cast(static_cast(wd.wd_))) , index_(static_cast(index)) {} #ifdef __GNUC__ # pragma GCC diagnostic pop #endif // __GNUC__ namespace detail { template std::basic_ostream& low_level_fmt(std::basic_ostream& os, const weekday_indexed& wdi) { return low_level_fmt(os, wdi.weekday()) << '[' << wdi.index() << ']'; } } // namespace detail template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_indexed& wdi) { detail::low_level_fmt(os, wdi); if (!wdi.ok()) os << " is not a valid weekday_indexed"; return os; } CONSTCD11 inline weekday_indexed weekday::operator[](unsigned index) const NOEXCEPT { return {*this, index}; } CONSTCD11 inline bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT { return x.weekday() == y.weekday() && x.index() == y.index(); } CONSTCD11 inline bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT { return !(x == y); } // weekday_last CONSTCD11 inline date::weekday weekday_last::weekday() const NOEXCEPT {return wd_;} CONSTCD11 inline bool weekday_last::ok() const NOEXCEPT {return wd_.ok();} CONSTCD11 inline weekday_last::weekday_last(const date::weekday& wd) NOEXCEPT : wd_(wd) {} CONSTCD11 inline bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT { return x.weekday() == y.weekday(); } CONSTCD11 inline bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT { return !(x == y); } namespace detail { template std::basic_ostream& low_level_fmt(std::basic_ostream& os, const weekday_last& wdl) { return low_level_fmt(os, wdl.weekday()) << "[last]"; } } // namespace detail template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_last& wdl) { detail::low_level_fmt(os, wdl); if (!wdl.ok()) os << " is not a valid weekday_last"; return os; } CONSTCD11 inline weekday_last weekday::operator[](last_spec) const NOEXCEPT { return weekday_last{*this}; } // year_month CONSTCD11 inline year_month::year_month(const date::year& y, const date::month& m) NOEXCEPT : y_(y) , m_(m) {} CONSTCD11 inline year year_month::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month::month() const NOEXCEPT {return m_;} CONSTCD11 inline bool year_month::ok() const NOEXCEPT {return y_.ok() && m_.ok();} template CONSTCD14 inline year_month& year_month::operator+=(const months& dm) NOEXCEPT { *this = *this + dm; return *this; } template CONSTCD14 inline year_month& year_month::operator-=(const months& dm) NOEXCEPT { *this = *this - dm; return *this; } CONSTCD14 inline year_month& year_month::operator+=(const years& dy) NOEXCEPT { *this = *this + dy; return *this; } CONSTCD14 inline year_month& year_month::operator-=(const years& dy) NOEXCEPT { *this = *this - dy; return *this; } CONSTCD11 inline bool operator==(const year_month& x, const year_month& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month(); } CONSTCD11 inline bool operator!=(const year_month& x, const year_month& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_month& x, const year_month& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.month() < y.month())); } CONSTCD11 inline bool operator>(const year_month& x, const year_month& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_month& x, const year_month& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_month& x, const year_month& y) NOEXCEPT { return !(x < y); } template CONSTCD14 inline year_month operator+(const year_month& ym, const months& dm) NOEXCEPT { auto dmi = static_cast(static_cast(ym.month())) - 1 + dm.count(); auto dy = (dmi >= 0 ? dmi : dmi-11) / 12; dmi = dmi - dy * 12 + 1; return (ym.year() + years(dy)) / month(static_cast(dmi)); } template CONSTCD14 inline year_month operator+(const months& dm, const year_month& ym) NOEXCEPT { return ym + dm; } template CONSTCD14 inline year_month operator-(const year_month& ym, const months& dm) NOEXCEPT { return ym + -dm; } CONSTCD11 inline months operator-(const year_month& x, const year_month& y) NOEXCEPT { return (x.year() - y.year()) + months(static_cast(x.month()) - static_cast(y.month())); } CONSTCD11 inline year_month operator+(const year_month& ym, const years& dy) NOEXCEPT { return (ym.year() + dy) / ym.month(); } CONSTCD11 inline year_month operator+(const years& dy, const year_month& ym) NOEXCEPT { return ym + dy; } CONSTCD11 inline year_month operator-(const year_month& ym, const years& dy) NOEXCEPT { return ym + -dy; } namespace detail { template std::basic_ostream& low_level_fmt(std::basic_ostream& os, const year_month& ym) { low_level_fmt(os, ym.year()) << '/'; return low_level_fmt(os, ym.month()); } } // namespace detail template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month& ym) { detail::low_level_fmt(os, ym); if (!ym.ok()) os << " is not a valid year_month"; return os; } // month_day CONSTCD11 inline month_day::month_day(const date::month& m, const date::day& d) NOEXCEPT : m_(m) , d_(d) {} CONSTCD11 inline date::month month_day::month() const NOEXCEPT {return m_;} CONSTCD11 inline date::day month_day::day() const NOEXCEPT {return d_;} CONSTCD14 inline bool month_day::ok() const NOEXCEPT { CONSTDATA date::day d[] = { date::day(31), date::day(29), date::day(31), date::day(30), date::day(31), date::day(30), date::day(31), date::day(31), date::day(30), date::day(31), date::day(30), date::day(31) }; return m_.ok() && date::day{1} <= d_ && d_ <= d[static_cast(m_)-1]; } CONSTCD11 inline bool operator==(const month_day& x, const month_day& y) NOEXCEPT { return x.month() == y.month() && x.day() == y.day(); } CONSTCD11 inline bool operator!=(const month_day& x, const month_day& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const month_day& x, const month_day& y) NOEXCEPT { return x.month() < y.month() ? true : (x.month() > y.month() ? false : (x.day() < y.day())); } CONSTCD11 inline bool operator>(const month_day& x, const month_day& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const month_day& x, const month_day& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const month_day& x, const month_day& y) NOEXCEPT { return !(x < y); } namespace detail { template std::basic_ostream& low_level_fmt(std::basic_ostream& os, const month_day& md) { low_level_fmt(os, md.month()) << '/'; return low_level_fmt(os, md.day()); } } // namespace detail template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_day& md) { detail::low_level_fmt(os, md); if (!md.ok()) os << " is not a valid month_day"; return os; } // month_day_last CONSTCD11 inline month month_day_last::month() const NOEXCEPT {return m_;} CONSTCD11 inline bool month_day_last::ok() const NOEXCEPT {return m_.ok();} CONSTCD11 inline month_day_last::month_day_last(const date::month& m) NOEXCEPT : m_(m) {} CONSTCD11 inline bool operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT { return x.month() == y.month(); } CONSTCD11 inline bool operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const month_day_last& x, const month_day_last& y) NOEXCEPT { return x.month() < y.month(); } CONSTCD11 inline bool operator>(const month_day_last& x, const month_day_last& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT { return !(x < y); } namespace detail { template std::basic_ostream& low_level_fmt(std::basic_ostream& os, const month_day_last& mdl) { return low_level_fmt(os, mdl.month()) << "/last"; } } // namespace detail template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_day_last& mdl) { detail::low_level_fmt(os, mdl); if (!mdl.ok()) os << " is not a valid month_day_last"; return os; } // month_weekday CONSTCD11 inline month_weekday::month_weekday(const date::month& m, const date::weekday_indexed& wdi) NOEXCEPT : m_(m) , wdi_(wdi) {} CONSTCD11 inline month month_weekday::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday_indexed month_weekday::weekday_indexed() const NOEXCEPT { return wdi_; } CONSTCD11 inline bool month_weekday::ok() const NOEXCEPT { return m_.ok() && wdi_.ok(); } CONSTCD11 inline bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT { return x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed(); } CONSTCD11 inline bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT { return !(x == y); } namespace detail { template std::basic_ostream& low_level_fmt(std::basic_ostream& os, const month_weekday& mwd) { low_level_fmt(os, mwd.month()) << '/'; return low_level_fmt(os, mwd.weekday_indexed()); } } // namespace detail template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday& mwd) { detail::low_level_fmt(os, mwd); if (!mwd.ok()) os << " is not a valid month_weekday"; return os; } // month_weekday_last CONSTCD11 inline month_weekday_last::month_weekday_last(const date::month& m, const date::weekday_last& wdl) NOEXCEPT : m_(m) , wdl_(wdl) {} CONSTCD11 inline month month_weekday_last::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday_last month_weekday_last::weekday_last() const NOEXCEPT { return wdl_; } CONSTCD11 inline bool month_weekday_last::ok() const NOEXCEPT { return m_.ok() && wdl_.ok(); } CONSTCD11 inline bool operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT { return x.month() == y.month() && x.weekday_last() == y.weekday_last(); } CONSTCD11 inline bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT { return !(x == y); } namespace detail { template std::basic_ostream& low_level_fmt(std::basic_ostream& os, const month_weekday_last& mwdl) { low_level_fmt(os, mwdl.month()) << '/'; return low_level_fmt(os, mwdl.weekday_last()); } } // namespace detail template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday_last& mwdl) { detail::low_level_fmt(os, mwdl); if (!mwdl.ok()) os << " is not a valid month_weekday_last"; return os; } // year_month_day_last CONSTCD11 inline year_month_day_last::year_month_day_last(const date::year& y, const date::month_day_last& mdl) NOEXCEPT : y_(y) , mdl_(mdl) {} template CONSTCD14 inline year_month_day_last& year_month_day_last::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } template CONSTCD14 inline year_month_day_last& year_month_day_last::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_day_last& year_month_day_last::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_day_last& year_month_day_last::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_month_day_last::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_day_last::month() const NOEXCEPT {return mdl_.month();} CONSTCD11 inline month_day_last year_month_day_last::month_day_last() const NOEXCEPT { return mdl_; } CONSTCD14 inline day year_month_day_last::day() const NOEXCEPT { CONSTDATA date::day d[] = { date::day(31), date::day(28), date::day(31), date::day(30), date::day(31), date::day(30), date::day(31), date::day(31), date::day(30), date::day(31), date::day(30), date::day(31) }; return (month() != February || !y_.is_leap()) && mdl_.ok() ? d[static_cast(month()) - 1] : date::day{29}; } CONSTCD14 inline year_month_day_last::operator sys_days() const NOEXCEPT { return sys_days(year()/month()/day()); } CONSTCD14 inline year_month_day_last::operator local_days() const NOEXCEPT { return local_days(year()/month()/day()); } CONSTCD11 inline bool year_month_day_last::ok() const NOEXCEPT { return y_.ok() && mdl_.ok(); } CONSTCD11 inline bool operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return x.year() == y.year() && x.month_day_last() == y.month_day_last(); } CONSTCD11 inline bool operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.month_day_last() < y.month_day_last())); } CONSTCD11 inline bool operator>(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return !(x < y); } namespace detail { template std::basic_ostream& low_level_fmt(std::basic_ostream& os, const year_month_day_last& ymdl) { low_level_fmt(os, ymdl.year()) << '/'; return low_level_fmt(os, ymdl.month_day_last()); } } // namespace detail template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day_last& ymdl) { detail::low_level_fmt(os, ymdl); if (!ymdl.ok()) os << " is not a valid year_month_day_last"; return os; } template CONSTCD14 inline year_month_day_last operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT { return (ymdl.year() / ymdl.month() + dm) / last; } template CONSTCD14 inline year_month_day_last operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT { return ymdl + dm; } template CONSTCD14 inline year_month_day_last operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT { return ymdl + (-dm); } CONSTCD11 inline year_month_day_last operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT { return {ymdl.year()+dy, ymdl.month_day_last()}; } CONSTCD11 inline year_month_day_last operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT { return ymdl + dy; } CONSTCD11 inline year_month_day_last operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT { return ymdl + (-dy); } // year_month_day CONSTCD11 inline year_month_day::year_month_day(const date::year& y, const date::month& m, const date::day& d) NOEXCEPT : y_(y) , m_(m) , d_(d) {} CONSTCD14 inline year_month_day::year_month_day(const year_month_day_last& ymdl) NOEXCEPT : y_(ymdl.year()) , m_(ymdl.month()) , d_(ymdl.day()) {} CONSTCD14 inline year_month_day::year_month_day(sys_days dp) NOEXCEPT : year_month_day(from_days(dp.time_since_epoch())) {} CONSTCD14 inline year_month_day::year_month_day(local_days dp) NOEXCEPT : year_month_day(from_days(dp.time_since_epoch())) {} CONSTCD11 inline year year_month_day::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_day::month() const NOEXCEPT {return m_;} CONSTCD11 inline day year_month_day::day() const NOEXCEPT {return d_;} template CONSTCD14 inline year_month_day& year_month_day::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } template CONSTCD14 inline year_month_day& year_month_day::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_day& year_month_day::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_day& year_month_day::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD14 inline days year_month_day::to_days() const NOEXCEPT { static_assert(std::numeric_limits::digits >= 18, "This algorithm has not been ported to a 16 bit unsigned integer"); static_assert(std::numeric_limits::digits >= 20, "This algorithm has not been ported to a 16 bit signed integer"); auto const y = static_cast(y_) - (m_ <= February); auto const m = static_cast(m_); auto const d = static_cast(d_); auto const era = (y >= 0 ? y : y-399) / 400; auto const yoe = static_cast(y - era * 400); // [0, 399] auto const doy = (153*(m > 2 ? m-3 : m+9) + 2)/5 + d-1; // [0, 365] auto const doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096] return days{era * 146097 + static_cast(doe) - 719468}; } CONSTCD14 inline year_month_day::operator sys_days() const NOEXCEPT { return sys_days{to_days()}; } CONSTCD14 inline year_month_day::operator local_days() const NOEXCEPT { return local_days{to_days()}; } CONSTCD14 inline bool year_month_day::ok() const NOEXCEPT { if (!(y_.ok() && m_.ok())) return false; return date::day{1} <= d_ && d_ <= (y_ / m_ / last).day(); } CONSTCD11 inline bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month() && x.day() == y.day(); } CONSTCD11 inline bool operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_month_day& x, const year_month_day& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.month() < y.month() ? true : (x.month() > y.month() ? false : (x.day() < y.day())))); } CONSTCD11 inline bool operator>(const year_month_day& x, const year_month_day& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day& ymd) { detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.imbue(std::locale::classic()); os << static_cast(ymd.year()) << '-'; os.width(2); os << static_cast(ymd.month()) << '-'; os.width(2); os << static_cast(ymd.day()); if (!ymd.ok()) os << " is not a valid year_month_day"; return os; } CONSTCD14 inline year_month_day year_month_day::from_days(days dp) NOEXCEPT { static_assert(std::numeric_limits::digits >= 18, "This algorithm has not been ported to a 16 bit unsigned integer"); static_assert(std::numeric_limits::digits >= 20, "This algorithm has not been ported to a 16 bit signed integer"); auto const z = dp.count() + 719468; auto const era = (z >= 0 ? z : z - 146096) / 146097; auto const doe = static_cast(z - era * 146097); // [0, 146096] auto const yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399] auto const y = static_cast(yoe) + era * 400; auto const doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365] auto const mp = (5*doy + 2)/153; // [0, 11] auto const d = doy - (153*mp+2)/5 + 1; // [1, 31] auto const m = mp < 10 ? mp+3 : mp-9; // [1, 12] return year_month_day{date::year{y + (m <= 2)}, date::month(m), date::day(d)}; } template CONSTCD14 inline year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT { return (ymd.year() / ymd.month() + dm) / ymd.day(); } template CONSTCD14 inline year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT { return ymd + dm; } template CONSTCD14 inline year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT { return ymd + (-dm); } CONSTCD11 inline year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT { return (ymd.year() + dy) / ymd.month() / ymd.day(); } CONSTCD11 inline year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT { return ymd + dy; } CONSTCD11 inline year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT { return ymd + (-dy); } // year_month_weekday CONSTCD11 inline year_month_weekday::year_month_weekday(const date::year& y, const date::month& m, const date::weekday_indexed& wdi) NOEXCEPT : y_(y) , m_(m) , wdi_(wdi) {} CONSTCD14 inline year_month_weekday::year_month_weekday(const sys_days& dp) NOEXCEPT : year_month_weekday(from_days(dp.time_since_epoch())) {} CONSTCD14 inline year_month_weekday::year_month_weekday(const local_days& dp) NOEXCEPT : year_month_weekday(from_days(dp.time_since_epoch())) {} template CONSTCD14 inline year_month_weekday& year_month_weekday::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } template CONSTCD14 inline year_month_weekday& year_month_weekday::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_weekday& year_month_weekday::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_weekday& year_month_weekday::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_month_weekday::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_weekday::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday year_month_weekday::weekday() const NOEXCEPT { return wdi_.weekday(); } CONSTCD11 inline unsigned year_month_weekday::index() const NOEXCEPT { return wdi_.index(); } CONSTCD11 inline weekday_indexed year_month_weekday::weekday_indexed() const NOEXCEPT { return wdi_; } CONSTCD14 inline year_month_weekday::operator sys_days() const NOEXCEPT { return sys_days{to_days()}; } CONSTCD14 inline year_month_weekday::operator local_days() const NOEXCEPT { return local_days{to_days()}; } CONSTCD14 inline bool year_month_weekday::ok() const NOEXCEPT { if (!y_.ok() || !m_.ok() || !wdi_.weekday().ok() || wdi_.index() < 1) return false; if (wdi_.index() <= 4) return true; auto d2 = wdi_.weekday() - date::weekday(static_cast(y_/m_/1)) + days((wdi_.index()-1)*7 + 1); return static_cast(d2.count()) <= static_cast((y_/m_/last).day()); } CONSTCD14 inline year_month_weekday year_month_weekday::from_days(days d) NOEXCEPT { sys_days dp{d}; auto const wd = date::weekday(dp); auto const ymd = year_month_day(dp); return {ymd.year(), ymd.month(), wd[(static_cast(ymd.day())-1)/7+1]}; } CONSTCD14 inline days year_month_weekday::to_days() const NOEXCEPT { auto d = sys_days(y_/m_/1); return (d + (wdi_.weekday() - date::weekday(d) + days{(wdi_.index()-1)*7}) ).time_since_epoch(); } CONSTCD11 inline bool operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed(); } CONSTCD11 inline bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi) { detail::low_level_fmt(os, ymwdi.year()) << '/'; detail::low_level_fmt(os, ymwdi.month()) << '/'; detail::low_level_fmt(os, ymwdi.weekday_indexed()); if (!ymwdi.ok()) os << " is not a valid year_month_weekday"; return os; } template CONSTCD14 inline year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT { return (ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed(); } template CONSTCD14 inline year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT { return ymwd + dm; } template CONSTCD14 inline year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT { return ymwd + (-dm); } CONSTCD11 inline year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT { return {ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()}; } CONSTCD11 inline year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT { return ymwd + dy; } CONSTCD11 inline year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT { return ymwd + (-dy); } // year_month_weekday_last CONSTCD11 inline year_month_weekday_last::year_month_weekday_last(const date::year& y, const date::month& m, const date::weekday_last& wdl) NOEXCEPT : y_(y) , m_(m) , wdl_(wdl) {} template CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } template CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_month_weekday_last::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_weekday_last::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday year_month_weekday_last::weekday() const NOEXCEPT { return wdl_.weekday(); } CONSTCD11 inline weekday_last year_month_weekday_last::weekday_last() const NOEXCEPT { return wdl_; } CONSTCD14 inline year_month_weekday_last::operator sys_days() const NOEXCEPT { return sys_days{to_days()}; } CONSTCD14 inline year_month_weekday_last::operator local_days() const NOEXCEPT { return local_days{to_days()}; } CONSTCD11 inline bool year_month_weekday_last::ok() const NOEXCEPT { return y_.ok() && m_.ok() && wdl_.ok(); } CONSTCD14 inline days year_month_weekday_last::to_days() const NOEXCEPT { auto const d = sys_days(y_/m_/last); return (d - (date::weekday{d} - wdl_.weekday())).time_since_epoch(); } CONSTCD11 inline bool operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month() && x.weekday_last() == y.weekday_last(); } CONSTCD11 inline bool operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl) { detail::low_level_fmt(os, ymwdl.year()) << '/'; detail::low_level_fmt(os, ymwdl.month()) << '/'; detail::low_level_fmt(os, ymwdl.weekday_last()); if (!ymwdl.ok()) os << " is not a valid year_month_weekday_last"; return os; } template CONSTCD14 inline year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT { return (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last(); } template CONSTCD14 inline year_month_weekday_last operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT { return ymwdl + dm; } template CONSTCD14 inline year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT { return ymwdl + (-dm); } CONSTCD11 inline year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT { return {ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()}; } CONSTCD11 inline year_month_weekday_last operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT { return ymwdl + dy; } CONSTCD11 inline year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT { return ymwdl + (-dy); } // year_month from operator/() CONSTCD11 inline year_month operator/(const year& y, const month& m) NOEXCEPT { return {y, m}; } CONSTCD11 inline year_month operator/(const year& y, int m) NOEXCEPT { return y / month(static_cast(m)); } // month_day from operator/() CONSTCD11 inline month_day operator/(const month& m, const day& d) NOEXCEPT { return {m, d}; } CONSTCD11 inline month_day operator/(const day& d, const month& m) NOEXCEPT { return m / d; } CONSTCD11 inline month_day operator/(const month& m, int d) NOEXCEPT { return m / day(static_cast(d)); } CONSTCD11 inline month_day operator/(int m, const day& d) NOEXCEPT { return month(static_cast(m)) / d; } CONSTCD11 inline month_day operator/(const day& d, int m) NOEXCEPT {return m / d;} // month_day_last from operator/() CONSTCD11 inline month_day_last operator/(const month& m, last_spec) NOEXCEPT { return month_day_last{m}; } CONSTCD11 inline month_day_last operator/(last_spec, const month& m) NOEXCEPT { return m/last; } CONSTCD11 inline month_day_last operator/(int m, last_spec) NOEXCEPT { return month(static_cast(m))/last; } CONSTCD11 inline month_day_last operator/(last_spec, int m) NOEXCEPT { return m/last; } // month_weekday from operator/() CONSTCD11 inline month_weekday operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT { return {m, wdi}; } CONSTCD11 inline month_weekday operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT { return m / wdi; } CONSTCD11 inline month_weekday operator/(int m, const weekday_indexed& wdi) NOEXCEPT { return month(static_cast(m)) / wdi; } CONSTCD11 inline month_weekday operator/(const weekday_indexed& wdi, int m) NOEXCEPT { return m / wdi; } // month_weekday_last from operator/() CONSTCD11 inline month_weekday_last operator/(const month& m, const weekday_last& wdl) NOEXCEPT { return {m, wdl}; } CONSTCD11 inline month_weekday_last operator/(const weekday_last& wdl, const month& m) NOEXCEPT { return m / wdl; } CONSTCD11 inline month_weekday_last operator/(int m, const weekday_last& wdl) NOEXCEPT { return month(static_cast(m)) / wdl; } CONSTCD11 inline month_weekday_last operator/(const weekday_last& wdl, int m) NOEXCEPT { return m / wdl; } // year_month_day from operator/() CONSTCD11 inline year_month_day operator/(const year_month& ym, const day& d) NOEXCEPT { return {ym.year(), ym.month(), d}; } CONSTCD11 inline year_month_day operator/(const year_month& ym, int d) NOEXCEPT { return ym / day(static_cast(d)); } CONSTCD11 inline year_month_day operator/(const year& y, const month_day& md) NOEXCEPT { return y / md.month() / md.day(); } CONSTCD11 inline year_month_day operator/(int y, const month_day& md) NOEXCEPT { return year(y) / md; } CONSTCD11 inline year_month_day operator/(const month_day& md, const year& y) NOEXCEPT { return y / md; } CONSTCD11 inline year_month_day operator/(const month_day& md, int y) NOEXCEPT { return year(y) / md; } // year_month_day_last from operator/() CONSTCD11 inline year_month_day_last operator/(const year_month& ym, last_spec) NOEXCEPT { return {ym.year(), month_day_last{ym.month()}}; } CONSTCD11 inline year_month_day_last operator/(const year& y, const month_day_last& mdl) NOEXCEPT { return {y, mdl}; } CONSTCD11 inline year_month_day_last operator/(int y, const month_day_last& mdl) NOEXCEPT { return year(y) / mdl; } CONSTCD11 inline year_month_day_last operator/(const month_day_last& mdl, const year& y) NOEXCEPT { return y / mdl; } CONSTCD11 inline year_month_day_last operator/(const month_day_last& mdl, int y) NOEXCEPT { return year(y) / mdl; } // year_month_weekday from operator/() CONSTCD11 inline year_month_weekday operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT { return {ym.year(), ym.month(), wdi}; } CONSTCD11 inline year_month_weekday operator/(const year& y, const month_weekday& mwd) NOEXCEPT { return {y, mwd.month(), mwd.weekday_indexed()}; } CONSTCD11 inline year_month_weekday operator/(int y, const month_weekday& mwd) NOEXCEPT { return year(y) / mwd; } CONSTCD11 inline year_month_weekday operator/(const month_weekday& mwd, const year& y) NOEXCEPT { return y / mwd; } CONSTCD11 inline year_month_weekday operator/(const month_weekday& mwd, int y) NOEXCEPT { return year(y) / mwd; } // year_month_weekday_last from operator/() CONSTCD11 inline year_month_weekday_last operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT { return {ym.year(), ym.month(), wdl}; } CONSTCD11 inline year_month_weekday_last operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT { return {y, mwdl.month(), mwdl.weekday_last()}; } CONSTCD11 inline year_month_weekday_last operator/(int y, const month_weekday_last& mwdl) NOEXCEPT { return year(y) / mwdl; } CONSTCD11 inline year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT { return y / mwdl; } CONSTCD11 inline year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) NOEXCEPT { return year(y) / mwdl; } template struct fields; template std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const fields& fds, const std::string* abbrev = nullptr, const std::chrono::seconds* offset_sec = nullptr); template std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, fields& fds, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr); // hh_mm_ss namespace detail { struct undocumented {explicit undocumented() = default;}; // width::value is the number of fractional decimal digits in 1/n // width<0>::value and width<1>::value are defined to be 0 // If 1/n takes more than 18 fractional decimal digits, // the result is truncated to 19. // Example: width<2>::value == 1 // Example: width<3>::value == 19 // Example: width<4>::value == 2 // Example: width<10>::value == 1 // Example: width<1000>::value == 3 template struct width { static_assert(d > 0, "width called with zero denominator"); static CONSTDATA unsigned value = 1 + width::value; }; template struct width { static CONSTDATA unsigned value = 0; }; template struct static_pow10 { private: static CONSTDATA std::uint64_t h = static_pow10::value; public: static CONSTDATA std::uint64_t value = h * h * (exp % 2 ? 10 : 1); }; template <> struct static_pow10<0> { static CONSTDATA std::uint64_t value = 1; }; template class decimal_format_seconds { using CT = typename std::common_type::type; using rep = typename CT::rep; static unsigned CONSTDATA trial_width = detail::width::value; public: static unsigned CONSTDATA width = trial_width < 19 ? trial_width : 6u; using precision = std::chrono::duration::value>>; private: std::chrono::seconds s_; precision sub_s_; public: CONSTCD11 decimal_format_seconds() : s_() , sub_s_() {} CONSTCD11 explicit decimal_format_seconds(const Duration& d) NOEXCEPT : s_(std::chrono::duration_cast(d)) , sub_s_(std::chrono::duration_cast(d - s_)) {} CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_;} CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_;} CONSTCD11 precision subseconds() const NOEXCEPT {return sub_s_;} CONSTCD14 precision to_duration() const NOEXCEPT { return s_ + sub_s_; } CONSTCD11 bool in_conventional_range() const NOEXCEPT { return sub_s_ < std::chrono::seconds{1} && s_ < std::chrono::minutes{1}; } template friend std::basic_ostream& operator<<(std::basic_ostream& os, const decimal_format_seconds& x) { return x.print(os, std::chrono::treat_as_floating_point{}); } template std::basic_ostream& print(std::basic_ostream& os, std::true_type) const { date::detail::save_ostream _(os); std::chrono::duration d = s_ + sub_s_; if (d < std::chrono::seconds{10}) os << '0'; os.precision(width+6); os << std::fixed << d.count(); return os; } template std::basic_ostream& print(std::basic_ostream& os, std::false_type) const { date::detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.width(2); os << s_.count(); if (width > 0) { #if !ONLY_C_LOCALE os << std::use_facet>(os.getloc()).decimal_point(); #else os << '.'; #endif date::detail::save_ostream _s(os); os.imbue(std::locale::classic()); os.width(width); os << sub_s_.count(); } return os; } }; template inline CONSTCD11 typename std::enable_if < std::numeric_limits::is_signed, std::chrono::duration >::type abs(std::chrono::duration d) { return d >= d.zero() ? +d : -d; } template inline CONSTCD11 typename std::enable_if < !std::numeric_limits::is_signed, std::chrono::duration >::type abs(std::chrono::duration d) { return d; } } // namespace detail template class hh_mm_ss { using dfs = detail::decimal_format_seconds::type>; std::chrono::hours h_; std::chrono::minutes m_; dfs s_; bool neg_; public: static unsigned CONSTDATA fractional_width = dfs::width; using precision = typename dfs::precision; CONSTCD11 hh_mm_ss() NOEXCEPT : hh_mm_ss(Duration::zero()) {} CONSTCD11 explicit hh_mm_ss(Duration d) NOEXCEPT : h_(std::chrono::duration_cast(detail::abs(d))) , m_(std::chrono::duration_cast(detail::abs(d)) - h_) , s_(detail::abs(d) - h_ - m_) , neg_(d < Duration::zero()) {} CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;} CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_.seconds();} CONSTCD14 std::chrono::seconds& seconds(detail::undocumented) NOEXCEPT {return s_.seconds();} CONSTCD11 precision subseconds() const NOEXCEPT {return s_.subseconds();} CONSTCD11 bool is_negative() const NOEXCEPT {return neg_;} CONSTCD11 explicit operator precision() const NOEXCEPT {return to_duration();} CONSTCD11 precision to_duration() const NOEXCEPT {return (s_.to_duration() + m_ + h_) * (1-2*neg_);} CONSTCD11 bool in_conventional_range() const NOEXCEPT { return !neg_ && h_ < days{1} && m_ < std::chrono::hours{1} && s_.in_conventional_range(); } private: template friend std::basic_ostream& operator<<(std::basic_ostream& os, hh_mm_ss const& tod) { if (tod.is_negative()) os << '-'; if (tod.h_ < std::chrono::hours{10}) os << '0'; os << tod.h_.count() << ':'; if (tod.m_ < std::chrono::minutes{10}) os << '0'; os << tod.m_.count() << ':' << tod.s_; return os; } template friend std::basic_ostream& date::to_stream(std::basic_ostream& os, const CharT* fmt, const fields& fds, const std::string* abbrev, const std::chrono::seconds* offset_sec); template friend std::basic_istream& date::from_stream(std::basic_istream& is, const CharT* fmt, fields& fds, std::basic_string* abbrev, std::chrono::minutes* offset); }; inline CONSTCD14 bool is_am(std::chrono::hours const& h) NOEXCEPT { using std::chrono::hours; return hours{0} <= h && h < hours{12}; } inline CONSTCD14 bool is_pm(std::chrono::hours const& h) NOEXCEPT { using std::chrono::hours; return hours{12} <= h && h < hours{24}; } inline CONSTCD14 std::chrono::hours make12(std::chrono::hours h) NOEXCEPT { using std::chrono::hours; if (h < hours{12}) { if (h == hours{0}) h = hours{12}; } else { if (h != hours{12}) h = h - hours{12}; } return h; } inline CONSTCD14 std::chrono::hours make24(std::chrono::hours h, bool is_pm) NOEXCEPT { using std::chrono::hours; if (is_pm) { if (h != hours{12}) h = h + hours{12}; } else if (h == hours{12}) h = hours{0}; return h; } template using time_of_day = hh_mm_ss; template CONSTCD11 inline hh_mm_ss> make_time(const std::chrono::duration& d) { return hh_mm_ss>(d); } template inline typename std::enable_if < std::ratio_less::value , std::basic_ostream& >::type operator<<(std::basic_ostream& os, const sys_time& tp) { auto const dp = date::floor(tp); return os << year_month_day(dp) << ' ' << make_time(tp-dp); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const sys_days& dp) { return os << year_month_day(dp); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const local_time& ut) { return (os << sys_time{ut.time_since_epoch()}); } namespace detail { template class string_literal; template inline CONSTCD14 string_literal::type, N1 + N2 - 1> operator+(const string_literal& x, const string_literal& y) NOEXCEPT; template class string_literal { CharT p_[N]; CONSTCD11 string_literal() NOEXCEPT : p_{} {} public: using const_iterator = const CharT*; string_literal(string_literal const&) = default; string_literal& operator=(string_literal const&) = delete; template ::type> CONSTCD11 string_literal(CharT c) NOEXCEPT : p_{c} { } template ::type> CONSTCD11 string_literal(CharT c1, CharT c2) NOEXCEPT : p_{c1, c2} { } template ::type> CONSTCD11 string_literal(CharT c1, CharT c2, CharT c3) NOEXCEPT : p_{c1, c2, c3} { } CONSTCD14 string_literal(const CharT(&a)[N]) NOEXCEPT : p_{} { for (std::size_t i = 0; i < N; ++i) p_[i] = a[i]; } template ::type> CONSTCD14 string_literal(const char(&a)[N]) NOEXCEPT : p_{} { for (std::size_t i = 0; i < N; ++i) p_[i] = a[i]; } template ::value>::type> CONSTCD14 string_literal(string_literal const& a) NOEXCEPT : p_{} { for (std::size_t i = 0; i < N; ++i) p_[i] = a[i]; } CONSTCD11 const CharT* data() const NOEXCEPT {return p_;} CONSTCD11 std::size_t size() const NOEXCEPT {return N-1;} CONSTCD11 const_iterator begin() const NOEXCEPT {return p_;} CONSTCD11 const_iterator end() const NOEXCEPT {return p_ + N-1;} CONSTCD11 CharT const& operator[](std::size_t n) const NOEXCEPT { return p_[n]; } template friend std::basic_ostream& operator<<(std::basic_ostream& os, const string_literal& s) { return os << s.p_; } template friend CONSTCD14 string_literal::type, N1 + N2 - 1> operator+(const string_literal& x, const string_literal& y) NOEXCEPT; }; template CONSTCD11 inline string_literal operator+(const string_literal& x, const string_literal& y) NOEXCEPT { return string_literal(x[0], y[0]); } template CONSTCD11 inline string_literal operator+(const string_literal& x, const string_literal& y) NOEXCEPT { return string_literal(x[0], x[1], y[0]); } template CONSTCD14 inline string_literal::type, N1 + N2 - 1> operator+(const string_literal& x, const string_literal& y) NOEXCEPT { using CT = typename std::conditional::type; string_literal r; std::size_t i = 0; for (; i < N1-1; ++i) r.p_[i] = CT(x.p_[i]); for (std::size_t j = 0; j < N2; ++j, ++i) r.p_[i] = CT(y.p_[j]); return r; } template inline std::basic_string operator+(std::basic_string x, const string_literal& y) { x.append(y.data(), y.size()); return x; } #if __cplusplus >= 201402 && (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 411) \ && (!defined(__SUNPRO_CC) || __SUNPRO_CC > 0x5150) template ::value || std::is_same::value || std::is_same::value || std::is_same::value>> CONSTCD14 inline string_literal msl(CharT c) NOEXCEPT { return string_literal{c}; } CONSTCD14 inline std::size_t to_string_len(std::intmax_t i) { std::size_t r = 0; do { i /= 10; ++r; } while (i > 0); return r; } template CONSTCD14 inline std::enable_if_t < N < 10, string_literal > msl() NOEXCEPT { return msl(char(N % 10 + '0')); } template CONSTCD14 inline std::enable_if_t < 10 <= N, string_literal > msl() NOEXCEPT { return msl() + msl(char(N % 10 + '0')); } template CONSTCD14 inline std::enable_if_t < std::ratio::type::den != 1, string_literal::type::num) + to_string_len(std::ratio::type::den) + 4> > msl(std::ratio) NOEXCEPT { using R = typename std::ratio::type; return msl(CharT{'['}) + msl() + msl(CharT{'/'}) + msl() + msl(CharT{']'}); } template CONSTCD14 inline std::enable_if_t < std::ratio::type::den == 1, string_literal::type::num) + 3> > msl(std::ratio) NOEXCEPT { using R = typename std::ratio::type; return msl(CharT{'['}) + msl() + msl(CharT{']'}); } #else // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411) inline std::string to_string(std::uint64_t x) { return std::to_string(x); } template inline std::basic_string to_string(std::uint64_t x) { auto y = std::to_string(x); return std::basic_string(y.begin(), y.end()); } template inline typename std::enable_if < std::ratio::type::den != 1, std::basic_string >::type msl(std::ratio) { using R = typename std::ratio::type; return std::basic_string(1, '[') + to_string(R::num) + CharT{'/'} + to_string(R::den) + CharT{']'}; } template inline typename std::enable_if < std::ratio::type::den == 1, std::basic_string >::type msl(std::ratio) { using R = typename std::ratio::type; return std::basic_string(1, '[') + to_string(R::num) + CharT{']'}; } #endif // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411) template CONSTCD11 inline string_literal msl(std::atto) NOEXCEPT { return string_literal{'a'}; } template CONSTCD11 inline string_literal msl(std::femto) NOEXCEPT { return string_literal{'f'}; } template CONSTCD11 inline string_literal msl(std::pico) NOEXCEPT { return string_literal{'p'}; } template CONSTCD11 inline string_literal msl(std::nano) NOEXCEPT { return string_literal{'n'}; } template CONSTCD11 inline typename std::enable_if < std::is_same::value, string_literal >::type msl(std::micro) NOEXCEPT { return string_literal{'\xC2', '\xB5'}; } template CONSTCD11 inline typename std::enable_if < !std::is_same::value, string_literal >::type msl(std::micro) NOEXCEPT { return string_literal{CharT{static_cast('\xB5')}}; } template CONSTCD11 inline string_literal msl(std::milli) NOEXCEPT { return string_literal{'m'}; } template CONSTCD11 inline string_literal msl(std::centi) NOEXCEPT { return string_literal{'c'}; } template CONSTCD11 inline string_literal msl(std::deca) NOEXCEPT { return string_literal{'d', 'a'}; } template CONSTCD11 inline string_literal msl(std::deci) NOEXCEPT { return string_literal{'d'}; } template CONSTCD11 inline string_literal msl(std::hecto) NOEXCEPT { return string_literal{'h'}; } template CONSTCD11 inline string_literal msl(std::kilo) NOEXCEPT { return string_literal{'k'}; } template CONSTCD11 inline string_literal msl(std::mega) NOEXCEPT { return string_literal{'M'}; } template CONSTCD11 inline string_literal msl(std::giga) NOEXCEPT { return string_literal{'G'}; } template CONSTCD11 inline string_literal msl(std::tera) NOEXCEPT { return string_literal{'T'}; } template CONSTCD11 inline string_literal msl(std::peta) NOEXCEPT { return string_literal{'P'}; } template CONSTCD11 inline string_literal msl(std::exa) NOEXCEPT { return string_literal{'E'}; } template CONSTCD11 inline auto get_units(Period p) -> decltype(msl(p) + string_literal{'s'}) { return msl(p) + string_literal{'s'}; } template CONSTCD11 inline string_literal get_units(std::ratio<1>) { return string_literal{'s'}; } template CONSTCD11 inline string_literal get_units(std::ratio<3600>) { return string_literal{'h'}; } template CONSTCD11 inline string_literal get_units(std::ratio<60>) { return string_literal{'m', 'i', 'n'}; } template CONSTCD11 inline string_literal get_units(std::ratio<86400>) { return string_literal{'d'}; } template > struct make_string; template <> struct make_string { template static std::string from(Rep n) { return std::to_string(n); } }; template struct make_string { template static std::basic_string from(Rep n) { auto s = std::to_string(n); return std::basic_string(s.begin(), s.end()); } }; template <> struct make_string { template static std::wstring from(Rep n) { return std::to_wstring(n); } }; template struct make_string { template static std::basic_string from(Rep n) { auto s = std::to_wstring(n); return std::basic_string(s.begin(), s.end()); } }; } // namespace detail // to_stream CONSTDATA year nanyear{-32768}; template struct fields { year_month_day ymd{nanyear/0/0}; weekday wd{8u}; hh_mm_ss tod{}; bool has_tod = false; fields() = default; fields(year_month_day ymd_) : ymd(ymd_) {} fields(weekday wd_) : wd(wd_) {} fields(hh_mm_ss tod_) : tod(tod_), has_tod(true) {} fields(year_month_day ymd_, weekday wd_) : ymd(ymd_), wd(wd_) {} fields(year_month_day ymd_, hh_mm_ss tod_) : ymd(ymd_), tod(tod_), has_tod(true) {} fields(weekday wd_, hh_mm_ss tod_) : wd(wd_), tod(tod_), has_tod(true) {} fields(year_month_day ymd_, weekday wd_, hh_mm_ss tod_) : ymd(ymd_) , wd(wd_) , tod(tod_) , has_tod(true) {} }; namespace detail { template unsigned extract_weekday(std::basic_ostream& os, const fields& fds) { if (!fds.ymd.ok() && !fds.wd.ok()) { // fds does not contain a valid weekday os.setstate(std::ios::failbit); return 8; } weekday wd; if (fds.ymd.ok()) { wd = weekday{sys_days(fds.ymd)}; if (fds.wd.ok() && wd != fds.wd) { // fds.ymd and fds.wd are inconsistent os.setstate(std::ios::failbit); return 8; } } else wd = fds.wd; return static_cast((wd - Sunday).count()); } template unsigned extract_month(std::basic_ostream& os, const fields& fds) { if (!fds.ymd.month().ok()) { // fds does not contain a valid month os.setstate(std::ios::failbit); return 0; } return static_cast(fds.ymd.month()); } } // namespace detail #if ONLY_C_LOCALE namespace detail { inline std::pair weekday_names() { static const std::string nm[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; return std::make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); } inline std::pair month_names() { static const std::string nm[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; return std::make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); } inline std::pair ampm_names() { static const std::string nm[] = { "AM", "PM" }; return std::make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); } template FwdIter scan_keyword(std::basic_istream& is, FwdIter kb, FwdIter ke) { size_t nkw = static_cast(std::distance(kb, ke)); const unsigned char doesnt_match = '\0'; const unsigned char might_match = '\1'; const unsigned char does_match = '\2'; unsigned char statbuf[100]; unsigned char* status = statbuf; std::unique_ptr stat_hold(0, free); if (nkw > sizeof(statbuf)) { status = (unsigned char*)std::malloc(nkw); if (status == nullptr) throw std::bad_alloc(); stat_hold.reset(status); } size_t n_might_match = nkw; // At this point, any keyword might match size_t n_does_match = 0; // but none of them definitely do // Initialize all statuses to might_match, except for "" keywords are does_match unsigned char* st = status; for (auto ky = kb; ky != ke; ++ky, ++st) { if (!ky->empty()) *st = might_match; else { *st = does_match; --n_might_match; ++n_does_match; } } // While there might be a match, test keywords against the next CharT for (size_t indx = 0; is && n_might_match > 0; ++indx) { // Peek at the next CharT but don't consume it auto ic = is.peek(); if (ic == EOF) { is.setstate(std::ios::eofbit); break; } auto c = static_cast(toupper(static_cast(ic))); bool consume = false; // For each keyword which might match, see if the indx character is c // If a match if found, consume c // If a match is found, and that is the last character in the keyword, // then that keyword matches. // If the keyword doesn't match this character, then change the keyword // to doesn't match st = status; for (auto ky = kb; ky != ke; ++ky, ++st) { if (*st == might_match) { if (c == static_cast(toupper(static_cast((*ky)[indx])))) { consume = true; if (ky->size() == indx+1) { *st = does_match; --n_might_match; ++n_does_match; } } else { *st = doesnt_match; --n_might_match; } } } // consume if we matched a character if (consume) { (void)is.get(); // If we consumed a character and there might be a matched keyword that // was marked matched on a previous iteration, then such keywords // are now marked as not matching. if (n_might_match + n_does_match > 1) { st = status; for (auto ky = kb; ky != ke; ++ky, ++st) { if (*st == does_match && ky->size() != indx+1) { *st = doesnt_match; --n_does_match; } } } } } // We've exited the loop because we hit eof and/or we have no more "might matches". // Return the first matching result for (st = status; kb != ke; ++kb, ++st) if (*st == does_match) break; if (kb == ke) is.setstate(std::ios::failbit); return kb; } } // namespace detail #endif // ONLY_C_LOCALE template std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const fields& fds, const std::string* abbrev, const std::chrono::seconds* offset_sec) { #if ONLY_C_LOCALE using detail::weekday_names; using detail::month_names; using detail::ampm_names; #endif using detail::save_ostream; using detail::get_units; using detail::extract_weekday; using detail::extract_month; using std::ios; using std::chrono::duration_cast; using std::chrono::seconds; using std::chrono::minutes; using std::chrono::hours; date::detail::save_ostream ss(os); os.fill(' '); os.flags(std::ios::skipws | std::ios::dec); os.width(0); tm tm{}; bool insert_negative = fds.has_tod && fds.tod.to_duration() < Duration::zero(); #if !ONLY_C_LOCALE auto& facet = std::use_facet>(os.getloc()); #endif const CharT* command = nullptr; CharT modified = CharT{}; for (; *fmt; ++fmt) { switch (*fmt) { case 'a': case 'A': if (command) { if (modified == CharT{}) { tm.tm_wday = static_cast(extract_weekday(os, fds)); if (os.fail()) return os; #if !ONLY_C_LOCALE const CharT f[] = {'%', *fmt}; facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); #else // ONLY_C_LOCALE os << weekday_names().first[tm.tm_wday+7*(*fmt == 'a')]; #endif // ONLY_C_LOCALE } else { os << CharT{'%'} << modified << *fmt; modified = CharT{}; } command = nullptr; } else os << *fmt; break; case 'b': case 'B': case 'h': if (command) { if (modified == CharT{}) { tm.tm_mon = static_cast(extract_month(os, fds)) - 1; #if !ONLY_C_LOCALE const CharT f[] = {'%', *fmt}; facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); #else // ONLY_C_LOCALE os << month_names().first[tm.tm_mon+12*(*fmt != 'B')]; #endif // ONLY_C_LOCALE } else { os << CharT{'%'} << modified << *fmt; modified = CharT{}; } command = nullptr; } else os << *fmt; break; case 'c': case 'x': if (command) { if (modified == CharT{'O'}) os << CharT{'%'} << modified << *fmt; else { if (!fds.ymd.ok()) os.setstate(std::ios::failbit); if (*fmt == 'c' && !fds.has_tod) os.setstate(std::ios::failbit); #if !ONLY_C_LOCALE tm = std::tm{}; auto const& ymd = fds.ymd; auto ld = local_days(ymd); if (*fmt == 'c') { tm.tm_sec = static_cast(fds.tod.seconds().count()); tm.tm_min = static_cast(fds.tod.minutes().count()); tm.tm_hour = static_cast(fds.tod.hours().count()); } tm.tm_mday = static_cast(static_cast(ymd.day())); tm.tm_mon = static_cast(extract_month(os, fds) - 1); tm.tm_year = static_cast(ymd.year()) - 1900; tm.tm_wday = static_cast(extract_weekday(os, fds)); if (os.fail()) return os; tm.tm_yday = static_cast((ld - local_days(ymd.year()/1/1)).count()); CharT f[3] = {'%'}; auto fe = std::begin(f) + 1; if (modified == CharT{'E'}) *fe++ = modified; *fe++ = *fmt; facet.put(os, os, os.fill(), &tm, std::begin(f), fe); #else // ONLY_C_LOCALE if (*fmt == 'c') { auto wd = static_cast(extract_weekday(os, fds)); os << weekday_names().first[static_cast(wd)+7] << ' '; os << month_names().first[extract_month(os, fds)-1+12] << ' '; auto d = static_cast(static_cast(fds.ymd.day())); if (d < 10) os << ' '; os << d << ' ' << make_time(duration_cast(fds.tod.to_duration())) << ' ' << fds.ymd.year(); } else // *fmt == 'x' { auto const& ymd = fds.ymd; save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.width(2); os << static_cast(ymd.month()) << CharT{'/'}; os.width(2); os << static_cast(ymd.day()) << CharT{'/'}; os.width(2); os << static_cast(ymd.year()) % 100; } #endif // ONLY_C_LOCALE } command = nullptr; modified = CharT{}; } else os << *fmt; break; case 'C': if (command) { if (modified == CharT{'O'}) os << CharT{'%'} << modified << *fmt; else { if (!fds.ymd.year().ok()) os.setstate(std::ios::failbit); auto y = static_cast(fds.ymd.year()); #if !ONLY_C_LOCALE if (modified == CharT{}) #endif { save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); if (y >= 0) { os.width(2); os << y/100; } else { os << CharT{'-'}; os.width(2); os << -(y-99)/100; } } #if !ONLY_C_LOCALE else if (modified == CharT{'E'}) { tm.tm_year = y - 1900; CharT f[3] = {'%', 'E', 'C'}; facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); } #endif } command = nullptr; modified = CharT{}; } else os << *fmt; break; case 'd': case 'e': if (command) { if (modified == CharT{'E'}) os << CharT{'%'} << modified << *fmt; else { if (!fds.ymd.day().ok()) os.setstate(std::ios::failbit); auto d = static_cast(static_cast(fds.ymd.day())); #if !ONLY_C_LOCALE if (modified == CharT{}) #endif { save_ostream _(os); if (*fmt == CharT{'d'}) os.fill('0'); else os.fill(' '); os.flags(std::ios::dec | std::ios::right); os.width(2); os << d; } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { tm.tm_mday = d; CharT f[3] = {'%', 'O', *fmt}; facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); } #endif } command = nullptr; modified = CharT{}; } else os << *fmt; break; case 'D': if (command) { if (modified == CharT{}) { if (!fds.ymd.ok()) os.setstate(std::ios::failbit); auto const& ymd = fds.ymd; save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.width(2); os << static_cast(ymd.month()) << CharT{'/'}; os.width(2); os << static_cast(ymd.day()) << CharT{'/'}; os.width(2); os << static_cast(ymd.year()) % 100; } else { os << CharT{'%'} << modified << *fmt; modified = CharT{}; } command = nullptr; } else os << *fmt; break; case 'F': if (command) { if (modified == CharT{}) { if (!fds.ymd.ok()) os.setstate(std::ios::failbit); auto const& ymd = fds.ymd; save_ostream _(os); os.imbue(std::locale::classic()); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.width(4); os << static_cast(ymd.year()) << CharT{'-'}; os.width(2); os << static_cast(ymd.month()) << CharT{'-'}; os.width(2); os << static_cast(ymd.day()); } else { os << CharT{'%'} << modified << *fmt; modified = CharT{}; } command = nullptr; } else os << *fmt; break; case 'g': case 'G': if (command) { if (modified == CharT{}) { if (!fds.ymd.ok()) os.setstate(std::ios::failbit); auto ld = local_days(fds.ymd); auto y = year_month_day{ld + days{3}}.year(); auto start = local_days((y-years{1})/December/Thursday[last]) + (Monday-Thursday); if (ld < start) --y; if (*fmt == CharT{'G'}) os << y; else { save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.width(2); os << std::abs(static_cast(y)) % 100; } } else { os << CharT{'%'} << modified << *fmt; modified = CharT{}; } command = nullptr; } else os << *fmt; break; case 'H': case 'I': if (command) { if (modified == CharT{'E'}) os << CharT{'%'} << modified << *fmt; else { if (!fds.has_tod) os.setstate(std::ios::failbit); if (insert_negative) { os << '-'; insert_negative = false; } auto hms = fds.tod; #if !ONLY_C_LOCALE if (modified == CharT{}) #endif { auto h = *fmt == CharT{'I'} ? date::make12(hms.hours()) : hms.hours(); if (h < hours{10}) os << CharT{'0'}; os << h.count(); } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { const CharT f[] = {'%', modified, *fmt}; tm.tm_hour = static_cast(hms.hours().count()); facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); } #endif } modified = CharT{}; command = nullptr; } else os << *fmt; break; case 'j': if (command) { if (modified == CharT{}) { if (fds.ymd.ok() || fds.has_tod) { days doy; if (fds.ymd.ok()) { auto ld = local_days(fds.ymd); auto y = fds.ymd.year(); doy = ld - local_days(y/January/1) + days{1}; } else { doy = duration_cast(fds.tod.to_duration()); } save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.width(3); os << doy.count(); } else { os.setstate(std::ios::failbit); } } else { os << CharT{'%'} << modified << *fmt; modified = CharT{}; } command = nullptr; } else os << *fmt; break; case 'm': if (command) { if (modified == CharT{'E'}) os << CharT{'%'} << modified << *fmt; else { if (!fds.ymd.month().ok()) os.setstate(std::ios::failbit); auto m = static_cast(fds.ymd.month()); #if !ONLY_C_LOCALE if (modified == CharT{}) #endif { if (m < 10) os << CharT{'0'}; os << m; } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { const CharT f[] = {'%', modified, *fmt}; tm.tm_mon = static_cast(m-1); facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); } #endif } modified = CharT{}; command = nullptr; } else os << *fmt; break; case 'M': if (command) { if (modified == CharT{'E'}) os << CharT{'%'} << modified << *fmt; else { if (!fds.has_tod) os.setstate(std::ios::failbit); if (insert_negative) { os << '-'; insert_negative = false; } #if !ONLY_C_LOCALE if (modified == CharT{}) #endif { if (fds.tod.minutes() < minutes{10}) os << CharT{'0'}; os << fds.tod.minutes().count(); } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { const CharT f[] = {'%', modified, *fmt}; tm.tm_min = static_cast(fds.tod.minutes().count()); facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); } #endif } modified = CharT{}; command = nullptr; } else os << *fmt; break; case 'n': if (command) { if (modified == CharT{}) os << CharT{'\n'}; else { os << CharT{'%'} << modified << *fmt; modified = CharT{}; } command = nullptr; } else os << *fmt; break; case 'p': if (command) { if (modified == CharT{}) { if (!fds.has_tod) os.setstate(std::ios::failbit); #if !ONLY_C_LOCALE const CharT f[] = {'%', *fmt}; tm.tm_hour = static_cast(fds.tod.hours().count()); facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); #else if (date::is_am(fds.tod.hours())) os << ampm_names().first[0]; else os << ampm_names().first[1]; #endif } else { os << CharT{'%'} << modified << *fmt; } modified = CharT{}; command = nullptr; } else os << *fmt; break; case 'Q': case 'q': if (command) { if (modified == CharT{}) { if (!fds.has_tod) os.setstate(std::ios::failbit); auto d = fds.tod.to_duration(); if (*fmt == 'q') os << get_units(typename decltype(d)::period::type{}); else os << d.count(); } else { os << CharT{'%'} << modified << *fmt; } modified = CharT{}; command = nullptr; } else os << *fmt; break; case 'r': if (command) { if (modified == CharT{}) { if (!fds.has_tod) os.setstate(std::ios::failbit); #if !ONLY_C_LOCALE const CharT f[] = {'%', *fmt}; tm.tm_hour = static_cast(fds.tod.hours().count()); tm.tm_min = static_cast(fds.tod.minutes().count()); tm.tm_sec = static_cast(fds.tod.seconds().count()); facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); #else hh_mm_ss tod(duration_cast(fds.tod.to_duration())); save_ostream _(os); os.fill('0'); os.width(2); os << date::make12(tod.hours()).count() << CharT{':'}; os.width(2); os << tod.minutes().count() << CharT{':'}; os.width(2); os << tod.seconds().count() << CharT{' '}; if (date::is_am(tod.hours())) os << ampm_names().first[0]; else os << ampm_names().first[1]; #endif } else { os << CharT{'%'} << modified << *fmt; } modified = CharT{}; command = nullptr; } else os << *fmt; break; case 'R': if (command) { if (modified == CharT{}) { if (!fds.has_tod) os.setstate(std::ios::failbit); if (fds.tod.hours() < hours{10}) os << CharT{'0'}; os << fds.tod.hours().count() << CharT{':'}; if (fds.tod.minutes() < minutes{10}) os << CharT{'0'}; os << fds.tod.minutes().count(); } else { os << CharT{'%'} << modified << *fmt; modified = CharT{}; } command = nullptr; } else os << *fmt; break; case 'S': if (command) { if (modified == CharT{'E'}) os << CharT{'%'} << modified << *fmt; else { if (!fds.has_tod) os.setstate(std::ios::failbit); if (insert_negative) { os << '-'; insert_negative = false; } #if !ONLY_C_LOCALE if (modified == CharT{}) #endif { os << fds.tod.s_; } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { const CharT f[] = {'%', modified, *fmt}; tm.tm_sec = static_cast(fds.tod.s_.seconds().count()); facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); } #endif } modified = CharT{}; command = nullptr; } else os << *fmt; break; case 't': if (command) { if (modified == CharT{}) os << CharT{'\t'}; else { os << CharT{'%'} << modified << *fmt; modified = CharT{}; } command = nullptr; } else os << *fmt; break; case 'T': if (command) { if (modified == CharT{}) { if (!fds.has_tod) os.setstate(std::ios::failbit); os << fds.tod; } else { os << CharT{'%'} << modified << *fmt; modified = CharT{}; } command = nullptr; } else os << *fmt; break; case 'u': if (command) { if (modified == CharT{'E'}) os << CharT{'%'} << modified << *fmt; else { auto wd = extract_weekday(os, fds); #if !ONLY_C_LOCALE if (modified == CharT{}) #endif { os << (wd != 0 ? wd : 7u); } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { const CharT f[] = {'%', modified, *fmt}; tm.tm_wday = static_cast(wd); facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); } #endif } modified = CharT{}; command = nullptr; } else os << *fmt; break; case 'U': if (command) { if (modified == CharT{'E'}) os << CharT{'%'} << modified << *fmt; else { auto const& ymd = fds.ymd; if (!ymd.ok()) os.setstate(std::ios::failbit); auto ld = local_days(ymd); #if !ONLY_C_LOCALE if (modified == CharT{}) #endif { auto st = local_days(Sunday[1]/January/ymd.year()); if (ld < st) os << CharT{'0'} << CharT{'0'}; else { auto wn = duration_cast(ld - st).count() + 1; if (wn < 10) os << CharT{'0'}; os << wn; } } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { const CharT f[] = {'%', modified, *fmt}; tm.tm_year = static_cast(ymd.year()) - 1900; tm.tm_wday = static_cast(extract_weekday(os, fds)); if (os.fail()) return os; tm.tm_yday = static_cast((ld - local_days(ymd.year()/1/1)).count()); facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); } #endif } modified = CharT{}; command = nullptr; } else os << *fmt; break; case 'V': if (command) { if (modified == CharT{'E'}) os << CharT{'%'} << modified << *fmt; else { if (!fds.ymd.ok()) os.setstate(std::ios::failbit); auto ld = local_days(fds.ymd); #if !ONLY_C_LOCALE if (modified == CharT{}) #endif { auto y = year_month_day{ld + days{3}}.year(); auto st = local_days((y-years{1})/12/Thursday[last]) + (Monday-Thursday); if (ld < st) { --y; st = local_days((y - years{1})/12/Thursday[last]) + (Monday-Thursday); } auto wn = duration_cast(ld - st).count() + 1; if (wn < 10) os << CharT{'0'}; os << wn; } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { const CharT f[] = {'%', modified, *fmt}; auto const& ymd = fds.ymd; tm.tm_year = static_cast(ymd.year()) - 1900; tm.tm_wday = static_cast(extract_weekday(os, fds)); if (os.fail()) return os; tm.tm_yday = static_cast((ld - local_days(ymd.year()/1/1)).count()); facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); } #endif } modified = CharT{}; command = nullptr; } else os << *fmt; break; case 'w': if (command) { auto wd = extract_weekday(os, fds); if (os.fail()) return os; #if !ONLY_C_LOCALE if (modified == CharT{}) #else if (modified != CharT{'E'}) #endif { os << wd; } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { const CharT f[] = {'%', modified, *fmt}; tm.tm_wday = static_cast(wd); facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); } #endif else { os << CharT{'%'} << modified << *fmt; } modified = CharT{}; command = nullptr; } else os << *fmt; break; case 'W': if (command) { if (modified == CharT{'E'}) os << CharT{'%'} << modified << *fmt; else { auto const& ymd = fds.ymd; if (!ymd.ok()) os.setstate(std::ios::failbit); auto ld = local_days(ymd); #if !ONLY_C_LOCALE if (modified == CharT{}) #endif { auto st = local_days(Monday[1]/January/ymd.year()); if (ld < st) os << CharT{'0'} << CharT{'0'}; else { auto wn = duration_cast(ld - st).count() + 1; if (wn < 10) os << CharT{'0'}; os << wn; } } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { const CharT f[] = {'%', modified, *fmt}; tm.tm_year = static_cast(ymd.year()) - 1900; tm.tm_wday = static_cast(extract_weekday(os, fds)); if (os.fail()) return os; tm.tm_yday = static_cast((ld - local_days(ymd.year()/1/1)).count()); facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); } #endif } modified = CharT{}; command = nullptr; } else os << *fmt; break; case 'X': if (command) { if (modified == CharT{'O'}) os << CharT{'%'} << modified << *fmt; else { if (!fds.has_tod) os.setstate(std::ios::failbit); #if !ONLY_C_LOCALE tm = std::tm{}; tm.tm_sec = static_cast(fds.tod.seconds().count()); tm.tm_min = static_cast(fds.tod.minutes().count()); tm.tm_hour = static_cast(fds.tod.hours().count()); CharT f[3] = {'%'}; auto fe = std::begin(f) + 1; if (modified == CharT{'E'}) *fe++ = modified; *fe++ = *fmt; facet.put(os, os, os.fill(), &tm, std::begin(f), fe); #else os << fds.tod; #endif } command = nullptr; modified = CharT{}; } else os << *fmt; break; case 'y': if (command) { if (!fds.ymd.year().ok()) os.setstate(std::ios::failbit); auto y = static_cast(fds.ymd.year()); #if !ONLY_C_LOCALE if (modified == CharT{}) { #endif y = std::abs(y) % 100; if (y < 10) os << CharT{'0'}; os << y; #if !ONLY_C_LOCALE } else { const CharT f[] = {'%', modified, *fmt}; tm.tm_year = y - 1900; facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); } #endif modified = CharT{}; command = nullptr; } else os << *fmt; break; case 'Y': if (command) { if (modified == CharT{'O'}) os << CharT{'%'} << modified << *fmt; else { if (!fds.ymd.year().ok()) os.setstate(std::ios::failbit); auto y = fds.ymd.year(); #if !ONLY_C_LOCALE if (modified == CharT{}) #endif { save_ostream _(os); os.imbue(std::locale::classic()); os << y; } #if !ONLY_C_LOCALE else if (modified == CharT{'E'}) { const CharT f[] = {'%', modified, *fmt}; tm.tm_year = static_cast(y) - 1900; facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f)); } #endif } modified = CharT{}; command = nullptr; } else os << *fmt; break; case 'z': if (command) { if (offset_sec == nullptr) { // Can not format %z with unknown offset os.setstate(ios::failbit); return os; } auto m = duration_cast(*offset_sec); auto neg = m < minutes{0}; m = date::abs(m); auto h = duration_cast(m); m -= h; if (neg) os << CharT{'-'}; else os << CharT{'+'}; if (h < hours{10}) os << CharT{'0'}; os << h.count(); if (modified != CharT{}) os << CharT{':'}; if (m < minutes{10}) os << CharT{'0'}; os << m.count(); command = nullptr; modified = CharT{}; } else os << *fmt; break; case 'Z': if (command) { if (modified == CharT{}) { if (abbrev == nullptr) { // Can not format %Z with unknown time_zone os.setstate(ios::failbit); return os; } for (auto c : *abbrev) os << CharT(c); } else { os << CharT{'%'} << modified << *fmt; modified = CharT{}; } command = nullptr; } else os << *fmt; break; case 'E': case 'O': if (command) { if (modified == CharT{}) { modified = *fmt; } else { os << CharT{'%'} << modified << *fmt; command = nullptr; modified = CharT{}; } } else os << *fmt; break; case '%': if (command) { if (modified == CharT{}) { os << CharT{'%'}; command = nullptr; } else { os << CharT{'%'} << modified << CharT{'%'}; command = nullptr; modified = CharT{}; } } else command = fmt; break; default: if (command) { os << CharT{'%'}; command = nullptr; } if (modified != CharT{}) { os << modified; modified = CharT{}; } os << *fmt; break; } } if (command) os << CharT{'%'}; if (modified != CharT{}) os << modified; return os; } template inline std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const year& y) { using CT = std::chrono::seconds; fields fds{y/0/0}; return to_stream(os, fmt, fds); } template inline std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const month& m) { using CT = std::chrono::seconds; fields fds{m/0/nanyear}; return to_stream(os, fmt, fds); } template inline std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const day& d) { using CT = std::chrono::seconds; fields fds{d/0/nanyear}; return to_stream(os, fmt, fds); } template inline std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const weekday& wd) { using CT = std::chrono::seconds; fields fds{wd}; return to_stream(os, fmt, fds); } template inline std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const year_month& ym) { using CT = std::chrono::seconds; fields fds{ym/0}; return to_stream(os, fmt, fds); } template inline std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const month_day& md) { using CT = std::chrono::seconds; fields fds{md/nanyear}; return to_stream(os, fmt, fds); } template inline std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const year_month_day& ymd) { using CT = std::chrono::seconds; fields fds{ymd}; return to_stream(os, fmt, fds); } template inline std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const std::chrono::duration& d) { using Duration = std::chrono::duration; using CT = typename std::common_type::type; fields fds{hh_mm_ss{d}}; return to_stream(os, fmt, fds); } template std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const local_time& tp, const std::string* abbrev = nullptr, const std::chrono::seconds* offset_sec = nullptr) { using CT = typename std::common_type::type; auto ld = floor(tp); fields fds{year_month_day{ld}, hh_mm_ss{tp-local_seconds{ld}}}; return to_stream(os, fmt, fds, abbrev, offset_sec); } template std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const sys_time& tp) { using std::chrono::seconds; using CT = typename std::common_type::type; const std::string abbrev("UTC"); CONSTDATA seconds offset{0}; auto sd = floor(tp); fields fds{year_month_day{sd}, hh_mm_ss{tp-sys_seconds{sd}}}; return to_stream(os, fmt, fds, &abbrev, &offset); } // format template auto format(const std::locale& loc, const CharT* fmt, const Streamable& tp) -> decltype(to_stream(std::declval&>(), fmt, tp), std::basic_string{}) { std::basic_ostringstream os; os.exceptions(std::ios::failbit | std::ios::badbit); os.imbue(loc); to_stream(os, fmt, tp); return os.str(); } template auto format(const CharT* fmt, const Streamable& tp) -> decltype(to_stream(std::declval&>(), fmt, tp), std::basic_string{}) { std::basic_ostringstream os; os.exceptions(std::ios::failbit | std::ios::badbit); to_stream(os, fmt, tp); return os.str(); } template auto format(const std::locale& loc, const std::basic_string& fmt, const Streamable& tp) -> decltype(to_stream(std::declval&>(), fmt.c_str(), tp), std::basic_string{}) { std::basic_ostringstream os; os.exceptions(std::ios::failbit | std::ios::badbit); os.imbue(loc); to_stream(os, fmt.c_str(), tp); return os.str(); } template auto format(const std::basic_string& fmt, const Streamable& tp) -> decltype(to_stream(std::declval&>(), fmt.c_str(), tp), std::basic_string{}) { std::basic_ostringstream os; os.exceptions(std::ios::failbit | std::ios::badbit); to_stream(os, fmt.c_str(), tp); return os.str(); } // parse namespace detail { template bool read_char(std::basic_istream& is, CharT fmt, std::ios::iostate& err) { auto ic = is.get(); if (Traits::eq_int_type(ic, Traits::eof()) || !Traits::eq(Traits::to_char_type(ic), fmt)) { err |= std::ios::failbit; is.setstate(std::ios::failbit); return false; } return true; } template unsigned read_unsigned(std::basic_istream& is, unsigned m = 1, unsigned M = 10) { unsigned x = 0; unsigned count = 0; while (true) { auto ic = is.peek(); if (Traits::eq_int_type(ic, Traits::eof())) break; auto c = static_cast(Traits::to_char_type(ic)); if (!('0' <= c && c <= '9')) break; (void)is.get(); ++count; x = 10*x + static_cast(c - '0'); if (count == M) break; } if (count < m) is.setstate(std::ios::failbit); return x; } template int read_signed(std::basic_istream& is, unsigned m = 1, unsigned M = 10) { auto ic = is.peek(); if (!Traits::eq_int_type(ic, Traits::eof())) { auto c = static_cast(Traits::to_char_type(ic)); if (('0' <= c && c <= '9') || c == '-' || c == '+') { if (c == '-' || c == '+') (void)is.get(); auto x = static_cast(read_unsigned(is, std::max(m, 1u), M)); if (!is.fail()) { if (c == '-') x = -x; return x; } } } if (m > 0) is.setstate(std::ios::failbit); return 0; } template long double read_long_double(std::basic_istream& is, unsigned m = 1, unsigned M = 10) { unsigned count = 0; unsigned fcount = 0; unsigned long long i = 0; unsigned long long f = 0; bool parsing_fraction = false; #if ONLY_C_LOCALE typename Traits::int_type decimal_point = '.'; #else auto decimal_point = Traits::to_int_type( std::use_facet>(is.getloc()).decimal_point()); #endif while (true) { auto ic = is.peek(); if (Traits::eq_int_type(ic, Traits::eof())) break; if (Traits::eq_int_type(ic, decimal_point)) { decimal_point = Traits::eof(); parsing_fraction = true; } else { auto c = static_cast(Traits::to_char_type(ic)); if (!('0' <= c && c <= '9')) break; if (!parsing_fraction) { i = 10*i + static_cast(c - '0'); } else { f = 10*f + static_cast(c - '0'); ++fcount; } } (void)is.get(); if (++count == M) break; } if (count < m) { is.setstate(std::ios::failbit); return 0; } return i + f/std::pow(10.L, fcount); } struct rs { int& i; unsigned m; unsigned M; }; struct ru { int& i; unsigned m; unsigned M; }; struct rld { long double& i; unsigned m; unsigned M; }; template void read(std::basic_istream&) { } template void read(std::basic_istream& is, CharT a0, Args&& ...args); template void read(std::basic_istream& is, rs a0, Args&& ...args); template void read(std::basic_istream& is, ru a0, Args&& ...args); template void read(std::basic_istream& is, int a0, Args&& ...args); template void read(std::basic_istream& is, rld a0, Args&& ...args); template void read(std::basic_istream& is, CharT a0, Args&& ...args) { // No-op if a0 == CharT{} if (a0 != CharT{}) { auto ic = is.peek(); if (Traits::eq_int_type(ic, Traits::eof())) { is.setstate(std::ios::failbit | std::ios::eofbit); return; } if (!Traits::eq(Traits::to_char_type(ic), a0)) { is.setstate(std::ios::failbit); return; } (void)is.get(); } read(is, std::forward(args)...); } template void read(std::basic_istream& is, rs a0, Args&& ...args) { auto x = read_signed(is, a0.m, a0.M); if (is.fail()) return; a0.i = x; read(is, std::forward(args)...); } template void read(std::basic_istream& is, ru a0, Args&& ...args) { auto x = read_unsigned(is, a0.m, a0.M); if (is.fail()) return; a0.i = static_cast(x); read(is, std::forward(args)...); } template void read(std::basic_istream& is, int a0, Args&& ...args) { if (a0 != -1) { auto u = static_cast(a0); CharT buf[std::numeric_limits::digits10+2u] = {}; auto e = buf; do { *e++ = static_cast(CharT(u % 10) + CharT{'0'}); u /= 10; } while (u > 0); std::reverse(buf, e); for (auto p = buf; p != e && is.rdstate() == std::ios::goodbit; ++p) read(is, *p); } if (is.rdstate() == std::ios::goodbit) read(is, std::forward(args)...); } template void read(std::basic_istream& is, rld a0, Args&& ...args) { auto x = read_long_double(is, a0.m, a0.M); if (is.fail()) return; a0.i = x; read(is, std::forward(args)...); } template inline void checked_set(T& value, T from, T not_a_value, std::basic_ios& is) { if (!is.fail()) { if (value == not_a_value) value = std::move(from); else if (value != from) is.setstate(std::ios::failbit); } } } // namespace detail; template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, fields& fds, std::basic_string* abbrev, std::chrono::minutes* offset) { using std::numeric_limits; using std::ios; using std::chrono::duration; using std::chrono::duration_cast; using std::chrono::seconds; using std::chrono::minutes; using std::chrono::hours; using detail::round_i; typename std::basic_istream::sentry ok{is, true}; if (ok) { date::detail::save_istream ss(is); is.fill(' '); is.flags(std::ios::skipws | std::ios::dec); is.width(0); #if !ONLY_C_LOCALE auto& f = std::use_facet>(is.getloc()); std::tm tm{}; #endif const CharT* command = nullptr; auto modified = CharT{}; auto width = -1; CONSTDATA int not_a_year = numeric_limits::min(); CONSTDATA int not_a_2digit_year = 100; CONSTDATA int not_a_century = not_a_year / 100; CONSTDATA int not_a_month = 0; CONSTDATA int not_a_day = 0; CONSTDATA int not_a_hour = numeric_limits::min(); CONSTDATA int not_a_hour_12_value = 0; CONSTDATA int not_a_minute = not_a_hour; CONSTDATA Duration not_a_second = Duration::min(); CONSTDATA int not_a_doy = -1; CONSTDATA int not_a_weekday = 8; CONSTDATA int not_a_week_num = 100; CONSTDATA int not_a_ampm = -1; CONSTDATA minutes not_a_offset = minutes::min(); int Y = not_a_year; // c, F, Y * int y = not_a_2digit_year; // D, x, y * int g = not_a_2digit_year; // g * int G = not_a_year; // G * int C = not_a_century; // C * int m = not_a_month; // b, B, h, m, c, D, F, x * int d = not_a_day; // c, d, D, e, F, x * int j = not_a_doy; // j * int wd = not_a_weekday; // a, A, u, w * int H = not_a_hour; // c, H, R, T, X * int I = not_a_hour_12_value; // I, r * int p = not_a_ampm; // p, r * int M = not_a_minute; // c, M, r, R, T, X * Duration s = not_a_second; // c, r, S, T, X * int U = not_a_week_num; // U * int V = not_a_week_num; // V * int W = not_a_week_num; // W * std::basic_string temp_abbrev; // Z * minutes temp_offset = not_a_offset; // z * using detail::read; using detail::rs; using detail::ru; using detail::rld; using detail::checked_set; for (; *fmt != CharT{} && !is.fail(); ++fmt) { switch (*fmt) { case 'a': case 'A': case 'u': case 'w': // wd: a, A, u, w if (command) { int trial_wd = not_a_weekday; if (*fmt == 'a' || *fmt == 'A') { if (modified == CharT{}) { #if !ONLY_C_LOCALE ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); is.setstate(err); if (!is.fail()) trial_wd = tm.tm_wday; #else auto nm = detail::weekday_names(); auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; if (!is.fail()) trial_wd = i % 7; #endif } else read(is, CharT{'%'}, width, modified, *fmt); } else // *fmt == 'u' || *fmt == 'w' { #if !ONLY_C_LOCALE if (modified == CharT{}) #else if (modified != CharT{'E'}) #endif { read(is, ru{trial_wd, 1, width == -1 ? 1u : static_cast(width)}); if (!is.fail()) { if (*fmt == 'u') { if (!(1 <= trial_wd && trial_wd <= 7)) { trial_wd = not_a_weekday; is.setstate(ios::failbit); } else if (trial_wd == 7) trial_wd = 0; } else // *fmt == 'w' { if (!(0 <= trial_wd && trial_wd <= 6)) { trial_wd = not_a_weekday; is.setstate(ios::failbit); } } } } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); is.setstate(err); if (!is.fail()) trial_wd = tm.tm_wday; } #endif else read(is, CharT{'%'}, width, modified, *fmt); } if (trial_wd != not_a_weekday) checked_set(wd, trial_wd, not_a_weekday, is); } else // !command read(is, *fmt); command = nullptr; width = -1; modified = CharT{}; break; case 'b': case 'B': case 'h': if (command) { if (modified == CharT{}) { int ttm = not_a_month; #if !ONLY_C_LOCALE ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); if ((err & ios::failbit) == 0) ttm = tm.tm_mon + 1; is.setstate(err); #else auto nm = detail::month_names(); auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; if (!is.fail()) ttm = i % 12 + 1; #endif checked_set(m, ttm, not_a_month, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'c': if (command) { if (modified != CharT{'O'}) { #if !ONLY_C_LOCALE ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); if ((err & ios::failbit) == 0) { checked_set(Y, tm.tm_year + 1900, not_a_year, is); checked_set(m, tm.tm_mon + 1, not_a_month, is); checked_set(d, tm.tm_mday, not_a_day, is); checked_set(H, tm.tm_hour, not_a_hour, is); checked_set(M, tm.tm_min, not_a_minute, is); checked_set(s, duration_cast(seconds{tm.tm_sec}), not_a_second, is); } is.setstate(err); #else // "%a %b %e %T %Y" auto nm = detail::weekday_names(); auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; checked_set(wd, static_cast(i % 7), not_a_weekday, is); ws(is); nm = detail::month_names(); i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; checked_set(m, static_cast(i % 12 + 1), not_a_month, is); ws(is); int td = not_a_day; read(is, rs{td, 1, 2}); checked_set(d, td, not_a_day, is); ws(is); using dfs = detail::decimal_format_seconds; CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; int tH; int tM; long double S; read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, CharT{':'}, rld{S, 1, w}); checked_set(H, tH, not_a_hour, is); checked_set(M, tM, not_a_minute, is); checked_set(s, round_i(duration{S}), not_a_second, is); ws(is); int tY = not_a_year; read(is, rs{tY, 1, 4u}); checked_set(Y, tY, not_a_year, is); #endif } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'x': if (command) { if (modified != CharT{'O'}) { #if !ONLY_C_LOCALE ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); if ((err & ios::failbit) == 0) { checked_set(Y, tm.tm_year + 1900, not_a_year, is); checked_set(m, tm.tm_mon + 1, not_a_month, is); checked_set(d, tm.tm_mday, not_a_day, is); } is.setstate(err); #else // "%m/%d/%y" int ty = not_a_2digit_year; int tm = not_a_month; int td = not_a_day; read(is, ru{tm, 1, 2}, CharT{'/'}, ru{td, 1, 2}, CharT{'/'}, rs{ty, 1, 2}); checked_set(y, ty, not_a_2digit_year, is); checked_set(m, tm, not_a_month, is); checked_set(d, td, not_a_day, is); #endif } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'X': if (command) { if (modified != CharT{'O'}) { #if !ONLY_C_LOCALE ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); if ((err & ios::failbit) == 0) { checked_set(H, tm.tm_hour, not_a_hour, is); checked_set(M, tm.tm_min, not_a_minute, is); checked_set(s, duration_cast(seconds{tm.tm_sec}), not_a_second, is); } is.setstate(err); #else // "%T" using dfs = detail::decimal_format_seconds; CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; int tH = not_a_hour; int tM = not_a_minute; long double S; read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, CharT{':'}, rld{S, 1, w}); checked_set(H, tH, not_a_hour, is); checked_set(M, tM, not_a_minute, is); checked_set(s, round_i(duration{S}), not_a_second, is); #endif } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'C': if (command) { int tC = not_a_century; #if !ONLY_C_LOCALE if (modified == CharT{}) { #endif read(is, rs{tC, 1, width == -1 ? 2u : static_cast(width)}); #if !ONLY_C_LOCALE } else { ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); if ((err & ios::failbit) == 0) { auto tY = tm.tm_year + 1900; tC = (tY >= 0 ? tY : tY-99) / 100; } is.setstate(err); } #endif checked_set(C, tC, not_a_century, is); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'D': if (command) { if (modified == CharT{}) { int tn = not_a_month; int td = not_a_day; int ty = not_a_2digit_year; read(is, ru{tn, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'}, ru{td, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'}, rs{ty, 1, 2}); checked_set(y, ty, not_a_2digit_year, is); checked_set(m, tn, not_a_month, is); checked_set(d, td, not_a_day, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'F': if (command) { if (modified == CharT{}) { int tY = not_a_year; int tn = not_a_month; int td = not_a_day; read(is, rs{tY, 1, width == -1 ? 4u : static_cast(width)}, CharT{'-'}, ru{tn, 1, 2}, CharT{'-'}, ru{td, 1, 2}); checked_set(Y, tY, not_a_year, is); checked_set(m, tn, not_a_month, is); checked_set(d, td, not_a_day, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'd': case 'e': if (command) { #if !ONLY_C_LOCALE if (modified == CharT{}) #else if (modified != CharT{'E'}) #endif { int td = not_a_day; read(is, rs{td, 1, width == -1 ? 2u : static_cast(width)}); checked_set(d, td, not_a_day, is); } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); command = nullptr; width = -1; modified = CharT{}; if ((err & ios::failbit) == 0) checked_set(d, tm.tm_mday, not_a_day, is); is.setstate(err); } #endif else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'H': if (command) { #if !ONLY_C_LOCALE if (modified == CharT{}) #else if (modified != CharT{'E'}) #endif { int tH = not_a_hour; read(is, ru{tH, 1, width == -1 ? 2u : static_cast(width)}); checked_set(H, tH, not_a_hour, is); } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); if ((err & ios::failbit) == 0) checked_set(H, tm.tm_hour, not_a_hour, is); is.setstate(err); } #endif else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'I': if (command) { if (modified == CharT{}) { int tI = not_a_hour_12_value; // reads in an hour into I, but most be in [1, 12] read(is, rs{tI, 1, width == -1 ? 2u : static_cast(width)}); if (!(1 <= tI && tI <= 12)) is.setstate(ios::failbit); checked_set(I, tI, not_a_hour_12_value, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'j': if (command) { if (modified == CharT{}) { int tj = not_a_doy; read(is, ru{tj, 1, width == -1 ? 3u : static_cast(width)}); checked_set(j, tj, not_a_doy, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'M': if (command) { #if !ONLY_C_LOCALE if (modified == CharT{}) #else if (modified != CharT{'E'}) #endif { int tM = not_a_minute; read(is, ru{tM, 1, width == -1 ? 2u : static_cast(width)}); checked_set(M, tM, not_a_minute, is); } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); if ((err & ios::failbit) == 0) checked_set(M, tm.tm_min, not_a_minute, is); is.setstate(err); } #endif else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'm': if (command) { #if !ONLY_C_LOCALE if (modified == CharT{}) #else if (modified != CharT{'E'}) #endif { int tn = not_a_month; read(is, rs{tn, 1, width == -1 ? 2u : static_cast(width)}); checked_set(m, tn, not_a_month, is); } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); if ((err & ios::failbit) == 0) checked_set(m, tm.tm_mon + 1, not_a_month, is); is.setstate(err); } #endif else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'n': case 't': if (command) { if (modified == CharT{}) { // %n matches a single white space character // %t matches 0 or 1 white space characters auto ic = is.peek(); if (Traits::eq_int_type(ic, Traits::eof())) { ios::iostate err = ios::eofbit; if (*fmt == 'n') err |= ios::failbit; is.setstate(err); break; } if (isspace(ic)) { (void)is.get(); } else if (*fmt == 'n') is.setstate(ios::failbit); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'p': if (command) { if (modified == CharT{}) { int tp = not_a_ampm; #if !ONLY_C_LOCALE tm = std::tm{}; tm.tm_hour = 1; ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); is.setstate(err); if (tm.tm_hour == 1) tp = 0; else if (tm.tm_hour == 13) tp = 1; else is.setstate(err); #else auto nm = detail::ampm_names(); auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; tp = static_cast(i); #endif checked_set(p, tp, not_a_ampm, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'r': if (command) { if (modified == CharT{}) { #if !ONLY_C_LOCALE ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); if ((err & ios::failbit) == 0) { checked_set(H, tm.tm_hour, not_a_hour, is); checked_set(M, tm.tm_min, not_a_hour, is); checked_set(s, duration_cast(seconds{tm.tm_sec}), not_a_second, is); } is.setstate(err); #else // "%I:%M:%S %p" using dfs = detail::decimal_format_seconds; CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; long double S; int tI = not_a_hour_12_value; int tM = not_a_minute; read(is, ru{tI, 1, 2}, CharT{':'}, ru{tM, 1, 2}, CharT{':'}, rld{S, 1, w}); checked_set(I, tI, not_a_hour_12_value, is); checked_set(M, tM, not_a_minute, is); checked_set(s, round_i(duration{S}), not_a_second, is); ws(is); auto nm = detail::ampm_names(); auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; checked_set(p, static_cast(i), not_a_ampm, is); #endif } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'R': if (command) { if (modified == CharT{}) { int tH = not_a_hour; int tM = not_a_minute; read(is, ru{tH, 1, 2}, CharT{'\0'}, CharT{':'}, CharT{'\0'}, ru{tM, 1, 2}, CharT{'\0'}); checked_set(H, tH, not_a_hour, is); checked_set(M, tM, not_a_minute, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'S': if (command) { #if !ONLY_C_LOCALE if (modified == CharT{}) #else if (modified != CharT{'E'}) #endif { using dfs = detail::decimal_format_seconds; CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; long double S; read(is, rld{S, 1, width == -1 ? w : static_cast(width)}); checked_set(s, round_i(duration{S}), not_a_second, is); } #if !ONLY_C_LOCALE else if (modified == CharT{'O'}) { ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); if ((err & ios::failbit) == 0) checked_set(s, duration_cast(seconds{tm.tm_sec}), not_a_second, is); is.setstate(err); } #endif else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'T': if (command) { if (modified == CharT{}) { using dfs = detail::decimal_format_seconds; CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; int tH = not_a_hour; int tM = not_a_minute; long double S; read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, CharT{':'}, rld{S, 1, w}); checked_set(H, tH, not_a_hour, is); checked_set(M, tM, not_a_minute, is); checked_set(s, round_i(duration{S}), not_a_second, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'Y': if (command) { #if !ONLY_C_LOCALE if (modified == CharT{}) #else if (modified != CharT{'O'}) #endif { int tY = not_a_year; read(is, rs{tY, 1, width == -1 ? 4u : static_cast(width)}); checked_set(Y, tY, not_a_year, is); } #if !ONLY_C_LOCALE else if (modified == CharT{'E'}) { ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); if ((err & ios::failbit) == 0) checked_set(Y, tm.tm_year + 1900, not_a_year, is); is.setstate(err); } #endif else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'y': if (command) { #if !ONLY_C_LOCALE if (modified == CharT{}) #endif { int ty = not_a_2digit_year; read(is, ru{ty, 1, width == -1 ? 2u : static_cast(width)}); checked_set(y, ty, not_a_2digit_year, is); } #if !ONLY_C_LOCALE else { ios::iostate err = ios::goodbit; f.get(is, nullptr, is, err, &tm, command, fmt+1); if ((err & ios::failbit) == 0) checked_set(Y, tm.tm_year + 1900, not_a_year, is); is.setstate(err); } #endif command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'g': if (command) { if (modified == CharT{}) { int tg = not_a_2digit_year; read(is, ru{tg, 1, width == -1 ? 2u : static_cast(width)}); checked_set(g, tg, not_a_2digit_year, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'G': if (command) { if (modified == CharT{}) { int tG = not_a_year; read(is, rs{tG, 1, width == -1 ? 4u : static_cast(width)}); checked_set(G, tG, not_a_year, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'U': if (command) { if (modified == CharT{}) { int tU = not_a_week_num; read(is, ru{tU, 1, width == -1 ? 2u : static_cast(width)}); checked_set(U, tU, not_a_week_num, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'V': if (command) { if (modified == CharT{}) { int tV = not_a_week_num; read(is, ru{tV, 1, width == -1 ? 2u : static_cast(width)}); checked_set(V, tV, not_a_week_num, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'W': if (command) { if (modified == CharT{}) { int tW = not_a_week_num; read(is, ru{tW, 1, width == -1 ? 2u : static_cast(width)}); checked_set(W, tW, not_a_week_num, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'E': case 'O': if (command) { if (modified == CharT{}) { modified = *fmt; } else { read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } } else read(is, *fmt); break; case '%': if (command) { if (modified == CharT{}) read(is, *fmt); else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else command = fmt; break; case 'z': if (command) { int tH, tM; minutes toff = not_a_offset; bool neg = false; auto ic = is.peek(); if (!Traits::eq_int_type(ic, Traits::eof())) { auto c = static_cast(Traits::to_char_type(ic)); if (c == '-') neg = true; } if (modified == CharT{}) { read(is, rs{tH, 2, 2}); if (!is.fail()) toff = hours{std::abs(tH)}; if (is.good()) { ic = is.peek(); if (!Traits::eq_int_type(ic, Traits::eof())) { auto c = static_cast(Traits::to_char_type(ic)); if ('0' <= c && c <= '9') { read(is, ru{tM, 2, 2}); if (!is.fail()) toff += minutes{tM}; } } } } else { read(is, rs{tH, 1, 2}); if (!is.fail()) toff = hours{std::abs(tH)}; if (is.good()) { ic = is.peek(); if (!Traits::eq_int_type(ic, Traits::eof())) { auto c = static_cast(Traits::to_char_type(ic)); if (c == ':') { (void)is.get(); read(is, ru{tM, 2, 2}); if (!is.fail()) toff += minutes{tM}; } } } } if (neg) toff = -toff; checked_set(temp_offset, toff, not_a_offset, is); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; case 'Z': if (command) { if (modified == CharT{}) { std::basic_string buf; while (is.rdstate() == std::ios::goodbit) { auto i = is.rdbuf()->sgetc(); if (Traits::eq_int_type(i, Traits::eof())) { is.setstate(ios::eofbit); break; } auto wc = Traits::to_char_type(i); auto c = static_cast(wc); // is c a valid time zone name or abbreviation character? if (!(CharT{1} < wc && wc < CharT{127}) || !(isalnum(c) || c == '_' || c == '/' || c == '-' || c == '+')) break; buf.push_back(c); is.rdbuf()->sbumpc(); } if (buf.empty()) is.setstate(ios::failbit); checked_set(temp_abbrev, buf, {}, is); } else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } else read(is, *fmt); break; default: if (command) { if (width == -1 && modified == CharT{} && '0' <= *fmt && *fmt <= '9') { width = static_cast(*fmt) - '0'; while ('0' <= fmt[1] && fmt[1] <= '9') width = 10*width + static_cast(*++fmt) - '0'; } else { if (modified == CharT{}) read(is, CharT{'%'}, width, *fmt); else read(is, CharT{'%'}, width, modified, *fmt); command = nullptr; width = -1; modified = CharT{}; } } else // !command { if (isspace(static_cast(*fmt))) { // space matches 0 or more white space characters if (is.good()) ws(is); } else read(is, *fmt); } break; } } // is.fail() || *fmt == CharT{} if (is.rdstate() == ios::goodbit && command) { if (modified == CharT{}) read(is, CharT{'%'}, width); else read(is, CharT{'%'}, width, modified); } if (!is.fail()) { if (y != not_a_2digit_year) { // Convert y and an optional C to Y if (!(0 <= y && y <= 99)) goto broken; if (C == not_a_century) { if (Y == not_a_year) { if (y >= 69) C = 19; else C = 20; } else { C = (Y >= 0 ? Y : Y-100) / 100; } } int tY; if (C >= 0) tY = 100*C + y; else tY = 100*(C+1) - (y == 0 ? 100 : y); if (Y != not_a_year && Y != tY) goto broken; Y = tY; } if (g != not_a_2digit_year) { // Convert g and an optional C to G if (!(0 <= g && g <= 99)) goto broken; if (C == not_a_century) { if (G == not_a_year) { if (g >= 69) C = 19; else C = 20; } else { C = (G >= 0 ? G : G-100) / 100; } } int tG; if (C >= 0) tG = 100*C + g; else tG = 100*(C+1) - (g == 0 ? 100 : g); if (G != not_a_year && G != tG) goto broken; G = tG; } if (Y < static_cast(year::min()) || Y > static_cast(year::max())) Y = not_a_year; bool computed = false; if (G != not_a_year && V != not_a_week_num && wd != not_a_weekday) { year_month_day ymd_trial = sys_days(year{G-1}/December/Thursday[last]) + (Monday-Thursday) + weeks{V-1} + (weekday{static_cast(wd)}-Monday); if (Y == not_a_year) Y = static_cast(ymd_trial.year()); else if (year{Y} != ymd_trial.year()) goto broken; if (m == not_a_month) m = static_cast(static_cast(ymd_trial.month())); else if (month(static_cast(m)) != ymd_trial.month()) goto broken; if (d == not_a_day) d = static_cast(static_cast(ymd_trial.day())); else if (day(static_cast(d)) != ymd_trial.day()) goto broken; computed = true; } if (Y != not_a_year && U != not_a_week_num && wd != not_a_weekday) { year_month_day ymd_trial = sys_days(year{Y}/January/Sunday[1]) + weeks{U-1} + (weekday{static_cast(wd)} - Sunday); if (Y == not_a_year) Y = static_cast(ymd_trial.year()); else if (year{Y} != ymd_trial.year()) goto broken; if (m == not_a_month) m = static_cast(static_cast(ymd_trial.month())); else if (month(static_cast(m)) != ymd_trial.month()) goto broken; if (d == not_a_day) d = static_cast(static_cast(ymd_trial.day())); else if (day(static_cast(d)) != ymd_trial.day()) goto broken; computed = true; } if (Y != not_a_year && W != not_a_week_num && wd != not_a_weekday) { year_month_day ymd_trial = sys_days(year{Y}/January/Monday[1]) + weeks{W-1} + (weekday{static_cast(wd)} - Monday); if (Y == not_a_year) Y = static_cast(ymd_trial.year()); else if (year{Y} != ymd_trial.year()) goto broken; if (m == not_a_month) m = static_cast(static_cast(ymd_trial.month())); else if (month(static_cast(m)) != ymd_trial.month()) goto broken; if (d == not_a_day) d = static_cast(static_cast(ymd_trial.day())); else if (day(static_cast(d)) != ymd_trial.day()) goto broken; computed = true; } if (j != not_a_doy && Y != not_a_year) { auto ymd_trial = year_month_day{local_days(year{Y}/1/1) + days{j-1}}; if (m == 0) m = static_cast(static_cast(ymd_trial.month())); else if (month(static_cast(m)) != ymd_trial.month()) goto broken; if (d == 0) d = static_cast(static_cast(ymd_trial.day())); else if (day(static_cast(d)) != ymd_trial.day()) goto broken; j = not_a_doy; } auto ymd = year{Y}/m/d; if (ymd.ok()) { if (wd == not_a_weekday) wd = static_cast((weekday(sys_days(ymd)) - Sunday).count()); else if (wd != static_cast((weekday(sys_days(ymd)) - Sunday).count())) goto broken; if (!computed) { if (G != not_a_year || V != not_a_week_num) { sys_days sd = ymd; auto G_trial = year_month_day{sd + days{3}}.year(); auto start = sys_days((G_trial - years{1})/December/Thursday[last]) + (Monday - Thursday); if (sd < start) { --G_trial; if (V != not_a_week_num) start = sys_days((G_trial - years{1})/December/Thursday[last]) + (Monday - Thursday); } if (G != not_a_year && G != static_cast(G_trial)) goto broken; if (V != not_a_week_num) { auto V_trial = duration_cast(sd - start).count() + 1; if (V != V_trial) goto broken; } } if (U != not_a_week_num) { auto start = sys_days(Sunday[1]/January/ymd.year()); auto U_trial = floor(sys_days(ymd) - start).count() + 1; if (U != U_trial) goto broken; } if (W != not_a_week_num) { auto start = sys_days(Monday[1]/January/ymd.year()); auto W_trial = floor(sys_days(ymd) - start).count() + 1; if (W != W_trial) goto broken; } } } fds.ymd = ymd; if (I != not_a_hour_12_value) { if (!(1 <= I && I <= 12)) goto broken; if (p != not_a_ampm) { // p is in [0, 1] == [AM, PM] // Store trial H in I if (I == 12) --p; I += p*12; // Either set H from I or make sure H and I are consistent if (H == not_a_hour) H = I; else if (I != H) goto broken; } else // p == not_a_ampm { // if H, make sure H and I could be consistent if (H != not_a_hour) { if (I == 12) { if (H != 0 && H != 12) goto broken; } else if (!(I == H || I == H+12)) { goto broken; } } else // I is ambiguous, AM or PM? goto broken; } } if (H != not_a_hour) { fds.has_tod = true; fds.tod = hh_mm_ss{hours{H}}; } if (M != not_a_minute) { fds.has_tod = true; fds.tod.m_ = minutes{M}; } if (s != not_a_second) { fds.has_tod = true; fds.tod.s_ = detail::decimal_format_seconds{s}; } if (j != not_a_doy) { fds.has_tod = true; fds.tod.h_ += hours{days{j}}; } if (wd != not_a_weekday) fds.wd = weekday{static_cast(wd)}; if (abbrev != nullptr) *abbrev = std::move(temp_abbrev); if (offset != nullptr && temp_offset != not_a_offset) *offset = temp_offset; } return is; } broken: is.setstate(ios::failbit); return is; } template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, year& y, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { using CT = std::chrono::seconds; fields fds{}; from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.year().ok()) is.setstate(std::ios::failbit); if (!is.fail()) y = fds.ymd.year(); return is; } template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, month& m, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { using CT = std::chrono::seconds; fields fds{}; from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.month().ok()) is.setstate(std::ios::failbit); if (!is.fail()) m = fds.ymd.month(); return is; } template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, day& d, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { using CT = std::chrono::seconds; fields fds{}; from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.day().ok()) is.setstate(std::ios::failbit); if (!is.fail()) d = fds.ymd.day(); return is; } template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, weekday& wd, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { using CT = std::chrono::seconds; fields fds{}; from_stream(is, fmt, fds, abbrev, offset); if (!fds.wd.ok()) is.setstate(std::ios::failbit); if (!is.fail()) wd = fds.wd; return is; } template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, year_month& ym, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { using CT = std::chrono::seconds; fields fds{}; from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.month().ok()) is.setstate(std::ios::failbit); if (!is.fail()) ym = fds.ymd.year()/fds.ymd.month(); return is; } template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, month_day& md, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { using CT = std::chrono::seconds; fields fds{}; from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.month().ok() || !fds.ymd.day().ok()) is.setstate(std::ios::failbit); if (!is.fail()) md = fds.ymd.month()/fds.ymd.day(); return is; } template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, year_month_day& ymd, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { using CT = std::chrono::seconds; fields fds{}; from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.ok()) is.setstate(std::ios::failbit); if (!is.fail()) ymd = fds.ymd; return is; } template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, sys_time& tp, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { using CT = typename std::common_type::type; using detail::round_i; std::chrono::minutes offset_local{}; auto offptr = offset ? offset : &offset_local; fields fds{}; fds.has_tod = true; from_stream(is, fmt, fds, abbrev, offptr); if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) is.setstate(std::ios::failbit); if (!is.fail()) tp = round_i(sys_days(fds.ymd) - *offptr + fds.tod.to_duration()); return is; } template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, local_time& tp, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { using CT = typename std::common_type::type; using detail::round_i; fields fds{}; fds.has_tod = true; from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) is.setstate(std::ios::failbit); if (!is.fail()) tp = round_i(local_seconds{local_days(fds.ymd)} + fds.tod.to_duration()); return is; } template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, std::chrono::duration& d, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { using Duration = std::chrono::duration; using CT = typename std::common_type::type; fields fds{}; from_stream(is, fmt, fds, abbrev, offset); if (!fds.has_tod) is.setstate(std::ios::failbit); if (!is.fail()) d = std::chrono::duration_cast(fds.tod.to_duration()); return is; } template , class Alloc = std::allocator> struct parse_manip { const std::basic_string format_; Parsable& tp_; std::basic_string* abbrev_; std::chrono::minutes* offset_; public: parse_manip(std::basic_string format, Parsable& tp, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) : format_(std::move(format)) , tp_(tp) , abbrev_(abbrev) , offset_(offset) {} }; template std::basic_istream& operator>>(std::basic_istream& is, const parse_manip& x) { return from_stream(is, x.format_.c_str(), x.tp_, x.abbrev_, x.offset_); } template inline auto parse(const std::basic_string& format, Parsable& tp) -> decltype(from_stream(std::declval&>(), format.c_str(), tp), parse_manip{format, tp}) { return {format, tp}; } template inline auto parse(const std::basic_string& format, Parsable& tp, std::basic_string& abbrev) -> decltype(from_stream(std::declval&>(), format.c_str(), tp, &abbrev), parse_manip{format, tp, &abbrev}) { return {format, tp, &abbrev}; } template inline auto parse(const std::basic_string& format, Parsable& tp, std::chrono::minutes& offset) -> decltype(from_stream(std::declval&>(), format.c_str(), tp, std::declval*>(), &offset), parse_manip{format, tp, nullptr, &offset}) { return {format, tp, nullptr, &offset}; } template inline auto parse(const std::basic_string& format, Parsable& tp, std::basic_string& abbrev, std::chrono::minutes& offset) -> decltype(from_stream(std::declval&>(), format.c_str(), tp, &abbrev, &offset), parse_manip{format, tp, &abbrev, &offset}) { return {format, tp, &abbrev, &offset}; } // const CharT* formats template inline auto parse(const CharT* format, Parsable& tp) -> decltype(from_stream(std::declval&>(), format, tp), parse_manip{format, tp}) { return {format, tp}; } template inline auto parse(const CharT* format, Parsable& tp, std::basic_string& abbrev) -> decltype(from_stream(std::declval&>(), format, tp, &abbrev), parse_manip{format, tp, &abbrev}) { return {format, tp, &abbrev}; } template inline auto parse(const CharT* format, Parsable& tp, std::chrono::minutes& offset) -> decltype(from_stream(std::declval&>(), format, tp, std::declval*>(), &offset), parse_manip{format, tp, nullptr, &offset}) { return {format, tp, nullptr, &offset}; } template inline auto parse(const CharT* format, Parsable& tp, std::basic_string& abbrev, std::chrono::minutes& offset) -> decltype(from_stream(std::declval&>(), format, tp, &abbrev, &offset), parse_manip{format, tp, &abbrev, &offset}) { return {format, tp, &abbrev, &offset}; } // duration streaming template inline std::basic_ostream& operator<<(std::basic_ostream& os, const std::chrono::duration& d) { return os << detail::make_string::from(d.count()) + detail::get_units(typename Period::type{}); } } // namespace date #ifdef _MSC_VER # pragma warning(pop) #endif #ifdef __GNUC__ # pragma GCC diagnostic pop #endif #endif // DATE_H date-3.0.1/include/date/ios.h000066400000000000000000000031211403643451100157310ustar00rootroot00000000000000// // ios.h // DateTimeLib // // The MIT License (MIT) // // Copyright (c) 2016 Alexander Kormanovsky // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef ios_hpp #define ios_hpp #if __APPLE__ # include # if TARGET_OS_IPHONE # include namespace date { namespace iOSUtils { std::string get_tzdata_path(); std::string get_current_timezone(); } // namespace iOSUtils } // namespace date # endif // TARGET_OS_IPHONE #else // !__APPLE__ # define TARGET_OS_IPHONE 0 #endif // !__APPLE__ #endif // ios_hpp date-3.0.1/include/date/islamic.h000066400000000000000000002127171403643451100165750ustar00rootroot00000000000000#ifndef ISLAMIC_H #define ISLAMIC_H // The MIT License (MIT) // // Copyright (c) 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // Our apologies. When the previous paragraph was written, lowercase had not yet // been invented (that would involve another several millennia of evolution). // We did not mean to shout. #include "date.h" namespace islamic { // durations using days = date::days; using weeks = date::weeks; using years = std::chrono::duration , days::period>>; using months = std::chrono::duration >>; // time_point using sys_days = date::sys_days; using local_days = date::local_days; // types struct last_spec { explicit last_spec() = default; }; class day; class month; class year; class weekday; class weekday_indexed; class weekday_last; class month_day; class month_day_last; class month_weekday; class month_weekday_last; class year_month; class year_month_day; class year_month_day_last; class year_month_weekday; class year_month_weekday_last; // date composition operators CONSTCD11 year_month operator/(const year& y, const month& m) NOEXCEPT; CONSTCD11 year_month operator/(const year& y, int m) NOEXCEPT; CONSTCD11 month_day operator/(const day& d, const month& m) NOEXCEPT; CONSTCD11 month_day operator/(const day& d, int m) NOEXCEPT; CONSTCD11 month_day operator/(const month& m, const day& d) NOEXCEPT; CONSTCD11 month_day operator/(const month& m, int d) NOEXCEPT; CONSTCD11 month_day operator/(int m, const day& d) NOEXCEPT; CONSTCD11 month_day_last operator/(const month& m, last_spec) NOEXCEPT; CONSTCD11 month_day_last operator/(int m, last_spec) NOEXCEPT; CONSTCD11 month_day_last operator/(last_spec, const month& m) NOEXCEPT; CONSTCD11 month_day_last operator/(last_spec, int m) NOEXCEPT; CONSTCD11 month_weekday operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT; CONSTCD11 month_weekday operator/(int m, const weekday_indexed& wdi) NOEXCEPT; CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT; CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, int m) NOEXCEPT; CONSTCD11 month_weekday_last operator/(const month& m, const weekday_last& wdl) NOEXCEPT; CONSTCD11 month_weekday_last operator/(int m, const weekday_last& wdl) NOEXCEPT; CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, const month& m) NOEXCEPT; CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, int m) NOEXCEPT; CONSTCD11 year_month_day operator/(const year_month& ym, const day& d) NOEXCEPT; CONSTCD11 year_month_day operator/(const year_month& ym, int d) NOEXCEPT; CONSTCD11 year_month_day operator/(const year& y, const month_day& md) NOEXCEPT; CONSTCD11 year_month_day operator/(int y, const month_day& md) NOEXCEPT; CONSTCD11 year_month_day operator/(const month_day& md, const year& y) NOEXCEPT; CONSTCD11 year_month_day operator/(const month_day& md, int y) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const year_month& ym, last_spec) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const year& y, const month_day_last& mdl) NOEXCEPT; CONSTCD11 year_month_day_last operator/(int y, const month_day_last& mdl) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const month_day_last& mdl, const year& y) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const month_day_last& mdl, int y) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const year& y, const month_weekday& mwd) NOEXCEPT; CONSTCD11 year_month_weekday operator/(int y, const month_weekday& mwd) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const month_weekday& mwd, const year& y) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const month_weekday& mwd, int y) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(int y, const month_weekday_last& mwdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) NOEXCEPT; // Detailed interface // day class day { unsigned char d_; public: explicit CONSTCD11 day(unsigned d) NOEXCEPT; CONSTCD14 day& operator++() NOEXCEPT; CONSTCD14 day operator++(int) NOEXCEPT; CONSTCD14 day& operator--() NOEXCEPT; CONSTCD14 day operator--(int) NOEXCEPT; CONSTCD14 day& operator+=(const days& d) NOEXCEPT; CONSTCD14 day& operator-=(const days& d) NOEXCEPT; CONSTCD11 explicit operator unsigned() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator!=(const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator< (const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator> (const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator<=(const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator>=(const day& x, const day& y) NOEXCEPT; CONSTCD11 day operator+(const day& x, const days& y) NOEXCEPT; CONSTCD11 day operator+(const days& x, const day& y) NOEXCEPT; CONSTCD11 day operator-(const day& x, const days& y) NOEXCEPT; CONSTCD11 days operator-(const day& x, const day& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const day& d); // month class month { unsigned char m_; public: explicit CONSTCD11 month(unsigned m) NOEXCEPT; CONSTCD14 month& operator++() NOEXCEPT; CONSTCD14 month operator++(int) NOEXCEPT; CONSTCD14 month& operator--() NOEXCEPT; CONSTCD14 month operator--(int) NOEXCEPT; CONSTCD14 month& operator+=(const months& m) NOEXCEPT; CONSTCD14 month& operator-=(const months& m) NOEXCEPT; CONSTCD11 explicit operator unsigned() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator!=(const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator< (const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator> (const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator<=(const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator>=(const month& x, const month& y) NOEXCEPT; CONSTCD14 month operator+(const month& x, const months& y) NOEXCEPT; CONSTCD14 month operator+(const months& x, const month& y) NOEXCEPT; CONSTCD14 month operator-(const month& x, const months& y) NOEXCEPT; CONSTCD14 months operator-(const month& x, const month& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month& m); // year class year { short y_; public: explicit CONSTCD11 year(int y) NOEXCEPT; CONSTCD14 year& operator++() NOEXCEPT; CONSTCD14 year operator++(int) NOEXCEPT; CONSTCD14 year& operator--() NOEXCEPT; CONSTCD14 year operator--(int) NOEXCEPT; CONSTCD14 year& operator+=(const years& y) NOEXCEPT; CONSTCD14 year& operator-=(const years& y) NOEXCEPT; CONSTCD14 bool is_leap() const NOEXCEPT; CONSTCD11 explicit operator int() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; static CONSTCD11 year min() NOEXCEPT; static CONSTCD11 year max() NOEXCEPT; }; CONSTCD11 bool operator==(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator!=(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator< (const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator> (const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator<=(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator>=(const year& x, const year& y) NOEXCEPT; CONSTCD11 year operator+(const year& x, const years& y) NOEXCEPT; CONSTCD11 year operator+(const years& x, const year& y) NOEXCEPT; CONSTCD11 year operator-(const year& x, const years& y) NOEXCEPT; CONSTCD11 years operator-(const year& x, const year& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year& y); // weekday class weekday { unsigned char wd_; public: explicit CONSTCD11 weekday(unsigned wd) NOEXCEPT; explicit weekday(int) = delete; CONSTCD11 weekday(const sys_days& dp) NOEXCEPT; CONSTCD11 explicit weekday(const local_days& dp) NOEXCEPT; CONSTCD14 weekday& operator++() NOEXCEPT; CONSTCD14 weekday operator++(int) NOEXCEPT; CONSTCD14 weekday& operator--() NOEXCEPT; CONSTCD14 weekday operator--(int) NOEXCEPT; CONSTCD14 weekday& operator+=(const days& d) NOEXCEPT; CONSTCD14 weekday& operator-=(const days& d) NOEXCEPT; CONSTCD11 explicit operator unsigned() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; CONSTCD11 weekday_indexed operator[](unsigned index) const NOEXCEPT; CONSTCD11 weekday_last operator[](last_spec) const NOEXCEPT; private: static CONSTCD11 unsigned char weekday_from_days(int z) NOEXCEPT; }; CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday& x, const weekday& y) NOEXCEPT; CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT; CONSTCD14 weekday operator+(const days& x, const weekday& y) NOEXCEPT; CONSTCD14 weekday operator-(const weekday& x, const days& y) NOEXCEPT; CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday& wd); // weekday_indexed class weekday_indexed { unsigned char wd_ : 4; unsigned char index_ : 4; public: CONSTCD11 weekday_indexed(const islamic::weekday& wd, unsigned index) NOEXCEPT; CONSTCD11 islamic::weekday weekday() const NOEXCEPT; CONSTCD11 unsigned index() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_indexed& wdi); // weekday_last class weekday_last { islamic::weekday wd_; public: explicit CONSTCD11 weekday_last(const islamic::weekday& wd) NOEXCEPT; CONSTCD11 islamic::weekday weekday() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_last& wdl); // year_month class year_month { islamic::year y_; islamic::month m_; public: CONSTCD11 year_month(const islamic::year& y, const islamic::month& m) NOEXCEPT; CONSTCD11 islamic::year year() const NOEXCEPT; CONSTCD11 islamic::month month() const NOEXCEPT; CONSTCD14 year_month& operator+=(const months& dm) NOEXCEPT; CONSTCD14 year_month& operator-=(const months& dm) NOEXCEPT; CONSTCD14 year_month& operator+=(const years& dy) NOEXCEPT; CONSTCD14 year_month& operator-=(const years& dy) NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator< (const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator> (const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD14 year_month operator+(const year_month& ym, const months& dm) NOEXCEPT; CONSTCD14 year_month operator+(const months& dm, const year_month& ym) NOEXCEPT; CONSTCD14 year_month operator-(const year_month& ym, const months& dm) NOEXCEPT; CONSTCD11 months operator-(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 year_month operator+(const year_month& ym, const years& dy) NOEXCEPT; CONSTCD11 year_month operator+(const years& dy, const year_month& ym) NOEXCEPT; CONSTCD11 year_month operator-(const year_month& ym, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month& ym); // month_day class month_day { islamic::month m_; islamic::day d_; public: CONSTCD11 month_day(const islamic::month& m, const islamic::day& d) NOEXCEPT; CONSTCD11 islamic::month month() const NOEXCEPT; CONSTCD11 islamic::day day() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator< (const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator> (const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator<=(const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator>=(const month_day& x, const month_day& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_day& md); // month_day_last class month_day_last { islamic::month m_; public: CONSTCD11 explicit month_day_last(const islamic::month& m) NOEXCEPT; CONSTCD11 islamic::month month() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator< (const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator> (const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_day_last& mdl); // month_weekday class month_weekday { islamic::month m_; islamic::weekday_indexed wdi_; public: CONSTCD11 month_weekday(const islamic::month& m, const islamic::weekday_indexed& wdi) NOEXCEPT; CONSTCD11 islamic::month month() const NOEXCEPT; CONSTCD11 islamic::weekday_indexed weekday_indexed() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday& mwd); // month_weekday_last class month_weekday_last { islamic::month m_; islamic::weekday_last wdl_; public: CONSTCD11 month_weekday_last(const islamic::month& m, const islamic::weekday_last& wd) NOEXCEPT; CONSTCD11 islamic::month month() const NOEXCEPT; CONSTCD11 islamic::weekday_last weekday_last() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday_last& mwdl); // class year_month_day class year_month_day { islamic::year y_; islamic::month m_; islamic::day d_; public: CONSTCD11 year_month_day(const islamic::year& y, const islamic::month& m, const islamic::day& d) NOEXCEPT; CONSTCD14 year_month_day(const year_month_day_last& ymdl) NOEXCEPT; CONSTCD14 year_month_day(sys_days dp) NOEXCEPT; CONSTCD14 explicit year_month_day(local_days dp) NOEXCEPT; CONSTCD14 year_month_day& operator+=(const months& m) NOEXCEPT; CONSTCD14 year_month_day& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_day& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_day& operator-=(const years& y) NOEXCEPT; CONSTCD11 islamic::year year() const NOEXCEPT; CONSTCD11 islamic::month month() const NOEXCEPT; CONSTCD11 islamic::day day() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; private: static CONSTCD14 year_month_day from_days(days dp) NOEXCEPT; CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator< (const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator> (const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD14 year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT; CONSTCD14 year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT; CONSTCD14 year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT; CONSTCD11 year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT; CONSTCD11 year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT; CONSTCD11 year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day& ymd); // year_month_day_last class year_month_day_last { islamic::year y_; islamic::month_day_last mdl_; public: CONSTCD11 year_month_day_last(const islamic::year& y, const islamic::month_day_last& mdl) NOEXCEPT; CONSTCD14 year_month_day_last& operator+=(const months& m) NOEXCEPT; CONSTCD14 year_month_day_last& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_day_last& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_day_last& operator-=(const years& y) NOEXCEPT; CONSTCD11 islamic::year year() const NOEXCEPT; CONSTCD11 islamic::month month() const NOEXCEPT; CONSTCD11 islamic::month_day_last month_day_last() const NOEXCEPT; CONSTCD14 islamic::day day() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator< (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator> (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD14 year_month_day_last operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; CONSTCD14 year_month_day_last operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT; CONSTCD11 year_month_day_last operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; CONSTCD11 year_month_day_last operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT; CONSTCD14 year_month_day_last operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; CONSTCD11 year_month_day_last operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day_last& ymdl); // year_month_weekday class year_month_weekday { islamic::year y_; islamic::month m_; islamic::weekday_indexed wdi_; public: CONSTCD11 year_month_weekday(const islamic::year& y, const islamic::month& m, const islamic::weekday_indexed& wdi) NOEXCEPT; CONSTCD14 year_month_weekday(const sys_days& dp) NOEXCEPT; CONSTCD14 explicit year_month_weekday(const local_days& dp) NOEXCEPT; CONSTCD14 year_month_weekday& operator+=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_weekday& operator-=(const years& y) NOEXCEPT; CONSTCD11 islamic::year year() const NOEXCEPT; CONSTCD11 islamic::month month() const NOEXCEPT; CONSTCD11 islamic::weekday weekday() const NOEXCEPT; CONSTCD11 unsigned index() const NOEXCEPT; CONSTCD11 islamic::weekday_indexed weekday_indexed() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; private: static CONSTCD14 year_month_weekday from_days(days dp) NOEXCEPT; CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; CONSTCD14 year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; CONSTCD14 year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT; CONSTCD11 year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; CONSTCD11 year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT; CONSTCD14 year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; CONSTCD11 year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi); // year_month_weekday_last class year_month_weekday_last { islamic::year y_; islamic::month m_; islamic::weekday_last wdl_; public: CONSTCD11 year_month_weekday_last(const islamic::year& y, const islamic::month& m, const islamic::weekday_last& wdl) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator+=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator-=(const years& y) NOEXCEPT; CONSTCD11 islamic::year year() const NOEXCEPT; CONSTCD11 islamic::month month() const NOEXCEPT; CONSTCD11 islamic::weekday weekday() const NOEXCEPT; CONSTCD11 islamic::weekday_last weekday_last() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; private: CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; CONSTCD14 year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; CONSTCD14 year_month_weekday_last operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; CONSTCD11 year_month_weekday_last operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT; CONSTCD14 year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; CONSTCD11 year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl); #if !defined(_MSC_VER) || (_MSC_VER >= 1900) inline namespace literals { CONSTCD11 islamic::day operator "" _d(unsigned long long d) NOEXCEPT; CONSTCD11 islamic::year operator "" _y(unsigned long long y) NOEXCEPT; } // inline namespace literals #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) //----------------+ // Implementation | //----------------+ // day CONSTCD11 inline day::day(unsigned d) NOEXCEPT : d_(static_cast(d)) {} CONSTCD14 inline day& day::operator++() NOEXCEPT {++d_; return *this;} CONSTCD14 inline day day::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline day& day::operator--() NOEXCEPT {--d_; return *this;} CONSTCD14 inline day day::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline day& day::operator+=(const days& d) NOEXCEPT {*this = *this + d; return *this;} CONSTCD14 inline day& day::operator-=(const days& d) NOEXCEPT {*this = *this - d; return *this;} CONSTCD11 inline day::operator unsigned() const NOEXCEPT {return d_;} CONSTCD11 inline bool day::ok() const NOEXCEPT {return 1 <= d_ && d_ <= 30;} CONSTCD11 inline bool operator==(const day& x, const day& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const day& x, const day& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const day& x, const day& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const day& x, const day& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const day& x, const day& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const day& x, const day& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline days operator-(const day& x, const day& y) NOEXCEPT { return days{static_cast(static_cast(x) - static_cast(y))}; } CONSTCD11 inline day operator+(const day& x, const days& y) NOEXCEPT { return day{static_cast(x) + static_cast(y.count())}; } CONSTCD11 inline day operator+(const days& x, const day& y) NOEXCEPT { return y + x; } CONSTCD11 inline day operator-(const day& x, const days& y) NOEXCEPT { return x + -y; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const day& d) { date::detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.width(2); os << static_cast(d); return os; } // month CONSTCD11 inline month::month(unsigned m) NOEXCEPT : m_(static_cast(m)) {} CONSTCD14 inline month& month::operator++() NOEXCEPT {if (++m_ == 13) m_ = 1; return *this;} CONSTCD14 inline month month::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline month& month::operator--() NOEXCEPT {if (--m_ == 0) m_ = 12; return *this;} CONSTCD14 inline month month::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline month& month::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline month& month::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD11 inline month::operator unsigned() const NOEXCEPT {return m_;} CONSTCD11 inline bool month::ok() const NOEXCEPT {return 1 <= m_ && m_ <= 12;} CONSTCD11 inline bool operator==(const month& x, const month& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const month& x, const month& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const month& x, const month& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const month& x, const month& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const month& x, const month& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const month& x, const month& y) NOEXCEPT { return !(x < y); } CONSTCD14 inline months operator-(const month& x, const month& y) NOEXCEPT { auto const d = static_cast(x) - static_cast(y); return months(d <= 11 ? d : d + 12); } CONSTCD14 inline month operator+(const month& x, const months& y) NOEXCEPT { auto const mu = static_cast(static_cast(x)) - 1 + y.count(); auto const yr = (mu >= 0 ? mu : mu-11) / 12; return month{static_cast(mu - yr * 12 + 1)}; } CONSTCD14 inline month operator+(const months& x, const month& y) NOEXCEPT { return y + x; } CONSTCD14 inline month operator-(const month& x, const months& y) NOEXCEPT { return x + -y; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month& m) { switch (static_cast(m)) { case 1: os << "Muharram"; break; case 2: os << "Safar"; break; case 3: os << "Rabi' al-awwal"; break; case 4: os << "Rabi' al-thani"; break; case 5: os << "Jumada al-awwal"; break; case 6: os << "Jumada al-Thani"; break; case 7: os << "Rajab"; break; case 8: os << "Sha'ban"; break; case 9: os << "Ramadan"; break; case 10: os << "Shawwal"; break; case 11: os << "Dhu al-Qi'dah"; break; case 12: os << "Dhu al-Hijjah"; break; default: os << static_cast(m) << " is not a valid month"; break; } return os; } // year CONSTCD11 inline year::year(int y) NOEXCEPT : y_(static_cast(y)) {} CONSTCD14 inline year& year::operator++() NOEXCEPT {++y_; return *this;} CONSTCD14 inline year year::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline year& year::operator--() NOEXCEPT {--y_; return *this;} CONSTCD14 inline year year::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline year& year::operator+=(const years& y) NOEXCEPT {*this = *this + y; return *this;} CONSTCD14 inline year& year::operator-=(const years& y) NOEXCEPT {*this = *this - y; return *this;} CONSTCD14 inline bool year::is_leap() const NOEXCEPT { int y = y_ - 1; const int era = (y >= 0 ? y : y-29) / 30; const unsigned yoe = static_cast(y - era * 30); switch (yoe) { case 1: case 4: case 6: case 9: case 12: case 15: case 17: case 20: case 23: case 25: case 28: return true; default: return false; } } CONSTCD11 inline year::operator int() const NOEXCEPT {return y_;} CONSTCD11 inline bool year::ok() const NOEXCEPT {return true;} CONSTCD11 inline year year::min() NOEXCEPT { return year{std::numeric_limits::min()}; } CONSTCD11 inline year year::max() NOEXCEPT { return year{std::numeric_limits::max()}; } CONSTCD11 inline bool operator==(const year& x, const year& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const year& x, const year& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year& x, const year& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const year& x, const year& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year& x, const year& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year& x, const year& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline years operator-(const year& x, const year& y) NOEXCEPT { return years{static_cast(x) - static_cast(y)}; } CONSTCD11 inline year operator+(const year& x, const years& y) NOEXCEPT { return year{static_cast(x) + y.count()}; } CONSTCD11 inline year operator+(const years& x, const year& y) NOEXCEPT { return y + x; } CONSTCD11 inline year operator-(const year& x, const years& y) NOEXCEPT { return year{static_cast(x) - y.count()}; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year& y) { date::detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::internal); os.width(4 + (y < year{0})); os << static_cast(y); return os; } // weekday CONSTCD11 inline unsigned char weekday::weekday_from_days(int z) NOEXCEPT { return static_cast(static_cast( z >= -4 ? (z+4) % 7 : (z+5) % 7 + 6)); } CONSTCD11 inline weekday::weekday(unsigned wd) NOEXCEPT : wd_(static_cast(wd)) {} CONSTCD11 inline weekday::weekday(const sys_days& dp) NOEXCEPT : wd_(weekday_from_days(dp.time_since_epoch().count())) {} CONSTCD11 inline weekday::weekday(const local_days& dp) NOEXCEPT : wd_(weekday_from_days(dp.time_since_epoch().count())) {} CONSTCD14 inline weekday& weekday::operator++() NOEXCEPT {if (++wd_ == 7) wd_ = 0; return *this;} CONSTCD14 inline weekday weekday::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline weekday& weekday::operator--() NOEXCEPT {if (wd_-- == 0) wd_ = 6; return *this;} CONSTCD14 inline weekday weekday::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline weekday& weekday::operator+=(const days& d) NOEXCEPT { *this = *this + d; return *this; } CONSTCD14 inline weekday& weekday::operator-=(const days& d) NOEXCEPT { *this = *this - d; return *this; } CONSTCD11 inline weekday::operator unsigned() const NOEXCEPT { return static_cast(wd_); } CONSTCD11 inline bool weekday::ok() const NOEXCEPT {return wd_ <= 6;} CONSTCD11 inline bool operator==(const weekday& x, const weekday& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const weekday& x, const weekday& y) NOEXCEPT { return !(x == y); } CONSTCD14 inline days operator-(const weekday& x, const weekday& y) NOEXCEPT { auto const diff = static_cast(x) - static_cast(y); return days{diff <= 6 ? diff : diff + 7}; } CONSTCD14 inline weekday operator+(const weekday& x, const days& y) NOEXCEPT { auto const wdu = static_cast(static_cast(x)) + y.count(); auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7; return weekday{static_cast(wdu - wk * 7)}; } CONSTCD14 inline weekday operator+(const days& x, const weekday& y) NOEXCEPT { return y + x; } CONSTCD14 inline weekday operator-(const weekday& x, const days& y) NOEXCEPT { return x + -y; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday& wd) { switch (static_cast(wd)) { case 0: os << "al-Aḥad"; break; case 1: os << "al-Ithnayn"; break; case 2: os << "ath-Thulāthā’"; break; case 3: os << "al-Arba‘ā’"; break; case 4: os << "al-Khamīs"; break; case 5: os << "al-Jum‘ah"; break; case 6: os << "as-Sabt"; break; default: os << static_cast(wd) << " is not a valid weekday"; break; } return os; } #if !defined(_MSC_VER) || (_MSC_VER >= 1900) inline namespace literals { CONSTCD11 inline islamic::day operator "" _d(unsigned long long d) NOEXCEPT { return islamic::day{static_cast(d)}; } CONSTCD11 inline islamic::year operator "" _y(unsigned long long y) NOEXCEPT { return islamic::year(static_cast(y)); } #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) CONSTDATA islamic::last_spec last{}; #if !defined(_MSC_VER) || (_MSC_VER >= 1900) } // inline namespace literals #endif // weekday_indexed CONSTCD11 inline weekday weekday_indexed::weekday() const NOEXCEPT { return islamic::weekday{static_cast(wd_)}; } CONSTCD11 inline unsigned weekday_indexed::index() const NOEXCEPT {return index_;} CONSTCD11 inline bool weekday_indexed::ok() const NOEXCEPT { return weekday().ok() && 1 <= index_ && index_ <= 5; } CONSTCD11 inline weekday_indexed::weekday_indexed(const islamic::weekday& wd, unsigned index) NOEXCEPT : wd_(static_cast(static_cast(wd))) , index_(static_cast(index)) {} template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_indexed& wdi) { return os << wdi.weekday() << '[' << wdi.index() << ']'; } CONSTCD11 inline weekday_indexed weekday::operator[](unsigned index) const NOEXCEPT { return {*this, index}; } CONSTCD11 inline bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT { return x.weekday() == y.weekday() && x.index() == y.index(); } CONSTCD11 inline bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT { return !(x == y); } // weekday_last CONSTCD11 inline islamic::weekday weekday_last::weekday() const NOEXCEPT {return wd_;} CONSTCD11 inline bool weekday_last::ok() const NOEXCEPT {return wd_.ok();} CONSTCD11 inline weekday_last::weekday_last(const islamic::weekday& wd) NOEXCEPT : wd_(wd) {} CONSTCD11 inline bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT { return x.weekday() == y.weekday(); } CONSTCD11 inline bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_last& wdl) { return os << wdl.weekday() << "[last]"; } CONSTCD11 inline weekday_last weekday::operator[](last_spec) const NOEXCEPT { return weekday_last{*this}; } // year_month CONSTCD11 inline year_month::year_month(const islamic::year& y, const islamic::month& m) NOEXCEPT : y_(y) , m_(m) {} CONSTCD11 inline year year_month::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month::month() const NOEXCEPT {return m_;} CONSTCD11 inline bool year_month::ok() const NOEXCEPT {return y_.ok() && m_.ok();} CONSTCD14 inline year_month& year_month::operator+=(const months& dm) NOEXCEPT { *this = *this + dm; return *this; } CONSTCD14 inline year_month& year_month::operator-=(const months& dm) NOEXCEPT { *this = *this - dm; return *this; } CONSTCD14 inline year_month& year_month::operator+=(const years& dy) NOEXCEPT { *this = *this + dy; return *this; } CONSTCD14 inline year_month& year_month::operator-=(const years& dy) NOEXCEPT { *this = *this - dy; return *this; } CONSTCD11 inline bool operator==(const year_month& x, const year_month& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month(); } CONSTCD11 inline bool operator!=(const year_month& x, const year_month& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_month& x, const year_month& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.month() < y.month())); } CONSTCD11 inline bool operator>(const year_month& x, const year_month& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_month& x, const year_month& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_month& x, const year_month& y) NOEXCEPT { return !(x < y); } CONSTCD14 inline year_month operator+(const year_month& ym, const months& dm) NOEXCEPT { auto dmi = static_cast(static_cast(ym.month())) - 1 + dm.count(); auto dy = (dmi >= 0 ? dmi : dmi-11) / 12; dmi = dmi - dy * 12 + 1; return (ym.year() + years(dy)) / month(static_cast(dmi)); } CONSTCD14 inline year_month operator+(const months& dm, const year_month& ym) NOEXCEPT { return ym + dm; } CONSTCD14 inline year_month operator-(const year_month& ym, const months& dm) NOEXCEPT { return ym + -dm; } CONSTCD11 inline months operator-(const year_month& x, const year_month& y) NOEXCEPT { return (x.year() - y.year()) + months(static_cast(x.month()) - static_cast(y.month())); } CONSTCD11 inline year_month operator+(const year_month& ym, const years& dy) NOEXCEPT { return (ym.year() + dy) / ym.month(); } CONSTCD11 inline year_month operator+(const years& dy, const year_month& ym) NOEXCEPT { return ym + dy; } CONSTCD11 inline year_month operator-(const year_month& ym, const years& dy) NOEXCEPT { return ym + -dy; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month& ym) { return os << ym.year() << '/' << ym.month(); } // month_day CONSTCD11 inline month_day::month_day(const islamic::month& m, const islamic::day& d) NOEXCEPT : m_(m) , d_(d) {} CONSTCD11 inline islamic::month month_day::month() const NOEXCEPT {return m_;} CONSTCD11 inline islamic::day month_day::day() const NOEXCEPT {return d_;} CONSTCD14 inline bool month_day::ok() const NOEXCEPT { CONSTDATA islamic::day d[] = {30_d, 29_d, 30_d, 29_d, 30_d, 29_d, 30_d, 29_d, 30_d, 29_d, 30_d, 30_d}; return m_.ok() && 1_d <= d_ && d_ <= d[static_cast(m_)-1]; } CONSTCD11 inline bool operator==(const month_day& x, const month_day& y) NOEXCEPT { return x.month() == y.month() && x.day() == y.day(); } CONSTCD11 inline bool operator!=(const month_day& x, const month_day& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const month_day& x, const month_day& y) NOEXCEPT { return x.month() < y.month() ? true : (x.month() > y.month() ? false : (x.day() < y.day())); } CONSTCD11 inline bool operator>(const month_day& x, const month_day& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const month_day& x, const month_day& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const month_day& x, const month_day& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_day& md) { return os << md.month() << '/' << md.day(); } // month_day_last CONSTCD11 inline month month_day_last::month() const NOEXCEPT {return m_;} CONSTCD11 inline bool month_day_last::ok() const NOEXCEPT {return m_.ok();} CONSTCD11 inline month_day_last::month_day_last(const islamic::month& m) NOEXCEPT : m_(m) {} CONSTCD11 inline bool operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT { return x.month() == y.month(); } CONSTCD11 inline bool operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const month_day_last& x, const month_day_last& y) NOEXCEPT { return x.month() < y.month(); } CONSTCD11 inline bool operator>(const month_day_last& x, const month_day_last& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_day_last& mdl) { return os << mdl.month() << "/last"; } // month_weekday CONSTCD11 inline month_weekday::month_weekday(const islamic::month& m, const islamic::weekday_indexed& wdi) NOEXCEPT : m_(m) , wdi_(wdi) {} CONSTCD11 inline month month_weekday::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday_indexed month_weekday::weekday_indexed() const NOEXCEPT { return wdi_; } CONSTCD11 inline bool month_weekday::ok() const NOEXCEPT { return m_.ok() && wdi_.ok(); } CONSTCD11 inline bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT { return x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed(); } CONSTCD11 inline bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday& mwd) { return os << mwd.month() << '/' << mwd.weekday_indexed(); } // month_weekday_last CONSTCD11 inline month_weekday_last::month_weekday_last(const islamic::month& m, const islamic::weekday_last& wdl) NOEXCEPT : m_(m) , wdl_(wdl) {} CONSTCD11 inline month month_weekday_last::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday_last month_weekday_last::weekday_last() const NOEXCEPT { return wdl_; } CONSTCD11 inline bool month_weekday_last::ok() const NOEXCEPT { return m_.ok() && wdl_.ok(); } CONSTCD11 inline bool operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT { return x.month() == y.month() && x.weekday_last() == y.weekday_last(); } CONSTCD11 inline bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday_last& mwdl) { return os << mwdl.month() << '/' << mwdl.weekday_last(); } // year_month_day_last CONSTCD11 inline year_month_day_last::year_month_day_last(const islamic::year& y, const islamic::month_day_last& mdl) NOEXCEPT : y_(y) , mdl_(mdl) {} CONSTCD14 inline year_month_day_last& year_month_day_last::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline year_month_day_last& year_month_day_last::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_day_last& year_month_day_last::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_day_last& year_month_day_last::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_month_day_last::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_day_last::month() const NOEXCEPT {return mdl_.month();} CONSTCD11 inline month_day_last year_month_day_last::month_day_last() const NOEXCEPT { return mdl_; } CONSTCD14 inline day year_month_day_last::day() const NOEXCEPT { CONSTDATA islamic::day d[] = {30_d, 29_d, 30_d, 29_d, 30_d, 29_d, 30_d, 29_d, 30_d, 29_d, 30_d, 29_d}; return month() != islamic::month(12) || !y_.is_leap() ? d[static_cast(month())-1] : 30_d; } CONSTCD14 inline year_month_day_last::operator sys_days() const NOEXCEPT { return sys_days(year()/month()/day()); } CONSTCD14 inline year_month_day_last::operator local_days() const NOEXCEPT { return local_days(year()/month()/day()); } CONSTCD11 inline bool year_month_day_last::ok() const NOEXCEPT { return y_.ok() && mdl_.ok(); } CONSTCD11 inline bool operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return x.year() == y.year() && x.month_day_last() == y.month_day_last(); } CONSTCD11 inline bool operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.month_day_last() < y.month_day_last())); } CONSTCD11 inline bool operator>(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day_last& ymdl) { return os << ymdl.year() << '/' << ymdl.month_day_last(); } CONSTCD14 inline year_month_day_last operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT { return (ymdl.year() / ymdl.month() + dm) / last; } CONSTCD14 inline year_month_day_last operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT { return ymdl + dm; } CONSTCD14 inline year_month_day_last operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT { return ymdl + (-dm); } CONSTCD11 inline year_month_day_last operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT { return {ymdl.year()+dy, ymdl.month_day_last()}; } CONSTCD11 inline year_month_day_last operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT { return ymdl + dy; } CONSTCD11 inline year_month_day_last operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT { return ymdl + (-dy); } // year_month_day CONSTCD11 inline year_month_day::year_month_day(const islamic::year& y, const islamic::month& m, const islamic::day& d) NOEXCEPT : y_(y) , m_(m) , d_(d) {} CONSTCD14 inline year_month_day::year_month_day(const year_month_day_last& ymdl) NOEXCEPT : y_(ymdl.year()) , m_(ymdl.month()) , d_(ymdl.day()) {} CONSTCD14 inline year_month_day::year_month_day(sys_days dp) NOEXCEPT : year_month_day(from_days(dp.time_since_epoch())) {} CONSTCD14 inline year_month_day::year_month_day(local_days dp) NOEXCEPT : year_month_day(from_days(dp.time_since_epoch())) {} CONSTCD11 inline year year_month_day::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_day::month() const NOEXCEPT {return m_;} CONSTCD11 inline day year_month_day::day() const NOEXCEPT {return d_;} CONSTCD14 inline year_month_day& year_month_day::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline year_month_day& year_month_day::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_day& year_month_day::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_day& year_month_day::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD14 inline days year_month_day::to_days() const NOEXCEPT { static_assert(std::numeric_limits::digits >= 18, "This algorithm has not been ported to a 16 bit unsigned integer"); static_assert(std::numeric_limits::digits >= 20, "This algorithm has not been ported to a 16 bit signed integer"); auto const y = static_cast(y_) - 1; auto const m = static_cast(m_); auto const d = static_cast(d_); auto const era = (y >= 0 ? y : y-29) / 30; auto const yoe = static_cast(y - era * 30); // [0, 29] auto const doy = 29*(m-1) + m/2 + d-1; // [0, 354] auto const doe = yoe * 354 + (11*(yoe+1)+3)/30 + doy; // [0, 10630] return days{era * 10631 + static_cast(doe) - 492148}; } CONSTCD14 inline year_month_day::operator sys_days() const NOEXCEPT { return sys_days{to_days()}; } CONSTCD14 inline year_month_day::operator local_days() const NOEXCEPT { return local_days{to_days()}; } CONSTCD14 inline bool year_month_day::ok() const NOEXCEPT { if (!(y_.ok() && m_.ok())) return false; return 1_d <= d_ && d_ <= (y_/m_/last).day(); } CONSTCD11 inline bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month() && x.day() == y.day(); } CONSTCD11 inline bool operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_month_day& x, const year_month_day& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.month() < y.month() ? true : (x.month() > y.month() ? false : (x.day() < y.day())))); } CONSTCD11 inline bool operator>(const year_month_day& x, const year_month_day& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day& ymd) { date::detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os << ymd.year() << '-'; os.width(2); os << static_cast(ymd.month()) << '-'; os << ymd.day(); return os; } CONSTCD14 inline year_month_day year_month_day::from_days(days dp) NOEXCEPT { static_assert(std::numeric_limits::digits >= 18, "This algorithm has not been ported to a 16 bit unsigned integer"); static_assert(std::numeric_limits::digits >= 20, "This algorithm has not been ported to a 16 bit signed integer"); auto const z = dp.count() + 492148; auto const era = (z >= 0 ? z : z - 10630) / 10631; auto const doe = static_cast(z - era * 10631); // [0, 10630] auto const yoe = (30*doe + 10646)/10631 - 1; // [0, 29] auto const y = static_cast(yoe) + era * 30 + 1; auto const doy = doe - (yoe * 354 + (11*(yoe+1)+3)/30); // [0, 354] auto const m = (11*doy + 330) / 325; // [1, 12] auto const d = doy - (29*(m-1) + m/2) + 1; // [1, 30] return year_month_day{islamic::year{y}, islamic::month(m), islamic::day(d)}; } CONSTCD14 inline year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT { return (ymd.year() / ymd.month() + dm) / ymd.day(); } CONSTCD14 inline year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT { return ymd + dm; } CONSTCD14 inline year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT { return ymd + (-dm); } CONSTCD11 inline year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT { return (ymd.year() + dy) / ymd.month() / ymd.day(); } CONSTCD11 inline year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT { return ymd + dy; } CONSTCD11 inline year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT { return ymd + (-dy); } // year_month_weekday CONSTCD11 inline year_month_weekday::year_month_weekday(const islamic::year& y, const islamic::month& m, const islamic::weekday_indexed& wdi) NOEXCEPT : y_(y) , m_(m) , wdi_(wdi) {} CONSTCD14 inline year_month_weekday::year_month_weekday(const sys_days& dp) NOEXCEPT : year_month_weekday(from_days(dp.time_since_epoch())) {} CONSTCD14 inline year_month_weekday::year_month_weekday(const local_days& dp) NOEXCEPT : year_month_weekday(from_days(dp.time_since_epoch())) {} CONSTCD14 inline year_month_weekday& year_month_weekday::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline year_month_weekday& year_month_weekday::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_weekday& year_month_weekday::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_weekday& year_month_weekday::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_month_weekday::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_weekday::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday year_month_weekday::weekday() const NOEXCEPT { return wdi_.weekday(); } CONSTCD11 inline unsigned year_month_weekday::index() const NOEXCEPT { return wdi_.index(); } CONSTCD11 inline weekday_indexed year_month_weekday::weekday_indexed() const NOEXCEPT { return wdi_; } CONSTCD14 inline year_month_weekday::operator sys_days() const NOEXCEPT { return sys_days{to_days()}; } CONSTCD14 inline year_month_weekday::operator local_days() const NOEXCEPT { return local_days{to_days()}; } CONSTCD14 inline bool year_month_weekday::ok() const NOEXCEPT { if (!y_.ok() || !m_.ok() || !wdi_.weekday().ok() || wdi_.index() < 1) return false; if (wdi_.index() <= 4) return true; auto d2 = wdi_.weekday() - islamic::weekday(y_/m_/1) + days((wdi_.index()-1)*7 + 1); return static_cast(d2.count()) <= static_cast((y_/m_/last).day()); } CONSTCD14 inline year_month_weekday year_month_weekday::from_days(days d) NOEXCEPT { sys_days dp{d}; auto const wd = islamic::weekday(dp); auto const ymd = year_month_day(dp); return {ymd.year(), ymd.month(), wd[(static_cast(ymd.day())-1)/7+1]}; } CONSTCD14 inline days year_month_weekday::to_days() const NOEXCEPT { auto d = sys_days(y_/m_/1); return (d + (wdi_.weekday() - islamic::weekday(d) + days{(wdi_.index()-1)*7}) ).time_since_epoch(); } CONSTCD11 inline bool operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed(); } CONSTCD11 inline bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi) { return os << ymwdi.year() << '/' << ymwdi.month() << '/' << ymwdi.weekday_indexed(); } CONSTCD14 inline year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT { return (ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed(); } CONSTCD14 inline year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT { return ymwd + dm; } CONSTCD14 inline year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT { return ymwd + (-dm); } CONSTCD11 inline year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT { return {ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()}; } CONSTCD11 inline year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT { return ymwd + dy; } CONSTCD11 inline year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT { return ymwd + (-dy); } // year_month_weekday_last CONSTCD11 inline year_month_weekday_last::year_month_weekday_last(const islamic::year& y, const islamic::month& m, const islamic::weekday_last& wdl) NOEXCEPT : y_(y) , m_(m) , wdl_(wdl) {} CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_month_weekday_last::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_weekday_last::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday year_month_weekday_last::weekday() const NOEXCEPT { return wdl_.weekday(); } CONSTCD11 inline weekday_last year_month_weekday_last::weekday_last() const NOEXCEPT { return wdl_; } CONSTCD14 inline year_month_weekday_last::operator sys_days() const NOEXCEPT { return sys_days{to_days()}; } CONSTCD14 inline year_month_weekday_last::operator local_days() const NOEXCEPT { return local_days{to_days()}; } CONSTCD11 inline bool year_month_weekday_last::ok() const NOEXCEPT { return y_.ok() && m_.ok() && wdl_.ok(); } CONSTCD14 inline days year_month_weekday_last::to_days() const NOEXCEPT { auto const d = sys_days(y_/m_/last); return (d - (islamic::weekday{d} - wdl_.weekday())).time_since_epoch(); } CONSTCD11 inline bool operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month() && x.weekday_last() == y.weekday_last(); } CONSTCD11 inline bool operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl) { return os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last(); } CONSTCD14 inline year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT { return (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last(); } CONSTCD14 inline year_month_weekday_last operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT { return ymwdl + dm; } CONSTCD14 inline year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT { return ymwdl + (-dm); } CONSTCD11 inline year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT { return {ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()}; } CONSTCD11 inline year_month_weekday_last operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT { return ymwdl + dy; } CONSTCD11 inline year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT { return ymwdl + (-dy); } // year_month from operator/() CONSTCD11 inline year_month operator/(const year& y, const month& m) NOEXCEPT { return {y, m}; } CONSTCD11 inline year_month operator/(const year& y, int m) NOEXCEPT { return y / month(static_cast(m)); } // month_day from operator/() CONSTCD11 inline month_day operator/(const month& m, const day& d) NOEXCEPT { return {m, d}; } CONSTCD11 inline month_day operator/(const day& d, const month& m) NOEXCEPT { return m / d; } CONSTCD11 inline month_day operator/(const month& m, int d) NOEXCEPT { return m / day(static_cast(d)); } CONSTCD11 inline month_day operator/(int m, const day& d) NOEXCEPT { return month(static_cast(m)) / d; } CONSTCD11 inline month_day operator/(const day& d, int m) NOEXCEPT {return m / d;} // month_day_last from operator/() CONSTCD11 inline month_day_last operator/(const month& m, last_spec) NOEXCEPT { return month_day_last{m}; } CONSTCD11 inline month_day_last operator/(last_spec, const month& m) NOEXCEPT { return m/last; } CONSTCD11 inline month_day_last operator/(int m, last_spec) NOEXCEPT { return month(static_cast(m))/last; } CONSTCD11 inline month_day_last operator/(last_spec, int m) NOEXCEPT { return m/last; } // month_weekday from operator/() CONSTCD11 inline month_weekday operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT { return {m, wdi}; } CONSTCD11 inline month_weekday operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT { return m / wdi; } CONSTCD11 inline month_weekday operator/(int m, const weekday_indexed& wdi) NOEXCEPT { return month(static_cast(m)) / wdi; } CONSTCD11 inline month_weekday operator/(const weekday_indexed& wdi, int m) NOEXCEPT { return m / wdi; } // month_weekday_last from operator/() CONSTCD11 inline month_weekday_last operator/(const month& m, const weekday_last& wdl) NOEXCEPT { return {m, wdl}; } CONSTCD11 inline month_weekday_last operator/(const weekday_last& wdl, const month& m) NOEXCEPT { return m / wdl; } CONSTCD11 inline month_weekday_last operator/(int m, const weekday_last& wdl) NOEXCEPT { return month(static_cast(m)) / wdl; } CONSTCD11 inline month_weekday_last operator/(const weekday_last& wdl, int m) NOEXCEPT { return m / wdl; } // year_month_day from operator/() CONSTCD11 inline year_month_day operator/(const year_month& ym, const day& d) NOEXCEPT { return {ym.year(), ym.month(), d}; } CONSTCD11 inline year_month_day operator/(const year_month& ym, int d) NOEXCEPT { return ym / day(static_cast(d)); } CONSTCD11 inline year_month_day operator/(const year& y, const month_day& md) NOEXCEPT { return y / md.month() / md.day(); } CONSTCD11 inline year_month_day operator/(int y, const month_day& md) NOEXCEPT { return year(y) / md; } CONSTCD11 inline year_month_day operator/(const month_day& md, const year& y) NOEXCEPT { return y / md; } CONSTCD11 inline year_month_day operator/(const month_day& md, int y) NOEXCEPT { return year(y) / md; } // year_month_day_last from operator/() CONSTCD11 inline year_month_day_last operator/(const year_month& ym, last_spec) NOEXCEPT { return {ym.year(), month_day_last{ym.month()}}; } CONSTCD11 inline year_month_day_last operator/(const year& y, const month_day_last& mdl) NOEXCEPT { return {y, mdl}; } CONSTCD11 inline year_month_day_last operator/(int y, const month_day_last& mdl) NOEXCEPT { return year(y) / mdl; } CONSTCD11 inline year_month_day_last operator/(const month_day_last& mdl, const year& y) NOEXCEPT { return y / mdl; } CONSTCD11 inline year_month_day_last operator/(const month_day_last& mdl, int y) NOEXCEPT { return year(y) / mdl; } // year_month_weekday from operator/() CONSTCD11 inline year_month_weekday operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT { return {ym.year(), ym.month(), wdi}; } CONSTCD11 inline year_month_weekday operator/(const year& y, const month_weekday& mwd) NOEXCEPT { return {y, mwd.month(), mwd.weekday_indexed()}; } CONSTCD11 inline year_month_weekday operator/(int y, const month_weekday& mwd) NOEXCEPT { return year(y) / mwd; } CONSTCD11 inline year_month_weekday operator/(const month_weekday& mwd, const year& y) NOEXCEPT { return y / mwd; } CONSTCD11 inline year_month_weekday operator/(const month_weekday& mwd, int y) NOEXCEPT { return year(y) / mwd; } // year_month_weekday_last from operator/() CONSTCD11 inline year_month_weekday_last operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT { return {ym.year(), ym.month(), wdl}; } CONSTCD11 inline year_month_weekday_last operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT { return {y, mwdl.month(), mwdl.weekday_last()}; } CONSTCD11 inline year_month_weekday_last operator/(int y, const month_weekday_last& mwdl) NOEXCEPT { return year(y) / mwdl; } CONSTCD11 inline year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT { return y / mwdl; } CONSTCD11 inline year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) NOEXCEPT { return year(y) / mwdl; } } // namespace islamic #endif // ISLAMIC_H date-3.0.1/include/date/iso_week.h000066400000000000000000001240321403643451100167510ustar00rootroot00000000000000#ifndef ISO_WEEK_H #define ISO_WEEK_H // The MIT License (MIT) // // Copyright (c) 2015, 2016, 2017 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "date.h" #include namespace iso_week { // y/wn/wd // wn/wd/y // wd/wn/y using days = date::days; using weeks = date::weeks; using years = date::years; // time_point using sys_days = date::sys_days; using local_days = date::local_days; // types struct last_week { explicit last_week() = default; }; class weekday; class weeknum; class year; class year_weeknum; class year_lastweek; class weeknum_weekday; class lastweek_weekday; class year_weeknum_weekday; class year_lastweek_weekday; // date composition operators CONSTCD11 year_weeknum operator/(const year& y, const weeknum& wn) NOEXCEPT; CONSTCD11 year_weeknum operator/(const year& y, int wn) NOEXCEPT; CONSTCD11 year_lastweek operator/(const year& y, last_week wn) NOEXCEPT; CONSTCD11 weeknum_weekday operator/(const weeknum& wn, const weekday& wd) NOEXCEPT; CONSTCD11 weeknum_weekday operator/(const weeknum& wn, int wd) NOEXCEPT; CONSTCD11 weeknum_weekday operator/(const weekday& wd, const weeknum& wn) NOEXCEPT; CONSTCD11 weeknum_weekday operator/(const weekday& wd, int wn) NOEXCEPT; CONSTCD11 lastweek_weekday operator/(const last_week& wn, const weekday& wd) NOEXCEPT; CONSTCD11 lastweek_weekday operator/(const last_week& wn, int wd) NOEXCEPT; CONSTCD11 lastweek_weekday operator/(const weekday& wd, const last_week& wn) NOEXCEPT; CONSTCD11 year_weeknum_weekday operator/(const year_weeknum& ywn, const weekday& wd) NOEXCEPT; CONSTCD11 year_weeknum_weekday operator/(const year_weeknum& ywn, int wd) NOEXCEPT; CONSTCD11 year_weeknum_weekday operator/(const weeknum_weekday& wnwd, const year& y) NOEXCEPT; CONSTCD11 year_weeknum_weekday operator/(const weeknum_weekday& wnwd, int y) NOEXCEPT; CONSTCD11 year_lastweek_weekday operator/(const year_lastweek& ylw, const weekday& wd) NOEXCEPT; CONSTCD11 year_lastweek_weekday operator/(const year_lastweek& ylw, int wd) NOEXCEPT; CONSTCD11 year_lastweek_weekday operator/(const lastweek_weekday& lwwd, const year& y) NOEXCEPT; CONSTCD11 year_lastweek_weekday operator/(const lastweek_weekday& lwwd, int y) NOEXCEPT; // weekday class weekday { unsigned char wd_; public: explicit CONSTCD11 weekday(unsigned wd) NOEXCEPT; CONSTCD11 weekday(date::weekday wd) NOEXCEPT; explicit weekday(int) = delete; CONSTCD11 weekday(const sys_days& dp) NOEXCEPT; CONSTCD11 explicit weekday(const local_days& dp) NOEXCEPT; weekday& operator++() NOEXCEPT; weekday operator++(int) NOEXCEPT; weekday& operator--() NOEXCEPT; weekday operator--(int) NOEXCEPT; weekday& operator+=(const days& d) NOEXCEPT; weekday& operator-=(const days& d) NOEXCEPT; CONSTCD11 explicit operator unsigned() const NOEXCEPT; CONSTCD11 operator date::weekday() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; private: static CONSTCD11 unsigned char weekday_from_days(int z) NOEXCEPT; static CONSTCD11 unsigned char to_iso_encoding(unsigned char) NOEXCEPT; static CONSTCD11 unsigned from_iso_encoding(unsigned) NOEXCEPT; }; CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday& x, const weekday& y) NOEXCEPT; CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT; CONSTCD14 weekday operator+(const days& x, const weekday& y) NOEXCEPT; CONSTCD14 weekday operator-(const weekday& x, const days& y) NOEXCEPT; CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday& wd); // year class year { short y_; public: explicit CONSTCD11 year(int y) NOEXCEPT; year& operator++() NOEXCEPT; year operator++(int) NOEXCEPT; year& operator--() NOEXCEPT; year operator--(int) NOEXCEPT; year& operator+=(const years& y) NOEXCEPT; year& operator-=(const years& y) NOEXCEPT; CONSTCD11 explicit operator int() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; static CONSTCD11 year min() NOEXCEPT; static CONSTCD11 year max() NOEXCEPT; }; CONSTCD11 bool operator==(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator!=(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator< (const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator> (const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator<=(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator>=(const year& x, const year& y) NOEXCEPT; CONSTCD11 year operator+(const year& x, const years& y) NOEXCEPT; CONSTCD11 year operator+(const years& x, const year& y) NOEXCEPT; CONSTCD11 year operator-(const year& x, const years& y) NOEXCEPT; CONSTCD11 years operator-(const year& x, const year& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year& y); // weeknum class weeknum { unsigned char wn_; public: explicit CONSTCD11 weeknum(unsigned wn) NOEXCEPT; weeknum& operator++() NOEXCEPT; weeknum operator++(int) NOEXCEPT; weeknum& operator--() NOEXCEPT; weeknum operator--(int) NOEXCEPT; weeknum& operator+=(const weeks& y) NOEXCEPT; weeknum& operator-=(const weeks& y) NOEXCEPT; CONSTCD11 explicit operator unsigned() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const weeknum& x, const weeknum& y) NOEXCEPT; CONSTCD11 bool operator!=(const weeknum& x, const weeknum& y) NOEXCEPT; CONSTCD11 bool operator< (const weeknum& x, const weeknum& y) NOEXCEPT; CONSTCD11 bool operator> (const weeknum& x, const weeknum& y) NOEXCEPT; CONSTCD11 bool operator<=(const weeknum& x, const weeknum& y) NOEXCEPT; CONSTCD11 bool operator>=(const weeknum& x, const weeknum& y) NOEXCEPT; CONSTCD11 weeknum operator+(const weeknum& x, const weeks& y) NOEXCEPT; CONSTCD11 weeknum operator+(const weeks& x, const weeknum& y) NOEXCEPT; CONSTCD11 weeknum operator-(const weeknum& x, const weeks& y) NOEXCEPT; CONSTCD11 weeks operator-(const weeknum& x, const weeknum& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weeknum& wn); // year_weeknum class year_weeknum { iso_week::year y_; iso_week::weeknum wn_; public: CONSTCD11 year_weeknum(const iso_week::year& y, const iso_week::weeknum& wn) NOEXCEPT; CONSTCD11 iso_week::year year() const NOEXCEPT; CONSTCD11 iso_week::weeknum weeknum() const NOEXCEPT; year_weeknum& operator+=(const years& dy) NOEXCEPT; year_weeknum& operator-=(const years& dy) NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_weeknum& x, const year_weeknum& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_weeknum& x, const year_weeknum& y) NOEXCEPT; CONSTCD11 bool operator< (const year_weeknum& x, const year_weeknum& y) NOEXCEPT; CONSTCD11 bool operator> (const year_weeknum& x, const year_weeknum& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_weeknum& x, const year_weeknum& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_weeknum& x, const year_weeknum& y) NOEXCEPT; CONSTCD11 year_weeknum operator+(const year_weeknum& ym, const years& dy) NOEXCEPT; CONSTCD11 year_weeknum operator+(const years& dy, const year_weeknum& ym) NOEXCEPT; CONSTCD11 year_weeknum operator-(const year_weeknum& ym, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_weeknum& ym); // year_lastweek class year_lastweek { iso_week::year y_; public: CONSTCD11 explicit year_lastweek(const iso_week::year& y) NOEXCEPT; CONSTCD11 iso_week::year year() const NOEXCEPT; CONSTCD14 iso_week::weeknum weeknum() const NOEXCEPT; year_lastweek& operator+=(const years& dy) NOEXCEPT; year_lastweek& operator-=(const years& dy) NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_lastweek& x, const year_lastweek& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_lastweek& x, const year_lastweek& y) NOEXCEPT; CONSTCD11 bool operator< (const year_lastweek& x, const year_lastweek& y) NOEXCEPT; CONSTCD11 bool operator> (const year_lastweek& x, const year_lastweek& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_lastweek& x, const year_lastweek& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_lastweek& x, const year_lastweek& y) NOEXCEPT; CONSTCD11 year_lastweek operator+(const year_lastweek& ym, const years& dy) NOEXCEPT; CONSTCD11 year_lastweek operator+(const years& dy, const year_lastweek& ym) NOEXCEPT; CONSTCD11 year_lastweek operator-(const year_lastweek& ym, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_lastweek& ym); // weeknum_weekday class weeknum_weekday { iso_week::weeknum wn_; iso_week::weekday wd_; public: CONSTCD11 weeknum_weekday(const iso_week::weeknum& wn, const iso_week::weekday& wd) NOEXCEPT; CONSTCD11 iso_week::weeknum weeknum() const NOEXCEPT; CONSTCD11 iso_week::weekday weekday() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT; CONSTCD11 bool operator< (const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT; CONSTCD11 bool operator> (const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT; CONSTCD11 bool operator<=(const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT; CONSTCD11 bool operator>=(const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weeknum_weekday& md); // lastweek_weekday class lastweek_weekday { iso_week::weekday wd_; public: CONSTCD11 explicit lastweek_weekday(const iso_week::weekday& wd) NOEXCEPT; CONSTCD11 iso_week::weekday weekday() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT; CONSTCD11 bool operator< (const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT; CONSTCD11 bool operator> (const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT; CONSTCD11 bool operator<=(const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT; CONSTCD11 bool operator>=(const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const lastweek_weekday& md); // year_lastweek_weekday class year_lastweek_weekday { iso_week::year y_; iso_week::weekday wd_; public: CONSTCD11 year_lastweek_weekday(const iso_week::year& y, const iso_week::weekday& wd) NOEXCEPT; year_lastweek_weekday& operator+=(const years& y) NOEXCEPT; year_lastweek_weekday& operator-=(const years& y) NOEXCEPT; CONSTCD11 iso_week::year year() const NOEXCEPT; CONSTCD14 iso_week::weeknum weeknum() const NOEXCEPT; CONSTCD11 iso_week::weekday weekday() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_lastweek_weekday& x, const year_lastweek_weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_lastweek_weekday& x, const year_lastweek_weekday& y) NOEXCEPT; CONSTCD11 bool operator< (const year_lastweek_weekday& x, const year_lastweek_weekday& y) NOEXCEPT; CONSTCD11 bool operator> (const year_lastweek_weekday& x, const year_lastweek_weekday& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_lastweek_weekday& x, const year_lastweek_weekday& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_lastweek_weekday& x, const year_lastweek_weekday& y) NOEXCEPT; CONSTCD11 year_lastweek_weekday operator+(const year_lastweek_weekday& ywnwd, const years& y) NOEXCEPT; CONSTCD11 year_lastweek_weekday operator+(const years& y, const year_lastweek_weekday& ywnwd) NOEXCEPT; CONSTCD11 year_lastweek_weekday operator-(const year_lastweek_weekday& ywnwd, const years& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_lastweek_weekday& ywnwd); // class year_weeknum_weekday class year_weeknum_weekday { iso_week::year y_; iso_week::weeknum wn_; iso_week::weekday wd_; public: CONSTCD11 year_weeknum_weekday(const iso_week::year& y, const iso_week::weeknum& wn, const iso_week::weekday& wd) NOEXCEPT; CONSTCD14 year_weeknum_weekday(const year_lastweek_weekday& ylwwd) NOEXCEPT; CONSTCD14 year_weeknum_weekday(const sys_days& dp) NOEXCEPT; CONSTCD14 explicit year_weeknum_weekday(const local_days& dp) NOEXCEPT; year_weeknum_weekday& operator+=(const years& y) NOEXCEPT; year_weeknum_weekday& operator-=(const years& y) NOEXCEPT; CONSTCD11 iso_week::year year() const NOEXCEPT; CONSTCD11 iso_week::weeknum weeknum() const NOEXCEPT; CONSTCD11 iso_week::weekday weekday() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; private: static CONSTCD14 year_weeknum_weekday from_days(days dp) NOEXCEPT; }; CONSTCD11 bool operator==(const year_weeknum_weekday& x, const year_weeknum_weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_weeknum_weekday& x, const year_weeknum_weekday& y) NOEXCEPT; CONSTCD11 bool operator< (const year_weeknum_weekday& x, const year_weeknum_weekday& y) NOEXCEPT; CONSTCD11 bool operator> (const year_weeknum_weekday& x, const year_weeknum_weekday& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_weeknum_weekday& x, const year_weeknum_weekday& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_weeknum_weekday& x, const year_weeknum_weekday& y) NOEXCEPT; CONSTCD11 year_weeknum_weekday operator+(const year_weeknum_weekday& ywnwd, const years& y) NOEXCEPT; CONSTCD11 year_weeknum_weekday operator+(const years& y, const year_weeknum_weekday& ywnwd) NOEXCEPT; CONSTCD11 year_weeknum_weekday operator-(const year_weeknum_weekday& ywnwd, const years& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_weeknum_weekday& ywnwd); //----------------+ // Implementation | //----------------+ // weekday CONSTCD11 inline unsigned char weekday::to_iso_encoding(unsigned char z) NOEXCEPT { return z != 0 ? z : (unsigned char)7; } CONSTCD11 inline unsigned weekday::from_iso_encoding(unsigned z) NOEXCEPT { return z != 7 ? z : 0u; } CONSTCD11 inline unsigned char weekday::weekday_from_days(int z) NOEXCEPT { return to_iso_encoding(static_cast(static_cast( z >= -4 ? (z+4) % 7 : (z+5) % 7 + 6))); } CONSTCD11 inline weekday::weekday(unsigned wd) NOEXCEPT : wd_(static_cast(wd)) {} CONSTCD11 inline weekday::weekday(date::weekday wd) NOEXCEPT : wd_(wd.iso_encoding()) {} CONSTCD11 inline weekday::weekday(const sys_days& dp) NOEXCEPT : wd_(weekday_from_days(dp.time_since_epoch().count())) {} CONSTCD11 inline weekday::weekday(const local_days& dp) NOEXCEPT : wd_(weekday_from_days(dp.time_since_epoch().count())) {} inline weekday& weekday::operator++() NOEXCEPT {if (++wd_ == 8) wd_ = 1; return *this;} inline weekday weekday::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} inline weekday& weekday::operator--() NOEXCEPT {if (wd_-- == 1) wd_ = 7; return *this;} inline weekday weekday::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} inline weekday& weekday::operator+=(const days& d) NOEXCEPT { *this = *this + d; return *this; } inline weekday& weekday::operator-=(const days& d) NOEXCEPT { *this = *this - d; return *this; } CONSTCD11 inline weekday::operator unsigned() const NOEXCEPT { return wd_; } CONSTCD11 inline weekday::operator date::weekday() const NOEXCEPT { return date::weekday{from_iso_encoding(unsigned{wd_})}; } CONSTCD11 inline bool weekday::ok() const NOEXCEPT {return 1 <= wd_ && wd_ <= 7;} CONSTCD11 inline bool operator==(const weekday& x, const weekday& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const weekday& x, const weekday& y) NOEXCEPT { return !(x == y); } CONSTCD14 inline days operator-(const weekday& x, const weekday& y) NOEXCEPT { auto const diff = static_cast(x) - static_cast(y); return days{diff <= 6 ? diff : diff + 7}; } CONSTCD14 inline weekday operator+(const weekday& x, const days& y) NOEXCEPT { auto const wdu = static_cast(static_cast(x) - 1u) + y.count(); auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7; return weekday{static_cast(wdu - wk * 7) + 1u}; } CONSTCD14 inline weekday operator+(const days& x, const weekday& y) NOEXCEPT { return y + x; } CONSTCD14 inline weekday operator-(const weekday& x, const days& y) NOEXCEPT { return x + -y; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday& wd) { switch (static_cast(wd)) { case 7: os << "Sun"; break; case 1: os << "Mon"; break; case 2: os << "Tue"; break; case 3: os << "Wed"; break; case 4: os << "Thu"; break; case 5: os << "Fri"; break; case 6: os << "Sat"; break; default: os << static_cast(wd) << " is not a valid weekday"; break; } return os; } // year CONSTCD11 inline year::year(int y) NOEXCEPT : y_(static_cast(y)) {} inline year& year::operator++() NOEXCEPT {++y_; return *this;} inline year year::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} inline year& year::operator--() NOEXCEPT {--y_; return *this;} inline year year::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} inline year& year::operator+=(const years& y) NOEXCEPT {*this = *this + y; return *this;} inline year& year::operator-=(const years& y) NOEXCEPT {*this = *this - y; return *this;} CONSTCD11 inline year::operator int() const NOEXCEPT {return y_;} CONSTCD11 inline bool year::ok() const NOEXCEPT {return min() <= *this && *this <= max();} CONSTCD11 inline year year::min() NOEXCEPT { using std::chrono::seconds; using std::chrono::minutes; using std::chrono::hours; using std::chrono::duration_cast; static_assert(sizeof(seconds)*CHAR_BIT >= 41, "seconds may overflow"); static_assert(sizeof(hours)*CHAR_BIT >= 30, "hours may overflow"); return sizeof(minutes)*CHAR_BIT < 34 ? year{1970} + duration_cast(minutes::min()) : year{std::numeric_limits::min()}; } CONSTCD11 inline year year::max() NOEXCEPT { using std::chrono::seconds; using std::chrono::minutes; using std::chrono::hours; using std::chrono::duration_cast; static_assert(sizeof(seconds)*CHAR_BIT >= 41, "seconds may overflow"); static_assert(sizeof(hours)*CHAR_BIT >= 30, "hours may overflow"); return sizeof(minutes)*CHAR_BIT < 34 ? year{1969} + duration_cast(minutes::max()) : year{std::numeric_limits::max()}; } CONSTCD11 inline bool operator==(const year& x, const year& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const year& x, const year& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year& x, const year& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const year& x, const year& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year& x, const year& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year& x, const year& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline years operator-(const year& x, const year& y) NOEXCEPT { return years{static_cast(x) - static_cast(y)}; } CONSTCD11 inline year operator+(const year& x, const years& y) NOEXCEPT { return year{static_cast(x) + y.count()}; } CONSTCD11 inline year operator+(const years& x, const year& y) NOEXCEPT { return y + x; } CONSTCD11 inline year operator-(const year& x, const years& y) NOEXCEPT { return year{static_cast(x) - y.count()}; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year& y) { date::detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::internal); os.width(4 + (y < year{0})); os << static_cast(y); return os; } #if !defined(_MSC_VER) || (_MSC_VER >= 1900) inline namespace literals { CONSTCD11 inline iso_week::year operator "" _y(unsigned long long y) NOEXCEPT { return iso_week::year(static_cast(y)); } CONSTCD11 inline iso_week::weeknum operator "" _w(unsigned long long wn) NOEXCEPT { return iso_week::weeknum(static_cast(wn)); } #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) CONSTDATA iso_week::last_week last{}; CONSTDATA iso_week::weekday sun{7u}; CONSTDATA iso_week::weekday mon{1u}; CONSTDATA iso_week::weekday tue{2u}; CONSTDATA iso_week::weekday wed{3u}; CONSTDATA iso_week::weekday thu{4u}; CONSTDATA iso_week::weekday fri{5u}; CONSTDATA iso_week::weekday sat{6u}; #if !defined(_MSC_VER) || (_MSC_VER >= 1900) } // inline namespace literals #endif // weeknum CONSTCD11 inline weeknum::weeknum(unsigned wn) NOEXCEPT : wn_(static_cast(wn)) {} inline weeknum& weeknum::operator++() NOEXCEPT {++wn_; return *this;} inline weeknum weeknum::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} inline weeknum& weeknum::operator--() NOEXCEPT {--wn_; return *this;} inline weeknum weeknum::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} inline weeknum& weeknum::operator+=(const weeks& y) NOEXCEPT { *this = *this + y; return *this; } inline weeknum& weeknum::operator-=(const weeks& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline weeknum::operator unsigned() const NOEXCEPT {return wn_;} CONSTCD11 inline bool weeknum::ok() const NOEXCEPT {return 1 <= wn_ && wn_ <= 53;} CONSTCD11 inline bool operator==(const weeknum& x, const weeknum& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const weeknum& x, const weeknum& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const weeknum& x, const weeknum& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const weeknum& x, const weeknum& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const weeknum& x, const weeknum& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const weeknum& x, const weeknum& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline weeks operator-(const weeknum& x, const weeknum& y) NOEXCEPT { return weeks{static_cast(static_cast(x)) - static_cast(static_cast(y))}; } CONSTCD11 inline weeknum operator+(const weeknum& x, const weeks& y) NOEXCEPT { return weeknum{static_cast(x) + static_cast(y.count())}; } CONSTCD11 inline weeknum operator+(const weeks& x, const weeknum& y) NOEXCEPT { return y + x; } CONSTCD11 inline weeknum operator-(const weeknum& x, const weeks& y) NOEXCEPT { return x + -y; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weeknum& wn) { date::detail::save_ostream _(os); os << 'W'; os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.width(2); os << static_cast(wn); return os; } // year_weeknum CONSTCD11 inline year_weeknum::year_weeknum(const iso_week::year& y, const iso_week::weeknum& wn) NOEXCEPT : y_(y) , wn_(wn) {} CONSTCD11 inline year year_weeknum::year() const NOEXCEPT {return y_;} CONSTCD11 inline weeknum year_weeknum::weeknum() const NOEXCEPT {return wn_;} CONSTCD11 inline bool year_weeknum::ok() const NOEXCEPT { return y_.ok() && 1u <= static_cast(wn_) && wn_ <= (y_/last).weeknum(); } inline year_weeknum& year_weeknum::operator+=(const years& dy) NOEXCEPT { *this = *this + dy; return *this; } inline year_weeknum& year_weeknum::operator-=(const years& dy) NOEXCEPT { *this = *this - dy; return *this; } CONSTCD11 inline bool operator==(const year_weeknum& x, const year_weeknum& y) NOEXCEPT { return x.year() == y.year() && x.weeknum() == y.weeknum(); } CONSTCD11 inline bool operator!=(const year_weeknum& x, const year_weeknum& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_weeknum& x, const year_weeknum& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.weeknum() < y.weeknum())); } CONSTCD11 inline bool operator>(const year_weeknum& x, const year_weeknum& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_weeknum& x, const year_weeknum& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_weeknum& x, const year_weeknum& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline year_weeknum operator+(const year_weeknum& ym, const years& dy) NOEXCEPT { return (ym.year() + dy) / ym.weeknum(); } CONSTCD11 inline year_weeknum operator+(const years& dy, const year_weeknum& ym) NOEXCEPT { return ym + dy; } CONSTCD11 inline year_weeknum operator-(const year_weeknum& ym, const years& dy) NOEXCEPT { return ym + -dy; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_weeknum& ywn) { return os << ywn.year() << '-' << ywn.weeknum(); } // year_lastweek CONSTCD11 inline year_lastweek::year_lastweek(const iso_week::year& y) NOEXCEPT : y_(y) {} CONSTCD11 inline year year_lastweek::year() const NOEXCEPT {return y_;} CONSTCD14 inline weeknum year_lastweek::weeknum() const NOEXCEPT { const auto y = date::year{static_cast(y_)}; const auto s0 = sys_days((y-years{1})/12/date::thu[date::last]); const auto s1 = sys_days(y/12/date::thu[date::last]); return iso_week::weeknum(static_cast(date::trunc(s1-s0).count())); } CONSTCD11 inline bool year_lastweek::ok() const NOEXCEPT {return y_.ok();} inline year_lastweek& year_lastweek::operator+=(const years& dy) NOEXCEPT { *this = *this + dy; return *this; } inline year_lastweek& year_lastweek::operator-=(const years& dy) NOEXCEPT { *this = *this - dy; return *this; } CONSTCD11 inline bool operator==(const year_lastweek& x, const year_lastweek& y) NOEXCEPT { return x.year() == y.year(); } CONSTCD11 inline bool operator!=(const year_lastweek& x, const year_lastweek& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_lastweek& x, const year_lastweek& y) NOEXCEPT { return x.year() < y.year(); } CONSTCD11 inline bool operator>(const year_lastweek& x, const year_lastweek& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_lastweek& x, const year_lastweek& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_lastweek& x, const year_lastweek& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline year_lastweek operator+(const year_lastweek& ym, const years& dy) NOEXCEPT { return year_lastweek{ym.year() + dy}; } CONSTCD11 inline year_lastweek operator+(const years& dy, const year_lastweek& ym) NOEXCEPT { return ym + dy; } CONSTCD11 inline year_lastweek operator-(const year_lastweek& ym, const years& dy) NOEXCEPT { return ym + -dy; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_lastweek& ywn) { return os << ywn.year() << "-W last"; } // weeknum_weekday CONSTCD11 inline weeknum_weekday::weeknum_weekday(const iso_week::weeknum& wn, const iso_week::weekday& wd) NOEXCEPT : wn_(wn) , wd_(wd) {} CONSTCD11 inline weeknum weeknum_weekday::weeknum() const NOEXCEPT {return wn_;} CONSTCD11 inline weekday weeknum_weekday::weekday() const NOEXCEPT {return wd_;} CONSTCD14 inline bool weeknum_weekday::ok() const NOEXCEPT { return wn_.ok() && wd_.ok(); } CONSTCD11 inline bool operator==(const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT { return x.weeknum() == y.weeknum() && x.weekday() == y.weekday(); } CONSTCD11 inline bool operator!=(const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT { return x.weeknum() < y.weeknum() ? true : (x.weeknum() > y.weeknum() ? false : (static_cast(x.weekday()) < static_cast(y.weekday()))); } CONSTCD11 inline bool operator>(const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weeknum_weekday& md) { return os << md.weeknum() << '-' << md.weekday(); } // lastweek_weekday CONSTCD11 inline lastweek_weekday::lastweek_weekday(const iso_week::weekday& wd) NOEXCEPT : wd_(wd) {} CONSTCD11 inline weekday lastweek_weekday::weekday() const NOEXCEPT {return wd_;} CONSTCD14 inline bool lastweek_weekday::ok() const NOEXCEPT { return wd_.ok(); } CONSTCD11 inline bool operator==(const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT { return x.weekday() == y.weekday(); } CONSTCD11 inline bool operator!=(const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT { return static_cast(x.weekday()) < static_cast(y.weekday()); } CONSTCD11 inline bool operator>(const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const lastweek_weekday& md) { return os << "W last-" << md.weekday(); } // year_lastweek_weekday CONSTCD11 inline year_lastweek_weekday::year_lastweek_weekday(const iso_week::year& y, const iso_week::weekday& wd) NOEXCEPT : y_(y) , wd_(wd) {} inline year_lastweek_weekday& year_lastweek_weekday::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } inline year_lastweek_weekday& year_lastweek_weekday::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_lastweek_weekday::year() const NOEXCEPT {return y_;} CONSTCD14 inline weeknum year_lastweek_weekday::weeknum() const NOEXCEPT { return (y_ / last).weeknum(); } CONSTCD11 inline weekday year_lastweek_weekday::weekday() const NOEXCEPT {return wd_;} CONSTCD14 inline year_lastweek_weekday::operator sys_days() const NOEXCEPT { return sys_days(date::year{static_cast(y_)}/date::dec/date::thu[date::last]) + (sun - thu) - (sun - wd_); } CONSTCD14 inline year_lastweek_weekday::operator local_days() const NOEXCEPT { return local_days(date::year{static_cast(y_)}/date::dec/date::thu[date::last]) + (sun - thu) - (sun - wd_); } CONSTCD11 inline bool year_lastweek_weekday::ok() const NOEXCEPT { return y_.ok() && wd_.ok(); } CONSTCD11 inline bool operator==(const year_lastweek_weekday& x, const year_lastweek_weekday& y) NOEXCEPT { return x.year() == y.year() && x.weekday() == y.weekday(); } CONSTCD11 inline bool operator!=(const year_lastweek_weekday& x, const year_lastweek_weekday& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_lastweek_weekday& x, const year_lastweek_weekday& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (static_cast(x.weekday()) < static_cast(y.weekday()))); } CONSTCD11 inline bool operator>(const year_lastweek_weekday& x, const year_lastweek_weekday& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_lastweek_weekday& x, const year_lastweek_weekday& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_lastweek_weekday& x, const year_lastweek_weekday& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline year_lastweek_weekday operator+(const year_lastweek_weekday& ywnwd, const years& y) NOEXCEPT { return (ywnwd.year() + y) / last / ywnwd.weekday(); } CONSTCD11 inline year_lastweek_weekday operator+(const years& y, const year_lastweek_weekday& ywnwd) NOEXCEPT { return ywnwd + y; } CONSTCD11 inline year_lastweek_weekday operator-(const year_lastweek_weekday& ywnwd, const years& y) NOEXCEPT { return ywnwd + -y; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_lastweek_weekday& ywnwd) { return os << ywnwd.year() << "-W last-" << ywnwd.weekday(); } // year_weeknum_weekday CONSTCD11 inline year_weeknum_weekday::year_weeknum_weekday(const iso_week::year& y, const iso_week::weeknum& wn, const iso_week::weekday& wd) NOEXCEPT : y_(y) , wn_(wn) , wd_(wd) {} CONSTCD14 inline year_weeknum_weekday::year_weeknum_weekday(const year_lastweek_weekday& ylwwd) NOEXCEPT : y_(ylwwd.year()) , wn_(ylwwd.weeknum()) , wd_(ylwwd.weekday()) {} CONSTCD14 inline year_weeknum_weekday::year_weeknum_weekday(const sys_days& dp) NOEXCEPT : year_weeknum_weekday(from_days(dp.time_since_epoch())) {} CONSTCD14 inline year_weeknum_weekday::year_weeknum_weekday(const local_days& dp) NOEXCEPT : year_weeknum_weekday(from_days(dp.time_since_epoch())) {} inline year_weeknum_weekday& year_weeknum_weekday::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } inline year_weeknum_weekday& year_weeknum_weekday::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_weeknum_weekday::year() const NOEXCEPT {return y_;} CONSTCD11 inline weeknum year_weeknum_weekday::weeknum() const NOEXCEPT {return wn_;} CONSTCD11 inline weekday year_weeknum_weekday::weekday() const NOEXCEPT {return wd_;} CONSTCD14 inline year_weeknum_weekday::operator sys_days() const NOEXCEPT { return sys_days(date::year{static_cast(y_)-1}/date::dec/date::thu[date::last]) + (date::mon - date::thu) + weeks{static_cast(wn_)-1} + (wd_ - mon); } CONSTCD14 inline year_weeknum_weekday::operator local_days() const NOEXCEPT { return local_days(date::year{static_cast(y_)-1}/date::dec/date::thu[date::last]) + (date::mon - date::thu) + weeks{static_cast(wn_)-1} + (wd_ - mon); } CONSTCD14 inline bool year_weeknum_weekday::ok() const NOEXCEPT { return y_.ok() && wd_.ok() && iso_week::weeknum{1u} <= wn_ && wn_ <= year_lastweek{y_}.weeknum(); } CONSTCD14 inline year_weeknum_weekday year_weeknum_weekday::from_days(days d) NOEXCEPT { const auto dp = sys_days{d}; const auto wd = iso_week::weekday{dp}; auto y = date::year_month_day{dp + days{3}}.year(); auto start = sys_days((y - date::years{1})/date::dec/date::thu[date::last]) + (mon-thu); if (dp < start) { --y; start = sys_days((y - date::years{1})/date::dec/date::thu[date::last]) + (mon-thu); } const auto wn = iso_week::weeknum( static_cast(date::trunc(dp - start).count() + 1)); return {iso_week::year(static_cast(y)), wn, wd}; } CONSTCD11 inline bool operator==(const year_weeknum_weekday& x, const year_weeknum_weekday& y) NOEXCEPT { return x.year() == y.year() && x.weeknum() == y.weeknum() && x.weekday() == y.weekday(); } CONSTCD11 inline bool operator!=(const year_weeknum_weekday& x, const year_weeknum_weekday& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_weeknum_weekday& x, const year_weeknum_weekday& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.weeknum() < y.weeknum() ? true : (x.weeknum() > y.weeknum() ? false : (static_cast(x.weekday()) < static_cast(y.weekday()))))); } CONSTCD11 inline bool operator>(const year_weeknum_weekday& x, const year_weeknum_weekday& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_weeknum_weekday& x, const year_weeknum_weekday& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_weeknum_weekday& x, const year_weeknum_weekday& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline year_weeknum_weekday operator+(const year_weeknum_weekday& ywnwd, const years& y) NOEXCEPT { return (ywnwd.year() + y) / ywnwd.weeknum() / ywnwd.weekday(); } CONSTCD11 inline year_weeknum_weekday operator+(const years& y, const year_weeknum_weekday& ywnwd) NOEXCEPT { return ywnwd + y; } CONSTCD11 inline year_weeknum_weekday operator-(const year_weeknum_weekday& ywnwd, const years& y) NOEXCEPT { return ywnwd + -y; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_weeknum_weekday& ywnwd) { return os << ywnwd.year() << '-' << ywnwd.weeknum() << '-' << ywnwd.weekday(); } // date composition operators CONSTCD11 inline year_weeknum operator/(const year& y, const weeknum& wn) NOEXCEPT { return {y, wn}; } CONSTCD11 inline year_weeknum operator/(const year& y, int wn) NOEXCEPT { return y/weeknum(static_cast(wn)); } CONSTCD11 inline year_lastweek operator/(const year& y, last_week) NOEXCEPT { return year_lastweek{y}; } CONSTCD11 inline weeknum_weekday operator/(const weeknum& wn, const weekday& wd) NOEXCEPT { return {wn, wd}; } CONSTCD11 inline weeknum_weekday operator/(const weeknum& wn, int wd) NOEXCEPT { return wn/weekday{static_cast(wd)}; } CONSTCD11 inline weeknum_weekday operator/(const weekday& wd, const weeknum& wn) NOEXCEPT { return wn/wd; } CONSTCD11 inline weeknum_weekday operator/(const weekday& wd, int wn) NOEXCEPT { return weeknum{static_cast(wn)}/wd; } CONSTCD11 inline lastweek_weekday operator/(const last_week&, const weekday& wd) NOEXCEPT { return lastweek_weekday{wd}; } CONSTCD11 inline lastweek_weekday operator/(const last_week& wn, int wd) NOEXCEPT { return wn / weekday{static_cast(wd)}; } CONSTCD11 inline lastweek_weekday operator/(const weekday& wd, const last_week& wn) NOEXCEPT { return wn / wd; } CONSTCD11 inline year_weeknum_weekday operator/(const year_weeknum& ywn, const weekday& wd) NOEXCEPT { return {ywn.year(), ywn.weeknum(), wd}; } CONSTCD11 inline year_weeknum_weekday operator/(const year_weeknum& ywn, int wd) NOEXCEPT { return ywn / weekday(static_cast(wd)); } CONSTCD11 inline year_weeknum_weekday operator/(const weeknum_weekday& wnwd, const year& y) NOEXCEPT { return {y, wnwd.weeknum(), wnwd.weekday()}; } CONSTCD11 inline year_weeknum_weekday operator/(const weeknum_weekday& wnwd, int y) NOEXCEPT { return wnwd / year{y}; } CONSTCD11 inline year_lastweek_weekday operator/(const year_lastweek& ylw, const weekday& wd) NOEXCEPT { return {ylw.year(), wd}; } CONSTCD11 inline year_lastweek_weekday operator/(const year_lastweek& ylw, int wd) NOEXCEPT { return ylw / weekday(static_cast(wd)); } CONSTCD11 inline year_lastweek_weekday operator/(const lastweek_weekday& lwwd, const year& y) NOEXCEPT { return {y, lwwd.weekday()}; } CONSTCD11 inline year_lastweek_weekday operator/(const lastweek_weekday& lwwd, int y) NOEXCEPT { return lwwd / year{y}; } } // namespace iso_week #endif // ISO_WEEK_H date-3.0.1/include/date/julian.h000066400000000000000000002144701403643451100164340ustar00rootroot00000000000000#ifndef JULIAN_H #define JULIAN_H // The MIT License (MIT) // // Copyright (c) 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // Our apologies. When the previous paragraph was written, lowercase had not yet // been invented (that would involve another several millennia of evolution). // We did not mean to shout. #include "date.h" namespace julian { // durations using days = date::days; using weeks = date::weeks; using years = std::chrono::duration , days::period>>; using months = std::chrono::duration >>; // time_point using sys_days = date::sys_days; using local_days = date::local_days; // types struct last_spec { explicit last_spec() = default; }; class day; class month; class year; class weekday; class weekday_indexed; class weekday_last; class month_day; class month_day_last; class month_weekday; class month_weekday_last; class year_month; class year_month_day; class year_month_day_last; class year_month_weekday; class year_month_weekday_last; // date composition operators CONSTCD11 year_month operator/(const year& y, const month& m) NOEXCEPT; CONSTCD11 year_month operator/(const year& y, int m) NOEXCEPT; CONSTCD11 month_day operator/(const day& d, const month& m) NOEXCEPT; CONSTCD11 month_day operator/(const day& d, int m) NOEXCEPT; CONSTCD11 month_day operator/(const month& m, const day& d) NOEXCEPT; CONSTCD11 month_day operator/(const month& m, int d) NOEXCEPT; CONSTCD11 month_day operator/(int m, const day& d) NOEXCEPT; CONSTCD11 month_day_last operator/(const month& m, last_spec) NOEXCEPT; CONSTCD11 month_day_last operator/(int m, last_spec) NOEXCEPT; CONSTCD11 month_day_last operator/(last_spec, const month& m) NOEXCEPT; CONSTCD11 month_day_last operator/(last_spec, int m) NOEXCEPT; CONSTCD11 month_weekday operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT; CONSTCD11 month_weekday operator/(int m, const weekday_indexed& wdi) NOEXCEPT; CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT; CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, int m) NOEXCEPT; CONSTCD11 month_weekday_last operator/(const month& m, const weekday_last& wdl) NOEXCEPT; CONSTCD11 month_weekday_last operator/(int m, const weekday_last& wdl) NOEXCEPT; CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, const month& m) NOEXCEPT; CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, int m) NOEXCEPT; CONSTCD11 year_month_day operator/(const year_month& ym, const day& d) NOEXCEPT; CONSTCD11 year_month_day operator/(const year_month& ym, int d) NOEXCEPT; CONSTCD11 year_month_day operator/(const year& y, const month_day& md) NOEXCEPT; CONSTCD11 year_month_day operator/(int y, const month_day& md) NOEXCEPT; CONSTCD11 year_month_day operator/(const month_day& md, const year& y) NOEXCEPT; CONSTCD11 year_month_day operator/(const month_day& md, int y) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const year_month& ym, last_spec) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const year& y, const month_day_last& mdl) NOEXCEPT; CONSTCD11 year_month_day_last operator/(int y, const month_day_last& mdl) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const month_day_last& mdl, const year& y) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const month_day_last& mdl, int y) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const year& y, const month_weekday& mwd) NOEXCEPT; CONSTCD11 year_month_weekday operator/(int y, const month_weekday& mwd) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const month_weekday& mwd, const year& y) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const month_weekday& mwd, int y) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(int y, const month_weekday_last& mwdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) NOEXCEPT; // Detailed interface // day class day { unsigned char d_; public: explicit CONSTCD11 day(unsigned d) NOEXCEPT; CONSTCD14 day& operator++() NOEXCEPT; CONSTCD14 day operator++(int) NOEXCEPT; CONSTCD14 day& operator--() NOEXCEPT; CONSTCD14 day operator--(int) NOEXCEPT; CONSTCD14 day& operator+=(const days& d) NOEXCEPT; CONSTCD14 day& operator-=(const days& d) NOEXCEPT; CONSTCD11 explicit operator unsigned() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator!=(const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator< (const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator> (const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator<=(const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator>=(const day& x, const day& y) NOEXCEPT; CONSTCD11 day operator+(const day& x, const days& y) NOEXCEPT; CONSTCD11 day operator+(const days& x, const day& y) NOEXCEPT; CONSTCD11 day operator-(const day& x, const days& y) NOEXCEPT; CONSTCD11 days operator-(const day& x, const day& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const day& d); // month class month { unsigned char m_; public: explicit CONSTCD11 month(unsigned m) NOEXCEPT; CONSTCD14 month& operator++() NOEXCEPT; CONSTCD14 month operator++(int) NOEXCEPT; CONSTCD14 month& operator--() NOEXCEPT; CONSTCD14 month operator--(int) NOEXCEPT; CONSTCD14 month& operator+=(const months& m) NOEXCEPT; CONSTCD14 month& operator-=(const months& m) NOEXCEPT; CONSTCD11 explicit operator unsigned() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator!=(const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator< (const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator> (const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator<=(const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator>=(const month& x, const month& y) NOEXCEPT; CONSTCD14 month operator+(const month& x, const months& y) NOEXCEPT; CONSTCD14 month operator+(const months& x, const month& y) NOEXCEPT; CONSTCD14 month operator-(const month& x, const months& y) NOEXCEPT; CONSTCD14 months operator-(const month& x, const month& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month& m); // year class year { short y_; public: explicit CONSTCD11 year(int y) NOEXCEPT; CONSTCD14 year& operator++() NOEXCEPT; CONSTCD14 year operator++(int) NOEXCEPT; CONSTCD14 year& operator--() NOEXCEPT; CONSTCD14 year operator--(int) NOEXCEPT; CONSTCD14 year& operator+=(const years& y) NOEXCEPT; CONSTCD14 year& operator-=(const years& y) NOEXCEPT; CONSTCD11 bool is_leap() const NOEXCEPT; CONSTCD11 explicit operator int() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; static CONSTCD11 year min() NOEXCEPT; static CONSTCD11 year max() NOEXCEPT; }; CONSTCD11 bool operator==(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator!=(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator< (const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator> (const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator<=(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator>=(const year& x, const year& y) NOEXCEPT; CONSTCD11 year operator+(const year& x, const years& y) NOEXCEPT; CONSTCD11 year operator+(const years& x, const year& y) NOEXCEPT; CONSTCD11 year operator-(const year& x, const years& y) NOEXCEPT; CONSTCD11 years operator-(const year& x, const year& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year& y); // weekday class weekday { unsigned char wd_; public: explicit CONSTCD11 weekday(unsigned wd) NOEXCEPT; explicit weekday(int) = delete; CONSTCD11 weekday(const sys_days& dp) NOEXCEPT; CONSTCD11 explicit weekday(const local_days& dp) NOEXCEPT; CONSTCD14 weekday& operator++() NOEXCEPT; CONSTCD14 weekday operator++(int) NOEXCEPT; CONSTCD14 weekday& operator--() NOEXCEPT; CONSTCD14 weekday operator--(int) NOEXCEPT; CONSTCD14 weekday& operator+=(const days& d) NOEXCEPT; CONSTCD14 weekday& operator-=(const days& d) NOEXCEPT; CONSTCD11 explicit operator unsigned() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; CONSTCD11 weekday_indexed operator[](unsigned index) const NOEXCEPT; CONSTCD11 weekday_last operator[](last_spec) const NOEXCEPT; private: static CONSTCD11 unsigned char weekday_from_days(int z) NOEXCEPT; }; CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday& x, const weekday& y) NOEXCEPT; CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT; CONSTCD14 weekday operator+(const days& x, const weekday& y) NOEXCEPT; CONSTCD14 weekday operator-(const weekday& x, const days& y) NOEXCEPT; CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday& wd); // weekday_indexed class weekday_indexed { unsigned char wd_ : 4; unsigned char index_ : 4; public: CONSTCD11 weekday_indexed(const julian::weekday& wd, unsigned index) NOEXCEPT; CONSTCD11 julian::weekday weekday() const NOEXCEPT; CONSTCD11 unsigned index() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_indexed& wdi); // weekday_last class weekday_last { julian::weekday wd_; public: explicit CONSTCD11 weekday_last(const julian::weekday& wd) NOEXCEPT; CONSTCD11 julian::weekday weekday() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_last& wdl); // year_month class year_month { julian::year y_; julian::month m_; public: CONSTCD11 year_month(const julian::year& y, const julian::month& m) NOEXCEPT; CONSTCD11 julian::year year() const NOEXCEPT; CONSTCD11 julian::month month() const NOEXCEPT; CONSTCD14 year_month& operator+=(const months& dm) NOEXCEPT; CONSTCD14 year_month& operator-=(const months& dm) NOEXCEPT; CONSTCD14 year_month& operator+=(const years& dy) NOEXCEPT; CONSTCD14 year_month& operator-=(const years& dy) NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator< (const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator> (const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD14 year_month operator+(const year_month& ym, const months& dm) NOEXCEPT; CONSTCD14 year_month operator+(const months& dm, const year_month& ym) NOEXCEPT; CONSTCD14 year_month operator-(const year_month& ym, const months& dm) NOEXCEPT; CONSTCD11 months operator-(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 year_month operator+(const year_month& ym, const years& dy) NOEXCEPT; CONSTCD11 year_month operator+(const years& dy, const year_month& ym) NOEXCEPT; CONSTCD11 year_month operator-(const year_month& ym, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month& ym); // month_day class month_day { julian::month m_; julian::day d_; public: CONSTCD11 month_day(const julian::month& m, const julian::day& d) NOEXCEPT; CONSTCD11 julian::month month() const NOEXCEPT; CONSTCD11 julian::day day() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator< (const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator> (const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator<=(const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator>=(const month_day& x, const month_day& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_day& md); // month_day_last class month_day_last { julian::month m_; public: CONSTCD11 explicit month_day_last(const julian::month& m) NOEXCEPT; CONSTCD11 julian::month month() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator< (const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator> (const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_day_last& mdl); // month_weekday class month_weekday { julian::month m_; julian::weekday_indexed wdi_; public: CONSTCD11 month_weekday(const julian::month& m, const julian::weekday_indexed& wdi) NOEXCEPT; CONSTCD11 julian::month month() const NOEXCEPT; CONSTCD11 julian::weekday_indexed weekday_indexed() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday& mwd); // month_weekday_last class month_weekday_last { julian::month m_; julian::weekday_last wdl_; public: CONSTCD11 month_weekday_last(const julian::month& m, const julian::weekday_last& wd) NOEXCEPT; CONSTCD11 julian::month month() const NOEXCEPT; CONSTCD11 julian::weekday_last weekday_last() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday_last& mwdl); // class year_month_day class year_month_day { julian::year y_; julian::month m_; julian::day d_; public: CONSTCD11 year_month_day(const julian::year& y, const julian::month& m, const julian::day& d) NOEXCEPT; CONSTCD14 year_month_day(const year_month_day_last& ymdl) NOEXCEPT; CONSTCD14 year_month_day(sys_days dp) NOEXCEPT; CONSTCD14 explicit year_month_day(local_days dp) NOEXCEPT; CONSTCD14 year_month_day& operator+=(const months& m) NOEXCEPT; CONSTCD14 year_month_day& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_day& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_day& operator-=(const years& y) NOEXCEPT; CONSTCD11 julian::year year() const NOEXCEPT; CONSTCD11 julian::month month() const NOEXCEPT; CONSTCD11 julian::day day() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; private: static CONSTCD14 year_month_day from_days(days dp) NOEXCEPT; CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator< (const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator> (const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD14 year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT; CONSTCD14 year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT; CONSTCD14 year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT; CONSTCD11 year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT; CONSTCD11 year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT; CONSTCD11 year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day& ymd); // year_month_day_last class year_month_day_last { julian::year y_; julian::month_day_last mdl_; public: CONSTCD11 year_month_day_last(const julian::year& y, const julian::month_day_last& mdl) NOEXCEPT; CONSTCD14 year_month_day_last& operator+=(const months& m) NOEXCEPT; CONSTCD14 year_month_day_last& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_day_last& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_day_last& operator-=(const years& y) NOEXCEPT; CONSTCD11 julian::year year() const NOEXCEPT; CONSTCD11 julian::month month() const NOEXCEPT; CONSTCD11 julian::month_day_last month_day_last() const NOEXCEPT; CONSTCD14 julian::day day() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator< (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator> (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD14 year_month_day_last operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; CONSTCD14 year_month_day_last operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT; CONSTCD11 year_month_day_last operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; CONSTCD11 year_month_day_last operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT; CONSTCD14 year_month_day_last operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; CONSTCD11 year_month_day_last operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day_last& ymdl); // year_month_weekday class year_month_weekday { julian::year y_; julian::month m_; julian::weekday_indexed wdi_; public: CONSTCD11 year_month_weekday(const julian::year& y, const julian::month& m, const julian::weekday_indexed& wdi) NOEXCEPT; CONSTCD14 year_month_weekday(const sys_days& dp) NOEXCEPT; CONSTCD14 explicit year_month_weekday(const local_days& dp) NOEXCEPT; CONSTCD14 year_month_weekday& operator+=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_weekday& operator-=(const years& y) NOEXCEPT; CONSTCD11 julian::year year() const NOEXCEPT; CONSTCD11 julian::month month() const NOEXCEPT; CONSTCD11 julian::weekday weekday() const NOEXCEPT; CONSTCD11 unsigned index() const NOEXCEPT; CONSTCD11 julian::weekday_indexed weekday_indexed() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; private: static CONSTCD14 year_month_weekday from_days(days dp) NOEXCEPT; CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; CONSTCD14 year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; CONSTCD14 year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT; CONSTCD11 year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; CONSTCD11 year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT; CONSTCD14 year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; CONSTCD11 year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi); // year_month_weekday_last class year_month_weekday_last { julian::year y_; julian::month m_; julian::weekday_last wdl_; public: CONSTCD11 year_month_weekday_last(const julian::year& y, const julian::month& m, const julian::weekday_last& wdl) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator+=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator-=(const years& y) NOEXCEPT; CONSTCD11 julian::year year() const NOEXCEPT; CONSTCD11 julian::month month() const NOEXCEPT; CONSTCD11 julian::weekday weekday() const NOEXCEPT; CONSTCD11 julian::weekday_last weekday_last() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; private: CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; CONSTCD14 year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; CONSTCD14 year_month_weekday_last operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; CONSTCD11 year_month_weekday_last operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT; CONSTCD14 year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; CONSTCD11 year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl); #if !defined(_MSC_VER) || (_MSC_VER >= 1900) inline namespace literals { CONSTCD11 julian::day operator "" _d(unsigned long long d) NOEXCEPT; CONSTCD11 julian::year operator "" _y(unsigned long long y) NOEXCEPT; // CONSTDATA julian::month jan{1}; // CONSTDATA julian::month feb{2}; // CONSTDATA julian::month mar{3}; // CONSTDATA julian::month apr{4}; // CONSTDATA julian::month may{5}; // CONSTDATA julian::month jun{6}; // CONSTDATA julian::month jul{7}; // CONSTDATA julian::month aug{8}; // CONSTDATA julian::month sep{9}; // CONSTDATA julian::month oct{10}; // CONSTDATA julian::month nov{11}; // CONSTDATA julian::month dec{12}; } // inline namespace literals #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) //----------------+ // Implementation | //----------------+ // day CONSTCD11 inline day::day(unsigned d) NOEXCEPT : d_(static_cast(d)) {} CONSTCD14 inline day& day::operator++() NOEXCEPT {++d_; return *this;} CONSTCD14 inline day day::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline day& day::operator--() NOEXCEPT {--d_; return *this;} CONSTCD14 inline day day::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline day& day::operator+=(const days& d) NOEXCEPT {*this = *this + d; return *this;} CONSTCD14 inline day& day::operator-=(const days& d) NOEXCEPT {*this = *this - d; return *this;} CONSTCD11 inline day::operator unsigned() const NOEXCEPT {return d_;} CONSTCD11 inline bool day::ok() const NOEXCEPT {return 1 <= d_ && d_ <= 31;} CONSTCD11 inline bool operator==(const day& x, const day& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const day& x, const day& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const day& x, const day& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const day& x, const day& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const day& x, const day& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const day& x, const day& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline days operator-(const day& x, const day& y) NOEXCEPT { return days{static_cast(static_cast(x) - static_cast(y))}; } CONSTCD11 inline day operator+(const day& x, const days& y) NOEXCEPT { return day{static_cast(x) + static_cast(y.count())}; } CONSTCD11 inline day operator+(const days& x, const day& y) NOEXCEPT { return y + x; } CONSTCD11 inline day operator-(const day& x, const days& y) NOEXCEPT { return x + -y; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const day& d) { date::detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.width(2); os << static_cast(d); return os; } // month CONSTCD11 inline month::month(unsigned m) NOEXCEPT : m_(static_cast(m)) {} CONSTCD14 inline month& month::operator++() NOEXCEPT {if (++m_ == 13) m_ = 1; return *this;} CONSTCD14 inline month month::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline month& month::operator--() NOEXCEPT {if (--m_ == 0) m_ = 12; return *this;} CONSTCD14 inline month month::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline month& month::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline month& month::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD11 inline month::operator unsigned() const NOEXCEPT {return m_;} CONSTCD11 inline bool month::ok() const NOEXCEPT {return 1 <= m_ && m_ <= 12;} CONSTCD11 inline bool operator==(const month& x, const month& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const month& x, const month& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const month& x, const month& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const month& x, const month& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const month& x, const month& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const month& x, const month& y) NOEXCEPT { return !(x < y); } CONSTCD14 inline months operator-(const month& x, const month& y) NOEXCEPT { auto const d = static_cast(x) - static_cast(y); return months(d <= 11 ? d : d + 12); } CONSTCD14 inline month operator+(const month& x, const months& y) NOEXCEPT { auto const mu = static_cast(static_cast(x)) - 1 + y.count(); auto const yr = (mu >= 0 ? mu : mu-11) / 12; return month{static_cast(mu - yr * 12 + 1)}; } CONSTCD14 inline month operator+(const months& x, const month& y) NOEXCEPT { return y + x; } CONSTCD14 inline month operator-(const month& x, const months& y) NOEXCEPT { return x + -y; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month& m) { switch (static_cast(m)) { case 1: os << "Jan"; break; case 2: os << "Feb"; break; case 3: os << "Mar"; break; case 4: os << "Apr"; break; case 5: os << "May"; break; case 6: os << "Jun"; break; case 7: os << "Jul"; break; case 8: os << "Aug"; break; case 9: os << "Sep"; break; case 10: os << "Oct"; break; case 11: os << "Nov"; break; case 12: os << "Dec"; break; default: os << static_cast(m) << " is not a valid month"; break; } return os; } // year CONSTCD11 inline year::year(int y) NOEXCEPT : y_(static_cast(y)) {} CONSTCD14 inline year& year::operator++() NOEXCEPT {++y_; return *this;} CONSTCD14 inline year year::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline year& year::operator--() NOEXCEPT {--y_; return *this;} CONSTCD14 inline year year::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline year& year::operator+=(const years& y) NOEXCEPT {*this = *this + y; return *this;} CONSTCD14 inline year& year::operator-=(const years& y) NOEXCEPT {*this = *this - y; return *this;} CONSTCD11 inline bool year::is_leap() const NOEXCEPT { return y_ % 4 == 0; } CONSTCD11 inline year::operator int() const NOEXCEPT {return y_;} CONSTCD11 inline bool year::ok() const NOEXCEPT {return true;} CONSTCD11 inline year year::min() NOEXCEPT { return year{std::numeric_limits::min()}; } CONSTCD11 inline year year::max() NOEXCEPT { return year{std::numeric_limits::max()}; } CONSTCD11 inline bool operator==(const year& x, const year& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const year& x, const year& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year& x, const year& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const year& x, const year& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year& x, const year& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year& x, const year& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline years operator-(const year& x, const year& y) NOEXCEPT { return years{static_cast(x) - static_cast(y)}; } CONSTCD11 inline year operator+(const year& x, const years& y) NOEXCEPT { return year{static_cast(x) + y.count()}; } CONSTCD11 inline year operator+(const years& x, const year& y) NOEXCEPT { return y + x; } CONSTCD11 inline year operator-(const year& x, const years& y) NOEXCEPT { return year{static_cast(x) - y.count()}; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year& y) { date::detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::internal); os.width(4 + (y < year{0})); os << static_cast(y); return os; } // weekday CONSTCD11 inline unsigned char weekday::weekday_from_days(int z) NOEXCEPT { return static_cast(static_cast( z >= -4 ? (z+4) % 7 : (z+5) % 7 + 6)); } CONSTCD11 inline weekday::weekday(unsigned wd) NOEXCEPT : wd_(static_cast(wd)) {} CONSTCD11 inline weekday::weekday(const sys_days& dp) NOEXCEPT : wd_(weekday_from_days(dp.time_since_epoch().count())) {} CONSTCD11 inline weekday::weekday(const local_days& dp) NOEXCEPT : wd_(weekday_from_days(dp.time_since_epoch().count())) {} CONSTCD14 inline weekday& weekday::operator++() NOEXCEPT {if (++wd_ == 7) wd_ = 0; return *this;} CONSTCD14 inline weekday weekday::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline weekday& weekday::operator--() NOEXCEPT {if (wd_-- == 0) wd_ = 6; return *this;} CONSTCD14 inline weekday weekday::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline weekday& weekday::operator+=(const days& d) NOEXCEPT { *this = *this + d; return *this; } CONSTCD14 inline weekday& weekday::operator-=(const days& d) NOEXCEPT { *this = *this - d; return *this; } CONSTCD11 inline weekday::operator unsigned() const NOEXCEPT { return static_cast(wd_); } CONSTCD11 inline bool weekday::ok() const NOEXCEPT {return wd_ <= 6;} CONSTCD11 inline bool operator==(const weekday& x, const weekday& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const weekday& x, const weekday& y) NOEXCEPT { return !(x == y); } CONSTCD14 inline days operator-(const weekday& x, const weekday& y) NOEXCEPT { auto const diff = static_cast(x) - static_cast(y); return days{diff <= 6 ? diff : diff + 7}; } CONSTCD14 inline weekday operator+(const weekday& x, const days& y) NOEXCEPT { auto const wdu = static_cast(static_cast(x)) + y.count(); auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7; return weekday{static_cast(wdu - wk * 7)}; } CONSTCD14 inline weekday operator+(const days& x, const weekday& y) NOEXCEPT { return y + x; } CONSTCD14 inline weekday operator-(const weekday& x, const days& y) NOEXCEPT { return x + -y; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday& wd) { switch (static_cast(wd)) { case 0: os << "Sun"; break; case 1: os << "Mon"; break; case 2: os << "Tue"; break; case 3: os << "Wed"; break; case 4: os << "Thu"; break; case 5: os << "Fri"; break; case 6: os << "Sat"; break; default: os << static_cast(wd) << " is not a valid weekday"; break; } return os; } #if !defined(_MSC_VER) || (_MSC_VER >= 1900) inline namespace literals { CONSTCD11 inline julian::day operator "" _d(unsigned long long d) NOEXCEPT { return julian::day{static_cast(d)}; } CONSTCD11 inline julian::year operator "" _y(unsigned long long y) NOEXCEPT { return julian::year(static_cast(y)); } #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) CONSTDATA julian::last_spec last{}; CONSTDATA julian::month jan{1}; CONSTDATA julian::month feb{2}; CONSTDATA julian::month mar{3}; CONSTDATA julian::month apr{4}; CONSTDATA julian::month may{5}; CONSTDATA julian::month jun{6}; CONSTDATA julian::month jul{7}; CONSTDATA julian::month aug{8}; CONSTDATA julian::month sep{9}; CONSTDATA julian::month oct{10}; CONSTDATA julian::month nov{11}; CONSTDATA julian::month dec{12}; CONSTDATA julian::weekday sun{0u}; CONSTDATA julian::weekday mon{1u}; CONSTDATA julian::weekday tue{2u}; CONSTDATA julian::weekday wed{3u}; CONSTDATA julian::weekday thu{4u}; CONSTDATA julian::weekday fri{5u}; CONSTDATA julian::weekday sat{6u}; #if !defined(_MSC_VER) || (_MSC_VER >= 1900) } // inline namespace literals #endif // weekday_indexed CONSTCD11 inline weekday weekday_indexed::weekday() const NOEXCEPT { return julian::weekday{static_cast(wd_)}; } CONSTCD11 inline unsigned weekday_indexed::index() const NOEXCEPT {return index_;} CONSTCD11 inline bool weekday_indexed::ok() const NOEXCEPT { return weekday().ok() && 1 <= index_ && index_ <= 5; } CONSTCD11 inline weekday_indexed::weekday_indexed(const julian::weekday& wd, unsigned index) NOEXCEPT : wd_(static_cast(static_cast(wd))) , index_(static_cast(index)) {} template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_indexed& wdi) { return os << wdi.weekday() << '[' << wdi.index() << ']'; } CONSTCD11 inline weekday_indexed weekday::operator[](unsigned index) const NOEXCEPT { return {*this, index}; } CONSTCD11 inline bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT { return x.weekday() == y.weekday() && x.index() == y.index(); } CONSTCD11 inline bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT { return !(x == y); } // weekday_last CONSTCD11 inline julian::weekday weekday_last::weekday() const NOEXCEPT {return wd_;} CONSTCD11 inline bool weekday_last::ok() const NOEXCEPT {return wd_.ok();} CONSTCD11 inline weekday_last::weekday_last(const julian::weekday& wd) NOEXCEPT : wd_(wd) {} CONSTCD11 inline bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT { return x.weekday() == y.weekday(); } CONSTCD11 inline bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_last& wdl) { return os << wdl.weekday() << "[last]"; } CONSTCD11 inline weekday_last weekday::operator[](last_spec) const NOEXCEPT { return weekday_last{*this}; } // year_month CONSTCD11 inline year_month::year_month(const julian::year& y, const julian::month& m) NOEXCEPT : y_(y) , m_(m) {} CONSTCD11 inline year year_month::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month::month() const NOEXCEPT {return m_;} CONSTCD11 inline bool year_month::ok() const NOEXCEPT {return y_.ok() && m_.ok();} CONSTCD14 inline year_month& year_month::operator+=(const months& dm) NOEXCEPT { *this = *this + dm; return *this; } CONSTCD14 inline year_month& year_month::operator-=(const months& dm) NOEXCEPT { *this = *this - dm; return *this; } CONSTCD14 inline year_month& year_month::operator+=(const years& dy) NOEXCEPT { *this = *this + dy; return *this; } CONSTCD14 inline year_month& year_month::operator-=(const years& dy) NOEXCEPT { *this = *this - dy; return *this; } CONSTCD11 inline bool operator==(const year_month& x, const year_month& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month(); } CONSTCD11 inline bool operator!=(const year_month& x, const year_month& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_month& x, const year_month& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.month() < y.month())); } CONSTCD11 inline bool operator>(const year_month& x, const year_month& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_month& x, const year_month& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_month& x, const year_month& y) NOEXCEPT { return !(x < y); } CONSTCD14 inline year_month operator+(const year_month& ym, const months& dm) NOEXCEPT { auto dmi = static_cast(static_cast(ym.month())) - 1 + dm.count(); auto dy = (dmi >= 0 ? dmi : dmi-11) / 12; dmi = dmi - dy * 12 + 1; return (ym.year() + years(dy)) / month(static_cast(dmi)); } CONSTCD14 inline year_month operator+(const months& dm, const year_month& ym) NOEXCEPT { return ym + dm; } CONSTCD14 inline year_month operator-(const year_month& ym, const months& dm) NOEXCEPT { return ym + -dm; } CONSTCD11 inline months operator-(const year_month& x, const year_month& y) NOEXCEPT { return (x.year() - y.year()) + months(static_cast(x.month()) - static_cast(y.month())); } CONSTCD11 inline year_month operator+(const year_month& ym, const years& dy) NOEXCEPT { return (ym.year() + dy) / ym.month(); } CONSTCD11 inline year_month operator+(const years& dy, const year_month& ym) NOEXCEPT { return ym + dy; } CONSTCD11 inline year_month operator-(const year_month& ym, const years& dy) NOEXCEPT { return ym + -dy; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month& ym) { return os << ym.year() << '/' << ym.month(); } // month_day CONSTCD11 inline month_day::month_day(const julian::month& m, const julian::day& d) NOEXCEPT : m_(m) , d_(d) {} CONSTCD11 inline julian::month month_day::month() const NOEXCEPT {return m_;} CONSTCD11 inline julian::day month_day::day() const NOEXCEPT {return d_;} CONSTCD14 inline bool month_day::ok() const NOEXCEPT { CONSTDATA julian::day d[] = { julian::day(31), julian::day(29), julian::day(31), julian::day(30), julian::day(31), julian::day(30), julian::day(31), julian::day(31), julian::day(30), julian::day(31), julian::day(30), julian::day(31) }; return m_.ok() && julian::day(1) <= d_ && d_ <= d[static_cast(m_)-1]; } CONSTCD11 inline bool operator==(const month_day& x, const month_day& y) NOEXCEPT { return x.month() == y.month() && x.day() == y.day(); } CONSTCD11 inline bool operator!=(const month_day& x, const month_day& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const month_day& x, const month_day& y) NOEXCEPT { return x.month() < y.month() ? true : (x.month() > y.month() ? false : (x.day() < y.day())); } CONSTCD11 inline bool operator>(const month_day& x, const month_day& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const month_day& x, const month_day& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const month_day& x, const month_day& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_day& md) { return os << md.month() << '/' << md.day(); } // month_day_last CONSTCD11 inline month month_day_last::month() const NOEXCEPT {return m_;} CONSTCD11 inline bool month_day_last::ok() const NOEXCEPT {return m_.ok();} CONSTCD11 inline month_day_last::month_day_last(const julian::month& m) NOEXCEPT : m_(m) {} CONSTCD11 inline bool operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT { return x.month() == y.month(); } CONSTCD11 inline bool operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const month_day_last& x, const month_day_last& y) NOEXCEPT { return x.month() < y.month(); } CONSTCD11 inline bool operator>(const month_day_last& x, const month_day_last& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_day_last& mdl) { return os << mdl.month() << "/last"; } // month_weekday CONSTCD11 inline month_weekday::month_weekday(const julian::month& m, const julian::weekday_indexed& wdi) NOEXCEPT : m_(m) , wdi_(wdi) {} CONSTCD11 inline month month_weekday::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday_indexed month_weekday::weekday_indexed() const NOEXCEPT { return wdi_; } CONSTCD11 inline bool month_weekday::ok() const NOEXCEPT { return m_.ok() && wdi_.ok(); } CONSTCD11 inline bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT { return x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed(); } CONSTCD11 inline bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday& mwd) { return os << mwd.month() << '/' << mwd.weekday_indexed(); } // month_weekday_last CONSTCD11 inline month_weekday_last::month_weekday_last(const julian::month& m, const julian::weekday_last& wdl) NOEXCEPT : m_(m) , wdl_(wdl) {} CONSTCD11 inline month month_weekday_last::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday_last month_weekday_last::weekday_last() const NOEXCEPT { return wdl_; } CONSTCD11 inline bool month_weekday_last::ok() const NOEXCEPT { return m_.ok() && wdl_.ok(); } CONSTCD11 inline bool operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT { return x.month() == y.month() && x.weekday_last() == y.weekday_last(); } CONSTCD11 inline bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday_last& mwdl) { return os << mwdl.month() << '/' << mwdl.weekday_last(); } // year_month_day_last CONSTCD11 inline year_month_day_last::year_month_day_last(const julian::year& y, const julian::month_day_last& mdl) NOEXCEPT : y_(y) , mdl_(mdl) {} CONSTCD14 inline year_month_day_last& year_month_day_last::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline year_month_day_last& year_month_day_last::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_day_last& year_month_day_last::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_day_last& year_month_day_last::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_month_day_last::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_day_last::month() const NOEXCEPT {return mdl_.month();} CONSTCD11 inline month_day_last year_month_day_last::month_day_last() const NOEXCEPT { return mdl_; } CONSTCD14 inline day year_month_day_last::day() const NOEXCEPT { CONSTDATA julian::day d[] = { julian::day(31), julian::day(28), julian::day(31), julian::day(30), julian::day(31), julian::day(30), julian::day(31), julian::day(31), julian::day(30), julian::day(31), julian::day(30), julian::day(31) }; return month() != feb || !y_.is_leap() ? d[static_cast(month())-1] : julian::day(29); } CONSTCD14 inline year_month_day_last::operator sys_days() const NOEXCEPT { return sys_days(year()/month()/day()); } CONSTCD14 inline year_month_day_last::operator local_days() const NOEXCEPT { return local_days(year()/month()/day()); } CONSTCD11 inline bool year_month_day_last::ok() const NOEXCEPT { return y_.ok() && mdl_.ok(); } CONSTCD11 inline bool operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return x.year() == y.year() && x.month_day_last() == y.month_day_last(); } CONSTCD11 inline bool operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.month_day_last() < y.month_day_last())); } CONSTCD11 inline bool operator>(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day_last& ymdl) { return os << ymdl.year() << '/' << ymdl.month_day_last(); } CONSTCD14 inline year_month_day_last operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT { return (ymdl.year() / ymdl.month() + dm) / last; } CONSTCD14 inline year_month_day_last operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT { return ymdl + dm; } CONSTCD14 inline year_month_day_last operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT { return ymdl + (-dm); } CONSTCD11 inline year_month_day_last operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT { return {ymdl.year()+dy, ymdl.month_day_last()}; } CONSTCD11 inline year_month_day_last operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT { return ymdl + dy; } CONSTCD11 inline year_month_day_last operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT { return ymdl + (-dy); } // year_month_day CONSTCD11 inline year_month_day::year_month_day(const julian::year& y, const julian::month& m, const julian::day& d) NOEXCEPT : y_(y) , m_(m) , d_(d) {} CONSTCD14 inline year_month_day::year_month_day(const year_month_day_last& ymdl) NOEXCEPT : y_(ymdl.year()) , m_(ymdl.month()) , d_(ymdl.day()) {} CONSTCD14 inline year_month_day::year_month_day(sys_days dp) NOEXCEPT : year_month_day(from_days(dp.time_since_epoch())) {} CONSTCD14 inline year_month_day::year_month_day(local_days dp) NOEXCEPT : year_month_day(from_days(dp.time_since_epoch())) {} CONSTCD11 inline year year_month_day::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_day::month() const NOEXCEPT {return m_;} CONSTCD11 inline day year_month_day::day() const NOEXCEPT {return d_;} CONSTCD14 inline year_month_day& year_month_day::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline year_month_day& year_month_day::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_day& year_month_day::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_day& year_month_day::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD14 inline days year_month_day::to_days() const NOEXCEPT { static_assert(std::numeric_limits::digits >= 18, "This algorithm has not been ported to a 16 bit unsigned integer"); static_assert(std::numeric_limits::digits >= 20, "This algorithm has not been ported to a 16 bit signed integer"); auto const y = static_cast(y_) - (m_ <= feb); auto const m = static_cast(m_); auto const d = static_cast(d_); auto const era = (y >= 0 ? y : y-3) / 4; auto const yoe = static_cast(y - era * 4); // [0, 3] auto const doy = (153*(m > 2 ? m-3 : m+9) + 2)/5 + d-1; // [0, 365] auto const doe = yoe * 365 + doy; // [0, 1460] return days{era * 1461 + static_cast(doe) - 719470}; } CONSTCD14 inline year_month_day::operator sys_days() const NOEXCEPT { return sys_days{to_days()}; } CONSTCD14 inline year_month_day::operator local_days() const NOEXCEPT { return local_days{to_days()}; } CONSTCD14 inline bool year_month_day::ok() const NOEXCEPT { if (!(y_.ok() && m_.ok())) return false; return julian::day(1) <= d_ && d_ <= (y_/m_/last).day(); } CONSTCD11 inline bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month() && x.day() == y.day(); } CONSTCD11 inline bool operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_month_day& x, const year_month_day& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.month() < y.month() ? true : (x.month() > y.month() ? false : (x.day() < y.day())))); } CONSTCD11 inline bool operator>(const year_month_day& x, const year_month_day& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day& ymd) { date::detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os << ymd.year() << '-'; os.width(2); os << static_cast(ymd.month()) << '-'; os << ymd.day(); return os; } CONSTCD14 inline year_month_day year_month_day::from_days(days dp) NOEXCEPT { static_assert(std::numeric_limits::digits >= 18, "This algorithm has not been ported to a 16 bit unsigned integer"); static_assert(std::numeric_limits::digits >= 20, "This algorithm has not been ported to a 16 bit signed integer"); auto const z = dp.count() + 719470; auto const era = (z >= 0 ? z : z - 1460) / 1461; auto const doe = static_cast(z - era * 1461); // [0, 1460] auto const yoe = (doe - doe/1460) / 365; // [0, 3] auto const y = static_cast(yoe) + era * 4; auto const doy = doe - 365*yoe; // [0, 365] auto const mp = (5*doy + 2)/153; // [0, 11] auto const d = doy - (153*mp+2)/5 + 1; // [1, 31] auto const m = mp < 10 ? mp+3 : mp-9; // [1, 12] return year_month_day{julian::year{y + (m <= 2)}, julian::month(m), julian::day(d)}; } CONSTCD14 inline year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT { return (ymd.year() / ymd.month() + dm) / ymd.day(); } CONSTCD14 inline year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT { return ymd + dm; } CONSTCD14 inline year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT { return ymd + (-dm); } CONSTCD11 inline year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT { return (ymd.year() + dy) / ymd.month() / ymd.day(); } CONSTCD11 inline year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT { return ymd + dy; } CONSTCD11 inline year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT { return ymd + (-dy); } // year_month_weekday CONSTCD11 inline year_month_weekday::year_month_weekday(const julian::year& y, const julian::month& m, const julian::weekday_indexed& wdi) NOEXCEPT : y_(y) , m_(m) , wdi_(wdi) {} CONSTCD14 inline year_month_weekday::year_month_weekday(const sys_days& dp) NOEXCEPT : year_month_weekday(from_days(dp.time_since_epoch())) {} CONSTCD14 inline year_month_weekday::year_month_weekday(const local_days& dp) NOEXCEPT : year_month_weekday(from_days(dp.time_since_epoch())) {} CONSTCD14 inline year_month_weekday& year_month_weekday::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline year_month_weekday& year_month_weekday::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_weekday& year_month_weekday::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_weekday& year_month_weekday::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_month_weekday::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_weekday::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday year_month_weekday::weekday() const NOEXCEPT { return wdi_.weekday(); } CONSTCD11 inline unsigned year_month_weekday::index() const NOEXCEPT { return wdi_.index(); } CONSTCD11 inline weekday_indexed year_month_weekday::weekday_indexed() const NOEXCEPT { return wdi_; } CONSTCD14 inline year_month_weekday::operator sys_days() const NOEXCEPT { return sys_days{to_days()}; } CONSTCD14 inline year_month_weekday::operator local_days() const NOEXCEPT { return local_days{to_days()}; } CONSTCD14 inline bool year_month_weekday::ok() const NOEXCEPT { if (!y_.ok() || !m_.ok() || !wdi_.weekday().ok() || wdi_.index() < 1) return false; if (wdi_.index() <= 4) return true; auto d2 = wdi_.weekday() - julian::weekday(y_/m_/1) + days((wdi_.index()-1)*7 + 1); return static_cast(d2.count()) <= static_cast((y_/m_/last).day()); } CONSTCD14 inline year_month_weekday year_month_weekday::from_days(days d) NOEXCEPT { sys_days dp{d}; auto const wd = julian::weekday(dp); auto const ymd = year_month_day(dp); return {ymd.year(), ymd.month(), wd[(static_cast(ymd.day())-1)/7+1]}; } CONSTCD14 inline days year_month_weekday::to_days() const NOEXCEPT { auto d = sys_days(y_/m_/1); return (d + (wdi_.weekday() - julian::weekday(d) + days{(wdi_.index()-1)*7}) ).time_since_epoch(); } CONSTCD11 inline bool operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed(); } CONSTCD11 inline bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi) { return os << ymwdi.year() << '/' << ymwdi.month() << '/' << ymwdi.weekday_indexed(); } CONSTCD14 inline year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT { return (ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed(); } CONSTCD14 inline year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT { return ymwd + dm; } CONSTCD14 inline year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT { return ymwd + (-dm); } CONSTCD11 inline year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT { return {ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()}; } CONSTCD11 inline year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT { return ymwd + dy; } CONSTCD11 inline year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT { return ymwd + (-dy); } // year_month_weekday_last CONSTCD11 inline year_month_weekday_last::year_month_weekday_last(const julian::year& y, const julian::month& m, const julian::weekday_last& wdl) NOEXCEPT : y_(y) , m_(m) , wdl_(wdl) {} CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_month_weekday_last::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_weekday_last::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday year_month_weekday_last::weekday() const NOEXCEPT { return wdl_.weekday(); } CONSTCD11 inline weekday_last year_month_weekday_last::weekday_last() const NOEXCEPT { return wdl_; } CONSTCD14 inline year_month_weekday_last::operator sys_days() const NOEXCEPT { return sys_days{to_days()}; } CONSTCD14 inline year_month_weekday_last::operator local_days() const NOEXCEPT { return local_days{to_days()}; } CONSTCD11 inline bool year_month_weekday_last::ok() const NOEXCEPT { return y_.ok() && m_.ok() && wdl_.ok(); } CONSTCD14 inline days year_month_weekday_last::to_days() const NOEXCEPT { auto const d = sys_days(y_/m_/last); return (d - (julian::weekday{d} - wdl_.weekday())).time_since_epoch(); } CONSTCD11 inline bool operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month() && x.weekday_last() == y.weekday_last(); } CONSTCD11 inline bool operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl) { return os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last(); } CONSTCD14 inline year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT { return (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last(); } CONSTCD14 inline year_month_weekday_last operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT { return ymwdl + dm; } CONSTCD14 inline year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT { return ymwdl + (-dm); } CONSTCD11 inline year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT { return {ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()}; } CONSTCD11 inline year_month_weekday_last operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT { return ymwdl + dy; } CONSTCD11 inline year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT { return ymwdl + (-dy); } // year_month from operator/() CONSTCD11 inline year_month operator/(const year& y, const month& m) NOEXCEPT { return {y, m}; } CONSTCD11 inline year_month operator/(const year& y, int m) NOEXCEPT { return y / month(static_cast(m)); } // month_day from operator/() CONSTCD11 inline month_day operator/(const month& m, const day& d) NOEXCEPT { return {m, d}; } CONSTCD11 inline month_day operator/(const day& d, const month& m) NOEXCEPT { return m / d; } CONSTCD11 inline month_day operator/(const month& m, int d) NOEXCEPT { return m / day(static_cast(d)); } CONSTCD11 inline month_day operator/(int m, const day& d) NOEXCEPT { return month(static_cast(m)) / d; } CONSTCD11 inline month_day operator/(const day& d, int m) NOEXCEPT {return m / d;} // month_day_last from operator/() CONSTCD11 inline month_day_last operator/(const month& m, last_spec) NOEXCEPT { return month_day_last{m}; } CONSTCD11 inline month_day_last operator/(last_spec, const month& m) NOEXCEPT { return m/last; } CONSTCD11 inline month_day_last operator/(int m, last_spec) NOEXCEPT { return month(static_cast(m))/last; } CONSTCD11 inline month_day_last operator/(last_spec, int m) NOEXCEPT { return m/last; } // month_weekday from operator/() CONSTCD11 inline month_weekday operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT { return {m, wdi}; } CONSTCD11 inline month_weekday operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT { return m / wdi; } CONSTCD11 inline month_weekday operator/(int m, const weekday_indexed& wdi) NOEXCEPT { return month(static_cast(m)) / wdi; } CONSTCD11 inline month_weekday operator/(const weekday_indexed& wdi, int m) NOEXCEPT { return m / wdi; } // month_weekday_last from operator/() CONSTCD11 inline month_weekday_last operator/(const month& m, const weekday_last& wdl) NOEXCEPT { return {m, wdl}; } CONSTCD11 inline month_weekday_last operator/(const weekday_last& wdl, const month& m) NOEXCEPT { return m / wdl; } CONSTCD11 inline month_weekday_last operator/(int m, const weekday_last& wdl) NOEXCEPT { return month(static_cast(m)) / wdl; } CONSTCD11 inline month_weekday_last operator/(const weekday_last& wdl, int m) NOEXCEPT { return m / wdl; } // year_month_day from operator/() CONSTCD11 inline year_month_day operator/(const year_month& ym, const day& d) NOEXCEPT { return {ym.year(), ym.month(), d}; } CONSTCD11 inline year_month_day operator/(const year_month& ym, int d) NOEXCEPT { return ym / day(static_cast(d)); } CONSTCD11 inline year_month_day operator/(const year& y, const month_day& md) NOEXCEPT { return y / md.month() / md.day(); } CONSTCD11 inline year_month_day operator/(int y, const month_day& md) NOEXCEPT { return year(y) / md; } CONSTCD11 inline year_month_day operator/(const month_day& md, const year& y) NOEXCEPT { return y / md; } CONSTCD11 inline year_month_day operator/(const month_day& md, int y) NOEXCEPT { return year(y) / md; } // year_month_day_last from operator/() CONSTCD11 inline year_month_day_last operator/(const year_month& ym, last_spec) NOEXCEPT { return {ym.year(), month_day_last{ym.month()}}; } CONSTCD11 inline year_month_day_last operator/(const year& y, const month_day_last& mdl) NOEXCEPT { return {y, mdl}; } CONSTCD11 inline year_month_day_last operator/(int y, const month_day_last& mdl) NOEXCEPT { return year(y) / mdl; } CONSTCD11 inline year_month_day_last operator/(const month_day_last& mdl, const year& y) NOEXCEPT { return y / mdl; } CONSTCD11 inline year_month_day_last operator/(const month_day_last& mdl, int y) NOEXCEPT { return year(y) / mdl; } // year_month_weekday from operator/() CONSTCD11 inline year_month_weekday operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT { return {ym.year(), ym.month(), wdi}; } CONSTCD11 inline year_month_weekday operator/(const year& y, const month_weekday& mwd) NOEXCEPT { return {y, mwd.month(), mwd.weekday_indexed()}; } CONSTCD11 inline year_month_weekday operator/(int y, const month_weekday& mwd) NOEXCEPT { return year(y) / mwd; } CONSTCD11 inline year_month_weekday operator/(const month_weekday& mwd, const year& y) NOEXCEPT { return y / mwd; } CONSTCD11 inline year_month_weekday operator/(const month_weekday& mwd, int y) NOEXCEPT { return year(y) / mwd; } // year_month_weekday_last from operator/() CONSTCD11 inline year_month_weekday_last operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT { return {ym.year(), ym.month(), wdl}; } CONSTCD11 inline year_month_weekday_last operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT { return {y, mwdl.month(), mwdl.weekday_last()}; } CONSTCD11 inline year_month_weekday_last operator/(int y, const month_weekday_last& mwdl) NOEXCEPT { return year(y) / mwdl; } CONSTCD11 inline year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT { return y / mwdl; } CONSTCD11 inline year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) NOEXCEPT { return year(y) / mwdl; } } // namespace julian #endif // JULIAN_H date-3.0.1/include/date/ptz.h000066400000000000000000000567141403643451100157740ustar00rootroot00000000000000#ifndef PTZ_H #define PTZ_H // The MIT License (MIT) // // Copyright (c) 2017 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // This header allows Posix-style time zones as specified for TZ here: // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03 // // Posix::time_zone can be constructed with a posix-style string and then used in // a zoned_time like so: // // zoned_time zt{"EST5EDT,M3.2.0,M11.1.0", // system_clock::now()}; // or: // // Posix::time_zone tz{"EST5EDT,M3.2.0,M11.1.0"}; // zoned_time zt{tz, system_clock::now()}; // // If the rule set is missing (everything starting with ','), then the rule is that the // alternate offset is never enabled. // // Note, Posix-style time zones are not recommended for all of the reasons described here: // https://stackoverflow.com/tags/timezone/info // // They are provided here as a non-trivial custom time zone example, and if you really // have to have Posix time zones, you're welcome to use this one. #include "date/tz.h" #include #include #include namespace Posix { namespace detail { #if HAS_STRING_VIEW using string_t = std::string_view; #else // !HAS_STRING_VIEW using string_t = std::string; #endif // !HAS_STRING_VIEW class rule; void throw_invalid(const string_t& s, unsigned i, const string_t& message); unsigned read_date(const string_t& s, unsigned i, rule& r); unsigned read_name(const string_t& s, unsigned i, std::string& name); unsigned read_signed_time(const string_t& s, unsigned i, std::chrono::seconds& t); unsigned read_unsigned_time(const string_t& s, unsigned i, std::chrono::seconds& t); unsigned read_unsigned(const string_t& s, unsigned i, unsigned limit, unsigned& u, const string_t& message = string_t{}); class rule { enum {off, J, M, N}; date::month m_; date::weekday wd_; unsigned short n_ : 14; unsigned short mode_ : 2; std::chrono::duration time_ = std::chrono::hours{2}; public: rule() : mode_(off) {} bool ok() const {return mode_ != off;} date::local_seconds operator()(date::year y) const; std::string to_string() const; friend std::ostream& operator<<(std::ostream& os, const rule& r); friend unsigned read_date(const string_t& s, unsigned i, rule& r); friend bool operator==(const rule& x, const rule& y); }; inline bool operator==(const rule& x, const rule& y) { if (x.mode_ != y.mode_) return false; switch (x.mode_) { case rule::J: case rule::N: return x.n_ == y.n_; case rule::M: return x.m_ == y.m_ && x.n_ == y.n_ && x.wd_ == y.wd_; default: return true; } } inline bool operator!=(const rule& x, const rule& y) { return !(x == y); } inline date::local_seconds rule::operator()(date::year y) const { using date::local_days; using date::January; using date::days; using date::last; using sec = std::chrono::seconds; date::local_seconds t; switch (mode_) { case J: t = local_days{y/January/0} + days{n_ + (y.is_leap() && n_ > 59)} + sec{time_}; break; case M: t = (n_ == 5 ? local_days{y/m_/wd_[last]} : local_days{y/m_/wd_[n_]}) + sec{time_}; break; case N: t = local_days{y/January/1} + days{n_} + sec{time_}; break; default: assert(!"rule called with bad mode"); } return t; } inline std::string rule::to_string() const { using namespace std::chrono; auto print_offset = [](seconds off) { std::string nm; if (off != hours{2}) { date::hh_mm_ss offset{off}; nm = '/'; nm += std::to_string(offset.hours().count()); if (offset.minutes() != minutes{0} || offset.seconds() != seconds{0}) { nm += ':'; if (offset.minutes() < minutes{10}) nm += '0'; nm += std::to_string(offset.minutes().count()); if (offset.seconds() != seconds{0}) { nm += ':'; if (offset.seconds() < seconds{10}) nm += '0'; nm += std::to_string(offset.seconds().count()); } } } return nm; }; std::string nm; switch (mode_) { case rule::J: nm = 'J'; nm += std::to_string(n_); break; case rule::M: nm = 'M'; nm += std::to_string(static_cast(m_)); nm += '.'; nm += std::to_string(n_); nm += '.'; nm += std::to_string(wd_.c_encoding()); break; case rule::N: nm = std::to_string(n_); break; default: break; } nm += print_offset(time_); return nm; } inline std::ostream& operator<<(std::ostream& os, const rule& r) { switch (r.mode_) { case rule::J: os << 'J' << r.n_ << date::format(" %T", r.time_); break; case rule::M: if (r.n_ == 5) os << r.m_/r.wd_[date::last]; else os << r.m_/r.wd_[r.n_]; os << date::format(" %T", r.time_); break; case rule::N: os << r.n_ << date::format(" %T", r.time_); break; default: break; } return os; } } // namespace detail class time_zone { std::string std_abbrev_; std::string dst_abbrev_ = {}; std::chrono::seconds offset_; std::chrono::seconds save_ = std::chrono::hours{1}; detail::rule start_rule_; detail::rule end_rule_; public: explicit time_zone(const detail::string_t& name); template date::sys_info get_info(date::sys_time st) const; template date::local_info get_info(date::local_time tp) const; template date::sys_time::type> to_sys(date::local_time tp) const; template date::sys_time::type> to_sys(date::local_time tp, date::choose z) const; template date::local_time::type> to_local(date::sys_time tp) const; friend std::ostream& operator<<(std::ostream& os, const time_zone& z); const time_zone* operator->() const {return this;} std::string name() const; friend bool operator==(const time_zone& x, const time_zone& y); private: date::sys_seconds get_start(date::year y) const; date::sys_seconds get_prev_start(date::year y) const; date::sys_seconds get_next_start(date::year y) const; date::sys_seconds get_end(date::year y) const; date::sys_seconds get_prev_end(date::year y) const; date::sys_seconds get_next_end(date::year y) const; date::sys_info contant_offset() const; }; inline date::sys_seconds time_zone::get_start(date::year y) const { return date::sys_seconds{(start_rule_(y) - offset_).time_since_epoch()}; } inline date::sys_seconds time_zone::get_prev_start(date::year y) const { return date::sys_seconds{(start_rule_(--y) - offset_).time_since_epoch()}; } inline date::sys_seconds time_zone::get_next_start(date::year y) const { return date::sys_seconds{(start_rule_(++y) - offset_).time_since_epoch()}; } inline date::sys_seconds time_zone::get_end(date::year y) const { return date::sys_seconds{(end_rule_(y) - (offset_ + save_)).time_since_epoch()}; } inline date::sys_seconds time_zone::get_prev_end(date::year y) const { return date::sys_seconds{(end_rule_(--y) - (offset_ + save_)).time_since_epoch()}; } inline date::sys_seconds time_zone::get_next_end(date::year y) const { return date::sys_seconds{(end_rule_(++y) - (offset_ + save_)).time_since_epoch()}; } date::sys_info time_zone::contant_offset() const { using date::year; using date::sys_info; using date::sys_days; using date::January; using date::December; using date::last; sys_info r; r.begin = sys_days{year::min()/January/1}; r.end = sys_days{year::max()/December/last}; r.abbrev = std_abbrev_; r.offset = offset_; return r; } inline time_zone::time_zone(const detail::string_t& s) { using detail::read_name; using detail::read_signed_time; using detail::throw_invalid; auto i = read_name(s, 0, std_abbrev_); i = read_signed_time(s, i, offset_); offset_ = -offset_; if (i != s.size()) { i = read_name(s, i, dst_abbrev_); if (i != s.size()) { if (s[i] != ',') { i = read_signed_time(s, i, save_); save_ = -save_ - offset_; } if (i != s.size()) { if (s[i] != ',') throw_invalid(s, i, "Expecting end of string or ',' to start rule"); ++i; i = read_date(s, i, start_rule_); if (i == s.size() || s[i] != ',') throw_invalid(s, i, "Expecting ',' and then the ending rule"); ++i; i = read_date(s, i, end_rule_); if (i != s.size()) throw_invalid(s, i, "Found unexpected trailing characters"); } } } } template date::sys_info time_zone::get_info(date::sys_time st) const { using date::sys_info; using date::year_month_day; using date::sys_days; using date::floor; using date::ceil; using date::days; using date::year; using date::January; using date::December; using date::last; using std::chrono::minutes; sys_info r{}; r.offset = offset_; if (start_rule_.ok()) { auto y = year_month_day{floor(st)}.year(); auto start = get_start(y); auto end = get_end(y); if (start <= end) // (northern hemisphere) { if (start <= st && st < end) { r.begin = start; r.end = end; r.offset += save_; r.save = ceil(save_); r.abbrev = dst_abbrev_; } else if (st < start) { r.begin = get_prev_end(y); r.end = start; r.abbrev = std_abbrev_; } else // st >= end { r.begin = end; r.end = get_next_start(y); r.abbrev = std_abbrev_; } } else // end < start (southern hemisphere) { if (end <= st && st < start) { r.begin = end; r.end = start; r.abbrev = std_abbrev_; } else if (st < end) { r.begin = get_prev_start(y); r.end = end; r.offset += save_; r.save = ceil(save_); r.abbrev = dst_abbrev_; } else // st >= start { r.begin = start; r.end = get_next_end(y); r.offset += save_; r.save = ceil(save_); r.abbrev = dst_abbrev_; } } } else r = contant_offset(); return r; } template date::local_info time_zone::get_info(date::local_time tp) const { using date::local_info; using date::year_month_day; using date::days; using date::sys_days; using date::sys_seconds; using date::year; using date::ceil; using date::January; using date::December; using date::last; using std::chrono::seconds; using std::chrono::minutes; local_info r{}; using date::floor; if (start_rule_.ok()) { auto y = year_month_day{floor(tp)}.year(); auto start = get_start(y); auto end = get_end(y); auto utcs = sys_seconds{floor(tp - offset_).time_since_epoch()}; auto utcd = sys_seconds{floor(tp - (offset_ + save_)).time_since_epoch()}; auto northern = start <= end; if ((utcs < start) != (utcd < start)) { if (northern) r.first.begin = get_prev_end(y); else r.first.begin = end; r.first.end = start; r.first.offset = offset_; r.first.abbrev = std_abbrev_; r.second.begin = start; if (northern) r.second.end = end; else r.second.end = get_next_end(y); r.second.abbrev = dst_abbrev_; r.second.offset = offset_ + save_; r.second.save = ceil(save_); r.result = save_ > seconds{0} ? local_info::nonexistent : local_info::ambiguous; } else if ((utcs < end) != (utcd < end)) { if (northern) r.first.begin = start; else r.first.begin = get_prev_start(y); r.first.end = end; r.first.offset = offset_ + save_; r.first.save = ceil(save_); r.first.abbrev = dst_abbrev_; r.second.begin = end; if (northern) r.second.end = get_next_start(y); else r.second.end = start; r.second.abbrev = std_abbrev_; r.second.offset = offset_; r.result = save_ > seconds{0} ? local_info::ambiguous : local_info::nonexistent; } else r.first = get_info(utcs); } else r.first = contant_offset(); return r; } template date::sys_time::type> time_zone::to_sys(date::local_time tp) const { using date::local_info; using date::sys_time; using date::ambiguous_local_time; using date::nonexistent_local_time; auto i = get_info(tp); if (i.result == local_info::nonexistent) throw nonexistent_local_time(tp, i); else if (i.result == local_info::ambiguous) throw ambiguous_local_time(tp, i); return sys_time{tp.time_since_epoch()} - i.first.offset; } template date::sys_time::type> time_zone::to_sys(date::local_time tp, date::choose z) const { using date::local_info; using date::sys_time; using date::choose; auto i = get_info(tp); if (i.result == local_info::nonexistent) { return i.first.end; } else if (i.result == local_info::ambiguous) { if (z == choose::latest) return sys_time{tp.time_since_epoch()} - i.second.offset; } return sys_time{tp.time_since_epoch()} - i.first.offset; } template date::local_time::type> time_zone::to_local(date::sys_time tp) const { using date::local_time; using std::chrono::seconds; using LT = local_time::type>; auto i = get_info(tp); return LT{(tp + i.offset).time_since_epoch()}; } inline std::ostream& operator<<(std::ostream& os, const time_zone& z) { using date::operator<<; os << '{'; os << z.std_abbrev_ << ", " << z.dst_abbrev_ << date::format(", %T, ", z.offset_) << date::format("%T, [", z.save_) << z.start_rule_ << ", " << z.end_rule_ << ")}"; return os; } inline std::string time_zone::name() const { using namespace date; using namespace std::chrono; auto nm = std_abbrev_; auto print_offset = [](seconds off) { std::string nm; hh_mm_ss offset{-off}; if (offset.is_negative()) nm += '-'; nm += std::to_string(offset.hours().count()); if (offset.minutes() != minutes{0} || offset.seconds() != seconds{0}) { nm += ':'; if (offset.minutes() < minutes{10}) nm += '0'; nm += std::to_string(offset.minutes().count()); if (offset.seconds() != seconds{0}) { nm += ':'; if (offset.seconds() < seconds{10}) nm += '0'; nm += std::to_string(offset.seconds().count()); } } return nm; }; nm += print_offset(offset_); if (!dst_abbrev_.empty()) { nm += dst_abbrev_; if (save_ != hours{1}) nm += print_offset(offset_+save_); if (start_rule_.ok()) { nm += ','; nm += start_rule_.to_string(); nm += ','; nm += end_rule_.to_string(); } } return nm; } inline bool operator==(const time_zone& x, const time_zone& y) { return x.std_abbrev_ == y.std_abbrev_ && x.dst_abbrev_ == y. dst_abbrev_ && x.offset_ == y.offset_ && x.save_ == y.save_ && x.start_rule_ == y.start_rule_ && x.end_rule_ == y.end_rule_; } inline bool operator!=(const time_zone& x, const time_zone& y) { return !(x == y); } namespace detail { inline void throw_invalid(const string_t& s, unsigned i, const string_t& message) { throw std::runtime_error(std::string("Invalid time_zone initializer.\n") + std::string(message) + ":\n" + std::string(s) + '\n' + "\x1b[1;32m" + std::string(i, '~') + '^' + std::string(i < s.size() ? s.size()-i-1 : 0, '~') + "\x1b[0m"); } inline unsigned read_date(const string_t& s, unsigned i, rule& r) { using date::month; using date::weekday; if (i == s.size()) throw_invalid(s, i, "Expected rule but found end of string"); if (s[i] == 'J') { ++i; unsigned n; i = read_unsigned(s, i, 3, n, "Expected to find the Julian day [1, 365]"); r.mode_ = rule::J; r.n_ = n; } else if (s[i] == 'M') { ++i; unsigned m; i = read_unsigned(s, i, 2, m, "Expected to find month [1, 12]"); if (i == s.size() || s[i] != '.') throw_invalid(s, i, "Expected '.' after month"); ++i; unsigned n; i = read_unsigned(s, i, 1, n, "Expected to find week number [1, 5]"); if (i == s.size() || s[i] != '.') throw_invalid(s, i, "Expected '.' after weekday index"); ++i; unsigned wd; i = read_unsigned(s, i, 1, wd, "Expected to find day of week [0, 6]"); r.mode_ = rule::M; r.m_ = month{m}; r.wd_ = weekday{wd}; r.n_ = n; } else if (std::isdigit(s[i])) { unsigned n; i = read_unsigned(s, i, 3, n); r.mode_ = rule::N; r.n_ = n; } else throw_invalid(s, i, "Expected 'J', 'M', or a digit to start rule"); if (i != s.size() && s[i] == '/') { ++i; std::chrono::seconds t; i = read_unsigned_time(s, i, t); r.time_ = t; } return i; } inline unsigned read_name(const string_t& s, unsigned i, std::string& name) { if (i == s.size()) throw_invalid(s, i, "Expected a name but found end of string"); if (s[i] == '<') { ++i; while (true) { if (i == s.size()) throw_invalid(s, i, "Expected to find closing '>', but found end of string"); if (s[i] == '>') break; name.push_back(s[i]); ++i; } ++i; } else { while (i != s.size() && std::isalpha(s[i])) { name.push_back(s[i]); ++i; } } if (name.size() < 3) throw_invalid(s, i, "Found name to be shorter than 3 characters"); return i; } inline unsigned read_signed_time(const string_t& s, unsigned i, std::chrono::seconds& t) { if (i == s.size()) throw_invalid(s, i, "Expected to read signed time, but found end of string"); bool negative = false; if (s[i] == '-') { negative = true; ++i; } else if (s[i] == '+') ++i; i = read_unsigned_time(s, i, t); if (negative) t = -t; return i; } inline unsigned read_unsigned_time(const string_t& s, unsigned i, std::chrono::seconds& t) { using std::chrono::seconds; using std::chrono::minutes; using std::chrono::hours; if (i == s.size()) throw_invalid(s, i, "Expected to read unsigned time, but found end of string"); unsigned x; i = read_unsigned(s, i, 2, x, "Expected to find hours [0, 24]"); t = hours{x}; if (i != s.size() && s[i] == ':') { ++i; i = read_unsigned(s, i, 2, x, "Expected to find minutes [0, 59]"); t += minutes{x}; if (i != s.size() && s[i] == ':') { ++i; i = read_unsigned(s, i, 2, x, "Expected to find seconds [0, 59]"); t += seconds{x}; } } return i; } inline unsigned read_unsigned(const string_t& s, unsigned i, unsigned limit, unsigned& u, const string_t& message) { if (i == s.size() || !std::isdigit(s[i])) throw_invalid(s, i, message); u = static_cast(s[i] - '0'); unsigned count = 1; for (++i; count < limit && i != s.size() && std::isdigit(s[i]); ++i, ++count) u = u * 10 + static_cast(s[i] - '0'); return i; } } // namespace detail } // namespace Posix namespace date { template <> struct zoned_traits { #if HAS_STRING_VIEW static Posix::time_zone locate_zone(std::string_view name) { return Posix::time_zone{name}; } #else // !HAS_STRING_VIEW static Posix::time_zone locate_zone(const std::string& name) { return Posix::time_zone{name}; } static Posix::time_zone locate_zone(const char* name) { return Posix::time_zone{name}; } #endif // !HAS_STRING_VIEW }; } // namespace date #endif // PTZ_H date-3.0.1/include/date/solar_hijri.h000066400000000000000000002316221403643451100174550ustar00rootroot00000000000000#ifndef SOLAR_HIJRI_H #define SOLAR_HIJRI_H // The MIT License (MIT) // // Copyright (c) 2016 Howard Hinnant // Copyright (c) 2019 Asad. Gharighi // // Calculations are based on: // https://www.timeanddate.com/calendar/persian-calendar.html // and follow style // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // Our apologies. When the previous paragraph was written, lowercase had not yet // been invented (that would involve another several millennia of evolution). // We did not mean to shout. #include "date.h" namespace solar_hijri { namespace internal { static const auto epoch = static_cast(2121446); static const auto days_in_era = static_cast(1029983); static const auto years_in_era = static_cast(2820); static const auto unix_time_shift = static_cast(2440588); auto const years_in_first_cycle = static_cast(29); auto const years_in_other_cycles = static_cast(33); auto const years_in_period = static_cast(128); // 29 + 3*33 auto const days_in_first_cycle = static_cast(10592); // 28/4 + 29*365 auto const days_in_other_cycles = static_cast(12053); // 32/4 + 33*365 auto const days_in_period = static_cast(46751); // days_in_first_cycle + 3*days_in_other_cycles; } // durations using days = date::days; using weeks = date::weeks; using years = std::chrono::duration , days::period>>; using months = std::chrono::duration >>; // time_point using sys_days = date::sys_days; using local_days = date::local_days; // types struct last_spec { explicit last_spec() = default; }; class day; class month; class year; class weekday; class weekday_indexed; class weekday_last; class month_day; class month_day_last; class month_weekday; class month_weekday_last; class year_month; class year_month_day; class year_month_day_last; class year_month_weekday; class year_month_weekday_last; // date composition operators CONSTCD11 year_month operator/(const year& y, const month& m) NOEXCEPT; CONSTCD11 year_month operator/(const year& y, int m) NOEXCEPT; CONSTCD11 month_day operator/(const day& d, const month& m) NOEXCEPT; CONSTCD11 month_day operator/(const day& d, int m) NOEXCEPT; CONSTCD11 month_day operator/(const month& m, const day& d) NOEXCEPT; CONSTCD11 month_day operator/(const month& m, int d) NOEXCEPT; CONSTCD11 month_day operator/(int m, const day& d) NOEXCEPT; CONSTCD11 month_day_last operator/(const month& m, last_spec) NOEXCEPT; CONSTCD11 month_day_last operator/(int m, last_spec) NOEXCEPT; CONSTCD11 month_day_last operator/(last_spec, const month& m) NOEXCEPT; CONSTCD11 month_day_last operator/(last_spec, int m) NOEXCEPT; CONSTCD11 month_weekday operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT; CONSTCD11 month_weekday operator/(int m, const weekday_indexed& wdi) NOEXCEPT; CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT; CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, int m) NOEXCEPT; CONSTCD11 month_weekday_last operator/(const month& m, const weekday_last& wdl) NOEXCEPT; CONSTCD11 month_weekday_last operator/(int m, const weekday_last& wdl) NOEXCEPT; CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, const month& m) NOEXCEPT; CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, int m) NOEXCEPT; CONSTCD11 year_month_day operator/(const year_month& ym, const day& d) NOEXCEPT; CONSTCD11 year_month_day operator/(const year_month& ym, int d) NOEXCEPT; CONSTCD11 year_month_day operator/(const year& y, const month_day& md) NOEXCEPT; CONSTCD11 year_month_day operator/(int y, const month_day& md) NOEXCEPT; CONSTCD11 year_month_day operator/(const month_day& md, const year& y) NOEXCEPT; CONSTCD11 year_month_day operator/(const month_day& md, int y) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const year_month& ym, last_spec) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const year& y, const month_day_last& mdl) NOEXCEPT; CONSTCD11 year_month_day_last operator/(int y, const month_day_last& mdl) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const month_day_last& mdl, const year& y) NOEXCEPT; CONSTCD11 year_month_day_last operator/(const month_day_last& mdl, int y) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const year& y, const month_weekday& mwd) NOEXCEPT; CONSTCD11 year_month_weekday operator/(int y, const month_weekday& mwd) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const month_weekday& mwd, const year& y) NOEXCEPT; CONSTCD11 year_month_weekday operator/(const month_weekday& mwd, int y) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(int y, const month_weekday_last& mwdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT; CONSTCD11 year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) NOEXCEPT; // Detailed interface // day class day { unsigned char d_; public: day() = default; explicit CONSTCD11 day(unsigned d) NOEXCEPT; CONSTCD14 day& operator++() NOEXCEPT; CONSTCD14 day operator++(int) NOEXCEPT; CONSTCD14 day& operator--() NOEXCEPT; CONSTCD14 day operator--(int) NOEXCEPT; CONSTCD14 day& operator+=(const days& d) NOEXCEPT; CONSTCD14 day& operator-=(const days& d) NOEXCEPT; CONSTCD11 explicit operator unsigned() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator!=(const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator< (const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator> (const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator<=(const day& x, const day& y) NOEXCEPT; CONSTCD11 bool operator>=(const day& x, const day& y) NOEXCEPT; CONSTCD11 day operator+(const day& x, const days& y) NOEXCEPT; CONSTCD11 day operator+(const days& x, const day& y) NOEXCEPT; CONSTCD11 day operator-(const day& x, const days& y) NOEXCEPT; CONSTCD11 days operator-(const day& x, const day& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const day& d); // month class month { unsigned char m_; public: month() = default; explicit CONSTCD11 month(unsigned m) NOEXCEPT; CONSTCD14 month& operator++() NOEXCEPT; CONSTCD14 month operator++(int) NOEXCEPT; CONSTCD14 month& operator--() NOEXCEPT; CONSTCD14 month operator--(int) NOEXCEPT; CONSTCD14 month& operator+=(const months& m) NOEXCEPT; CONSTCD14 month& operator-=(const months& m) NOEXCEPT; CONSTCD11 explicit operator unsigned() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator!=(const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator< (const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator> (const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator<=(const month& x, const month& y) NOEXCEPT; CONSTCD11 bool operator>=(const month& x, const month& y) NOEXCEPT; CONSTCD14 month operator+(const month& x, const months& y) NOEXCEPT; CONSTCD14 month operator+(const months& x, const month& y) NOEXCEPT; CONSTCD14 month operator-(const month& x, const months& y) NOEXCEPT; CONSTCD14 months operator-(const month& x, const month& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month& m); // year class year { short y_; public: year() = default; explicit CONSTCD11 year(int y) NOEXCEPT; CONSTCD14 year& operator++() NOEXCEPT; CONSTCD14 year operator++(int) NOEXCEPT; CONSTCD14 year& operator--() NOEXCEPT; CONSTCD14 year operator--(int) NOEXCEPT; CONSTCD14 year& operator+=(const years& y) NOEXCEPT; CONSTCD14 year& operator-=(const years& y) NOEXCEPT; CONSTCD14 bool is_leap() const NOEXCEPT; CONSTCD11 explicit operator int() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; static CONSTCD11 year min() NOEXCEPT; static CONSTCD11 year max() NOEXCEPT; }; CONSTCD11 bool operator==(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator!=(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator< (const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator> (const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator<=(const year& x, const year& y) NOEXCEPT; CONSTCD11 bool operator>=(const year& x, const year& y) NOEXCEPT; CONSTCD11 year operator+(const year& x, const years& y) NOEXCEPT; CONSTCD11 year operator+(const years& x, const year& y) NOEXCEPT; CONSTCD11 year operator-(const year& x, const years& y) NOEXCEPT; CONSTCD11 years operator-(const year& x, const year& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year& y); // weekday class weekday { unsigned char wd_; public: weekday() = default; explicit CONSTCD11 weekday(unsigned wd) NOEXCEPT; explicit weekday(int) = delete; CONSTCD11 weekday(const sys_days& dp) NOEXCEPT; CONSTCD11 explicit weekday(const local_days& dp) NOEXCEPT; CONSTCD14 weekday& operator++() NOEXCEPT; CONSTCD14 weekday operator++(int) NOEXCEPT; CONSTCD14 weekday& operator--() NOEXCEPT; CONSTCD14 weekday operator--(int) NOEXCEPT; CONSTCD14 weekday& operator+=(const days& d) NOEXCEPT; CONSTCD14 weekday& operator-=(const days& d) NOEXCEPT; CONSTCD11 explicit operator unsigned() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; CONSTCD11 weekday_indexed operator[](unsigned index) const NOEXCEPT; CONSTCD11 weekday_last operator[](last_spec) const NOEXCEPT; private: static CONSTCD11 unsigned char weekday_from_days(int z) NOEXCEPT; }; CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday& x, const weekday& y) NOEXCEPT; CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT; CONSTCD14 weekday operator+(const days& x, const weekday& y) NOEXCEPT; CONSTCD14 weekday operator-(const weekday& x, const days& y) NOEXCEPT; CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday& wd); // weekday_indexed class weekday_indexed { unsigned char wd_ : 4; unsigned char index_ : 4; public: weekday_indexed() = default; CONSTCD11 weekday_indexed(const solar_hijri::weekday& wd, unsigned index) NOEXCEPT; CONSTCD11 solar_hijri::weekday weekday() const NOEXCEPT; CONSTCD11 unsigned index() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_indexed& wdi); // weekday_last class weekday_last { solar_hijri::weekday wd_; public: weekday_last() = default; explicit CONSTCD11 weekday_last(const solar_hijri::weekday& wd) NOEXCEPT; CONSTCD11 solar_hijri::weekday weekday() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_last& wdl); // year_month class year_month { solar_hijri::year y_; solar_hijri::month m_; public: year_month() = default; CONSTCD11 year_month(const solar_hijri::year& y, const solar_hijri::month& m) NOEXCEPT; CONSTCD11 solar_hijri::year year() const NOEXCEPT; CONSTCD11 solar_hijri::month month() const NOEXCEPT; CONSTCD14 year_month& operator+=(const months& dm) NOEXCEPT; CONSTCD14 year_month& operator-=(const months& dm) NOEXCEPT; CONSTCD14 year_month& operator+=(const years& dy) NOEXCEPT; CONSTCD14 year_month& operator-=(const years& dy) NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator< (const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator> (const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD14 year_month operator+(const year_month& ym, const months& dm) NOEXCEPT; CONSTCD14 year_month operator+(const months& dm, const year_month& ym) NOEXCEPT; CONSTCD14 year_month operator-(const year_month& ym, const months& dm) NOEXCEPT; CONSTCD11 months operator-(const year_month& x, const year_month& y) NOEXCEPT; CONSTCD11 year_month operator+(const year_month& ym, const years& dy) NOEXCEPT; CONSTCD11 year_month operator+(const years& dy, const year_month& ym) NOEXCEPT; CONSTCD11 year_month operator-(const year_month& ym, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month& ym); // month_day class month_day { solar_hijri::month m_; solar_hijri::day d_; public: month_day() = default; CONSTCD11 month_day(const solar_hijri::month& m, const solar_hijri::day& d) NOEXCEPT; CONSTCD11 solar_hijri::month month() const NOEXCEPT; CONSTCD11 solar_hijri::day day() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator< (const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator> (const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator<=(const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator>=(const month_day& x, const month_day& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_day& md); // month_day_last class month_day_last { solar_hijri::month m_; public: month_day_last() = default; CONSTCD11 explicit month_day_last(const solar_hijri::month& m) NOEXCEPT; CONSTCD11 solar_hijri::month month() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator< (const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator> (const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_day_last& mdl); // month_weekday class month_weekday { solar_hijri::month m_; solar_hijri::weekday_indexed wdi_; public: month_weekday() = default; CONSTCD11 month_weekday(const solar_hijri::month& m, const solar_hijri::weekday_indexed& wdi) NOEXCEPT; CONSTCD11 solar_hijri::month month() const NOEXCEPT; CONSTCD11 solar_hijri::weekday_indexed weekday_indexed() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday& mwd); // month_weekday_last class month_weekday_last { solar_hijri::month m_; solar_hijri::weekday_last wdl_; public: month_weekday_last() = default; CONSTCD11 month_weekday_last(const solar_hijri::month& m, const solar_hijri::weekday_last& wd) NOEXCEPT; CONSTCD11 solar_hijri::month month() const NOEXCEPT; CONSTCD11 solar_hijri::weekday_last weekday_last() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday_last& mwdl); // class year_month_day class year_month_day { solar_hijri::year y_; solar_hijri::month m_; solar_hijri::day d_; public: year_month_day() = default; CONSTCD11 year_month_day(const solar_hijri::year& y, const solar_hijri::month& m, const solar_hijri::day& d) NOEXCEPT; CONSTCD14 year_month_day(const year_month_day_last& ymdl) NOEXCEPT; CONSTCD14 year_month_day(sys_days dp) NOEXCEPT; CONSTCD14 explicit year_month_day(local_days dp) NOEXCEPT; CONSTCD14 year_month_day& operator+=(const months& m) NOEXCEPT; CONSTCD14 year_month_day& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_day& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_day& operator-=(const years& y) NOEXCEPT; CONSTCD11 solar_hijri::year year() const NOEXCEPT; CONSTCD11 solar_hijri::month month() const NOEXCEPT; CONSTCD11 solar_hijri::day day() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; private: static CONSTCD14 year_month_day from_days(days dp) NOEXCEPT; CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator< (const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator> (const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD14 year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT; CONSTCD14 year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT; CONSTCD14 year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT; CONSTCD11 year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT; CONSTCD11 year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT; CONSTCD11 year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day& ymd); // year_month_day_last class year_month_day_last { solar_hijri::year y_; solar_hijri::month_day_last mdl_; public: year_month_day_last() = default; CONSTCD11 year_month_day_last(const solar_hijri::year& y, const solar_hijri::month_day_last& mdl) NOEXCEPT; CONSTCD14 year_month_day_last& operator+=(const months& m) NOEXCEPT; CONSTCD14 year_month_day_last& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_day_last& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_day_last& operator-=(const years& y) NOEXCEPT; CONSTCD11 solar_hijri::year year() const NOEXCEPT; CONSTCD11 solar_hijri::month month() const NOEXCEPT; CONSTCD11 solar_hijri::month_day_last month_day_last() const NOEXCEPT; CONSTCD14 solar_hijri::day day() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator< (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator> (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; CONSTCD14 year_month_day_last operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; CONSTCD14 year_month_day_last operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT; CONSTCD11 year_month_day_last operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; CONSTCD11 year_month_day_last operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT; CONSTCD14 year_month_day_last operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; CONSTCD11 year_month_day_last operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day_last& ymdl); // year_month_weekday class year_month_weekday { solar_hijri::year y_; solar_hijri::month m_; solar_hijri::weekday_indexed wdi_; public: year_month_weekday() = default; CONSTCD11 year_month_weekday(const solar_hijri::year& y, const solar_hijri::month& m, const solar_hijri::weekday_indexed& wdi) NOEXCEPT; CONSTCD14 year_month_weekday(const sys_days& dp) NOEXCEPT; CONSTCD14 explicit year_month_weekday(const local_days& dp) NOEXCEPT; CONSTCD14 year_month_weekday& operator+=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_weekday& operator-=(const years& y) NOEXCEPT; CONSTCD11 solar_hijri::year year() const NOEXCEPT; CONSTCD11 solar_hijri::month month() const NOEXCEPT; CONSTCD11 solar_hijri::weekday weekday() const NOEXCEPT; CONSTCD11 unsigned index() const NOEXCEPT; CONSTCD11 solar_hijri::weekday_indexed weekday_indexed() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; private: static CONSTCD14 year_month_weekday from_days(days dp) NOEXCEPT; CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; CONSTCD14 year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; CONSTCD14 year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT; CONSTCD11 year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; CONSTCD11 year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT; CONSTCD14 year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; CONSTCD11 year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi); // year_month_weekday_last class year_month_weekday_last { solar_hijri::year y_; solar_hijri::month m_; solar_hijri::weekday_last wdl_; public: year_month_weekday_last() = default; CONSTCD11 year_month_weekday_last(const solar_hijri::year& y, const solar_hijri::month& m, const solar_hijri::weekday_last& wdl) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator+=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator-=(const months& m) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator+=(const years& y) NOEXCEPT; CONSTCD14 year_month_weekday_last& operator-=(const years& y) NOEXCEPT; CONSTCD11 solar_hijri::year year() const NOEXCEPT; CONSTCD11 solar_hijri::month month() const NOEXCEPT; CONSTCD11 solar_hijri::weekday weekday() const NOEXCEPT; CONSTCD11 solar_hijri::weekday_last weekday_last() const NOEXCEPT; CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; private: CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; CONSTCD14 year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; CONSTCD14 year_month_weekday_last operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT; CONSTCD11 year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; CONSTCD11 year_month_weekday_last operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT; CONSTCD14 year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; CONSTCD11 year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; template std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl); #if !defined(_MSC_VER) || (_MSC_VER >= 1900) inline namespace literals { CONSTCD11 solar_hijri::day operator "" _d(unsigned long long d) NOEXCEPT; CONSTCD11 solar_hijri::year operator "" _y(unsigned long long y) NOEXCEPT; } // inline namespace literals #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) //----------------+ // Implementation | //----------------+ // day CONSTCD11 inline day::day(unsigned d) NOEXCEPT : d_(static_cast(d)) {} CONSTCD14 inline day& day::operator++() NOEXCEPT {++d_; return *this;} CONSTCD14 inline day day::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline day& day::operator--() NOEXCEPT {--d_; return *this;} CONSTCD14 inline day day::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline day& day::operator+=(const days& d) NOEXCEPT {*this = *this + d; return *this;} CONSTCD14 inline day& day::operator-=(const days& d) NOEXCEPT {*this = *this - d; return *this;} CONSTCD11 inline day::operator unsigned() const NOEXCEPT {return d_;} CONSTCD11 inline bool day::ok() const NOEXCEPT {return 1 <= d_ && d_ <= 30;} CONSTCD11 inline bool operator==(const day& x, const day& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const day& x, const day& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const day& x, const day& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const day& x, const day& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const day& x, const day& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const day& x, const day& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline days operator-(const day& x, const day& y) NOEXCEPT { return days{static_cast(static_cast(x) - static_cast(y))}; } CONSTCD11 inline day operator+(const day& x, const days& y) NOEXCEPT { return day{static_cast(x) + static_cast(y.count())}; } CONSTCD11 inline day operator+(const days& x, const day& y) NOEXCEPT { return y + x; } CONSTCD11 inline day operator-(const day& x, const days& y) NOEXCEPT { return x + -y; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const day& d) { date::detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.width(2); os << static_cast(d); return os; } // month CONSTCD11 inline month::month(unsigned m) NOEXCEPT : m_(static_cast(m)) {} CONSTCD14 inline month& month::operator++() NOEXCEPT {if (++m_ == 13) m_ = 1; return *this;} CONSTCD14 inline month month::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline month& month::operator--() NOEXCEPT {if (--m_ == 0) m_ = 12; return *this;} CONSTCD14 inline month month::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline month& month::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline month& month::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD11 inline month::operator unsigned() const NOEXCEPT {return m_;} CONSTCD11 inline bool month::ok() const NOEXCEPT {return 1 <= m_ && m_ <= 12;} CONSTCD11 inline bool operator==(const month& x, const month& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const month& x, const month& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const month& x, const month& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const month& x, const month& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const month& x, const month& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const month& x, const month& y) NOEXCEPT { return !(x < y); } CONSTCD14 inline months operator-(const month& x, const month& y) NOEXCEPT { auto const d = static_cast(x) - static_cast(y); return months(d <= 11 ? d : d + 12); } CONSTCD14 inline month operator+(const month& x, const months& y) NOEXCEPT { auto const mu = static_cast(static_cast(x)) - 1 + y.count(); auto const yr = (mu >= 0 ? mu : mu-11) / 12; return month{static_cast(mu - yr * 12 + 1)}; } CONSTCD14 inline month operator+(const months& x, const month& y) NOEXCEPT { return y + x; } CONSTCD14 inline month operator-(const month& x, const months& y) NOEXCEPT { return x + -y; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month& m) { switch (static_cast(m)) { case 1: os << "Farvardin"; break; case 2: os << "Ordibehesht"; break; case 3: os << "Khordad"; break; case 4: os << "Tir"; break; case 5: os << "Mordad"; break; case 6: os << "Shahrivar"; break; case 7: os << "Mehr"; break; case 8: os << "Aban"; break; case 9: os << "Azar"; break; case 10: os << "Dey"; break; case 11: os << "Bahman"; break; case 12: os << "Esfand"; break; default: os << static_cast(m) << " is not a valid month"; break; } return os; } // year CONSTCD11 inline year::year(int y) NOEXCEPT : y_(static_cast(y)) {} CONSTCD14 inline year& year::operator++() NOEXCEPT {++y_; return *this;} CONSTCD14 inline year year::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline year& year::operator--() NOEXCEPT {--y_; return *this;} CONSTCD14 inline year year::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline year& year::operator+=(const years& y) NOEXCEPT {*this = *this + y; return *this;} CONSTCD14 inline year& year::operator-=(const years& y) NOEXCEPT {*this = *this - y; return *this;} CONSTCD14 inline bool year::is_leap() const NOEXCEPT { using namespace internal; auto const y = static_cast(y_)-475; auto const era_d = static_cast(y >= 0 ? y : y-years_in_era+1) / static_cast(years_in_era); auto const era = static_cast(era_d); auto const yoe = static_cast(y - era * years_in_era); // Reference: https://www.timeanddate.com/date/iran-leap-year.html // 29 + 33 + 33 + 33 = 128 // 22 * 128 + 4 auto const yoc = (yoe < (22 * 128)) ? ((yoe%128) < 29 ? yoe%128 : (yoe%128 - 29)%33) : yoe - (22 * 128) + 33; return (yoc != 0 && (yoc%4)==0); } CONSTCD11 inline year::operator int() const NOEXCEPT {return y_;} CONSTCD11 inline bool year::ok() const NOEXCEPT {return true;} CONSTCD11 inline year year::min() NOEXCEPT { return year{std::numeric_limits::min()}; } CONSTCD11 inline year year::max() NOEXCEPT { return year{std::numeric_limits::max()}; } CONSTCD11 inline bool operator==(const year& x, const year& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const year& x, const year& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year& x, const year& y) NOEXCEPT { return static_cast(x) < static_cast(y); } CONSTCD11 inline bool operator>(const year& x, const year& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year& x, const year& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year& x, const year& y) NOEXCEPT { return !(x < y); } CONSTCD11 inline years operator-(const year& x, const year& y) NOEXCEPT { return years{static_cast(x) - static_cast(y)}; } CONSTCD11 inline year operator+(const year& x, const years& y) NOEXCEPT { return year{static_cast(x) + y.count()}; } CONSTCD11 inline year operator+(const years& x, const year& y) NOEXCEPT { return y + x; } CONSTCD11 inline year operator-(const year& x, const years& y) NOEXCEPT { return year{static_cast(x) - y.count()}; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year& y) { date::detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::internal); os.width(4 + (y < year{0})); os << static_cast(y); return os; } // weekday CONSTCD11 inline unsigned char weekday::weekday_from_days(int z) NOEXCEPT { auto u = static_cast(z); return static_cast(z >= -4 ? (u+4) % 7 : u % 7); } CONSTCD11 inline weekday::weekday(unsigned wd) NOEXCEPT : wd_(static_cast(wd != 7 ? wd : 0)) {} CONSTCD11 inline weekday::weekday(const sys_days& dp) NOEXCEPT : wd_(weekday_from_days(dp.time_since_epoch().count())) {} CONSTCD11 inline weekday::weekday(const local_days& dp) NOEXCEPT : wd_(weekday_from_days(dp.time_since_epoch().count())) {} CONSTCD14 inline weekday& weekday::operator++() NOEXCEPT {if (++wd_ == 7) wd_ = 0; return *this;} CONSTCD14 inline weekday weekday::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} CONSTCD14 inline weekday& weekday::operator--() NOEXCEPT {if (wd_-- == 0) wd_ = 6; return *this;} CONSTCD14 inline weekday weekday::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} CONSTCD14 inline weekday& weekday::operator+=(const days& d) NOEXCEPT { *this = *this + d; return *this; } CONSTCD14 inline weekday& weekday::operator-=(const days& d) NOEXCEPT { *this = *this - d; return *this; } CONSTCD11 inline weekday::operator unsigned() const NOEXCEPT { return static_cast(wd_); } CONSTCD11 inline bool weekday::ok() const NOEXCEPT {return wd_ <= 6;} CONSTCD11 inline bool operator==(const weekday& x, const weekday& y) NOEXCEPT { return static_cast(x) == static_cast(y); } CONSTCD11 inline bool operator!=(const weekday& x, const weekday& y) NOEXCEPT { return !(x == y); } CONSTCD14 inline days operator-(const weekday& x, const weekday& y) NOEXCEPT { auto const diff = static_cast(x) - static_cast(y); return days{diff <= 6 ? diff : diff + 7}; } CONSTCD14 inline weekday operator+(const weekday& x, const days& y) NOEXCEPT { auto const wdu = static_cast(static_cast(x)) + y.count(); auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7; return weekday{static_cast(wdu - wk * 7)}; } CONSTCD14 inline weekday operator+(const days& x, const weekday& y) NOEXCEPT { return y + x; } CONSTCD14 inline weekday operator-(const weekday& x, const days& y) NOEXCEPT { return x + -y; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday& wd) { switch (static_cast(wd)) { case 0: os << "Yekshanbe"; break; case 1: os << "Doshanbe"; break; case 2: os << "Seshanbe"; break; case 3: os << "Chaharshanbe"; break; case 4: os << "Panjshanbe"; break; case 5: os << "Adine"; break; case 6: os << "Shanbe"; break; default: os << static_cast(wd) << " is not a valid weekday"; break; } return os; } #if !defined(_MSC_VER) || (_MSC_VER >= 1900) inline namespace literals { CONSTCD11 inline solar_hijri::day operator "" _d(unsigned long long d) NOEXCEPT { return solar_hijri::day{static_cast(d)}; } CONSTCD11 inline solar_hijri::year operator "" _y(unsigned long long y) NOEXCEPT { return solar_hijri::year(static_cast(y)); } #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) CONSTDATA solar_hijri::last_spec last{}; CONSTDATA solar_hijri::month far {1}; CONSTDATA solar_hijri::month ord {2}; CONSTDATA solar_hijri::month kho {3}; CONSTDATA solar_hijri::month tir {4}; CONSTDATA solar_hijri::month mor {5}; CONSTDATA solar_hijri::month sha {6}; CONSTDATA solar_hijri::month meh {7}; CONSTDATA solar_hijri::month aba {8}; CONSTDATA solar_hijri::month aza {9}; CONSTDATA solar_hijri::month dey {10}; CONSTDATA solar_hijri::month bah {11}; CONSTDATA solar_hijri::month esf {12}; CONSTDATA solar_hijri::month Farvardin {1}; CONSTDATA solar_hijri::month Ordibehesht {2}; CONSTDATA solar_hijri::month Khordad {3}; CONSTDATA solar_hijri::month Tir {4}; CONSTDATA solar_hijri::month Mordad {5}; CONSTDATA solar_hijri::month Shahrivar {6}; CONSTDATA solar_hijri::month Mehr {7}; CONSTDATA solar_hijri::month Aban {8}; CONSTDATA solar_hijri::month Azar {9}; CONSTDATA solar_hijri::month Dey {10}; CONSTDATA solar_hijri::month Bahman {11}; CONSTDATA solar_hijri::month Esfand {12}; CONSTDATA solar_hijri::weekday yek {0u}; CONSTDATA solar_hijri::weekday dos {1u}; CONSTDATA solar_hijri::weekday ses {2u}; CONSTDATA solar_hijri::weekday cha {3u}; CONSTDATA solar_hijri::weekday pan {4u}; CONSTDATA solar_hijri::weekday adi {5u}; CONSTDATA solar_hijri::weekday shn {6u}; CONSTDATA solar_hijri::weekday Yekshanbe {0u}; CONSTDATA solar_hijri::weekday Doshanbe {1u}; CONSTDATA solar_hijri::weekday Seshanbe {2u}; CONSTDATA solar_hijri::weekday Chaharshanbe {3u}; CONSTDATA solar_hijri::weekday Panjshanbe {4u}; CONSTDATA solar_hijri::weekday Adine {5u}; CONSTDATA solar_hijri::weekday Shanbe {6u}; #if !defined(_MSC_VER) || (_MSC_VER >= 1900) } // inline namespace literals #endif // weekday_indexed CONSTCD11 inline weekday weekday_indexed::weekday() const NOEXCEPT { return solar_hijri::weekday{static_cast(wd_)}; } CONSTCD11 inline unsigned weekday_indexed::index() const NOEXCEPT {return index_;} CONSTCD11 inline bool weekday_indexed::ok() const NOEXCEPT { return weekday().ok() && 1 <= index_ && index_ <= 5; } CONSTCD11 inline weekday_indexed::weekday_indexed(const solar_hijri::weekday& wd, unsigned index) NOEXCEPT : wd_(static_cast(static_cast(wd))) , index_(static_cast(index)) {} template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_indexed& wdi) { return os << wdi.weekday() << '[' << wdi.index() << ']'; } CONSTCD11 inline weekday_indexed weekday::operator[](unsigned index) const NOEXCEPT { return {*this, index}; } CONSTCD11 inline bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT { return x.weekday() == y.weekday() && x.index() == y.index(); } CONSTCD11 inline bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT { return !(x == y); } // weekday_last CONSTCD11 inline solar_hijri::weekday weekday_last::weekday() const NOEXCEPT {return wd_;} CONSTCD11 inline bool weekday_last::ok() const NOEXCEPT {return wd_.ok();} CONSTCD11 inline weekday_last::weekday_last(const solar_hijri::weekday& wd) NOEXCEPT : wd_(wd) {} CONSTCD11 inline bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT { return x.weekday() == y.weekday(); } CONSTCD11 inline bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_last& wdl) { return os << wdl.weekday() << "[last]"; } CONSTCD11 inline weekday_last weekday::operator[](last_spec) const NOEXCEPT { return weekday_last{*this}; } // year_month CONSTCD11 inline year_month::year_month(const solar_hijri::year& y, const solar_hijri::month& m) NOEXCEPT : y_(y) , m_(m) {} CONSTCD11 inline year year_month::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month::month() const NOEXCEPT {return m_;} CONSTCD11 inline bool year_month::ok() const NOEXCEPT {return y_.ok() && m_.ok();} CONSTCD14 inline year_month& year_month::operator+=(const months& dm) NOEXCEPT { *this = *this + dm; return *this; } CONSTCD14 inline year_month& year_month::operator-=(const months& dm) NOEXCEPT { *this = *this - dm; return *this; } CONSTCD14 inline year_month& year_month::operator+=(const years& dy) NOEXCEPT { *this = *this + dy; return *this; } CONSTCD14 inline year_month& year_month::operator-=(const years& dy) NOEXCEPT { *this = *this - dy; return *this; } CONSTCD11 inline bool operator==(const year_month& x, const year_month& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month(); } CONSTCD11 inline bool operator!=(const year_month& x, const year_month& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_month& x, const year_month& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.month() < y.month())); } CONSTCD11 inline bool operator>(const year_month& x, const year_month& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_month& x, const year_month& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_month& x, const year_month& y) NOEXCEPT { return !(x < y); } CONSTCD14 inline year_month operator+(const year_month& ym, const months& dm) NOEXCEPT { auto dmi = static_cast(static_cast(ym.month())) - 1 + dm.count(); auto dy = (dmi >= 0 ? dmi : dmi-11) / 12; dmi = dmi - dy * 12 + 1; return (ym.year() + years(dy)) / month(static_cast(dmi)); } CONSTCD14 inline year_month operator+(const months& dm, const year_month& ym) NOEXCEPT { return ym + dm; } CONSTCD14 inline year_month operator-(const year_month& ym, const months& dm) NOEXCEPT { return ym + -dm; } CONSTCD11 inline months operator-(const year_month& x, const year_month& y) NOEXCEPT { return (x.year() - y.year()) + months(static_cast(x.month()) - static_cast(y.month())); } CONSTCD11 inline year_month operator+(const year_month& ym, const years& dy) NOEXCEPT { return (ym.year() + dy) / ym.month(); } CONSTCD11 inline year_month operator+(const years& dy, const year_month& ym) NOEXCEPT { return ym + dy; } CONSTCD11 inline year_month operator-(const year_month& ym, const years& dy) NOEXCEPT { return ym + -dy; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month& ym) { return os << ym.year() << '/' << ym.month(); } // month_day CONSTCD11 inline month_day::month_day(const solar_hijri::month& m, const solar_hijri::day& d) NOEXCEPT : m_(m) , d_(d) {} CONSTCD11 inline solar_hijri::month month_day::month() const NOEXCEPT {return m_;} CONSTCD11 inline solar_hijri::day month_day::day() const NOEXCEPT {return d_;} CONSTCD14 inline bool month_day::ok() const NOEXCEPT { CONSTDATA solar_hijri::day d[] = { solar_hijri::day(31), solar_hijri::day(31), solar_hijri::day(31), solar_hijri::day(31), solar_hijri::day(31), solar_hijri::day(31), solar_hijri::day(30), solar_hijri::day(30), solar_hijri::day(30), solar_hijri::day(30), solar_hijri::day(30), solar_hijri::day(30) }; return m_.ok() && solar_hijri::day(1) <= d_ && d_ <= d[static_cast(m_)-1]; } CONSTCD11 inline bool operator==(const month_day& x, const month_day& y) NOEXCEPT { return x.month() == y.month() && x.day() == y.day(); } CONSTCD11 inline bool operator!=(const month_day& x, const month_day& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const month_day& x, const month_day& y) NOEXCEPT { return x.month() < y.month() ? true : (x.month() > y.month() ? false : (x.day() < y.day())); } CONSTCD11 inline bool operator>(const month_day& x, const month_day& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const month_day& x, const month_day& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const month_day& x, const month_day& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_day& md) { return os << md.month() << '/' << md.day(); } // month_day_last CONSTCD11 inline month month_day_last::month() const NOEXCEPT {return m_;} CONSTCD11 inline bool month_day_last::ok() const NOEXCEPT {return m_.ok();} CONSTCD11 inline month_day_last::month_day_last(const solar_hijri::month& m) NOEXCEPT : m_(m) {} CONSTCD11 inline bool operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT { return x.month() == y.month(); } CONSTCD11 inline bool operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const month_day_last& x, const month_day_last& y) NOEXCEPT { return x.month() < y.month(); } CONSTCD11 inline bool operator>(const month_day_last& x, const month_day_last& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_day_last& mdl) { return os << mdl.month() << "/last"; } // month_weekday CONSTCD11 inline month_weekday::month_weekday(const solar_hijri::month& m, const solar_hijri::weekday_indexed& wdi) NOEXCEPT : m_(m) , wdi_(wdi) {} CONSTCD11 inline month month_weekday::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday_indexed month_weekday::weekday_indexed() const NOEXCEPT { return wdi_; } CONSTCD11 inline bool month_weekday::ok() const NOEXCEPT { return m_.ok() && wdi_.ok(); } CONSTCD11 inline bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT { return x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed(); } CONSTCD11 inline bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday& mwd) { return os << mwd.month() << '/' << mwd.weekday_indexed(); } // month_weekday_last CONSTCD11 inline month_weekday_last::month_weekday_last(const solar_hijri::month& m, const solar_hijri::weekday_last& wdl) NOEXCEPT : m_(m) , wdl_(wdl) {} CONSTCD11 inline month month_weekday_last::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday_last month_weekday_last::weekday_last() const NOEXCEPT { return wdl_; } CONSTCD11 inline bool month_weekday_last::ok() const NOEXCEPT { return m_.ok() && wdl_.ok(); } CONSTCD11 inline bool operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT { return x.month() == y.month() && x.weekday_last() == y.weekday_last(); } CONSTCD11 inline bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday_last& mwdl) { return os << mwdl.month() << '/' << mwdl.weekday_last(); } // year_month_day_last CONSTCD11 inline year_month_day_last::year_month_day_last(const solar_hijri::year& y, const solar_hijri::month_day_last& mdl) NOEXCEPT : y_(y) , mdl_(mdl) {} CONSTCD14 inline year_month_day_last& year_month_day_last::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline year_month_day_last& year_month_day_last::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_day_last& year_month_day_last::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_day_last& year_month_day_last::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_month_day_last::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_day_last::month() const NOEXCEPT {return mdl_.month();} CONSTCD11 inline month_day_last year_month_day_last::month_day_last() const NOEXCEPT { return mdl_; } CONSTCD14 inline day year_month_day_last::day() const NOEXCEPT { CONSTDATA solar_hijri::day d[] = { solar_hijri::day(31), solar_hijri::day(31), solar_hijri::day(31), solar_hijri::day(31), solar_hijri::day(31), solar_hijri::day(31), solar_hijri::day(30), solar_hijri::day(30), solar_hijri::day(30), solar_hijri::day(30), solar_hijri::day(30), solar_hijri::day(29) }; return month() != esf || !y_.is_leap() ? d[static_cast(month()) - 1] : solar_hijri::day(30); } CONSTCD14 inline year_month_day_last::operator sys_days() const NOEXCEPT { return sys_days(year()/month()/day()); } CONSTCD14 inline year_month_day_last::operator local_days() const NOEXCEPT { return local_days(year()/month()/day()); } CONSTCD11 inline bool year_month_day_last::ok() const NOEXCEPT { return y_.ok() && mdl_.ok(); } CONSTCD11 inline bool operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return x.year() == y.year() && x.month_day_last() == y.month_day_last(); } CONSTCD11 inline bool operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.month_day_last() < y.month_day_last())); } CONSTCD11 inline bool operator>(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day_last& ymdl) { return os << ymdl.year() << '/' << ymdl.month_day_last(); } CONSTCD14 inline year_month_day_last operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT { return (ymdl.year() / ymdl.month() + dm) / last; } CONSTCD14 inline year_month_day_last operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT { return ymdl + dm; } CONSTCD14 inline year_month_day_last operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT { return ymdl + (-dm); } CONSTCD11 inline year_month_day_last operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT { return {ymdl.year()+dy, ymdl.month_day_last()}; } CONSTCD11 inline year_month_day_last operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT { return ymdl + dy; } CONSTCD11 inline year_month_day_last operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT { return ymdl + (-dy); } // year_month_day CONSTCD11 inline year_month_day::year_month_day(const solar_hijri::year& y, const solar_hijri::month& m, const solar_hijri::day& d) NOEXCEPT : y_(y) , m_(m) , d_(d) {} CONSTCD14 inline year_month_day::year_month_day(const year_month_day_last& ymdl) NOEXCEPT : y_(ymdl.year()) , m_(ymdl.month()) , d_(ymdl.day()) {} CONSTCD14 inline year_month_day::year_month_day(sys_days dp) NOEXCEPT : year_month_day(from_days(dp.time_since_epoch())) {} CONSTCD14 inline year_month_day::year_month_day(local_days dp) NOEXCEPT : year_month_day(from_days(dp.time_since_epoch())) {} CONSTCD11 inline year year_month_day::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_day::month() const NOEXCEPT {return m_;} CONSTCD11 inline day year_month_day::day() const NOEXCEPT {return d_;} CONSTCD14 inline year_month_day& year_month_day::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline year_month_day& year_month_day::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_day& year_month_day::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_day& year_month_day::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD14 inline days year_month_day::to_days() const NOEXCEPT { static_assert(std::numeric_limits::digits >= 18, "This algorithm has not been ported to a 16 bit unsigned integer"); static_assert(std::numeric_limits::digits >= 20, "This algorithm has not been ported to a 16 bit signed integer"); using namespace internal; auto const y = static_cast(y_) - 475; auto const m = static_cast(m_); auto const d = static_cast(d_); auto const era_d = static_cast(y >= 0 ? y : y-years_in_era+1) / static_cast(years_in_era); auto const era = static_cast(era_d); auto const fdoe = static_cast(epoch + era * days_in_era); auto const yoe = static_cast(y - era * years_in_era); auto const period_d = static_cast(yoe/years_in_period); auto const period = static_cast(period_d); auto const yop = yoe%years_in_period; auto const fdop = period*days_in_period; auto const cycle = yop < 29 ? 0 : static_cast((yop-29)/years_in_other_cycles + 1); auto const yoc = yop < 29 ? yop : (yop-29)%years_in_other_cycles; auto const fdoc = cycle > 0 ? days_in_first_cycle + (cycle-1)*days_in_other_cycles : 0; auto const group = yoc < 1 ? 0 : static_cast((yoc-1) / 4); auto const yog = static_cast(yoc < 1 ? -1 : (yoc-1) % 4); auto const fdoyog = group*1461 + (yog+1)*365; auto const fdoyoe = fdop + fdoc + fdoyog; auto const doy = 30*(m-1) + ((m > 6) ? 6 : m-1) + d-1; // [0, 365] auto const doe = fdoe + fdoyoe + doy; return days{doe - unix_time_shift}; } CONSTCD14 inline year_month_day::operator sys_days() const NOEXCEPT { return sys_days{to_days()}; } CONSTCD14 inline year_month_day::operator local_days() const NOEXCEPT { return local_days{to_days()}; } CONSTCD14 inline bool year_month_day::ok() const NOEXCEPT { if (!(y_.ok() && m_.ok())) return false; return solar_hijri::day(1) <= d_ && d_ <= (y_/m_/last).day(); } CONSTCD11 inline bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month() && x.day() == y.day(); } CONSTCD11 inline bool operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT { return !(x == y); } CONSTCD11 inline bool operator<(const year_month_day& x, const year_month_day& y) NOEXCEPT { return x.year() < y.year() ? true : (x.year() > y.year() ? false : (x.month() < y.month() ? true : (x.month() > y.month() ? false : (x.day() < y.day())))); } CONSTCD11 inline bool operator>(const year_month_day& x, const year_month_day& y) NOEXCEPT { return y < x; } CONSTCD11 inline bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT { return !(y < x); } CONSTCD11 inline bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT { return !(x < y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day& ymd) { date::detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os << ymd.year() << '-'; os.width(2); os << static_cast(ymd.month()) << '-'; os << ymd.day(); return os; } CONSTCD14 inline year_month_day year_month_day::from_days(days dp) NOEXCEPT { static_assert(std::numeric_limits::digits >= 18, "This algorithm has not been ported to a 16 bit unsigned integer"); static_assert(std::numeric_limits::digits >= 20, "This algorithm has not been ported to a 16 bit signed integer"); using namespace internal; auto const z = dp.count() + unix_time_shift; auto const delta = static_cast(z - epoch); auto const era = static_cast(delta >= 0 ? delta : delta-days_in_era+1) / static_cast(days_in_era); auto const era_i = static_cast(era); auto const fdoe = static_cast(epoch + static_cast(era_i * days_in_era)); auto const doe_fdoe = z - fdoe; auto const period = static_cast(doe_fdoe < 22*days_in_period ? doe_fdoe / days_in_period : 22); auto const dop = doe_fdoe % days_in_period; auto const cycle = dop < days_in_first_cycle ? 0 : (dop-days_in_first_cycle) / days_in_other_cycles + 1; auto const doc = dop < days_in_first_cycle ? dop : (dop-days_in_first_cycle) % days_in_other_cycles; auto const group = doc < 365 && period != 22 ? -1 : static_cast(((doc < 365 ? 365 : doc)-365)/1461); auto const yog = doc < 365 && period != 22 ? -1 : static_cast( (period != 22 ? ((doc-365 )%1461) : doc)/365); auto const yoc = group == -1 ? 0 : (period != 22 ? 1 : 0) + group*4 + (yog == 4 ? 3 : yog); auto const doy = group == -1 ? doc : (period != 22 ? ((yoc-1)%4 == 0 ? (group >= 0 ? (doe_fdoe - (period*days_in_period) - (cycle > 0 ? days_in_first_cycle + (cycle-1)*days_in_other_cycles : 0) - (group*1461 + ((yog == 4 ? 3 : yog)+1)*365)) : 365) : doe_fdoe - (period*days_in_period) - (cycle > 0 ? days_in_first_cycle + (cycle-1)*days_in_other_cycles : 0) - (group*1461 + ((yog == 4 ? 3 : yog)+1)*365)) : (yog == 4 ? 365 : doe_fdoe - (period*days_in_period) - yog*365)); auto const yoe = period != 22 ? period*years_in_period + (cycle > 0 ? years_in_first_cycle + (cycle-1)*years_in_other_cycles : 0) + yoc : 22*years_in_period + ((yog == 4) ? 3 : yog); auto const y = static_cast(static_cast(yoe) + 475 + era_i * years_in_era); auto const m = doy < 186 ? doy/31 + 1 : (doy-186)/30 + 7; // [1, 12] auto const d = doy - (30*(m-1) + ((m > 6) ? 6 : m-1) - 1); // [1, 31] return year_month_day{solar_hijri::year(y), solar_hijri::month(m), solar_hijri::day(d)}; } CONSTCD14 inline year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT { return (ymd.year() / ymd.month() + dm) / ymd.day(); } CONSTCD14 inline year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT { return ymd + dm; } CONSTCD14 inline year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT { return ymd + (-dm); } CONSTCD11 inline year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT { return (ymd.year() + dy) / ymd.month() / ymd.day(); } CONSTCD11 inline year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT { return ymd + dy; } CONSTCD11 inline year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT { return ymd + (-dy); } // year_month_weekday CONSTCD11 inline year_month_weekday::year_month_weekday(const solar_hijri::year& y, const solar_hijri::month& m, const solar_hijri::weekday_indexed& wdi) NOEXCEPT : y_(y) , m_(m) , wdi_(wdi) {} CONSTCD14 inline year_month_weekday::year_month_weekday(const sys_days& dp) NOEXCEPT : year_month_weekday(from_days(dp.time_since_epoch())) {} CONSTCD14 inline year_month_weekday::year_month_weekday(const local_days& dp) NOEXCEPT : year_month_weekday(from_days(dp.time_since_epoch())) {} CONSTCD14 inline year_month_weekday& year_month_weekday::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline year_month_weekday& year_month_weekday::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_weekday& year_month_weekday::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_weekday& year_month_weekday::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_month_weekday::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_weekday::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday year_month_weekday::weekday() const NOEXCEPT { return wdi_.weekday(); } CONSTCD11 inline unsigned year_month_weekday::index() const NOEXCEPT { return wdi_.index(); } CONSTCD11 inline weekday_indexed year_month_weekday::weekday_indexed() const NOEXCEPT { return wdi_; } CONSTCD14 inline year_month_weekday::operator sys_days() const NOEXCEPT { return sys_days{to_days()}; } CONSTCD14 inline year_month_weekday::operator local_days() const NOEXCEPT { return local_days{to_days()}; } CONSTCD14 inline bool year_month_weekday::ok() const NOEXCEPT { if (!y_.ok() || !m_.ok() || !wdi_.weekday().ok() || wdi_.index() < 1) return false; if (wdi_.index() <= 4) return true; auto d2 = wdi_.weekday() - solar_hijri::weekday(y_/m_/1) + days((wdi_.index()-1)*7 + 1); return static_cast(d2.count()) <= static_cast((y_/m_/last).day()); } CONSTCD14 inline year_month_weekday year_month_weekday::from_days(days d) NOEXCEPT { sys_days dp{d}; auto const wd = solar_hijri::weekday(dp); auto const ymd = year_month_day(dp); return {ymd.year(), ymd.month(), wd[(static_cast(ymd.day())-1)/7+1]}; } CONSTCD14 inline days year_month_weekday::to_days() const NOEXCEPT { auto d = sys_days(y_/m_/1); return (d + (wdi_.weekday() - solar_hijri::weekday(d) + days{(wdi_.index()-1)*7}) ).time_since_epoch(); } CONSTCD11 inline bool operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed(); } CONSTCD11 inline bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi) { return os << ymwdi.year() << '/' << ymwdi.month() << '/' << ymwdi.weekday_indexed(); } CONSTCD14 inline year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT { return (ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed(); } CONSTCD14 inline year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT { return ymwd + dm; } CONSTCD14 inline year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT { return ymwd + (-dm); } CONSTCD11 inline year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT { return {ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()}; } CONSTCD11 inline year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT { return ymwd + dy; } CONSTCD11 inline year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT { return ymwd + (-dy); } // year_month_weekday_last CONSTCD11 inline year_month_weekday_last::year_month_weekday_last(const solar_hijri::year& y, const solar_hijri::month& m, const solar_hijri::weekday_last& wdl) NOEXCEPT : y_(y) , m_(m) , wdl_(wdl) {} CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator+=(const months& m) NOEXCEPT { *this = *this + m; return *this; } CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator-=(const months& m) NOEXCEPT { *this = *this - m; return *this; } CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator+=(const years& y) NOEXCEPT { *this = *this + y; return *this; } CONSTCD14 inline year_month_weekday_last& year_month_weekday_last::operator-=(const years& y) NOEXCEPT { *this = *this - y; return *this; } CONSTCD11 inline year year_month_weekday_last::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_weekday_last::month() const NOEXCEPT {return m_;} CONSTCD11 inline weekday year_month_weekday_last::weekday() const NOEXCEPT { return wdl_.weekday(); } CONSTCD11 inline weekday_last year_month_weekday_last::weekday_last() const NOEXCEPT { return wdl_; } CONSTCD14 inline year_month_weekday_last::operator sys_days() const NOEXCEPT { return sys_days{to_days()}; } CONSTCD14 inline year_month_weekday_last::operator local_days() const NOEXCEPT { return local_days{to_days()}; } CONSTCD11 inline bool year_month_weekday_last::ok() const NOEXCEPT { return y_.ok() && m_.ok() && wdl_.ok(); } CONSTCD14 inline days year_month_weekday_last::to_days() const NOEXCEPT { auto const d = sys_days(y_/m_/last); return (d - (solar_hijri::weekday{d} - wdl_.weekday())).time_since_epoch(); } CONSTCD11 inline bool operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT { return x.year() == y.year() && x.month() == y.month() && x.weekday_last() == y.weekday_last(); } CONSTCD11 inline bool operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT { return !(x == y); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl) { return os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last(); } CONSTCD14 inline year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT { return (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last(); } CONSTCD14 inline year_month_weekday_last operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT { return ymwdl + dm; } CONSTCD14 inline year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT { return ymwdl + (-dm); } CONSTCD11 inline year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT { return {ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()}; } CONSTCD11 inline year_month_weekday_last operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT { return ymwdl + dy; } CONSTCD11 inline year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT { return ymwdl + (-dy); } // year_month from operator/() CONSTCD11 inline year_month operator/(const year& y, const month& m) NOEXCEPT { return {y, m}; } CONSTCD11 inline year_month operator/(const year& y, int m) NOEXCEPT { return y / month(static_cast(m)); } // month_day from operator/() CONSTCD11 inline month_day operator/(const month& m, const day& d) NOEXCEPT { return {m, d}; } CONSTCD11 inline month_day operator/(const day& d, const month& m) NOEXCEPT { return m / d; } CONSTCD11 inline month_day operator/(const month& m, int d) NOEXCEPT { return m / day(static_cast(d)); } CONSTCD11 inline month_day operator/(int m, const day& d) NOEXCEPT { return month(static_cast(m)) / d; } CONSTCD11 inline month_day operator/(const day& d, int m) NOEXCEPT {return m / d;} // month_day_last from operator/() CONSTCD11 inline month_day_last operator/(const month& m, last_spec) NOEXCEPT { return month_day_last{m}; } CONSTCD11 inline month_day_last operator/(last_spec, const month& m) NOEXCEPT { return m/last; } CONSTCD11 inline month_day_last operator/(int m, last_spec) NOEXCEPT { return month(static_cast(m))/last; } CONSTCD11 inline month_day_last operator/(last_spec, int m) NOEXCEPT { return m/last; } // month_weekday from operator/() CONSTCD11 inline month_weekday operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT { return {m, wdi}; } CONSTCD11 inline month_weekday operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT { return m / wdi; } CONSTCD11 inline month_weekday operator/(int m, const weekday_indexed& wdi) NOEXCEPT { return month(static_cast(m)) / wdi; } CONSTCD11 inline month_weekday operator/(const weekday_indexed& wdi, int m) NOEXCEPT { return m / wdi; } // month_weekday_last from operator/() CONSTCD11 inline month_weekday_last operator/(const month& m, const weekday_last& wdl) NOEXCEPT { return {m, wdl}; } CONSTCD11 inline month_weekday_last operator/(const weekday_last& wdl, const month& m) NOEXCEPT { return m / wdl; } CONSTCD11 inline month_weekday_last operator/(int m, const weekday_last& wdl) NOEXCEPT { return month(static_cast(m)) / wdl; } CONSTCD11 inline month_weekday_last operator/(const weekday_last& wdl, int m) NOEXCEPT { return m / wdl; } // year_month_day from operator/() CONSTCD11 inline year_month_day operator/(const year_month& ym, const day& d) NOEXCEPT { return {ym.year(), ym.month(), d}; } CONSTCD11 inline year_month_day operator/(const year_month& ym, int d) NOEXCEPT { return ym / day(static_cast(d)); } CONSTCD11 inline year_month_day operator/(const year& y, const month_day& md) NOEXCEPT { return y / md.month() / md.day(); } CONSTCD11 inline year_month_day operator/(int y, const month_day& md) NOEXCEPT { return year(y) / md; } CONSTCD11 inline year_month_day operator/(const month_day& md, const year& y) NOEXCEPT { return y / md; } CONSTCD11 inline year_month_day operator/(const month_day& md, int y) NOEXCEPT { return year(y) / md; } // year_month_day_last from operator/() CONSTCD11 inline year_month_day_last operator/(const year_month& ym, last_spec) NOEXCEPT { return {ym.year(), month_day_last{ym.month()}}; } CONSTCD11 inline year_month_day_last operator/(const year& y, const month_day_last& mdl) NOEXCEPT { return {y, mdl}; } CONSTCD11 inline year_month_day_last operator/(int y, const month_day_last& mdl) NOEXCEPT { return year(y) / mdl; } CONSTCD11 inline year_month_day_last operator/(const month_day_last& mdl, const year& y) NOEXCEPT { return y / mdl; } CONSTCD11 inline year_month_day_last operator/(const month_day_last& mdl, int y) NOEXCEPT { return year(y) / mdl; } // year_month_weekday from operator/() CONSTCD11 inline year_month_weekday operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT { return {ym.year(), ym.month(), wdi}; } CONSTCD11 inline year_month_weekday operator/(const year& y, const month_weekday& mwd) NOEXCEPT { return {y, mwd.month(), mwd.weekday_indexed()}; } CONSTCD11 inline year_month_weekday operator/(int y, const month_weekday& mwd) NOEXCEPT { return year(y) / mwd; } CONSTCD11 inline year_month_weekday operator/(const month_weekday& mwd, const year& y) NOEXCEPT { return y / mwd; } CONSTCD11 inline year_month_weekday operator/(const month_weekday& mwd, int y) NOEXCEPT { return year(y) / mwd; } // year_month_weekday_last from operator/() CONSTCD11 inline year_month_weekday_last operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT { return {ym.year(), ym.month(), wdl}; } CONSTCD11 inline year_month_weekday_last operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT { return {y, mwdl.month(), mwdl.weekday_last()}; } CONSTCD11 inline year_month_weekday_last operator/(int y, const month_weekday_last& mwdl) NOEXCEPT { return year(y) / mwdl; } CONSTCD11 inline year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT { return y / mwdl; } CONSTCD11 inline year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) NOEXCEPT { return year(y) / mwdl; } } // namespace solar_hijri #endif // SOLAR_HIJRI_H date-3.0.1/include/date/tz.h000066400000000000000000002452111403643451100156040ustar00rootroot00000000000000#ifndef TZ_H #define TZ_H // The MIT License (MIT) // // Copyright (c) 2015, 2016, 2017 Howard Hinnant // Copyright (c) 2017 Jiangang Zhuang // Copyright (c) 2017 Aaron Bishop // Copyright (c) 2017 Tomasz Kamiński // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // Our apologies. When the previous paragraph was written, lowercase had not yet // been invented (that would involve another several millennia of evolution). // We did not mean to shout. // Get more recent database at http://www.iana.org/time-zones // The notion of "current timezone" is something the operating system is expected to "just // know". How it knows this is system specific. It's often a value set by the user at OS // installation time and recorded by the OS somewhere. On Linux and Mac systems the current // timezone name is obtained by looking at the name or contents of a particular file on // disk. On Windows the current timezone name comes from the registry. In either method, // there is no guarantee that the "native" current timezone name obtained will match any // of the "Standard" names in this library's "database". On Linux, the names usually do // seem to match so mapping functions to map from native to "Standard" are typically not // required. On Windows, the names are never "Standard" so mapping is always required. // Technically any OS may use the mapping process but currently only Windows does use it. #ifndef USE_OS_TZDB # define USE_OS_TZDB 0 #endif #ifndef HAS_REMOTE_API # if USE_OS_TZDB == 0 # ifdef _WIN32 # define HAS_REMOTE_API 0 # else # define HAS_REMOTE_API 1 # endif # else // HAS_REMOTE_API makes no since when using the OS timezone database # define HAS_REMOTE_API 0 # endif #endif #ifdef __clang__ # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wconstant-logical-operand" #endif static_assert(!(USE_OS_TZDB && HAS_REMOTE_API), "USE_OS_TZDB and HAS_REMOTE_API can not be used together"); #ifdef __clang__ # pragma clang diagnostic pop #endif #ifndef AUTO_DOWNLOAD # define AUTO_DOWNLOAD HAS_REMOTE_API #endif static_assert(HAS_REMOTE_API == 0 ? AUTO_DOWNLOAD == 0 : true, "AUTO_DOWNLOAD can not be turned on without HAS_REMOTE_API"); #ifndef USE_SHELL_API # define USE_SHELL_API 1 #endif #if USE_OS_TZDB # ifdef _WIN32 # error "USE_OS_TZDB can not be used on Windows" # endif #endif #ifndef HAS_DEDUCTION_GUIDES # if __cplusplus >= 201703 # define HAS_DEDUCTION_GUIDES 1 # else # define HAS_DEDUCTION_GUIDES 0 # endif #endif // HAS_DEDUCTION_GUIDES #include "date.h" #if defined(_MSC_VER) && (_MSC_VER < 1900) #include "tz_private.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 # ifdef DATE_BUILD_DLL # define DATE_API __declspec(dllexport) # elif defined(DATE_USE_DLL) # define DATE_API __declspec(dllimport) # else # define DATE_API # endif #else # ifdef DATE_BUILD_DLL # define DATE_API __attribute__ ((visibility ("default"))) # else # define DATE_API # endif #endif namespace date { enum class choose {earliest, latest}; namespace detail { struct undocumented; template struct nodeduct { using type = T; }; template using nodeduct_t = typename nodeduct::type; } struct sys_info { sys_seconds begin; sys_seconds end; std::chrono::seconds offset; std::chrono::minutes save; std::string abbrev; }; template std::basic_ostream& operator<<(std::basic_ostream& os, const sys_info& r) { os << r.begin << '\n'; os << r.end << '\n'; os << make_time(r.offset) << "\n"; os << make_time(r.save) << "\n"; os << r.abbrev << '\n'; return os; } struct local_info { enum {unique, nonexistent, ambiguous} result; sys_info first; sys_info second; }; template std::basic_ostream& operator<<(std::basic_ostream& os, const local_info& r) { if (r.result == local_info::nonexistent) os << "nonexistent between\n"; else if (r.result == local_info::ambiguous) os << "ambiguous between\n"; os << r.first; if (r.result != local_info::unique) { os << "and\n"; os << r.second; } return os; } class nonexistent_local_time : public std::runtime_error { public: template nonexistent_local_time(local_time tp, const local_info& i); private: template static std::string make_msg(local_time tp, const local_info& i); }; template inline nonexistent_local_time::nonexistent_local_time(local_time tp, const local_info& i) : std::runtime_error(make_msg(tp, i)) { } template std::string nonexistent_local_time::make_msg(local_time tp, const local_info& i) { assert(i.result == local_info::nonexistent); std::ostringstream os; os << tp << " is in a gap between\n" << local_seconds{i.first.end.time_since_epoch()} + i.first.offset << ' ' << i.first.abbrev << " and\n" << local_seconds{i.second.begin.time_since_epoch()} + i.second.offset << ' ' << i.second.abbrev << " which are both equivalent to\n" << i.first.end << " UTC"; return os.str(); } class ambiguous_local_time : public std::runtime_error { public: template ambiguous_local_time(local_time tp, const local_info& i); private: template static std::string make_msg(local_time tp, const local_info& i); }; template inline ambiguous_local_time::ambiguous_local_time(local_time tp, const local_info& i) : std::runtime_error(make_msg(tp, i)) { } template std::string ambiguous_local_time::make_msg(local_time tp, const local_info& i) { assert(i.result == local_info::ambiguous); std::ostringstream os; os << tp << " is ambiguous. It could be\n" << tp << ' ' << i.first.abbrev << " == " << tp - i.first.offset << " UTC or\n" << tp << ' ' << i.second.abbrev << " == " << tp - i.second.offset << " UTC"; return os.str(); } class time_zone; #if HAS_STRING_VIEW DATE_API const time_zone* locate_zone(std::string_view tz_name); #else DATE_API const time_zone* locate_zone(const std::string& tz_name); #endif DATE_API const time_zone* current_zone(); template struct zoned_traits { }; template <> struct zoned_traits { static const time_zone* default_zone() { return date::locate_zone("Etc/UTC"); } #if HAS_STRING_VIEW static const time_zone* locate_zone(std::string_view name) { return date::locate_zone(name); } #else // !HAS_STRING_VIEW static const time_zone* locate_zone(const std::string& name) { return date::locate_zone(name); } static const time_zone* locate_zone(const char* name) { return date::locate_zone(name); } #endif // !HAS_STRING_VIEW }; template class zoned_time; template bool operator==(const zoned_time& x, const zoned_time& y); template class zoned_time { public: using duration = typename std::common_type::type; private: TimeZonePtr zone_; sys_time tp_; public: #if !defined(_MSC_VER) || (_MSC_VER > 1916) template ::default_zone())> #endif zoned_time(); #if !defined(_MSC_VER) || (_MSC_VER > 1916) template ::default_zone())> #endif zoned_time(const sys_time& st); explicit zoned_time(TimeZonePtr z); #if HAS_STRING_VIEW template ::locate_zone(std::string_view())) >::value >::type> explicit zoned_time(std::string_view name); #else # if !defined(_MSC_VER) || (_MSC_VER > 1916) template ::locate_zone(std::string())) >::value >::type> # endif explicit zoned_time(const std::string& name); #endif template , sys_time>::value >::type> zoned_time(const zoned_time& zt) NOEXCEPT; zoned_time(TimeZonePtr z, const sys_time& st); #if !defined(_MSC_VER) || (_MSC_VER > 1916) template ()->to_sys(local_time{})), sys_time >::value >::type> #endif zoned_time(TimeZonePtr z, const local_time& tp); #if !defined(_MSC_VER) || (_MSC_VER > 1916) template ()->to_sys(local_time{}, choose::earliest)), sys_time >::value >::type> #endif zoned_time(TimeZonePtr z, const local_time& tp, choose c); template , sys_time>::value >::type> zoned_time(TimeZonePtr z, const zoned_time& zt); template , sys_time>::value >::type> zoned_time(TimeZonePtr z, const zoned_time& zt, choose); #if HAS_STRING_VIEW template ::locate_zone(std::string_view())), sys_time >::value >::type> zoned_time(std::string_view name, detail::nodeduct_t&> st); template ::locate_zone(std::string_view())), local_time >::value >::type> zoned_time(std::string_view name, detail::nodeduct_t&> tp); template ::locate_zone(std::string_view())), local_time, choose >::value >::type> zoned_time(std::string_view name, detail::nodeduct_t&> tp, choose c); template , sys_time>::value && std::is_constructible < zoned_time, decltype(zoned_traits::locate_zone(std::string_view())), zoned_time >::value >::type> zoned_time(std::string_view name, const zoned_time& zt); template , sys_time>::value && std::is_constructible < zoned_time, decltype(zoned_traits::locate_zone(std::string_view())), zoned_time, choose >::value >::type> zoned_time(std::string_view name, const zoned_time& zt, choose); #else // !HAS_STRING_VIEW #if !defined(_MSC_VER) || (_MSC_VER > 1916) template ::locate_zone(std::string())), sys_time >::value >::type> #endif zoned_time(const std::string& name, const sys_time& st); #if !defined(_MSC_VER) || (_MSC_VER > 1916) template ::locate_zone(std::string())), sys_time >::value >::type> #endif zoned_time(const char* name, const sys_time& st); #if !defined(_MSC_VER) || (_MSC_VER > 1916) template ::locate_zone(std::string())), local_time >::value >::type> #endif zoned_time(const std::string& name, const local_time& tp); #if !defined(_MSC_VER) || (_MSC_VER > 1916) template ::locate_zone(std::string())), local_time >::value >::type> #endif zoned_time(const char* name, const local_time& tp); #if !defined(_MSC_VER) || (_MSC_VER > 1916) template ::locate_zone(std::string())), local_time, choose >::value >::type> #endif zoned_time(const std::string& name, const local_time& tp, choose c); #if !defined(_MSC_VER) || (_MSC_VER > 1916) template ::locate_zone(std::string())), local_time, choose >::value >::type> #endif zoned_time(const char* name, const local_time& tp, choose c); #if !defined(_MSC_VER) || (_MSC_VER > 1916) template , sys_time>::value && std::is_constructible < zoned_time, decltype(zoned_traits::locate_zone(std::string())), zoned_time >::value >::type> #else template #endif zoned_time(const std::string& name, const zoned_time& zt); #if !defined(_MSC_VER) || (_MSC_VER > 1916) template , sys_time>::value && std::is_constructible < zoned_time, decltype(zoned_traits::locate_zone(std::string())), zoned_time >::value >::type> #else template #endif zoned_time(const char* name, const zoned_time& zt); #if !defined(_MSC_VER) || (_MSC_VER > 1916) template , sys_time>::value && std::is_constructible < zoned_time, decltype(zoned_traits::locate_zone(std::string())), zoned_time, choose >::value >::type> #else template #endif zoned_time(const std::string& name, const zoned_time& zt, choose); #if !defined(_MSC_VER) || (_MSC_VER > 1916) template , sys_time>::value && std::is_constructible < zoned_time, decltype(zoned_traits::locate_zone(std::string())), zoned_time, choose >::value >::type> #else template #endif zoned_time(const char* name, const zoned_time& zt, choose); #endif // !HAS_STRING_VIEW zoned_time& operator=(const sys_time& st); zoned_time& operator=(const local_time& ut); explicit operator sys_time() const; explicit operator local_time() const; TimeZonePtr get_time_zone() const; local_time get_local_time() const; sys_time get_sys_time() const; sys_info get_info() const; template friend bool operator==(const zoned_time& x, const zoned_time& y); template friend std::basic_ostream& operator<<(std::basic_ostream& os, const zoned_time& t); private: template friend class zoned_time; template static TimeZonePtr2&& check(TimeZonePtr2&& p); }; using zoned_seconds = zoned_time; #if HAS_DEDUCTION_GUIDES namespace detail { template using time_zone_representation = std::conditional_t < std::is_convertible::value, time_zone const*, std::remove_cv_t> >; } zoned_time() -> zoned_time; template zoned_time(sys_time) -> zoned_time>; template zoned_time(TimeZonePtrOrName&&) -> zoned_time>; template zoned_time(TimeZonePtrOrName&&, sys_time) -> zoned_time, detail::time_zone_representation>; template zoned_time(TimeZonePtrOrName&&, local_time, choose = choose::earliest) -> zoned_time, detail::time_zone_representation>; template zoned_time(TimeZonePtrOrName&&, zoned_time, choose = choose::earliest) -> zoned_time, detail::time_zone_representation>; #endif // HAS_DEDUCTION_GUIDES template inline bool operator==(const zoned_time& x, const zoned_time& y) { return x.zone_ == y.zone_ && x.tp_ == y.tp_; } template inline bool operator!=(const zoned_time& x, const zoned_time& y) { return !(x == y); } #if !defined(_MSC_VER) || (_MSC_VER >= 1900) namespace detail { # if USE_OS_TZDB struct transition; struct expanded_ttinfo; # else // !USE_OS_TZDB struct zonelet; class Rule; # endif // !USE_OS_TZDB } #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) class time_zone { private: std::string name_; #if USE_OS_TZDB std::vector transitions_; std::vector ttinfos_; #else // !USE_OS_TZDB std::vector zonelets_; #endif // !USE_OS_TZDB std::unique_ptr adjusted_; public: #if !defined(_MSC_VER) || (_MSC_VER >= 1900) time_zone(time_zone&&) = default; time_zone& operator=(time_zone&&) = default; #else // defined(_MSC_VER) && (_MSC_VER < 1900) time_zone(time_zone&& src); time_zone& operator=(time_zone&& src); #endif // defined(_MSC_VER) && (_MSC_VER < 1900) DATE_API explicit time_zone(const std::string& s, detail::undocumented); const std::string& name() const NOEXCEPT; template sys_info get_info(sys_time st) const; template local_info get_info(local_time tp) const; template sys_time::type> to_sys(local_time tp) const; template sys_time::type> to_sys(local_time tp, choose z) const; template local_time::type> to_local(sys_time tp) const; friend bool operator==(const time_zone& x, const time_zone& y) NOEXCEPT; friend bool operator< (const time_zone& x, const time_zone& y) NOEXCEPT; friend DATE_API std::ostream& operator<<(std::ostream& os, const time_zone& z); #if !USE_OS_TZDB DATE_API void add(const std::string& s); #endif // !USE_OS_TZDB private: DATE_API sys_info get_info_impl(sys_seconds tp) const; DATE_API local_info get_info_impl(local_seconds tp) const; template sys_time::type> to_sys_impl(local_time tp, choose z, std::false_type) const; template sys_time::type> to_sys_impl(local_time tp, choose, std::true_type) const; #if USE_OS_TZDB DATE_API void init() const; DATE_API void init_impl(); DATE_API sys_info load_sys_info(std::vector::const_iterator i) const; template DATE_API void load_data(std::istream& inf, std::int32_t tzh_leapcnt, std::int32_t tzh_timecnt, std::int32_t tzh_typecnt, std::int32_t tzh_charcnt); #else // !USE_OS_TZDB DATE_API sys_info get_info_impl(sys_seconds tp, int timezone) const; DATE_API void adjust_infos(const std::vector& rules); DATE_API void parse_info(std::istream& in); #endif // !USE_OS_TZDB }; #if defined(_MSC_VER) && (_MSC_VER < 1900) inline time_zone::time_zone(time_zone&& src) : name_(std::move(src.name_)) , zonelets_(std::move(src.zonelets_)) , adjusted_(std::move(src.adjusted_)) {} inline time_zone& time_zone::operator=(time_zone&& src) { name_ = std::move(src.name_); zonelets_ = std::move(src.zonelets_); adjusted_ = std::move(src.adjusted_); return *this; } #endif // defined(_MSC_VER) && (_MSC_VER < 1900) inline const std::string& time_zone::name() const NOEXCEPT { return name_; } template inline sys_info time_zone::get_info(sys_time st) const { return get_info_impl(date::floor(st)); } template inline local_info time_zone::get_info(local_time tp) const { return get_info_impl(date::floor(tp)); } template inline sys_time::type> time_zone::to_sys(local_time tp) const { return to_sys_impl(tp, choose{}, std::true_type{}); } template inline sys_time::type> time_zone::to_sys(local_time tp, choose z) const { return to_sys_impl(tp, z, std::false_type{}); } template inline local_time::type> time_zone::to_local(sys_time tp) const { using LT = local_time::type>; auto i = get_info(tp); return LT{(tp + i.offset).time_since_epoch()}; } inline bool operator==(const time_zone& x, const time_zone& y) NOEXCEPT {return x.name_ == y.name_;} inline bool operator< (const time_zone& x, const time_zone& y) NOEXCEPT {return x.name_ < y.name_;} inline bool operator!=(const time_zone& x, const time_zone& y) NOEXCEPT {return !(x == y);} inline bool operator> (const time_zone& x, const time_zone& y) NOEXCEPT {return y < x;} inline bool operator<=(const time_zone& x, const time_zone& y) NOEXCEPT {return !(y < x);} inline bool operator>=(const time_zone& x, const time_zone& y) NOEXCEPT {return !(x < y);} template sys_time::type> time_zone::to_sys_impl(local_time tp, choose z, std::false_type) const { auto i = get_info(tp); if (i.result == local_info::nonexistent) { return i.first.end; } else if (i.result == local_info::ambiguous) { if (z == choose::latest) return sys_time{tp.time_since_epoch()} - i.second.offset; } return sys_time{tp.time_since_epoch()} - i.first.offset; } template sys_time::type> time_zone::to_sys_impl(local_time tp, choose, std::true_type) const { auto i = get_info(tp); if (i.result == local_info::nonexistent) throw nonexistent_local_time(tp, i); else if (i.result == local_info::ambiguous) throw ambiguous_local_time(tp, i); return sys_time{tp.time_since_epoch()} - i.first.offset; } #if !USE_OS_TZDB class time_zone_link { private: std::string name_; std::string target_; public: DATE_API explicit time_zone_link(const std::string& s); const std::string& name() const {return name_;} const std::string& target() const {return target_;} friend bool operator==(const time_zone_link& x, const time_zone_link& y) {return x.name_ == y.name_;} friend bool operator< (const time_zone_link& x, const time_zone_link& y) {return x.name_ < y.name_;} friend DATE_API std::ostream& operator<<(std::ostream& os, const time_zone_link& x); }; using link = time_zone_link; inline bool operator!=(const time_zone_link& x, const time_zone_link& y) {return !(x == y);} inline bool operator> (const time_zone_link& x, const time_zone_link& y) {return y < x;} inline bool operator<=(const time_zone_link& x, const time_zone_link& y) {return !(y < x);} inline bool operator>=(const time_zone_link& x, const time_zone_link& y) {return !(x < y);} #endif // !USE_OS_TZDB class leap_second { private: sys_seconds date_; public: #if USE_OS_TZDB DATE_API explicit leap_second(const sys_seconds& s, detail::undocumented); #else DATE_API explicit leap_second(const std::string& s, detail::undocumented); #endif sys_seconds date() const {return date_;} friend bool operator==(const leap_second& x, const leap_second& y) {return x.date_ == y.date_;} friend bool operator< (const leap_second& x, const leap_second& y) {return x.date_ < y.date_;} template friend bool operator==(const leap_second& x, const sys_time& y) { return x.date_ == y; } template friend bool operator< (const leap_second& x, const sys_time& y) { return x.date_ < y; } template friend bool operator< (const sys_time& x, const leap_second& y) { return x < y.date_; } friend DATE_API std::ostream& operator<<(std::ostream& os, const leap_second& x); }; inline bool operator!=(const leap_second& x, const leap_second& y) {return !(x == y);} inline bool operator> (const leap_second& x, const leap_second& y) {return y < x;} inline bool operator<=(const leap_second& x, const leap_second& y) {return !(y < x);} inline bool operator>=(const leap_second& x, const leap_second& y) {return !(x < y);} template inline bool operator==(const sys_time& x, const leap_second& y) { return y == x; } template inline bool operator!=(const leap_second& x, const sys_time& y) { return !(x == y); } template inline bool operator!=(const sys_time& x, const leap_second& y) { return !(x == y); } template inline bool operator> (const leap_second& x, const sys_time& y) { return y < x; } template inline bool operator> (const sys_time& x, const leap_second& y) { return y < x; } template inline bool operator<=(const leap_second& x, const sys_time& y) { return !(y < x); } template inline bool operator<=(const sys_time& x, const leap_second& y) { return !(y < x); } template inline bool operator>=(const leap_second& x, const sys_time& y) { return !(x < y); } template inline bool operator>=(const sys_time& x, const leap_second& y) { return !(x < y); } using leap = leap_second; #ifdef _WIN32 namespace detail { // The time zone mapping is modelled after this data file: // http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml // and the field names match the element names from the mapZone element // of windowsZones.xml. // The website displays this file here: // http://www.unicode.org/cldr/charts/latest/supplemental/zone_tzid.html // The html view is sorted before being displayed but is otherwise the same // There is a mapping between the os centric view (in this case windows) // the html displays uses and the generic view the xml file. // That mapping is this: // display column "windows" -> xml field "other". // display column "region" -> xml field "territory". // display column "tzid" -> xml field "type". // This structure uses the generic terminology because it could be // used to to support other os/native name conversions, not just windows, // and using the same generic names helps retain the connection to the // origin of the data that we are using. struct timezone_mapping { timezone_mapping(const char* other, const char* territory, const char* type) : other(other), territory(territory), type(type) { } timezone_mapping() = default; std::string other; std::string territory; std::string type; }; } // detail #endif // _WIN32 struct tzdb { std::string version = "unknown"; std::vector zones; #if !USE_OS_TZDB std::vector links; #endif std::vector leap_seconds; #if !USE_OS_TZDB std::vector rules; #endif #ifdef _WIN32 std::vector mappings; #endif tzdb* next = nullptr; tzdb() = default; #if !defined(_MSC_VER) || (_MSC_VER >= 1900) tzdb(tzdb&&) = default; tzdb& operator=(tzdb&&) = default; #else // defined(_MSC_VER) && (_MSC_VER < 1900) tzdb(tzdb&& src) : version(std::move(src.version)) , zones(std::move(src.zones)) , links(std::move(src.links)) , leap_seconds(std::move(src.leap_seconds)) , rules(std::move(src.rules)) , mappings(std::move(src.mappings)) {} tzdb& operator=(tzdb&& src) { version = std::move(src.version); zones = std::move(src.zones); links = std::move(src.links); leap_seconds = std::move(src.leap_seconds); rules = std::move(src.rules); mappings = std::move(src.mappings); return *this; } #endif // defined(_MSC_VER) && (_MSC_VER < 1900) #if HAS_STRING_VIEW const time_zone* locate_zone(std::string_view tz_name) const; #else const time_zone* locate_zone(const std::string& tz_name) const; #endif const time_zone* current_zone() const; }; using TZ_DB = tzdb; DATE_API std::ostream& operator<<(std::ostream& os, const tzdb& db); DATE_API const tzdb& get_tzdb(); class tzdb_list { std::atomic head_{nullptr}; public: ~tzdb_list(); tzdb_list() = default; tzdb_list(tzdb_list&& x) NOEXCEPT; const tzdb& front() const NOEXCEPT {return *head_;} tzdb& front() NOEXCEPT {return *head_;} class const_iterator; const_iterator begin() const NOEXCEPT; const_iterator end() const NOEXCEPT; const_iterator cbegin() const NOEXCEPT; const_iterator cend() const NOEXCEPT; const_iterator erase_after(const_iterator p) NOEXCEPT; struct undocumented_helper; private: void push_front(tzdb* tzdb) NOEXCEPT; }; class tzdb_list::const_iterator { tzdb* p_ = nullptr; explicit const_iterator(tzdb* p) NOEXCEPT : p_{p} {} public: const_iterator() = default; using iterator_category = std::forward_iterator_tag; using value_type = tzdb; using reference = const value_type&; using pointer = const value_type*; using difference_type = std::ptrdiff_t; reference operator*() const NOEXCEPT {return *p_;} pointer operator->() const NOEXCEPT {return p_;} const_iterator& operator++() NOEXCEPT {p_ = p_->next; return *this;} const_iterator operator++(int) NOEXCEPT {auto t = *this; ++(*this); return t;} friend bool operator==(const const_iterator& x, const const_iterator& y) NOEXCEPT {return x.p_ == y.p_;} friend bool operator!=(const const_iterator& x, const const_iterator& y) NOEXCEPT {return !(x == y);} friend class tzdb_list; }; inline tzdb_list::const_iterator tzdb_list::begin() const NOEXCEPT { return const_iterator{head_}; } inline tzdb_list::const_iterator tzdb_list::end() const NOEXCEPT { return const_iterator{nullptr}; } inline tzdb_list::const_iterator tzdb_list::cbegin() const NOEXCEPT { return begin(); } inline tzdb_list::const_iterator tzdb_list::cend() const NOEXCEPT { return end(); } DATE_API tzdb_list& get_tzdb_list(); #if !USE_OS_TZDB DATE_API const tzdb& reload_tzdb(); DATE_API void set_install(const std::string& install); #endif // !USE_OS_TZDB #if HAS_REMOTE_API DATE_API std::string remote_version(); // if provided error_buffer size should be at least CURL_ERROR_SIZE DATE_API bool remote_download(const std::string& version, char* error_buffer = nullptr); DATE_API bool remote_install(const std::string& version); #endif // zoned_time namespace detail { template inline T* to_raw_pointer(T* p) NOEXCEPT { return p; } template inline auto to_raw_pointer(Pointer p) NOEXCEPT -> decltype(detail::to_raw_pointer(p.operator->())) { return detail::to_raw_pointer(p.operator->()); } } // namespace detail template template inline TimeZonePtr2&& zoned_time::check(TimeZonePtr2&& p) { if (detail::to_raw_pointer(p) == nullptr) throw std::runtime_error( "zoned_time constructed with a time zone pointer == nullptr"); return std::forward(p); } template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #endif inline zoned_time::zoned_time() : zone_(check(zoned_traits::default_zone())) {} template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #endif inline zoned_time::zoned_time(const sys_time& st) : zone_(check(zoned_traits::default_zone())) , tp_(st) {} template inline zoned_time::zoned_time(TimeZonePtr z) : zone_(check(std::move(z))) {} #if HAS_STRING_VIEW template template inline zoned_time::zoned_time(std::string_view name) : zoned_time(zoned_traits::locate_zone(name)) {} #else // !HAS_STRING_VIEW template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #endif inline zoned_time::zoned_time(const std::string& name) : zoned_time(zoned_traits::locate_zone(name)) {} #endif // !HAS_STRING_VIEW template template inline zoned_time::zoned_time(const zoned_time& zt) NOEXCEPT : zone_(zt.zone_) , tp_(zt.tp_) {} template inline zoned_time::zoned_time(TimeZonePtr z, const sys_time& st) : zone_(check(std::move(z))) , tp_(st) {} template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #endif inline zoned_time::zoned_time(TimeZonePtr z, const local_time& t) : zone_(check(std::move(z))) , tp_(zone_->to_sys(t)) {} template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #endif inline zoned_time::zoned_time(TimeZonePtr z, const local_time& t, choose c) : zone_(check(std::move(z))) , tp_(zone_->to_sys(t, c)) {} template template inline zoned_time::zoned_time(TimeZonePtr z, const zoned_time& zt) : zone_(check(std::move(z))) , tp_(zt.tp_) {} template template inline zoned_time::zoned_time(TimeZonePtr z, const zoned_time& zt, choose) : zoned_time(std::move(z), zt) {} #if HAS_STRING_VIEW template template inline zoned_time::zoned_time(std::string_view name, detail::nodeduct_t&> st) : zoned_time(zoned_traits::locate_zone(name), st) {} template template inline zoned_time::zoned_time(std::string_view name, detail::nodeduct_t&> t) : zoned_time(zoned_traits::locate_zone(name), t) {} template template inline zoned_time::zoned_time(std::string_view name, detail::nodeduct_t&> t, choose c) : zoned_time(zoned_traits::locate_zone(name), t, c) {} template template inline zoned_time::zoned_time(std::string_view name, const zoned_time& zt) : zoned_time(zoned_traits::locate_zone(name), zt) {} template template inline zoned_time::zoned_time(std::string_view name, const zoned_time& zt, choose c) : zoned_time(zoned_traits::locate_zone(name), zt, c) {} #else // !HAS_STRING_VIEW template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #endif inline zoned_time::zoned_time(const std::string& name, const sys_time& st) : zoned_time(zoned_traits::locate_zone(name), st) {} template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #endif inline zoned_time::zoned_time(const char* name, const sys_time& st) : zoned_time(zoned_traits::locate_zone(name), st) {} template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #endif inline zoned_time::zoned_time(const std::string& name, const local_time& t) : zoned_time(zoned_traits::locate_zone(name), t) {} template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #endif inline zoned_time::zoned_time(const char* name, const local_time& t) : zoned_time(zoned_traits::locate_zone(name), t) {} template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #endif inline zoned_time::zoned_time(const std::string& name, const local_time& t, choose c) : zoned_time(zoned_traits::locate_zone(name), t, c) {} template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #endif inline zoned_time::zoned_time(const char* name, const local_time& t, choose c) : zoned_time(zoned_traits::locate_zone(name), t, c) {} template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #else template #endif inline zoned_time::zoned_time(const std::string& name, const zoned_time& zt) : zoned_time(zoned_traits::locate_zone(name), zt) {} template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #else template #endif inline zoned_time::zoned_time(const char* name, const zoned_time& zt) : zoned_time(zoned_traits::locate_zone(name), zt) {} template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #else template #endif inline zoned_time::zoned_time(const std::string& name, const zoned_time& zt, choose c) : zoned_time(zoned_traits::locate_zone(name), zt, c) {} template #if !defined(_MSC_VER) || (_MSC_VER > 1916) template #else template #endif inline zoned_time::zoned_time(const char* name, const zoned_time& zt, choose c) : zoned_time(zoned_traits::locate_zone(name), zt, c) {} #endif // HAS_STRING_VIEW template inline zoned_time& zoned_time::operator=(const sys_time& st) { tp_ = st; return *this; } template inline zoned_time& zoned_time::operator=(const local_time& ut) { tp_ = zone_->to_sys(ut); return *this; } template inline zoned_time::operator local_time::duration>() const { return get_local_time(); } template inline zoned_time::operator sys_time::duration>() const { return get_sys_time(); } template inline TimeZonePtr zoned_time::get_time_zone() const { return zone_; } template inline local_time::duration> zoned_time::get_local_time() const { return zone_->to_local(tp_); } template inline sys_time::duration> zoned_time::get_sys_time() const { return tp_; } template inline sys_info zoned_time::get_info() const { return zone_->get_info(tp_); } // make_zoned_time inline zoned_time make_zoned() { return zoned_time(); } template inline zoned_time::type> make_zoned(const sys_time& tp) { return zoned_time::type>(tp); } template 1916) #if !defined(__INTEL_COMPILER) || (__INTEL_COMPILER > 1600) , class = typename std::enable_if < std::is_class < typename std::decay < decltype(*detail::to_raw_pointer(std::declval())) >::type >{} >::type #endif #endif > inline zoned_time make_zoned(TimeZonePtr z) { return zoned_time(std::move(z)); } inline zoned_seconds make_zoned(const std::string& name) { return zoned_seconds(name); } template 1916) #if !defined(__INTEL_COMPILER) || (__INTEL_COMPILER > 1600) , class = typename std::enable_if < std::is_class())>::type>{} >::type #endif #endif > inline zoned_time::type, TimeZonePtr> make_zoned(TimeZonePtr zone, const local_time& tp) { return zoned_time::type, TimeZonePtr>(std::move(zone), tp); } template 1916) #if !defined(__INTEL_COMPILER) || (__INTEL_COMPILER > 1600) , class = typename std::enable_if < std::is_class())>::type>{} >::type #endif #endif > inline zoned_time::type, TimeZonePtr> make_zoned(TimeZonePtr zone, const local_time& tp, choose c) { return zoned_time::type, TimeZonePtr>(std::move(zone), tp, c); } template inline zoned_time::type> make_zoned(const std::string& name, const local_time& tp) { return zoned_time::type>(name, tp); } template inline zoned_time::type> make_zoned(const std::string& name, const local_time& tp, choose c) { return zoned_time::type>(name, tp, c); } template inline zoned_time make_zoned(TimeZonePtr zone, const zoned_time& zt) { return zoned_time(std::move(zone), zt); } template inline zoned_time make_zoned(const std::string& name, const zoned_time& zt) { return zoned_time(name, zt); } template inline zoned_time make_zoned(TimeZonePtr zone, const zoned_time& zt, choose c) { return zoned_time(std::move(zone), zt, c); } template inline zoned_time make_zoned(const std::string& name, const zoned_time& zt, choose c) { return zoned_time(name, zt, c); } template 1916) #if !defined(__INTEL_COMPILER) || (__INTEL_COMPILER > 1600) , class = typename std::enable_if < std::is_class())>::type>{} >::type #endif #endif > inline zoned_time::type, TimeZonePtr> make_zoned(TimeZonePtr zone, const sys_time& st) { return zoned_time::type, TimeZonePtr>(std::move(zone), st); } template inline zoned_time::type> make_zoned(const std::string& name, const sys_time& st) { return zoned_time::type>(name, st); } template std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const zoned_time& tp) { using duration = typename zoned_time::duration; using LT = local_time; auto const st = tp.get_sys_time(); auto const info = tp.get_time_zone()->get_info(st); return to_stream(os, fmt, LT{(st+info.offset).time_since_epoch()}, &info.abbrev, &info.offset); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const zoned_time& t) { const CharT fmt[] = {'%', 'F', ' ', '%', 'T', ' ', '%', 'Z', CharT{}}; return to_stream(os, fmt, t); } class utc_clock { public: using duration = std::chrono::system_clock::duration; using rep = duration::rep; using period = duration::period; using time_point = std::chrono::time_point; static CONSTDATA bool is_steady = false; static time_point now(); template static std::chrono::time_point::type> to_sys(const std::chrono::time_point&); template static std::chrono::time_point::type> from_sys(const std::chrono::time_point&); template static std::chrono::time_point::type> to_local(const std::chrono::time_point&); template static std::chrono::time_point::type> from_local(const std::chrono::time_point&); }; template using utc_time = std::chrono::time_point; using utc_seconds = utc_time; template utc_time::type> utc_clock::from_sys(const sys_time& st) { using std::chrono::seconds; using CD = typename std::common_type::type; auto const& leaps = get_tzdb().leap_seconds; auto const lt = std::upper_bound(leaps.begin(), leaps.end(), st); return utc_time{st.time_since_epoch() + seconds{lt-leaps.begin()}}; } // Return pair // first is true if ut is during a leap second insertion, otherwise false. // If ut is during a leap second insertion, that leap second is included in the count template std::pair is_leap_second(date::utc_time const& ut) { using std::chrono::seconds; using duration = typename std::common_type::type; auto const& leaps = get_tzdb().leap_seconds; auto tp = sys_time{ut.time_since_epoch()}; auto const lt = std::upper_bound(leaps.begin(), leaps.end(), tp); auto ds = seconds{lt-leaps.begin()}; tp -= ds; auto ls = false; if (lt > leaps.begin()) { if (tp < lt[-1]) { if (tp >= lt[-1].date() - seconds{1}) ls = true; else --ds; } } return {ls, ds}; } struct leap_second_info { bool is_leap_second; std::chrono::seconds elapsed; }; template leap_second_info get_leap_second_info(date::utc_time const& ut) { auto p = is_leap_second(ut); return {p.first, p.second}; } template sys_time::type> utc_clock::to_sys(const utc_time& ut) { using std::chrono::seconds; using CD = typename std::common_type::type; auto ls = is_leap_second(ut); auto tp = sys_time{ut.time_since_epoch() - ls.second}; if (ls.first) tp = floor(tp) + seconds{1} - CD{1}; return tp; } inline utc_clock::time_point utc_clock::now() { return from_sys(std::chrono::system_clock::now()); } template utc_time::type> utc_clock::from_local(const local_time& st) { return from_sys(sys_time{st.time_since_epoch()}); } template local_time::type> utc_clock::to_local(const utc_time& ut) { using CD = typename std::common_type::type; return local_time{to_sys(ut).time_since_epoch()}; } template std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const utc_time& t) { using std::chrono::seconds; using CT = typename std::common_type::type; const std::string abbrev("UTC"); CONSTDATA seconds offset{0}; auto ls = is_leap_second(t); auto tp = sys_time{t.time_since_epoch() - ls.second}; auto const sd = floor(tp); year_month_day ymd = sd; auto time = make_time(tp - sys_seconds{sd}); time.seconds(detail::undocumented{}) += seconds{ls.first}; fields fds{ymd, time}; return to_stream(os, fmt, fds, &abbrev, &offset); } template std::basic_ostream& operator<<(std::basic_ostream& os, const utc_time& t) { const CharT fmt[] = {'%', 'F', ' ', '%', 'T', CharT{}}; return to_stream(os, fmt, t); } template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, utc_time& tp, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { using std::chrono::seconds; using std::chrono::minutes; using CT = typename std::common_type::type; minutes offset_local{}; auto offptr = offset ? offset : &offset_local; fields fds{}; fds.has_tod = true; from_stream(is, fmt, fds, abbrev, offptr); if (!fds.ymd.ok()) is.setstate(std::ios::failbit); if (!is.fail()) { bool is_60_sec = fds.tod.seconds() == seconds{60}; if (is_60_sec) fds.tod.seconds(detail::undocumented{}) -= seconds{1}; auto tmp = utc_clock::from_sys(sys_days(fds.ymd) - *offptr + fds.tod.to_duration()); if (is_60_sec) tmp += seconds{1}; if (is_60_sec != is_leap_second(tmp).first || !fds.tod.in_conventional_range()) { is.setstate(std::ios::failbit); return is; } tp = std::chrono::time_point_cast(tmp); } return is; } // tai_clock class tai_clock { public: using duration = std::chrono::system_clock::duration; using rep = duration::rep; using period = duration::period; using time_point = std::chrono::time_point; static const bool is_steady = false; static time_point now(); template static std::chrono::time_point::type> to_utc(const std::chrono::time_point&) NOEXCEPT; template static std::chrono::time_point::type> from_utc(const std::chrono::time_point&) NOEXCEPT; template static std::chrono::time_point::type> to_local(const std::chrono::time_point&) NOEXCEPT; template static std::chrono::time_point::type> from_local(const std::chrono::time_point&) NOEXCEPT; }; template using tai_time = std::chrono::time_point; using tai_seconds = tai_time; template inline utc_time::type> tai_clock::to_utc(const tai_time& t) NOEXCEPT { using std::chrono::seconds; using CD = typename std::common_type::type; return utc_time{t.time_since_epoch()} - (sys_days(year{1970}/January/1) - sys_days(year{1958}/January/1) + seconds{10}); } template inline tai_time::type> tai_clock::from_utc(const utc_time& t) NOEXCEPT { using std::chrono::seconds; using CD = typename std::common_type::type; return tai_time{t.time_since_epoch()} + (sys_days(year{1970}/January/1) - sys_days(year{1958}/January/1) + seconds{10}); } inline tai_clock::time_point tai_clock::now() { return from_utc(utc_clock::now()); } template inline local_time::type> tai_clock::to_local(const tai_time& t) NOEXCEPT { using CD = typename std::common_type::type; return local_time{t.time_since_epoch()} - (local_days(year{1970}/January/1) - local_days(year{1958}/January/1)); } template inline tai_time::type> tai_clock::from_local(const local_time& t) NOEXCEPT { using CD = typename std::common_type::type; return tai_time{t.time_since_epoch()} + (local_days(year{1970}/January/1) - local_days(year{1958}/January/1)); } template std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const tai_time& t) { const std::string abbrev("TAI"); CONSTDATA std::chrono::seconds offset{0}; return to_stream(os, fmt, tai_clock::to_local(t), &abbrev, &offset); } template std::basic_ostream& operator<<(std::basic_ostream& os, const tai_time& t) { const CharT fmt[] = {'%', 'F', ' ', '%', 'T', CharT{}}; return to_stream(os, fmt, t); } template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, tai_time& tp, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { local_time lp; from_stream(is, fmt, lp, abbrev, offset); if (!is.fail()) tp = tai_clock::from_local(lp); return is; } // gps_clock class gps_clock { public: using duration = std::chrono::system_clock::duration; using rep = duration::rep; using period = duration::period; using time_point = std::chrono::time_point; static const bool is_steady = false; static time_point now(); template static std::chrono::time_point::type> to_utc(const std::chrono::time_point&) NOEXCEPT; template static std::chrono::time_point::type> from_utc(const std::chrono::time_point&) NOEXCEPT; template static std::chrono::time_point::type> to_local(const std::chrono::time_point&) NOEXCEPT; template static std::chrono::time_point::type> from_local(const std::chrono::time_point&) NOEXCEPT; }; template using gps_time = std::chrono::time_point; using gps_seconds = gps_time; template inline utc_time::type> gps_clock::to_utc(const gps_time& t) NOEXCEPT { using std::chrono::seconds; using CD = typename std::common_type::type; return utc_time{t.time_since_epoch()} + (sys_days(year{1980}/January/Sunday[1]) - sys_days(year{1970}/January/1) + seconds{9}); } template inline gps_time::type> gps_clock::from_utc(const utc_time& t) NOEXCEPT { using std::chrono::seconds; using CD = typename std::common_type::type; return gps_time{t.time_since_epoch()} - (sys_days(year{1980}/January/Sunday[1]) - sys_days(year{1970}/January/1) + seconds{9}); } inline gps_clock::time_point gps_clock::now() { return from_utc(utc_clock::now()); } template inline local_time::type> gps_clock::to_local(const gps_time& t) NOEXCEPT { using CD = typename std::common_type::type; return local_time{t.time_since_epoch()} + (local_days(year{1980}/January/Sunday[1]) - local_days(year{1970}/January/1)); } template inline gps_time::type> gps_clock::from_local(const local_time& t) NOEXCEPT { using CD = typename std::common_type::type; return gps_time{t.time_since_epoch()} - (local_days(year{1980}/January/Sunday[1]) - local_days(year{1970}/January/1)); } template std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const gps_time& t) { const std::string abbrev("GPS"); CONSTDATA std::chrono::seconds offset{0}; return to_stream(os, fmt, gps_clock::to_local(t), &abbrev, &offset); } template std::basic_ostream& operator<<(std::basic_ostream& os, const gps_time& t) { const CharT fmt[] = {'%', 'F', ' ', '%', 'T', CharT{}}; return to_stream(os, fmt, t); } template > std::basic_istream& from_stream(std::basic_istream& is, const CharT* fmt, gps_time& tp, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { local_time lp; from_stream(is, fmt, lp, abbrev, offset); if (!is.fail()) tp = gps_clock::from_local(lp); return is; } // clock_time_conversion template struct clock_time_conversion {}; template <> struct clock_time_conversion { template CONSTCD14 sys_time operator()(const sys_time& st) const { return st; } }; template <> struct clock_time_conversion { template CONSTCD14 utc_time operator()(const utc_time& ut) const { return ut; } }; template<> struct clock_time_conversion { template CONSTCD14 local_time operator()(const local_time& lt) const { return lt; } }; template <> struct clock_time_conversion { template utc_time::type> operator()(const sys_time& st) const { return utc_clock::from_sys(st); } }; template <> struct clock_time_conversion { template sys_time::type> operator()(const utc_time& ut) const { return utc_clock::to_sys(ut); } }; template<> struct clock_time_conversion { template CONSTCD14 local_time operator()(const sys_time& st) const { return local_time{st.time_since_epoch()}; } }; template<> struct clock_time_conversion { template CONSTCD14 sys_time operator()(const local_time& lt) const { return sys_time{lt.time_since_epoch()}; } }; template<> struct clock_time_conversion { template utc_time::type> operator()(const local_time& lt) const { return utc_clock::from_local(lt); } }; template<> struct clock_time_conversion { template local_time::type> operator()(const utc_time& ut) const { return utc_clock::to_local(ut); } }; template struct clock_time_conversion { template CONSTCD14 std::chrono::time_point operator()(const std::chrono::time_point& tp) const { return tp; } }; namespace ctc_detail { template using time_point = std::chrono::time_point; using std::declval; using std::chrono::system_clock; //Check if TimePoint is time for given clock, //if not emits hard error template struct return_clock_time { using clock_time_point = time_point; using type = TimePoint; static_assert(std::is_same::value, "time point with appropariate clock shall be returned"); }; // Check if Clock has to_sys method accepting TimePoint with given duration const& and // returning sys_time. If so has nested type member equal to return type to_sys. template struct return_to_sys {}; template struct return_to_sys < Clock, Duration, decltype(Clock::to_sys(declval const&>()), void()) > : return_clock_time < system_clock, decltype(Clock::to_sys(declval const&>())) > {}; // Similiar to above template struct return_from_sys {}; template struct return_from_sys < Clock, Duration, decltype(Clock::from_sys(declval const&>()), void()) > : return_clock_time < Clock, decltype(Clock::from_sys(declval const&>())) > {}; // Similiar to above template struct return_to_utc {}; template struct return_to_utc < Clock, Duration, decltype(Clock::to_utc(declval const&>()), void()) > : return_clock_time < utc_clock, decltype(Clock::to_utc(declval const&>()))> {}; // Similiar to above template struct return_from_utc {}; template struct return_from_utc < Clock, Duration, decltype(Clock::from_utc(declval const&>()), void()) > : return_clock_time < Clock, decltype(Clock::from_utc(declval const&>())) > {}; // Similiar to above template struct return_to_local {}; template struct return_to_local < Clock, Duration, decltype(Clock::to_local(declval const&>()), void()) > : return_clock_time < local_t, decltype(Clock::to_local(declval const&>())) > {}; // Similiar to above template struct return_from_local {}; template struct return_from_local < Clock, Duration, decltype(Clock::from_local(declval const&>()), void()) > : return_clock_time < Clock, decltype(Clock::from_local(declval const&>())) > {}; } // namespace ctc_detail template struct clock_time_conversion { template CONSTCD14 typename ctc_detail::return_to_sys::type operator()(const std::chrono::time_point& tp) const { return SrcClock::to_sys(tp); } }; template struct clock_time_conversion { template CONSTCD14 typename ctc_detail::return_from_sys::type operator()(const sys_time& st) const { return DstClock::from_sys(st); } }; template struct clock_time_conversion { template CONSTCD14 typename ctc_detail::return_to_utc::type operator()(const std::chrono::time_point& tp) const { return SrcClock::to_utc(tp); } }; template struct clock_time_conversion { template CONSTCD14 typename ctc_detail::return_from_utc::type operator()(const utc_time& ut) const { return DstClock::from_utc(ut); } }; template struct clock_time_conversion { template CONSTCD14 typename ctc_detail::return_to_local::type operator()(const std::chrono::time_point& tp) const { return SrcClock::to_local(tp); } }; template struct clock_time_conversion { template CONSTCD14 typename ctc_detail::return_from_local::type operator()(const local_time& lt) const { return DstClock::from_local(lt); } }; namespace clock_cast_detail { template using time_point = std::chrono::time_point; using std::chrono::system_clock; template CONSTCD14 auto conv_clock(const time_point& t) -> decltype(std::declval>()(t)) { return clock_time_conversion{}(t); } //direct trait conversion, 1st candidate template CONSTCD14 auto cc_impl(const time_point& t, const time_point*) -> decltype(conv_clock(t)) { return conv_clock(t); } //conversion through sys, 2nd candidate template CONSTCD14 auto cc_impl(const time_point& t, const void*) -> decltype(conv_clock(conv_clock(t))) { return conv_clock(conv_clock(t)); } //conversion through utc, 2nd candidate template CONSTCD14 auto cc_impl(const time_point& t, const void*) -> decltype(0, // MSVC_WORKAROUND conv_clock(conv_clock(t))) { return conv_clock(conv_clock(t)); } //conversion through sys and utc, 3rd candidate template CONSTCD14 auto cc_impl(const time_point& t, ...) -> decltype(conv_clock(conv_clock(conv_clock(t)))) { return conv_clock(conv_clock(conv_clock(t))); } //conversion through utc and sys, 3rd candidate template CONSTCD14 auto cc_impl(const time_point& t, ...) -> decltype(0, // MSVC_WORKAROUND conv_clock(conv_clock(conv_clock(t)))) { return conv_clock(conv_clock(conv_clock(t))); } } // namespace clock_cast_detail template CONSTCD14 auto clock_cast(const std::chrono::time_point& tp) -> decltype(clock_cast_detail::cc_impl(tp, &tp)) { return clock_cast_detail::cc_impl(tp, &tp); } // Deprecated API template inline sys_time::type> to_sys_time(const utc_time& t) { return utc_clock::to_sys(t); } template inline sys_time::type> to_sys_time(const tai_time& t) { return utc_clock::to_sys(tai_clock::to_utc(t)); } template inline sys_time::type> to_sys_time(const gps_time& t) { return utc_clock::to_sys(gps_clock::to_utc(t)); } template inline utc_time::type> to_utc_time(const sys_time& t) { return utc_clock::from_sys(t); } template inline utc_time::type> to_utc_time(const tai_time& t) { return tai_clock::to_utc(t); } template inline utc_time::type> to_utc_time(const gps_time& t) { return gps_clock::to_utc(t); } template inline tai_time::type> to_tai_time(const sys_time& t) { return tai_clock::from_utc(utc_clock::from_sys(t)); } template inline tai_time::type> to_tai_time(const utc_time& t) { return tai_clock::from_utc(t); } template inline tai_time::type> to_tai_time(const gps_time& t) { return tai_clock::from_utc(gps_clock::to_utc(t)); } template inline gps_time::type> to_gps_time(const sys_time& t) { return gps_clock::from_utc(utc_clock::from_sys(t)); } template inline gps_time::type> to_gps_time(const utc_time& t) { return gps_clock::from_utc(t); } template inline gps_time::type> to_gps_time(const tai_time& t) { return gps_clock::from_utc(tai_clock::to_utc(t)); } } // namespace date #endif // TZ_H date-3.0.1/include/date/tz_private.h000066400000000000000000000247021403643451100173360ustar00rootroot00000000000000#ifndef TZ_PRIVATE_H #define TZ_PRIVATE_H // The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // Our apologies. When the previous paragraph was written, lowercase had not yet // been invented (that would involve another several millennia of evolution). // We did not mean to shout. #if !defined(_MSC_VER) || (_MSC_VER >= 1900) #include "tz.h" #else #include "date.h" #include #endif namespace date { namespace detail { #if !USE_OS_TZDB enum class tz {utc, local, standard}; //forward declare to avoid warnings in gcc 6.2 class MonthDayTime; std::istream& operator>>(std::istream& is, MonthDayTime& x); std::ostream& operator<<(std::ostream& os, const MonthDayTime& x); class MonthDayTime { private: struct pair { #if defined(_MSC_VER) && (_MSC_VER < 1900) pair() : month_day_(date::jan / 1), weekday_(0U) {} pair(const date::month_day& month_day, const date::weekday& weekday) : month_day_(month_day), weekday_(weekday) {} #endif date::month_day month_day_; date::weekday weekday_; }; enum Type {month_day, month_last_dow, lteq, gteq}; Type type_{month_day}; #if !defined(_MSC_VER) || (_MSC_VER >= 1900) union U #else struct U #endif { date::month_day month_day_; date::month_weekday_last month_weekday_last_; pair month_day_weekday_; #if !defined(_MSC_VER) || (_MSC_VER >= 1900) U() : month_day_{date::jan/1} {} #else U() : month_day_(date::jan/1), month_weekday_last_(date::month(0U), date::weekday_last(date::weekday(0U))) {} #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) U& operator=(const date::month_day& x); U& operator=(const date::month_weekday_last& x); U& operator=(const pair& x); } u; std::chrono::hours h_{0}; std::chrono::minutes m_{0}; std::chrono::seconds s_{0}; tz zone_{tz::local}; public: MonthDayTime() = default; MonthDayTime(local_seconds tp, tz timezone); MonthDayTime(const date::month_day& md, tz timezone); date::day day() const; date::month month() const; tz zone() const {return zone_;} void canonicalize(date::year y); sys_seconds to_sys(date::year y, std::chrono::seconds offset, std::chrono::seconds save) const; sys_days to_sys_days(date::year y) const; sys_seconds to_time_point(date::year y) const; int compare(date::year y, const MonthDayTime& x, date::year yx, std::chrono::seconds offset, std::chrono::minutes prev_save) const; friend std::istream& operator>>(std::istream& is, MonthDayTime& x); friend std::ostream& operator<<(std::ostream& os, const MonthDayTime& x); }; // A Rule specifies one or more set of datetimes without using an offset. // Multiple dates are specified with multiple years. The years in effect // go from starting_year_ to ending_year_, inclusive. starting_year_ <= // ending_year_. save_ is in effect for times from the specified time // onward, including the specified time. When the specified time is // local, it uses the save_ from the chronologically previous Rule, or if // there is none, 0. //forward declare to avoid warnings in gcc 6.2 class Rule; bool operator==(const Rule& x, const Rule& y); bool operator<(const Rule& x, const Rule& y); bool operator==(const Rule& x, const date::year& y); bool operator<(const Rule& x, const date::year& y); bool operator==(const date::year& x, const Rule& y); bool operator<(const date::year& x, const Rule& y); bool operator==(const Rule& x, const std::string& y); bool operator<(const Rule& x, const std::string& y); bool operator==(const std::string& x, const Rule& y); bool operator<(const std::string& x, const Rule& y); std::ostream& operator<<(std::ostream& os, const Rule& r); class Rule { private: std::string name_; date::year starting_year_{0}; date::year ending_year_{0}; MonthDayTime starting_at_; std::chrono::minutes save_{0}; std::string abbrev_; public: Rule() = default; explicit Rule(const std::string& s); Rule(const Rule& r, date::year starting_year, date::year ending_year); const std::string& name() const {return name_;} const std::string& abbrev() const {return abbrev_;} const MonthDayTime& mdt() const {return starting_at_;} const date::year& starting_year() const {return starting_year_;} const date::year& ending_year() const {return ending_year_;} const std::chrono::minutes& save() const {return save_;} static void split_overlaps(std::vector& rules); friend bool operator==(const Rule& x, const Rule& y); friend bool operator<(const Rule& x, const Rule& y); friend bool operator==(const Rule& x, const date::year& y); friend bool operator<(const Rule& x, const date::year& y); friend bool operator==(const date::year& x, const Rule& y); friend bool operator<(const date::year& x, const Rule& y); friend bool operator==(const Rule& x, const std::string& y); friend bool operator<(const Rule& x, const std::string& y); friend bool operator==(const std::string& x, const Rule& y); friend bool operator<(const std::string& x, const Rule& y); friend std::ostream& operator<<(std::ostream& os, const Rule& r); private: date::day day() const; date::month month() const; static void split_overlaps(std::vector& rules, std::size_t i, std::size_t& e); static bool overlaps(const Rule& x, const Rule& y); static void split(std::vector& rules, std::size_t i, std::size_t k, std::size_t& e); }; inline bool operator!=(const Rule& x, const Rule& y) {return !(x == y);} inline bool operator> (const Rule& x, const Rule& y) {return y < x;} inline bool operator<=(const Rule& x, const Rule& y) {return !(y < x);} inline bool operator>=(const Rule& x, const Rule& y) {return !(x < y);} inline bool operator!=(const Rule& x, const date::year& y) {return !(x == y);} inline bool operator> (const Rule& x, const date::year& y) {return y < x;} inline bool operator<=(const Rule& x, const date::year& y) {return !(y < x);} inline bool operator>=(const Rule& x, const date::year& y) {return !(x < y);} inline bool operator!=(const date::year& x, const Rule& y) {return !(x == y);} inline bool operator> (const date::year& x, const Rule& y) {return y < x;} inline bool operator<=(const date::year& x, const Rule& y) {return !(y < x);} inline bool operator>=(const date::year& x, const Rule& y) {return !(x < y);} inline bool operator!=(const Rule& x, const std::string& y) {return !(x == y);} inline bool operator> (const Rule& x, const std::string& y) {return y < x;} inline bool operator<=(const Rule& x, const std::string& y) {return !(y < x);} inline bool operator>=(const Rule& x, const std::string& y) {return !(x < y);} inline bool operator!=(const std::string& x, const Rule& y) {return !(x == y);} inline bool operator> (const std::string& x, const Rule& y) {return y < x;} inline bool operator<=(const std::string& x, const Rule& y) {return !(y < x);} inline bool operator>=(const std::string& x, const Rule& y) {return !(x < y);} struct zonelet { enum tag {has_rule, has_save, is_empty}; std::chrono::seconds gmtoff_; tag tag_ = has_rule; #if !defined(_MSC_VER) || (_MSC_VER >= 1900) union U #else struct U #endif { std::string rule_; std::chrono::minutes save_; ~U() {} U() {} U(const U&) {} U& operator=(const U&) = delete; } u; std::string format_; date::year until_year_{0}; MonthDayTime until_date_; sys_seconds until_utc_; local_seconds until_std_; local_seconds until_loc_; std::chrono::minutes initial_save_{0}; std::string initial_abbrev_; std::pair first_rule_{nullptr, date::year::min()}; std::pair last_rule_{nullptr, date::year::max()}; ~zonelet(); zonelet(); zonelet(const zonelet& i); zonelet& operator=(const zonelet&) = delete; }; #else // USE_OS_TZDB struct ttinfo { std::int32_t tt_gmtoff; unsigned char tt_isdst; unsigned char tt_abbrind; unsigned char pad[2]; }; static_assert(sizeof(ttinfo) == 8, ""); struct expanded_ttinfo { std::chrono::seconds offset; std::string abbrev; bool is_dst; }; struct transition { sys_seconds timepoint; const expanded_ttinfo* info; transition(sys_seconds tp, const expanded_ttinfo* i = nullptr) : timepoint(tp) , info(i) {} friend std::ostream& operator<<(std::ostream& os, const transition& t) { using date::operator<<; os << t.timepoint << "Z "; if (t.info->offset >= std::chrono::seconds{0}) os << '+'; os << make_time(t.info->offset); if (t.info->is_dst > 0) os << " daylight "; else os << " standard "; os << t.info->abbrev; return os; } }; #endif // USE_OS_TZDB } // namespace detail } // namespace date #if defined(_MSC_VER) && (_MSC_VER < 1900) #include "tz.h" #endif #endif // TZ_PRIVATE_H date-3.0.1/src/000077500000000000000000000000001403643451100132205ustar00rootroot00000000000000date-3.0.1/src/ios.mm000066400000000000000000000274531403643451100143600ustar00rootroot00000000000000// // The MIT License (MIT) // // Copyright (c) 2016 Alexander Kormanovsky // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // #include "date/ios.h" #if TARGET_OS_IPHONE #include #include #include #include #ifndef TAR_DEBUG # define TAR_DEBUG 0 #endif #define INTERNAL_DIR "Library" #define TZDATA_DIR "tzdata" #define TARGZ_EXTENSION "tar.gz" #define TAR_BLOCK_SIZE 512 #define TAR_TYPE_POSITION 156 #define TAR_NAME_POSITION 0 #define TAR_NAME_SIZE 100 #define TAR_SIZE_POSITION 124 #define TAR_SIZE_SIZE 12 namespace date { namespace iOSUtils { struct TarInfo { char objType; std::string objName; size_t realContentSize; // writable size without padding zeroes size_t blocksContentSize; // adjusted size to 512 bytes blocks bool success; }; std::string convertCFStringRefPathToCStringPath(CFStringRef ref); bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath); TarInfo getTarObjectInfo(std::ifstream &readStream); std::string getTarObject(std::ifstream &readStream, int64_t size); bool writeFile(const std::string &tzdataPath, const std::string &fileName, const std::string &data, size_t realContentSize); std::string get_current_timezone() { CFTimeZoneRef tzRef = CFTimeZoneCopySystem(); CFStringRef tzNameRef = CFTimeZoneGetName(tzRef); CFIndex bufferSize = CFStringGetLength(tzNameRef) + 1; char buffer[bufferSize]; if (CFStringGetCString(tzNameRef, buffer, bufferSize, kCFStringEncodingUTF8)) { CFRelease(tzRef); return std::string(buffer); } CFRelease(tzRef); return ""; } std::string get_tzdata_path() { CFURLRef homeUrlRef = CFCopyHomeDirectoryURL(); CFStringRef homePath = CFURLCopyPath(homeUrlRef); std::string path(std::string(convertCFStringRefPathToCStringPath(homePath)) + INTERNAL_DIR + "/" + TZDATA_DIR); std::string result_path(std::string(convertCFStringRefPathToCStringPath(homePath)) + INTERNAL_DIR); if (access(path.c_str(), F_OK) == 0) { #if TAR_DEBUG printf("tzdata dir exists\n"); #endif CFRelease(homeUrlRef); CFRelease(homePath); return result_path; } CFBundleRef mainBundle = CFBundleGetMainBundle(); CFArrayRef paths = CFBundleCopyResourceURLsOfType(mainBundle, CFSTR(TARGZ_EXTENSION), NULL); if (CFArrayGetCount(paths) != 0) { // get archive path, assume there is no other tar.gz in bundle CFURLRef archiveUrl = static_cast(CFArrayGetValueAtIndex(paths, 0)); CFStringRef archiveName = CFURLCopyPath(archiveUrl); archiveUrl = CFBundleCopyResourceURL(mainBundle, archiveName, NULL, NULL); extractTzdata(homeUrlRef, archiveUrl, path); CFRelease(archiveUrl); CFRelease(archiveName); } CFRelease(homeUrlRef); CFRelease(homePath); CFRelease(paths); return result_path; } std::string convertCFStringRefPathToCStringPath(CFStringRef ref) { CFIndex bufferSize = CFStringGetMaximumSizeOfFileSystemRepresentation(ref); char *buffer = new char[bufferSize]; CFStringGetFileSystemRepresentation(ref, buffer, bufferSize); auto result = std::string(buffer); delete[] buffer; return result; } bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath) { std::string TAR_TMP_PATH = "/tmp.tar"; CFStringRef homeStringRef = CFURLCopyPath(homeUrl); auto homePath = convertCFStringRefPathToCStringPath(homeStringRef); CFRelease(homeStringRef); CFStringRef archiveStringRef = CFURLCopyPath(archiveUrl); auto archivePath = convertCFStringRefPathToCStringPath(archiveStringRef); CFRelease(archiveStringRef); // create Library path auto libraryPath = homePath + INTERNAL_DIR; // create tzdata path auto tzdataPath = libraryPath + "/" + TZDATA_DIR; // -- replace %20 with " " const std::string search = "%20"; const std::string replacement = " "; size_t pos = 0; while ((pos = archivePath.find(search, pos)) != std::string::npos) { archivePath.replace(pos, search.length(), replacement); pos += replacement.length(); } gzFile tarFile = gzopen(archivePath.c_str(), "rb"); // create tar unpacking path auto tarPath = libraryPath + TAR_TMP_PATH; // create tzdata directory mkdir(destPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); // ======= extract tar ======== std::ofstream os(tarPath.c_str(), std::ofstream::out | std::ofstream::app); unsigned int bufferLength = 1024 * 256; // 256Kb unsigned char *buffer = (unsigned char *)malloc(bufferLength); bool success = true; while (true) { int readBytes = gzread(tarFile, buffer, bufferLength); if (readBytes > 0) { os.write((char *) &buffer[0], readBytes); } else if (readBytes == 0) { break; } else if (readBytes == -1) { printf("decompression failed\n"); success = false; break; } else { printf("unexpected zlib state\n"); success = false; break; } } os.close(); free(buffer); gzclose(tarFile); if (!success) { remove(tarPath.c_str()); return false; } // ======== extract files ========= uint64_t location = 0; // Position in the file // get file size struct stat stat_buf; int res = stat(tarPath.c_str(), &stat_buf); if (res != 0) { printf("error file size\n"); remove(tarPath.c_str()); return false; } int64_t tarSize = stat_buf.st_size; // create read stream std::ifstream is(tarPath.c_str(), std::ifstream::in | std::ifstream::binary); // process files while (location < tarSize) { TarInfo info = getTarObjectInfo(is); if (!info.success || info.realContentSize == 0) { break; // something wrong or all files are read } switch (info.objType) { case '0': // file case '\0': // { std::string obj = getTarObject(is, info.blocksContentSize); #if TAR_DEBUG size += info.realContentSize; printf("#%i %s file size %lld written total %ld from %lld\n", ++count, info.objName.c_str(), info.realContentSize, size, tarSize); #endif writeFile(tzdataPath, info.objName, obj, info.realContentSize); location += info.blocksContentSize; break; } } } remove(tarPath.c_str()); return true; } TarInfo getTarObjectInfo(std::ifstream &readStream) { int64_t length = TAR_BLOCK_SIZE; char buffer[length]; char type; char name[TAR_NAME_SIZE + 1]; char sizeBuf[TAR_SIZE_SIZE + 1]; readStream.read(buffer, length); memcpy(&type, &buffer[TAR_TYPE_POSITION], 1); memset(&name, '\0', TAR_NAME_SIZE + 1); memcpy(&name, &buffer[TAR_NAME_POSITION], TAR_NAME_SIZE); memset(&sizeBuf, '\0', TAR_SIZE_SIZE + 1); memcpy(&sizeBuf, &buffer[TAR_SIZE_POSITION], TAR_SIZE_SIZE); size_t realSize = strtol(sizeBuf, NULL, 8); size_t blocksSize = realSize + (TAR_BLOCK_SIZE - (realSize % TAR_BLOCK_SIZE)); return {type, std::string(name), realSize, blocksSize, true}; } std::string getTarObject(std::ifstream &readStream, int64_t size) { char buffer[size]; readStream.read(buffer, size); return std::string(buffer); } bool writeFile(const std::string &tzdataPath, const std::string &fileName, const std::string &data, size_t realContentSize) { std::ofstream os(tzdataPath + "/" + fileName, std::ofstream::out | std::ofstream::binary); if (!os) { return false; } // trim empty space char trimmedData[realContentSize + 1]; memset(&trimmedData, '\0', realContentSize); memcpy(&trimmedData, data.c_str(), realContentSize); // write os.write(trimmedData, realContentSize); os.close(); return true; } } // namespace iOSUtils } // namespace date #endif // TARGET_OS_IPHONE date-3.0.1/src/tz.cpp000066400000000000000000003457671403643451100144070ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016, 2017 Howard Hinnant // Copyright (c) 2015 Ville Voutilainen // Copyright (c) 2016 Alexander Kormanovsky // Copyright (c) 2016, 2017 Jiangang Zhuang // Copyright (c) 2017 Nicolas Veloz Savino // Copyright (c) 2017 Florian Dang // Copyright (c) 2017 Aaron Bishop // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // Our apologies. When the previous paragraph was written, lowercase had not yet // been invented (that would involve another several millennia of evolution). // We did not mean to shout. #ifdef _WIN32 // windows.h will be included directly and indirectly (e.g. by curl). // We need to define these macros to prevent windows.h bringing in // more than we need and do it early so windows.h doesn't get included // without these macros having been defined. // min/max macros interfere with the C++ versions. # ifndef NOMINMAX # define NOMINMAX # endif // We don't need all that Windows has to offer. # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif // for wcstombs # ifndef _CRT_SECURE_NO_WARNINGS # define _CRT_SECURE_NO_WARNINGS # endif // None of this happens with the MS SDK (at least VS14 which I tested), but: // Compiling with mingw, we get "error: 'KF_FLAG_DEFAULT' was not declared in this scope." // and error: 'SHGetKnownFolderPath' was not declared in this scope.". // It seems when using mingw NTDDI_VERSION is undefined and that // causes KNOWN_FOLDER_FLAG and the KF_ flags to not get defined. // So we must define NTDDI_VERSION to get those flags on mingw. // The docs say though here: // https://msdn.microsoft.com/en-nz/library/windows/desktop/aa383745(v=vs.85).aspx // that "If you define NTDDI_VERSION, you must also define _WIN32_WINNT." // So we declare we require Vista or greater. # ifdef __MINGW32__ # ifndef NTDDI_VERSION # define NTDDI_VERSION 0x06000000 # define _WIN32_WINNT _WIN32_WINNT_VISTA # elif NTDDI_VERSION < 0x06000000 # warning "If this fails to compile NTDDI_VERSION may be to low. See comments above." # endif // But once we define the values above we then get this linker error: // "tz.cpp:(.rdata$.refptr.FOLDERID_Downloads[.refptr.FOLDERID_Downloads]+0x0): " // "undefined reference to `FOLDERID_Downloads'" // which #include cures see: // https://support.microsoft.com/en-us/kb/130869 # include // But with included, the error moves on to: // error: 'FOLDERID_Downloads' was not declared in this scope // Which #include cures. # include # endif // __MINGW32__ # include #endif // _WIN32 #include "date/tz_private.h" #ifdef __APPLE__ # include "date/ios.h" #else # define TARGET_OS_IPHONE 0 # define TARGET_OS_SIMULATOR 0 #endif #if USE_OS_TZDB # include #endif #include #include #include #include #include #include #include #include #include #include #if USE_OS_TZDB # include #endif #include #include #include #include #include // unistd.h is used on some platforms as part of the the means to get // the current time zone. On Win32 windows.h provides a means to do it. // gcc/mingw supports unistd.h on Win32 but MSVC does not. #ifdef _WIN32 # ifdef WINAPI_FAMILY # include # if WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP # define WINRT # define INSTALL . # endif # endif # include // _unlink etc. # if defined(__clang__) struct IUnknown; // fix for issue with static_cast<> in objbase.h // (see https://github.com/philsquared/Catch/issues/690) # endif # include // CoTaskFree, ShGetKnownFolderPath etc. # if HAS_REMOTE_API # include // _mkdir # include // ShFileOperation etc. # endif // HAS_REMOTE_API #else // !_WIN32 # include # if !USE_OS_TZDB && !defined(INSTALL) # include # endif # include # include # if !USE_SHELL_API # include # include # include # include # include # include # endif //!USE_SHELL_API #endif // !_WIN32 #if HAS_REMOTE_API // Note curl includes windows.h so we must include curl AFTER definitions of things // that affect windows.h such as NOMINMAX. #if defined(_MSC_VER) && defined(SHORTENED_CURL_INCLUDE) // For rmt_curl nuget package # include #else # include #endif #endif #ifdef _WIN32 static CONSTDATA char folder_delimiter = '\\'; #else // !_WIN32 static CONSTDATA char folder_delimiter = '/'; #endif // !_WIN32 #if defined(__GNUC__) && __GNUC__ < 5 // GCC 4.9 Bug 61489 Wrong warning with -Wmissing-field-initializers # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wmissing-field-initializers" #endif // defined(__GNUC__) && __GNUC__ < 5 #if !USE_OS_TZDB # ifdef _WIN32 # ifndef WINRT namespace { struct task_mem_deleter { void operator()(wchar_t buf[]) { if (buf != nullptr) CoTaskMemFree(buf); } }; using co_task_mem_ptr = std::unique_ptr; } // We might need to know certain locations even if not using the remote API, // so keep these routines out of that block for now. static std::string get_known_folder(const GUID& folderid) { std::string folder; PWSTR pfolder = nullptr; HRESULT hr = SHGetKnownFolderPath(folderid, KF_FLAG_DEFAULT, nullptr, &pfolder); if (SUCCEEDED(hr)) { co_task_mem_ptr folder_ptr(pfolder); const wchar_t* fptr = folder_ptr.get(); auto state = std::mbstate_t(); const auto required = std::wcsrtombs(nullptr, &fptr, 0, &state); if (required != 0 && required != std::size_t(-1)) { folder.resize(required); std::wcsrtombs(&folder[0], &fptr, folder.size(), &state); } } return folder; } # ifndef INSTALL // Usually something like "c:\Users\username\Downloads". static std::string get_download_folder() { return get_known_folder(FOLDERID_Downloads); } # endif // !INSTALL # endif // WINRT # else // !_WIN32 # if !defined(INSTALL) static std::string expand_path(std::string path) { # if TARGET_OS_IPHONE return date::iOSUtils::get_tzdata_path(); # else // !TARGET_OS_IPHONE ::wordexp_t w{}; std::unique_ptr<::wordexp_t, void(*)(::wordexp_t*)> hold{&w, ::wordfree}; ::wordexp(path.c_str(), &w, 0); if (w.we_wordc != 1) throw std::runtime_error("Cannot expand path: " + path); path = w.we_wordv[0]; return path; # endif // !TARGET_OS_IPHONE } static std::string get_download_folder() { return expand_path("~/Downloads"); } # endif // !defined(INSTALL) # endif // !_WIN32 #endif // !USE_OS_TZDB namespace date { // +---------------------+ // | Begin Configuration | // +---------------------+ using namespace detail; #if !USE_OS_TZDB static std::string& access_install() { static std::string install #ifndef INSTALL = get_download_folder() + folder_delimiter + "tzdata"; #else // !INSTALL # define STRINGIZEIMP(x) #x # define STRINGIZE(x) STRINGIZEIMP(x) = STRINGIZE(INSTALL) + std::string(1, folder_delimiter) + "tzdata"; #undef STRINGIZEIMP #undef STRINGIZE #endif // !INSTALL return install; } void set_install(const std::string& s) { access_install() = s; } static const std::string& get_install() { static const std::string& ref = access_install(); return ref; } #if HAS_REMOTE_API static std::string get_download_gz_file(const std::string& version) { auto file = get_install() + version + ".tar.gz"; return file; } #endif // HAS_REMOTE_API #endif // !USE_OS_TZDB // These can be used to reduce the range of the database to save memory CONSTDATA auto min_year = date::year::min(); CONSTDATA auto max_year = date::year::max(); CONSTDATA auto min_day = date::January/1; CONSTDATA auto max_day = date::December/31; #if USE_OS_TZDB CONSTCD14 const sys_seconds min_seconds = sys_days(min_year/min_day); #endif // USE_OS_TZDB #ifndef _WIN32 static std::string discover_tz_dir() { struct stat sb; using namespace std; # ifndef __APPLE__ CONSTDATA auto tz_dir_default = "/usr/share/zoneinfo"; CONSTDATA auto tz_dir_buildroot = "/usr/share/zoneinfo/uclibc"; // Check special path which is valid for buildroot with uclibc builds if(stat(tz_dir_buildroot, &sb) == 0 && S_ISDIR(sb.st_mode)) return tz_dir_buildroot; else if(stat(tz_dir_default, &sb) == 0 && S_ISDIR(sb.st_mode)) return tz_dir_default; else throw runtime_error("discover_tz_dir failed to find zoneinfo\n"); # else // __APPLE__ # if TARGET_OS_IPHONE # if TARGET_OS_SIMULATOR return "/usr/share/zoneinfo"; # else return "/var/db/timezone/zoneinfo"; # endif # else CONSTDATA auto timezone = "/etc/localtime"; if (!(lstat(timezone, &sb) == 0 && S_ISLNK(sb.st_mode) && sb.st_size > 0)) throw runtime_error("discover_tz_dir failed\n"); string result; char rp[PATH_MAX+1] = {}; if (readlink(timezone, rp, sizeof(rp)-1) > 0) result = string(rp); else throw system_error(errno, system_category(), "readlink() failed"); auto i = result.find("zoneinfo"); if (i == string::npos) throw runtime_error("discover_tz_dir failed to find zoneinfo\n"); i = result.find('/', i); if (i == string::npos) throw runtime_error("discover_tz_dir failed to find '/'\n"); return result.substr(0, i); # endif # endif // __APPLE__ } static const std::string& get_tz_dir() { static const std::string tz_dir = discover_tz_dir(); return tz_dir; } #endif // +-------------------+ // | End Configuration | // +-------------------+ #ifndef _MSC_VER static_assert(min_year <= max_year, "Configuration error"); #endif static std::unique_ptr init_tzdb(); tzdb_list::~tzdb_list() { const tzdb* ptr = head_; head_ = nullptr; while (ptr != nullptr) { auto next = ptr->next; delete ptr; ptr = next; } } tzdb_list::tzdb_list(tzdb_list&& x) NOEXCEPT : head_{x.head_.exchange(nullptr)} { } void tzdb_list::push_front(tzdb* tzdb) NOEXCEPT { tzdb->next = head_; head_ = tzdb; } tzdb_list::const_iterator tzdb_list::erase_after(const_iterator p) NOEXCEPT { auto t = p.p_->next; p.p_->next = p.p_->next->next; delete t; return ++p; } struct tzdb_list::undocumented_helper { static void push_front(tzdb_list& db_list, tzdb* tzdb) NOEXCEPT { db_list.push_front(tzdb); } }; static tzdb_list create_tzdb() { tzdb_list tz_db; tzdb_list::undocumented_helper::push_front(tz_db, init_tzdb().release()); return tz_db; } tzdb_list& get_tzdb_list() { static tzdb_list tz_db = create_tzdb(); return tz_db; } static std::string parse3(std::istream& in) { std::string r(3, ' '); ws(in); r[0] = static_cast(in.get()); r[1] = static_cast(in.get()); r[2] = static_cast(in.get()); return r; } static unsigned parse_month(std::istream& in) { CONSTDATA char*const month_names[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; auto s = parse3(in); auto m = std::find(std::begin(month_names), std::end(month_names), s) - month_names; if (m >= std::end(month_names) - std::begin(month_names)) throw std::runtime_error("oops: bad month name: " + s); return static_cast(++m); } #if !USE_OS_TZDB #ifdef _WIN32 static void sort_zone_mappings(std::vector& mappings) { std::sort(mappings.begin(), mappings.end(), [](const date::detail::timezone_mapping& lhs, const date::detail::timezone_mapping& rhs)->bool { auto other_result = lhs.other.compare(rhs.other); if (other_result < 0) return true; else if (other_result == 0) { auto territory_result = lhs.territory.compare(rhs.territory); if (territory_result < 0) return true; else if (territory_result == 0) { if (lhs.type < rhs.type) return true; } } return false; }); } static bool native_to_standard_timezone_name(const std::string& native_tz_name, std::string& standard_tz_name) { // TOOD! Need be a case insensitive compare? if (native_tz_name == "UTC") { standard_tz_name = "Etc/UTC"; return true; } standard_tz_name.clear(); // TODO! we can improve on linear search. const auto& mappings = date::get_tzdb().mappings; for (const auto& tzm : mappings) { if (tzm.other == native_tz_name) { standard_tz_name = tzm.type; return true; } } return false; } // Parse this XML file: // https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml // The parsing method is designed to be simple and quick. It is not overly // forgiving of change but it should diagnose basic format issues. // See timezone_mapping structure for more info. static std::vector load_timezone_mappings_from_xml_file(const std::string& input_path) { std::size_t line_num = 0; std::vector mappings; std::string line; std::ifstream is(input_path); if (!is.is_open()) { // We don't emit file exceptions because that's an implementation detail. std::string msg = "Error opening time zone mapping file \""; msg += input_path; msg += "\"."; throw std::runtime_error(msg); } auto error = [&input_path, &line_num](const char* info) { std::string msg = "Error loading time zone mapping file \""; msg += input_path; msg += "\" at line "; msg += std::to_string(line_num); msg += ": "; msg += info; throw std::runtime_error(msg); }; // [optional space]a="b" auto read_attribute = [&line, &error] (const char* name, std::string& value, std::size_t startPos) ->std::size_t { value.clear(); // Skip leading space before attribute name. std::size_t spos = line.find_first_not_of(' ', startPos); if (spos == std::string::npos) spos = startPos; // Assume everything up to next = is the attribute name // and that an = will always delimit that. std::size_t epos = line.find('=', spos); if (epos == std::string::npos) error("Expected \'=\' right after attribute name."); std::size_t name_len = epos - spos; // Expect the name we find matches the name we expect. if (line.compare(spos, name_len, name) != 0) { std::string msg; msg = "Expected attribute name \'"; msg += name; msg += "\' around position "; msg += std::to_string(spos); msg += " but found something else."; error(msg.c_str()); } ++epos; // Skip the '=' that is after the attribute name. spos = epos; if (spos < line.length() && line[spos] == '\"') ++spos; // Skip the quote that is before the attribute value. else { std::string msg = "Expected '\"' to begin value of attribute \'"; msg += name; msg += "\'."; error(msg.c_str()); } epos = line.find('\"', spos); if (epos == std::string::npos) { std::string msg = "Expected '\"' to end value of attribute \'"; msg += name; msg += "\'."; error(msg.c_str()); } // Extract everything in between the quotes. Note no escaping is done. std::size_t value_len = epos - spos; value.assign(line, spos, value_len); ++epos; // Skip the quote that is after the attribute value; return epos; }; // Quick but not overly forgiving XML mapping file processing. bool mapTimezonesOpenTagFound = false; bool mapTimezonesCloseTagFound = false; std::size_t mapZonePos = std::string::npos; std::size_t mapTimezonesPos = std::string::npos; CONSTDATA char mapTimeZonesOpeningTag[] = { ""); mapTimezonesCloseTagFound = (mapTimezonesPos != std::string::npos); if (!mapTimezonesCloseTagFound) { std::size_t commentPos = line.find(" " << x.target_; } // leap_second leap_second::leap_second(const std::string& s, detail::undocumented) { using namespace date; std::istringstream in(s); in.exceptions(std::ios::failbit | std::ios::badbit); std::string word; int y; MonthDayTime date; in >> word >> y >> date; date_ = date.to_time_point(year(y)); } static bool file_exists(const std::string& filename) { #ifdef _WIN32 return ::_access(filename.c_str(), 0) == 0; #else return ::access(filename.c_str(), F_OK) == 0; #endif } #if HAS_REMOTE_API // CURL tools namespace { struct curl_global_init_and_cleanup { ~curl_global_init_and_cleanup() { ::curl_global_cleanup(); } curl_global_init_and_cleanup() { if (::curl_global_init(CURL_GLOBAL_DEFAULT) != 0) throw std::runtime_error("CURL global initialization failed"); } curl_global_init_and_cleanup(curl_global_init_and_cleanup const&) = delete; curl_global_init_and_cleanup& operator=(curl_global_init_and_cleanup const&) = delete; }; struct curl_deleter { void operator()(CURL* p) const { ::curl_easy_cleanup(p); } }; } // unnamed namespace static std::unique_ptr curl_init() { static const curl_global_init_and_cleanup _{}; return std::unique_ptr{::curl_easy_init()}; } static bool download_to_string(const std::string& url, std::string& str) { str.clear(); auto curl = curl_init(); if (!curl) return false; std::string version; curl_easy_setopt(curl.get(), CURLOPT_USERAGENT, "curl"); curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str()); curl_write_callback write_cb = [](char* contents, std::size_t size, std::size_t nmemb, void* userp) -> std::size_t { auto& userstr = *static_cast(userp); auto realsize = size * nmemb; userstr.append(contents, realsize); return realsize; }; curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, write_cb); curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str); curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, false); auto res = curl_easy_perform(curl.get()); return (res == CURLE_OK); } namespace { enum class download_file_options { binary, text }; } static bool download_to_file(const std::string& url, const std::string& local_filename, download_file_options opts, char* error_buffer) { auto curl = curl_init(); if (!curl) return false; curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str()); curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, false); if (error_buffer) curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, error_buffer); curl_write_callback write_cb = [](char* contents, std::size_t size, std::size_t nmemb, void* userp) -> std::size_t { auto& of = *static_cast(userp); auto realsize = size * nmemb; of.write(contents, static_cast(realsize)); return realsize; }; curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, write_cb); decltype(curl_easy_perform(curl.get())) res; { std::ofstream of(local_filename, opts == download_file_options::binary ? std::ofstream::out | std::ofstream::binary : std::ofstream::out); of.exceptions(std::ios::badbit); curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &of); res = curl_easy_perform(curl.get()); } return res == CURLE_OK; } std::string remote_version() { std::string version; std::string str; if (download_to_string("https://www.iana.org/time-zones", str)) { CONSTDATA char db[] = "/time-zones/releases/tzdata"; CONSTDATA auto db_size = sizeof(db) - 1; auto p = str.find(db, 0, db_size); const int ver_str_len = 5; if (p != std::string::npos && p + (db_size + ver_str_len) <= str.size()) version = str.substr(p + db_size, ver_str_len); } return version; } // TODO! Using system() create a process and a console window. // This is useful to see what errors may occur but is slow and distracting. // Consider implementing this functionality more directly, such as // using _mkdir and CreateProcess etc. // But use the current means now as matches Unix implementations and while // in proof of concept / testing phase. // TODO! Use eventually. static bool remove_folder_and_subfolders(const std::string& folder) { # ifdef _WIN32 # if USE_SHELL_API // Delete the folder contents by deleting the folder. std::string cmd = "rd /s /q \""; cmd += folder; cmd += '\"'; return std::system(cmd.c_str()) == EXIT_SUCCESS; # else // !USE_SHELL_API // Create a buffer containing the path to delete. It must be terminated // by two nuls. Who designs these API's... std::vector from; from.assign(folder.begin(), folder.end()); from.push_back('\0'); from.push_back('\0'); SHFILEOPSTRUCT fo{}; // Zero initialize. fo.wFunc = FO_DELETE; fo.pFrom = from.data(); fo.fFlags = FOF_NO_UI; int ret = SHFileOperation(&fo); if (ret == 0 && !fo.fAnyOperationsAborted) return true; return false; # endif // !USE_SHELL_API # else // !_WIN32 # if USE_SHELL_API return std::system(("rm -R " + folder).c_str()) == EXIT_SUCCESS; # else // !USE_SHELL_API struct dir_deleter { dir_deleter() {} void operator()(DIR* d) const { if (d != nullptr) { int result = closedir(d); assert(result == 0); } } }; using closedir_ptr = std::unique_ptr; std::string filename; struct stat statbuf; std::size_t folder_len = folder.length(); struct dirent* p = nullptr; closedir_ptr d(opendir(folder.c_str())); bool r = d.get() != nullptr; while (r && (p=readdir(d.get())) != nullptr) { if (strcmp(p->d_name, ".") == 0 || strcmp(p->d_name, "..") == 0) continue; // + 2 for path delimiter and nul terminator. std::size_t buf_len = folder_len + strlen(p->d_name) + 2; filename.resize(buf_len); std::size_t path_len = static_cast( snprintf(&filename[0], buf_len, "%s/%s", folder.c_str(), p->d_name)); assert(path_len == buf_len - 1); filename.resize(path_len); if (stat(filename.c_str(), &statbuf) == 0) r = S_ISDIR(statbuf.st_mode) ? remove_folder_and_subfolders(filename) : unlink(filename.c_str()) == 0; } d.reset(); if (r) r = rmdir(folder.c_str()) == 0; return r; # endif // !USE_SHELL_API # endif // !_WIN32 } static bool make_directory(const std::string& folder) { # ifdef _WIN32 # if USE_SHELL_API // Re-create the folder. std::string cmd = "mkdir \""; cmd += folder; cmd += '\"'; return std::system(cmd.c_str()) == EXIT_SUCCESS; # else // !USE_SHELL_API return _mkdir(folder.c_str()) == 0; # endif // !USE_SHELL_API # else // !_WIN32 # if USE_SHELL_API return std::system(("mkdir -p " + folder).c_str()) == EXIT_SUCCESS; # else // !USE_SHELL_API return mkdir(folder.c_str(), 0777) == 0; # endif // !USE_SHELL_API # endif // !_WIN32 } static bool delete_file(const std::string& file) { # ifdef _WIN32 # if USE_SHELL_API std::string cmd = "del \""; cmd += file; cmd += '\"'; return std::system(cmd.c_str()) == 0; # else // !USE_SHELL_API return _unlink(file.c_str()) == 0; # endif // !USE_SHELL_API # else // !_WIN32 # if USE_SHELL_API return std::system(("rm " + file).c_str()) == EXIT_SUCCESS; # else // !USE_SHELL_API return unlink(file.c_str()) == 0; # endif // !USE_SHELL_API # endif // !_WIN32 } # ifdef _WIN32 static bool move_file(const std::string& from, const std::string& to) { # if USE_SHELL_API std::string cmd = "move \""; cmd += from; cmd += "\" \""; cmd += to; cmd += '\"'; return std::system(cmd.c_str()) == EXIT_SUCCESS; # else // !USE_SHELL_API return !!::MoveFile(from.c_str(), to.c_str()); # endif // !USE_SHELL_API } // Usually something like "c:\Program Files". static std::string get_program_folder() { return get_known_folder(FOLDERID_ProgramFiles); } // Note folder can and usually does contain spaces. static std::string get_unzip_program() { std::string path; // 7-Zip appears to note its location in the registry. // If that doesn't work, fall through and take a guess, but it will likely be wrong. HKEY hKey = nullptr; if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\7-Zip", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { char value_buffer[MAX_PATH + 1]; // fyi 260 at time of writing. // in/out parameter. Documentation say that size is a count of bytes not chars. DWORD size = sizeof(value_buffer) - sizeof(value_buffer[0]); DWORD tzi_type = REG_SZ; // Testing shows Path key value is "C:\Program Files\7-Zip\" i.e. always with trailing \. bool got_value = (RegQueryValueExA(hKey, "Path", nullptr, &tzi_type, reinterpret_cast(value_buffer), &size) == ERROR_SUCCESS); RegCloseKey(hKey); // Close now incase of throw later. if (got_value) { // Function does not guarantee to null terminate. value_buffer[size / sizeof(value_buffer[0])] = '\0'; path = value_buffer; if (!path.empty()) { path += "7z.exe"; return path; } } } path += get_program_folder(); path += folder_delimiter; path += "7-Zip\\7z.exe"; return path; } # if !USE_SHELL_API static int run_program(const std::string& command) { STARTUPINFO si{}; si.cb = sizeof(si); PROCESS_INFORMATION pi{}; // Allegedly CreateProcess overwrites the command line. Ugh. std::string mutable_command(command); if (CreateProcess(nullptr, &mutable_command[0], nullptr, nullptr, FALSE, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi)) { WaitForSingleObject(pi.hProcess, INFINITE); DWORD exit_code; bool got_exit_code = !!GetExitCodeProcess(pi.hProcess, &exit_code); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); // Not 100% sure about this still active thing is correct, // but I'm going with it because I *think* WaitForSingleObject might // return in some cases without INFINITE-ly waiting. // But why/wouldn't GetExitCodeProcess return false in that case? if (got_exit_code && exit_code != STILL_ACTIVE) return static_cast(exit_code); } return EXIT_FAILURE; } # endif // !USE_SHELL_API static std::string get_download_tar_file(const std::string& version) { auto file = get_install(); file += folder_delimiter; file += "tzdata"; file += version; file += ".tar"; return file; } static bool extract_gz_file(const std::string& version, const std::string& gz_file, const std::string& dest_folder) { auto unzip_prog = get_unzip_program(); bool unzip_result = false; // Use the unzip program to extract the tar file from the archive. // Aim to create a string like: // "C:\Program Files\7-Zip\7z.exe" x "C:\Users\SomeUser\Downloads\tzdata2016d.tar.gz" // -o"C:\Users\SomeUser\Downloads\tzdata" std::string cmd; cmd = '\"'; cmd += unzip_prog; cmd += "\" x \""; cmd += gz_file; cmd += "\" -o\""; cmd += dest_folder; cmd += '\"'; # if USE_SHELL_API // When using shelling out with std::system() extra quotes are required around the // whole command. It's weird but necessary it seems, see: // http://stackoverflow.com/q/27975969/576911 cmd = "\"" + cmd + "\""; if (std::system(cmd.c_str()) == EXIT_SUCCESS) unzip_result = true; # else // !USE_SHELL_API if (run_program(cmd) == EXIT_SUCCESS) unzip_result = true; # endif // !USE_SHELL_API if (unzip_result) delete_file(gz_file); // Use the unzip program extract the data from the tar file that was // just extracted from the archive. auto tar_file = get_download_tar_file(version); cmd = '\"'; cmd += unzip_prog; cmd += "\" x \""; cmd += tar_file; cmd += "\" -o\""; cmd += get_install(); cmd += '\"'; # if USE_SHELL_API cmd = "\"" + cmd + "\""; if (std::system(cmd.c_str()) == EXIT_SUCCESS) unzip_result = true; # else // !USE_SHELL_API if (run_program(cmd) == EXIT_SUCCESS) unzip_result = true; # endif // !USE_SHELL_API if (unzip_result) delete_file(tar_file); return unzip_result; } static std::string get_download_mapping_file(const std::string& version) { auto file = get_install() + version + "windowsZones.xml"; return file; } # else // !_WIN32 # if !USE_SHELL_API static int run_program(const char* prog, const char*const args[]) { pid_t pid = fork(); if (pid == -1) // Child failed to start. return EXIT_FAILURE; if (pid != 0) { // We are in the parent. Child started. Wait for it. pid_t ret; int status; while ((ret = waitpid(pid, &status, 0)) == -1) { if (errno != EINTR) break; } if (ret != -1) { if (WIFEXITED(status)) return WEXITSTATUS(status); } printf("Child issues!\n"); return EXIT_FAILURE; // Not sure what status of child is. } else // We are in the child process. Start the program the parent wants to run. { if (execv(prog, const_cast(args)) == -1) // Does not return. { perror("unreachable 0\n"); _Exit(127); } printf("unreachable 2\n"); } printf("unreachable 2\n"); // Unreachable. assert(false); exit(EXIT_FAILURE); return EXIT_FAILURE; } # endif // !USE_SHELL_API static bool extract_gz_file(const std::string&, const std::string& gz_file, const std::string&) { # if USE_SHELL_API bool unzipped = std::system(("tar -xzf " + gz_file + " -C " + get_install()).c_str()) == EXIT_SUCCESS; # else // !USE_SHELL_API const char prog[] = {"/usr/bin/tar"}; const char*const args[] = { prog, "-xzf", gz_file.c_str(), "-C", get_install().c_str(), nullptr }; bool unzipped = (run_program(prog, args) == EXIT_SUCCESS); # endif // !USE_SHELL_API if (unzipped) { delete_file(gz_file); return true; } return false; } # endif // !_WIN32 bool remote_download(const std::string& version, char* error_buffer) { assert(!version.empty()); # ifdef _WIN32 // Download folder should be always available for Windows # else // !_WIN32 // Create download folder if it does not exist on UNIX system auto download_folder = get_install(); if (!file_exists(download_folder)) { if (!make_directory(download_folder)) return false; } # endif // _WIN32 auto url = "https://data.iana.org/time-zones/releases/tzdata" + version + ".tar.gz"; bool result = download_to_file(url, get_download_gz_file(version), download_file_options::binary, error_buffer); # ifdef _WIN32 if (result) { auto mapping_file = get_download_mapping_file(version); result = download_to_file( "https://raw.githubusercontent.com/unicode-org/cldr/master/" "common/supplemental/windowsZones.xml", mapping_file, download_file_options::text, error_buffer); } # endif // _WIN32 return result; } bool remote_install(const std::string& version) { auto success = false; assert(!version.empty()); std::string install = get_install(); auto gz_file = get_download_gz_file(version); if (file_exists(gz_file)) { if (file_exists(install)) remove_folder_and_subfolders(install); if (make_directory(install)) { if (extract_gz_file(version, gz_file, install)) success = true; # ifdef _WIN32 auto mapping_file_source = get_download_mapping_file(version); auto mapping_file_dest = get_install(); mapping_file_dest += folder_delimiter; mapping_file_dest += "windowsZones.xml"; if (!move_file(mapping_file_source, mapping_file_dest)) success = false; # endif // _WIN32 } } return success; } #endif // HAS_REMOTE_API static std::string get_version(const std::string& path) { std::string version; std::ifstream infile(path + "version"); if (infile.is_open()) { infile >> version; if (!infile.fail()) return version; } else { infile.open(path + "NEWS"); while (infile) { infile >> version; if (version == "Release") { infile >> version; return version; } } } throw std::runtime_error("Unable to get Timezone database version from " + path); } static std::unique_ptr init_tzdb() { using namespace date; const std::string install = get_install(); const std::string path = install + folder_delimiter; std::string line; bool continue_zone = false; std::unique_ptr db(new tzdb); #if AUTO_DOWNLOAD if (!file_exists(install)) { auto rv = remote_version(); if (!rv.empty() && remote_download(rv)) { if (!remote_install(rv)) { std::string msg = "Timezone database version \""; msg += rv; msg += "\" did not install correctly to \""; msg += install; msg += "\""; throw std::runtime_error(msg); } } if (!file_exists(install)) { std::string msg = "Timezone database not found at \""; msg += install; msg += "\""; throw std::runtime_error(msg); } db->version = get_version(path); } else { db->version = get_version(path); auto rv = remote_version(); if (!rv.empty() && db->version != rv) { if (remote_download(rv)) { remote_install(rv); db->version = get_version(path); } } } #else // !AUTO_DOWNLOAD if (!file_exists(install)) { std::string msg = "Timezone database not found at \""; msg += install; msg += "\""; throw std::runtime_error(msg); } db->version = get_version(path); #endif // !AUTO_DOWNLOAD CONSTDATA char*const files[] = { "africa", "antarctica", "asia", "australasia", "backward", "etcetera", "europe", "pacificnew", "northamerica", "southamerica", "systemv", "leapseconds" }; for (const auto& filename : files) { std::ifstream infile(path + filename); while (infile) { std::getline(infile, line); if (!line.empty() && line[0] != '#') { std::istringstream in(line); std::string word; in >> word; if (word == "Rule") { db->rules.push_back(Rule(line)); continue_zone = false; } else if (word == "Link") { db->links.push_back(time_zone_link(line)); continue_zone = false; } else if (word == "Leap") { db->leap_seconds.push_back(leap_second(line, detail::undocumented{})); continue_zone = false; } else if (word == "Zone") { db->zones.push_back(time_zone(line, detail::undocumented{})); continue_zone = true; } else if (line[0] == '\t' && continue_zone) { db->zones.back().add(line); } else { std::cerr << line << '\n'; } } } } std::sort(db->rules.begin(), db->rules.end()); Rule::split_overlaps(db->rules); std::sort(db->zones.begin(), db->zones.end()); db->zones.shrink_to_fit(); std::sort(db->links.begin(), db->links.end()); db->links.shrink_to_fit(); std::sort(db->leap_seconds.begin(), db->leap_seconds.end()); db->leap_seconds.shrink_to_fit(); #ifdef _WIN32 std::string mapping_file = get_install() + folder_delimiter + "windowsZones.xml"; db->mappings = load_timezone_mappings_from_xml_file(mapping_file); sort_zone_mappings(db->mappings); #endif // _WIN32 return db; } const tzdb& reload_tzdb() { #if AUTO_DOWNLOAD auto const& v = get_tzdb_list().front().version; if (!v.empty() && v == remote_version()) return get_tzdb_list().front(); #endif // AUTO_DOWNLOAD tzdb_list::undocumented_helper::push_front(get_tzdb_list(), init_tzdb().release()); return get_tzdb_list().front(); } #endif // !USE_OS_TZDB const tzdb& get_tzdb() { return get_tzdb_list().front(); } const time_zone* #if HAS_STRING_VIEW tzdb::locate_zone(std::string_view tz_name) const #else tzdb::locate_zone(const std::string& tz_name) const #endif { auto zi = std::lower_bound(zones.begin(), zones.end(), tz_name, #if HAS_STRING_VIEW [](const time_zone& z, const std::string_view& nm) #else [](const time_zone& z, const std::string& nm) #endif { return z.name() < nm; }); if (zi == zones.end() || zi->name() != tz_name) { #if !USE_OS_TZDB auto li = std::lower_bound(links.begin(), links.end(), tz_name, #if HAS_STRING_VIEW [](const time_zone_link& z, const std::string_view& nm) #else [](const time_zone_link& z, const std::string& nm) #endif { return z.name() < nm; }); if (li != links.end() && li->name() == tz_name) { zi = std::lower_bound(zones.begin(), zones.end(), li->target(), [](const time_zone& z, const std::string& nm) { return z.name() < nm; }); if (zi != zones.end() && zi->name() == li->target()) return &*zi; } #endif // !USE_OS_TZDB throw std::runtime_error(std::string(tz_name) + " not found in timezone database"); } return &*zi; } const time_zone* #if HAS_STRING_VIEW locate_zone(std::string_view tz_name) #else locate_zone(const std::string& tz_name) #endif { return get_tzdb().locate_zone(tz_name); } #if USE_OS_TZDB std::ostream& operator<<(std::ostream& os, const tzdb& db) { os << "Version: " << db.version << "\n\n"; for (const auto& x : db.zones) os << x << '\n'; os << '\n'; for (const auto& x : db.leap_seconds) os << x << '\n'; return os; } #else // !USE_OS_TZDB std::ostream& operator<<(std::ostream& os, const tzdb& db) { os << "Version: " << db.version << '\n'; std::string title("--------------------------------------------" "--------------------------------------------\n" "Name ""Start Y ""End Y " "Beginning ""Offset " "Designator\n" "--------------------------------------------" "--------------------------------------------\n"); int count = 0; for (const auto& x : db.rules) { if (count++ % 50 == 0) os << title; os << x << '\n'; } os << '\n'; title = std::string("---------------------------------------------------------" "--------------------------------------------------------\n" "Name ""Offset " "Rule ""Abrev ""Until\n" "---------------------------------------------------------" "--------------------------------------------------------\n"); count = 0; for (const auto& x : db.zones) { if (count++ % 10 == 0) os << title; os << x << '\n'; } os << '\n'; title = std::string("---------------------------------------------------------" "--------------------------------------------------------\n" "Alias ""To\n" "---------------------------------------------------------" "--------------------------------------------------------\n"); count = 0; for (const auto& x : db.links) { if (count++ % 45 == 0) os << title; os << x << '\n'; } os << '\n'; title = std::string("---------------------------------------------------------" "--------------------------------------------------------\n" "Leap second on\n" "---------------------------------------------------------" "--------------------------------------------------------\n"); os << title; for (const auto& x : db.leap_seconds) os << x << '\n'; return os; } #endif // !USE_OS_TZDB // ----------------------- #ifdef _WIN32 static std::string getTimeZoneKeyName() { DYNAMIC_TIME_ZONE_INFORMATION dtzi{}; auto result = GetDynamicTimeZoneInformation(&dtzi); if (result == TIME_ZONE_ID_INVALID) throw std::runtime_error("current_zone(): GetDynamicTimeZoneInformation()" " reported TIME_ZONE_ID_INVALID."); auto wlen = wcslen(dtzi.TimeZoneKeyName); char buf[128] = {}; assert(sizeof(buf) >= wlen+1); wcstombs(buf, dtzi.TimeZoneKeyName, wlen); if (strcmp(buf, "Coordinated Universal Time") == 0) return "UTC"; return buf; } const time_zone* tzdb::current_zone() const { std::string win_tzid = getTimeZoneKeyName(); std::string standard_tzid; if (!native_to_standard_timezone_name(win_tzid, standard_tzid)) { std::string msg; msg = "current_zone() failed: A mapping from the Windows Time Zone id \""; msg += win_tzid; msg += "\" was not found in the time zone mapping database."; throw std::runtime_error(msg); } return locate_zone(standard_tzid); } #else // !_WIN32 #if HAS_STRING_VIEW static std::string_view extract_tz_name(char const* rp) { using namespace std; string_view result = rp; CONSTDATA string_view zoneinfo = "zoneinfo"; size_t pos = result.rfind(zoneinfo); if (pos == result.npos) throw runtime_error( "current_zone() failed to find \"zoneinfo\" in " + string(result)); pos = result.find('/', pos); result.remove_prefix(pos + 1); return result; } #else // !HAS_STRING_VIEW static std::string extract_tz_name(char const* rp) { using namespace std; string result = rp; CONSTDATA char zoneinfo[] = "zoneinfo"; size_t pos = result.rfind(zoneinfo); if (pos == result.npos) throw runtime_error( "current_zone() failed to find \"zoneinfo\" in " + result); pos = result.find('/', pos); result.erase(0, pos + 1); return result; } #endif // HAS_STRING_VIEW static bool sniff_realpath(const char* timezone) { using namespace std; char rp[PATH_MAX+1] = {}; if (realpath(timezone, rp) == nullptr) throw system_error(errno, system_category(), "realpath() failed"); auto result = extract_tz_name(rp); return result != "posixrules"; } const time_zone* tzdb::current_zone() const { // On some OS's a file called /etc/localtime may // exist and it may be either a real file // containing time zone details or a symlink to such a file. // On MacOS and BSD Unix if this file is a symlink it // might resolve to a path like this: // "/usr/share/zoneinfo/America/Los_Angeles" // If it does, we try to determine the current // timezone from the remainder of the path by removing the prefix // and hoping the rest resolves to a valid timezone. // It may not always work though. If it doesn't then an // exception will be thrown by local_timezone. // The path may also take a relative form: // "../usr/share/zoneinfo/America/Los_Angeles". { struct stat sb; CONSTDATA auto timezone = "/etc/localtime"; if (lstat(timezone, &sb) == 0 && S_ISLNK(sb.st_mode) && sb.st_size > 0) { using namespace std; static const bool use_realpath = sniff_realpath(timezone); char rp[PATH_MAX+1] = {}; if (use_realpath) { if (realpath(timezone, rp) == nullptr) throw system_error(errno, system_category(), "realpath() failed"); } else { if (readlink(timezone, rp, sizeof(rp)-1) <= 0) throw system_error(errno, system_category(), "readlink() failed"); } return locate_zone(extract_tz_name(rp)); } } // On embedded systems e.g. buildroot with uclibc the timezone is linked // into /etc/TZ which is a symlink to path like this: // "/usr/share/zoneinfo/uclibc/America/Los_Angeles" // If it does, we try to determine the current // timezone from the remainder of the path by removing the prefix // and hoping the rest resolves to valid timezone. // It may not always work though. If it doesn't then an // exception will be thrown by local_timezone. // The path may also take a relative form: // "../usr/share/zoneinfo/uclibc/America/Los_Angeles". { struct stat sb; CONSTDATA auto timezone = "/etc/TZ"; if (lstat(timezone, &sb) == 0 && S_ISLNK(sb.st_mode) && sb.st_size > 0) { using namespace std; string result; char rp[PATH_MAX+1] = {}; if (readlink(timezone, rp, sizeof(rp)-1) > 0) result = string(rp); else throw system_error(errno, system_category(), "readlink() failed"); const size_t pos = result.find(get_tz_dir()); if (pos != result.npos) result.erase(0, get_tz_dir().size() + 1 + pos); return locate_zone(result); } } { // On some versions of some linux distro's (e.g. Ubuntu), // the current timezone might be in the first line of // the /etc/timezone file. std::ifstream timezone_file("/etc/timezone"); if (timezone_file.is_open()) { std::string result; std::getline(timezone_file, result); if (!result.empty()) return locate_zone(result); } // Fall through to try other means. } { // On some versions of some bsd distro's (e.g. FreeBSD), // the current timezone might be in the first line of // the /var/db/zoneinfo file. std::ifstream timezone_file("/var/db/zoneinfo"); if (timezone_file.is_open()) { std::string result; std::getline(timezone_file, result); if (!result.empty()) return locate_zone(result); } // Fall through to try other means. } { // On some versions of some bsd distro's (e.g. iOS), // it is not possible to use file based approach, // we switch to system API, calling functions in // CoreFoundation framework. #if TARGET_OS_IPHONE std::string result = date::iOSUtils::get_current_timezone(); if (!result.empty()) return locate_zone(result); #endif // Fall through to try other means. } { // On some versions of some linux distro's (e.g. Red Hat), // the current timezone might be in the first line of // the /etc/sysconfig/clock file as: // ZONE="US/Eastern" std::ifstream timezone_file("/etc/sysconfig/clock"); std::string result; while (timezone_file) { std::getline(timezone_file, result); auto p = result.find("ZONE=\""); if (p != std::string::npos) { result.erase(p, p+6); result.erase(result.rfind('"')); return locate_zone(result); } } // Fall through to try other means. } throw std::runtime_error("Could not get current timezone"); } #endif // !_WIN32 const time_zone* current_zone() { return get_tzdb().current_zone(); } } // namespace date #if defined(__GNUC__) && __GNUC__ < 5 # pragma GCC diagnostic pop #endif date-3.0.1/test/000077500000000000000000000000001403643451100134105ustar00rootroot00000000000000date-3.0.1/test/clock_cast_test/000077500000000000000000000000001403643451100165545ustar00rootroot00000000000000date-3.0.1/test/clock_cast_test/constexpr.pass.cpp000066400000000000000000000054641403643451100222630ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2019 nanoric // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "tz.h" #include #include struct const_clock { using duration = typename std::common_type::type; using rep = duration::rep; using period = duration::period; using time_point = std::chrono::time_point; static constexpr date::sys_days epoch { date::days { 1000 } }; template static std::chrono::time_point::type> CONSTCD11 to_sys(std::chrono::time_point const& tp) { return epoch + tp.time_since_epoch(); } template static std::chrono::time_point::type> CONSTCD11 from_sys( std::chrono::time_point const& tp) { using res = std::chrono::time_point::type>; return res(tp - epoch); } }; int main() { using namespace date; using namespace std::chrono; using const_days = time_point; CONSTCD14 sys_days sys { days { 1024 } }; static_assert(sys.time_since_epoch().count() == 1024, ""); CONSTCD14 const_days c {clock_cast(sys)}; CONSTCD14 sys_days sys2 {clock_cast(c)}; CONSTCD14 sys_days sys3 { clock_cast(const_days(days(48))) }; #if __cplusplus >= 201402L static_assert(c.time_since_epoch().count() == 24, ""); static_assert(sys2.time_since_epoch().count() == 1024, ""); static_assert(sys3.time_since_epoch().count() == 1048, ""); #endif } date-3.0.1/test/clock_cast_test/custom_clock.pass.cpp000066400000000000000000000141611403643451100227150ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2017, 2018 Tomasz Kamiński // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "tz.h" #include #include //used to count number of conversion int conversions = 0; //to/from impl struct mil_clock { using duration = typename std::common_type::type; using rep = duration::rep; using period = duration::period; using time_point = std::chrono::time_point; static constexpr date::sys_days epoch{date::days{1000}}; template static std::chrono::time_point::type> to_sys(std::chrono::time_point const& tp) { ++conversions; return epoch + tp.time_since_epoch(); } template static std::chrono::time_point::type> from_sys(std::chrono::time_point const& tp) { ++conversions; using res = std::chrono::time_point::type>; return res(tp - epoch); } template static std::chrono::time_point::type> to_local(std::chrono::time_point const& tp) { return date::clock_cast(to_sys(tp)); } template static std::chrono::time_point::type> from_local(std::chrono::time_point const& tp) { return from_sys(date::clock_cast(tp)); } static time_point now() { return from_sys(std::chrono::system_clock::now()); } }; date::sys_days const mil_clock::epoch; // traits example struct s2s_clock { using duration = std::chrono::system_clock::duration; using rep = duration::rep; using period = duration::period; using time_point = std::chrono::time_point; template static std::chrono::time_point to_sys(std::chrono::time_point const& tp) { ++conversions; return std::chrono::time_point(tp.time_since_epoch()); } template static std::chrono::time_point from_sys(std::chrono::time_point const& tp) { ++conversions; return std::chrono::time_point(tp.time_since_epoch()); } static time_point now() { return from_sys(std::chrono::system_clock::now()); } }; namespace date { template<> struct clock_time_conversion { template std::chrono::time_point::type> operator()(std::chrono::time_point const& tp) { ++conversions; using res = std::chrono::time_point::type>; return res(tp.time_since_epoch() - mil_clock::epoch.time_since_epoch()); } }; } int main() { using namespace date; using sys_clock = std::chrono::system_clock; // self { sys_days st(1997_y/dec/12); auto mt = mil_clock::from_sys(st); assert(clock_cast(mt) == mt); } // mil <-> local { local_days lt(1997_y/dec/12); auto mt = mil_clock::from_local(lt); assert(clock_cast(lt) == mt); assert(clock_cast(mt) == lt); } // mil <-> sys { sys_days st(1997_y/dec/12); auto mt = mil_clock::from_sys(st); assert(clock_cast(st) == mt); assert(clock_cast(mt) == st); } // mil <-> utc { sys_days st(1997_y/dec/12); auto mt = mil_clock::from_sys(st); auto ut = utc_clock::from_sys(st); assert(clock_cast(ut) == mt); assert(clock_cast(mt) == ut); } // mil <-> tai { sys_days st(1997_y/dec/12); auto mt = mil_clock::from_sys(st); auto ut = utc_clock::from_sys(st); auto tt = tai_clock::from_utc(ut); assert(clock_cast(mt) == tt); assert(clock_cast(tt) == mt); } // mil <-> gps { sys_days st(1997_y/dec/12); auto mt = mil_clock::from_sys(st); auto ut = utc_clock::from_sys(st); auto gt = gps_clock::from_utc(ut); assert(clock_cast(mt) == gt); assert(clock_cast(gt) == mt); } // s2s -> mil { sys_days st(1997_y/dec/12); auto mt = mil_clock::from_sys(st); auto s2t = s2s_clock::from_sys(st); //direct trait conversion conversions = 0; assert(clock_cast(s2t) == mt); assert(conversions == 1); //uses sys_clock conversions = 0; assert(clock_cast(mt) == s2t); assert(conversions == 2); } } date-3.0.1/test/clock_cast_test/deprecated.pass.cpp000066400000000000000000000050341403643451100223270ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2017 Tomasz Kamiński // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "tz.h" #include int main() { using namespace date; // sys <-> utc { sys_days st(1997_y/dec/12); auto ut = utc_clock::from_sys(st); assert(to_utc_time(st) == ut); assert(to_sys_time(ut) == st); } // tai <-> utc { sys_days st(1997_y/dec/12); auto ut = utc_clock::from_sys(st); auto tt = tai_clock::from_utc(ut); assert(to_tai_time(ut) == tt); assert(to_utc_time(tt) == ut); } // tai <-> sys { sys_days st(1997_y/dec/12); auto ut = utc_clock::from_sys(st); auto tt = tai_clock::from_utc(ut); assert(to_tai_time(st) == tt); assert(to_sys_time(tt) == st); } // gps <-> utc { sys_days st(1997_y/dec/12); auto ut = utc_clock::from_sys(st); auto gt = gps_clock::from_utc(ut); assert(to_gps_time(ut) == gt); assert(to_utc_time(gt) == ut); } // gps <-> sys { sys_days st(1997_y/dec/12); auto ut = utc_clock::from_sys(st); auto gt = gps_clock::from_utc(ut); assert(to_gps_time(st) == gt); assert(to_sys_time(gt) == st); } // tai <-> gps { sys_days st(1997_y/dec/12); auto ut = utc_clock::from_sys(st); auto tt = tai_clock::from_utc(ut); auto gt = gps_clock::from_utc(ut); assert(to_gps_time(tt) == gt); assert(to_tai_time(gt) == tt); } } date-3.0.1/test/clock_cast_test/local_t.pass.cpp000066400000000000000000000100461403643451100216430ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2018 Tomasz Kamiński // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include "date/tz.h" int main() { using namespace date; using namespace std::chrono; // self { auto ls = local_days{1970_y/January/1_d}; assert(clock_cast(ls) == ls); } /// sys epoch { auto ls = local_days{1970_y/January/1_d}; auto st = clock_cast(ls); assert(clock_cast(st) == ls); assert(st.time_since_epoch() == seconds(0)); } /// sys 2000 case { auto ls = local_days{2000_y/January/1_d}; auto st = clock_cast(ls); assert(clock_cast(st) == ls); assert(st.time_since_epoch() == seconds(946684800)); } /// utc epoch { auto lu = local_days{1970_y/January/1_d}; auto ut = clock_cast(lu); assert(clock_cast(ut) == lu); assert(ut.time_since_epoch() == seconds(0)); } // utc leap second { auto lu = local_days{2015_y/July/1_d} - milliseconds(1); auto ut = clock_cast(lu) + milliseconds(50); //into leap second assert(clock_cast(ut) == lu); } /// utc paper example { auto lu = local_days{2000_y/January/1_d}; auto ut = clock_cast(lu); assert(clock_cast(ut) == lu); assert(ut.time_since_epoch() == seconds(946684822)); } /// tai epoch { auto lt = local_days{1958_y/January/1_d}; auto tt = clock_cast(lt); assert(clock_cast(tt) == lt); assert(tt.time_since_epoch() == seconds(0)); auto lu = local_days{1958_y/January/1_d} - seconds(10); auto ut = clock_cast(lu); assert(clock_cast(ut) == tt); } // tai paper example { auto lt = local_days{2000_y/January/1_d} + seconds(32); auto tt = clock_cast(lt); assert(clock_cast(tt) == lt); auto lu = local_days{2000_y/January/1_d}; auto ut = clock_cast(lu); assert(clock_cast(ut) == tt); } /// gps epoch { auto lg = local_days{1980_y/January/Sunday[1]}; auto gt = clock_cast(lg); assert(clock_cast(gt) == lg); assert(gt.time_since_epoch() == seconds(0)); auto lu = local_days{1980_y/January/Sunday[1]}; auto ut = clock_cast(lu); assert(clock_cast(ut) == gt); auto lt = local_days{1980_y/January/Sunday[1]} + seconds(19); auto tt = clock_cast(lt); assert(clock_cast(tt) == gt); } // gps 2000 example { auto lg = local_days{2000_y/January/1_d}; auto gt = clock_cast(lg); assert(clock_cast(gt) == lg); auto lu = local_days{2000_y/January/1_d} - seconds(13); auto ut = clock_cast(lu); assert(clock_cast(ut) == gt); auto lt = local_days{2000_y/January/1_d} + seconds(19); auto tt = clock_cast(lt); assert(clock_cast(tt) == gt); } } date-3.0.1/test/clock_cast_test/noncastable.pass.cpp000066400000000000000000000235531403643451100225260ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2017, 2018 Tomasz Kamiński // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "tz.h" #include #include template struct is_clock_castable : std::false_type {}; template struct is_clock_castable(typename SourceClock::time_point()), void())> : std::true_type {}; //Clock based on steady clock, not related to wall time (sys_clock/utc_clock) struct steady_based_clock { using duration = std::chrono::steady_clock::duration; using rep = duration::rep; using period = duration::period; using time_point = std::chrono::time_point; static time_point now() { return time_point(std::chrono::steady_clock::now().time_since_epoch()); } }; //Traits that allow conversion between steady_clock and steady_based clock //Does not use wall-time clocks as rally (sys/utc) namespace date { template<> struct clock_time_conversion { template std::chrono::time_point operator()(std::chrono::time_point const& tp) const { using res = std::chrono::time_point; return res(tp.time_since_epoch()); } }; template<> struct clock_time_conversion { template std::chrono::time_point operator()(std::chrono::time_point const& tp) const { using res = std::chrono::time_point; return res(tp.time_since_epoch()); } }; } //Ambigous clocks both providing to/from_sys and to/from_utc //They are mock_ups just returning zero time_point struct amb1_clock { using duration = std::chrono::seconds; using rep = duration::rep; using period = duration::period; using time_point = std::chrono::time_point; static time_point now() { return {}; } template static std::chrono::time_point to_sys(std::chrono::time_point const&) { return {}; } template static std::chrono::time_point from_sys(std::chrono::time_point const&) { return {}; } template static std::chrono::time_point to_utc(std::chrono::time_point const&) { return {}; } template static std::chrono::time_point from_utc(std::chrono::time_point const&) { return {}; } }; struct amb2_clock { using duration = std::chrono::seconds; using rep = duration::rep; using period = duration::period; using time_point = std::chrono::time_point; static time_point now() { return {}; } template static std::chrono::time_point to_sys(std::chrono::time_point const&) { return {}; } template static std::chrono::time_point from_sys(std::chrono::time_point const&) { return {}; } template static std::chrono::time_point to_utc(std::chrono::time_point const&) { return {}; } template static std::chrono::time_point from_utc(std::chrono::time_point const&) { return {}; } }; namespace date { //Disambiguates that sys_clock is preffered template<> struct clock_time_conversion { template std::chrono::time_point operator()(std::chrono::time_point const& tp) const { return amb1_clock::from_sys(amb2_clock::to_sys(tp)); } }; } int main() { using namespace date; using namespace std::chrono; using sys_clock = std::chrono::system_clock; //steady_clock (must be different that sys_clock) static_assert(is_clock_castable::value, "steady_clock -> steady_clock"); static_assert(!is_clock_castable::value, "steady_clock -> local_t"); static_assert(!is_clock_castable::value, "local_t -> steady_clock"); static_assert(!is_clock_castable::value, "steady_clock -> sys_clock"); static_assert(!is_clock_castable::value, "sys_clock -> steady_clock"); static_assert(!is_clock_castable::value, "steady_clock -> utc_clock"); static_assert(!is_clock_castable::value, "utc_clock -> steady_clock"); static_assert(!is_clock_castable::value, "steady_clock -> tai_clock"); static_assert(!is_clock_castable::value, "tai_clock -> steady_clock"); //steady_based_clock (unrelated to sys_clock and utc_clocks) static_assert(is_clock_castable::value, "steady_based_clock -> steady_based_clock"); static_assert(!is_clock_castable::value, "steady_based_clock -> local_t"); static_assert(!is_clock_castable::value, "local_t -> steady_based_clock"); static_assert(!is_clock_castable::value, "steady_based_clock -> sys_clock"); static_assert(!is_clock_castable::value, "sys_clock -> steady_based_clock"); static_assert(!is_clock_castable::value, "steady_based_clock -> utc_clock"); static_assert(!is_clock_castable::value, "utc_clock -> steady_based_clock"); static_assert(!is_clock_castable::value, "steady_based_clock -> tai_clock"); static_assert(!is_clock_castable::value, "tai_clock -> steady_based_clock"); //steady_based <-> steady_clock { auto s1 = steady_clock::time_point(steady_clock::duration(200)); auto s2 = steady_based_clock::time_point(steady_based_clock::duration(200)); assert(clock_cast(s1) == s2); assert(clock_cast(s2) == s1); } //ambX <-> sys/utc works as one rally can be used in each case, or one lead to quicker conversione static_assert(is_clock_castable::value, "amb1_clock -> amb1_clock"); static_assert(is_clock_castable::value, "amb1_clock -> sys_clock"); static_assert(is_clock_castable::value, "sys_clock -> amb1_clock"); static_assert(is_clock_castable::value, "amb1_clock -> utc_clock"); static_assert(is_clock_castable::value, "utc_clock -> amb1_clock"); static_assert(is_clock_castable::value, "amb1_clock -> tai_clock"); static_assert(is_clock_castable::value, "tai_clock -> amb1_clock"); static_assert(is_clock_castable::value, "amb1_clock -> tai_clock"); static_assert(is_clock_castable::value, "gps_clock -> amb1_clock"); static_assert(is_clock_castable::value, "amb2_clock -> amb2_clock"); static_assert(is_clock_castable::value, "amb2_clock -> sys_clock"); static_assert(is_clock_castable::value, "sys_clock -> amb2_clock"); static_assert(is_clock_castable::value, "amb2_clock -> utc_clock"); static_assert(is_clock_castable::value, "utc_clock -> amb2_clock"); static_assert(is_clock_castable::value, "amb2_clock -> tai_clock"); static_assert(is_clock_castable::value, "tai_clock -> amb2_clock"); static_assert(is_clock_castable::value, "amb2_clock -> tai_clock"); static_assert(is_clock_castable::value, "gps_clock -> amb2_clock"); //amb1 -> amb2: ambigous because can either go trough sys_clock or utc_clock static_assert(!is_clock_castable::value, "amb1_clock -> amb2_clock"); //amb2 -> amb1: disambiguated via trait specialization static_assert(is_clock_castable::value, "amb2_clock -> amb1_clock"); } date-3.0.1/test/clock_cast_test/normal_clocks.pass.cpp000066400000000000000000000057461403643451100230670ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2017 Tomasz Kamiński // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "tz.h" #include int main() { using namespace date; using sys_clock = std::chrono::system_clock; // self { sys_days st(1997_y/dec/12); auto ut = utc_clock::from_sys(st); auto tt = tai_clock::from_utc(ut); assert(clock_cast(st) == st); assert(clock_cast(ut) == ut); assert(clock_cast(tt) == tt); } // sys <-> utc { sys_days st(1997_y/dec/12); auto ut = utc_clock::from_sys(st); assert(clock_cast(st) == ut); assert(clock_cast(ut) == st); } // tai <-> utc { sys_days st(1997_y/dec/12); auto ut = utc_clock::from_sys(st); auto tt = tai_clock::from_utc(ut); assert(clock_cast(ut) == tt); assert(clock_cast(tt) == ut); } // tai <-> sys { sys_days st(1997_y/dec/12); auto ut = utc_clock::from_sys(st); auto tt = tai_clock::from_utc(ut); assert(clock_cast(st) == tt); assert(clock_cast(tt) == st); } // gps <-> utc { sys_days st(1997_y/dec/12); auto ut = utc_clock::from_sys(st); auto gt = gps_clock::from_utc(ut); assert(clock_cast(ut) == gt); assert(clock_cast(gt) == ut); } // gps <-> sys { sys_days st(1997_y/dec/12); auto ut = utc_clock::from_sys(st); auto gt = gps_clock::from_utc(ut); assert(clock_cast(st) == gt); assert(clock_cast(gt) == st); } // tai <-> gps { sys_days st(1997_y/dec/12); auto ut = utc_clock::from_sys(st); auto tt = tai_clock::from_utc(ut); auto gt = gps_clock::from_utc(ut); assert(clock_cast(tt) == gt); assert(clock_cast(gt) == tt); } } date-3.0.1/test/clock_cast_test/to_sys_return_int.fail.cpp000066400000000000000000000032341403643451100237650ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2017 Tomasz Kamiński // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "tz.h" struct bad_clock { using duration = std::chrono::system_clock::duration; using rep = duration::rep; using period = duration::period; using time_point = std::chrono::time_point; template static int to_sys(std::chrono::time_point const& tp) { return tp.time_since_epoch().count(); } }; int main() { using namespace date; using sys_clock = std::chrono::system_clock; auto bt = bad_clock::time_point(); clock_cast(bt); } date-3.0.1/test/clock_cast_test/to_sys_return_reference.fail.cpp000066400000000000000000000034021403643451100251260ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2017 Tomasz Kamiński // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "tz.h" struct bad_clock { using duration = std::chrono::system_clock::duration; using rep = duration::rep; using period = duration::period; using time_point = std::chrono::time_point; template static date::sys_time const& to_sys(std::chrono::time_point const& tp) { static date::sys_time val; val = date::sys_time(tp.time_since_epoch()); return val; } }; int main() { using namespace date; using sys_clock = std::chrono::system_clock; auto bt = bad_clock::time_point(); clock_cast(bt); } date-3.0.1/test/clock_cast_test/to_sys_return_utc_time.fail.cpp000066400000000000000000000033111403643451100250000ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2017, 2018 Tomasz Kamiński // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "tz.h" struct bad_clock { using duration = std::chrono::system_clock::duration; using rep = duration::rep; using period = duration::period; using time_point = std::chrono::time_point; template static date::utc_time to_sys(std::chrono::time_point const& tp) { return date::utc_time(tp.time_since_epoch()); } }; int main() { using namespace date; using sys_clock = std::chrono::system_clock; auto bt = bad_clock::time_point(); clock_cast(bt); } date-3.0.1/test/date_test/000077500000000000000000000000001403643451100153645ustar00rootroot00000000000000date-3.0.1/test/date_test/day.pass.cpp000066400000000000000000000120211403643451100176060ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class day // { // unsigned char d_; // public: // explicit constexpr day(unsigned d) noexcept; // // day& operator++() noexcept; // day operator++(int) noexcept; // day& operator--() noexcept; // day operator--(int) noexcept; // // day& operator+=(const days& d) noexcept; // day& operator-=(const days& d) noexcept; // // constexpr explicit operator unsigned() const noexcept; // constexpr bool ok() const noexcept; // }; // // constexpr bool operator==(const day& x, const day& y) noexcept; // constexpr bool operator!=(const day& x, const day& y) noexcept; // constexpr bool operator< (const day& x, const day& y) noexcept; // constexpr bool operator> (const day& x, const day& y) noexcept; // constexpr bool operator<=(const day& x, const day& y) noexcept; // constexpr bool operator>=(const day& x, const day& y) noexcept; // // constexpr day operator+(const day& x, const days& y) noexcept; // constexpr day operator+(const days& x, const day& y) noexcept; // constexpr day operator-(const day& x, const days& y) noexcept; // constexpr days operator-(const day& x, const day& y) noexcept; // // constexpr day operator "" _d(unsigned long long d) noexcept; // std::ostream& operator<<(std::ostream& os, const day& d); #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert( std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert(static_cast(date::day{1}) == 1, ""); static_assert(!date::day{0}.ok(), ""); static_assert( date::day{1}.ok(), ""); static_assert( date::day{2}.ok(), ""); static_assert( date::day{3}.ok(), ""); static_assert( date::day{29}.ok(), ""); static_assert( date::day{30}.ok(), ""); static_assert( date::day{31}.ok(), ""); static_assert(!date::day{32}.ok(), ""); int main() { using namespace date; static_assert(std::is_same{}, ""); static_assert(1_d == day{1}, ""); static_assert(2_d == day{2}, ""); static_assert( 1_d == 1_d, ""); static_assert(!(1_d == 2_d), ""); static_assert(!(2_d == 1_d), ""); static_assert(!(1_d != 1_d), ""); static_assert( 1_d != 2_d, ""); static_assert( 2_d != 1_d, ""); static_assert(!(1_d < 1_d), ""); static_assert( 1_d < 2_d, ""); static_assert(!(2_d < 1_d), ""); static_assert( 1_d <= 1_d, ""); static_assert( 1_d <= 2_d, ""); static_assert(!(2_d <= 1_d), ""); static_assert(!(1_d > 1_d), ""); static_assert(!(1_d > 2_d), ""); static_assert( 2_d > 1_d, ""); static_assert( 1_d >= 1_d, ""); static_assert(!(1_d >= 2_d), ""); static_assert( 2_d >= 1_d, ""); static_assert(3_d + days{7} == 10_d, ""); static_assert(days{7} + 3_d == 10_d, ""); static_assert(3_d + weeks{1} == 10_d, ""); static_assert(weeks{1} + 3_d == 10_d, ""); static_assert(7_d - days{3} == 4_d, ""); static_assert(3_d - 7_d == days{-4}, ""); static_assert(25_d - 11_d == weeks{2}, ""); auto d = 1_d; assert(++d == 2_d); assert(d++ == 2_d); assert(d == 3_d); assert(d-- == 3_d); assert(d == 2_d); assert(--d == 1_d); assert((d += days{2}) == 3_d); assert((d -= days{2}) == 1_d); std::ostringstream os; os << d; assert(os.str() == "01"); d += days{11}; os.str(""); os << d; assert(os.str() == "12"); } date-3.0.1/test/date_test/daypday.fail.cpp000066400000000000000000000023511403643451100204360ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // day + day not allowed #include "date.h" int main() { using namespace date; auto x = 3_d + 7_d; } date-3.0.1/test/date_test/daysmday.fail.cpp000066400000000000000000000023561403643451100206230ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // days - day not allowed #include "date.h" int main() { using namespace date; auto x = days{3} - 7_d; } date-3.0.1/test/date_test/daysmweekday.fail.cpp000066400000000000000000000023621403643451100214740ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // days - weekday not allowed #include "date.h" int main() { using namespace date; auto b = days{1} - sun; } date-3.0.1/test/date_test/detail/000077500000000000000000000000001403643451100166265ustar00rootroot00000000000000date-3.0.1/test/date_test/detail/decimal_format_seconds.pass.cpp000066400000000000000000000122531403643451100247660ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2017 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // template // class decimal_format_seconds // { // using CT = typename std::common_type::type; // using rep = typename CT::rep; // public: // static unsigned constexpr width = detail::width::value < 19 ? // detail::width::value : 6u; // using precision = std::chrono::duration::value>>; // private: // std::chrono::seconds s_; // precision sub_s_; // // public: // constexpr explicit decimal_format_seconds(const Duration& d) noexcept; // // constexpr std::chrono::seconds& seconds() noexcept; // constexpr std::chrono::seconds seconds() const noexcept; // constexpr precision subseconds() const noexcept; // constexpr precision to_duration() const noexcept; // // template // friend // std::basic_ostream& // operator<<(std::basic_ostream& os, const decimal_format_seconds& x); // }; #include "date.h" #include #include #include using fortnights = std::chrono::duration, date::weeks::period>>; using microfortnights = std::chrono::duration>; int main() { using namespace date::detail; using namespace std; using namespace std::chrono; { using D = decimal_format_seconds; static_assert(is_same{}, ""); static_assert(D::width == 0, ""); D dfs{minutes{3}}; assert(dfs.seconds() == seconds{180}); assert(dfs.to_duration() == seconds{180}); ostringstream out; out << dfs; assert(out.str() == "180"); } { using D = decimal_format_seconds; static_assert(is_same{}, ""); static_assert(D::width == 0, ""); D dfs{seconds{3}}; assert(dfs.seconds() == seconds{3}); assert(dfs.to_duration() == seconds{3}); ostringstream out; out << dfs; assert(out.str() == "03"); } { using D = decimal_format_seconds; static_assert(D::width == 3, ""); D dfs{seconds{3}}; assert(dfs.seconds() == seconds{3}); assert(dfs.to_duration() == seconds{3}); assert(dfs.subseconds() == milliseconds{0}); ostringstream out; out << dfs; assert(out.str() == "03.000"); } { using D = decimal_format_seconds; static_assert(D::width == 3, ""); D dfs{milliseconds{3}}; assert(dfs.seconds() == seconds{0}); assert(dfs.to_duration() == milliseconds{3}); assert(dfs.subseconds() == milliseconds{3}); ostringstream out; out << dfs; assert(out.str() == "00.003"); } { using D = decimal_format_seconds; static_assert(D::width == 4, ""); D dfs{microfortnights{3}}; using S = D::precision; assert(dfs.seconds() == seconds{3}); assert(dfs.to_duration() == S{36288}); assert(dfs.subseconds() == S{6288}); ostringstream out; out << dfs; assert(out.str() == "03.6288"); } { using CT = common_type::type; using D = decimal_format_seconds; static_assert(D::width == 4, ""); D dfs{microfortnights{3}}; using S = D::precision; assert(dfs.seconds() == seconds{3}); assert(dfs.to_duration() == S{36288}); assert(dfs.subseconds() == S{6288}); ostringstream out; out << dfs; assert(out.str() == "03.6288"); } } date-3.0.1/test/date_test/detail/static_pow10.pass.cpp000066400000000000000000000037461403643451100226260ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2017 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // template // struct static_pow10 // { // static constepxr std::uint64_t value = ...; // }; #include "date.h" #include #include #include int main() { using namespace date::detail; static_assert(static_pow10<0>::value == 1, ""); static_assert(static_pow10<1>::value == 10, ""); static_assert(static_pow10<2>::value == 100, ""); static_assert(static_pow10<3>::value == 1000, ""); static_assert(static_pow10<4>::value == 10000, ""); static_assert(static_pow10<5>::value == 100000, ""); static_assert(static_pow10<6>::value == 1000000, ""); static_assert(static_pow10<7>::value == 10000000, ""); static_assert(static_pow10<8>::value == 100000000, ""); static_assert(static_pow10<9>::value == 1000000000, ""); static_assert(static_pow10<10>::value == 10000000000, ""); } date-3.0.1/test/date_test/detail/width.pass.cpp000066400000000000000000000047361403643451100214300ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2017 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // width::value is the number of fractional decimal digits in 1/n // width<0>::value and width<1>::value are defined to be 0 // If 1/n takes more than 18 fractional decimal digits, // the result is truncated to 19. // Example: width<2>::value == 1 // Example: width<3>::value == 19 // Example: width<4>::value == 2 // Example: width<10>::value == 1 // Example: width<1000>::value == 3 // template // // struct width // { // static constexpr unsigned value = ...; // }; #include "date.h" #include #include #include int main() { using namespace date::detail; static_assert(width<0, 1>::value == 0, ""); static_assert(width<1, 1>::value == 0, ""); static_assert(width<1, 2>::value == 1, ""); static_assert(width<1, 3>::value == 19, ""); static_assert(width<1, 4>::value == 2, ""); static_assert(width<1, 5>::value == 1, ""); static_assert(width<1, 6>::value == 19, ""); static_assert(width<1, 7>::value == 19, ""); static_assert(width<1, 8>::value == 3, ""); static_assert(width<1, 9>::value == 19, ""); static_assert(width<1, 10>::value == 1, ""); static_assert(width<1, 100>::value == 2, ""); static_assert(width<1, 1000>::value == 3, ""); static_assert(width<1, 10000>::value == 4, ""); static_assert(width<756, 625>::value == 4, ""); } date-3.0.1/test/date_test/durations.pass.cpp000066400000000000000000000045721403643451100210550ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // durations // // using days = std::chrono::duration // , std::chrono::hours::period>>; // // using weeks = std::chrono::duration // , days::period>>; // // using years = std::chrono::duration // , days::period>>; // // using months = std::chrono::duration // >>; // // time_point // // using sys_days = std::chrono::time_point; #include "date.h" #include static_assert(date::days{1} == std::chrono::hours{24}, ""); static_assert(date::weeks{1} == date::days{7}, ""); static_assert(date::months{12} == date::years{1}, ""); static_assert(date::days{30} < date::months{1} && date::months{1} < date::days{31}, ""); static_assert(date::weeks{4} < date::months{1} && date::months{1} < date::weeks{5}, ""); static_assert(date::years{400} == date::days{146097}, ""); static_assert(date::days{365} < date::years{1} && date::years{1} < date::days{366}, ""); static_assert(date::weeks{52} < date::years{1} && date::years{1} < date::weeks{53}, ""); static_assert(std::is_same{}, ""); int main() { } date-3.0.1/test/date_test/durations_output.pass.cpp000066400000000000000000000155731403643451100225000ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2018 Tomasz Kamiński // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "date.h" #include #include void test_SI() { using namespace std::chrono; using namespace date; std::ostringstream os; // atto { duration d(13); os << d; assert(os.str() == "13as"); os.str(""); } // femto { duration d(13); os << d; assert(os.str() == "13fs"); os.str(""); } // pico { duration d(13); os << d; assert(os.str() == "13ps"); os.str(""); } // nano { duration d(13); os << d; assert(os.str() == "13ns"); os.str(""); } // mikro { duration d(13); os << d; assert(os.str() == "13\xC2\xB5s"); os.str(""); } // milli { duration d(13); os << d; assert(os.str() == "13ms"); os.str(""); } // centi { duration d(13); os << d; assert(os.str() == "13cs"); os.str(""); } // deci { duration d(13); os << d; assert(os.str() == "13ds"); os.str(""); } // seconds { duration d(13); os << d; assert(os.str() == "13s"); os.str(""); } // deca { duration d(13); os << d; assert(os.str() == "13das"); os.str(""); } // hecto { duration d(13); os << d; assert(os.str() == "13hs"); os.str(""); } // kilo { duration d(13); os << d; assert(os.str() == "13ks"); os.str(""); } // mega { duration d(13); os << d; assert(os.str() == "13Ms"); os.str(""); } // giga { duration d(13); os << d; assert(os.str() == "13Gs"); os.str(""); } // tera { duration d(13); os << d; assert(os.str() == "13Ts"); os.str(""); } // peta { duration d(13); os << d; assert(os.str() == "13Ps"); os.str(""); } // femto { duration d(13); os << d; assert(os.str() == "13Es"); os.str(""); } } void test_calendar() { using namespace std::chrono; using namespace date; std::ostringstream os; // minutes { minutes d(13); os << d; assert(os.str() == "13min"); os.str(""); } // hours { hours d(13); os << d; assert(os.str() == "13h"); os.str(""); } // days { days d(13); os << d; assert(os.str() == "13d"); os.str(""); } } void test_integral_scale() { using namespace std::chrono; using namespace date; std::ostringstream os; // ratio 123 / 1 { duration> d(13); os << d; assert(os.str() == "13[123]s"); os.str(""); } // ratio 100 / 4 = ratio 25 / 1 { duration> d(13); os << d; assert(os.str() == "13[25]s"); os.str(""); } // weeks = ratio 7 * 24 * 60 * 60 / 1 = ratio 604800 / 1 { weeks d(13); os << d; assert(os.str() == "13[604800]s"); os.str(""); } // years = 146097/400 days = ratio 146097/400 * 24 * 60 * 60 = ratio 31556952 / 1 { years d(13); os << d; assert(os.str() == "13[31556952]s"); os.str(""); } // months = 1/12 years = ratio 1/12 * 31556952 = ratio 2629746 / 1 { months d(13); os << d; assert(os.str() == "13[2629746]s"); os.str(""); } } void test_ratio_scale() { using namespace std::chrono; using namespace date; std::ostringstream os; // ratio 1 / 2 { duration> d(13); os << d; assert(os.str() == "13[1/2]s"); os.str(""); } // ratio 100 / 3 { duration> d(13); os << d; assert(os.str() == "13[100/3]s"); os.str(""); } // ratio 100 / 6 = ratio 50 / 3 { duration> d(13); os << d; assert(os.str() == "13[50/3]s"); os.str(""); } } void test_constexpr() { using date::detail::get_units; CONSTCD11 auto as = get_units(std::atto{}); CONSTCD11 auto fs = get_units(std::femto{}); CONSTCD11 auto ps = get_units(std::pico{}); CONSTCD11 auto ns = get_units(std::nano{}); CONSTCD11 auto us = get_units(std::micro{}); CONSTCD11 auto usw = get_units(std::micro{}); CONSTCD11 auto ms = get_units(std::milli{}); CONSTCD11 auto cs = get_units(std::centi{}); CONSTCD11 auto ds = get_units(std::deci{}); CONSTCD11 auto s = get_units(std::ratio<1>{}); CONSTCD11 auto das = get_units(std::deca{}); CONSTCD11 auto hs = get_units(std::hecto{}); CONSTCD11 auto ks = get_units(std::kilo{}); CONSTCD11 auto Ms = get_units(std::mega{}); CONSTCD11 auto Gs = get_units(std::giga{}); CONSTCD11 auto Ts = get_units(std::tera{}); CONSTCD11 auto Ps = get_units(std::peta{}); CONSTCD11 auto Es = get_units(std::exa{}); (void)as, (void)fs, (void)ps, (void)ns, (void)usw, (void)us, (void)ms, (void)cs, (void)ds, (void)s, (void)das, (void)hs, (void)ks, (void)Ms, (void)Gs, (void)Ts, (void)Ps, (void)Es; CONSTCD11 auto min = get_units(std::ratio<60>{}); CONSTCD11 auto h = get_units(std::ratio<3600>{}); CONSTCD11 auto d = get_units(std::ratio<86400>{}); (void)min, (void)h, (void)d; CONSTCD14 auto integer = get_units(std::ratio<123>{}); CONSTCD14 auto ratio = get_units(std::ratio<123, 3>{}); (void)integer, (void)ratio; } int main() { test_SI(); test_calendar(); test_integral_scale(); test_ratio_scale(); } date-3.0.1/test/date_test/format/000077500000000000000000000000001403643451100166545ustar00rootroot00000000000000date-3.0.1/test/date_test/format/century.pass.cpp000066400000000000000000000063121403643451100220200ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "date.h" #include #include #include int main() { using namespace date; using namespace std::chrono; std::ostringstream os; os << format("%C", sys_days{jun/1/20001}); assert(os.str() == "200"); os.str(""); os << format("%C", sys_days{jun/1/20000}); assert(os.str() == "200"); os.str(""); os << format("%C", sys_days{jun/1/19999}); assert(os.str() == "199"); os.str(""); os << format("%C", sys_days{jun/1/2001}); assert(os.str() == "20"); os.str(""); os << format("%C", sys_days{jun/1/2000}); assert(os.str() == "20"); os.str(""); os << format("%C", sys_days{jun/1/1999}); assert(os.str() == "19"); os.str(""); os << format("%C", sys_days{jun/1/101}); assert(os.str() == "01"); os.str(""); os << format("%C", sys_days{jun/1/100}); assert(os.str() == "01"); os.str(""); os << format("%C", sys_days{jun/1/99}); assert(os.str() == "00"); os.str(""); os << format("%C", sys_days{jun/1/1}); assert(os.str() == "00"); os.str(""); os << format("%C", sys_days{jun/1/0}); assert(os.str() == "00"); os.str(""); os << format("%C", sys_days{jun/1/-1}); assert(os.str() == "-01"); os.str(""); os << format("%C", sys_days{jun/1/-99}); assert(os.str() == "-01"); os.str(""); os << format("%C", sys_days{jun/1/-100}); assert(os.str() == "-01"); os.str(""); os << format("%C", sys_days{jun/1/-101}); assert(os.str() == "-02"); os.str(""); os << format("%C", sys_days{jun/1/-1999}); assert(os.str() == "-20"); os.str(""); os << format("%C", sys_days{jun/1/-2000}); assert(os.str() == "-20"); os.str(""); os << format("%C", sys_days{jun/1/-2001}); assert(os.str() == "-21"); os.str(""); os << format("%C", sys_days{jun/1/-19999}); assert(os.str() == "-200"); os.str(""); os << format("%C", sys_days{jun/1/-20000}); assert(os.str() == "-200"); os.str(""); os << format("%C", sys_days{jun/1/-20001}); assert(os.str() == "-201"); } date-3.0.1/test/date_test/format/misc.pass.cpp000066400000000000000000000035611403643451100212650ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "date.h" #include #include template void test(const std::string& in_fmt, const std::string& input, const std::string& out_fmt, const std::string& output) { using namespace date; std::istringstream in{input}; T t; in >> parse(in_fmt, t); assert(!in.fail()); auto s = format(out_fmt, t); assert(s == output); } int main() { using namespace date; test("%Y", "2017", "%Y", "2017"); test("%m", "3", "%m", "03"); test("%d", "25", "%d", "25"); test("%Y-%m", "2017-03", "%Y-%m", "2017-03"); test("%y%m", "1703", "%Y-%m", "2017-03"); test("%m/%d", "3/25", "%m/%d", "03/25"); test("%w", "3", "%w", "3"); } date-3.0.1/test/date_test/format/range.pass.cpp000066400000000000000000000063511403643451100214260ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "date.h" #include #include #include using fortnights = std::chrono::duration, date::weeks::period>>; using microfortnights = std::chrono::duration>; int main() { using namespace date; using namespace std::chrono; std::ostringstream os; os << format("%F %T", sys_days{jan/1/year::min()}); assert(os.str() == "-32767-01-01 00:00:00"); os.str(""); os << format("%F %T", sys_days{dec/last/year::max()}); assert(os.str() == "32767-12-31 00:00:00"); os.str(""); os << format("%F %T", sys_days{dec/last/year::max()} + hours{23} + minutes{59} + seconds{59} + microseconds{999999}); assert(os.str() == "32767-12-31 23:59:59.999999"); os.str(""); os << format("%Y-%m-%d %H:%M:%S", sys_days{jan/1/year::min()}); assert(os.str() == "-32767-01-01 00:00:00"); os.str(""); os << format("%Y-%m-%d %H:%M:%S", sys_days{dec/last/year::max()}); assert(os.str() == "32767-12-31 00:00:00"); os.str(""); os << format("%Y-%m-%d %H:%M:%S", sys_days{dec/last/year::max()} + hours{23} + minutes{59} + seconds{59} + microseconds{999999}); assert(os.str() == "32767-12-31 23:59:59.999999"); os.str(""); os << format("%F %T", sys_days{jan/1/year::min()} + microfortnights{1}); assert(os.str() == "-32767-01-01 00:00:01.2096"); os.str(""); os << format("%F %T", sys_days{dec/last/year::max()} + microfortnights{1}); assert(os.str() == "32767-12-31 00:00:01.2096"); os.str(""); os << format("%F", jan/1/year::min()); assert(os.str() == "-32767-01-01"); os.str(""); os << format("%F", dec/last/year::max()); assert(os.str() == "32767-12-31"); os.str(""); } date-3.0.1/test/date_test/format/two_dight_year.pass.cpp000066400000000000000000000064361403643451100233460ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "date.h" #include #include #include int main() { using namespace date; using namespace std::chrono; std::ostringstream os; os << format("%y", sys_days{jun/1/20001}); assert(os.str() == "01"); os.str(""); os << format("%y", sys_days{jun/1/20000}); assert(os.str() == "00"); os.str(""); os << format("%y", sys_days{jun/1/19999}); assert(os.str() == "99"); os.str(""); os << format("%y", sys_days{jun/1/2001}); assert(os.str() == "01"); os.str(""); os << format("%y", sys_days{jun/1/2000}); assert(os.str() == "00"); os.str(""); os << format("%y", sys_days{jun/1/1999}); assert(os.str() == "99"); os.str(""); os << format("%y", sys_days{jun/1/101}); assert(os.str() == "01"); os.str(""); os << format("%y", sys_days{jun/1/100}); assert(os.str() == "00"); os.str(""); os << format("%y", sys_days{jun/1/99}); assert(os.str() == "99"); os.str(""); os << format("%y", sys_days{jun/1/1}); assert(os.str() == "01"); os.str(""); os << format("%y", sys_days{jun/1/0}); assert(os.str() == "00"); os.str(""); os << format("%y", sys_days{jun/1/-1}); assert(os.str() == "01"); os.str(""); os << format("%y", sys_days{jun/1/-99}); assert(os.str() == "99"); os.str(""); os << format("%y", sys_days{jun/1/-100}); assert(os.str() == "00"); os.str(""); os << format("%y", sys_days{jun/1/-101}); assert(os.str() == "01"); os.str(""); os << format("%y", sys_days{jun/1/-1999}); assert(os.str() == "99"); os.str(""); os << format("%y", sys_days{jun/1/-2000}); assert(os.str() == "00"); os.str(""); os << format("%y", sys_days{jun/1/-2001}); assert(os.str() == "01"); os.str(""); os << format("%y", sys_days{jun/1/-19999}); assert(os.str() == "99"); os.str(""); os << format("%y", sys_days{jun/1/-20000}); assert(os.str() == "00"); os.str(""); os << format("%y", sys_days{jun/1/-20001}); assert(os.str() == "01"); os.str(""); os << format("%y", sys_days{jun/1/year::min()}); assert(os.str() == "67"); } date-3.0.1/test/date_test/last.pass.cpp000066400000000000000000000024601403643451100200020ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // constexpr struct last_spec {} last{}; #include "date.h" #include static_assert(std::is_same{}, ""); int main() { } date-3.0.1/test/date_test/make_time.pass.cpp000066400000000000000000000061611403643451100207740ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // template ::value>::type> // constexpr // time_of_day> // make_time(std::chrono::duration d) noexcept; #include "date.h" #include #include int main() { using namespace date; using namespace std; using namespace std::chrono; { static_assert(is_same>{}, ""); auto tod = make_time(nanoseconds{18429000000022}); assert(tod.hours() == hours{5}); assert(tod.minutes() == minutes{7}); assert(tod.seconds() == seconds{9}); assert(tod.subseconds() == nanoseconds{22}); } { static_assert(is_same>{}, ""); auto tod = make_time(microseconds{18429000022}); assert(tod.hours() == hours{5}); assert(tod.minutes() == minutes{7}); assert(tod.seconds() == seconds{9}); assert(tod.subseconds() == microseconds{22}); } { static_assert(is_same>{}, ""); auto tod = make_time(seconds{18429}); assert(tod.hours() == hours{5}); assert(tod.minutes() == minutes{7}); assert(tod.seconds() == seconds{9}); } { static_assert(is_same>{}, ""); auto tod = make_time(minutes{307}); assert(tod.hours() == hours{5}); assert(tod.minutes() == minutes{7}); } { static_assert(is_same>{}, ""); auto tod = make_time(hours{5}); assert(tod.hours() == hours{5}); } } date-3.0.1/test/date_test/month.pass.cpp000066400000000000000000000143551403643451100201720ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class month // { // unsigned char m_; // public: // explicit constexpr month(unsigned m) noexcept; // // month& operator++() noexcept; // month operator++(int) noexcept; // month& operator--() noexcept; // month operator--(int) noexcept; // // month& operator+=(const months& m) noexcept; // month& operator-=(const months& m) noexcept; // // constexpr explicit operator unsigned() const noexcept; // constexpr bool ok() const noexcept; // }; // // constexpr bool operator==(const month& x, const month& y) noexcept; // constexpr bool operator!=(const month& x, const month& y) noexcept; // constexpr bool operator< (const month& x, const month& y) noexcept; // constexpr bool operator> (const month& x, const month& y) noexcept; // constexpr bool operator<=(const month& x, const month& y) noexcept; // constexpr bool operator>=(const month& x, const month& y) noexcept; // // constexpr month operator+(const month& x, const months& y) noexcept; // constexpr month operator+(const months& x, const month& y) noexcept; // constexpr month operator-(const month& x, const months& y) noexcept; // constexpr months operator-(const month& x, const month& y) noexcept; // // std::ostream& operator<<(std::ostream& os, const month& m); // constexpr month jan{1}; // constexpr month feb{2}; // constexpr month mar{3}; // constexpr month apr{4}; // constexpr month may{5}; // constexpr month jun{6}; // constexpr month jul{7}; // constexpr month aug{8}; // constexpr month sep{9}; // constexpr month oct{10}; // constexpr month nov{11}; // constexpr month dec{12}; #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert( std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert(static_cast(date::month{1}) == 1, ""); static_assert(!date::month{0}.ok(), ""); static_assert( date::month{1}.ok(), ""); static_assert( date::month{2}.ok(), ""); static_assert( date::month{3}.ok(), ""); static_assert( date::month{4}.ok(), ""); static_assert( date::month{5}.ok(), ""); static_assert( date::month{6}.ok(), ""); static_assert( date::month{7}.ok(), ""); static_assert( date::month{8}.ok(), ""); static_assert( date::month{9}.ok(), ""); static_assert( date::month{10}.ok(), ""); static_assert( date::month{11}.ok(), ""); static_assert( date::month{12}.ok(), ""); static_assert(!date::month{13}.ok(), ""); int main() { using namespace date; static_assert(jan == month{1}, ""); static_assert(feb == month{2}, ""); static_assert(mar == month{3}, ""); static_assert(apr == month{4}, ""); static_assert(may == month{5}, ""); static_assert(jun == month{6}, ""); static_assert(jul == month{7}, ""); static_assert(aug == month{8}, ""); static_assert(sep == month{9}, ""); static_assert(oct == month{10}, ""); static_assert(nov == month{11}, ""); static_assert(dec == month{12}, ""); static_assert(!(jan != jan), ""); static_assert( jan != feb, ""); static_assert( feb != jan, ""); static_assert(!(jan < jan), ""); static_assert( jan < feb, ""); static_assert(!(feb < jan), ""); static_assert( jan <= jan, ""); static_assert( jan <= feb, ""); static_assert(!(feb <= jan), ""); static_assert(!(jan > jan), ""); static_assert(!(jan > feb), ""); static_assert( feb > jan, ""); static_assert( jan >= jan, ""); static_assert(!(jan >= feb), ""); static_assert( feb >= jan, ""); assert(mar + months{7} == oct); assert(mar + months{27} == jun); assert(months{7} + mar == oct); assert(months{27} + mar == jun); assert(mar - months{7} == aug); assert(mar - months{27} == dec); assert(mar - feb == months{1}); assert(feb - mar == months{11}); #if __cplusplus >= 201402 static_assert(mar + months{7} == oct, ""); static_assert(mar + months{27} == jun, ""); static_assert(months{7} + mar == oct, ""); static_assert(months{27} + mar == jun, ""); static_assert(mar - months{7} == aug, ""); static_assert(mar - months{27} == dec, ""); static_assert(mar - feb == months{1}, ""); static_assert(feb - mar == months{11}, ""); #endif auto m = dec; assert(++m == jan); assert(m++ == jan); assert(m == feb); assert(m-- == feb); assert(m == jan); assert(--m == dec); assert((m += months{2}) == feb); assert((m -= months{2}) == dec); std::ostringstream os; os << m; assert(os.str() == "Dec"); m += months{11}; os.str(""); os << m; assert(os.str() == "Nov"); } date-3.0.1/test/date_test/month_day.pass.cpp000066400000000000000000000064201403643451100210210ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class month_day // { // public: // constexpr month_day(const date::month& m, const date::day& d) noexcept; // // constexpr date::month month() const noexcept; // constexpr date::day day() const noexcept; // // constexpr bool ok() const noexcept; // }; // constexpr bool operator==(const month_day& x, const month_day& y) noexcept; // constexpr bool operator!=(const month_day& x, const month_day& y) noexcept; // constexpr bool operator< (const month_day& x, const month_day& y) noexcept; // constexpr bool operator> (const month_day& x, const month_day& y) noexcept; // constexpr bool operator<=(const month_day& x, const month_day& y) noexcept; // constexpr bool operator>=(const month_day& x, const month_day& y) noexcept; // std::ostream& operator<<(std::ostream& os, const month_day& md); #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert( std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_nothrow_constructible{}, ""); int main() { using namespace date; constexpr month_day md1 = {feb, day{28}}; constexpr month_day md2 = {mar, day{1}}; #if __cplusplus >= 201402 static_assert(md1.ok(), ""); static_assert(md2.ok(), ""); static_assert(!month_day{feb, day{32}}.ok(), ""); static_assert(!month_day{month{0}, day{1}}.ok(), ""); #endif static_assert(md1.month() == feb, ""); static_assert(md1.day() == day{28}, ""); static_assert(md2.month() == mar, ""); static_assert(md2.day() == day{1}, ""); static_assert(md1 == md1, ""); static_assert(md1 != md2, ""); static_assert(md1 < md2, ""); std::ostringstream os; os << md1; assert(os.str() == "Feb/28"); } date-3.0.1/test/date_test/month_day_last.pass.cpp000066400000000000000000000062231403643451100220450ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class month_day_last // { // public: // constexpr explicit month_day_last(const date::month& m) noexcept; // // constexpr date::month month() const noexcept; // constexpr bool ok() const noexcept; // }; // constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept; // constexpr bool operator!=(const month_day_last& x, const month_day_last& y) noexcept; // constexpr bool operator< (const month_day_last& x, const month_day_last& y) noexcept; // constexpr bool operator> (const month_day_last& x, const month_day_last& y) noexcept; // constexpr bool operator<=(const month_day_last& x, const month_day_last& y) noexcept; // constexpr bool operator>=(const month_day_last& x, const month_day_last& y) noexcept; // std::ostream& operator<<(std::ostream& os, const month_day_last& mdl); #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); int main() { using namespace date; constexpr month_day_last mdl1{feb}; constexpr month_day_last mdl2{mar}; static_assert(mdl1.ok(), ""); static_assert(mdl2.ok(), ""); static_assert(!month_day_last{month{0}}.ok(), ""); static_assert(mdl1.month() == feb, ""); static_assert(mdl2.month() == mar, ""); static_assert(mdl1 == mdl1, ""); static_assert(mdl1 != mdl2, ""); static_assert(mdl1 < mdl2, ""); std::ostringstream os; os << mdl1; assert(os.str() == "Feb/last"); } date-3.0.1/test/date_test/month_weekday.pass.cpp000066400000000000000000000062101403643451100216720ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class month_weekday // { // public: // constexpr month_weekday(const date::month& m, // const date::weekday_indexed& wdi) noexcept; // // constexpr date::month month() const noexcept; // constexpr date::weekday_indexed weekday_indexed() const noexcept; // // constexpr bool ok() const noexcept; // }; // constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept; // constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept; // std::ostream& operator<<(std::ostream& os, const month_weekday& mwd); #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_nothrow_constructible{}, ""); int main() { using namespace date; constexpr month_weekday mwd1 = {feb, sat[4]}; constexpr month_weekday mwd2 = {mar, mon[1]}; static_assert(mwd1.ok(), ""); static_assert(mwd2.ok(), ""); static_assert(!month_weekday{feb, sat[0]}.ok(), ""); static_assert(!month_weekday{month{0}, sun[1]}.ok(), ""); static_assert(mwd1.month() == feb, ""); static_assert(mwd1.weekday_indexed() == sat[4], ""); static_assert(mwd2.month() == mar, ""); static_assert(mwd2.weekday_indexed() == mon[1], ""); static_assert(mwd1 == mwd1, ""); static_assert(mwd1 != mwd2, ""); std::ostringstream os; os << mwd1; assert(os.str() == "Feb/Sat[4]"); } date-3.0.1/test/date_test/month_weekday_last.pass.cpp000066400000000000000000000062151403643451100227220ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class month_weekday_last // { // public: // constexpr month_weekday_last(const date::month& m, // const date::weekday_last& wdl) noexcept; // // constexpr date::month month() const noexcept; // constexpr date::weekday_last weekday_last() const noexcept; // // constexpr bool ok() const noexcept; // }; // constexpr // bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept; // constexpr // bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept; // std::ostream& operator<<(std::ostream& os, const month_weekday_last& mwdl); #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_nothrow_constructible{}, ""); int main() { using namespace date; constexpr month_weekday_last mwdl1 = {feb, sat[last]}; constexpr month_weekday_last mwdl2 = {mar, mon[last]}; static_assert(mwdl1.ok(), ""); static_assert(mwdl2.ok(), ""); static_assert(!month_weekday_last{month{0}, sun[last]}.ok(), ""); static_assert(mwdl1.month() == feb, ""); static_assert(mwdl1.weekday_last() == sat[last], ""); static_assert(mwdl2.month() == mar, ""); static_assert(mwdl2.weekday_last() == mon[last], ""); static_assert(mwdl1 == mwdl1, ""); static_assert(mwdl1 != mwdl2, ""); std::ostringstream os; os << mwdl1; assert(os.str() == "Feb/Sat[last]"); } date-3.0.1/test/date_test/month_weekday_last_less.fail.cpp000066400000000000000000000025551403643451100237200ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // month_weekday_last < month_weekday_last not allowed #include "date.h" int main() { using namespace date; month_weekday_last mwdl1 = {feb, sat[last]}; month_weekday_last mwdl2 = {mar, mon[last]}; auto b = mwdl1 < mwdl2; } date-3.0.1/test/date_test/month_weekday_less.fail.cpp000066400000000000000000000025171403643451100226730ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // month_weekday < month_weekday not allowed #include "date.h" int main() { using namespace date; month_weekday mwd1 = {feb, sat[4]}; month_weekday mwd2 = {mar, mon[1]}; auto b = mwd1 < mwd2; } date-3.0.1/test/date_test/monthpmonth.fail.cpp000066400000000000000000000023551403643451100213620ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // month + month not allowed #include "date.h" int main() { using namespace date; auto x = mar + jul; } date-3.0.1/test/date_test/months_m_year_month.fail.cpp000066400000000000000000000024161403643451100230560ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // months - year_month not allowed #include "date.h" int main() { using namespace date; auto x = months{1} - year_month{2015_y, jan}; } date-3.0.1/test/date_test/months_m_year_month_day.fail.cpp000066400000000000000000000024251403643451100237130ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // months - year_month_day not allowed #include "date.h" int main() { using namespace date; auto x = jan - year_month_day{2015_y, aug, 9_d}; } date-3.0.1/test/date_test/monthsmmonth.fail.cpp000066400000000000000000000023641403643451100215420ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // months - month not allowed #include "date.h" int main() { using namespace date; auto x = months{3} - jul; } date-3.0.1/test/date_test/multi_year_duration_addition.pass.cpp000066400000000000000000000525311403643451100247750ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2018 Tomasz Kamiński // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "date.h" #include #include #include #define CPP11_ASSERT(...) static_assert(__VA_ARGS__, "") #if __cplusplus >= 201402 // C++14 # define CPP14_ASSERT(...) static_assert(__VA_ARGS__, "") #else // C++11 # define CPP14_ASSERT(...) assert(__VA_ARGS__) #endif #define NOEXCEPT_ASSERT(...) static_assert(noexcept(__VA_ARGS__), "") //Invocation involves a conversion between duration that is currently //not marked as noexcept. #define NOEXCEPT_CONVERSION(...) template constexpr T copy(T const& t) noexcept { return t; } struct ConvertibleToYears { CONSTCD11 operator date::years() const NOEXCEPT { return date::years{1}; }; }; struct ConvertibleToMonths { CONSTCD11 operator date::months() const NOEXCEPT { return date::months{1}; }; }; struct ConvertibleToYearsAndMonths { CONSTCD11 operator date::years() const NOEXCEPT { return date::years{1}; }; CONSTCD11 operator date::months() const NOEXCEPT { return date::months{1}; }; }; int main() { using namespace date; using namespace std::chrono; using decades = duration, years::period>>; using decamonths = duration, months::period>>; constexpr months one_month{1}; constexpr years one_year{1}; constexpr decades one_decade{1}; constexpr decamonths one_decamonth{1}; constexpr ConvertibleToMonths custom_month; constexpr ConvertibleToYears custom_year; constexpr ConvertibleToYearsAndMonths prefer_year; { constexpr year_month ym = 2001_y/feb; CPP14_ASSERT(ym + one_month == 2001_y/mar); NOEXCEPT_ASSERT(ym + one_month); CPP14_ASSERT(one_month + ym == 2001_y/mar); NOEXCEPT_ASSERT(one_month + ym); CPP14_ASSERT(ym - one_month == 2001_y/jan); NOEXCEPT_ASSERT(ym - one_month); CPP14_ASSERT((copy(ym) += one_month) == 2001_y/mar); NOEXCEPT_ASSERT(copy(ym) += one_month); CPP14_ASSERT((copy(ym) -= one_month) == 2001_y/jan); NOEXCEPT_ASSERT(copy(ym) -= one_month); CPP11_ASSERT(ym + one_year == 2002_y/feb); NOEXCEPT_ASSERT(ym + one_year); CPP11_ASSERT(one_year + ym == 2002_y/feb); NOEXCEPT_ASSERT(one_year + ym); CPP11_ASSERT(ym - one_year == 2000_y/feb); NOEXCEPT_ASSERT(ym - one_year); CPP14_ASSERT((copy(ym) += one_year) == 2002_y/feb); NOEXCEPT_ASSERT(copy(ym) += one_year); CPP14_ASSERT((copy(ym) -= one_year) == 2000_y/feb); NOEXCEPT_ASSERT(copy(ym) -= one_year); CPP11_ASSERT(ym + one_decade == 2011_y/feb); NOEXCEPT_CONVERSION(ym + one_decade); CPP11_ASSERT(one_decade + ym == 2011_y/feb); NOEXCEPT_CONVERSION(one_decade + ym); CPP11_ASSERT(ym - one_decade == 1991_y/feb); NOEXCEPT_CONVERSION(ym - one_decade); CPP14_ASSERT((copy(ym) += one_decade) == 2011_y/feb); NOEXCEPT_CONVERSION(copy(ym) += one_decade); CPP14_ASSERT((copy(ym) -= one_decade) == 1991_y/feb); NOEXCEPT_CONVERSION(copy(ym) -= one_decade); CPP14_ASSERT(ym + one_decamonth == 2001_y/dec); NOEXCEPT_CONVERSION(ym + one_decamonth); CPP14_ASSERT(one_decamonth + ym == 2001_y/dec); NOEXCEPT_CONVERSION(one_decamonth + ym); CPP14_ASSERT(ym - one_decamonth == 2000_y/apr); NOEXCEPT_CONVERSION(ym - one_decamonth); CPP14_ASSERT((copy(ym) += one_decamonth) == 2001_y/dec); NOEXCEPT_CONVERSION(copy(ym) += one_decamonth); CPP14_ASSERT((copy(ym) -= one_decamonth) == 2000_y/apr); NOEXCEPT_CONVERSION(copy(ym) -= one_decamonth); CPP14_ASSERT(ym + custom_month == 2001_y/mar); NOEXCEPT_ASSERT(ym + custom_month); CPP14_ASSERT(custom_month + ym == 2001_y/mar); NOEXCEPT_ASSERT(custom_month + ym); CPP14_ASSERT(ym - custom_month == 2001_y/jan); NOEXCEPT_ASSERT(ym - custom_month); CPP14_ASSERT((copy(ym) += custom_month) == 2001_y/mar); NOEXCEPT_ASSERT(copy(ym) += custom_month); CPP14_ASSERT((copy(ym) -= custom_month) == 2001_y/jan); NOEXCEPT_ASSERT(copy(ym) -= custom_month); CPP11_ASSERT(ym + custom_year == 2002_y/feb); NOEXCEPT_ASSERT(ym + custom_year); CPP11_ASSERT(custom_year + ym == 2002_y/feb); NOEXCEPT_ASSERT(custom_year + ym); CPP11_ASSERT(ym - custom_year == 2000_y/feb); NOEXCEPT_ASSERT(ym - custom_year); CPP14_ASSERT((copy(ym) += custom_year) == 2002_y/feb); NOEXCEPT_ASSERT(copy(ym) += custom_year); CPP14_ASSERT((copy(ym) -= custom_year) == 2000_y/feb); NOEXCEPT_ASSERT(copy(ym) -= custom_year); CPP11_ASSERT(ym + prefer_year == 2002_y/feb); NOEXCEPT_ASSERT(ym + prefer_year); CPP11_ASSERT(prefer_year + ym == 2002_y/feb); NOEXCEPT_ASSERT(prefer_year + ym); CPP11_ASSERT(ym - prefer_year == 2000_y/feb); NOEXCEPT_ASSERT(ym - prefer_year); CPP14_ASSERT((copy(ym) += prefer_year) == 2002_y/feb); NOEXCEPT_ASSERT(copy(ym) += prefer_year); CPP14_ASSERT((copy(ym) -= prefer_year) == 2000_y/feb); NOEXCEPT_ASSERT(copy(ym) -= prefer_year); } { constexpr year_month_day ym = 2001_y/feb/10; CPP14_ASSERT(ym + one_month == 2001_y/mar/10); NOEXCEPT_ASSERT(ym + one_month); CPP14_ASSERT(one_month + ym == 2001_y/mar/10); NOEXCEPT_ASSERT(one_month + ym); CPP14_ASSERT(ym - one_month == 2001_y/jan/10); NOEXCEPT_ASSERT(ym - one_month); CPP14_ASSERT((copy(ym) += one_month) == 2001_y/mar/10); NOEXCEPT_ASSERT(copy(ym) += one_month); CPP14_ASSERT((copy(ym) -= one_month) == 2001_y/jan/10); NOEXCEPT_ASSERT(copy(ym) -= one_month); CPP11_ASSERT(ym + one_year == 2002_y/feb/10); NOEXCEPT_ASSERT(ym + one_year); CPP11_ASSERT(one_year + ym == 2002_y/feb/10); NOEXCEPT_ASSERT(one_year + ym); CPP11_ASSERT(ym - one_year == 2000_y/feb/10); NOEXCEPT_ASSERT(ym - one_year); CPP14_ASSERT((copy(ym) += one_year) == 2002_y/feb/10); NOEXCEPT_ASSERT(copy(ym) += one_year); CPP14_ASSERT((copy(ym) -= one_year) == 2000_y/feb/10); NOEXCEPT_ASSERT(copy(ym) -= one_year); CPP11_ASSERT(ym + one_decade == 2011_y/feb/10); NOEXCEPT_CONVERSION(ym + one_decade); CPP11_ASSERT(one_decade + ym == 2011_y/feb/10); NOEXCEPT_CONVERSION(one_decade + ym); CPP11_ASSERT(ym - one_decade == 1991_y/feb/10); NOEXCEPT_CONVERSION(ym - one_decade); CPP14_ASSERT((copy(ym) += one_decade) == 2011_y/feb/10); NOEXCEPT_CONVERSION(copy(ym) += one_decade); CPP14_ASSERT((copy(ym) -= one_decade) == 1991_y/feb/10); NOEXCEPT_CONVERSION(copy(ym) -= one_decade); CPP14_ASSERT(ym + one_decamonth == 2001_y/dec/10); NOEXCEPT_CONVERSION(ym + one_decamonth); CPP14_ASSERT(one_decamonth + ym == 2001_y/dec/10); NOEXCEPT_CONVERSION(one_decamonth + ym); CPP14_ASSERT(ym - one_decamonth == 2000_y/apr/10); NOEXCEPT_CONVERSION(ym - one_decamonth); CPP14_ASSERT((copy(ym) += one_decamonth) == 2001_y/dec/10); NOEXCEPT_CONVERSION(copy(ym) += one_decamonth); CPP14_ASSERT((copy(ym) -= one_decamonth) == 2000_y/apr/10); NOEXCEPT_CONVERSION(copy(ym) -= one_decamonth); CPP14_ASSERT(ym + custom_month == 2001_y/mar/10); NOEXCEPT_ASSERT(ym + custom_month); CPP14_ASSERT(custom_month + ym == 2001_y/mar/10); NOEXCEPT_ASSERT(custom_month + ym); CPP14_ASSERT(ym - custom_month == 2001_y/jan/10); NOEXCEPT_ASSERT(ym - custom_month); CPP14_ASSERT((copy(ym) += custom_month) == 2001_y/mar/10); NOEXCEPT_ASSERT(copy(ym) += custom_month); CPP14_ASSERT((copy(ym) -= custom_month) == 2001_y/jan/10); NOEXCEPT_ASSERT(copy(ym) -= custom_month); CPP11_ASSERT(ym + custom_year == 2002_y/feb/10); NOEXCEPT_ASSERT(ym + custom_year); CPP11_ASSERT(custom_year + ym == 2002_y/feb/10); NOEXCEPT_ASSERT(custom_year + ym); CPP11_ASSERT(ym - custom_year == 2000_y/feb/10); NOEXCEPT_ASSERT(ym - custom_year); CPP14_ASSERT((copy(ym) += custom_year) == 2002_y/feb/10); NOEXCEPT_ASSERT(copy(ym) += custom_year); CPP14_ASSERT((copy(ym) -= custom_year) == 2000_y/feb/10); NOEXCEPT_ASSERT(copy(ym) -= custom_year); CPP11_ASSERT(ym + prefer_year == 2002_y/feb/10); NOEXCEPT_ASSERT(ym + prefer_year); CPP11_ASSERT(prefer_year + ym == 2002_y/feb/10); NOEXCEPT_ASSERT(prefer_year + ym); CPP11_ASSERT(ym - prefer_year == 2000_y/feb/10); NOEXCEPT_ASSERT(ym - prefer_year); CPP14_ASSERT((copy(ym) += prefer_year) == 2002_y/feb/10); NOEXCEPT_ASSERT(copy(ym) += prefer_year); CPP14_ASSERT((copy(ym) -= prefer_year) == 2000_y/feb/10); NOEXCEPT_ASSERT(copy(ym) -= prefer_year); } { constexpr year_month_day_last ym = 2001_y/feb/last; CPP14_ASSERT(ym + one_month == 2001_y/mar/last); NOEXCEPT_ASSERT(ym + one_month); CPP14_ASSERT(one_month + ym == 2001_y/mar/last); NOEXCEPT_ASSERT(one_month + ym); CPP14_ASSERT(ym - one_month == 2001_y/jan/last); NOEXCEPT_ASSERT(ym - one_month); CPP14_ASSERT((copy(ym) += one_month) == 2001_y/mar/last); NOEXCEPT_ASSERT(copy(ym) += one_month); CPP14_ASSERT((copy(ym) -= one_month) == 2001_y/jan/last); NOEXCEPT_ASSERT(copy(ym) -= one_month); CPP11_ASSERT(ym + one_year == 2002_y/feb/last); NOEXCEPT_ASSERT(ym + one_year); CPP11_ASSERT(one_year + ym == 2002_y/feb/last); NOEXCEPT_ASSERT(one_year + ym); CPP11_ASSERT(ym - one_year == 2000_y/feb/last); NOEXCEPT_ASSERT(ym - one_year); CPP14_ASSERT((copy(ym) += one_year) == 2002_y/feb/last); NOEXCEPT_ASSERT(copy(ym) += one_year); CPP14_ASSERT((copy(ym) -= one_year) == 2000_y/feb/last); NOEXCEPT_ASSERT(copy(ym) -= one_year); CPP11_ASSERT(ym + one_decade == 2011_y/feb/last); NOEXCEPT_CONVERSION(ym + one_decade); CPP11_ASSERT(one_decade + ym == 2011_y/feb/last); NOEXCEPT_CONVERSION(one_decade + ym); CPP11_ASSERT(ym - one_decade == 1991_y/feb/last); NOEXCEPT_CONVERSION(ym - one_decade); CPP14_ASSERT((copy(ym) += one_decade) == 2011_y/feb/last); NOEXCEPT_CONVERSION(copy(ym) += one_decade); CPP14_ASSERT((copy(ym) -= one_decade) == 1991_y/feb/last); NOEXCEPT_CONVERSION(copy(ym) -= one_decade); CPP14_ASSERT(ym + one_decamonth == 2001_y/dec/last); NOEXCEPT_CONVERSION(ym + one_decamonth); CPP14_ASSERT(one_decamonth + ym == 2001_y/dec/last); NOEXCEPT_CONVERSION(one_decamonth + ym); CPP14_ASSERT(ym - one_decamonth == 2000_y/apr/last); NOEXCEPT_CONVERSION(ym - one_decamonth); CPP14_ASSERT((copy(ym) += one_decamonth) == 2001_y/dec/last); NOEXCEPT_CONVERSION(copy(ym) += one_decamonth); CPP14_ASSERT((copy(ym) -= one_decamonth) == 2000_y/apr/last); NOEXCEPT_CONVERSION(copy(ym) -= one_decamonth); CPP14_ASSERT(ym + custom_month == 2001_y/mar/last); NOEXCEPT_ASSERT(ym + custom_month); CPP14_ASSERT(custom_month + ym == 2001_y/mar/last); NOEXCEPT_ASSERT(custom_month + ym); CPP14_ASSERT(ym - custom_month == 2001_y/jan/last); NOEXCEPT_ASSERT(ym - custom_month); CPP14_ASSERT((copy(ym) += custom_month) == 2001_y/mar/last); NOEXCEPT_ASSERT(copy(ym) += custom_month); CPP14_ASSERT((copy(ym) -= custom_month) == 2001_y/jan/last); NOEXCEPT_ASSERT(copy(ym) -= custom_month); CPP11_ASSERT(ym + custom_year == 2002_y/feb/last); NOEXCEPT_ASSERT(ym + custom_year); CPP11_ASSERT(custom_year + ym == 2002_y/feb/last); NOEXCEPT_ASSERT(custom_year + ym); CPP11_ASSERT(ym - custom_year == 2000_y/feb/last); NOEXCEPT_ASSERT(ym - custom_year); CPP14_ASSERT((copy(ym) += custom_year) == 2002_y/feb/last); NOEXCEPT_ASSERT(copy(ym) += custom_year); CPP14_ASSERT((copy(ym) -= custom_year) == 2000_y/feb/last); NOEXCEPT_ASSERT(copy(ym) -= custom_year); CPP11_ASSERT(ym + prefer_year == 2002_y/feb/last); NOEXCEPT_ASSERT(ym + prefer_year); CPP11_ASSERT(prefer_year + ym == 2002_y/feb/last); NOEXCEPT_ASSERT(prefer_year + ym); CPP11_ASSERT(ym - prefer_year == 2000_y/feb/last); NOEXCEPT_ASSERT(ym - prefer_year); CPP14_ASSERT((copy(ym) += prefer_year) == 2002_y/feb/last); NOEXCEPT_ASSERT(copy(ym) += prefer_year); CPP14_ASSERT((copy(ym) -= prefer_year) == 2000_y/feb/last); NOEXCEPT_ASSERT(copy(ym) -= prefer_year); } { constexpr year_month_weekday ym = 2001_y/feb/fri[4]; CPP14_ASSERT(ym + one_month == 2001_y/mar/fri[4]); NOEXCEPT_ASSERT(ym + one_month); CPP14_ASSERT(one_month + ym == 2001_y/mar/fri[4]); NOEXCEPT_ASSERT(one_month + ym); CPP14_ASSERT(ym - one_month == 2001_y/jan/fri[4]); NOEXCEPT_ASSERT(ym - one_month); CPP14_ASSERT((copy(ym) += one_month) == 2001_y/mar/fri[4]); NOEXCEPT_ASSERT(copy(ym) += one_month); CPP14_ASSERT((copy(ym) -= one_month) == 2001_y/jan/fri[4]); NOEXCEPT_ASSERT(copy(ym) -= one_month); CPP11_ASSERT(ym + one_year == 2002_y/feb/fri[4]); NOEXCEPT_ASSERT(ym + one_year); CPP11_ASSERT(one_year + ym == 2002_y/feb/fri[4]); NOEXCEPT_ASSERT(one_year + ym); CPP11_ASSERT(ym - one_year == 2000_y/feb/fri[4]); NOEXCEPT_ASSERT(ym - one_year); CPP14_ASSERT((copy(ym) += one_year) == 2002_y/feb/fri[4]); NOEXCEPT_ASSERT(copy(ym) += one_year); CPP14_ASSERT((copy(ym) -= one_year) == 2000_y/feb/fri[4]); NOEXCEPT_ASSERT(copy(ym) -= one_year); CPP11_ASSERT(ym + one_decade == 2011_y/feb/fri[4]); NOEXCEPT_CONVERSION(ym + one_decade); CPP11_ASSERT(one_decade + ym == 2011_y/feb/fri[4]); NOEXCEPT_CONVERSION(one_decade + ym); CPP11_ASSERT(ym - one_decade == 1991_y/feb/fri[4]); NOEXCEPT_CONVERSION(ym - one_decade); CPP14_ASSERT((copy(ym) += one_decade) == 2011_y/feb/fri[4]); NOEXCEPT_CONVERSION(copy(ym) += one_decade); CPP14_ASSERT((copy(ym) -= one_decade) == 1991_y/feb/fri[4]); NOEXCEPT_CONVERSION(copy(ym) -= one_decade); CPP14_ASSERT(ym + one_decamonth == 2001_y/dec/fri[4]); NOEXCEPT_CONVERSION(ym + one_decamonth); CPP14_ASSERT(one_decamonth + ym == 2001_y/dec/fri[4]); NOEXCEPT_CONVERSION(one_decamonth + ym); CPP14_ASSERT(ym - one_decamonth == 2000_y/apr/fri[4]); NOEXCEPT_CONVERSION(ym - one_decamonth); CPP14_ASSERT((copy(ym) += one_decamonth) == 2001_y/dec/fri[4]); NOEXCEPT_CONVERSION(copy(ym) += one_decamonth); CPP14_ASSERT((copy(ym) -= one_decamonth) == 2000_y/apr/fri[4]); NOEXCEPT_CONVERSION(copy(ym) -= one_decamonth); CPP14_ASSERT(ym + custom_month == 2001_y/mar/fri[4]); NOEXCEPT_ASSERT(ym + custom_month); CPP14_ASSERT(custom_month + ym == 2001_y/mar/fri[4]); NOEXCEPT_ASSERT(custom_month + ym); CPP14_ASSERT(ym - custom_month == 2001_y/jan/fri[4]); NOEXCEPT_ASSERT(ym - custom_month); CPP14_ASSERT((copy(ym) += custom_month) == 2001_y/mar/fri[4]); NOEXCEPT_ASSERT(copy(ym) += custom_month); CPP14_ASSERT((copy(ym) -= custom_month) == 2001_y/jan/fri[4]); NOEXCEPT_ASSERT(copy(ym) -= custom_month); CPP11_ASSERT(ym + custom_year == 2002_y/feb/fri[4]); NOEXCEPT_ASSERT(ym + custom_year); CPP11_ASSERT(custom_year + ym == 2002_y/feb/fri[4]); NOEXCEPT_ASSERT(custom_year + ym); CPP11_ASSERT(ym - custom_year == 2000_y/feb/fri[4]); NOEXCEPT_ASSERT(ym - custom_year); CPP14_ASSERT((copy(ym) += custom_year) == 2002_y/feb/fri[4]); NOEXCEPT_ASSERT(copy(ym) += custom_year); CPP14_ASSERT((copy(ym) -= custom_year) == 2000_y/feb/fri[4]); NOEXCEPT_ASSERT(copy(ym) -= custom_year); CPP11_ASSERT(ym + prefer_year == 2002_y/feb/fri[4]); NOEXCEPT_ASSERT(ym + prefer_year); CPP11_ASSERT(prefer_year + ym == 2002_y/feb/fri[4]); NOEXCEPT_ASSERT(prefer_year + ym); CPP11_ASSERT(ym - prefer_year == 2000_y/feb/fri[4]); NOEXCEPT_ASSERT(ym - prefer_year); CPP14_ASSERT((copy(ym) += prefer_year) == 2002_y/feb/fri[4]); NOEXCEPT_ASSERT(copy(ym) += prefer_year); CPP14_ASSERT((copy(ym) -= prefer_year) == 2000_y/feb/fri[4]); NOEXCEPT_ASSERT(copy(ym) -= prefer_year); } { constexpr year_month_weekday_last ym = 2001_y/feb/fri[last]; CPP14_ASSERT(ym + one_month == 2001_y/mar/fri[last]); NOEXCEPT_ASSERT(ym + one_month); CPP14_ASSERT(one_month + ym == 2001_y/mar/fri[last]); NOEXCEPT_ASSERT(one_month + ym); CPP14_ASSERT(ym - one_month == 2001_y/jan/fri[last]); NOEXCEPT_ASSERT(ym - one_month); CPP14_ASSERT((copy(ym) += one_month) == 2001_y/mar/fri[last]); NOEXCEPT_ASSERT(copy(ym) += one_month); CPP14_ASSERT((copy(ym) -= one_month) == 2001_y/jan/fri[last]); NOEXCEPT_ASSERT(copy(ym) -= one_month); CPP11_ASSERT(ym + one_year == 2002_y/feb/fri[last]); NOEXCEPT_ASSERT(ym + one_year); CPP11_ASSERT(one_year + ym == 2002_y/feb/fri[last]); NOEXCEPT_ASSERT(one_year + ym); CPP11_ASSERT(ym - one_year == 2000_y/feb/fri[last]); NOEXCEPT_ASSERT(ym - one_year); CPP14_ASSERT((copy(ym) += one_year) == 2002_y/feb/fri[last]); NOEXCEPT_ASSERT(copy(ym) += one_year); CPP14_ASSERT((copy(ym) -= one_year) == 2000_y/feb/fri[last]); NOEXCEPT_ASSERT(copy(ym) -= one_year); CPP11_ASSERT(ym + one_decade == 2011_y/feb/fri[last]); NOEXCEPT_CONVERSION(ym + one_decade); CPP11_ASSERT(one_decade + ym == 2011_y/feb/fri[last]); NOEXCEPT_CONVERSION(one_decade + ym); CPP11_ASSERT(ym - one_decade == 1991_y/feb/fri[last]); NOEXCEPT_CONVERSION(ym - one_decade); CPP14_ASSERT((copy(ym) += one_decade) == 2011_y/feb/fri[last]); NOEXCEPT_CONVERSION(copy(ym) += one_decade); CPP14_ASSERT((copy(ym) -= one_decade) == 1991_y/feb/fri[last]); NOEXCEPT_CONVERSION(copy(ym) -= one_decade); CPP14_ASSERT(ym + one_decamonth == 2001_y/dec/fri[last]); NOEXCEPT_CONVERSION(ym + one_decamonth); CPP14_ASSERT(one_decamonth + ym == 2001_y/dec/fri[last]); NOEXCEPT_CONVERSION(one_decamonth + ym); CPP14_ASSERT(ym - one_decamonth == 2000_y/apr/fri[last]); NOEXCEPT_CONVERSION(ym - one_decamonth); CPP14_ASSERT((copy(ym) += one_decamonth) == 2001_y/dec/fri[last]); NOEXCEPT_CONVERSION(copy(ym) += one_decamonth); CPP14_ASSERT((copy(ym) -= one_decamonth) == 2000_y/apr/fri[last]); NOEXCEPT_CONVERSION(copy(ym) -= one_decamonth); CPP14_ASSERT(ym + custom_month == 2001_y/mar/fri[last]); NOEXCEPT_ASSERT(ym + custom_month); CPP14_ASSERT(custom_month + ym == 2001_y/mar/fri[last]); NOEXCEPT_ASSERT(custom_month + ym); CPP14_ASSERT(ym - custom_month == 2001_y/jan/fri[last]); NOEXCEPT_ASSERT(ym - custom_month); CPP14_ASSERT((copy(ym) += custom_month) == 2001_y/mar/fri[last]); NOEXCEPT_ASSERT(copy(ym) += custom_month); CPP14_ASSERT((copy(ym) -= custom_month) == 2001_y/jan/fri[last]); NOEXCEPT_ASSERT(copy(ym) -= custom_month); CPP11_ASSERT(ym + custom_year == 2002_y/feb/fri[last]); NOEXCEPT_ASSERT(ym + custom_year); CPP11_ASSERT(custom_year + ym == 2002_y/feb/fri[last]); NOEXCEPT_ASSERT(custom_year + ym); CPP11_ASSERT(ym - custom_year == 2000_y/feb/fri[last]); NOEXCEPT_ASSERT(ym - custom_year); CPP14_ASSERT((copy(ym) += custom_year) == 2002_y/feb/fri[last]); NOEXCEPT_ASSERT(copy(ym) += custom_year); CPP14_ASSERT((copy(ym) -= custom_year) == 2000_y/feb/fri[last]); NOEXCEPT_ASSERT(copy(ym) -= custom_year); CPP11_ASSERT(ym + prefer_year == 2002_y/feb/fri[last]); NOEXCEPT_ASSERT(ym + prefer_year); CPP11_ASSERT(prefer_year + ym == 2002_y/feb/fri[last]); NOEXCEPT_ASSERT(prefer_year + ym); CPP11_ASSERT(ym - prefer_year == 2000_y/feb/fri[last]); NOEXCEPT_ASSERT(ym - prefer_year); CPP14_ASSERT((copy(ym) += prefer_year) == 2002_y/feb/fri[last]); NOEXCEPT_ASSERT(copy(ym) += prefer_year); CPP14_ASSERT((copy(ym) -= prefer_year) == 2000_y/feb/fri[last]); NOEXCEPT_ASSERT(copy(ym) -= prefer_year); } } date-3.0.1/test/date_test/op_div_day_day.fail.cpp000066400000000000000000000023521403643451100217560ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // day / day not allowed #include "date.h" int main() { using namespace date; auto x = 14_d/14_d; } date-3.0.1/test/date_test/op_div_int_month.fail.cpp000066400000000000000000000023501403643451100223410ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // int / month not allowed #include "date.h" int main() { using namespace date; auto x = 8/aug; } date-3.0.1/test/date_test/op_div_int_year.fail.cpp000066400000000000000000000023521403643451100221560ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // int / year not allowed #include "date.h" int main() { using namespace date; auto x = 8/2015_y; } date-3.0.1/test/date_test/op_div_last_last.fail.cpp000066400000000000000000000023541403643451100223340ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // last / last not allowed #include "date.h" int main() { using namespace date; auto x = last/last; } date-3.0.1/test/date_test/op_div_month_day.pass.cpp000066400000000000000000000035331403643451100223630ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // constexpr month_day operator/(const month& m, const day& d) noexcept; // constexpr month_day operator/(const month& m, int d) noexcept; // constexpr month_day operator/(int m, const day& d) noexcept; // constexpr month_day operator/(const day& d, const month& m) noexcept; // constexpr month_day operator/(const day& d, int m) noexcept; #include "date.h" int main() { using namespace date; static_assert( aug/14_d == month_day{month{8}, day{14}}, ""); static_assert( aug/14 == month_day{month{8}, day{14}}, ""); static_assert( 8/14_d == month_day{month{8}, day{14}}, ""); static_assert(14_d/aug == month_day{month{8}, day{14}}, ""); static_assert(14_d/8 == month_day{month{8}, day{14}}, ""); } date-3.0.1/test/date_test/op_div_month_day_last.pass.cpp000066400000000000000000000033171403643451100234060ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // constexpr month_day_last operator/(const month& m, last_spec) noexcept; // constexpr month_day_last operator/(int m, last_spec) noexcept; // constexpr month_day_last operator/(last_spec, const month& m) noexcept; // constexpr month_day_last operator/(last_spec, int m) noexcept; #include "date.h" int main() { using namespace date; static_assert( aug/last == month_day_last{month{8}}, ""); static_assert( 8/last == month_day_last{month{8}}, ""); static_assert(last/aug == month_day_last{month{8}}, ""); static_assert(last/8 == month_day_last{month{8}}, ""); } date-3.0.1/test/date_test/op_div_month_day_month_day.fail.cpp000066400000000000000000000024021403643451100243640ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // month_day / month_day not allowed #include "date.h" int main() { using namespace date; auto x = (aug/14_d)/(aug/14_d); } date-3.0.1/test/date_test/op_div_month_month.fail.cpp000066400000000000000000000023541403643451100227000ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // month / month not allowed #include "date.h" int main() { using namespace date; auto x = aug/aug; } date-3.0.1/test/date_test/op_div_month_weekday.pass.cpp000066400000000000000000000036371403643451100232440ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // constexpr month_weekday operator/(const month& m, const weekday_indexed& wdi) noexcept; // constexpr month_weekday operator/(int m, const weekday_indexed& wdi) noexcept; // constexpr month_weekday operator/(const weekday_indexed& wdi, const month& m) noexcept; // constexpr month_weekday operator/(const weekday_indexed& wdi, int m) noexcept; #include "date.h" int main() { using namespace date; static_assert( aug/fri[2] == month_weekday{month{8}, weekday_indexed{weekday{5u}, 2}}, ""); static_assert( 8/fri[2] == month_weekday{month{8}, weekday_indexed{weekday{5u}, 2}}, ""); static_assert(fri[2]/aug == month_weekday{month{8}, weekday_indexed{weekday{5u}, 2}}, ""); static_assert(fri[2]/8 == month_weekday{month{8}, weekday_indexed{weekday{5u}, 2}}, ""); } date-3.0.1/test/date_test/op_div_month_weekday_last.pass.cpp000066400000000000000000000036731403643451100242670ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // constexpr month_weekday_last operator/(const month& m, const weekday_last& wdl) noexcept; // constexpr month_weekday_last operator/(int m, const weekday_last& wdl) noexcept; // constexpr month_weekday_last operator/(const weekday_last& wdl, const month& m) noexcept; // constexpr month_weekday_last operator/(const weekday_last& wdl, int m) noexcept; #include "date.h" int main() { using namespace date; static_assert( aug/fri[last] == month_weekday_last{month{8}, weekday_last{weekday{5u}}}, ""); static_assert( 8/fri[last] == month_weekday_last{month{8}, weekday_last{weekday{5u}}}, ""); static_assert(fri[last]/aug == month_weekday_last{month{8}, weekday_last{weekday{5u}}}, ""); static_assert(fri[last]/8 == month_weekday_last{month{8}, weekday_last{weekday{5u}}}, ""); } date-3.0.1/test/date_test/op_div_month_year.fail.cpp000066400000000000000000000023561403643451100225150ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // month / year not allowed #include "date.h" int main() { using namespace date; auto x = aug/2015_y; } date-3.0.1/test/date_test/op_div_survey.pass.cpp000066400000000000000000000775561403643451100217560ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "date.h" #include template constexpr auto test(I i, J j, K k) -> decltype(i/j/k) { return i/j/k; } void test(...) { } int main() { using std::is_same; using namespace date; static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); } date-3.0.1/test/date_test/op_div_weekday_indexed_weekday_indexed.fail.cpp000066400000000000000000000024061403643451100267060ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // weekday_indexed / weekday_indexed not allowed #include "date.h" int main() { using namespace date; auto x = fri[2]/fri[2]; } date-3.0.1/test/date_test/op_div_weekday_last_weekday_last.fail.cpp000066400000000000000000000024061403643451100255540ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // weekday_last / weekday_last not allowed #include "date.h" int main() { using namespace date; auto x = fri[last]/fri[last]; } date-3.0.1/test/date_test/op_div_year_month.pass.cpp000066400000000000000000000027141403643451100225460ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // constexpr year_month operator/(const year& y, const month& m) noexcept; // constexpr year_month operator/(const year& y, int m) noexcept; #include "date.h" int main() { using namespace date; static_assert(2015_y/aug == year_month{year{2015}, aug}, ""); static_assert(2015_y/8 == year_month{year{2015}, aug}, ""); } date-3.0.1/test/date_test/op_div_year_month_day.pass.cpp000066400000000000000000000043121403643451100233770ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // constexpr year_month_day operator/(const year_month& ym, const day& d) noexcept; // constexpr year_month_day operator/(const year_month& ym, int d) noexcept; // constexpr year_month_day operator/(const year& y, const month_day& md) noexcept; // constexpr year_month_day operator/(int y, const month_day& md) noexcept; // constexpr year_month_day operator/(const month_day& md, const year& y) noexcept; // constexpr year_month_day operator/(const month_day& md, int y) noexcept; #include "date.h" int main() { using namespace date; static_assert( 2015_y/aug/14_d == year_month_day{year{2015}, month{8}, day{14}}, ""); static_assert( 2015_y/aug/14 == year_month_day{year{2015}, month{8}, day{14}}, ""); static_assert( 2015_y/(aug/14_d) == year_month_day{year{2015}, month{8}, day{14}}, ""); static_assert( 2015/(aug/14_d) == year_month_day{year{2015}, month{8}, day{14}}, ""); static_assert(aug/14_d/2015_y == year_month_day{year{2015}, month{8}, day{14}}, ""); static_assert(aug/14_d/2015 == year_month_day{year{2015}, month{8}, day{14}}, ""); } date-3.0.1/test/date_test/op_div_year_month_day_last.pass.cpp000066400000000000000000000042221403643451100244220ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // constexpr year_month_day_last operator/(const year_month& ym, last_spec) noexcept; // constexpr year_month_day_last operator/(const year& y, const month_day_last& mdl) noexcept; // constexpr year_month_day_last operator/(int y, const month_day_last& mdl) noexcept; // constexpr year_month_day_last operator/(const month_day_last& mdl, const year& y) noexcept; // constexpr year_month_day_last operator/(const month_day_last& mdl, int y) noexcept; #include "date.h" int main() { using namespace date; static_assert(2015_y/aug/last == year_month_day_last{year{2015}, month_day_last{month{8}}}, ""); static_assert( 2015_y/(aug/last) == year_month_day_last{year{2015}, month_day_last{month{8}}}, ""); static_assert( 2015/(aug/last) == year_month_day_last{year{2015}, month_day_last{month{8}}}, ""); static_assert( aug/last/2015_y == year_month_day_last{year{2015}, month_day_last{month{8}}}, ""); static_assert( aug/last/2015 == year_month_day_last{year{2015}, month_day_last{month{8}}}, ""); } date-3.0.1/test/date_test/op_div_year_month_weekday.pass.cpp000066400000000000000000000044501403643451100242560ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // constexpr year_month_weekday operator/(const year_month& ym, const weekday_indexed& wdi) noexcept; // constexpr year_month_weekday operator/(const year& y, const month_weekday& mwd) noexcept; // constexpr year_month_weekday operator/(int y, const month_weekday& mwd) noexcept; // constexpr year_month_weekday operator/(const month_weekday& mwd, const year& y) noexcept; // constexpr year_month_weekday operator/(const month_weekday& mwd, int y) noexcept; #include "date.h" int main() { using namespace date; static_assert(2015_y/aug/fri[2] == year_month_weekday{year{2015}, month{8}, weekday_indexed{weekday{5u}, 2}}, ""); static_assert( 2015_y/(aug/fri[2]) == year_month_weekday{year{2015}, month{8}, weekday_indexed{weekday{5u}, 2}}, ""); static_assert( 2015/(aug/fri[2]) == year_month_weekday{year{2015}, month{8}, weekday_indexed{weekday{5u}, 2}}, ""); static_assert(aug/fri[2]/2015_y == year_month_weekday{year{2015}, month{8}, weekday_indexed{weekday{5u}, 2}}, ""); static_assert(aug/fri[2]/2015 == year_month_weekday{year{2015}, month{8}, weekday_indexed{weekday{5u}, 2}}, ""); } date-3.0.1/test/date_test/op_div_year_month_weekday_last.pass.cpp000066400000000000000000000044731403643451100253060ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // constexpr year_month_weekday_last operator/(const year_month& ym, const weekday_last& wdl) noexcept; // constexpr year_month_weekday_last operator/(const year& y, const month_weekday_last& mwdl) noexcept; // constexpr year_month_weekday_last operator/(int y, const month_weekday_last& mwdl) noexcept; // constexpr year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) noexcept; // constexpr year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) noexcept; #include "date.h" int main() { using namespace date; static_assert( 2015_y/aug/fri[last] == year_month_weekday_last{year{2015}, month{8}, weekday_last{weekday{5u}}}, ""); static_assert( 2015_y/(aug/fri[last]) == year_month_weekday_last{year{2015}, month{8}, weekday_last{weekday{5u}}}, ""); static_assert( 2015/(aug/fri[last]) == year_month_weekday_last{year{2015}, month{8}, weekday_last{weekday{5u}}}, ""); static_assert(aug/fri[last]/2015_y == year_month_weekday_last{year{2015}, month{8}, weekday_last{weekday{5u}}}, ""); static_assert(aug/fri[last]/2015 == year_month_weekday_last{year{2015}, month{8}, weekday_last{weekday{5u}}}, ""); } date-3.0.1/test/date_test/op_div_year_month_year_month.fail.cpp000066400000000000000000000024101403643451100247310ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // year_month / year_month not allowed #include "date.h" int main() { using namespace date; auto x = (2015_y/aug)/(2015_y/aug); } date-3.0.1/test/date_test/op_div_year_year.fail.cpp000066400000000000000000000023601403643451100223230ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // year / year not allowed #include "date.h" int main() { using namespace date; auto x = 2015_y/2015_y; } date-3.0.1/test/date_test/parse.pass.cpp000066400000000000000000000534451403643451100201620ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // This test is meant to maintain a record of the sizeof each type. #include "date.h" #include #include void test_a() { using namespace date; { // correct abbreviation std::istringstream in{"Sun 2016-12-11"}; sys_days tp; in >> parse("%a %F", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct abbreviation std::istringstream in{"Sun 2016-12-11"}; sys_days tp; in >> parse("%A %F", tp); // this may fail with libstdc++, see https://github.com/HowardHinnant/date/issues/388 // possible workaround: compile date.h with -DONLY_C_LOCALE=1 assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct full name std::istringstream in{"Sunday 2016-12-11"}; sys_days tp; in >> parse("%a %F", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct full name std::istringstream in{"Sunday 2016-12-11"}; sys_days tp; in >> parse("%A %F", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // not a valid name std::istringstream in{"Dec 2016-12-11"}; sys_days tp; in >> parse("%a %F", tp); assert( in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 1970_y/1/1); } { // wrong name std::istringstream in{"Sat 2016-12-11"}; sys_days tp; in >> parse("%a %F", tp); assert( in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 1970_y/1/1); } { // extra ws in input std::istringstream in{"Sun 2016-12-11"}; sys_days tp; in >> parse("%a %F", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // extra ws in format std::istringstream in{"Sun 2016-12-11"}; sys_days tp; in >> parse("%a %F", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } } void test_b() { using namespace date; { // correct abbreviation std::istringstream in{"Dec 11 2016"}; sys_days tp; in >> parse("%b %d %Y", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct abbreviation std::istringstream in{"Dec 11 2016"}; sys_days tp; in >> parse("%B %d %Y", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct abbreviation std::istringstream in{"Dec 11 2016"}; sys_days tp; in >> parse("%h %d %Y", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct full name std::istringstream in{"December 11 2016"}; sys_days tp; in >> parse("%b %d %Y", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct full name std::istringstream in{"December 11 2016"}; sys_days tp; in >> parse("%B %d %Y", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct full name std::istringstream in{"December 11 2016"}; sys_days tp; in >> parse("%h %d %Y", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // incorrect abbreviation std::istringstream in{"Dece 11 2016"}; sys_days tp; in >> parse("%b %d %Y", tp); assert( in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 1970_y/1/1); } } void test_c() { using namespace date; using namespace std::chrono; { // correct abbreviation std::istringstream in{"Sun Dec 11 14:02:43 2016"}; sys_seconds tp; in >> parse("%c", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{14} + minutes{2} + seconds{43}); } } void test_x() { using namespace date; using namespace std::chrono; { // correct abbreviation std::istringstream in{"12/11/16"}; sys_seconds tp; in >> parse("%x", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11}); } } void test_X() { using namespace date; using namespace std::chrono; { // correct abbreviation std::istringstream in{"2016-12-11 14:02:43"}; sys_seconds tp; in >> parse("%F %X", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{14} + minutes{2} + seconds{43}); } } void test_C() { using namespace date; using namespace std::chrono; { std::istringstream in{"20 16 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/11); } { std::istringstream in{"-2 1 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == -101_y/12/11); } { std::istringstream in{"-1 0 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == -100_y/12/11); } { std::istringstream in{"-1 99 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == -99_y/12/11); } { std::istringstream in{"-1 1 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == -1_y/12/11); } { std::istringstream in{"0 0 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 0_y/12/11); } { std::istringstream in{"0 1 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 1_y/12/11); } { std::istringstream in{"0 99 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 99_y/12/11); } { std::istringstream in{"1 0 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 100_y/12/11); } { std::istringstream in{"1 1 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 101_y/12/11); } } void test_d() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016 09 12"}; sys_days tp; in >> parse("%Y %d %m", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/9); } { std::istringstream in{"2016 09 12"}; sys_days tp; in >> parse("%Y %e %m", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/9); } { std::istringstream in{"2016 9 12"}; sys_days tp; in >> parse("%Y %d %m", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/9); } { std::istringstream in{"2016 9 12"}; sys_days tp; in >> parse("%Y %e %m", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/9); } { std::istringstream in{"2016 31 11"}; sys_days tp; in >> parse("%Y %e %m", tp); assert(in.fail()); } } void test_D() { using namespace date; using namespace std::chrono; { std::istringstream in{"12/11/16"}; sys_days tp; in >> parse("%D", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/11); } } void test_F() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-13"}; sys_days tp; in >> parse("%F", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/13); } { std::istringstream in{"2016-12-13"}; year_month_day tp; in >> parse("%F", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/13); } } void test_H() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-11 15"}; sys_time tp; in >> parse("%F %H", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{15}); } { std::istringstream in{"2016-12-11 24"}; sys_time tp; in >> parse("%F %H", tp); assert(in.fail()); } } void test_Ip() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-11 1 pm"}; sys_time tp; in >> parse("%F %I %p", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{13}); } { std::istringstream in{"2016-12-11 1 am"}; sys_time tp; in >> parse("%F %I %p", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{1}); } { std::istringstream in{"2016-12-11 13 am"}; sys_time tp; in >> parse("%F %I %p", tp); assert(in.fail()); } } void test_j() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016 361"}; sys_days tp; in >> parse("%Y %j", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } } void test_m() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016 12 09"}; sys_days tp; in >> parse("%Y %d %m", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/9/12); } { std::istringstream in{"2016 12 9"}; sys_days tp; in >> parse("%Y %d %m", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/9/12); } { std::istringstream in{"2016 12 13"}; sys_days tp; in >> parse("%Y %d %m", tp); assert(in.fail()); } } void test_M() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-11 15"}; sys_time tp; in >> parse("%F %M", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + minutes{15}); } { std::istringstream in{"2016-12-11 65"}; sys_time tp; in >> parse("%F %M", tp); assert(in.fail()); } } void test_S() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-11 15"}; sys_seconds tp; in >> parse("%F %S", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + seconds{15}); } { std::istringstream in{"2016-12-11 15.001"}; sys_time tp; in >> parse("%F %S", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + seconds{15} + milliseconds{1}); } { std::istringstream in{"2016-12-11 60"}; sys_seconds tp; in >> parse("%F %S", tp); assert(in.fail()); } } void test_T() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-11 15:43:22"}; sys_seconds tp; in >> parse("%F %T", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{15} + minutes{43} + seconds{22}); } { std::istringstream in{"2016-12-11 15:43:22.001"}; sys_time tp; in >> parse("%F %T", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{15} + minutes{43} + seconds{22} + milliseconds{1}); } { std::istringstream in{"2016-12-11 15:43:22"}; sys_time tp; in >> parse("%F %T", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{15} + minutes{43} + seconds{22}); } { std::istringstream in{"15:43:22.001"}; milliseconds d; in >> parse("%T", d); assert(!in.fail()); assert(!in.bad()); assert(d == hours{15} + minutes{43} + seconds{22} + milliseconds{1}); } { std::istringstream in{"2016-12-11 24:43:22"}; sys_seconds tp; in >> parse("%F %T", tp); assert(in.fail()); } { std::istringstream in{"2016-12-11 15:60:22"}; sys_seconds tp; in >> parse("%F %T", tp); assert(in.fail()); } { std::istringstream in{"2016-12-11 15:43:60"}; sys_seconds tp; in >> parse("%F %T", tp); assert(in.fail()); } } void test_p() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-11 11pm"}; sys_time tp; in >> parse("%F %I%p", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{23}); } { std::istringstream in{"1986-12-01 01:01:01 pm"}; sys_time tp; in >> parse("%Y-%m-%d %I:%M:%S %p", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{1986_y/12/01} + hours{13} + minutes{01} + seconds{01}); } { std::istringstream in{"1986-12-01 01:01:01"}; sys_time tp; in >> parse("%Y-%m-%d %I:%M:%S", tp); // The test will fail because %I needs the %p option to shows if it is AM or PM assert(in.fail()); } } void test_r() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-26 1:36:57 pm"}; sys_seconds tp; in >> parse("%F %r", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26} + hours{13} + minutes{36} + seconds{57}); } } void test_R() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-26 13:36"}; sys_seconds tp; in >> parse("%F %R", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26} + hours{13} + minutes{36}); } } void test_U() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-52-1"}; sys_days tp; in >> parse("%Y-%U-%w", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } } void test_W() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-52-1"}; sys_days tp; in >> parse("%Y-%W-%w", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } } void test_GV() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-52-1"}; sys_days tp; in >> parse("%G-%V-%w", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } { std::istringstream in{"2016-52-1"}; sys_days tp; in >> parse("%G-%V-%w", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } { std::istringstream in{"20 16-52-1"}; sys_days tp; in >> parse("%C %g-%V-%w", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } { std::istringstream in{"20 16-52-1"}; sys_days tp; in >> parse("%C %g-%V-%u", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } } void test_z() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-26 15:53:22 -0500"}; sys_seconds tp; in >> parse("%F %T %z", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26} + hours{20} + minutes{53} + seconds{22}); } { std::istringstream in{"2016-12-26 15:53:22 -0500"}; local_seconds tp; in >> parse("%F %T %z", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == local_days{2016_y/12/26} + hours{15} + minutes{53} + seconds{22}); } { std::istringstream in{"2016-12-26 15:53:22 -05:00"}; sys_seconds tp; in >> parse("%F %T %Ez", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26} + hours{20} + minutes{53} + seconds{22}); } } void test_Z() { using namespace date; using namespace std::chrono; { std::string a; std::istringstream in{"2016-12-26 15:53:22 word"}; local_seconds tp; in >> parse("%F %T %Z", tp, a); assert(!in.fail()); assert(!in.bad()); assert(tp == local_days{2016_y/12/26} + hours{15} + minutes{53} + seconds{22}); assert(a == "word"); } } void test_trailing_Z() { std::string format = "%FT%TZ"; std::string datetime = "2017-2-15T13:13:13"; std::istringstream input(datetime); date::sys_seconds tp; input >> date::parse(format, tp); assert(input.fail()); assert(input.eof()); } void test_leading_ws() { using namespace std; using namespace date; istringstream in{"05/04/17 5/4/17"}; year_month_day d1, d2; in >> parse("%D", d1) >> parse("%n%D", d2); assert(d1 == may/4/2017); assert(d2 == may/4/2017); } void test_space() { using namespace std; using namespace date; { istringstream in{"05/04/17"}; year_month_day d1; in >> parse(" %D", d1); assert(d1 == may/4/2017); } { istringstream in{" 05/04/17"}; year_month_day d1; in >> parse(" %D", d1); assert(d1 == may/4/2017); } { istringstream in{" 05/04/17"}; year_month_day d1; in >> parse(" %D", d1); assert(d1 == may/4/2017); } } void test_n() { using namespace std; using namespace date; { istringstream in{"05/04/17"}; year_month_day d1; in >> parse("%n%D", d1); assert(in.fail()); } { istringstream in{" 05/04/17"}; year_month_day d1; in >> parse("%n%D", d1); assert(d1 == may/4/2017); } { istringstream in{" 05/04/17"}; year_month_day d1; in >> parse("%n%D", d1); assert(in.fail()); } } void test_t() { using namespace std; using namespace date; { istringstream in{"05/04/17"}; year_month_day d1; in >> parse("%t%D", d1); assert(d1 == may/4/2017); } { istringstream in{" 05/04/17"}; year_month_day d1; in >> parse("%t%D", d1); assert(d1 == may/4/2017); } { istringstream in{" 05/04/17"}; year_month_day d1; in >> parse("%t%D", d1); assert(in.fail()); } } int main() { test_a(); test_b(); test_c(); test_C(); test_d(); test_D(); test_F(); test_H(); test_Ip(); test_j(); test_m(); test_M(); test_p(); test_r(); test_R(); test_S(); test_T(); test_U(); test_W(); test_GV(); test_x(); test_X(); test_z(); test_Z(); test_trailing_Z(); test_leading_ws(); test_space(); test_n(); test_t(); } date-3.0.1/test/date_test/sizeof.pass.cpp000066400000000000000000000050461403643451100203410ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // This test is meant to maintain a record of the sizeof each type. #include "date.h" int main() { using namespace date; static_assert(sizeof(days) == 4, ""); static_assert(sizeof(weeks) == 4, ""); static_assert(sizeof(months) == 4, ""); static_assert(sizeof(years) == 4, ""); static_assert(sizeof(sys_days) == 4, ""); static_assert(sizeof(last_spec) == 1, ""); static_assert(sizeof(day) == 1, ""); static_assert(sizeof(month) == 1, ""); static_assert(sizeof(year) == 2, ""); static_assert(sizeof(weekday) == 1, ""); static_assert(sizeof(weekday_indexed) == 1, ""); static_assert(sizeof(weekday_last) == 1, ""); static_assert(sizeof(month_day) == 2, ""); static_assert(sizeof(month_day_last) == 1, ""); static_assert(sizeof(month_weekday) == 2, ""); static_assert(sizeof(month_weekday_last) == 2, ""); static_assert(sizeof(year_month) == 4, ""); static_assert(sizeof(year_month_day) == 4, ""); static_assert(sizeof(year_month_day_last) == 4, ""); static_assert(sizeof(year_month_weekday) == 4, ""); static_assert(sizeof(year_month_weekday_last) == 4, ""); // sizeof time_of_day varies } date-3.0.1/test/date_test/time_of_day_hours.pass.cpp000066400000000000000000000064321403643451100225410ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // enum {am = 1, pm}; // class time_of_day // { // public: // using precision = std::chrono::hours; // // constexpr explicit time_of_day(std::chrono::hours since_midnight) noexcept; // constexpr time_of_day(std::chrono::hours h, unsigned md) noexcept; // // constexpr std::chrono::hours hours() const noexcept; // constexpr unsigned mode() const noexcept; // // constexpr explicit operator precision() const noexcept; // constexpr precision to_duration() const noexcept; // // void make24() noexcept; // void make12() noexcept; // }; // std::ostream& operator<<(std::ostream& os, const time_of_day& t); #include "date.h" #include #include #include int main() { using namespace date; using namespace std; using namespace std::chrono; using tod = time_of_day; static_assert(is_same{}, ""); static_assert( is_trivially_destructible{}, ""); static_assert( is_default_constructible{}, ""); static_assert( is_trivially_copy_constructible{}, ""); static_assert( is_trivially_copy_assignable{}, ""); static_assert( is_trivially_move_constructible{}, ""); static_assert( is_trivially_move_assignable{}, ""); static_assert(is_nothrow_constructible{}, ""); static_assert(!is_convertible{}, ""); static_assert(is_nothrow_constructible{}, ""); static_assert(!is_convertible{}, ""); constexpr tod t1 = tod{hours{13}}; static_assert(t1.hours() == hours{13}, ""); #if __cplusplus >= 201402 static_assert(static_cast(t1) == hours{13}, ""); static_assert(t1.to_duration() == hours{13}, ""); #endif auto t2 = t1; assert(t2.hours() == t1.hours()); assert(t2.to_duration() == t1.to_duration()); ostringstream os; os << t2; assert(os.str() == "13:00:00"); auto h = make12(t2.hours()); os.str(""); assert(h == hours{1}); assert(t2.to_duration() == t1.to_duration()); assert(!is_am(t2.hours())); assert(is_pm(t2.hours())); } date-3.0.1/test/date_test/time_of_day_microfortnights.pass.cpp000066400000000000000000000110011403643451100246060ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // enum {am = 1, pm}; // template // class time_of_day> // { // public: // using precision = std::chrono::std::chrono::duration; // // constexpr explicit time_of_day(precision since_midnight) noexcept; // constexpr time_of_day(std::chrono::hours h, std::chrono::minutes m, // std::chrono::seconds s, precision sub_s, // unsigned md) noexcept; // // constexpr std::chrono::hours hours() const noexcept; // constexpr std::chrono::minutes minutes() const noexcept; // constexpr std::chrono::seconds seconds() const noexcept; // constexpr precision subseconds() const noexcept; // constexpr unsigned mode() const noexcept; // // constexpr explicit operator precision() const noexcept; // constexpr precision to_duration() const noexcept; // // void make24() noexcept; // void make12() noexcept; // }; // template // std::ostream& // operator<<(std::ostream& os, const time_of_day>& t); #include "date.h" #include #include #include using fortnights = std::chrono::duration, date::weeks::period>>; using microfortnights = std::chrono::duration>; int main() { using namespace date; using namespace std; using namespace std::chrono; using tod = time_of_day::type>; static_assert(is_same>{}, ""); static_assert( is_trivially_destructible{}, ""); static_assert( is_default_constructible{}, ""); static_assert( is_trivially_copy_constructible{}, ""); static_assert( is_trivially_copy_assignable{}, ""); static_assert( is_trivially_move_constructible{}, ""); static_assert( is_trivially_move_assignable{}, ""); static_assert(is_constructible{}, ""); static_assert(!is_convertible{}, ""); static_assert(is_nothrow_constructible{}, ""); static_assert(!is_convertible{}, ""); constexpr tod t1 = tod{hours{13} + minutes{7} + microfortnights{5}}; static_assert(t1.hours() == hours{13}, ""); static_assert(t1.minutes() == minutes{7}, ""); static_assert(t1.seconds() == seconds{6}, ""); static_assert(t1.subseconds() == tod::precision{480}, ""); #if __cplusplus >= 201402 static_assert(static_cast(t1) == hours{13} + minutes{7} + microfortnights{5}, ""); static_assert(t1.to_duration() == hours{13} + minutes{7} + microfortnights{5}, ""); #endif auto t2 = t1; assert(t2.hours() == t1.hours()); assert(t2.minutes() == t1.minutes()); assert(t2.seconds() == t1.seconds()); assert(t2.subseconds() == t1.subseconds()); assert(t2.to_duration() == t1.to_duration()); ostringstream os; os << t2; assert(os.str() == "13:07:06.0480"); } date-3.0.1/test/date_test/time_of_day_milliseconds.pass.cpp000066400000000000000000000100671403643451100240650ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // enum {am = 1, pm}; // template // class time_of_day> // { // public: // using precision = std::chrono::std::chrono::duration; // // constexpr explicit time_of_day(precision since_midnight) noexcept; // constexpr time_of_day(std::chrono::hours h, std::chrono::minutes m, // std::chrono::seconds s, precision sub_s, // unsigned md) noexcept; // // constexpr std::chrono::hours hours() const noexcept; // constexpr std::chrono::minutes minutes() const noexcept; // constexpr std::chrono::seconds seconds() const noexcept; // constexpr precision subseconds() const noexcept; // constexpr unsigned mode() const noexcept; // // constexpr explicit operator precision() const noexcept; // constexpr precision to_duration() const noexcept; // // void make24() noexcept; // void make12() noexcept; // }; // template // std::ostream& // operator<<(std::ostream& os, const time_of_day>& t); #include "date.h" #include #include #include int main() { using namespace date; using namespace std; using namespace std::chrono; using tod = time_of_day; static_assert(is_same{}, ""); static_assert( is_trivially_destructible{}, ""); static_assert( is_default_constructible{}, ""); static_assert( is_trivially_copy_constructible{}, ""); static_assert( is_trivially_copy_assignable{}, ""); static_assert( is_trivially_move_constructible{}, ""); static_assert( is_trivially_move_assignable{}, ""); static_assert(is_nothrow_constructible{}, ""); static_assert(!is_convertible{}, ""); static_assert(is_nothrow_constructible{}, ""); static_assert(!is_convertible{}, ""); constexpr tod t1 = tod{hours{13} + minutes{7} + seconds{5} + milliseconds{22}}; static_assert(t1.hours() == hours{13}, ""); static_assert(t1.minutes() == minutes{7}, ""); static_assert(t1.seconds() == seconds{5}, ""); static_assert(t1.subseconds() == milliseconds{22}, ""); #if __cplusplus >= 201402 static_assert(static_cast(t1) == hours{13} + minutes{7} + seconds{5} + milliseconds{22}, ""); static_assert(t1.to_duration() == hours{13} + minutes{7} + seconds{5} + milliseconds{22}, ""); #endif auto t2 = t1; assert(t2.hours() == t1.hours()); assert(t2.minutes() == t1.minutes()); assert(t2.seconds() == t1.seconds()); assert(t2.subseconds() == t1.subseconds()); assert(t2.to_duration() == t1.to_duration()); ostringstream os; os << t2; assert(os.str() == "13:07:05.022"); } date-3.0.1/test/date_test/time_of_day_minutes.pass.cpp000066400000000000000000000065441403643451100230710ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // enum {am = 1, pm}; // class time_of_day // { // public: // using precision = std::chrono::minutes; // // constexpr explicit time_of_day(std::chrono::minutes since_midnight) noexcept; // constexpr time_of_day(std::chrono::hours h, std::chrono::minutes m, // unsigned md) noexcept; // // constexpr std::chrono::hours hours() const noexcept; // constexpr std::chrono::minutes minutes() const noexcept; // constexpr unsigned mode() const noexcept; // // constexpr explicit operator precision() const noexcept; // constexpr precision to_duration() const noexcept; // // void make24() noexcept; // void make12() noexcept; // }; // std::ostream& operator<<(std::ostream& os, const time_of_day& t); #include "date.h" #include #include #include int main() { using namespace date; using namespace std; using namespace std::chrono; using tod = time_of_day; static_assert(is_same{}, ""); static_assert( is_trivially_destructible{}, ""); static_assert( is_default_constructible{}, ""); static_assert( is_trivially_copy_constructible{}, ""); static_assert( is_trivially_copy_assignable{}, ""); static_assert( is_trivially_move_constructible{}, ""); static_assert( is_trivially_move_assignable{}, ""); static_assert(is_nothrow_constructible{}, ""); static_assert(!is_convertible{}, ""); static_assert(is_nothrow_constructible{}, ""); static_assert(!is_convertible{}, ""); constexpr tod t1 = tod{hours{13} + minutes{7}}; static_assert(t1.hours() == hours{13}, ""); static_assert(t1.minutes() == minutes{7}, ""); #if __cplusplus >= 201402 static_assert(static_cast(t1) == hours{13} + minutes{7}, ""); static_assert(t1.to_duration() == hours{13} + minutes{7}, ""); #endif auto t2 = t1; assert(t2.hours() == t1.hours()); assert(t2.minutes() == t1.minutes()); assert(t2.to_duration() == t1.to_duration()); ostringstream os; os << t2; assert(os.str() == "13:07:00"); } date-3.0.1/test/date_test/time_of_day_nanoseconds.pass.cpp000066400000000000000000000100651403643451100237100ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // enum {am = 1, pm}; // template // class time_of_day> // { // public: // using precision = std::chrono::std::chrono::duration; // // constexpr explicit time_of_day(precision since_midnight) noexcept; // constexpr time_of_day(std::chrono::hours h, std::chrono::minutes m, // std::chrono::seconds s, precision sub_s, // unsigned md) noexcept; // // constexpr std::chrono::hours hours() const noexcept; // constexpr std::chrono::minutes minutes() const noexcept; // constexpr std::chrono::seconds seconds() const noexcept; // constexpr precision subseconds() const noexcept; // constexpr unsigned mode() const noexcept; // // constexpr explicit operator precision() const noexcept; // constexpr precision to_duration() const noexcept; // // void make24() noexcept; // void make12() noexcept; // }; // template // std::ostream& // operator<<(std::ostream& os, const time_of_day>& t); #include "date.h" #include #include #include int main() { using namespace date; using namespace std; using namespace std::chrono; using tod = time_of_day; static_assert(is_same{}, ""); static_assert( is_trivially_destructible{}, ""); static_assert( is_default_constructible{}, ""); static_assert( is_trivially_copy_constructible{}, ""); static_assert( is_trivially_copy_assignable{}, ""); static_assert( is_trivially_move_constructible{}, ""); static_assert( is_trivially_move_assignable{}, ""); static_assert(is_nothrow_constructible{}, ""); static_assert(!is_convertible{}, ""); static_assert(is_nothrow_constructible{}, ""); static_assert(!is_convertible{}, ""); constexpr tod t1 = tod{hours{13} + minutes{7} + seconds{5} + nanoseconds{22}}; static_assert(t1.hours() == hours{13}, ""); static_assert(t1.minutes() == minutes{7}, ""); static_assert(t1.seconds() == seconds{5}, ""); static_assert(t1.subseconds() == nanoseconds{22}, ""); #if __cplusplus >= 201402 static_assert(static_cast(t1) == hours{13} + minutes{7} + seconds{5} + nanoseconds{22}, ""); static_assert(t1.to_duration() == hours{13} + minutes{7} + seconds{5} + nanoseconds{22}, ""); #endif auto t2 = t1; assert(t2.hours() == t1.hours()); assert(t2.minutes() == t1.minutes()); assert(t2.seconds() == t1.seconds()); assert(t2.subseconds() == t1.subseconds()); assert(t2.to_duration() == t1.to_duration()); ostringstream os; os << t2; assert(os.str() == "13:07:05.000000022"); } date-3.0.1/test/date_test/time_of_day_seconds.pass.cpp000066400000000000000000000071651403643451100230430ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // enum {am = 1, pm}; // class time_of_day // { // public: // using precision = std::chrono::seconds; // // constexpr explicit time_of_day(std::chrono::seconds since_midnight) noexcept; // constexpr time_of_day(std::chrono::hours h, std::chrono::minutes m, // std::chrono::seconds s, unsigned md) noexcept; // // constexpr std::chrono::hours hours() const noexcept; // constexpr std::chrono::minutes minutes() const noexcept; // constexpr std::chrono::seconds seconds() const noexcept; // constexpr unsigned mode() const noexcept; // // constexpr explicit operator precision() const noexcept; // constexpr precision to_duration() const noexcept; // // void make24() noexcept; // void make12() noexcept; // }; // std::ostream& operator<<(std::ostream& os, const time_of_day& t); #include "date.h" #include #include #include int main() { using namespace date; using namespace std; using namespace std::chrono; using tod = time_of_day; static_assert(is_same{}, ""); static_assert( is_trivially_destructible{}, ""); static_assert( is_default_constructible{}, ""); static_assert( is_trivially_copy_constructible{}, ""); static_assert( is_trivially_copy_assignable{}, ""); static_assert( is_trivially_move_constructible{}, ""); static_assert( is_trivially_move_assignable{}, ""); static_assert(is_nothrow_constructible{}, ""); static_assert(!is_convertible{}, ""); static_assert(is_nothrow_constructible{}, ""); static_assert(!is_convertible{}, ""); constexpr tod t1 = tod{hours{13} + minutes{7} + seconds{5}}; static_assert(t1.hours() == hours{13}, ""); static_assert(t1.minutes() == minutes{7}, ""); static_assert(t1.seconds() == seconds{5}, ""); #if __cplusplus >= 201402 static_assert(static_cast(t1) == hours{13} + minutes{7} + seconds{5}, ""); static_assert(t1.to_duration() == hours{13} + minutes{7} + seconds{5}, ""); #endif auto t2 = t1; assert(t2.hours() == t1.hours()); assert(t2.minutes() == t1.minutes()); assert(t2.seconds() == t1.seconds()); assert(t2.to_duration() == t1.to_duration()); ostringstream os; os << t2; assert(os.str() == "13:07:05"); } date-3.0.1/test/date_test/weekday.pass.cpp000066400000000000000000000147741403643451100205030ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class weekday // { // unsigned char wd_; // public: // explicit constexpr weekday(unsigned wd) noexcept; // constexpr weekday(const sys_days& dp) noexcept; // // weekday& operator++() noexcept; // weekday operator++(int) noexcept; // weekday& operator--() noexcept; // weekday operator--(int) noexcept; // // weekday& operator+=(const days& d) noexcept; // weekday& operator-=(const days& d) noexcept; // // constexpr explicit operator unsigned() const noexcept; // constexpr bool ok() const noexcept; // // // tested with weekday_indexed // constexpr weekday_indexed operator[](unsigned index) const noexcept; // // tested with weekday_last // constexpr weekday_last operator[](last_spec) const noexcept; // }; // constexpr bool operator==(const weekday& x, const weekday& y) noexcept; // constexpr bool operator!=(const weekday& x, const weekday& y) noexcept; // constexpr weekday operator+(const weekday& x, const days& y) noexcept; // constexpr weekday operator+(const days& x, const weekday& y) noexcept; // constexpr weekday operator-(const weekday& x, const days& y) noexcept; // constexpr days operator-(const weekday& x, const weekday& y) noexcept; // std::ostream& operator<<(std::ostream& os, const weekday& wd); // constexpr weekday sun{0}; // constexpr weekday mon{1}; // constexpr weekday tue{2}; // constexpr weekday wed{3}; // constexpr weekday thu{4}; // constexpr weekday fri{5}; // constexpr weekday sat{6}; #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert( std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert( std::is_convertible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert( date::weekday{0u}.ok(), ""); static_assert( date::weekday{1u}.ok(), ""); static_assert( date::weekday{2u}.ok(), ""); static_assert( date::weekday{3u}.ok(), ""); static_assert( date::weekday{4u}.ok(), ""); static_assert( date::weekday{5u}.ok(), ""); static_assert( date::weekday{6u}.ok(), ""); static_assert( date::weekday{7u}.ok(), ""); static_assert(!date::weekday{8u}.ok(), ""); void test_weekday_arithmetic() { using namespace date; constexpr unsigned a[7][7] = {// - Sun Mon Tue Wed Thu Fri Sat /*Sun*/ {0, 6, 5, 4, 3, 2, 1}, /*Mon*/ {1, 0, 6, 5, 4, 3, 2}, /*Tue*/ {2, 1, 0, 6, 5, 4, 3}, /*Wed*/ {3, 2, 1, 0, 6, 5, 4}, /*Thu*/ {4, 3, 2, 1, 0, 6, 5}, /*Fri*/ {5, 4, 3, 2, 1, 0, 6}, /*Sat*/ {6, 5, 4, 3, 2, 1, 0} }; for (unsigned x = 0; x < 7; ++x) { for (unsigned y = 0; y < 7; ++y) { assert(weekday{x} - weekday{y} == days{a[x][y]}); assert(weekday{x} - days{a[x][y]} == weekday{y}); assert(weekday{x} == weekday{y} + days{a[x][y]}); assert(weekday{x} == days{a[x][y]} + weekday{y}); } } for (unsigned x = 0; x < 7; ++x) { for (int y = -21; y < 21; ++y) { weekday wx{x}; days dy{y}; wx += dy; weekday wz = weekday{x} + days{y}; assert(wx.ok()); assert(wz.ok()); assert(wx == wz); assert(wx - weekday{x} == days{y % 7 + (y % 7 < 0 ? 7 : 0)}); } } for (unsigned x = 0; x < 7; ++x) { for (int y = -21; y < 21; ++y) { weekday wx{x}; days dy{y}; wx -= dy; assert(wx == weekday{x} + days{-y}); } } for (unsigned x = 0; x < 7; ++x) { weekday wx{x}; assert(++wx - weekday{x} == days{1}); assert(wx++ - weekday{x} == days{1}); assert(wx - weekday{x} == days{2}); assert(wx-- - weekday{x} == days{2}); assert(wx - weekday{x} == days{1}); assert(--wx - weekday{x} == days{0}); } } int main() { using namespace date; static_assert(sun == weekday{0u}, ""); static_assert(mon == weekday{1u}, ""); static_assert(tue == weekday{2u}, ""); static_assert(wed == weekday{3u}, ""); static_assert(thu == weekday{4u}, ""); static_assert(fri == weekday{5u}, ""); static_assert(sat == weekday{6u}, ""); static_assert(!(sun != sun), ""); static_assert( sun != mon, ""); static_assert( mon != sun, ""); test_weekday_arithmetic(); std::ostringstream os; os << sun; assert(os.str() == "Sun"); os.str(""); os << mon; assert(os.str() == "Mon"); os.str(""); os << tue; assert(os.str() == "Tue"); os.str(""); os << wed; assert(os.str() == "Wed"); os.str(""); os << thu; assert(os.str() == "Thu"); os.str(""); os << fri; assert(os.str() == "Fri"); os.str(""); os << sat; assert(os.str() == "Sat"); } date-3.0.1/test/date_test/weekday_indexed.pass.cpp000066400000000000000000000055321403643451100221730ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class weekday_indexed // { // public: // weekday_indexed() = default; // constexpr weekday_indexed(const date::weekday& wd, unsigned index) noexcept; // // constexpr date::weekday weekday() const noexcept; // constexpr unsigned index() const noexcept; // constexpr bool ok() const noexcept; // }; // // constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept; // constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept; // // std::ostream& operator<<(std::ostream& os, const weekday_indexed& wdi); #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert( std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_nothrow_constructible{}, ""); int main() { using namespace date; constexpr weekday_indexed wdi = sun[1]; static_assert(wdi.weekday() == sun, ""); static_assert(wdi.index() == 1, ""); static_assert(wdi.ok(), ""); static_assert(wdi == weekday_indexed{sun, 1}, ""); static_assert(wdi != weekday_indexed{sun, 2}, ""); static_assert(wdi != weekday_indexed{mon, 1}, ""); std::ostringstream os; os << wdi; assert(os.str() == "Sun[1]"); } date-3.0.1/test/date_test/weekday_last.pass.cpp000066400000000000000000000051531403643451100215150ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class weekday_last // { // public: // explicit constexpr weekday_last(const date::weekday& wd) noexcept; // // constexpr date::weekday weekday() const noexcept; // constexpr bool ok() const noexcept; // }; // // constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept; // constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept; // // std::ostream& operator<<(std::ostream& os, const weekday_last& wdl); #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); int main() { using namespace date; constexpr weekday_last wdl = sun[last]; static_assert(wdl.weekday() == sun, ""); static_assert(wdl.ok(), ""); static_assert(wdl == weekday_last{sun}, ""); static_assert(wdl != weekday_last{mon}, ""); std::ostringstream os; os << wdl; assert(os.str() == "Sun[last]"); } date-3.0.1/test/date_test/weekday_lessthan.fail.cpp000066400000000000000000000023611403643451100223360ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // weekday < weekday not allowed #include "date.h" int main() { using namespace date; auto b = sun < mon; } date-3.0.1/test/date_test/weekday_sum.fail.cpp000066400000000000000000000023611403643451100213210ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // weekday + weekday not allowed #include "date.h" int main() { using namespace date; auto b = sun + mon; } date-3.0.1/test/date_test/year.pass.cpp000066400000000000000000000134351403643451100200030ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class year // { // public: // explicit constexpr year(int y) noexcept; // // year& operator++() noexcept; // year operator++(int) noexcept; // year& operator--() noexcept; // year operator--(int) noexcept; // // year& operator+=(const years& y) noexcept; // year& operator-=(const years& y) noexcept; // // constexpr bool is_leap() const noexcept; // // constexpr explicit operator int() const noexcept; // constexpr bool ok() const noexcept; // // static constexpr year min() noexcept; // static constexpr year max() noexcept; // }; // constexpr bool operator==(const year& x, const year& y) noexcept; // constexpr bool operator!=(const year& x, const year& y) noexcept; // constexpr bool operator< (const year& x, const year& y) noexcept; // constexpr bool operator> (const year& x, const year& y) noexcept; // constexpr bool operator<=(const year& x, const year& y) noexcept; // constexpr bool operator>=(const year& x, const year& y) noexcept; // constexpr year operator+(const year& x, const years& y) noexcept; // constexpr year operator+(const years& x, const year& y) noexcept; // constexpr year operator-(const year& x, const years& y) noexcept; // constexpr years operator-(const year& x, const year& y) noexcept; // constexpr year operator "" _y(unsigned long long y) noexcept; // std::ostream& operator<<(std::ostream& os, const year& y); #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert( std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert(static_cast(date::year{-1}) == -1, ""); template constexpr inline std::chrono::duration as(std::chrono::duration d) { return d; } int main() { using namespace date; using namespace std::chrono; static_assert(year{2015} == 2015_y, ""); static_assert(year{2015} != 2016_y, ""); static_assert(year{2015} < 2016_y, ""); static_assert(year{2016} > 2015_y, ""); static_assert(year{2015} <= 2015_y, ""); static_assert(year{2016} >= 2015_y, ""); static_assert(!year{2015}.is_leap(), ""); static_assert( year{2016}.is_leap(), ""); static_assert(year::min().ok(), ""); static_assert(year{2015}.ok(), ""); static_assert(year{2016}.ok(), ""); static_assert(year::max().ok(), ""); #if __cplusplus >= 201402 using std::int64_t; static_assert(sys_days(year::min()/jan/1) - sys_days(1970_y/jan/1) >= as(days::min()), ""); static_assert(sys_days(year::min()/jan/1) - sys_days(1970_y/jan/1) >= as(hours::min()), ""); static_assert(sys_days(year::min()/jan/1) - sys_days(1970_y/jan/1) >= as(minutes::min()), ""); static_assert(sys_days(year::min()/jan/1) - sys_days(1970_y/jan/1) >= as(seconds::min()), ""); static_assert(sys_days(year::min()/jan/1) - sys_days(1970_y/jan/1) >= as(milliseconds::min()), ""); static_assert(sys_days(year::min()/jan/1) - sys_days(1970_y/jan/1) >= as(microseconds::min()), ""); static_assert(sys_days(year::max()/dec/31) - sys_days(1970_y/jan/1) <= as(microseconds::max()), ""); static_assert(sys_days(year::max()/dec/31) - sys_days(1970_y/jan/1) <= as(milliseconds::max()), ""); static_assert(sys_days(year::max()/dec/31) - sys_days(1970_y/jan/1) <= as(seconds::max()), ""); static_assert(sys_days(year::max()/dec/31) - sys_days(1970_y/jan/1) <= as(minutes::max()), ""); static_assert(sys_days(year::max()/dec/31) - sys_days(1970_y/jan/1) <= as(hours::max()), ""); static_assert(sys_days(year::max()/dec/31) - sys_days(1970_y/jan/1) <= as(days::max()), ""); #endif static_assert(2015_y - 2010_y == years{5}, ""); static_assert(2015_y - years{5} == 2010_y, ""); static_assert(2015_y == years{5} + 2010_y, ""); static_assert(2015_y == 2010_y + years{5}, ""); auto y = 2015_y; std::ostringstream os; os << y; assert(os.str() == "2015"); } date-3.0.1/test/date_test/year_month.pass.cpp000066400000000000000000000164321403643451100212100ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class year_month // { // public: // constexpr year_month(const date::year& y, const date::month& m) noexcept; // // constexpr date::year year() const noexcept; // constexpr date::month month() const noexcept; // // year_month& operator+=(const months& dm) noexcept; // year_month& operator-=(const months& dm) noexcept; // year_month& operator+=(const years& dy) noexcept; // year_month& operator-=(const years& dy) noexcept; // // constexpr bool ok() const noexcept; // }; // constexpr bool operator==(const year_month& x, const year_month& y) noexcept; // constexpr bool operator!=(const year_month& x, const year_month& y) noexcept; // constexpr bool operator< (const year_month& x, const year_month& y) noexcept; // constexpr bool operator> (const year_month& x, const year_month& y) noexcept; // constexpr bool operator<=(const year_month& x, const year_month& y) noexcept; // constexpr bool operator>=(const year_month& x, const year_month& y) noexcept; // constexpr year_month operator+(const year_month& ym, const months& dm) noexcept; // constexpr year_month operator+(const months& dm, const year_month& ym) noexcept; // constexpr year_month operator-(const year_month& ym, const months& dm) noexcept; // constexpr months operator-(const year_month& x, const year_month& y) noexcept; // constexpr year_month operator+(const year_month& ym, const years& dy) noexcept; // constexpr year_month operator+(const years& dy, const year_month& ym) noexcept; // constexpr year_month operator-(const year_month& ym, const years& dy) noexcept; // std::ostream& operator<<(std::ostream& os, const year_month& ym); #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert( std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_nothrow_constructible{}, ""); void test_arithmetic() { using namespace date; using namespace std::chrono; for (int y1 = 2010; y1 <= 2015; ++y1) { for (int y2 = 2010; y2 <= 2015; ++y2) { for (unsigned m1 = 1; m1 <= 12; ++m1) { for (unsigned m2 = 1; m2 <= 12; ++m2) { year_month ym1{year{y1}, month{m1}}; year_month ym2 = {year{y2}, month{m2}}; months dm = ym1 - ym2; assert((dm < months{0}) == (ym1 < ym2)); assert((dm == months{0}) == (ym1 == ym2)); assert((dm > months{0}) == (ym1 > ym2)); assert(dm + ym2 == ym1); assert(ym2 + dm == ym1); assert(ym1 - dm == ym2); years dy{y1-y2}; assert((ym1 + dy == year_month{ym1.year() + dy, ym1.month()})); assert((dy + ym1 == year_month{ym1.year() + dy, ym1.month()})); assert((ym1 - dy == year_month{ym1.year() - dy, ym1.month()})); assert((year_month{ym2} += dm) == ym1); assert((year_month{ym1} -= dm) == ym2); assert(((year_month{ym1} += dy) == year_month{ym1.year() + dy, ym1.month()})); assert(((year_month{ym1} -= dy) == year_month{ym1.year() - dy, ym1.month()})); } } } } } void test_arithemtic_not_ok() { using namespace date; using namespace std::chrono; year_month ym{2018_y, month{14}}; { year_month ym2{2019_y, month{2}}; assert(ym + months{0} == ym2); assert(ym - months{0} == ym2); assert(ym - ym2 == months{0}); assert(ym2 - ym == months{0}); auto ymc = ym; ymc += months{0}; assert(ymc.ok()); assert(ymc == ym2); } { year_month ym2{2019_y, month{6}}; assert(ym + months{4} == ym2); assert(ym2 - ym == months{4}); assert(ym - ym2 == -months{4}); auto ymc = ym; ymc += months{4}; assert(ymc.ok()); assert(ymc == ym2); } { year_month ym2{2018_y, month{10}}; assert(ym - months{4} == ym2); assert(ym2 - ym == -months{4}); assert(ym - ym2 == months{4}); auto ymc = ym; ymc -= months{4}; assert(ymc.ok()); assert(ymc == ym2); } { year_month ym2{2020_y, month{6}}; assert(ym + months{16} == ym2); assert(ym2 - ym == months{16}); assert(ym - ym2 == -months{16}); auto ymc = ym; ymc += months{16}; assert(ymc.ok()); assert(ymc == ym2); } { year_month ym2{2017_y, month{10}}; assert(ym - months{16} == ym2); assert(ym2 - ym == -months{16}); assert(ym - ym2 == months(16)); auto ymc = ym; ymc -= months{16}; assert(ymc.ok()); assert(ymc == ym2); } { year_month ym2{2018_y, month{25}}; assert(ym2 - ym == months{11}); assert(ym - ym2 == -months{11}); } { year_month ym2{2019_y, month{25}}; assert(ym2 - ym == months{23}); assert(ym - ym2 == -months{23}); } } int main() { using namespace date; constexpr year_month ym1 = {2015_y, jun}; static_assert(ym1.year() == year{2015}, ""); static_assert(ym1.month() == jun, ""); static_assert(ym1.ok(), ""); constexpr year_month ym2 = {2016_y, may}; static_assert(ym2.year() == year{2016}, ""); static_assert(ym2.month() == may, ""); static_assert(ym2.ok(), ""); static_assert(ym1 == ym1, ""); static_assert(ym1 != ym2, ""); static_assert(ym1 < ym2, ""); static_assert(ym1 <= ym2, ""); static_assert(ym2 > ym1, ""); static_assert(ym2 >= ym2, ""); static_assert(ym2 - ym1 == months{11}, ""); static_assert(ym1 - ym2 == -months{11}, ""); test_arithmetic(); test_arithemtic_not_ok(); std::ostringstream os; os << ym1; assert(os.str() == "2015/Jun"); } date-3.0.1/test/date_test/year_month_day.pass.cpp000066400000000000000000000236541403643451100220510ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class year_month_day // { // public: // constexpr year_month_day(const date::year& y, const date::month& m, // const date::day& d) noexcept; // constexpr year_month_day(const year_month_day_last& ymdl) noexcept; // constexpr year_month_day(const sys_days& dp) noexcept; // // year_month_day& operator+=(const months& m) noexcept; // year_month_day& operator-=(const months& m) noexcept; // year_month_day& operator+=(const years& y) noexcept; // year_month_day& operator-=(const years& y) noexcept; // // constexpr date::year year() const noexcept; // constexpr date::month month() const noexcept; // constexpr date::day day() const noexcept; // // constexpr operator sys_days() const noexcept; // constexpr bool ok() const noexcept; // }; // constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept; // constexpr bool operator!=(const year_month_day& x, const year_month_day& y) noexcept; // constexpr bool operator< (const year_month_day& x, const year_month_day& y) noexcept; // constexpr bool operator> (const year_month_day& x, const year_month_day& y) noexcept; // constexpr bool operator<=(const year_month_day& x, const year_month_day& y) noexcept; // constexpr bool operator>=(const year_month_day& x, const year_month_day& y) noexcept; // constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept; // constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept; // constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept; // constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept; // constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept; // constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept; // std::ostream& operator<<(std::ostream& os, const year_month_day& ymd); #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert( std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_convertible{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_convertible{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_convertible{}, ""); void test_arithmetic() { using namespace date; for (int y1 = 2010; y1 <= 2015; ++y1) { for (unsigned m1 = 1; m1 <= 12; ++m1) { year_month_day ymd1{year{y1}, month{m1}, 9_d}; year_month_day ymd2 = ymd1 + months(24); assert((ymd2 == year_month_day{year{y1+2}, ymd1.month(), ymd1.day()})); ymd2 = ymd1 - months(24); assert((ymd2 == year_month_day{year{y1-2}, ymd1.month(), ymd1.day()})); for (int m2 = -24; m2 <= 24; ++m2) { months m{m2}; year_month_day ymd3 = ymd1 + m; months dm = year_month{ymd3.year(), ymd3.month()} - year_month{ymd2.year(), ymd2.month()}; assert(dm == m + years{2}); assert(ymd3 - m == ymd1); assert(ymd3 + -m == ymd1); assert(-m + ymd3 == ymd1); assert((year_month_day{ymd1} += m) == ymd3); assert((year_month_day{ymd3} -= m) == ymd1); } for (int y2 = -2; y2 <= 5; ++y2) { years y{y2}; year_month_day ymd3 = ymd1 + y; years dy = floor(year_month{ymd3.year(), ymd3.month()} - year_month{ymd2.year(), ymd2.month()}); assert(dy == y + years{2}); assert(ymd3 - y == ymd1); assert(ymd3 + -y == ymd1); assert(-y + ymd3 == ymd1); assert((year_month_day{ymd1} += y) == ymd3); assert((year_month_day{ymd3} -= y) == ymd1); } } } } void test_day_point_conversion() { using namespace date; year y = year{-1000}; year end = 3000_y; sys_days prev_dp = sys_days(year_month_day{y, jan, 1_d}) - days{1}; weekday prev_wd = weekday{prev_dp}; for (; y <= end; ++y) { month m = jan; do { day last_day = year_month_day_last{y, month_day_last{m}}.day(); for (day d = 1_d; d <= last_day; ++d) { year_month_day ymd = {y, m, d}; assert(ymd.ok()); sys_days dp = ymd; assert(dp == prev_dp + days{1}); year_month_day ymd2 = dp; assert(ymd2 == ymd); weekday wd = dp; assert(wd.ok()); assert(wd == prev_wd + days{1}); prev_wd = wd; prev_dp = dp; } } while (++m != jan); } } int main() { using namespace date; constexpr year_month_day ymd1 = {2015_y, aug, 9_d}; #if __cplusplus >= 201402 static_assert(ymd1.ok(), ""); #endif static_assert(ymd1.year() == 2015_y, ""); static_assert(ymd1.month() == aug, ""); static_assert(ymd1.day() == 9_d, ""); #if __cplusplus >= 201402 constexpr sys_days dp = ymd1; static_assert(dp.time_since_epoch() == days{16656}, ""); constexpr year_month_day ymd2 = dp; static_assert(ymd1 == ymd2, ""); #endif constexpr year_month_day ymd3 = {1969_y, dec, 31_d}; #if __cplusplus >= 201402 static_assert(ymd3.ok(), ""); #endif static_assert(ymd3.year() == 1969_y, ""); static_assert(ymd3.month() == dec, ""); static_assert(ymd3.day() == 31_d, ""); #if __cplusplus >= 201402 constexpr sys_days dp3 = ymd3; static_assert(dp3.time_since_epoch() == days{-1}, ""); constexpr year_month_day ymd4 = dp3; static_assert(ymd3 == ymd4, ""); #endif static_assert(ymd1 != ymd3, ""); static_assert(ymd1 > ymd3, ""); static_assert(ymd3 < ymd1, ""); static_assert(ymd1 >= ymd1, ""); static_assert(ymd3 <= ymd1, ""); test_arithmetic(); test_day_point_conversion(); std::ostringstream os; os << ymd1; assert(os.str() == "2015-08-09"); #if __cplusplus >= 201402 static_assert( (2000_y/feb/29).ok(), ""); static_assert(!(2000_y/feb/30).ok(), ""); static_assert( (2100_y/feb/28).ok(), ""); static_assert(!(2100_y/feb/29).ok(), ""); static_assert(sys_days(2100_y/feb/28) + days{1} == sys_days(2100_y/mar/1), ""); static_assert(sys_days(2000_y/mar/1) - sys_days(2000_y/feb/28) == days{2}, ""); static_assert(sys_days(2100_y/mar/1) - sys_days(2100_y/feb/28) == days{1}, ""); static_assert(jan/31/2015 == jan/last/2015, ""); static_assert(feb/28/2015 == feb/last/2015, ""); static_assert(mar/31/2015 == mar/last/2015, ""); static_assert(apr/30/2015 == apr/last/2015, ""); static_assert(may/31/2015 == may/last/2015, ""); static_assert(jun/30/2015 == jun/last/2015, ""); static_assert(jul/31/2015 == jul/last/2015, ""); static_assert(aug/31/2015 == aug/last/2015, ""); static_assert(sep/30/2015 == sep/last/2015, ""); static_assert(oct/31/2015 == oct/last/2015, ""); static_assert(nov/30/2015 == nov/last/2015, ""); static_assert(dec/31/2015 == dec/last/2015, ""); static_assert(jan/31/2016 == jan/last/2016, ""); static_assert(feb/29/2016 == feb/last/2016, ""); static_assert(mar/31/2016 == mar/last/2016, ""); static_assert(apr/30/2016 == apr/last/2016, ""); static_assert(may/31/2016 == may/last/2016, ""); static_assert(jun/30/2016 == jun/last/2016, ""); static_assert(jul/31/2016 == jul/last/2016, ""); static_assert(aug/31/2016 == aug/last/2016, ""); static_assert(sep/30/2016 == sep/last/2016, ""); static_assert(oct/31/2016 == oct/last/2016, ""); static_assert(nov/30/2016 == nov/last/2016, ""); static_assert(dec/31/2016 == dec/last/2016, ""); #endif } date-3.0.1/test/date_test/year_month_day_last.pass.cpp000066400000000000000000000152741403643451100230730ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class year_month_day_last // { // public: // constexpr year_month_day_last(const date::year& y, // const date::month_day_last& mdl) noexcept; // // year_month_day_last& operator+=(const months& m) noexcept; // year_month_day_last& operator-=(const months& m) noexcept; // year_month_day_last& operator+=(const years& y) noexcept; // year_month_day_last& operator-=(const years& y) noexcept; // // constexpr date::year year() const noexcept; // constexpr date::month month() const noexcept; // constexpr date::month_day_last month_day_last() const noexcept; // constexpr date::day day() const noexcept; // // constexpr operator sys_days() const noexcept; // constexpr bool ok() const noexcept; // }; // constexpr // bool operator==(const year_month_day_last& x, const year_month_day_last& y) noexcept; // constexpr // bool operator!=(const year_month_day_last& x, const year_month_day_last& y) noexcept; // constexpr // bool operator< (const year_month_day_last& x, const year_month_day_last& y) noexcept; // constexpr // bool operator> (const year_month_day_last& x, const year_month_day_last& y) noexcept; // constexpr // bool operator<=(const year_month_day_last& x, const year_month_day_last& y) noexcept; // constexpr // bool operator>=(const year_month_day_last& x, const year_month_day_last& y) noexcept; // constexpr // year_month_day_last // operator+(const year_month_day_last& ymdl, const months& dm) noexcept; // // constexpr // year_month_day_last // operator+(const months& dm, const year_month_day_last& ymdl) noexcept; // // constexpr // year_month_day_last // operator+(const year_month_day_last& ymdl, const years& dy) noexcept; // // constexpr // year_month_day_last // operator+(const years& dy, const year_month_day_last& ymdl) noexcept; // // constexpr // year_month_day_last // operator-(const year_month_day_last& ymdl, const months& dm) noexcept; // // constexpr // year_month_day_last // operator-(const year_month_day_last& ymdl, const years& dy) noexcept; // std::ostream& operator<<(std::ostream& os, const year_month_day_last& ymdl); #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_convertible{}, ""); void test_arithmetic() { using namespace date; for (int y1 = 2010; y1 <= 2015; ++y1) { for (int m1 = 1; m1 <= 12; ++m1) { auto ymd1 = last/m1/y1;; auto ymd2 = ymd1 + months(24); assert(ymd2 == last/m1/(y1+2)); ymd2 = ymd1 - months(24); assert(ymd2 == last/m1/(y1-2)); for (int m2 = -24; m2 <= 24; ++m2) { months m{m2}; auto ymd3 = ymd1 + m; months dm = year_month{ymd3.year(), ymd3.month()} - year_month{ymd2.year(), ymd2.month()}; assert(dm == m + years{2}); assert(ymd3 - m == ymd1); assert(ymd3 + -m == ymd1); assert(-m + ymd3 == ymd1); assert((year_month_day_last{ymd1} += m) == ymd3); assert((year_month_day_last{ymd3} -= m) == ymd1); } for (int y2 = -2; y2 <= 5; ++y2) { years y{y2}; auto ymd3 = ymd1 + y; years dy = floor(year_month{ymd3.year(), ymd3.month()} - year_month{ymd2.year(), ymd2.month()}); assert(dy == y + years{2}); assert(ymd3 - y == ymd1); assert(ymd3 + -y == ymd1); assert(-y + ymd3 == ymd1); assert((year_month_day_last{ymd1} += y) == ymd3); assert((year_month_day_last{ymd3} -= y) == ymd1); } } } } int main() { using namespace date; constexpr year_month_day_last ymdl1 = {2015_y, month_day_last{aug}}; static_assert(ymdl1.ok(), ""); static_assert(ymdl1.year() == 2015_y, ""); static_assert(ymdl1.month() == aug, ""); static_assert(ymdl1.month_day_last() == month_day_last{aug}, ""); #if __cplusplus >= 201402 static_assert(ymdl1.day() == 31_d, ""); constexpr sys_days dp = ymdl1; constexpr year_month_day ymd = dp; static_assert(ymd == 2015_y/aug/31, ""); #endif constexpr year_month_day_last ymdl2 = {2015_y, month_day_last{sep}}; static_assert(ymdl1 == ymdl1, ""); static_assert(ymdl1 != ymdl2, ""); static_assert(ymdl1 < ymdl2, ""); static_assert(ymdl2 > ymdl1, ""); static_assert(ymdl1 <= ymdl1, ""); static_assert(ymdl2 >= ymdl1, ""); test_arithmetic(); std::ostringstream os; os << ymdl1; assert(os.str() == "2015/Aug/last"); } date-3.0.1/test/date_test/year_month_day_m_year_month_day.fail.cpp000066400000000000000000000024721403643451100254070ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // year_month_day - year_month_day not allowed #include "date.h" int main() { using namespace date; auto x = year_month_day{2015_y, aug, 9_d} - year_month_day{2015_y, aug, 9_d}; } date-3.0.1/test/date_test/year_month_day_p_year_month_day.fail.cpp000066400000000000000000000024721403643451100254120ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // year_month_day + year_month_day not allowed #include "date.h" int main() { using namespace date; auto x = year_month_day{2015_y, aug, 9_d} + year_month_day{2015_y, aug, 9_d}; } date-3.0.1/test/date_test/year_month_p_year_month.fail.cpp000066400000000000000000000024401403643451100237130ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // year_month + year_month not allowed #include "date.h" int main() { using namespace date; auto x = year_month{2015_y, jan} + year_month{2015_y, jan}; } date-3.0.1/test/date_test/year_month_weekday.pass.cpp000066400000000000000000000152441403643451100227210ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class year_month_weekday // { // public: // year_month_weekday() = default; // constexpr year_month_weekday(const date::year& y, const date::month& m, // const date::weekday_indexed& wdi) noexcept; // constexpr year_month_weekday(const sys_days& dp) noexcept; // // year_month_weekday& operator+=(const months& m) noexcept; // year_month_weekday& operator-=(const months& m) noexcept; // year_month_weekday& operator+=(const years& y) noexcept; // year_month_weekday& operator-=(const years& y) noexcept; // // constexpr date::year year() const noexcept; // constexpr date::month month() const noexcept; // constexpr date::weekday weekday() const noexcept; // constexpr unsigned index() const noexcept; // constexpr date::weekday_indexed weekday_indexed() const noexcept; // // constexpr operator sys_days() const noexcept; // constexpr bool ok() const noexcept; // // private: // static constexpr year_month_weekday from_day_point(const sys_days& dp) noexcept; // }; // constexpr // bool operator==(const year_month_weekday& x, const year_month_weekday& y) noexcept; // constexpr // bool operator!=(const year_month_weekday& x, const year_month_weekday& y) noexcept; // constexpr // year_month_weekday // operator+(const year_month_weekday& ymwd, const months& dm) noexcept; // // constexpr // year_month_weekday // operator+(const months& dm, const year_month_weekday& ymwd) noexcept; // // constexpr // year_month_weekday // operator+(const year_month_weekday& ymwd, const years& dy) noexcept; // // constexpr // year_month_weekday // operator+(const years& dy, const year_month_weekday& ymwd) noexcept; // // constexpr // year_month_weekday // operator-(const year_month_weekday& ymwd, const months& dm) noexcept; // // constexpr // year_month_weekday // operator-(const year_month_weekday& ymwd, const years& dy) noexcept; // std::ostream& operator<<(std::ostream& os, const year_month_weekday& ymwdi); #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert( std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_convertible{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_convertible{}, ""); void test_arithmetic() { using namespace date; for (int y1 = 2010; y1 <= 2015; ++y1) { for (int m1 = 1; m1 <= 12; ++m1) { auto ymd1 = mon[2]/m1/y1;; auto ymd2 = ymd1 + months(24); assert(ymd2 == mon[2]/m1/(y1+2)); ymd2 = ymd1 - months(24); assert(ymd2 == mon[2]/m1/(y1-2)); for (int m2 = -24; m2 <= 24; ++m2) { months m{m2}; auto ymd3 = ymd1 + m; months dm = year_month{ymd3.year(), ymd3.month()} - year_month{ymd2.year(), ymd2.month()}; assert(dm == m + years{2}); assert(ymd3 - m == ymd1); assert(ymd3 + -m == ymd1); assert(-m + ymd3 == ymd1); assert((year_month_weekday{ymd1} += m) == ymd3); assert((year_month_weekday{ymd3} -= m) == ymd1); } for (int y2 = -2; y2 <= 5; ++y2) { years y{y2}; auto ymd3 = ymd1 + y; years dy = floor(year_month{ymd3.year(), ymd3.month()} - year_month{ymd2.year(), ymd2.month()}); assert(dy == y + years{2}); assert(ymd3 - y == ymd1); assert(ymd3 + -y == ymd1); assert(-y + ymd3 == ymd1); assert((year_month_weekday{ymd1} += y) == ymd3); assert((year_month_weekday{ymd3} -= y) == ymd1); } } } } int main() { using namespace date; constexpr year_month_weekday ymdl1 = {2015_y, aug, weekday_indexed{fri, 2}}; #if __cplusplus >= 201402 static_assert(ymdl1.ok(), ""); #endif static_assert(ymdl1.year() == 2015_y, ""); static_assert(ymdl1.month() == aug, ""); static_assert(ymdl1.weekday() == fri, ""); static_assert(ymdl1.index() == 2u, ""); static_assert(ymdl1.weekday_indexed() == fri[2], ""); #if __cplusplus >= 201402 constexpr sys_days dp = ymdl1; constexpr year_month_day ymd = dp; static_assert(ymd == 2015_y/aug/14, ""); #endif constexpr year_month_weekday ymdl2 = sat[1]/aug/2015; static_assert(ymdl1 == ymdl1, ""); static_assert(ymdl1 != ymdl2, ""); test_arithmetic(); std::ostringstream os; os << ymdl1; assert(os.str() == "2015/Aug/Fri[2]"); } date-3.0.1/test/date_test/year_month_weekday_last.pass.cpp000066400000000000000000000144661403643451100237510ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class year_month_weekday_last // { // public: // constexpr year_month_weekday_last(const date::year& y, const date::month& m, // const date::weekday_last& wdl) noexcept; // // year_month_weekday_last& operator+=(const months& m) noexcept; // year_month_weekday_last& operator-=(const months& m) noexcept; // year_month_weekday_last& operator+=(const years& y) noexcept; // year_month_weekday_last& operator-=(const years& y) noexcept; // // constexpr date::year year() const noexcept; // constexpr date::month month() const noexcept; // constexpr date::weekday weekday() const noexcept; // constexpr date::weekday_last weekday_last() const noexcept; // // constexpr operator sys_days() const noexcept; // constexpr bool ok() const noexcept; // }; // constexpr // bool // operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept; // // constexpr // bool // operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept; // constexpr // year_month_weekday_last // operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept; // // constexpr // year_month_weekday_last // operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept; // // constexpr // year_month_weekday_last // operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept; // // constexpr // year_month_weekday_last // operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept; // // constexpr // year_month_weekday_last // operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept; // // constexpr // year_month_weekday_last // operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept; // std::ostream& operator<<(std::ostream& os, const year_month_weekday_last& ymwdl); #include "date.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_convertible{}, ""); void test_arithmetic() { using namespace date; for (int y1 = 2010; y1 <= 2015; ++y1) { for (int m1 = 1; m1 <= 12; ++m1) { auto ymd1 = mon[last]/m1/y1;; auto ymd2 = ymd1 + months(24); assert(ymd2 == mon[last]/m1/(y1+2)); ymd2 = ymd1 - months(24); assert(ymd2 == mon[last]/m1/(y1-2)); for (int m2 = -24; m2 <= 24; ++m2) { months m{m2}; auto ymd3 = ymd1 + m; months dm = year_month{ymd3.year(), ymd3.month()} - year_month{ymd2.year(), ymd2.month()}; assert(dm == m + years{2}); assert(ymd3 - m == ymd1); assert(ymd3 + -m == ymd1); assert(-m + ymd3 == ymd1); assert((year_month_weekday_last{ymd1} += m) == ymd3); assert((year_month_weekday_last{ymd3} -= m) == ymd1); } for (int y2 = -2; y2 <= 5; ++y2) { years y{y2}; auto ymd3 = ymd1 + y; years dy = floor(year_month{ymd3.year(), ymd3.month()} - year_month{ymd2.year(), ymd2.month()}); assert(dy == y + years{2}); assert(ymd3 - y == ymd1); assert(ymd3 + -y == ymd1); assert(-y + ymd3 == ymd1); assert((year_month_weekday_last{ymd1} += y) == ymd3); assert((year_month_weekday_last{ymd3} -= y) == ymd1); } } } } int main() { using namespace date; constexpr year_month_weekday_last ymdl1 = {2015_y, aug, weekday_last{fri}}; static_assert(ymdl1.ok(), ""); static_assert(ymdl1.year() == 2015_y, ""); static_assert(ymdl1.month() == aug, ""); static_assert(ymdl1.weekday() == fri, ""); static_assert(ymdl1.weekday_last() == fri[last], ""); #if __cplusplus >= 201402 constexpr sys_days dp = ymdl1; constexpr year_month_day ymd = dp; static_assert(ymd == 2015_y/aug/28, ""); #endif constexpr year_month_weekday_last ymdl2 = sat[last]/aug/2015; static_assert(ymdl1 == ymdl1, ""); static_assert(ymdl1 != ymdl2, ""); test_arithmetic(); std::ostringstream os; os << ymdl1; assert(os.str() == "2015/Aug/Fri[last]"); } date-3.0.1/test/date_test/year_p_year.fail.cpp000066400000000000000000000023611403643451100213030ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // year + year not allowed #include "date.h" int main() { using namespace date; auto x = 2015_y + 2015_y; } date-3.0.1/test/date_test/years_m_year.fail.cpp000066400000000000000000000023641403643451100214660ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // years - year not allowed #include "date.h" int main() { using namespace date; auto x = years{3} - 2015_y; } date-3.0.1/test/date_test/years_m_year_month.fail.cpp000066400000000000000000000024141403643451100226670ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // years - year_month not allowed #include "date.h" int main() { using namespace date; auto x = years{1} - year_month{2015_y, jan}; } date-3.0.1/test/date_test/years_m_year_month_day.fail.cpp000066400000000000000000000024271403643451100235300ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // years - year_month_day not allowed #include "date.h" int main() { using namespace date; auto x = 2015_y - year_month_day{2015_y, aug, 9_d}; } date-3.0.1/test/iso_week/000077500000000000000000000000001403643451100152155ustar00rootroot00000000000000date-3.0.1/test/iso_week/last.pass.cpp000066400000000000000000000024741403643451100176400ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // constexpr struct last_spec {} last{}; #include "iso_week.h" #include static_assert(std::is_same{}, ""); int main() { } date-3.0.1/test/iso_week/lastweek_weekday.pass.cpp000066400000000000000000000067601403643451100222270ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class lastweek_weekday // { // iso_week::weekday wd_; // exposition only // // public: // explicit constexpr lastweek_weekday(const iso_week::weekday& wd) noexcept; // // constexpr iso_week::weekday weekday() const noexcept; // // constexpr bool ok() const noexcept; // }; // // constexpr bool operator==(const lastweek_weekday& x, const lastweek_weekday& y) noexcept; // constexpr bool operator!=(const lastweek_weekday& x, const lastweek_weekday& y) noexcept; // constexpr bool operator< (const lastweek_weekday& x, const lastweek_weekday& y) noexcept; // constexpr bool operator> (const lastweek_weekday& x, const lastweek_weekday& y) noexcept; // constexpr bool operator<=(const lastweek_weekday& x, const lastweek_weekday& y) noexcept; // constexpr bool operator>=(const lastweek_weekday& x, const lastweek_weekday& y) noexcept; // // std::ostream& operator<<(std::ostream& os, const lastweek_weekday& md); #include "iso_week.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_trivially_copyable{}, ""); static_assert(std::is_standard_layout{}, ""); static_assert(std::is_literal_type{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); int main() { using namespace iso_week; constexpr auto wn_wd = lastweek_weekday{tue}; static_assert(wn_wd.weekday() == tue, ""); static_assert(wn_wd.ok(), ""); static_assert(wn_wd == lastweek_weekday{tue}, ""); static_assert(!(wn_wd != lastweek_weekday{tue}), ""); static_assert(wn_wd < lastweek_weekday{wed}, ""); std::ostringstream os; os << wn_wd; assert(os.str() == "W last-Tue"); } date-3.0.1/test/iso_week/op_div_survey.pass.cpp000066400000000000000000000253701403643451100215720ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "iso_week.h" #include template constexpr auto test(I i, J j, K k) -> decltype(i/j/k) { return i/j/k; } void test(...) { } int main() { using std::is_same; using namespace iso_week; static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); static_assert(is_same{}, ""); } date-3.0.1/test/iso_week/weekday.pass.cpp000066400000000000000000000173001403643451100203200ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class weekday // { // unsigned char wd_; // public: // explicit constexpr weekday(unsigned wd) noexcept; // constexpr weekday(date::weekday wd) noexcept; // constexpr weekday(const sys_days& dp) noexcept; // // weekday& operator++() noexcept; // weekday operator++(int) noexcept; // weekday& operator--() noexcept; // weekday operator--(int) noexcept; // // weekday& operator+=(const days& d) noexcept; // weekday& operator-=(const days& d) noexcept; // // constexpr explicit operator unsigned() const noexcept; // constexpr operator date::weekday() const noexcept; // constexpr bool ok() const noexcept; // // // tested with weekday_indexed // constexpr weekday_indexed operator[](unsigned index) const noexcept; // // tested with weekday_last // constexpr weekday_last operator[](last_spec) const noexcept; // }; // constexpr bool operator==(const weekday& x, const weekday& y) noexcept; // constexpr bool operator!=(const weekday& x, const weekday& y) noexcept; // constexpr weekday operator+(const weekday& x, const days& y) noexcept; // constexpr weekday operator+(const days& x, const weekday& y) noexcept; // constexpr weekday operator-(const weekday& x, const days& y) noexcept; // constexpr days operator-(const weekday& x, const weekday& y) noexcept; // std::ostream& operator<<(std::ostream& os, const weekday& wd); // constexpr weekday sun{7}; // constexpr weekday mon{1}; // constexpr weekday tue{2}; // constexpr weekday wed{3}; // constexpr weekday thu{4}; // constexpr weekday fri{5}; // constexpr weekday sat{6}; #include "iso_week.h" #include "date.h" #include #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_trivially_copyable{}, ""); static_assert(std::is_standard_layout{}, ""); static_assert(std::is_literal_type{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert( std::is_convertible{}, ""); static_assert( std::is_convertible{}, ""); static_assert( std::is_convertible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert(static_cast(iso_week::weekday{1u}) == 1, ""); static_assert(!iso_week::weekday{0u}.ok(), ""); static_assert( iso_week::weekday{1u}.ok(), ""); static_assert( iso_week::weekday{2u}.ok(), ""); static_assert( iso_week::weekday{3u}.ok(), ""); static_assert( iso_week::weekday{4u}.ok(), ""); static_assert( iso_week::weekday{5u}.ok(), ""); static_assert( iso_week::weekday{6u}.ok(), ""); static_assert( iso_week::weekday{7u}.ok(), ""); void test_weekday_arithmetic() { using namespace iso_week; constexpr unsigned a[7][7] = {// - Mon Tue Wed Thu Fri Sat Sun /*Mon*/ {0, 6, 5, 4, 3, 2, 1}, /*Tue*/ {1, 0, 6, 5, 4, 3, 2}, /*Wed*/ {2, 1, 0, 6, 5, 4, 3}, /*Thu*/ {3, 2, 1, 0, 6, 5, 4}, /*Fri*/ {4, 3, 2, 1, 0, 6, 5}, /*Sat*/ {5, 4, 3, 2, 1, 0, 6}, /*Sun*/ {6, 5, 4, 3, 2, 1, 0} }; for (unsigned x = 1; x <= 7; ++x) { for (unsigned y = 1; y <= 7; ++y) { assert(weekday{x} - weekday{y} == days{a[x-1][y-1]}); assert(weekday{x} - days{a[x-1][y-1]} == weekday{y}); assert(weekday{x} == weekday{y} + days{a[x-1][y-1]}); assert(weekday{x} == days{a[x-1][y-1]} + weekday{y}); } } for (unsigned x = 1; x <= 7; ++x) { for (int y = -21; y < 21; ++y) { weekday wx{x}; days dy{y}; wx += dy; weekday wz = weekday{x} + days{y}; assert(wx.ok()); assert(wz.ok()); assert(wx == wz); assert(wx - weekday{x} == days{y % 7 + (y % 7 < 0 ? 7 : 0)}); } } for (unsigned x = 1; x <= 7; ++x) { for (int y = -21; y < 21; ++y) { weekday wx{x}; days dy{y}; wx -= dy; assert(wx == weekday{x} + days{-y}); } } for (unsigned x = 1; x <= 7; ++x) { weekday wx{x}; assert(++wx - weekday{x} == days{1}); assert(wx++ - weekday{x} == days{1}); assert(wx - weekday{x} == days{2}); assert(wx-- - weekday{x} == days{2}); assert(wx - weekday{x} == days{1}); assert(--wx - weekday{x} == days{0}); } } void test_with_date_weekday() { auto constexpr d1 = iso_week::sun; static_assert(unsigned{d1} == 7, ""); auto constexpr d2 = date::weekday{d1}; static_assert(d2 == date::Sunday, ""); auto constexpr d3 = iso_week::weekday{d2}; static_assert(unsigned{d3} == 7, ""); } int main() { using namespace iso_week; static_assert(sun == weekday{7u}, ""); static_assert(mon == weekday{1u}, ""); static_assert(tue == weekday{2u}, ""); static_assert(wed == weekday{3u}, ""); static_assert(thu == weekday{4u}, ""); static_assert(fri == weekday{5u}, ""); static_assert(sat == weekday{6u}, ""); static_assert(!(sun != sun), ""); static_assert( sun != mon, ""); static_assert( mon != sun, ""); test_weekday_arithmetic(); test_with_date_weekday(); std::ostringstream os; os << sun; assert(os.str() == "Sun"); os.str(""); os << mon; assert(os.str() == "Mon"); os.str(""); os << tue; assert(os.str() == "Tue"); os.str(""); os << wed; assert(os.str() == "Wed"); os.str(""); os << thu; assert(os.str() == "Thu"); os.str(""); os << fri; assert(os.str() == "Fri"); os.str(""); os << sat; assert(os.str() == "Sat"); } date-3.0.1/test/iso_week/weekday_lessthan.fail.cpp000066400000000000000000000023711403643451100221700ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // weekday < weekday not allowed #include "iso_week.h" int main() { using namespace iso_week; auto b = sun < mon; } date-3.0.1/test/iso_week/weekday_sum.fail.cpp000066400000000000000000000023711403643451100211530ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // weekday + weekday not allowed #include "iso_week.h" int main() { using namespace iso_week; auto b = sun + mon; } date-3.0.1/test/iso_week/weeknum.pass.cpp000066400000000000000000000114301403643451100203400ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class weeknum // { // unsigned char wn_; // // public: // explicit constexpr weeknum(unsigned wn) noexcept; // // weeknum& operator++() noexcept; // weeknum operator++(int) noexcept; // weeknum& operator--() noexcept; // weeknum operator--(int) noexcept; // // weeknum& operator+=(const weeks& y) noexcept; // weeknum& operator-=(const weeks& y) noexcept; // // constexpr explicit operator unsigned() const noexcept; // constexpr bool ok() const noexcept; // }; // // constexpr bool operator==(const weeknum& x, const weeknum& y) noexcept; // constexpr bool operator!=(const weeknum& x, const weeknum& y) noexcept; // constexpr bool operator< (const weeknum& x, const weeknum& y) noexcept; // constexpr bool operator> (const weeknum& x, const weeknum& y) noexcept; // constexpr bool operator<=(const weeknum& x, const weeknum& y) noexcept; // constexpr bool operator>=(const weeknum& x, const weeknum& y) noexcept; // // constexpr weeknum operator+(const weeknum& x, const weeks& y) noexcept; // constexpr weeknum operator+(const weeks& x, const weeknum& y) noexcept; // constexpr weeknum operator-(const weeknum& x, const weeks& y) noexcept; // constexpr weeks operator-(const weeknum& x, const weeknum& y) noexcept; // // std::ostream& operator<<(std::ostream& os, const weeknum& wn); // // constexpr weeknum operator "" _w(unsigned long long wn) noexcept; #include "iso_week.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_trivially_copyable{}, ""); static_assert(std::is_standard_layout{}, ""); static_assert(std::is_literal_type{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert(static_cast(iso_week::weeknum{3}) == 3, ""); int main() { using namespace iso_week; using namespace std::chrono; static_assert(weeknum{2} == 2_w, ""); static_assert(unsigned{weeknum{2}} == 2, ""); static_assert(unsigned{weeknum{3}} == 3, ""); static_assert(weeknum{2} != 3_w, ""); static_assert(weeknum{2} < 3_w, ""); static_assert(weeknum{3} > 2_w, ""); static_assert(weeknum{2} <= 2_w, ""); static_assert(weeknum{3} >= 2_w, ""); auto wn = weeknum{4}; assert(++wn == weeknum{5}); assert(wn == weeknum{5}); assert(wn++ == weeknum{5}); assert(wn == weeknum{6}); assert(--wn == weeknum{5}); assert(wn == weeknum{5}); assert(wn-- == weeknum{5}); assert(wn == weeknum{4}); static_assert(!weeknum{0}.ok(), ""); static_assert( weeknum{1}.ok(), ""); static_assert( weeknum{53}.ok(), ""); static_assert(!weeknum{54}.ok(), ""); static_assert(15_w - 10_w == weeks{5}, ""); static_assert(15_w - weeks{5} == 10_w, ""); static_assert(15_w == weeks{5} + 10_w, ""); static_assert(15_w == 10_w + weeks{5}, ""); static_assert(10_w - 15_w == -weeks{5}, ""); auto w = 5_w; std::ostringstream os; os << w; assert(os.str() == "W05"); } date-3.0.1/test/iso_week/weeknum_p_weeknum.fail.cpp000066400000000000000000000023711403643451100223630ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // weeknum + weeknum not allowed #include "iso_week.h" int main() { using namespace iso_week; auto x = 3_w + 4_w; } date-3.0.1/test/iso_week/weeknum_weekday.pass.cpp000066400000000000000000000072461403643451100220630ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class weeknum_weekday // { // iso_week::weeknum wn_; // exposition only // iso_week::weekday wd_; // exposition only // // public: // constexpr weeknum_weekday(const iso_week::weeknum& wn, // const iso_week::weekday& wd) noexcept; // // constexpr iso_week::weeknum weeknum() const noexcept; // constexpr iso_week::weekday weekday() const noexcept; // // constexpr bool ok() const noexcept; // }; // // constexpr bool operator==(const weeknum_weekday& x, const weeknum_weekday& y) noexcept; // constexpr bool operator!=(const weeknum_weekday& x, const weeknum_weekday& y) noexcept; // constexpr bool operator< (const weeknum_weekday& x, const weeknum_weekday& y) noexcept; // constexpr bool operator> (const weeknum_weekday& x, const weeknum_weekday& y) noexcept; // constexpr bool operator<=(const weeknum_weekday& x, const weeknum_weekday& y) noexcept; // constexpr bool operator>=(const weeknum_weekday& x, const weeknum_weekday& y) noexcept; // // std::ostream& operator<<(std::ostream& os, const weeknum_weekday& md); #include "iso_week.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_trivially_copyable{}, ""); static_assert(std::is_standard_layout{}, ""); static_assert(std::is_literal_type{}, ""); static_assert( std::is_nothrow_constructible{}, ""); int main() { using namespace iso_week; constexpr auto wn_wd = weeknum_weekday{52_w, tue}; static_assert(wn_wd.weeknum() == 52_w, ""); static_assert(wn_wd.weekday() == tue, ""); static_assert(wn_wd.ok(), ""); static_assert(wn_wd == weeknum_weekday{52_w, tue}, ""); static_assert(!(wn_wd != weeknum_weekday{52_w, tue}), ""); static_assert(wn_wd < weeknum_weekday{52_w, wed}, ""); std::ostringstream os; os << wn_wd; assert(os.str() == "W52-Tue"); } date-3.0.1/test/iso_week/year.pass.cpp000066400000000000000000000111251403643451100176260ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class year // { // public: // explicit constexpr year(int y) noexcept; // // year& operator++() noexcept; // year operator++(int) noexcept; // year& operator--() noexcept; // year operator--(int) noexcept; // // year& operator+=(const years& y) noexcept; // year& operator-=(const years& y) noexcept; // // constexpr explicit operator int() const noexcept; // constexpr bool ok() const noexcept; // // static constexpr year min() noexcept; // static constexpr year max() noexcept; // }; // constexpr bool operator==(const year& x, const year& y) noexcept; // constexpr bool operator!=(const year& x, const year& y) noexcept; // constexpr bool operator< (const year& x, const year& y) noexcept; // constexpr bool operator> (const year& x, const year& y) noexcept; // constexpr bool operator<=(const year& x, const year& y) noexcept; // constexpr bool operator>=(const year& x, const year& y) noexcept; // constexpr year operator+(const year& x, const years& y) noexcept; // constexpr year operator+(const years& x, const year& y) noexcept; // constexpr year operator-(const year& x, const years& y) noexcept; // constexpr years operator-(const year& x, const year& y) noexcept; // std::ostream& operator<<(std::ostream& os, const year& y); // inline namespace literals { // constexpr year operator "" _y(unsigned long long y) noexcept; // } #include "iso_week.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_trivially_copyable{}, ""); static_assert(std::is_standard_layout{}, ""); static_assert(std::is_literal_type{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); static_assert(static_cast(iso_week::year{-1}) == -1, ""); int main() { using namespace iso_week; static_assert(year{2015} == 2015_y, ""); static_assert(int{year{2015}} == 2015, ""); static_assert(year{2015} != 2016_y, ""); static_assert(year{2015} < 2016_y, ""); static_assert(year{2016} > 2015_y, ""); static_assert(year{2015} <= 2015_y, ""); static_assert(year{2016} >= 2015_y, ""); auto y = year{2014}; assert(++y == year{2015}); assert(y == year{2015}); assert(y++ == year{2015}); assert(y == year{2016}); assert(--y == year{2015}); assert(y == year{2015}); assert(y-- == year{2015}); assert(y == year{2014}); static_assert(year::min().ok(), ""); static_assert(year{2015}.ok(), ""); static_assert(year{2016}.ok(), ""); static_assert(year::max().ok(), ""); static_assert(2015_y - 2010_y == years{5}, ""); static_assert(2015_y - years{5} == 2010_y, ""); static_assert(2015_y == years{5} + 2010_y, ""); static_assert(2015_y == 2010_y + years{5}, ""); y = 2015_y; std::ostringstream os; os << y; assert(os.str() == "2015"); } date-3.0.1/test/iso_week/year_lastweek.pass.cpp000066400000000000000000000100771403643451100215320ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class year_lastweek // { // iso_week::year y_; // // public: // explicit constexpr year_lastweek(const iso_week::year& y) noexcept; // // constexpr iso_week::year year() const noexcept; // constexpr iso_week::weeknum weeknum() const noexcept; // // year_lastweek& operator+=(const years& dy) noexcept; // year_lastweek& operator-=(const years& dy) noexcept; // // constexpr bool ok() const noexcept; // }; // // constexpr bool operator==(const year_lastweek& x, const year_lastweek& y) noexcept; // constexpr bool operator!=(const year_lastweek& x, const year_lastweek& y) noexcept; // constexpr bool operator< (const year_lastweek& x, const year_lastweek& y) noexcept; // constexpr bool operator> (const year_lastweek& x, const year_lastweek& y) noexcept; // constexpr bool operator<=(const year_lastweek& x, const year_lastweek& y) noexcept; // constexpr bool operator>=(const year_lastweek& x, const year_lastweek& y) noexcept; // // constexpr year_lastweek operator+(const year_lastweek& ym, const years& dy) noexcept; // constexpr year_lastweek operator+(const years& dy, const year_lastweek& ym) noexcept; // constexpr year_lastweek operator-(const year_lastweek& ym, const years& dy) noexcept; // // std::ostream& operator<<(std::ostream& os, const year_lastweek& ym); #include "iso_week.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_trivially_copyable{}, ""); static_assert(std::is_standard_layout{}, ""); static_assert(std::is_literal_type{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(!std::is_convertible{}, ""); int main() { using namespace iso_week; constexpr auto y_wn = year_lastweek{2015_y}; static_assert(y_wn.year() == 2015_y, ""); static_assert(y_wn.weeknum() == 53_w, ""); static_assert(year_lastweek{2016_y}.weeknum() == 52_w, ""); static_assert(y_wn.ok(), ""); static_assert(y_wn == year_lastweek{2015_y}, ""); static_assert(!(y_wn != year_lastweek{2015_y}), ""); static_assert(y_wn < year_lastweek{2016_y}, ""); auto y_wn2 = y_wn + years{2}; assert(y_wn2 == year_lastweek{2017_y}); y_wn2 -= years{1}; assert(y_wn2 == year_lastweek{2016_y}); std::ostringstream os; os << y_wn; assert(os.str() == "2015-W last"); } date-3.0.1/test/iso_week/year_lastweek_weekday.pass.cpp000066400000000000000000000125321403643451100232410ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class year_lastweek_weekday // { // public: // constexpr year_lastweek_weekday(const iso_week::year& y, // const iso_week::weekday& wd) noexcept; // // year_lastweek_weekday& operator+=(const years& y) noexcept; // year_lastweek_weekday& operator-=(const years& y) noexcept; // // constexpr iso_week::year year() const noexcept; // constexpr iso_week::weeknum weeknum() const noexcept; // constexpr iso_week::weekday weekday() const noexcept; // // constexpr operator sys_days() const noexcept; // constexpr bool ok() const noexcept; // }; // // constexpr bool operator==(const year_lastweek_weekday& x, const year_lastweek_weekday& y) noexcept; // constexpr bool operator!=(const year_lastweek_weekday& x, const year_lastweek_weekday& y) noexcept; // constexpr bool operator< (const year_lastweek_weekday& x, const year_lastweek_weekday& y) noexcept; // constexpr bool operator> (const year_lastweek_weekday& x, const year_lastweek_weekday& y) noexcept; // constexpr bool operator<=(const year_lastweek_weekday& x, const year_lastweek_weekday& y) noexcept; // constexpr bool operator>=(const year_lastweek_weekday& x, const year_lastweek_weekday& y) noexcept; // // constexpr year_lastweek_weekday operator+(const year_lastweek_weekday& x, const years& y) noexcept; // constexpr year_lastweek_weekday operator+(const years& y, const year_lastweek_weekday& x) noexcept; // constexpr year_lastweek_weekday operator-(const year_lastweek_weekday& x, const years& y) noexcept; // // std::ostream& operator<<(std::ostream& os, const year_lastweek_weekday& x); #include "iso_week.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_trivially_copyable{}, ""); static_assert(std::is_standard_layout{}, ""); static_assert(std::is_literal_type{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert( std::is_convertible{}, ""); int main() { using namespace iso_week; constexpr auto x0 = year_lastweek_weekday{2015_y, tue}; static_assert(x0.year() == 2015_y, ""); static_assert(x0.weeknum() == 53_w, ""); static_assert(x0.weekday() == tue, ""); auto x3 = x0; x3 += years{2}; assert(x3.year() == 2017_y); assert(x3.weeknum() == 52_w); assert(x3.weekday() == tue); x3 -= years{1}; assert(x3.year() == 2016_y); assert(x3.weeknum() == 52_w); assert(x3.weekday() == tue); x3 -= years{1}; assert(x3.year() == 2015_y); assert(x3.weeknum() == 53_w); assert(x3.weekday() == tue); constexpr sys_days dp = 2015_y/last/wed; static_assert(dp == sys_days{days{16799}}, ""); static_assert(x0.ok(), ""); assert(x3.ok()); static_assert(2015_y/last/mon < 2015_y/last/sun, ""); static_assert(x0 + years{3} == 2018_y/last/tue, ""); static_assert(years{3} + x0 == 2018_y/last/tue, ""); static_assert(x0 - years{3} == 2012_y/last/tue, ""); std::ostringstream os; os << x0; assert(os.str() == "2015-W last-Tue"); for (auto y = 1950_y; y <= 2050_y; ++y) { auto wd = mon; do { auto x = y/last/wd; assert(date::year_month_day{x} == date::year_month_day{year_weeknum_weekday{x}}); ++wd; } while (wd != mon); } } date-3.0.1/test/iso_week/year_p_year.fail.cpp000066400000000000000000000023711403643451100211350ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // year + year not allowed #include "iso_week.h" int main() { using namespace iso_week; auto x = 2015_y + 2015_y; } date-3.0.1/test/iso_week/year_weeknum.pass.cpp000066400000000000000000000100441403643451100213600ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class year_weeknum // { // iso_week::year y_; // iso_week::weeknum wn_; // // public: // constexpr year_weeknum(const iso_week::year& y, const iso_week::weeknum& wn) noexcept; // // constexpr iso_week::year year() const noexcept; // constexpr iso_week::weeknum weeknum() const noexcept; // // year_weeknum& operator+=(const years& dy) noexcept; // year_weeknum& operator-=(const years& dy) noexcept; // // constexpr bool ok() const noexcept; // }; // // constexpr bool operator==(const year_weeknum& x, const year_weeknum& y) noexcept; // constexpr bool operator!=(const year_weeknum& x, const year_weeknum& y) noexcept; // constexpr bool operator< (const year_weeknum& x, const year_weeknum& y) noexcept; // constexpr bool operator> (const year_weeknum& x, const year_weeknum& y) noexcept; // constexpr bool operator<=(const year_weeknum& x, const year_weeknum& y) noexcept; // constexpr bool operator>=(const year_weeknum& x, const year_weeknum& y) noexcept; // // constexpr year_weeknum operator+(const year_weeknum& ym, const years& dy) noexcept; // constexpr year_weeknum operator+(const years& dy, const year_weeknum& ym) noexcept; // constexpr year_weeknum operator-(const year_weeknum& ym, const years& dy) noexcept; // // std::ostream& operator<<(std::ostream& os, const year_weeknum& ym); #include "iso_week.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_trivially_copyable{}, ""); static_assert(std::is_standard_layout{}, ""); static_assert(std::is_literal_type{}, ""); static_assert( std::is_nothrow_constructible{}, ""); int main() { using namespace iso_week; constexpr auto y_wn = year_weeknum{2015_y, 52_w}; static_assert(y_wn.year() == 2015_y, ""); static_assert(y_wn.weeknum() == 52_w, ""); static_assert(y_wn.ok(), ""); static_assert(y_wn == year_weeknum{2015_y, 52_w}, ""); static_assert(!(y_wn != year_weeknum{2015_y, 52_w}), ""); static_assert(y_wn < year_weeknum{2015_y, 53_w}, ""); auto y_wn2 = y_wn + years{2}; assert((y_wn2 == year_weeknum{2017_y, 52_w})); y_wn2 -= years{1}; assert((y_wn2 == year_weeknum{2016_y, 52_w})); std::ostringstream os; os << y_wn; assert(os.str() == "2015-W52"); } date-3.0.1/test/iso_week/year_weeknum_weekday.pass.cpp000066400000000000000000000144511403643451100230770ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class year_weeknum_weekday // class year_weeknum_weekday // { // public: // constexpr year_weeknum_weekday(const iso_week::year& y, const iso_week::weeknum& wn, // const iso_week::weekday& wd) noexcept; // constexpr year_weeknum_weekday(const year_lastweek_weekday& ylwwd) noexcept; // constexpr year_weeknum_weekday(const sys_days& dp) noexcept; // // year_weeknum_weekday& operator+=(const years& y) noexcept; // year_weeknum_weekday& operator-=(const years& y) noexcept; // // constexpr iso_week::year year() const noexcept; // constexpr iso_week::weeknum weeknum() const noexcept; // constexpr iso_week::weekday weekday() const noexcept; // // constexpr operator sys_days() const noexcept; // constexpr bool ok() const noexcept; // }; // // constexpr bool operator==(const year_weeknum_weekday& x, const year_weeknum_weekday& y) noexcept; // constexpr bool operator!=(const year_weeknum_weekday& x, const year_weeknum_weekday& y) noexcept; // constexpr bool operator< (const year_weeknum_weekday& x, const year_weeknum_weekday& y) noexcept; // constexpr bool operator> (const year_weeknum_weekday& x, const year_weeknum_weekday& y) noexcept; // constexpr bool operator<=(const year_weeknum_weekday& x, const year_weeknum_weekday& y) noexcept; // constexpr bool operator>=(const year_weeknum_weekday& x, const year_weeknum_weekday& y) noexcept; // // constexpr year_weeknum_weekday operator+(const year_weeknum_weekday& ywnwd, const years& y) noexcept; // constexpr year_weeknum_weekday operator+(const years& y, const year_weeknum_weekday& ywnwd) noexcept; // constexpr year_weeknum_weekday operator-(const year_weeknum_weekday& ywnwd, const years& y) noexcept; // // std::ostream& operator<<(std::ostream& os, const year_weeknum_weekday& ywnwd); #include "iso_week.h" #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert(!std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_trivially_copyable{}, ""); static_assert(std::is_standard_layout{}, ""); static_assert(std::is_literal_type{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert( std::is_convertible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert( std::is_convertible{}, ""); static_assert( std::is_nothrow_constructible{}, ""); static_assert( std::is_convertible{}, ""); int main() { using namespace iso_week; constexpr auto x0 = year_weeknum_weekday{2015_y, 52_w, tue}; static_assert(x0.year() == 2015_y, ""); static_assert(x0.weeknum() == 52_w, ""); static_assert(x0.weekday() == tue, ""); constexpr auto x1 = year_weeknum_weekday{2015_y/last/tue}; static_assert(x1.year() == 2015_y, ""); static_assert(x1.weeknum() == 53_w, ""); static_assert(x1.weekday() == tue, ""); constexpr year_weeknum_weekday x2 = sys_days{days{16792}}; static_assert(x2.year() == 2015_y, ""); static_assert(x2.weeknum() == 52_w, ""); static_assert(x2.weekday() == wed, ""); auto x3 = x2; x3 += years{2}; assert(x3.year() == 2017_y); assert(x3.weeknum() == 52_w); assert(x3.weekday() == wed); x3 -= years{1}; assert(x3.year() == 2016_y); assert(x3.weeknum() == 52_w); assert(x3.weekday() == wed); constexpr sys_days dp = 2015_y/52_w/wed; static_assert(dp == sys_days{days{16792}}, ""); static_assert(x0.ok(), ""); static_assert(x1.ok(), ""); static_assert(x2.ok(), ""); assert(x3.ok()); static_assert(!(2016_y/53_w/sun).ok(), ""); static_assert(2015_y/52_w/mon < 2015_y/52_w/sun, ""); static_assert(x0 + years{3} == 2018_y/52_w/tue, ""); static_assert(years{3} + x0 == 2018_y/52_w/tue, ""); static_assert(x0 - years{3} == 2012_y/52_w/tue, ""); std::ostringstream os; os << x0; assert(os.str() == "2015-W52-Tue"); } date-3.0.1/test/iso_week/years_m_year.fail.cpp000066400000000000000000000023741403643451100213200ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // years - year not allowed #include "iso_week.h" int main() { using namespace iso_week; auto x = years{3} - 2015_y; } date-3.0.1/test/just.pass.cpp000066400000000000000000000022121403643451100160430ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. int main() { } date-3.0.1/test/posix/000077500000000000000000000000001403643451100145525ustar00rootroot00000000000000date-3.0.1/test/posix/ptz.pass.cpp000066400000000000000000000077211403643451100170470ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2021 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // Test Posix::time_zone #include "tz.h" #include "ptz.h" #include bool is_equal(date::sys_info const& x, date::sys_info const& y) { return x.begin == y.begin && x.end == y.end && x.offset == y.offset && x.save == y.save && x.abbrev == y.abbrev; } bool is_equal(date::local_info const& x, date::local_info const& y) { return x.result == y.result && is_equal(x.first, y.first) && is_equal(x.second, y.second); } int main() { using namespace date; using namespace std; using namespace std::chrono; auto tzi = locate_zone("Australia/Sydney"); Posix::time_zone tzp{"AEST-10AEDT,M10.1.0,M4.1.0/3"}; auto tp = local_days{2021_y/1/1} + 0s; assert(tzp.get_info(tp).result == local_info::unique); assert(is_equal(tzi->get_info(tp), tzp.get_info(tp))); tp = local_days{2021_y/10/Sunday[1]} + 2h + 30min; assert(tzp.get_info(tp).result == local_info::nonexistent); assert(is_equal(tzi->get_info(tp), tzp.get_info(tp))); tp = local_days{2021_y/4/Sunday[1]} + 2h + 30min; assert(tzp.get_info(tp).result == local_info::ambiguous); assert(is_equal(tzi->get_info(tp), tzp.get_info(tp))); tp = local_days{2021_y/7/1}; assert(tzp.get_info(tp).result == local_info::unique); assert(is_equal(tzi->get_info(tp), tzp.get_info(tp))); tzi = locate_zone("America/New_York"); tzp = Posix::time_zone{"EST5EDT,M3.2.0,M11.1.0"}; tp = local_days{2021_y/1/1}; assert(tzp.get_info(tp).result == local_info::unique); assert(is_equal(tzi->get_info(tp), tzp.get_info(tp))); tp = local_days{2021_y/3/Sunday[2]} + 2h + 30min; assert(tzp.get_info(tp).result == local_info::nonexistent); assert(is_equal(tzi->get_info(tp), tzp.get_info(tp))); tp = local_days{2021_y/11/Sunday[1]} + 1h + 30min; assert(tzp.get_info(tp).result == local_info::ambiguous); assert(is_equal(tzi->get_info(tp), tzp.get_info(tp))); tp = local_days{2021_y/7/1}; assert(tzp.get_info(tp).result == local_info::unique); assert(is_equal(tzi->get_info(tp), tzp.get_info(tp))); tzi = locate_zone("Europe/Dublin"); tzp = Posix::time_zone{"IST-1GMT0,M10.5.0,M3.5.0/1"}; tp = local_days{2021_y/1/1}; assert(tzp.get_info(tp).result == local_info::unique); assert(is_equal(tzi->get_info(tp), tzp.get_info(tp))); tp = local_days{2021_y/3/Sunday[last]} + 1h + 30min; assert(tzp.get_info(tp).result == local_info::nonexistent); assert(is_equal(tzi->get_info(tp), tzp.get_info(tp))); tp = local_days{2021_y/10/Sunday[last]} + 1h + 30min; assert(tzp.get_info(tp).result == local_info::ambiguous); assert(is_equal(tzi->get_info(tp), tzp.get_info(tp))); tp = local_days{2021_y/7/1}; assert(tzp.get_info(tp).result == local_info::unique); assert(is_equal(tzi->get_info(tp), tzp.get_info(tp))); } date-3.0.1/test/solar_hijri_test/000077500000000000000000000000001403643451100167545ustar00rootroot00000000000000date-3.0.1/test/solar_hijri_test/parse.pass.cpp000066400000000000000000000205751403643451100215500ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2020 Asad. Gharighi // Copyright (c) 2020 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "date.h" #include "solar_hijri.h" #include "islamic.h" #include "tz.h" #include #include #include #include void test_a() { constexpr auto civil = date::year{2020}/date::January/27; using namespace solar_hijri; static_assert(year_month_day{civil} == 1398_y/11/07, ""); } void test_b() { using namespace solar_hijri::literals; static_assert(date::year_month_day{475_y/far/1} == date::year{1096}/03/21, ""); static_assert(date::year_month_weekday{475_y/far/1} == date::year{1096}/03/date::Saturday[3], ""); } void test_c() { using namespace solar_hijri; auto date = solar_hijri::year_month_day{1398_y/bah/6}; for (auto i = 0; i < 24; i++) { auto weekday = solar_hijri::weekday{date}; assert(date == 1398_y/11/06 + months{i}); assert(date.month() == month{(i+10u)%12 + 1}); assert(weekday == (weekday[1]/date.month()/date.year()).weekday()); auto k = weekday; for (auto j = 0; j < 14; j++, k++) { assert(weekday + days{j} == k); } date+=solar_hijri::months(1); } } void test_d() { auto zt = date::make_zoned(date::current_zone(), std::chrono::system_clock::now()); auto ld = date::floor(zt.get_local_time()); solar_hijri::year_month_day ymd{ld}; auto time = date::make_time(zt.get_local_time() - ld); (void)time; } void test_e() { auto sd = date::floor(std::chrono::system_clock::now()); auto today = solar_hijri::year_month_day{sd}; assert(solar_hijri::year_month_weekday{today}.weekday() == solar_hijri::weekday{sd}); } void test_f() { constexpr auto isl = islamic::year{1441}/6/1; using namespace solar_hijri; static_assert(year_month_day{isl} == 1398_y/11/07, ""); } void test_g() { date::year_month_day ymdd[] = { date::year{1583}/date::November/21, date::year{1583}/date::November/22, date::year{1583}/date::December/6, date::year{1591}/date::December/26, date::year{1616}/date::October/20, date::year{1619}/date::October/13, date::year{1627}/date::August/9, date::year{1649}/date::October/15, date::year{1657}/date::August/9, date::year{1682}/date::June/23, date::year{1691}/date::October/12, date::year{1712}/date::September/13, date::year{1718}/date::July/17, date::year{1747}/date::January/4, date::year{1756}/date::January/1, date::year{1770}/date::January/15, date::year{1798}/date::October/24, date::year{1809}/date::July/11, date::year{1834}/date::July/17, date::year{1850}/date::September/9, date::year{1865}/date::November/4, date::year{1902}/date::December/21, date::year{1926}/date::March/21, date::year{1926}/date::March/22, date::year{1957}/date::June/1, date::year{1977}/date::March/7, date::year{1982}/date::May/30, date::year{1992}/date::December/8 }; solar_hijri::year_month_day ymdh[] = { solar_hijri::year{962}/solar_hijri::Aban/30, solar_hijri::year{962}/solar_hijri::Azar/1, solar_hijri::year{962}/solar_hijri::Azar/15, solar_hijri::year{970}/solar_hijri::Dey/5, solar_hijri::year{995}/solar_hijri::Mehr/29, solar_hijri::year{998}/solar_hijri::Mehr/21, solar_hijri::year{1006}/solar_hijri::Mordad/18, solar_hijri::year{1028}/solar_hijri::Mehr/24, solar_hijri::year{1036}/solar_hijri::Mordad/19, solar_hijri::year{1061}/solar_hijri::Tir/3, solar_hijri::year{1070}/solar_hijri::Mehr/20, solar_hijri::year{1091}/solar_hijri::Shahrivar/22, solar_hijri::year{1097}/solar_hijri::Tir/26, solar_hijri::year{1125}/solar_hijri::Dey/14, solar_hijri::year{1134}/solar_hijri::Dey/11, solar_hijri::year{1148}/solar_hijri::Dey/26, solar_hijri::year{1177}/solar_hijri::Aban/2, solar_hijri::year{1188}/solar_hijri::Tir/20, solar_hijri::year{1213}/solar_hijri::Tir/26, solar_hijri::year{1229}/solar_hijri::Shahrivar/18, solar_hijri::year{1244}/solar_hijri::Aban/13, solar_hijri::year{1281}/solar_hijri::Azar/29, solar_hijri::year{1304}/solar_hijri::Esfand/30, solar_hijri::year{1305}/solar_hijri::Farvardin/1, solar_hijri::year{1336}/solar_hijri::Khordad/11, solar_hijri::year{1355}/solar_hijri::Esfand/16, solar_hijri::year{1361}/solar_hijri::Khordad/9, solar_hijri::year{1371}/solar_hijri::Azar/17 }; solar_hijri::year_month_weekday ymdwd[] = { solar_hijri::year{962}/solar_hijri::Aban/solar_hijri::Doshanbe[5], solar_hijri::year{962}/solar_hijri::Azar/solar_hijri::Seshanbe[1], solar_hijri::year{962}/solar_hijri::Azar/solar_hijri::Seshanbe[3], solar_hijri::year{970}/solar_hijri::Dey/solar_hijri::Panjshanbe[1], solar_hijri::year{995}/solar_hijri::Mehr/solar_hijri::Panjshanbe[5], solar_hijri::year{998}/solar_hijri::Mehr/solar_hijri::Yekshanbe[3], solar_hijri::year{1006}/solar_hijri::Mordad/solar_hijri::Doshanbe[3], solar_hijri::year{1028}/solar_hijri::Mehr/solar_hijri::Adine[4], solar_hijri::year{1036}/solar_hijri::Mordad/solar_hijri::Panjshanbe[3], solar_hijri::year{1061}/solar_hijri::Tir/solar_hijri::Seshanbe[1], solar_hijri::year{1070}/solar_hijri::Mehr/solar_hijri::Adine[3], solar_hijri::year{1091}/solar_hijri::Shahrivar/solar_hijri::Seshanbe[4], solar_hijri::year{1097}/solar_hijri::Tir/solar_hijri::Yekshanbe[4], solar_hijri::year{1125}/solar_hijri::Dey/solar_hijri::Chaharshanbe[2], solar_hijri::year{1134}/solar_hijri::Dey/solar_hijri::Panjshanbe[2], solar_hijri::year{1148}/solar_hijri::Dey/solar_hijri::Doshanbe[4], solar_hijri::year{1177}/solar_hijri::Aban/solar_hijri::Chaharshanbe[1], solar_hijri::year{1188}/solar_hijri::Tir/solar_hijri::Seshanbe[3], solar_hijri::year{1213}/solar_hijri::Tir/solar_hijri::Panjshanbe[4], solar_hijri::year{1229}/solar_hijri::Shahrivar/solar_hijri::Doshanbe[3], solar_hijri::year{1244}/solar_hijri::Aban/solar_hijri::Shanbe[2], solar_hijri::year{1281}/solar_hijri::Azar/solar_hijri::Yekshanbe[5], solar_hijri::year{1304}/solar_hijri::Esfand/solar_hijri::Yekshanbe[5], solar_hijri::year{1305}/solar_hijri::Farvardin/solar_hijri::Doshanbe[1], solar_hijri::year{1336}/solar_hijri::Khordad/solar_hijri::Shanbe[2], solar_hijri::year{1355}/solar_hijri::Esfand/solar_hijri::Doshanbe[3], solar_hijri::year{1361}/solar_hijri::Khordad/solar_hijri::Yekshanbe[2], solar_hijri::year{1371}/solar_hijri::Azar/solar_hijri::Seshanbe[3] }; bool leaps[] = { true, true, true, true, true, false, false, true, true, true, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false }; static_assert(sizeof(ymdd)/sizeof(ymdd[0]) == sizeof(ymdwd)/sizeof(ymdwd[0]), ""); static_assert(sizeof(ymdd)/sizeof(ymdd[0]) == sizeof(ymdh)/sizeof(ymdh[0]), ""); static_assert(sizeof(ymdd)/sizeof(ymdd[0]) == sizeof(leaps)/sizeof(leaps[0]), ""); for (auto i = 0; i < sizeof(ymdd)/sizeof(ymdd[0]); ++i) { assert(solar_hijri::year_month_day{ymdd[i]} == ymdh[i]); assert(ymdd[i] == date::year_month_day{ymdh[i]}); assert(ymdh[i].year().is_leap() == leaps[i]); assert(solar_hijri::year_month_weekday{ymdd[i]} == ymdwd[i]); } } int main() { test_a(); test_b(); test_c(); test_d(); test_e(); test_f(); test_g(); } date-3.0.1/test/solar_hijri_test/year_month_day.pass.cpp000066400000000000000000000164371403643451100234420ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2020 Asad. Gharighi // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // class year_month_day // { // public: // constexpr year_month_day(const date::year& y, const date::month& m, // const date::day& d) noexcept; // constexpr year_month_day(const year_month_day_last& ymdl) noexcept; // constexpr year_month_day(const sys_days& dp) noexcept; // // year_month_day& operator+=(const months& m) noexcept; // year_month_day& operator-=(const months& m) noexcept; // year_month_day& operator+=(const years& y) noexcept; // year_month_day& operator-=(const years& y) noexcept; // // constexpr date::year year() const noexcept; // constexpr date::month month() const noexcept; // constexpr date::day day() const noexcept; // // constexpr operator sys_days() const noexcept; // constexpr bool ok() const noexcept; // }; // constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept; // constexpr bool operator!=(const year_month_day& x, const year_month_day& y) noexcept; // constexpr bool operator< (const year_month_day& x, const year_month_day& y) noexcept; // constexpr bool operator> (const year_month_day& x, const year_month_day& y) noexcept; // constexpr bool operator<=(const year_month_day& x, const year_month_day& y) noexcept; // constexpr bool operator>=(const year_month_day& x, const year_month_day& y) noexcept; // constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept; // constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept; // constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept; // constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept; // constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept; // constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept; // std::ostream& operator<<(std::ostream& os, const year_month_day& ymd); #include "date.h" #include "solar_hijri.h" #include #include #include #include static_assert( std::is_trivially_destructible{}, ""); static_assert( std::is_default_constructible{}, ""); static_assert( std::is_trivially_copy_constructible{}, ""); static_assert( std::is_trivially_copy_assignable{}, ""); static_assert( std::is_trivially_move_constructible{}, ""); static_assert( std::is_trivially_move_assignable{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_convertible{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_convertible{}, ""); static_assert(std::is_nothrow_constructible{}, ""); static_assert(std::is_convertible{}, ""); void test_arithmetic() { using namespace solar_hijri; for (int y1 = 1380; y1 <= 1400; ++y1) { for (unsigned m1 = 1; m1 <= 12; ++m1) { year_month_day ymd1{year{y1}, month{m1}, 9_d}; year_month_day ymd2 = ymd1 + months(24); assert((ymd2 == year_month_day{year{y1+2}, ymd1.month(), ymd1.day()})); ymd2 = ymd1 - months(24); assert((ymd2 == year_month_day{year{y1-2}, ymd1.month(), ymd1.day()})); for (int m2 = -24; m2 <= 24; ++m2) { months m{m2}; year_month_day ymd3 = ymd1 + m; months dm = year_month{ymd3.year(), ymd3.month()} - year_month{ymd2.year(), ymd2.month()}; assert(dm == m + years{2}); assert(ymd3 - m == ymd1); assert(ymd3 + -m == ymd1); assert(-m + ymd3 == ymd1); assert((year_month_day{ymd1} += m) == ymd3); assert((year_month_day{ymd3} -= m) == ymd1); } for (int y2 = -2; y2 <= 5; ++y2) { years y{y2}; year_month_day ymd3 = ymd1 + y; years dy = date::floor(year_month{ymd3.year(), ymd3.month()} - year_month{ymd2.year(), ymd2.month()}); assert(dy == y + years{2}); assert(ymd3 - y == ymd1); assert(ymd3 + -y == ymd1); assert(-y + ymd3 == ymd1); assert((year_month_day{ymd1} += y) == ymd3); assert((year_month_day{ymd3} -= y) == ymd1); } } } } void test_day_point_conversion() { using namespace solar_hijri; year y = year{-30000}; year end = 30000_y; sys_days prev_dp = sys_days(year_month_day{y, far, 1_d}) - days{1}; weekday prev_wd = weekday{prev_dp}; for (; y <= end; ++y) { month m = far; do { day last_day = year_month_day_last{y, month_day_last{m}}.day(); for (day d = 1_d; d <= last_day; ++d) { year_month_day ymd = {y, m, d}; assert(ymd.ok()); sys_days dp = sys_days(ymd); assert(dp == prev_dp + days{1}); year_month_day ymd2 = dp; assert(ymd2 == ymd); weekday wd = dp; assert(wd.ok()); assert(wd == prev_wd + days{1}); prev_wd = wd; prev_dp = dp; } } while (++m != far); } } int main() { test_arithmetic(); test_day_point_conversion(); } date-3.0.1/test/testit000077500000000000000000000106621403643451100146570ustar00rootroot00000000000000#!/bin/sh # The MIT License (MIT) # # Copyright (c) 2015, 2016 Howard Hinnant # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. currentpath=`pwd` origpath=$currentpath currentdir=`basename $currentpath` while [ $currentdir != "test" ]; do if [ $currentdir = "/" ] then echo "current directory must be in or under \"test\"." exit 1 fi cd .. currentpath=`pwd` currentdir=`basename $currentpath` done cd .. ROOT=`pwd` cd $origpath if [ -z "$CXX" ] then CXX=clang++ fi if [ -z "$CXX_LANG" ] then CXX_LANG=c++14 fi OPTIONS="-std=${CXX_LANG} $OPTIONS -I$ROOT -Wall $ROOT/src/tz.cpp -lcurl" echo $ROOT HEADER_INCLUDE="-I$ROOT/include -I$ROOT/include/date" case $TRIPLE in *-*-mingw* | *-*-cygwin* | *-*-win*) TEST_EXE=test.exe ;; *) TEST_EXE=a.out ;; esac case $(uname -s) in NetBSD) THREAD_FLAGS=-lpthread ;; esac FAIL=0 PASS=0 UNIMPLEMENTED=0 IMPLEMENTED_FAIL=0 IMPLEMENTED_PASS=0 afunc() { fail=0 pass=0 if (ls ${TEST_PREFIX}*fail.cpp > /dev/null 2>&1) then for FILE in $(ls ${TEST_PREFIX}*fail.cpp); do if $CXX $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS -o ./$TEST_EXE > /dev/null 2>&1 then rm ./$TEST_EXE echo "$FILE should not compile" fail=$(($fail+1)) else pass=$(($pass+1)) fi done fi if (ls ${TEST_PREFIX}*pass.cpp > /dev/null 2>&1) then for FILE in $(ls ${TEST_PREFIX}*pass.cpp); do if [ "$VERBOSE" ] then echo "Running test: " $FILE fi if $CXX $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS $(test $1 = no || echo $THREAD_FLAGS) -o ./$TEST_EXE then if ./$TEST_EXE then rm ./$TEST_EXE pass=$(($pass+1)) else echo "`pwd`/$FILE failed at run time" echo "Compile line was:" $CXX $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS $(test $1 = no || echo $THREAD_FLAGS) fail=$(($fail+1)) rm ./$TEST_EXE fi else echo "`pwd`/$FILE failed to compile" echo "Compile line was:" $CXX $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS $(test $1 = no || echo $THREAD_FLAGS) fail=$(($fail+1)) fi done fi if [ $fail -gt 0 ] then echo "failed $fail tests in `pwd`" IMPLEMENTED_FAIL=$(($IMPLEMENTED_FAIL+1)) fi if [ $pass -gt 0 ] then echo "passed $pass tests in `pwd`" if [ $fail -eq 0 ] then IMPLEMENTED_PASS=$((IMPLEMENTED_PASS+1)) fi fi if [ $fail -eq 0 -a $pass -eq 0 ] then echo "not implemented: `pwd`" UNIMPLEMENTED=$(($UNIMPLEMENTED+1)) fi FAIL=$(($FAIL+$fail)) PASS=$(($PASS+$pass)) for FILE in * do if [ -d "$FILE" ]; then cd $FILE if [ $FILE = thread -o $1 = yes ]; then afunc yes else afunc no fi cd .. fi done } afunc no echo "****************************************************" echo "Results for `pwd`:" echo "using `$CXX --version`" echo "with $OPTIONS $HEADER_INCLUDE $SOURCE_LIB" echo "----------------------------------------------------" echo "sections without tests : $UNIMPLEMENTED" echo "sections with failures : $IMPLEMENTED_FAIL" echo "sections without failures: $IMPLEMENTED_PASS" echo " + ----" echo "total number of sections : $(($UNIMPLEMENTED+$IMPLEMENTED_FAIL+$IMPLEMENTED_PASS))" echo "----------------------------------------------------" echo "number of tests failed : $FAIL" echo "number of tests passed : $PASS" echo " + ----" echo "total number of tests : $(($FAIL+$PASS))" echo "****************************************************" exit $FAIL date-3.0.1/test/tz_test/000077500000000000000000000000001403643451100151045ustar00rootroot00000000000000date-3.0.1/test/tz_test/OffsetZone.h000066400000000000000000000050521403643451100173410ustar00rootroot00000000000000#ifndef OFFSET_ZONE_H #define OFFSET_ZONE_H // The MIT License (MIT) // // Copyright (c) 2017 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // Test custom time zone support #include "tz.h" class OffsetZone { std::chrono::minutes offset_; public: explicit OffsetZone(std::chrono::minutes offset) : offset_{offset} {} template auto to_local(date::sys_time tp) const { using namespace date; using namespace std::chrono; using LT = local_time>; return LT{(tp + offset_).time_since_epoch()}; } template auto to_sys(date::local_time tp, date::choose = date::choose::earliest) const { using namespace date; using namespace std::chrono; using ST = sys_time>; return ST{(tp - offset_).time_since_epoch()}; } template date::sys_info get_info(date::sys_time st) const { using namespace date; using namespace std::chrono; return {sys_seconds::min(), sys_seconds::max(), offset_, minutes{0}, offset_ >= minutes{0} ? "+" + date::format("%H%M", offset_) : "-" + date::format("%H%M", -offset_)}; } const OffsetZone* operator->() const {return this;} }; #endif // OFFSET_ZONE_H date-3.0.1/test/tz_test/OffsetZone.pass.cpp000066400000000000000000000030051403643451100206350ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2017 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // Test custom time zone support #include "tz.h" #include "OffsetZone.h" #include int main() { using namespace date; using namespace std::chrono; auto now = system_clock::now(); auto offset = hours{-4}; zoned_time zt{OffsetZone{offset}, now}; assert(zt.get_local_time().time_since_epoch() == now.time_since_epoch() + offset); } date-3.0.1/test/tz_test/README.md000066400000000000000000000021261403643451100163640ustar00rootroot00000000000000# TZ Test ## How to Test * Install tz.cpp by downloading the IANA timezone database at: http://www.iana.org/time-zones You only need the data, not the code. * Change the string `install` in tz.cpp to point to your downloaded IANA database. * Compile validate.cpp along with tz.cpp. * Run the binary and direct the terminal output to a temporary file. * Unzip the tzdata file that has the version corresponding to the IANA database you downloaded (e.g. tzdata2015f.txt.zip). * Compare the unzipped txt file with the output of your validate test program. If they are identical, the test passes, else it fails. ## Miscellaneous You can also compare one version of the tzdatabase with another using these uncompressed text files. The text files contain for each timezone its initial state, and each {offset, abbreviation} change contained in the database up through the year 2035. As the database versions change, minor updates to the set of these transitions are typically made, typically due to changes in government policies. The tests in this section will run much faster with optimizations cranked up. date-3.0.1/test/tz_test/tzdata2015e.txt.zip000066400000000000000000003636101403643451100204230ustar00rootroot00000000000000PKAtGtzdata2015e.txtUX UU_D}?bǰK.vf ͪ]oH.?PŸ3CUam=Γ ߑ\?_wdz~ݛ˗stݍ7]o??L4*/_OkwW 쯄WD}ŲZ;˻zϟ| \u7}Y|l4`[ *Nv p  ׀~z8i{N>Oj+a?j/C~n_>>~ֆ?˭7֔]XZ;an\h?6&ܚ.~bMbX/EXgaw ga8vi}`DQ/= (q[auWUwⵛ0]qdpr{a[߷fx+`6SFrMl&F3wkq~mXtѡ]3ж#wm ˓b 38Z䣡[nuaC}{`36S ^:}y__Wzǧ+[ wn 9n1/*_sקoܽ~}x3+<3˂o_s|P h/5݅_y+-~|pjUw)nmF ?mIFܢ$X2?oAHKFt+1 86yKa p[K: c:M~ Y2*lƋ/&`W"\qPb3Ux|Bp8-*BXpԨ"^VN)`hy`]z^lbŰ*R b^ URxbnxXר+T1jT1*T4 Eb)ÀUa.5 BpU0x)\WxPk.]4 UD*"WE pQt UE)TQ+W<(\EkT5¥KP.AQ.AQ6 U([JP¥KP{*JP_zG_y_^Qf|׻ އ}z7/}v{2s83NE;/6T궞 {[.ժZVvjZZUnjVժ[ZUkyD|rxO==amX:l. bMg_^]9n{:鬁2/N=J%#ٽT&YnӵGkp9p,6Kg\zrOÔL!ҽFUi`Y<{x <(4gWG,4 pԨ"r2//(p}x ë?FV4o<}޾?\q?ٍ{qӛ+f-ET;Ï^?WۋLJ]i3?3^ͥ/.?h"/劫yA]tw0~ëW|gg,N&. q9cq.}nS7ן{rvjwgO͛IN=<<|wO?y7ǻ=~+eC/zIzZrwpmpkޞ.X<{18)p!WIӀkJQ`"L?Qs+F 8(QS{eD|DQaߝ.^Ds5sYgW9EHapqEȃJإ!V1+Lo/w!e|2'hw <[Cbu2a*NMI'u m+{Au`'Yt.Xup˚U杳/>-|E~+..lvݥ~ݥmiw?pp_rL,}(#1eTwRA(^kY5 -q(ϻkb]k N[kbۤtctG9ò+'Nb[㮫 GtQ:<`KUOAGUt*Q:x$jJ<`G@Ux*F*F*xAcH]:.a0BW_`PE~eK=xIq 6=WE: \fШ+5KQ&(T4 UD*R# 3Kz̥Q\*Tz*S"1^c.>CUx*F*F*xAc]FKu U8UBr90sܥS*\UO^Ο~8}Z;% 1iS1Sr~׳^ו"vsɇtϿ2AG,9Ng_Zy ʹn5||se6.՘WGz s{*17n%RNbµKĊp %\7M/b70G =xݼnba =B!t܏SE<[0܏SA<`z! zgJwW*Y~#.n/ӏM)&!;=c g_ wܰlT7d#n\)׹)C4ޕp CnrE\ eܞ!\F AW-'w~,9 =D"*PV \CxuZ V+nO:Wpǫc+zцa+Wzĝ?d\Cq)!ܹ6CvYͬuMOHS!S \̘RwONZܞaID2=Ln^aoȏM7sBQf 2َ-Md~l tӃ\! nWm~liVԃWaTaT!(v܏m~1=!czp!Mcvs- c~4T%=pOZRM?w#8^Y{~Y& .-d ݜt%K]YDJ%?t'v $ d YR,Bd!K%]@Ȓ/ dId YR8WS Vw9V9Jfe)5]]v*R+^~=o=LX;(cyAړ4hoi#;NM~:;6)N^A ׀GxԀ4G8xZ;b^XyԷ@i nwyq>{K^q+¥+QcppȻ5KjӦجMuX.bZv^?v7CwiYͥ^6ڳ/^yNnd'zc,`V` \荑h8*ik *d|v Ӏz xP50* Ax^Px^JsGEE]<` ^ٶL-15le5\/`E;/z+C1 e[Zjb?P8y3%_ N;% WyV t菋gϳÀų瑷Va[z^f< &hT U؎v gXpik*U: w=75KA+T55 ]FKu U8UbP)͌x)\9K7Sy%:營+mX^|֞^և׎S|(5l/Ï.xDzv;en6~\s{P^Ô=^u~9?cof{SnaMo\{sUc3nދYXGU کJ?*ץqpe-~~M\qvRor%x+Byq "ܜ "ܜ "ܜ "ܜ "ܜ "ܜ rWɠ*w "ܤ_pTa "\GJnOJnNnNW+ ݪ;.A "ܷC8lp48];j5廩!pmǀn}Y;d=W+&|w~ ACT!r=؎vnd?\ZԪ`Caz=vہ =xFFnAaFǮzH-:LJ=|!9;\=aᇇ/fw3Ͼ%,/ڋRW_g FVӝ=nI7jǍ]; Kiso_޾79W"j-Rl) ,~zn{2B엗˼J8\ԓSyps~m(s2mJ5leC`;B2nmN5N=#ϩF!p1ޠ0!`FBFA1^T/*\uܥLpU,[9 g*U9nesis^0U Ux*xx¥].FQPEqUx¥ӠҽUw\coxJ2ƾ܉ "7׹e#p_{ymt.L) yo2M_ceU#\{lc-' y~Gt@j }v.Fr_]eR@2B;sww#?M۔IHSە?S0:0.q{o Ν;Nrx+# u-Bv^\FMku^%wMSnKFb:Wƒ%#{`dC`k'k?L(ݜvseRKkHf{P;YiyQiyYNf)/ 0KUYeR_,kG8xZ;bj /r@i :8U+U0_,k 3t=0:Y_p 9qYR"CͫR=+s)=+s)u0iG`*4yc g.KSsv&V8GjL1ǻ~ᗝ믿.ʟ{ep+@̷tunKtxKtxK_羫Etx}vKI_x c)NZSKyK_yKnKyKyK_W{mݸ 3 Nܚܚ 5ӿ.Xr\s$`9 %Ht`0^9 .Y]+TQ`VPbXrVY]rV[볺QU䰪!W Ք̥s`t2NUW:s=ϲ[1jTEb..`QΧޠ} RU3XΜ`)J|C)J]:|Uaժ^+WWk7rNߠt2"*TX5#Uqxi\33^ ]:kf.5CUq̥--V hAaAi\3s4bTbԨ"(T4Ƌ EKq̥p*qHK Szxi\33^ ]:kf.X&zo~p-.cr4ibǺޔn0s7k?ܔ[Jyj%7R7(R3lS{\96p<p<p<p<p{juyJyJyzBrl*ʱv ɱMsM;6UsޅcS}8y_޹lo4Qu Q(Eɡ;i& uUʼƴ6wtq»]7WLʝ7C/ ҟjpnCo׶~hMCtIUzx'N+6տ*\\kAsv}QWyvqvbY|Œ7ƔZ}YϝuA-<0+++++un0sKJJZatnV: W: W+zzz "aP:tz(kJ:ǥp{aPwOLJ+Ww7Ħ|?N1rQ=#n7!\ckms;>Lk$wb>) >T4\=+}H)RCJ) >$׼҇Py=&!Q1){>Tʘ`ևDPW+&E|+E|z =D"C)sKǥp-C)\Pv+E|;p?.E|z = = =݂nq)sK_[p=">npR=C)qE|?=I2bz!J~\Vj'MeuiE\kWZȟ 8Upz|@ک66#Aa[~Q疱T26jCPfSm v 26jC`4r+v =Bvnv5܏SCZҨE2f{v~ZBBBAa[~l#2Xd-|SmݖS6ԏSCHP>W/'cmBL˂+I5BγRߵzwWFNmHZj#*6r:Sm9j#kȩ6rz;GpJp/7w]Mx|siVTZ?h(kT۹ e$UoC3QFu^pm6|[ x\cCsQ߫ǏB>v)<M)g>u^p}u=s]u-vk;um纞۹\swk;~z6v9ڎ_=Wvj;~_9~i: nw&u#X6ǰ=Djǻ=[_GWǟ_tnܘ3Jۖ{PRR}J'Bgْ?@\g7w N]9r]xin.bIc` $` s os`PŨQŨPE/(7g7 \:8e*bU2PpU4^x)! ]::ұW"\qP" Un['k?yq?ӒƌS0+/e7i]Y]ؿֵƩx WB+5׹5kOk`o+3W%oیΌUpS/x#t >7c7#\Ky, lԭnKGny,X: =xX:zc7(se,tztkd,:2p{KGB^a7['ܑnP!*V}Up X:T>uT>};P?^W+,pZ/eB:< p=xLnL*2O\ xL ܏az4ׇe.>,-UIk$\* pCJܞۭT%* pB^9,pGL a2RrX&rX&ZnrX&:La;(v #;r?n1 C>>>\J\9,p* pLTÕ$-UI+eT%v+UI+eT%nPwz(UIv a+UIz =D"C9,-UIk$\* pCJܞۭT%T%W+0*0*v Eǥ*-eֹ* p CJ\Vq?.UIs=w[zpʰ`{c&;,X_]D9gs%cYoDɅٻk@ׯaS TtdhO%Qx[+q89\V+q8J`pBQPun WkJ`pC nV+q8z$0Bܠ7r?.:WkJ`p-[ ~\s=8 =xݼnܑq nP!*ցw\Cx\KzXv[w~W+ q8J`p%0\ ׹%0^8J`p%0ۭW+qJ`p\WM+q =B\r=8:ܞۭw~\z = = =݂nq ׹%0^8\V8\%0^ë+ӁgŴKXΓˁjg~ëG9w3سȗ+%= =Jz 8S{88}9\ʩf~ ׸//~awp3?턳7-&*A|㆙{g˕Hkrs_~حBĴgZy=vmiSncpa.\4ɀ:9wt_>6A6 +7Zn݆iok^ȯ7 W~KmǵZO<;ۭڎk=Z7y~mǵߣZFnAaH8Zqn;4ߎkzhǵZOMpqƿ>ÝweppL{Yni#\3ۛxEڔsDMƔeA>ndm\/]yŕ4̼ F|\8,9y[㒗[6ʏ]5ӴV~짇wx3A˂]Mv$m~&ylDD~}Km;; 9 Y](KMN: T9UpzU#n?s{ĝ+ a:r;vwa~a!wQ\1isrQ:grWgݜvKF1?NݟpYMƮwz8[+mg.s'uYZz =E\9mM]KXwn˒={3^r: +'hptMֹ-ݐk-ݐ *ݐsE;r(]v E"[W= p/q[g_ξ/spuξٷξMඃ6@jn;mSMඃ6@jn;mSoSطƾZcߊ>j}+W*olV7/&u3>\$gWfL 5}(1~҅K+{pS^}S35ppmn#n [dqz~_MfrS-zM1ߵ[se Un +9+U[rVunYWrV+9+c :WrV+CYW+&9+঺1v=o'ܐ`RʠY:M [&WS{զ|zkvrzB雇]C:,(,r?.9:7嬘J pMPJ pmJ p]cY+9++&'}w~ r)^YqS]jܝP?Yq-NjvrV{ܞm'Ǖm}|(Jp#u5P9 H9 s@{\Wr@{).K9=Rh_qBr@;ܒs/r=\qv܏/^K9=å7(v)Ǎ܏/v%T^q r]q9=np1t[r@^߽|o;93[f;i)3ιЌsZSMě=3 W@cs;k?8z-ߠzE#/6u+ߠ+u+u+ߠ5hpw˻Yi2Y3jW&_FiN-5lM-/ZUW24@sraSҁ:)s`\SЃW+6NuܠCP!*|:\\Psz(v+w2 pB^B2 pn2 p#P\+k.A]glj׻Ԯw\dlW26+:dlܒ\dlr Jp%c=CP26v Ip%cACT!r=M[26k Z\P26s ܏KpB^QQ[P-r?.:dlܒ\P26kJp㒱ܞdljܳ͋t`u-is}ITx7("-Ӣ>-E}6_Y=h'-zТ-zТ-zТ-zТ~7_"Myr/>Z.P皼)\7kM\{q]@\[sZp!+z(ۨ:=87(WߦD;8[ Cnr:oq?=Cn^aoG1(z =DuۼP?B?>TZZG0z8ny-uPpB\ Wz+A=^[zun WzkJPp%ܞwz(A= y$ܠCP!*JP-A=5܏KPp-C z(A=JPp%^èèCP-(^[zun z(A=n%q nPz5n ˧7ʨTQH~eMeK=]CYθhP`=}^" .@ Jp%\DW"+@ zBQnPM"+:D\z(@n%qnP";(v IpG%AC%j #r (2ԏ@T :up{ ԏ[Y_+ke}Vr[Y{]oW1_NG{re7܋֞_c?sYJ?a>AkymcF|G>T?ڥĒp"ׂo1[O}=tسG|. %ӯڇ?Ӟ,M_/_>bZ;#V.,8 :\.l[m5S+<(` 8hQ pqvk~&x^rr[?HxZk{K^q+¥S{ xQJ5 9 hڝpeD[YVvŵ;1-N/^[O@8ր1cz`'u"|5|)S1uF ޽h-F F-Dt*LY vPV8獯_jy{xکA1ǝ1qLNnandžlk7הdj˥f1׶Զ y:dQytld-!,_=+gn>Cp Uu7n.?b7G/W;(v JpBAk [nzŚܿF/.r kJpC^qKjk̘+x³s"3Dεg/(h9!r?C\ȹ s !K !˦s"6 ‚Rȹ {6 6 Ƃ^c\ȣ»& FQKWilwJbmam\!{U^ FRC\ȹN s"J5DbBZ5Bb5Dj*,(k+9!rІ!І!Xk,+9!rh#h5ڈ mH!K"wK "[6 BRƆȽ‚RȆȃ» F^QQ`X0*[JYjY(!eml6Dv 6Dڐ:YR Ͽ??<ݽ˗W&߻<~z! ۆ6n{vU[u8QDxT#i*&I$-wP,nQ3Jy~szJޛw^-`{u *Lkܜk&\5n5RJV)*OR4}Ɩ%q[Ɩmlolxm=pؒӴp[ƖSmlI%ml:Ɩ%4o[Ɩ[["o}a?B$,@"DqJp$,ܒ\IX$,W+ Jp%a{\IXЃW+& BQPunIX~\kJpCIXnV;zIXW+ z$aqIXԹ%a\PkJp㒰ܞ$,wP+v܏KpBQH欷EKX\䶄EKXEKXunKXEKXaٕ3VrKRI Mմw,n>`wu5 )(d Jp%YsK-d Jp-[I$kW5s=d \%Y^a7$kW5z =D"CIԹ%YqIz(u\%Y=[I$k+zzz "㒬sK-5\%Yۭ$kq?.J-ɚnMf9ve7iz$eAZg^&{6T]|sim:s}FuZ}|'xܽvptᰜ3:׳m8:, .n?xnoSLӅҟ8]x~Y1'^88-W܊n#.k=xxo_޾f7CmWX8c`pNIT0*&{]C[mSj5Ε***~$JZܜZ%\InNV7V W{W+S+U =BARĎMRkKjpmz()[ҡ܏ә9z9TBܠmpۡPnI]~8Tts5^R׀z = ;* nPMN Z55r.(Znr*(:LPʉ;(v i;r?.gnP!*ָi5ԏ}Ӏk}Ӏ}ӀSw~\ЃWAN\)\9ppOR:WJqn.!\)\VJqWN\)ܞ롔PJq+vS>WJq7(z =Drg[Jqp?.8kJ):R=[)܁q)\ЃWaTaT!(v܏K)N[sK)Rۭ~\Jqz(85*a<㶃;':n;4ONﷃ; ֹܹvp y%vp& |.ᶃ;7\vpg}msO`o`s s6>9ا\ms7\}?`>~-o+8|{{fئewq@~|x|swvkُ~c}вKk_ӅIq GZXbw9zx|}_O [~&ֲu]Zu]:u] uzPHu?`T80?nG.#6v¦.pۑ mG.l sۑ /޼l|+8tϼKk_J6q֝^e^;ߛ. .~_>QJ՗IkyPs'3!;pRs 1b [O5y- YЈ˷ K"  pM'`wYoS o:g͞sK*rӐNANeL Wj8}$V^epU"P*x^ct C.E4 UD*JIQx¥KQ[*JU;*JY ܥ sRX^QQ0^/rNcҥNcR]FR^VaR_Nҥ{fqgM%o^f4+̿Ye}Ѳv 1Ǖ۾]ܖ\rpe3΅5svkm2̚4_9H[nn0s`Y^?w, MqC.76u:uy6 JO/|!nr&Ǖ\iӃs67ѵF\ p-[\ p;\ŽȠ{͛w~sm}z4|.{Q۷oosN;2ʙ鈝#v=b'G䈝#vr{N;9b'G:#vrNu;9b'G䈝/7o~GN3kS} ̿K[dȳhO$˞3Z>o+<jX}bGm><>0.X=V:Sx܏k>or<>,ܣUU8)n>; ;(YZwZFōw]uT@%e<* ,JG=* Y|G,>,>[',#Y|GߑwdY|׹GߑwdY|GuwdY|Gߑw{dۖ?h!4rZ5$Gh|8Gh>͇p4|8p4|8G?᧗^57֬1 _ss27n<忆q:m)䵝,c/`=_T;c/$c++@;W'W!r%p%pSj9rM儛R 7nJ-'ܔZNO)p{n^a''ܠCPaTaz?ǟp '\ u\/q&q_1^@!}zHy"Bb",BX"`"6$\VaA  r rІ WhC5 "-DmmXEM.l."l6";"`G@"^ F & r& r ' r' r ( r(Yb l"""w mHl{6$^cA` 0 r0 rh#h1j1*!aB8"H"[6$րN 6 rWn8 hk1h1h4  -B!KB}@d)fD ShCbmrxp궖n{]o/M x^b7{2o1ANv,;3_jk_ c`ßS8 8gjW)gאaO67H\!H\o$8H܎!H^WMn$qAQ꡼7y\H\KPH\GPH܎ڭ=D =xF"ʍD+7Wn$Hls67H ۱}|nyz = = =݂n#jkap-[>8VzȇW_T=7LZwJS9Γe@SI ɓerZrsǭRnSnWRnWRnWRnWRnWRnWRnWRnWRnWRn+zz I JMSnܜrr!v)7<)7q=+܏W)7/Y\bx1W+^L/&pŋ>>orz2J/&Zҋ bncW+^L/&z:˔67{1\bx1re/&pŋ Cbnv pŋ Aèmnb8{1r=d/&:܎-{18{1+zzz F>^67{1p=d/&Zn\qbn-n1|s훻jLwӝp"R_c]12zƱ]cq _|tW֞N#v?I\=mW{3Í 7f=.c/dv49e.ngmk.=mk=m˧⺭q;_u ptqRkҥRks9\3kp4kpp͜>Ƿr{w_?[Nn㝙_ڗ]D/÷s̶h|GOn:_٣墔\~7Zv_s%<쒱\ +X'>U O,9A!ndOm䘜|-ndzp179W>)8PN Ǘ_Uݍ/%zP}r.~6al}?5~qDw88/ K4y&`;K4% D,_E^XhAhK4v,K4ͫ`Y[༔9?&j3lv:F ^|{ZMnF .^z RϢ gKtW+nQ^}Kߎ]]hC }h\ Rp/J_:+u|Wms67_*\Trp-CT!Gvˑi<Αi =xR =Hdpnܑ%kN\92 !Gr= K#pup Q{]q:̕Q{]q:}z;e~ةCT9@גIk&p]ww]{w* p]w]ww;uW{To}uuo|4W ߚk*΅jдPvj# :GБtdY@Gu:,# =,# o{7*GQ\{??{x{ZgmZXx^)eg\]?ԳM>tPø]i IlQ}ݜ-Nfő^fő-c`VYJ`VYʂQe"ͼn:K'vBn1 /y_mpܒ'Ο-c)CxkCr"1^Hm1ePWcXdIC ]^KY}$,G9O (Q7vg ^xw=crU%^<|4L{Fz6c_cΡtPm=q_EF$Q{O~uնozo;N.S5V) HX*z 7owW^W)z[oNΖ[JݎMYoߕͷ VYd S67e d n$\ܔ-H-aIk"ܐG7e!G\B\v{ 7@p\B+销)ptJ\9pCN܎-SnםN ^CJ$ANIAaNI#ǒN 9pS:%I$\&锄x7y\1mSn66)O"t;GV͛YNWkTl/ |Hr5'5> |-6GxT݉IF h(~+)C46P,V:^^ ı>EJ|NÜcGb]$!|t-I L`K ,KuXn pLl|+5ҝ3i b*FB11q+7^3 lQL`*bTEp\1"tx1׀S:&)P^XMW F>sJ0ǔ`qތFvrU3ٔ^2bF01N㪈YPcU1  |B!e.Tr"e )]&`KU*b[SRE?`S:PtJ4cVBFNi7)B_d!pB0{@`3-|׊&c"eO<_G15\ YS*m4n.ƇoՔ`*xH A1^Po<_( xLdmUӭ*bTh*b4hbңS:f[AUWE̶{*xRŔu^8hT!^xԨB*)  S,6^Y{]T.o4J0(/[6Npe'&]+os;$ʭߎM%L|Wo`;sn$ӎtpZ`vB)3hssj<-'KWOW7扳q= 1}!nЃW+6y[ nP!(0*0r=Hͭy[ zȭq=VqVu=\ЃW! Ajpn|Kͭ7 \ rIu|K =xݼn|K = =TE&? ?z(Ovne p{:zBrp-tkn1376vbS =̗Efn09p-n1d9 7׃bĉ =xݼnqyltpBAQ!>8z&lf;z>mq 3A=xnAac;yCLL-C01=8,ny1:]{~h_MwӇnX`8?1n3]Frc+$LrӉw7>+n6W3*S w)+n|Mn|7>&7>8pqc1xv oi}ߘC<_>q, 9YZ rr#4&Gdi3Lhsa@"KaB6 mvÄl 9ShC+!D z0!ٝ[rhchc(7EP EX-F@dQ,]k5HDN!DN1DNADNQDNaB8!KSS‚,@-@.@N  rІ k,5LQDNaDm6F6F6$v@<@d>@dІ)!!D "-aDmx666ƂAcQ1%@O d ( QhCB l";얰"w mH`MΑw~tݫ_sQXzL^Y'ݷxuJӶ^MeRf3fq..c2V^Oqtm|dBR+Ww@eqbR;}&9;ƶqۜMM0亙; nqfnU&79\ЃWaPaP!(vS̷gN\%&p=w8\V^lr &z(/p6ruzm)bylV3ډckyn}΍gqiNkw戸sCyn2xMnm flv܌ؾ#EzXlǮr,3o;C:&W4 cZW4QRpM!v{݆\@6.]\{16]r]}r}*^a7ېjnP!(0*0r=?} %pMڗzRV p׃w܎w)p{>sI =xnAaKmnΥ\s)r\Ju|\Jr.%\9pn^aK AèK"9p 9p-CΥ\s)v%8D\ЃWAJ"WJ"<ƕliӈXj"5\p&JMp&JMƕs=v IMz = =TeM&Z&:&vneM<.k"W+ 5Wj"D\Rp&Bk"&JMIY)k"D\Rp&JM+5+&5Wj"nP!(0*0r=mnN\Rp-C!D܎-Dܞ\pB^AA[Pm8DhssM67D\k"v5yk"nk"e*wUS IR~͏/ǻoʟncʶ x;T5DW!PMm1À .1VNܐܻRp1&osk'W%99 &ksVe?n_7]ojť ώy>?X?{7?"WM [86c[_IpgP|2I({O֏(ytk\i= vnj5xWۀ+m6wpŻ \nxWۀ+m6 =Tw-ۀ+K!wp-C\GPzv+ۀy\z+z6wpŻ \nxnswpŻ \햽ۀ+m6v\ٻ =CnW+&m6BB#Cnٻ \ۀwp;nܞ\ЃWaPaP!(v<67{\ۀkݲwpٻ Cn1/|mV~xW~:2⣘6A棐Gݎ]9Aϐsʯ>*p%p%pS ^~J7J7݂n 67~-~zȹ߀r7vn9p{>s7zB B Aa7Iܑoo5\9p-[v8;zqz y99AQtsp ǥsp-C\GP:v+y\:+z8sp9\q8ossp9\햝+q8v\9=CvW+&q8BB#Cv9\sp;nܞ\ЃWaPaP!(v<67;\kݲsp9Cv9~&S6qyZ {ҼiT~- 7pcS('&'Uom=@ۿm5kWR 4E J/MEW~nf&\)J/MY҄+E@[Β>4q;nܞ;9^ЃtAAa7#ǹ_kro?n:>s_?rW?z yݤ|~~zz^~-n\Cq\KP4Q= ʀt =xnAa`ঀJ@pgJ@pcJ@p_J@p[J@pn^a7ܠCPaTaz=\qhz u\9[hnqhW+0(0(v |F9!4r:>s@p;hqs@znܦ+^?xjfV.ʥQ_\[ܥ{Գܽ5A2b:~M]ץE;wG1(p^Ǟ7JPҽ=o ͥ{(1(ss^2y~3m7`[1nis;*n &[wunr9[|#vcz y݆nH:ܠèØ!t'n_ͻ\~ <:vFR~7C.?>vkhqY?oټp=npk"w\ם p;npu'w\q.sAqЃ8\>yzq=npqnpyW+0(0(vSs78<>n/\qwT8*+Q`@wT8*%pTXq@wT8*Vܣ"*pT8*V_QE7^thڟ 7u\|`7KG.\e&#{.G~[nc)p%pSJ<•6f"}# O)_pS# \&y+y{#8 L"&$p ǒG@G!n8WAwPA7(kHJ(8rzykrZnGGC#ܞ!xB71Rk\햯\C=C^a7\AèЃmss)67_\߯+WB+NW(nPu(i(N-_Q\ם|E p;|E p{|E pn^a|E pBAQ!:mssp 9Z!Gq=h9vn9Z=9Z^Ѓ:A)u Aa7)u #ǹi+Np=RkrSu|Rq=R+v IS<ΥN7(0*0R=N[2Z2Zꡌz(Qr<.zhy\X:\:\:\i+NWkrp)Jp;-ܞ!G+vR+r =FF\r5|h9Z-\qh9|h9zBBBAaqikrp-[8GzW`37~,w3pZjlcdM9vP;;Rk}Ik'\5ɑORk p#p&G>ƚ&G>N§dz yݤ&G>BB#C#p '\ |u\gfKՇxS$ܒ#DD@쉂Yn@4rWv"m9B_ K!69B [s:ȝB @^  Xk,(yP|FF#FyI.l.l6";"8`@"@^ цܨ#$@dSG)LrS:@P":BND Jv!"w mH{6$h^cAܲ#8@FhchcTh#ߵd  Qn UhCBڐ "w J{@"{6FFFAcਘP |%F * UXP [ )!69^~R_O5o߬kz1?z`;vu -4!*/ :_Cz6r+Ȁ\J62e#׸ {5d#^6r+Ȁ\zk\FܽlWw/ƕldFps6r\J62e#׸m7ƕldFq;lzFqn{5d#^6rzFqGwe6r[Fq ǕlR=Tk\GPFq;jJ6ry\FqB^F\F\F\F\FܽnFnss62J62J62Zn CFܞ!g#W+&Ȁ+Ȁz = =\9Ȁk<Ȁkr62: [Fܞ㜍 ^ààCP-(6yܜld5\9p-[F\qF܎!g#MNǷo_tN)+wῊ'3;'V1wckqݷF2yv[ZZ<ϻ31׳1ēGtP<וn}\1+M{'wO?^ֺaO՜.?դe q.o?##s>=&~2~;rtebcRh ukqGL^ C"d0!TZ AY2L٤#B3Mc<#O]Zc9-#w m q_jh#L{ Γ3r*!} 9h1j1*N ‚SLϮ`l;̻T֍%Ǵ9gw AmNai,+fw;x6b1S &Tښ}SXwOĨ/߿Cqj!ڛ}| }bvXɀi]ż F~]\%Ϛ|'ǽ/} ur|znȒO<%M{PBr`d偑SaD爜*#rsM<,9=;&#wr vK8}~"XX,w; ONXoS_yxZQOmDz&rPig$`iXN%` pJ;2p* &V #S#6 UUwxr_W)Ta:< UxxbJOi4 UU\4=qpJ[ç UXUaBqU.xSWLi)hPUx***xAaQ1ȧtjp' gI-L*,7s)ҮSuTo=CO{Z|>?>{痷oڀ l)X4gXXw3ڶqSXbSDdo,5!81S7jn1:mpgS;V̓c4&`K7MN%Qx??-qvH@`Ex>A`["<W;|0t&2H'CQLA̿`qx k~Xxko?`AA1^Poۏ8xvxRb(j`sf l*ʦ4nfGU!Y8윙jj#?8FPpA 1c5j#?8FPpA 1 c5j#?8FPpA 1c5*#?8FPp._?\ֻ[?w3+JLc‹Y&Z ɃPt:σ ݔ>UThAw*tV]fھl{N:  Beigtn5A/޼;*$:yeutZS'7zNc(-טkfcޖ =,-ٸU ov]hÑoft! _QHᒡVH⒡;leO=[ǙČsM~<>SRE&5x۝<w p ׀9'AO&.)? 8(qK%kS-_N| 8h^E*K|8"$A &L8^@a:^  +VS"n 3^d pLGvt BbJÒDA1cR3 8}zר+T1hT1(T4 ㍊)mG>I%JTBpU80x)s|JN QU,.?\kdM7B7L^'xţb~"OCy//B';kѵC;?qvtBBZ8BEi6:::::F"C噛h !"(V&)ϣ7  =ԟK9$Ine:KL:$нFNDhY$ЃfUP&Bͪ LU I6etDhW"Ж+e" )Bq3LDO , BF!J!F!AeƠ1'xD7Oܠk'{|m}w=8y6qٕӍ s̶ο}bW^7Y`oS ޸2;?^mxٔ<4N>ВgZZZZZZZZZbe:߿9__-I~bBw߱y_EK`M,  baU^0ދUђaDžWEK B;N}tFI-I-WHHЎ+L$轘[tci.d,j-.tkVӯhݕ6+wbA(Hhghg$h3Jh34%4 vF vFF;F;#Aтf;f;>vFQ#wF-;#:R쌚rgF;#6hnvFmBʝA;rgD7c3jW?~wݍ"-;秱av'۝Է;UUvgANB΂f۝f۝Ͷ; Ͷ; mwmw4$4,hIhYllpvgAle e? Zu晿X~|u^|,kDzv,kDz?cYW/j0]}KY_Ǻ"p9vʺ;V+I~<'NVj\c)r p;Wp)ոn͕pe\YfWV5peܽfn^_ܼYLvV5פm-<*Nu nv n Wp;(ܠ HkĸgxIiML3.o^q|Ҍ[Zp|KYg[J9#ܴ{J5{ޠnʡفniwg`#h˞+I\Õ՝}: 1d`9՟N#@[jNvtBw;*ZNBxV{;:zoYEm>gvUۄл*zwZElBAҪv|:kԋoݔ%zmv-ཆS2wYfmKCKC, XeC&lHҐ!KC*ʆa X4$`QWbШbP"h.P9qUl*rCx!;>sC*rCyŔ 8hT5*rC (tnHVܐB!w +tnH^ PŠQŠPE/(7*tnHQ"7$`0^nHN1sC Z䍺zb0$VflP$r~^޽y_Mo7ٸ@S 'Py66kJZ^f<=ۖy-p4l4`GSU VvGm{x!7EP/ x7kkzCpHA* pTkzòКe3`Ͳ= j+W{ņeP + ޫHh + mvR_ K]R{{d\F}P wJMMx {B5FMo0*קӔ,C5 U U UhJK!֔,jClɴ5DF7+m3hJǧR,*,d+T)YlxfSz @U*F*F )Y}BA ҋO\Kv\VSv )m{>TWbШbP"hSڎ|J/XU gX"H*,7s)NAf U,~|Y t7}:%u[j25>^^kݛШᰠQF '4j8,hp8QaA  5NhpXШpBÂF 54j8Yf (ds'TsJjfUwf?*KMOcܥ1{yuW)CASb6 oŐY9cep28uȿ͝ m5hB; S].g hiC.]AKv9-rZAhiй]Av9m [CV.'Җ_v-rۓ3y{FNyLнFNyL^*v9=hV.fUrzT)D4e6lCІ e\!ev\!ev9^!hR(dP)d($4fD/DZBm(d38n ;٧y p뷷RCL,_'jv3-7_ep+'_*v|G,uzd-;bi YGˎwHѲ#Fuzdw@61A[&e;=!NutQ^O:ګ5f4]1:BRYַ/qӵіlm !hG6v4: ZtM&h5A{O+A~&Ղ;oi!h#OoeGCz{-oC_jB0@mC'ڤEVk YˠBCih;Sv'Ci$hR(dP)d($4f5ݎNB!hB!jŒi&sdA+DN?߻jtns`?3xw7fC18Nv“4vlܟ(R;-TǦeK9\Wc7|x,6(n ڶLlZ r;w~Ï<91OΓ?}Pm+{"yeϓ\IW~*]eK~m9r[~q&vqDd<ʯyr?_i1՜ Kԯ*h MN+ؘ\?yx$}fGORlh&'ل(v6?ݾ+{ӡny.Tn:۸\l^gSd.q98U'X*[l={T `xbNi{ W<읗S'4O<(A < (VV̼A3r%̼A1Ֆk7hf4x fM)8(AAi U9~LcS@; q[c+xjK{~T[߼QjK\ QwHU(ԍ(R'x%Nx%5_RtGͫ!S*g^F`' Lg^JC`Dٓ\T]q͙A{|y~YB,;'K4zlS'AKo-Z4FhiM7AKotnMFƌ7AKo zAr zArUf3tP)$`&lZ4FhiMТk]E-g^{yt ė{y#:5#^C^{yL˛F!7A;Br/o4f̽ ׬|7A{BF!J!F!AeƠ1㨙蹗7@^{y($&h1cMN3s/o4 qO'ox{ڛ7i,:]{Hǚ4vI|6r׫88{v-C ~g]ENB;;*Z| vvUzi@@fG!Jr+ڪ0-GaopNV9!8$y{FN5rnU׬ Kj6C%m fUCѣJ!c7Щ]3cV԰ ZeRH"ntw)D(Ȍh{> *k22hTf 3|K32"T9)blw}47ˆ{7rzOyR9ð7pP,Cع߭H2~)NYMT#bici9qpR.lǮ-RCiH!`axUpJ!tP#tŝcre[ܧ@\nCJJJJ^c%`O JA%Q%>Nxk<[I|pW= Sz5T^ԻJ3\ S8]`zW4l4ԻxrGԻ; 0BW"e\!W/[!4 U\0FƳlJ/^lfX2*2HV32xb_ˠ)mF^AA1^PoTL饸 1b).TBKq gs9ŔeؔvBx]CpsgӚ>LrKk؏bfTDÍ|?o .GLsͅ N!jWezǶx.&|ooW)^aw&쾖?=_KT{[=_!?w}O_y˟Mz}np/زc}k4E@{)Zb XXU/f-\h\MbD?-.j4(v'ip_ "(~H w%ѧf( q O?1 .e cU3"[j5[nT"a$XQ̠IK)8 "yRhp=%Hhp4Kś%eL~nn<۳G{Pb XGo}Ij~`67EN{76j פ"BqQvẔݒAB]nO#ybB iJ$$cin nHٕⶄ;,)21"7fp#::1v[uǤ-Jmt\KLf')Qµ}4F>m zX =H u\Rp;z>m \ààCP-(6ylG>.q"AA`v<Q=DGWnusu"}1m͑Kkv(ĿW~EFu;1mU<~m܍cELc_a_ټepwfσSRUThAw*Zjlt-56Zjl hRcBK -56: \c͎Bl-56r *=xaO'I :r 5r56kV\cͪkltЬ A*H&F56UAЖ+AЎ+A7cYc{>U  * ƌ#e 56_FkWh~gdO=̒M֯KMKE%8Dx yl5?G$y6>k)+/2K:SUpJu)AB޾MM!MBlٞ`.I?ݫٜ̍͘籅bb_{Wdqdna3ojU^ b9w:GwmUhA;iН -wa\A9wa\A9wa\A9wa\A9wa\A9aM{06ջ7*s]zyiq)< iy zy zy zT)DMtyns4A*h\!9WHyfek!;Y$q:t{C7BˡЍr&h9t# Z-nC7Bˡ󡛠󡛠 S~(Ն́\__rPX}!c?|d b 8/c?óty,o\p6F *yߓg.ON:,ZZ*ՠQ'AAN : ZNN '5ZNN-''Bɉrr"h99!::(dL) rr*WnW~zz{rr"ogtS>9!t׬ DЃfU''U!zT)DNNMtyrj˓A*''\!ɉWHyr"莛< t'zy"hvP^vPЃF!AeƠ1'zy|"|"km7|0/oOy_H%?):̲.n~o}6m4,{2σUƂū5be^1׫k,j ƤJًN rH}_{4_n]VW^cvб=أݝTahfr.'_o榛|:.)s7ߛ=M^%ŭ#|~C}ng~48m%Xt, l7n|{_|r;+b_˓RDzoWlSD>{"9E&dsvH߭r,@[jNvtBK8 -9;Wqh9 h9@h9 h9@a%%瀠%%sA6; ٤ Z%dk_KI+G[%'9u95r95B9 A*U!Rȸ=TeA]Bs@Ж+9 hRtXt'zs@^QȠRȠQHP1h8^t9 hv9ѭ4Xrv&]No߾߀+E.eεc?_u(4ѿP)P⪋>8וp:frPiWz?M'⵬HORκF4; _;°[B0o[ΛC۞[sHxS.wr; ]ٹvlps9 [/._=OUp<.!9ntH}Oѩ TSC8K0p*B8xdez\6f4YL7 ֩abJ)TpPEn ^c<0ޠұ_ҹ7CQx(HAqP' . <!YNl3-Enp'n f<)#O)4O^ P77Sh;{ |_W1"%ӶK09*&GI }T1Y*&+Qd>裊}T1Y*&+W1|EWvEWvipGɿJ9~ΞɅp;&_||t#h#/hOh4'4 mm6 6FFyA|BF>F^h#F>F>F^h#h#_ no9F>F^nw'/o'h # Z-!zN~ =Bm?Bm?C݀l#t3t# )Bm?Bw܌Ŷ{>ыm?B{BF!J!F!AeƠ1'zG{F!}rS}Mu~Tovu}Z@yj?UThAw*^UBd%tOvs @%IYȖ+G z$[3e :QȦekBOhGmA|B>^hh/hOh4'4 v3#v vF;F;xA|B>^hh/hOh4'4 v `/;7$mcԛ\wܓ*|͇ԛMM[zo_Gt꩝ݩ{ܪhl+nUz[-;x޻VE.UѲES_wݪ較'X rm r3^y/71Ѳ;\0l z[ʏahf]:Zwm6A*6.mt&hC\!6WH&莛f<Mw}eNhO~Օ,?'?7#ic7[Or[ΘmSA~)R]5-ӏ%1Iz-5nZql)|RzGz,Ei°ӆbc ~w 7]8nys5 CiouªvrlwAsmR*vwƪh]J{o?~xj5njѳm S~͗Oge0;˜+2 2FgFgALBY&YF,,#htIht4:$4:ez,SGYw wT,w< _( BBQ|!Q|A(( h_Hh_4/$4/ FM M FFABBQ|!Q|A(0ySP~WmM̾8ȸ^Wc*C^]w:4rj%}[]?zퟫGP/w?_0m9GlȑJȡf΢ =}^[2z`;j?p%| }_Dۏ 3]ՎsωS<)٩ت#XG^.U?^.,@{&bO'^UMf-ua}LXWdH$?s>_.¥~y.a8ۦin!߄w\oZq5LMZ_t|)s Yzߴld(!۰6q-fF>w{|{oπ3a|Ef2`ڮ;:`zY^{xp4F3]w*|~ޱ@q4cvO=- ^qz'dxqr7 ޓau7˻w|r˹vP/^Sk_ۯ=$^|]pKՏ}Xެ7~mˆj>-^G%`yj~MSL5/pfeKww?{w\pVe.֥1=FL,zޡLjzޡLjLjzޡLj_f112훿ܝE/_nU^ovQIⳒkE/ ,26mAd܈s[ NN [5q+hV&?-x sKe88np梀+%@+,2Pqag'ĨRg Z_l|MeBsRa.v֭`GC=_՞+4cU"@C=_՞+, X|U{ϲ4cU?TPWJZAC=_՞+N X|U{O;e4c1,Xx7o|`7AU%=k_N5t^|zmqyQ5[>|{EEh-AHV.ON]jgM> <tyATCS A.O5]j;ShE(IJo~VV3WG/_'.Ǻ0uC:}*8`jt`j\`jN\`j f[`fN[`j Z`jNZ`jY`~WL,d,mWӹmku[ڤt*4۱_Sk_آ]IWM94,f>/[ ϶ŋ%;R嚛\s\/#Lez0 a-rT[A&Bk #ނ YKFB6$d'!{6 [}}0-Ư9H9HsZ _j%zV=+-J YIwJZ%zV=+5'K|PI|PK)ZNԒwS䝢%-A-A%d/!K|PK|PKރZUZ =h$A#A#A#y{ HȒ߃9z__uo,_mkLjmjvdKb!rr5OOf CWdb!\+C 7lӒO_=+en q$i禒8.ko0Ux.];8><^#8!DJC\Dvk DZ*SI N"כK]o^׻a=,CjMqsm'Rn@+ qS qWMaO(#|Bᮛ@ܸ [ ^2pa߂ REpK ஛ ޼@sremg9.Uq@);6]°Y zXmޛ[o_s)zqK-sQqu_{gqRpqz<^ס#7#ܼ/A|@sc@njb!n.A1W[xʁ|_P>VLWvۂsGkrkq=ozP.w%y40,';ܰncn!zn7=v c!q=haCz݇즭ncp?"@@@A` [XG܏>3zE!ms!m|ȏxCz0͟⻋ U˙簞yI]}g ^E[2 /7 ?+zD(.udhyFYbSp>"]Jqݚyn)^>j.]KM_G7Ua~kY8M]ⰛCp/~{{{۳I7;.]5~CHwO_ ׵-С/q݌-4GhƣKW4MtEѥ+& B]xth,vECTW4$ ]6:CХ&h+QG;BFg<ڋ%f%cN 9AX!9R\GK8, ZM!!t5.E'.}tAy47 aGo"pz_9 ip:ϐ&[̌%*hrZ RbrRrJ$O{"ČQ[-%P[L!%V@!%\%bKCߍ+7ߍE>>G#||>>G>6Gu7]t[M+??㓯(FOnKE::=/cfg,?b N;z NFi;Ci;Ci;Ci;hpڎv,q/߽ߟ.]G͗8Z]Y{~\݇_v Y pt$?.~K{/b|]Qr>|Eh-AHV._"g&'h33ȓ˗&'%< | h"Oz._"ʓ%.K"N8l6@kZKF6&levE貉e&BM<.x]6l!t躉GuQ!njiAM|_ uO$ceotCwl⑻g%rTv9EE{Sn,y*M<B#(RHw&n7ZOv5v v-nv&A{BD!H!D!Ad 1c躉GuՉB!on?޽sOٶ#vba+׶:7_cbvM/2X[={𾗿{~mc@kZKF6pA]*]3#2B ge83.Ù!tΌpf]3'AZ q,[&6yO϶m8w@Syt|v2̣-"v !rh< :o!< :o!t@ :}tͶB+Py5f f-nfͶB{BD!H!D!Ad 1c#eՉBK3 8on8v0,^m?۷e:anmDh#A[lQMM٢etC貉Ge&AM<.x]6l49EMԼ\6;.w\vlމ{xl6p@55.{Zw+S3F\vhkw! .i%UUUxvvm4hHmUˏoo?_w>臍R1Σz/vq;ۂZgl*u].X|䀼_"dSr?os_jкfѫZuUK_Ut2$((@c(:MAJV:QL Ji/(4e2:ͷ@MXaC)6oA >id1:wgm{m^{ѽ{zG1a{b 1c#!t\mEL_m'f)bh%ApbpAE^祟nu@*m<B>svCk˶ۆ ']'tj ^:Z"qG to#Kfitz,:+c~?Bڕ1ک~DZrkM;mA[9ы%f7B9{#"BH!Q?I'C!t D!^ D!ČJ$ѽ?Q~<vke^ trB1 B- ن}8t3Ӗ܁j Sgh !tNa99u4sGnf쪭ČB-Ws"c$f[C- $QHJ J-)$j>.oREhn =bn Y%w/knyTq!nya&nAR+j\AzC0np?^/Ü3Lw! Ŝ8N'\Q U5nhrZ܏-p=D'Ѓ V*pq =@C bvkW~FqFІpAoEoC\/Ѓa5w^OgXNPUoH}`jժu~*HKVZҸRV)BV\a ϢzHYLKlփ 6Ra x, C!z*AvnX+܏S C !Ea1=h!`1i+X;܏Sԃaa!vq bz0m`jf4ng܏`,a}z{އV, cOzYl6rJѷoJ0\*0. ݳ`}(TCQ.^p){*f*f*GOA`Rq㡞/X TQ-Z`Ԓ+-y0Uhɂu<*d*KLYc%J,Y’S,X_ɃJ|dLq% &k+y0UZɂ<*dǺJLUcU%*Y𱦒S%,XQɃJ|T9% >VS`k)y0UJɂ,,D%(Y𱊒SE,XCɃJ|T% >O`|'y0U<ɂ<*dILNc$&YjET$ >VL``%y0U.ɂՒ<*dZILJc$ %YNSe,X%Ƀ"I|T$ >VH`@<*dHGXHGXHLFc]$nv _qe[ 8߭qy3+nIVzx^>\_޽g׆.1mR  B<#@8#@G-@-2`5Lh݃a"E?`+0za"Ewz 90gT؞S/L90RaT؞Sa{L90gT؞Sa{L90gT؞Sa{L90gT؞a{L90gT؞Sa{L90gT؞Sa{L90gT؞Sa{L90gT؞Sa{L90gT؞3a{̄90gT؞Sa{L90gT؞Sa{L90gT؞Sa{L90gT؞Sa{L90gT؞a{L90gT؞Sa{L90gT؞Sa{L90gT؞Sa{L90gT؞Sa{L90gT؞a{L90gT؞Sa{L90gT؞Sa{L90gT؞Sa{L90gT؞Sa{L90gT؞a{L90gT؞&lρ T؞Sa{\/n{weXb95kIѠ^_Ջԅyc52:՟0WIoyF;)=N5t]u. ::Q&>7_zk,NX:B9k:<'WM3NP3;ˣ:b #_2cZւ{mR THzڔ7v{EK'u@Y2!tqյ z}uxIn AI`Fxr&k \ ӌB'cb}N:^߯W>h.9u\9dpp>M9݄UQXƫ)zlp zlqU<N=6kr{JjϸK<UD*")']&UQનxlsNx̥k"{*f*f|É_h?^??aυ)> ’S _>Wwok(jΕl _;/{7uo~ն5eT٬9fo_WڲДpF/S1v`s)'kp2X>N Kxp=&oomn:So.72.TԂs>W/U|: ^0g ^k5F8N[y9NQCXeU `/jƋ&yWEUT %ƛqc"HT*Rf4^*H']z޲XgU2 z޲E6| `]| `UW[>H,P,QE/HKV 5Y~|7?+zC{qlzppsfY{|YzۦzQ_CV}*'/qDu1G9s2D4lC9,#9 YȒs"-s "-sI DNsM DN>{- s"-DQ(F ˡ,Ym:Cd-F:Cj#6! ĂN ;PX}PazN()ah#l.$L!4PQ(8 @Q {Q ,NSOhh#:?:6Q&%g ,xoG*0OAw9(*mTrrF9V^QU (+ &`_@1K+D!h+Dh&x_W@߃|ރ|ń|F:`1a>VP"[6hC96hK,%ޭ +Dm6DQ = ,ZJZ ZF mHA i лSDT^YY `X0 MDfh#2(!2ɇ.@ #t#fAcam)޾/^tb.=}.·`bC-J*U~ۤ:6'7I>I*MROn ]rTۤB$&'7I>I*MROn }rT蓛B%l }rT蓛B$ڈmD6ڤB&&'7I>Y &d#FT蓭mROvn }rT蓛B$Y&'Bޝ jmROVmI>9 FT蓍ۤBlh }!>I$d/`TgM*A&'GXItjB,xTI>YڸN*uRO 6I>}T蓽DDDMROn }rT蓛B&6'7I>I*MROn }rT蓛Blh }hM*^bA/,6'6DQ(FTۤB&d-FT蓍@mRO I> M*^ /,,FX0H,&6%I>Y &d-`T蓍ۤBlh rTyo﹤@iܶzslc>ؑF j%_9ϻ7oI9.?MR;%a ĭ*gFodFod#d O$jGpǔ%a-ykɣ}XKZh֒>ߜ43s a k{1s>u,,d X#),%Dz }ʳhY k!g HdWw,߼';YԂ,, yQe Gd Gd ko%s֞F2'A\A:)a@}$FS Γ u2J&G|$9H9GI4#i>y$GҜ#Hs4Is<#iΑG|$9H9GI8i_}w34cn.ڤYl2.VӾ`#ۢA{L(%ƆK*\blr!cC%vEhri_ B.16<`%ƆiA\blrm_k !UY QY ,XW!dCz7C.hBNcC^bcCȥ}B.16$(16am1.!cC 6Ɔ56Ɔ 6ƆĂ%Ɔm !{ػB%(16\blrc5ƆK !B.16\blr!d+F!d'F!d/Xpxw! Fh#Jڨ16\clY hhXxw!d/цhchch#H,$16\clhXxw!d+Fumwwee;B yGh}Gh}Gh-y*y(@ctKɎV}.FV#YG\1FH1B%-ynɣEK}.ZsђG<\\G<\%>$ ~ _;YG`F&Hpdu4R*)VO=E>G`XHG)"#E0RyF#Hp"S~&݉06>/7*ӣ}߰=Wpj &W"bQ\, k Ek X/@3ru.EK!qLFeXttww'oLǹwYi$o¯}^Ŀe=h2}h~b;k7[7듛>蓛>蓛>蓛>蓽ĂMDHMD$ڈmD6.蓛>蓵@mDlhk$d+`[#';w5}rS#'75}rS#'m45}rX蓣c]rꓕ@ONHFmDlhk$e$hj$d/`S#'ς'[#'6>9ڸŨk$d{uDam\HuDl%lj$d{uD%ژ%ژ%hj$FOnj$FKnk$FOnj$FOnj$FOnj$FOm5}h蓽Ă^bYmD$mD6@mDHJmDhk$d#F[#'[> 蓽D^YY `X0 .蓕@mDlk$d#FOm5rQww')G2}c_>Jb)}]ϓ}^#QGcУT#cyïhwsYǠ1w+c@Nhg/~A-(@fǠڐcU>nD>nD>1]c:Ǡ#31 ycF>fc nj| In1{w1&XEs?|<Kyk8 ~$6x7F'6& qMT)V/Pj1~X++al -fGbmG W엌+ Y88%:\³ox^b{BY xOc \׾_?ð͏gw_{{&5p?__?MC!/=U]́Y`+ q}>#|3.g\ ,\>py>#|\xWܟE:BSIaWndf%tPY ׌8r5w2ޗF5m/\owr3gC C{\`E.?ߊgx?\pyY.?\py냷LQ NI  [x+ Chuخ[ [**!`'QoiSu(PEBO*RmhީhP Z~k UPObӋݪT!p^V ~Yp p\q:4U,W!E#eq\a!`%۲8^:8w΀WEȍ3 Xpt^dgB`/P,Q,PE/Nǂzq"N**UMČ5nm%.@⪈N4ToW,pd:vDCUs˴KGWRN#.]Nr(QE9"ITQΤ(G#9͈<6SWbb"HƋK4#)"1U(%PR*QtxJSF.@PN yfKwtUE"JTqUI`<=J)͈UhB*Ux .KT%u]LU WQUfČgKN3b.m@Ƣӗr0pox[ON֫y >׵7fܘR=|&YÒlojHv5y͗75]#~ .k]syM5#- p5ns/dyy&si pSÜJ u=xݼn-1);'1 =@C`~u[^ȏS^LAzC0u֟z=[ ; r*bd܈q,>7Nb8qՓUlm8Z\zCt=xݼnskz=D"֦:Bt\Mt\s\ڭMs\q^/Cj>!YJCJqj(?H}np(HUw (Hj4AM nJvK |NS,@^`7/[7ȏ՜D C! q=f7=vKi ̏8e50=h!%50=h!40i+X;܏SFԃaa!vqf`z0`f4n܏S&Ӄ~۟7G=Ռ˦oM1OI+qz!s.qa^>u߸r{礞p=FzX^ ݌ub~lNƸ6ánY^ׯ\&;&v =V[4 pcTsmzN>kQY?m9dpK1{/F8#Ra}mw%;g 9)p&nIA[4ggy-jt:Nי&?K,n7 qpA` [-vԄ\_ooomNZ\׻RpK-Ef7&6EfȬϭEfWzEfWvEf~\PP 6~\n!zjY[\\\ۭ\q-2^/C)2g3Rdpn F܏kY[n)2 C-2[-2Zdp-Zdp@^`7/[)23ǵ @C[dEfW~\-2C[dp-j :ԏ"3z="3[n)2 "3[Zd"3[n)2[-2 "3kq="3p="3v"3[n!zjY[\\\ۭ\>z@@A` [ȬϭEfWzEfWvEf~\Pz\d۷y.jZm§}aˤn~sRcyZF2qp\'m6 * B\9-r[r7lQr\7z>Mj*Wv9x[rPszpN/حn C! PZ=&n~Vs7(posC,Q YkpՐ>! }TCkq=\9uj>! }TC,Q Y5djpՐ>! }TC,Q YG5dj>! }TC,Q YG5djpՐ>! }TC YG5djpՐ>!  Yvѐe4d YFCw4dGCѐe4di7dy~㓗~wȚǵuV!r|/vxK^ͯf77U6s\;|4By*Z\;AV랛ƫ7EIgtq 鯟=w"Uh14qWAS`9SU}U~W}>>:$`ϒZpK-UT}RpK-U}r֦MUL-UWzUWvUT}\V}\V}\/حT}Rpn2ZAp{v_.jF\jw]}U|"*2 ^L[*lu)k\٫_ox:NYa- :b?qӳe^TM!L97g! Ypc~ܘ}) }nx;qqKEUp#qՎw>Cx8\/m{[n\z=ļsf-u:}Kqo)ƞ[-pRw.ϭR)[ *\[ j}Q;[ ZSß;[ zf܏݌ z[(CFs7Z\)p^J q=n~zV\qp@^YY {PzBϭ'PO(\ۭPzBZ\u v͸ 7z=D\A=_O(\|=p5zB\| W=_O(\/Ѓ衜P@  7~\O(-'PO(\ۭPzBZ\u=xݼnq?'n! Q='zU'FОPC{BZn P?nO(\/Ѓ衜P-'n9p [N(B[O(rB Wv'n9p kq= z' VN(rB@Q롞Ps p?'PO(\롞P[=p=xffnA`q= }n=pzBjn5 z'z\?ݧob mo?4~)\=G95:2jX;5C?&\Ǎ,N C%YpvRl'q=,!Iq8nj'q@T;)[5}.Nd Iq\l'q ǵvR~L^-K%YpvR$k.NdMK%YpvRWv#IqܒT;)kq=8@^`7-KAǍ=PHnqvRW~̴NTL;)kQ18Ci'q@^%YpKd -[5}nM5YpKd ոjd -kq=d ujzݼn%YpK@Q&kܚ 㚬CM\&kV5~\5 zzz"5YdM[5Wzqd 5d jɚ}%lL K '9˶5XI_ղVokˏY^N>$nI5HqM(<^u['p |"7W[:_\?:n n IB^/,,C-&7]}iC4a4!uuRf4n~u:az0fp}յvKoழr4.ιk`윛fMw͢snqS=qW\:ܘv.zEgUHCC\ /285ى|mwο YhMܘghM~&-P;?\];vt-npmt~^`7/[pK=z=D"ϭnpKq=zV;?\qp@^YY [-~N=nWzV \\\/m C! q=b>\q-&C-&C-&[-&ZLp@^RL@uP׵6\u U\ .Մ Մ}n&jBqjB[ n&-ՄzՄ v+ՄT C! Q=Մ=n[Mpm5!ըjBkP=Մעvk C&^/C&jB[ n&ϭՄ}n&jƤ&mxjB[ n&jB[ n&zJ5!-Մ7z=D\ϭTRMp5ZMp ZMp-nZMpǵz@@@A` [VϭՄWzՄWvՄ~\ P {\Mo7rEp[z]Zu. r5 t8]r<muD͝ nLpX[:<y}np<Wz(}q>-}kq=>ujrzݼn35p@A(CPOJr*܏Kr>5jrZn5p5p@%pgJr{G%>}p=>ոjr܏krZ\5p^`7/یqM C! q=>}p?}q=>5jrZn5p5p@^G@9pn9p#%pkn>UJnjn%p %p-GN/-q# C!zhr]n 6p56p 6p-j6pmnz@9pKn>-}sܒ5psn>ոjn>-}kq=>ujnzݼn9pKn@Qn\q\Psv}p?}z===݂nsKn>Ujnjn5p 5p-qsnn?~n]?G(h:f^p\;\9 DA\Oy35.nwW}X?q&7}Gs>N/-C~+H[Ïb$ǟ%F}[ jn.A-5-*\[ոj [ jP jP j VeRPpn1dՂO?Uu:}jwe^Q_m$MCĥf3Zyǵo?`8liGyG119wGyGyϹ#r] w츖̵]s[wwO f~|pl&l& X J>.Aor"Vkg}`H)\Cmѽ`IҨ.x}h <p:N.% Xx NMMm? =.e  %ƛsFpD UD*֘8LR 4^H tи*R TE0*R TER 5]:e@^ /QE*1$PUxw]:N*S+\)"jܥS 4^4K H)0PH90T^` /j&T 5u=%8ԡ>,,xh2ɘ,zh*,|h*,~h* ,h*¢ ,h2 ¡8!,h*r(~h*X4 aT4GSMCx4aTDGS!MDx4aTTGSaMEx4aTdEMFx4aTtGSMGx4 aTGS!MHx4$aTGSaMIx4(aTGSMJx4,aTA3Kx40aTĄGS!MLx44aTԄGSaMMx48aTGSMNx4-5; o@o9އ2F/Y}n a~#|Vy_x>mfw>mfw>uY}zrY}zrY}p?gn!zhg>U׳WzgP\ۭzVz@@@A` [sY=n=pzVjn>5׳zg{ܟ=N|1,ksm1^t}DRf1yS@ArǜCS?~8L1V \u#`U`WEۭeV`Ec0U` T1KT1 T$ ` 17ST"U WE5nTt4K=PHU{*KW|Yҵ'U0U8\k 㵁8`n#qXêhCqhcqk}`t{*@D@Ab 0^] )B)\'hU @y-Vn)Z\:\zݼnjz=D"ZT֢jp?EWzEzEvE~\ 0 0 v E܏kQu[ZT pZT p5nZT p ǵZ\?/Oʪ*?Y))juqIqҟf^:_ _epÝ V?*s 6pGV6p[r=85v3 81 .S'O%`- V%`Y Xy)g祔*x^ʩ`m0OXy[' ,Wϛ7K*תܴ'4Wc gܤ]`bIKw}/}ظv{#7}YTG f{uqwA`N$qW3zH'&ߌaz0NpIw܏Naz0n9"\'Ѓ 6~lf܏MVSsݬ z-yeg1\[>7~@k\pn7r(p">޸1׎n҃S[Zb>e ?5;K=,up?v:?݌?݌?SS! `_?v W{knipKo[zZc~ſ|ꬂ]o:+!wjO7H5]>hsjrػpz>?7Az>:|S'\k=1iS6C! q=!J}n= p~OivWg=\5YjqdKr|2Zrr>R\9,ȕݨ>Os6 OTWp=M\9Fpc+ǵoSK5pTVKoTVKoTVKuoTV4o%LVKnTVKnTVKunTVK5nTVKmTVKmTVKumTVK5mTVKlTV WQ[9.ձR [9.հRZ9.կRZ9.ծRZ9.խRZ9.լRZ9.իRZ9.ժRZ9.թRZ.٨}Z9.էRmZ9.զR]Z9.եRMZ9.դR=Z9.գR-Z9.բRZ9.աR Z9.ՠRY9.՟RY.ٞY9.՝RY9./azr\8^´fTkVKuf%?{۟/sB􏾘g+eSğ=˩SU?C޶)2PhZ-{=C_ppp? Ha,qBhȯFO8A jUF_Bb,H EIvY^^ҽ4]-^O宕t'ͥ2^O{=a ҽTz¸{=q/HzR ^_c|OSmM)GkݿoO¿_~?|{VbtT.lZn.vZe)Z-[sV99>>7TT5CR.:!\=p]n*Wp][.\>]'>4.r$Vߎ R.pg ݢ[rq\atu[ոݖOWz R.s@wm^%jWpۄ9s+s =v#;~Z_>OaTCw8w8vULN$oLMf$oLMf$oLN$oLU~`j7B,́X& &ys`S90UłI*b$oL`j7 X05ɛS`,̀0LNT  &ys`S90UƂI*c$oLՁ`j7 X0U ƁJ0Lq`S`cT1 fh0S Ɓj0Lq`S`cTA X0UƁ0Lq`$S5a cTQX0UƁ0L1`,ua cTa X0UƁ0Lq`4Sa cTqX0UƁ0Lq`<SacT& 80Y!Ɓ 1Lq`DS5bcTX0U%Ɓ*1Lq`LSubcT X0U)ƁJ1L1`TbcT#,L#,LX0U/FKwߞe$2آ$|oR3'QQQQ#3>#3>xD}FgD}Fԧ .Q5{qOsF[%nm=Y0oI"f5!NT[:r(>KqbۗSx=ہD K#\ڽNoS{)l꼎 J>r$WZ!B"K cWEOrx!PTAVH;80$?/w q`I~2^XTxcTSrǨ(b'厱rLO᪠b'pQrKr*Xx9Xddl<2V~2^vi2V~2^V+TAOw;90+?/wTdqNXxΚSr-LOˁ`b'@U0rXxb'pUPr*Xx9xTdLd  2V΂X9b,s`*V΂X9b's`UrL90+gTSrL90+gTSrL0+dSrL90+gTSrL90+gTSrL90+gTSrL90+gTSrL0+dSrL90aab0rLY0+'9V~s~Om} )/StW,Xi]w6Zr11rS[7gںq?֍٧n>u~Omݸ}jS[Omݸ}jM?væn>u~Omݸ}jS[7gںq?֛v7lͳ87B,}S]l+4h)삡>\G\hƝ@leF0pi^v#>g'q?RY2}޸}F37gq?go>#8q?go>#x~޸}F37gqiq?go>#CBlFMS 9gRHX،\ | !a=`3or$l7lFM.`|~S4ܭA.>E 3߫K.+𜇏#y%"ߋW ^p!DE'cp',p7&dɀ ɀHdHG2`$F2<#0' ɀ 8dW27dȻ/v?=,|{b?N[5&DUj.-k:\(3Q5`zw_=R-^"Do Xd{@is+dwXolӱ no5lsۤ춼h 췼N)vC36043-i MԴ MM`hl mF l MN%Ӂi #~Xu<?o}#?)ڋ>EN֮5=3If_qYɹCWEۃf.8g ls-~ ݖ.C>'QITxIT8T%*@[ǐ^儏[T][T{FF'\S\Dpy"%KT6.Qm\D,Q,PE/WD5 nyVlQmz=gC p<w;n[Tay{ uLEY0TTSQmLEY0<3QmLEY0TTSQmLEY0TTSQmLEY0TTSQmLEY0TTSQmLEY0fdTQmLEY0TTSQmLEY0TTSQmLEY0TTSQmLEY0TTSQmLEY0fdTQmLEY0TTSQmLEY0TTSQmLEY0TTSQmLEY0TTSQmLEY0fdTQmLEY0TTSQmLEY0TTSQm\4E7b t[M ^ֱ4b{w$+ѕp6>b,ʓC҉{M@7mG] r9 ~3`"xςrc x#(q1 x#(q1R%=8FPAc<8FPAccge 3v6uڭ?LtQ,h9]/zԞ:vM2,`pJA>xG0pG0pG0pG0pG0pG0``" `|xsv:.Ŗ뇵WЋ\8+QS\-VJyk֮.wygp}np ι2r e7.}nҸ =5>kg\ڙd3فG;<ڙv&Ghg2ڙhgrv&<ڙv&GOӇsi}zh_Oq >MXT_hOޔtd؏~k%Wan1W h.? xkLjQ}rQ}rQ}rQ}rQ}Vܣܣܣܣs?Ƿo󓇿[y-@MXu*jU>{QzmL.HQjc/&*Su2qS=pKe^i7k9nB qC]ܘ% p@˾ϭ/m8wbPU-4eHDK+QK^o4qRC*DbhT^N$&K$7õ9qc&~pbݢvr߯qT9Ap]C|5~sa|{Z~R wDZ䅋TBCx1;+֭Wq*wq,wqvaȓ-4&PϷ1il,' ϝ8`F[_E_D+v۔JN4ĕh+W!CC\Ɇ q%.4 Lh+W!AC\ɂ q%J4ĕ h+W!?C\~ q%J3ĕg+W=\z q%J3ĕg+W!;C\v q%J3ĕLg+W!9C\r q%3 g+W!7C\n q%Jn3ĕf+W!5C\j q%JN3ĕf+W3\f q%z 0!.J3ĕ,f"7[>h)|,]f7.뿠~.;rߑ\fw2;#̎ev|G.;rߑ\fw2;#̎ev|G.;rߑ,rNǏyqcߛna;#W껨wQ}wQ}[}wQ} (.BVžb}뽤JܷK*r~/}뽤JܷK*qz/}뽤JܷK*q^RطK*qz/}뽤JܷK*qz/}뽤JܷK*r~/}뽤in/cvAKM RM .K- RK QM.Ktz1#<gk}p '\ʐ O,!#$ATR2KKe,ip,!#$AT R22e,p,!#$ATR2KRKe,iq,!#$A!A$!$A!A$ȉ` `!A$!$A!A$!$A!A$!$A!A$!$A!A$(!!A$!$A!A$!$A!A$!$A!A$!$A!A$(!!A$!$A!A$!$A!A$!$A!A$!$A!A$(!!A$!$A!0%%Ng/_?UDV"/V"/V"_pk%rDJZV"/V"/V"/V"/i:Z\+/V"/V"/V"/V"/V"/V"/V"/V"/WDtK\uή-f 3&ēc?V\8·NJVhUr/gpz*x  -68Q`} xfk)vN\!onRnRhn>u3`xǴ8(n1oj.og_,ꕳxEN٧lbA0<&c(d [** Υ KNjϙKb \d .K\d>x^แ Ο;5p #p 8NbI 8S6-';Q^x4Σ5&*B>&&*7z\D&AJ"9-%IDENeRQQrDT\&x%-^Go\<5Q+6p?B\pmKm"k \ //_w2skڻeɭ[jn[.wKr [j[j%n[ڻnYrkڻeɭ[.ڻn[.wK?V{-KnR{,wKݲ-w˒[{-KnR{,wKݲ-Bǧn_}{oʇ׮!?[VU}[l-Y s`%o!e!mjì$)nsr9+FSkS=KNۋ|]ڶW xBc<}\$wSG>*Vu Sp[M\nͯcʕ70> pPVq+ReMnpc:~} K!~WEK`挋ˀ[,2Nՠ  (( HxDErK-ws pspQs b)`GGR%-xKAw^*DE YXKUw<xu ?oõa({/v74tRӥFvc 徉6q[=$g̭Yѳ]X٧. ׄu+\Z]VWXr|*`@%L Xr}*쁁cSKO,??T cSKޏO,??pmuk"%Z]qQQ[]VW[pmuU[] ꪀk^VW?VW*L37O7G9b 1\F`?8ӿxڇA4g<`ہ 8>IQq|69z(py <yCCʧ|C*˧~c+.Ac6`ƱREEjD]c')qƽ Nҝ!8(oH&= ((q;mkMD3mZv̛GOSWȱ09X[Oy쯐ͦ<:+{hsk6{sY4sʱ wJ.KÝr729> NWl'1gjmܗtOfTc v;@z"pƀP5=VB0*[q]S,*{Q}ا! L5Jࠉ TZAEplE. *W l(sSDElEE*/"Sl}%*V ^Mw.]_脽r1̀m xȝ.8Yy84yd0UQ"€tHqLVxT S]x2WDՆ'"*><G5A0׉'9jœ O[a[lƃ|s@p+DK,YLטjsYLu,Z`sS=yn9KMyn9 <7؜T[l΂`/ 6gA0՘ sYL,z`sSyn9 <7؜9 <L,`sSzn9 =7؜Tl΂`I 6gA0ե jsYL,`sSzn9 V=7؜Tl΂`Y 6gA0խ jsYL,`sS{n9 =7؜TϞl΂`i 6gA0յ js4g}櫗ߟ^M{F͹^Ӟ9%SESM7յrr@݀&,*|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,*|P$>>>> [S XRXR XRXR XRXR XRD0Pd0PXR XRXR XRXR XRXR XRXR XRXR XRXR XRXR XRXR XRXTXTXR XRXR XRXR XRXR XRXR XRXR XRXR XRXR XRXR XRXTXTXR XRXR XRXR XRXR XRXR XRXR XRXR XRXR XRXR XRXTXTXR XRXR XRWX‡'wkmal8_h|vܳ&nSs7BjFmlXN?jrϵs;?gM\bpmg縉S  Bw_3ܮ]|[C35]"roi̔VL)ݱʔ{jpEV4q;-+1MܞsW`AT}ixK#7rO{4q Kپ$nIIܒ %#Ap:Co3ܘ7\>8"ǽ9 xu[<Y-ۼI>vվcwˑgX=ؙuXAA">b3n׍+tN\X9ғ3cS<\-:q"cv@ĥjI*q>f#T1u HX#o>f#\y1{xછHh}D\c-qmJp#=".U|ĮGĥꚏTY{E.[|ĖGĥTM*i>b#RGlwD\ݎK3qr#:".U|VGĥpE#RGsD\mK2q:#69".U|Gĥ∸T;a>b#R%Go\퍈K0q#67".U|FĥڈT;]>bc#RGkD\rmK.p#65".U|ĞFĥh9qiYN\f "?~u[Tl{p8L f\w>FcV45m2lʌE<,W l;w 58Ґl\"' 5'~n5Pl\]̀]Ngܦ?1zF'$٬~B_0Q_0R_0S_0!ly1c'r9jڛf|gL9"2`y1\{Ԟ>[pS{lOמ>\{Ԟ>[pS{lOמ>RO'oo=}L{hM<&"=ؙ\^$s+FћAc4Na!6ϖd yII%KjL/I^r$/S[K(z.GO9rcxpMz6 v䩔c~fC68͜!24uQ6#,:U5k ÕS^'~Zs*vY(p4WSr2|Vv5k'k֮fj fj֮fk֮fj fj֮fk֮fjkw{3phI0M29u`]Kg|֬T8Ln XCn`CmV׹5($kwkt8qƱ9j-ír5yhs}s>f\= 9 ]>9- x샇G`?9^ᛤG2`#d!(2ZVx'qY .et$y?P<= xyc!;\ʀC4AׁPs咎#k:RtdMGtpMGtdMG^tdMGtpMGtdMG^tdMGtpMGӑ/; $ vX$}Ȳ=`sO3WY=zZ۪ ئ2gѮϢ].!ŀhG`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`I`QC`QC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`I@@C`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`I`QC`QC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`I`QC`QC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`I`QC`QC`I`IC`I`IC`^aKK.?`kf=*dp=k:vWDn{g'Rfǣ^gc3eZ.W"dQdy)5ӏ9>*Vu Sp[J7?"n'X7?nm7?.qO 7݉7? /.Xez"0Bc8"2""2""2""2""2"AE,/]R,$E,dE,$XHK-B[z)^"*&*"*fbzK/},Y,$JTcմx»c+Sr믅a1՝ ϧc~>}-7#9t)Pj07ŗT$X|IuL!X٫X?% : rg R7JkxdJ.K/Srū}8%QŰ%i`-rqRQ$;ETm57)S|e#6y kG&pnetYܐ Zx\tLFfwZͼ{ z~ z~ z~ z~ z~ z~ z~ z~ VrvLfLtltOh)<̰9Oǚviá]:vap;Y"nHq0n xJĠs`LϘؐN,$0-_ ֌'\>Idž.kŴ+DʄfWCr5$WCؖF1wjt6n$)zW<9sr„h-.2-I!r89]ZE.a]JM~&Y6_଀R`GErpq<VYŀw.U WDDWDE,^P,^bj<[15 6|T*R[zd""*o&)bh"fzyŖ<&\[mH pm9W[m\m9זs\[rۂk˹rn^Cu0hODD4x߮Nҧ֯x, &je9&5t 'vQ &mpa8v7y1\%n\%n׷ŋIpG\ke 2u 2u 2u 2u 2u 2u 2u 2u ReX_5r6}y鳩MktFky Mk-6}M7`]&^MXRl]Źkp͕\y͕\9++g5W^s5W^s kjooaRUr=p/ř1{Uuh8$+U*|U _UWU*|UU _UG+|o߼0?Zk\L\:R:3dq>|츖T0(pߴ]LH^ xŮmRqҪhtI3ੵimg>UTP` 8$gCZ/iWn WuWUݯ~U__WuUݿ~UU/nbum}?]6cxr~76[+ѐ|=3fQԏf)G s?"R-ӱ?ಅ,/83; %nV Sp*e0q}>[2%e/ nKp_½ۊ=]VYag V\V\V\V\V\V\V\V\V\V),^X۞[![p[nuHoһ!uH\![p+ +&v8tZT{&ϥc&g.XŞo+{ WLf <$y<<Ͻ {Fʡ#Zvz}lnc8LSز8 2ÿ{?= Gq-OyYufs dٙF*ϗqNh5[ET6"p ;{i[[:`nB>h"~@W\K8j \K8j \K8j \K8j \K8j \K8j \K8j \K8j \K8~Ols*w9%$Nfb~trZ盃Ϸ3͕߳79'mmUhA;iЭ ;DeНCtS^Ƚ@tSh/d_ )t3b.TP0~AA.~W25S 7t%xk,>@!ۗ[e"烗"^W~u3e⨠[&2;! =s;(>=)gnӛ+yU `]4=jshڤ78 m)!Y"H{LmZ"={{Uk"ī"k"$1hq7z^t>'nI"vkǶP]r |^?,s)0:L{j{_zJ9\N1{,'CpN&Rq2O'7zX]⹎ye1RLp\Hp뼳2'J Q.D:HRۂ :Hm ~MP(ja]~{8U#vQQ #1#1WcD5FTcD5F0jƈj\(c?nausp`6MgO=ЦF]Ѵشʥ b+?A\] ˜ ʄnPcAutb;vcF#MAK7f\vlC&J&ʀ&J&ʀ&J&ʀ&J&ʀ&Jfb&ʀ&5Qj_oew pG0>U3`?=3 Rt&pˁ,Gj7]6{Bx-w)wlQ,!n&.*fYYWWkWWk1UWkWWkWWkWWkWWkWWkWWkWWkWWkWWk1UWkWWkWWkWWk\WơCm [k=|*VֻrRm{1f8;.zكʘHS' N]\ZNԲFgnZ%5kK8s;O *Γ{ADګRࠈA^mkNȽ~Z]Kfwεilmצi\՞uV{vgo՞][pgW{\՞[{ۻonglq\+(jMR")E}㽃ôzVwza ^(Bqz~^Jk yOu ya*0T JU`X%*V JU%y5wfksoݡϧc8je ]q5$3]Fy3r<m*ۧ6YN p5̨Z]ju}߂ku}߂ku}߂ku}߂ku}߀ku ~ ~o>Q͡BߋZ`@`tQ t*.Egbj%xRӦmr];6-i3>.WJ8=.vgL`+/&4}e̥R?,1<= }ˉK1mízk7cθ[nV8vAZ> ԠaseOlw#짤nd~yX<_;ţ; tl NFo+w`KFg[{AWNjФ~9m344UM^eM^bpM^˚+˚˚+˚UūW'Ǥ֬sCiZa]{pÕOvvL&1P1iI356zaBJi`I҆T+w/gC_O ाMb(s؃?U=p:N<7>vSsk +υ29R^΋dmUhA;iЭ ]*K\ettQ(tѬt(ttѭ(tQthJJhNhNhIB?Q߇Tl]n}:W\Gp[^LR&AS)+yp)p.'5"_nŖGŖGŕGŕGC1E9&&GCu+n"ǨEWăWăWCP[PqT<$1$>V-r_Wu_׷E~]wSn]:?nEH~U/ޓQV 삭͍8_52 }=k@pksTh>Ob.oz1U_^Qkp5禛xo!}1M7 M7)p9K)㣢o׷W,^jaI !3/r5ś[Xๅ%. 7W2`+xQ Q1W2VxҖwΛ+mp Zi[+mZi[+mWZiJZiJZiJZiJZiJZiO޿Jr^Ә n L,FRLMT'ޘ 1H{Uޫ^W=\*Uy{{Uޫ^/~w~+im] v:O}9'3c3ۮC96z:څʞF0LgoC:t|QWmMW[]pkk\k zV4 k2`\ pfK"K"K"K"K"K"K"K"K"kZI"!,,,,\.}[pWmK_ҷ.}K\.}[{ڥۯCbsp;7 Șd:|:v1xGe*9k7ک*QX\Nζ67I`Ӳ3gX}gx\}gX}WgX}gx\}gX}WgX}gx\}gQ>6ӭby>>Mǚrpq,&V7$ Y Cc;dbk>w~\+ nbŵ9 nTbuS^Kq]&mjpBo\ce*s^+箽77(-$Zrkxp 9P>c1׮}kus~ku>v-ŃNbzźy~;c}"{l-66gN/G߼`ƌQ`;B߼ซ3v˟&kp[=3(5Ӏ(fN͜S> n}~0+*℧UB Cpӊnw.Rס3yu覍oe1\?5:?5Jt-:-FOooo]PCAq@\)l_!nCܒ QSnBpۥEP.JxIQXogom~IyǺbWu/G㟅c|{Ǻ|A-4G5BVq%aqm+r<\RA\QA\y"+Õ\ 7(M<" dSW< : &X;"nǃvD.\숸q%#JVGĕ+9Wr:"dt(rq%#J6Gĕl+Wr9"drD\䈸q%#JGĕ,+9Wr8"dpD\q%#JF퍀+Wr7"dnD\܈q%o#JFĕ+9Wr6"dlD\؈q%_#JFĕl+Wr5"dj\q%O#JFĕ,+9Wr4"dhD\Јq%?#JvFĕ쌈+Wr3"dfD\̈q%/#JVF+:Wr2"ddD\Z/>Fĥ`cD\ƈQ>{#ZXX[XZZ1ZT+c2V+ȭVjeVjeDjeVjeVFĭVjeVjeDjeVjeVFVjeVF[XʈN'FO>տ'O?_?}ݫo8_g̟֮C&K6qXL[ |z?y\ ф` >v(pGEץ&'KGk5g )KoH 1 N'3~v2m4_9O惓|bpЀ)<8sx*75x]a[OFE"ɨzK6]^xqqwt׳QQ1hb":ŋ{nzcOm*B0cSDVx;Ŗ|kbk`ÕŻ4|ӫoyr`,}͚voчӱYxl91Tc`8/>GOx7?kkC;Ok4;n k{o_ ?@h1SǯKw_ޏ+aȗqm={pW~߾y+:'܂%&yKON߁>/)!pn9ϧ _7|qet?QEl}/'_ԛټg]=yߎ?)gKBfݬG/?rצJbY.p"x6gŋ7nfV9Lyy[~1tnл9\{ϥc=±Q&` bjG$^ \ι yOcqN>OJUGXEǃunvRA٦dEӐjȭiȝ+bc+*PsŬڍb(=.uq\΅btnFs 'Ôu8߱+&spiS7t* ‹N9-)n5#$ÍBpQ!Ý|S#:dž)EpM*`&?[ne[`Ýo~`}wPldžcps:뺸xs~ קnPC.$Co{%Q%nQs&WY.Gq~#1S\pcGeKqHdvH~Z -n~/ayܐQC^@p3\Sso5~꾓~=t?oǃVO`ӓ OQ 7wc!G1ܐ< wPCuKݏu6wckxH>d}jlXǶ+++!(-(m}>\ǃ3|<8ǃ9˯[}OŃkxxӏۯO2;4`Z8\:qTXܹ=dLe<>[%Bl7t?T`(niFpfEF1pC%͢--aHx;'KlnAOp-p?a0ZaCN-b\r؇ot>}TͫSVV_Jh癖_wbp)3yܘ:3 ($4~Nߟ^Ea̡sF(+#t6ucO>퇼uc|0%gd{~ۯ gcQLg%'}IH5%7QΥ5n&hw?|'T Bܥx)aqkƣG.rCntΜpY"Nv p p*X)pBS '{ͥ3pP xCx?Rq@qb<.1ē:|E16'#؎u$.La$}\#gp/t]C:ɀC:nsLfe$ns;n}Sf3㯱3i!^Y#7^ET|#6H*M҈0YDj3 ئ^CBb1a!4' {ETH +BAxҨ0D) CB qZ[~qa-- q`w&A42 a, C`ifKCX0 `06 a, C`inKX0&A4: a,C`ivKX0A4> a,`#C`# C`iKX 1FA4C b, C`iKSX"1ƈA4G 9b, C`iKX$(1FA4K Yb, C`iKX&81ƉA4O yb, C`iKX(H1FA4S řb,C`iKSWXX10W b, [-ni^L~Mo[laNbzź?-~60(aasg?5>l0aܖ_*֭qta++!' u+EwPܡa095|< _6y xhxZ>SCX^ne >""E< l7D &M7fD &M7&DufDnb>1ܖ1C̆p`:E.\C~p 1qL}pZ6.*#7C?rc4u"oڬ]L؜)Ρ|"LѿύC1_\ 7m\ۥkp$}RniHp}Rv[pC`!) w.}nɭ[V2wh\ϟ 9pKF|}nh9Ap gsFZ>u|< 6g4nw+!g4WCh0ܠXI>. ;g4nh0\Ch0\˯[h0\`-%p;E30g4ahܖ_9Ap;~ +WăWăWCP[P9- ;g4ah\˯ۜ sF|<=2 b:ws؇Euy8m͹˝\M.7|:_`: [ TveH[P2da9x["p@vsCs0Cu>6td^!(aPǃmutd^f+&2ssfcKWLe:zEw.wmnDܢܢܢqZwܢ\o@pK--[[+WCnnP[Pϝ}\ì\˯۬\Y -@p;>f-u}f-`xWb6n6{$$iϧp?{ՂCQRRƐ#+GiE.5n 9'rm+6lydf>xAFl]fg'&<gE# <#O -Gy?/r\CCXҮ $W#[El8aGl+Z F.CԠȽ&6zMlxMlxMl  -n-)r,l Sbeí`:Ho_# Go_*Z1Brn!97Ƚf{ zWnƁ[llMl #+gnQ;aR;ݢb#'S$*6-fsB]9DUĆiL\lNf{ h/}rFƠAQm+hbw[)ņHY'nSĆm+h[ vm;N'26zMlxMlxMl  mv"6\bEl8XAg+bw;)ŭ`Rx~!5?lNICc9W讜|+ Txvk.b˺.b.b.b.b.b.b.b.b.`‹زċزƋزȋزʋز̋ز΋زЋزҋزԋز֋ز؋زڋز܋زދزززز @l","","","","","",##,##,##,#l(l#,##,##,##,##, # #, # #, # #, # #, # 6È-È-È- Ĉ-+Ĉ-KĈ-kĈ-Ĉ-Ĉ-Ĉ-Ĉ- ň-+ň-Kň-kň-ň-ň-ň-ŀ c1b˒1b˚1bˢ1b˪1b˲1b˺1b1b1b1b1b1b1b1b1b2b 2b2b2`زززززززز,|v;ݺASCtt4 (Q[*ņTG5 eQٖnHu>v>Fe۩@#bSB? Y,MwOY'?åA\t3!`0\EC3\EX@5}t3󱆏O7:ku_7Rul)3l". Шn6p{źy~ænP j1l͠æǬ7?faSdlv\w6E6fuaSdlvʰ)y6;f "gPMͳx+-"gscæt< xx(æ캕aSdlvaSdl6ʰ)y6e<^)y6"""b݂b~æl<æl<ææ>MqͳxM6Ez|lFuk;<ݔt)5="G*NiaŝR҆G'w}Ô (f}0xw4Ժ S<}ga2e=gQ- d%+ycWYs(Y>Y>| W%pkQ|wܜc%Gp-ns,-Y>| dn^nbJ=[|7(!(aPC9Gp ,|x|m܎Y>+WC1\cAn9p~,|7gd׭dq1ܖc"zźuY>}\| 7(aP"G|װx#e:6Y>۲܎,+!gnܜc%Gps,>d#9pKZ~,Y>[|a܎9Gp{źuY>[|7(!(aPC9Gp ,|x|m܎sx6xsKY>kx|6g#-so׷>9' 7?ᚃ9N N)u.[]qt?-U Ԕ|YןuqnKqǼ2|t듸yZ^6,CTR?$K,CTR?$KE,CTR?$K,CTޏbu?",CTRe?$K,CTRU?$KE,CTRE?$K,CTR5?$K,CTʏb%?",CTR?$KE,CTR?$K2y~ {/Ϙ:pE :pI :0* ErUxA :pI :pI :pI :pI dSG.uT\G.uT\G.uT\G.uT,7%7u{?o_|SڃtEٺ}>ad:xV)GPx>W?'1؎].OKuw9/Y8>ڋ*w vj|:. T;:Qb׉[ve׉[ve׉[veyX':.uȮ:qˮ:qˮ:qˮlY_87:Q`V&:β7?`}^ʋ>D'_.Σ_ܣ~`n!K>E I=oIwϚreztj-q@}%Х]<$ڦZq =}?8K(}^)tϠTkġKxݥb#kW-O(tTj4T2h"$v:5ei vCNf+DHV!VXFneN {!B "cvˡ!4T8aCtfpz$("$2IC[2Tc&)EHJd\teUw>ddC} z#0e =e,) f (( fs9EH_P=/e^F/ 2BzUxMxUzFe{}"47LLoYTN=yc’g=}7?B֜BO"LCݯsblG_g%AҌ6Ar[8$~ÿDUIE<G_}jp*#QY`h<ݡƃ p,^p߰ /={=-⵳O[|qs,Njjcq:p_ʻ]0xH*,);u-m{~K^^^AAxbŖv Sq.*"Y>*U,s9Үtj=Do~:ym"ӷwѡ;tbS.da(78pm߈0/m?/9}sz%v8גٍMFc{򏁂aſvQ9|۞n?[Eޔ7n}2.?{u7'/~㊉}x@l}IEs/'cqE[|'s4^Cp4;,*W{U*>?_O.9{;\Uo믟~v:#KϪC3oV?u97/^y8 <`:`I?˿uͿN@[ߑ.usRKl>v?[* #Lfc.550¤No#lZ>N3 ĝnR/Mҥcs^؃MC=7vK -po/_4Ң$,wE/쿜=s{3l>[ʟ%46MvcI tAxU鬮EwfߢI\|i-TKOf'q}pq%?cܟ>?a㯾o{7?sק{zK+Oӱ-g a~]>vO/^O1_ӕ7'w/^f[GOP9/Nw/o黙q= ?|o;&i R;.M_<2} 9y-CN`zl-!ȱ6 ٥2 2W09,RW2WF XZ!e7{0b#v{ac#-(7۟NPy丧ͨ=;}w l"+bLF7BI8xE|&( nv-KkƱYTLuO Muf%w2 8k|3.&.<|=.}pgrZw&U\׸sIZ~Nx]X^xb|z> 1ࠉA͉6'Qbs"V壢w}XU,^}o龿kR/8p7Q ,|Y,XeA 88<$_6%`@a<p+H*$_ "*&*"*$_K,|Y,Xe!B`ɗ/ %_W_[ek,I,|Y, Xe!˂`ɗ%/K_K,|Y, Xe!˂`ɗ/ %_K,|Y, Xe!˂`ɗ/ %_K,|Y,Xe!˂`ɗ/ %_K,|Y, Xe!˂`ɗ/ %_K,|Y, Xe!˂`ɗ/ E_K,|Y, Xe!˂`ɗ/ %_K,|Y, Xe!˂`ɗ/ %_K,|Y,Xe!˂`ɗ|Y, Xe!˂`ɗ%|񷇸{e 8܇k|/79zF# aҍoȝN?ޅEMpCnIp|w]sF5 Qpm1\˯[aSp[Up;S\^U+^ buocv#b$W߼"~}*+wL}v~z>OϱMضh nj4"|Vq4I{ՓBI>^ܩj'v8֯O8U' 8OM<\ 6gkt;-ʹx&f=\ p۶ l{y m>xi4ssh77UklٴhQi,aɏXv<*%,vsZi7'dV`d2$8(&oei G xd3n׸S,xpjz7PmRV l҃lc K.! Q;/) yy#LqD`~`+c?)I](r~Rd;'yj%awB#]Qvdz݇Y#ms:]lQGξics6NS+\F/ p 4pepiC ʹ!ܰs:+. < ⦵HOms6ӆp孤L•n1ĭV׺;.[s*C8q=C4-ٜ=]o:219`]_oaqL"#$3":{n1aEuGTⱶwޏcmX;cmνk{_amz;\5;Xsswܹ]cXs9\5;Xss~5wo*9s;mWKn|i˻DŴhh3_|4bFw~# u|ϸcdWD1+"w,1ppȮ(cdW1+w;F@vEq# 8]QpH+OE|N@tz?n)l_2ұ>Ww8Es:ઑp{l$\ kbMw\-ҝ bPt'Aڝ kwrɀ;p=v'K+A7 qˆMW>W%c pX\b,nzPc p׃K qˆb,n1P z\j,j,yz57p=M%M6orgl\2m:~dʖ)m[WLn2Ee pۖ)MmfCܲ!nmʖ)-=AALn>ɖ)u9C ''\nW}ru\qSpc''dC6-69O''\ >9z7 7<p#׃䄛 zȆeCܚONc P zTho}rT[p'H7<䀛 z=4p'|rp'y''>9fCܲ!n''\P z=TW}ru<'\>97O䀛 z=L=L=C܊!n}䀫>9:O'q7>˯2yʇW>6wx+^ʇW~;|x+^ʇW>|x+^osW>+ϻ_9K>Wݦ˷[wOhܝT<|vvw5_ovg*SO蹢x/x:|ş?<ǟ~w/|?gקs =wnr;zuvus/a=+zYw>O5<=/mq˼Cyyz6^q_KDH.Zu~S;wpwz=[֋Xu2_.~wzly;5ֳeFӳ~͛͟y^Ζ-zz7p `F7nvs={MOo9k8'iNAo9Gܲ{.]p>n=q=TžF߿l|s[g.· ?_@;uE?iam!7-rSOMdYH;B"“~-i[ zk ]J,nRKI%Rfz6Rfz6Rfq6[yJCu)ic=d&&!nJx)ilAKjkk{탗vTSحG`T}Au\!8֧N%o4 , (C5.dPTQAAo}`)>IѠQ&*g l dHimbQtpBZdz`y )m`UUmSz(٢lPdQdPEWqJ˓Hiy`p'т9]y< )Oab}BX:f*\2"[ )&K UE1ZTQ*״ꖱ8U=W9UWh^2O<}"T1YT1TQ,+UCJSzi' " CCxei)A!RU~uPKEPKAtGE @tzdata2015e.txtUXUUPKI)date-3.0.1/test/tz_test/tzdata2015f.txt.zip000066400000000000000000003643131403643451100204250ustar00rootroot00000000000000PKxtGtzdata2015f.txtUX UU_D}?bǰK.vf ͪ]oH.?PŸ3CUam=Γ ߑ\?_wdz~ݛ˗stݍ7]o??L4*/_OkwW 쯄WD}ŲZ;˻zϟ| \u7}Y|l4`[ *Nv p  ׀~z8i{N>Oj+a?j/C~n_>>~ֆ?˭7֔]XZ;an\h?6&ܚ.~bMbX/EXgaw ga8vi}`DQ/= (q[auWUwⵛ0]qdpr{a[߷fx+`6SFrMl&F3wkq~mXtѡ]3ж#wm ˓b 38Z䣡[nuaC}{`36S ^:}y__Wzǧ+[ wn 9n1/*_sקoܽ~}x3+<3˂o_s|P h/5݅_y+-~|pjUw)nmF ?mIFܢ$X2?oAHKFt+1 86yKa p[K: c:M~ Y2*lƋ/&`W"\qPb3Ux|Bp8-*BXpԨ"^VN)`hy`]z^lbŰ*R b^ URxbnxXר+T1jT1*T4 Eb)ÀUa.5 BpU0x)\WxPk.]4 UD*"WE pQt UE)TQ+W<(\EkT5¥KP.AQ.AQ6 U([JP¥KP{*JP_zG_y_^Qf|׻ އ}z7/}v{2s83NE;/6T궞 {[.ժZVvjZZUnjVժ[ZUkyD|rxO==amX:l. bMg_^]9n{:鬁2/N=J%#ٽT&YnӵGkp9p,6Kg\zrOÔL!ҽFUi`Y<{x <(4gWG,4 pԨ"r2//(p}x ë?FV4o<}޾?\q?ٍ{qӛ+f-ET;Ï^?WۋLJ]i3?3^ͥ/.?h"/劫yA]tw0~ëW|gg,N&. q9cq.}nS7ן{rvjwgO͛IN=<<|wO?y7ǻ=~+eC/zIzZrwpmpkޞ.X<{18)p!WIӀkJQ`"L?Qs+F 8(QS{eD|DQaߝ.^Ds5sYgW9EHapqEȃJإ!V1+Lo/w!e|2'hw <[Cbu2a*NMI'u m+{Au`'Yt.Xup˚U杳/>-|E~+..lvݥ~ݥmiw?pp_rL,}(#1eTwRA(^kY5 -q(ϻkb]k N[kbۤtctG9ò+'Nb[㮫 GtQ:<`KUOAGUt*Q:x$jJ<`G@Ux*F*F*xAcH]:.a0BW_`PE~eK=xIq 6=WE: \fШ+5KQ&(T4 UD*R# 3Kz̥Q\*Tz*S"1^c.>CUx*F*F*xAc]FKu U8UBr90sܥS*\UO^Ο~8}Z;% 1iS1Sr~׳^ו"vsɇtϿ2AG,9Ng_Zy ʹn5||se6.՘WGz s{*17n%RNbµKĊp %\7M/b70G =xݼnba =B!t܏SE<[0܏SA<`z! zgJwW*Y~#.n/ӏM)&!;=c g_ wܰlT7d#n\)׹)C4ޕp CnrE\ eܞ!\F AW-'w~,9 =D"*PV \CxuZ V+nO:Wpǫc+zцa+Wzĝ?d\Cq)!ܹ6CvYͬuMOHS!S \̘RwONZܞaID2=Ln^aoȏM7sBQf 2َ-Md~l tӃ\! nWm~liVԃWaTaT!(v܏m~1=!czp!Mcvs- c~4T%=pOZRM?w#8^Y{~Y& .-d ݜt%K]YDJ%?t'v $ d YR,Bd!K%]@Ȓ/ dId YR8WS Vw9V9Jfe)5]]v*R+^~=o=LX;(cyAړ4hoi#;NM~:;6)N^A ׀GxԀ4G8xZ;b^XyԷ@i nwyq>{K^q+¥+QcppȻ5KjӦجMuX.bZv^?v7CwiYͥ^6ڳ/^yNnd'zc,`V` \荑h8*ik *d|v Ӏz xP50* Ax^Px^JsGEE]<` ^ٶL-15le5\/`E;/z+C1 e[Zjb?P8y3%_ N;% WyV t菋gϳÀų瑷Va[z^f< &hT U؎v gXpik*U: w=75KA+T55 ]FKu U8UbP)͌x)\9K7Sy%:營+mX^|֞^և׎S|(5l/Ï.xDzv;en6~\s{P^Ô=^u~9?cof{SnaMo\{sUc3nދYXGU کJ?*ץqpe-~~M\qvRor%x+Byq "ܜ "ܜ "ܜ "ܜ "ܜ "ܜ rWɠ*w "ܤ_pTa "\GJnOJnNnNW+ ݪ;.A "ܷC8lp48];j5廩!pmǀn}Y;d=W+&|w~ ACT!r=؎vnd?\ZԪ`Caz=vہ =xFFnAaFǮzH-:LJ=|!9;\=aᇇ/fw3Ͼ%,/ڋRW_g FVӝ=nI7jǍ]; Kiso_޾79W"j-Rl) ,~zn{2B엗˼J8\ԓSyps~m(s2mJ5leC`;B2nmN5N=#ϩF!p1ޠ0!`FBFA1^T/*\uܥLpU,[9 g*U9nesis^0U Ux*xx¥].FQPEqUx¥ӠҽUw\coxJ2ƾ܉ "7׹e#p_{ymt.L) yo2M_ceU#\{lc-' y~Gt@j }v.Fr_]eR@2B;sww#?M۔IHSە?S0:0.q{o Ν;Nrx+# u-Bv^\FMku^%wMSnKFb:Wƒ%#{`dC`k'k?L(ݜvseRKkHf{P;YiyQiyYNf)/ 0KUYeR_,kG8xZ;bj /r@i :8U+U0_,k 3t=0:Y_p 9qYR"CͫR=+s)=+s)u0iG`*4yc g.KSsv&V8GjL1ǻ~ᗝ믿.ʟ{ep+@̷tunKtxKtxK_羫Etx}vKI_x c)NZSKyK_yKnKyKyK_W{mݸ 3 Nܚܚ 5ӿ.Xr\s$`9 %Ht`0^9 .Y]+TQ`VPbXrVY]rV[볺QU䰪!W Ք̥s`t2NUW:s=ϲ[1jTEb..`QΧޠ} RU3XΜ`)J|C)J]:|Uaժ^+WWk7rNߠt2"*TX5#Uqxi\33^ ]:kf.5CUq̥--V hAaAi\3s4bTbԨ"(T4Ƌ EKq̥p*qHK Szxi\33^ ]:kf.X&zo~p-.cr4ibǺޔn0s7k?ܔ[Jyj%7R7(R3lS{\96p<p<p<p<p{juyJyJyzBrl*ʱv ɱMsM;6UsޅcS}8y_޹lo4Qu Q(Eɡ;i& uUʼƴ6wtq»]7WLʝ7C/ ҟjpnCo׶~hMCtIUzx'N+6տ*\\kAsv}QWyvqvbY|Œ7ƔZ}YϝuA-<0+++++un0sKJJZatnV: W: W+zzz "aP:tz(kJ:ǥp{aPwOLJ+Ww7Ħ|?N1rQ=#n7!\ckms;>Lk$wb>) >T4\=+}H)RCJ) >$׼҇Py=&!Q1){>Tʘ`ևDPW+&E|+E|z =D"C)sKǥp-C)\Pv+E|;p?.E|z = = =݂nq)sK_[p=">npR=C)qE|?=I2bz!J~\Vj'MeuiE\kWZȟ 8Upz|@ک66#Aa[~Q疱T26jCPfSm v 26jC`4r+v =Bvnv5܏SCZҨE2f{v~ZBBBAa[~l#2Xd-|SmݖS6ԏSCHP>W/'cmBL˂+I5BγRߵzwWFNmHZj#*6r:Sm9j#kȩ6rz;GpJp/7w]Mx|siVTZ?h(kT۹ e$UoC3QFu^pm6|[ x\cCsQ߫ǏB>v)<M)g>u^p}u=s]u-vk;um纞۹\swk;~z6v9ڎ_=Wvj;~_9~i: nw&u#X6ǰ=Djǻ=[_GWǟ_tnܘ3Jۖ{PRR}J'Bgْ?@\g7w N]9r]xin.bIc` $` s os`PŨQŨPE/(7g7 \:8e*bU2PpU4^x)! ]::ұW"\qP" Un['k?yq?ӒƌS0+/e7i]Y]ؿֵƩx WB+5׹5kOk`o+3W%oیΌUpS/x#t >7c7#\Ky, lԭnKGny,X: =xX:zc7(se,tztkd,:2p{KGB^a7['ܑnP!*V}Up X:T>uT>};P?^W+,pZ/eB:< p=xLnL*2O\ xL ܏az4ׇe.>,-UIk$\* pCJܞۭT%* pB^9,pGL a2RrX&rX&ZnrX&:La;(v #;r?n1 C>>>\J\9,p* pLTÕ$-UI+eT%v+UI+eT%nPwz(UIv a+UIz =D"C9,-UIk$\* pCJܞۭT%T%W+0*0*v Eǥ*-eֹ* p CJ\Vq?.UIs=w[zpʰ`{c&;,X_]D9gs%cYoDɅٻk@ׯaS TtdhO%Qx[+q89\V+q8J`pBQPun WkJ`pC nV+q8z$0Bܠ7r?.:WkJ`p-[ ~\s=8 =xݼnܑq nP!*ցw\Cx\KzXv[w~W+ q8J`p%0\ ׹%0^8J`p%0ۭW+qJ`p\WM+q =B\r=8:ܞۭw~\z = = =݂nq ׹%0^8\V8\%0^ë+ӁgŴKXΓˁjg~ëG9w3سȗ+%= =Jz 8S{88}9\ʩf~ ׸//~awp3?턳7-&*A|㆙{g˕Hkrs_~حBĴgZy=vmiSncpa.\4ɀ:9wt_>6A6 +7Zn݆iok^ȯ7 W~KmǵZO<;ۭڎk=Z7y~mǵߣZFnAaH8Zqn;4ߎkzhǵZOMpqƿ>ÝweppL{Yni#\3ۛxEڔsDMƔeA>ndm\/]yŕ4̼ F|\8,9y[㒗[6ʏ]5ӴV~짇wx3A˂]Mv$m~&ylDD~}Km;; 9 Y](KMN: T9UpzU#n?s{ĝ+ a:r;vwa~a!wQ\1isrQ:grWgݜvKF1?NݟpYMƮwz8[+mg.s'uYZz =E\9mM]KXwn˒={3^r: +'hptMֹ-ݐk-ݐ *ݐsE;r(]v E"[W= p/q[g_ξ/spuξٷξMඃ6@jn;mSMඃ6@jn;mSoSطƾZcߊ>j}+W*olV7/&u3>\$gWfL 5}(1~҅K+{pS^}S35ppmn#n [dqz~_MfrS-zM1ߵ[se Un +9+U[rVunYWrV+9+c :WrV+CYW+&9+঺1v=o'ܐ`RʠY:M [&WS{զ|zkvrzB雇]C:,(,r?.9:7嬘J pMPJ pmJ p]cY+9++&'}w~ r)^YqS]jܝP?Yq-NjvrV{ܞm'Ǖm}|(Jp#u5P9 H9 s@{\Wr@{).K9=Rh_qBr@;ܒs/r=\qv܏/^K9=å7(v)Ǎ܏/v%T^q r]q9=np1t[r@^߽|o;93[f;i)3ιЌsZSMě=3 W@cs;k?8z-ߠzE#/6u+ߠ+u+u+ߠ5hpw˻Yi2Y3jW&_FiN-5lM-/ZUW24@sraSҁ:)s`\SЃW+6NuܠCP!*|:\\Psz(v+w2 pB^B2 pn2 p#P\+k.A]glj׻Ԯw\dlW26+:dlܒ\dlr Jp%c=CP26v Ip%cACT!r=M[26k Z\P26s ܏KpB^QQ[P-r?.:dlܒ\P26kJp㒱ܞdljܳ͋t`u-is}ITx7("-Ӣ>-E}6_Y=h'-zТ-zТ-zТ-zТ~7_"Myr/>Z.P皼)\7kM\{q]@\[sZp!+z(ۨ:=87(WߦD;8[ Cnr:oq?=Cn^aoG1(z =DuۼP?B?>TZZG0z8ny-uPpB\ Wz+A=^[zun WzkJPp%ܞwz(A= y$ܠCP!*JP-A=5܏KPp-C z(A=JPp%^èèCP-(^[zun z(A=n%q nPz5n ˧7ʨTQH~eMeK=]CYθhP`=}^" .@ Jp%\DW"+@ zBQnPM"+:D\z(@n%qnP";(v IpG%AC%j #r (2ԏ@T :up{ ԏ[Y_+ke}Vr[Y{]oW1_NG{re7܋֞_c?sYJ?a>AkymcF|G>T?ڥĒp"ׂo1[O}=tسG|. %ӯڇ?Ӟ,M_/_>bZ;#V.,8 :\.l[m5S+<(` 8hQ pqvk~&x^rr[?HxZk{K^q+¥S{ xQJ5 9 hڝpeD[YVvŵ;1-N/^[O@8ր1cz`'u"|5|)S1uF ޽h-F F-Dt*LY vPV8獯_jy{xکA1ǝ1qLNnandžlk7הdj˥f1׶Զ y:dQytld-!,_=+gn>Cp Uu7n.?b7G/W;(v JpBAk [nzŚܿF/.r kJpC^qKjk̘+x³s"3Dεg/(h9!r?C\ȹ s !K !˦s"6 ‚Rȹ {6 6 Ƃ^c\ȣ»& FQKWilwJbmam\!{U^ FRC\ȹN s"J5DbBZ5Bb5Dj*,(k+9!rІ!І!Xk,+9!rh#h5ڈ mH!K"wK "[6 BRƆȽ‚RȆȃ» F^QQ`X0*[JYjY(!eml6Dv 6Dڐ:YR Ͽ??<ݽ˗W&߻<~z! ۆ6n{vU[u8QDxT#i*&I$-wP,nQ3Jy~szJޛw^-`{u *Lkܜk&\5n5RJV)*OR4}Ɩ%q[Ɩmlolxm=pؒӴp[ƖSmlI%ml:Ɩ%4o[Ɩ[["o}a?B$,@"DqJp$,ܒ\IX$,W+ Jp%a{\IXЃW+& BQPunIX~\kJpCIXnV;zIXW+ z$aqIXԹ%a\PkJp㒰ܞ$,wP+v܏KpBQH欷EKX\䶄EKXEKXunKXEKXaٕ3VrKRI Mմw,n>`wu5 )(d Jp%YsK-d Jp-[I$kW5s=d \%Y^a7$kW5z =D"CIԹ%YqIz(u\%Y=[I$k+zzz "㒬sK-5\%Yۭ$kq?.J-ɚnMf9ve7iz$eAZg^&{6T]|sim:s}FuZ}|'xܽvptᰜ3:׳m8:, .n?xnoSLӅҟ8]x~Y1'^88-W܊n#.k=xxo_޾f7CmWX8c`pNIT0*&{]C[mSj5Ε***~$JZܜZ%\InNV7V W{W+S+U =BARĎMRkKjpmz()[ҡ܏ә9z9TBܠmpۡPnI]~8Tts5^R׀z = ;* nPMN Z55r.(Znr*(:LPʉ;(v i;r?.gnP!*ָi5ԏ}Ӏk}Ӏ}ӀSw~\ЃWAN\)\9ppOR:WJqn.!\)\VJqWN\)ܞ롔PJq+vS>WJq7(z =Drg[Jqp?.8kJ):R=[)܁q)\ЃWaTaT!(v܏K)N[sK)Rۭ~\Jqz(85*a<㶃;':n;4ONﷃ; ֹܹvp y%vp& |.ᶃ;7\vpg}msO`o`s s6>9ا\ms7\}?`>~-o+8|{{fئewq@~|x|swvkُ~c}вKk_ӅIq GZXbw9zx|}_O [~&ֲu]Zu]:u] uzPHu?`T80?nG.#6v¦.pۑ mG.l sۑ /޼l|+8tϼKk_J6q֝^e^;ߛ. .~_>QJ՗IkyPs'3!;pRs 1b [O5y- YЈ˷ K"  pM'`wYoS o:g͞sK*rӐNANeL Wj8}$V^epU"P>~=?X֌7찠.70 AYf  @ ]7ҳWKp]ެL9!9bkg.v5NaXMs._p܇eכ>2: =1ow=Āz#↜ 7Yu^:up pe.Zn7gRv㺼ܞ!AazpCv CMsP,z?b7(zy6Dwneյ3Hnf\geɅ:-Wfe (3HwmveIsm%2p CA/ uSfnϟ;e SfWm~\fnPA 7* XunAR$k$k u\e ne ܏  =xFFn2p#2-3Hp=$k u܏!s=&;p=&v ܏l =B!(lU|ϗ&klu\e *lU|ϗ&z =lzF" l܏l:6\m6\Vf~\fnPfЃW+& k;r?. kz =DuZnX\Cx=p-úa púa p{juԏ kz =HUl&+5 +MRP&+ +Mr&++Mz(Mwz(M+v&+M7(z =D2ۤ-Mp?.Mr=&ll&z = = =݂nqmR&unm6\Vf~\fnPfԸ'toޯn۽OԻ d+;Ƶh},W&g X$t83rUR l. ~sާg/qě%c/|qziqY\93#vrNvG䈝#vrNs;9b'G䈝\#vrN;=b'G䈝#vr;_͏Ifm)Vp뒉Q}y cXQms=V`T[-'gd֥ Pg Q} r-m_G{T'm~qg;|8Gh>͇p4|8G>p4|8Gh's4?rƚ9ukcnNƍ翲װ;N05Ӏe}lלֿ7xg7dlbzyHv~"~"3DnJ-'ܔZN)pSj9rM儛R 7y 7nЃW+<<z = =\\XDw?oBs9!G ]9!G +2𖁐ֆ BW!+@J p%\ BwTaz(!UBW!k@:2[ܞ2^/9;Hr pG0ˁ=qK9!G #rB@ |>}򧫱7 #rBsX 9b!G,䈅\BVRq)W|)䈅\#rBX =b!G,䈅Xȗ v*DNfT2D|b.lU@uo7V4+''՞ Z5Q@y1(AaHqap-C>zȇUap{>apB^AA[Pm8V|Xmsap C>vˇUu|*v\a۟gƜINa 0y g)38_bWfNsxL?߽yJ߾o&=)n=*#8}Tێ]eg}4X>y ^N ]SnUMs J J J J J J J J J zBrBrAa7I\IissMSnWRnp=n9p9p;rc*%+C+^L/&pŋ \bx1[-SnZ[ܴC\KPz1Q=^LvVpŋ \Oqrrrrrrf/f+^L/&Zn\bx1z^Lpn^a7bx17(zz^L5|g/&Z\qe/&|g/&zBBBAaqbًf/&\햽<^L-˓a| *c`fpñ}ώJ'_W;G:<(88_)|J˕4`RGg5q4"1'mpe3:Pihh1xT pwdf<`;Boj+6m6mu:۴57~;čWbkn[č5ik+ ȵo挀 ; {eNu[sFWo*v4/..q筓Aރ"Pœ;7@ؐӀf.+F9435yV47@ï1WKwnXjޥtu3}aK\}ЃW+6t Hv Yӕ[s-}x]ŹPV0NtdY@G>:,# =1Y@5=Y@GБtdY@׹GБtdY@MY@w~ZEuQ>?ogoo]oM;Q\ ˀ{cK=쌋zI@}gNj٢+T6)-E1i8Qk8e̊#?KI0̊#?KY0<*ܝ8x;`ls~V$°Mg)NV-W% [İe,^1ch{ xHNd4 13< j0l#vyKk)$߸(?n K=ǟr]d+GϓɜqH8~TϽf ѹ p 9|;'hH?*s޿^v]mej֡J7E _űѼ[6=mʫ*eUoWIrY۱)+um=^ۺ*•lAsjrslA•lAMق+ق W7,iMR(,DSh+YOnpsz @ܑ7@hs%ps:%N !Sz销qtJ)+zH锄;() 7() wX)7SnJ$\ 锄k$pǒNI׃SnЃW+) wX) 7(0*0R=MnN 2p-CN L܎ڭLܞ2pB^AA[Pm8Sy)Pp=<c݌v3c<6׃L`zn^ac3y+@=FF{v'n7kZGn!ٛn/><6mM>i]sڊy3 wpjpb;IƇ!%& ;q;i(~ %/`{;xȝʝEZ~\_ x/b[8ևtyb`%) }3v)!"w Di/v{xCs1ALPEШbT"&&opƋyx6),WE4"@U/P|Jd8^kT y TAa1ȧtN T1Λ1HN`US*bF0KF03^fS:&)=v\1b*Ft x^cbcP"EJNM@v K!a`ZyL(R+Cmn4~uuuœ߹UC1=ޔ=NKG 1uڀU=НoֱMҮxK1s`nFSbr7Ux*bq5./AV,Bj: [y῱ [t*U8xH౴]?Mætr)Sv\˥h^a^1S:^;4 UFFŔv'>'LpU,e@*Ѓs/>Su|J"\xw?}S>'2s9,mխK=fC bWO;ߍd}ܐnB ӎWh}8{mnN\3rxu J^<s =FFi5>s\:jp;njp{Vz =V;(Z nP- ܑci5VkZn7i5@ci5@׃ ^W- ܁ci5@AQh5'5t'Te pC|܎ڭ=nOqz\ЃWAn߂n͍/!Ɲb=f`Nu` ;Ȭu5&GP<v3-Ɯ 8z0C81=^W-74͐snP!(0*0r=D =qY5|PӃ\1`׃l[c!ez&gvs9>8\GKw~-np В G27MftS5ylIwU{:N'bōtFp 7>8pōɍO'\p.st >:֎M?5>}`yG^:'0!'?"KaBND&Ä\,m 99Y rrrn5 @di6LFn‚0!0"w mH {6$^cA4&A1saBmmXe&  (6"w؂Ep{<"{6F)B)D)F)H)J)L@' d  r r  UXP)!Dڐ"{Ƃ)j)lAƨƨІYl[lڐ";6$ȝ‚D@^1%^ ƠƠFX0h,8*fY ,D6 mHH‚T@dV@N ,9ۏn߼{˟~Wb:j7Ki4넿^|֫ |Zl~1L<4e]+I;1͝SH pJsLP;7]Ljqd?bض"nqɵ9\7s-r63C&gz = = =݂nVlq݉롼gk+Mv\&WN-W,-vcyB;ql;Mo׹v 5<7 qc}q7v.t;Xɍյ-v܌ Z.wVۗxĵHUE~~[mRpwHZ\$&wL&>j#^ IWp=n/Pks&ץ+wr/&KWKOWO+vҕ;R? =FFv/\I\^Jz{q.nq.^ààCP-(6ys)\͹kr.%ZnK K CΥܞ!RW+6ys)7(zzrI67R8Rzȹr.%vn$|z =HIJIָR-2-rKMR&Bk"D\.D\RpAԸRp{\pn^a7RpBAQꡬ5y\D\KPD\GPD܎ڭ=eM =x&JM+5Wj"DhssM67D\R1)k"6sMrML%ݻj*?4iU 0ׯ~Q׻xo\sÍ17ssL^ٖ/~sBz**w> ۿ-cP%cʩݐ¸{pC ܻ;{mn?pp6J67\!פumՊ2ql|T ;Mt?1/?qg/}GDv??J7=bddžyl__? O]T? e%R<~+'6wpŻ \nxWۀ+m6wpŻ Qnwpe)\nz(ۀJ6vnwp{:K6zB\nxWۀ+mvmnnxWۀkݲwpŻ ܎!{zm yĻ ܠCPaTaz67{yۀkwpCnn햽ۀyۀz = = =݂n#ٻfvۀkwp-[n8{zT7MʯEZF1pNvW^bl 夐W${M͢ghMYf- W~FZWA"\)J/M̄+E7"\))KphyvYGc1ƀ5nu'4+z.;( =7(&w8kss@pS@p C-w\qCB^a7t܁pBB#C˯-k<.kʀ:2[ܞ2^ààCP-(6yl} \ h\ ht\ h\ ht\ hW+&Wz = =\G_k< \9!4v < =xnAahss?674p=Zn\qhn-nhs78\: p;n p{>s78 =xn|#<GE"Q`=*莊GE"Q+Q@莊GE"{TX%GE"+m|SSnB^zHr׾$y׹|1]om7n# \#ܔG@ \Oy")n# \ yk$p%pyG_XWq=<r|< =H =H{ # \#GN\9p C#\yzys=<Q(sYqB<<Q(sYqB<t_}D[rܓyȞ(=QP"M9BYr Nd-G# 9ߗd  ܘ#dF3GVa|kYShCB+!D z!ٝrhchc(5EX E`-F@dQ,]k5ڐu,w9 Ynr rW*@dYG)XVaA  ܮ#0@N  rІ k,5[v4mm mv,D6-D mHBD@NaA # rH@dцhchch#h,4[ (!AD JXbvK`;6$&ׯT&o;]\mX2fPg|^lǮ.3:_Ee|]khs6WFq%pk\FܽlWw/ƕldFq%pk\^6r+Ȁ\J62e#׸ {nFnswk\Fܽlrf#׸ {5n\\5Wm/ƕldFqB{5^6.Fnq+5󸒍\ZJ6r*5nGVFq{:+5W+ Ȁ+Ȁ+Ȁ+Ȁ+ȀWmnF\F\F\햳WWzȀs=ld y$p%pBAQ!g#9p 9p-CF\vȀy+zzz F>s6rܜ !g#vȀ<Ȁq=l_ݿ}i˟)ew.Wdf*.yM}eIr~{|pZwv7li6c姚TL||!q~P<ɫUrH9B,&JKW;#K !}DqzF)o >Kk !SeN!K #mĝ)|^cyrzFN93!6F6F6IapRXpbvyjٺ6<쎁=),:{bvF,f$Ä6 qd䠱`<#B==%cbW}'68ۈd1ط)fw _%˾{žn z&͔;986FF#FA 1W $[Cڈ?Dڈ@hNA@4% Hq0)H1h!~9h,(~yij;zY{|?ۇJ[Ӻb 뮝P~WT:i6yŃ}7~307n6\ >T]{s{o]/^+]1 `y_=ޯ˃YSO7No"A{#cY2 y^$`BiJq]<0r;RSaD,% /Y=GX1r,1. r`wRXZe̾SipAT̀/m♲Srp,)B!g3E"dLxYvR'[ԣ!dσmrІ0Bhk,5ߙ|oFAQQ {RXОF1QnkڰV ڰN ),h;{춽bv[цhchch#h,4HGv'6I gpF gtVaA9xOQF}7JYLMفi4[=[NS^{l8-AkWO= ƍ<486eM"훶{YNgǟ%rpd.]\8]!>~ "O׃/Xȉ<,X tCGT,5T1_BӘ l*cbqlƋ~ISzq"U,^Q+T1/S{xÒEbJ/.QA`#V8DRd<)ܡhw(0^"U$o(Y3"9CɔNPjNiq)-P 'LAA@tУ锖6Ћœs{l[6Twb8@-{7:RI5O~''<)l6<%>{x[1qJ{c}חwzș$#gșr&*șr& șc PŠQŠPE/(7*Y-PUB1YsN1Su U{iOWϧ=g?w?RsM6 n_6x KL~ʙ(l&7fsF 5F lb`תyp4$ `I)$p'%.B> lG~3 ]"l}vKP 5p0ƓSh*x[rؔcPqUB1kwN5ҹ6*95w*`E l4`sά-VET*$ 3s[mA 1c5jT#?8FPpA 1c5j#?8FPxA 1c5j#?8FPpA1c5j#ˣwџzws7]ynsEyLxGO]wsn#6U27ƾNG+=_4D+!y.Z^ypἛ*ՠ 4NNתLUtZmo^5B՝A贾3l: V#tZ:ݭ&ś1ttA䶖A'wѰN 2{FOi̸ޘ%C3zl\oLےeA3|ףJ!n-~8-,.\!# ):\2 )Z\2t͸_~鶺G7t8s`n1ܳ؏gWԇ~JjH<ؤFO_v\wbN5^_6UZ v -QJf^1mϧUx***xAaQ1ȧ;)TD)*Q gs9ŔvOi)T:wkƛCƜ݋xtBO$ փs1R]ţUvyb1sq'nNT2sBW G(F"C"B"C"B"CՙBd~My!آݩВgZ AK^AK^BK^AK^BK^AK^BK^AK^BK s^A>6>ח;kl},ܽ#)whB[ کNTngQE)Z\{*zoYG=guۂ{zwZEChB(h3uPZx./VGbwmz`UAͮא`{QF. |ҐڬM`iH`iH@Ґ!KClH X4$`iH@ҐVEِ;l!KC5 U U Ux#eC6؜0'ܐ WEnH@/7$ `ǧtnH@WEnH@B^c<0ޠҹ!*BF#WEnH!Ŕ *TS"7$Naܐ{Ŕ kT4FŔ ܐsC6 Ul )tnHB!A Q?XWo:U3A8*܌J$RO<˻7mf>Wh*[$="3fpFQ1~-XW̃'g۲65^SWQ9؟`Rl8xh{*NS(-`/h ^/`bMo)HEA5*bMoXZlƚY6c[ 8~•C5\"{C5pذyeT{ yeTۢ-U5a Wjzo+ר.Q_齽)T]R{{O޻@ݨ f^xRuF^AA Mb7DRm ?(TfxrMb^BWA{*4%WOS |J/PŨQUa5%OH"Sz B֖b B֎jJNa^1mϧA U U UxbJۑO% Y*bLKYsN1Si:,_Տ/RZ1nK >45^k{54j8ШᰠQF '4j8,hp8QaA  5NhpXШpBÂF 4k8ЬpBl zNi]ެ .L>[e^鼀(_m6`) 7 77'wz\\/v-pQ .7Eu6]||Y\yoq\iMêYwx`qp?nfzxYy򮶱nܸW/9|ż>?}X?46>߿HTîoS"a* [OB;Z?|t6jilX26wy//e7vW̦wM7>+g ^~UThAw*Z -rZ !hi.]BKv9-r:!.V!2x6;{ڪRڲ#?Q]z{c&o) ) kV.ͪtЬ ]A*H&lFrUlCЖ+lCЎ+lC7c.{>v9U  * ƌ#e6BKlma|G>4o}Z*b}$a9Cw&c٣%R돵 ;b]>KŎ<@1B4eG; $h#N:Zv@1B4󎘠HF#&h1clrz'di5 YG{ƌfK6&BBVH*kEt=.~6ڒ̀mz!f@.F7A -&hOti#谝22ؤZ{s>-8-;bzHo!tHSMhm01B4jbB!K~THtb;m1cd>-U  * ƌfQ1IwR(BQ(YU9DwN1ї3aȉ{wC~mto (~OxƎtsS*5;ypشl)ޘk*b,↔b{/sŦ5-A7MkCn7pg=.'<9y-{y/r[4LG@5On_+M43aɃU%i'ϑo Is-ۤ~D=.8۷߿{`y:Tҟ=M7υMgW˒M Luu̅8.'Js=Kv˂'`oOri; SLaN6>YNFwMgS67?2 |}A!&OQi<}joӍiMӄ;/bS WTPD̖=1j#ܾZU|{\q߽yN;w؛$px8G;hG;hG툣5G툣q#v |ю8Gk~8*hw6#@w>tG=|ݷݿ~n~z-|E늱_UO]|XODj-?a۾Iu3^u>ofmn2~Pu>ܸ!7Oߜwf'氨37aO>wXŴ l_T'n>pt4Z[768#qq p%}%D4`ziA ~^6`8D 8nN qUqe~\<<o8*U1Xˍ7<8AtaeDWWkƛK0w+U:93Ha>u/~S/8?ϐ[2\e|FͳWBw*d#hi7BKo- Z#4&hiso΍ h՘17&hiw$_A5Hw$_A5Hʌ^cA3so*D7BKo- ZtТk]#蚠7Bks/oνr/oxz7BzkH˛s/o6){y($&hQHMНƌ7A/&hR(dP)d($4f5=˛s/o6^m5f̽ i&zMНF!߿{cޟ~u/z_{/>^kXn#fWC.z5b׮ŝ?O%ڪVv*Ӡ;GUc촫h1 iWc@ag]ENB;;::(dP ZbŲV[ƹ%( 6>8$:z{ oi;UѽFNUaiTWvH !tЬ c6zT)d̡:+cfL6 U!@+,C I77Bčn q0c'zV`qPxBBBʌAcƑOt`F&\ 1'B.yOw_vCVN;)[*Ǟ7E|.T8u7#7htHOY3غ^[Z׃؍΃'0mĊW*ڟ:h7usV1Mt5I{%!LguYRr*7ހ/TljT6TRɁT$I:ɉ7K Rv4aptB`"4&JZYrXsVV)jGF nI89ʱUp$Nl+<) JF~;௟)YÏ[?s/IjY,1 p p, pB`7;.}XصW*!c4 )=0 N!n#pXjn#xLnr,xm8C 8C8yC 89C8B 8B8yB k,] 8yA 8hT| aUO 'xJ^O\+TzW_ix5pBtўSlRj^|zWUXn<zWpw\W U+ |+FAQcž[xV3MŋTLK#SR\jfR\W,Kq4ר+T1hT1(T4 ㍊)AS:8BU,e*Qb).Txr9ұ ҮSuT1o߼vnlZӇqXZviMQltJhOG-yᗃ?=HIv.p)3R>7U^/`q۟/;doM6㍝^6+ndkjY`+﮼ <7޾~ն }WmNE[V8} cܟ(pv/EPq XXŬS 횫Rɴ[,1 |5 Quڥ 0rcFuK&uK ]=>RD+4~iC>'z7_RĞ<@.G f xX/Mg{"hֳx!U (/IL(rSƼF@mZ\]1Y#..\[2HKcaD4pSpò"@0 7{\MZµ\K3AAcn[<zzz F>%N 0p=H µnRpRp;MnXB /ƹb-9oym>n2=tt>tsoڐ9`6aWnt4/dlg>lCla^eGx=<2~嵼}{k&\4/Y{}Zep>9]ku:9]kV4$(hI0Q'AAZӵfA DrrBh99ZNN-''@AA U:ѵUANNsOSrrBoONNlr''5rU!zЬ DA*A*ɩ.ONmtyr"hWDЖ+<9 )ONq3!D/C k z($4fD/CCC}foe#/dg<^糗Yv}c^ϥwݍ]-a/_yjX]xF|^܋V0zu*^tA:vаG{Tݝ4lc LݻtOg%en}{+y$o}S/C#m~| —x𙁁R߀c {qg3zipMRS>艇2 ]{a)aBR3c@CjAy,J8lbۖRrs%UpU!T;yŔ4 UU\фxi4xۤ7v|o >7_o뷞OnvEky2SHm~7{O$H$,sUU΁hB[ کNTh9v'%`*-9-9-9-9=lu  t9 s@fG!4AKlk)ihsK~$瀼N#s@нFN9瀠fU9=hVs@A*U g 9h˜6|U(sr9Bʜ˜D/sګ5 T 4 *3G>˜9n='4Kݤi۷tr[(_ӥ̹vv؝_?J<J\u{?~>NߌR* XJ3vZ){D_}2_/|I Y׈Fpgw^~vG}_CHF핐tysHy|y oʅN_}pzgs3a\K763;.zn:=ae^0DZ<܍I;:D`pj6u WEHSlxVoLFBAc0^rq pp0p"7&`U:5lSL;*roȍkS:k`S:7&t(j6?( $A=GR#6˩r%` Sy-'e 8 kT8W574f8{|4>o?w*&Tdav2'QbrT1*&+Qd>G}T1٢*&+Qd*&_2<". ;w])G}3nA7`/nm6 6FFyA|BF>F^h#h#/hOh4'4 m4'4'4 mm퍼<'4 M9XS"ctW-Z-y^hh/hOh4'4 v vF;F;xA|B~A|B|B|veuolz39?n{XޔOazI W~kBh>S=Ӡ;z[-;Mwŭ-| 8AR#د6[%zѿĢ#&58IoUS-^3O;O*\H(MvPl3pϷ.1ƺ7-X sf_{Ꮳ|H;_NXU|ێ=Ypk +@2ahrWU}𥔣.Cg}nBEle0oQH&M!n_}?.SfًɀirkTaZgyq$ލpnY}nz*qgd,ۙTî*>DdMnAljޫA4[zO3//-.~2/{M}Y"nXxwn,5yW?aqz߰{-\ضxD}5M1]̃ڼew3؇Y%Xv?cG=Q1zw1z[1zwqoWorwWM]vW {?E%J G_y.Ȍ^<ᆓ){n\op#%w1\';9% NnPin|\#ZDa_/ .Aߖ^oK mw@@C=3DžߢzoӥJ,h}5m ~j~ŻXYgó c|UP?W? c|Uϲ4ԏU?RP?W?KSAC_,Ck c|UO;4ԏU?X?ƌ1?`߼}닋U=c:}uQ,>yuU~jFlxmDh#A[<κvdty5)TCS A.O5]j<tyAhGՆzTe4֣*ˢϾ}sX继Z\!|~৞ &cFԩn\u#`L p:͂m:s͂m:q͂m$9oMm:m͂m:k͂ym:i͂im:g͂]D_1x;{aM犷ockCO{h\l^M}bRkw%_6}䲘8l7>/xK%knn8sͱ^Fs͆T2$ )Qmy{)^l{ 2d-! HVBڈ>g(,YrABr#L.oN>}.NbqLq2i1Nl% f\i1|[#IBYI>+-Jg%ѳ)i1NYIwJZg׌Sb,A%A-yh;EK|PK|PK)ZNԒwS,A-A-yj{PVi1L6=h$Ac$d#!Kރ?|73CK5VL|׶3:櫵ڡ-mh9PSljׯ\/ްMV>M |{"8EJ0c|WyX WwxJT) qvڭ5 rveje O%qj~;\o.CZ#ty{\R#;7="]%H),M3]6yKn>p en 'q3n 'zɤ3]ֆ} J -)dn'zf ol6aTu=_b_wCw Þg)a zoo}I ϝ.7= -5DtUDU -p}qK]7w7ǵ}7x!\~_;[p\pُnAA\n)}BZ2a\m C @=PN!\A<擖17DspöB!uQAOM+܏"*85-A\[t9܏xcz===݂ncq?"̄aCz0 ͇X!?6-XT[7'...\W!.gXpE}e \>%p8r󪽠|w??N>Q'Rv{k^?Y!Y{~|q3!ZՎћhk_f<%9Wⷷ=p~ñUs 7{w qp]X2hrA]xth>G#||#?lsTwqE7uq.xr(?#>>-_bV\TĬIÏ2Fm}V0-͢+#z NۡkCi;Ci;Ci;C8w[h7]ݛku|y󯩵؅)oZ3< | h"Oz._"ȓ˗&'%<)_"ȓY4O K8A-N67O,_"@ItAT=A[ ID$UOKAItADR]Dt)|tH~ h?/q_" iD~ h;z%H!^YY 2c1~%V' ?.~çN6&\\ .үöanomDh#A[lQ]6g'a ![.x]6l!t#貉e&BMѥQBe83.Ù!tΌpf]3#2B ge83}tΌǢ˼ebjHl{x45Ggw/ <"rhȩ"SBSBPyH!yG7~l!B Z i ifll!)K22KDf 3Fћm?.~]Z(䰸4>0_ziVc>k~gSe@û}[\66@kZKF6&lԴ -ZFM<.x]6ltC貉Ge&@nXt#hE(0L&^_I?1Ң\Ǘ/lcL`e\qٿ#}eXψfp_h_3p\#ಷۭuB<5˾kIeW vO -lvG  ಟ^ /P,Q,PE/an}pF຋J4QϾo}~(/<ڭ2kg-xu֯R\׵e0G%B6-6?xV j5]^D^L'At:tDh%A &KQ&| Dۄ5Ѻ: 1tr1nQSFLC{wZpah+mIk/׫wy,pW*3<BVuAvѪm"V G!6 Ǿ4_z^9;^7 T_`xf^?!]3g7<lm^P |BuBe5*}@>&9bmAZ͢C~B:# ]ÉG%iviش&Y9Ȍ^b9{#7" RH($ Č~ѫ<4B籸ZK@!H@!JČN aLv_Ցۭ! B,' tҐm؇Ci0C0m0e]|V[BΙ#SGA9wiƮJX>!r:ah/Q,R,QHL<K\.bbx$+8IZn @kj%J-YҒS,XgɃ2K|T% >X`Ē+,y0U`ɂ<*dJW`S,XYɃJ|TY% >VU`k*y0URɂ<*dzJLSc5%)Y𱖒S,XIɂBJLQ`(y0UDɂ5<*d JLPc$'YzSœ,X;ɃI|T$ >M`l&Y0Y4ɁILLc$ &Y^S,X-ɃbI|T$ >VJ`P$y0U&ɂU<*dILHc$ & $90QɃH|xxTa$ >E26h?w̰%gq}\6޺` ?[?w=h>-5|Wk/w쯝.z~mX~!  D#@8#@8xѲ-#Z6e#Z6exDFlDF hوhوhوhوdey{#f[si/I/wGwV 5SG,!~g깓s>?O] AGUGz ӫE+ZIkc qCh+AmQƒA䌥/sA3~z4c4 5*<ڬ.P>N%3uNAh-&e@1xM yCh'^t^yR.cJBW]+NWG/df̣szBqiՊX" ]}et'>k7vKe]v&\viG]v˶e{ˎ 'T# l^6*R.ð)󰠫NO?׬>A`!?XtG@2 A;ߏZKӂ{L?K3:+0s3:'1K8gosFD DB@!~O3zK ʵ\ZK@!H@!JČN \Uc ćM᭻\@CYI8 N9]Ơ8=m8}s8_-^|r8y9v+d1pIzepSG%KFJ>ݔs.M*j+\5I5nGw隠GWEM#yc&tM# PE"⪨IyrjJ+ܥkBk\5 GV`<'p锉\&bbn>O/޽\h ,<UVָRhh/i lqUZ PH*x^bw8 \:*DQ"k`KkAbt"-[OuV.ɪ-{Zly v٥y YxUUx14^=o1`5PӉ*7ͧ߾}s/bઇ?˞o6>gΗmjZ:d||؇kygOd_sdi9,COf;s2Bs= B(,9` ق9` r09@yP9@zﳗXp09a r09H%ڈmI`0 ,Ȓ?Dm36h#@J,1 ލtBaf6AbBޝRڈ@Q @14F ;Z6`a0mll hCY6hC96Ă^bYjB Fh#JГhAޝNZޭ@ mF`:lZ ;;ND%ژ%ژ% KDl&6ґ P!#ҏ"1|1N.@=b4F"yyE7>O`/]=_ӗ|( v?,6⫤Q7xzH*M*Cn }rT蓛B$&%I.M*MROn }rT蓛B$&'7I>I*^b&'7I>I*A(FhM*tmROn }rT蓵@mRO6mI> ,&d'6'7I>I*MRO%h }rXI*Q)f&d%FTӮ{nI>M*V6'DMRO 6I>y<ۤB$h }rqTK&ĂI>Y}T5Bl`m\'d+`TI>K1K1K$&'7I>I*tmRKn }rT蓛B$&'7I>I*V6';6ڤB% n }rh#H%ڈmI.M*JmROmI>&d+`T蓝ۤB%mmmĂQmRKn ]rT蓕@mRO I>M*V6!7Io>K*<m7;_~ͦ;'x`Vz-b$}_KXNܪrodFodF<2xH- D2x6~D< ~L<л#72x#God A<<2x#ǑG=L750ڇu><ڇ>%a-ykɣ}OvcۑG<ڇ>%a-ykjkɣ}XKZh֒G<ڇ>%a-QÞ~zI0.<;^,,O="KY,KاY2aY0j$s{@{XUvXGIb4%< R'T`q$GҜ#Hs4Is<#iΑG|$9H9GI4#i>y$GҜ#Hs4W|=O3MʘͶm._bl5 v9_-DŽ\blB%ƆK !B.16\blW&U`!cC3 \bl9d%ƆK Uri_@5+}B6w3Ҿ ![6j*$(16%,16\W!cCAcCFcB.16`nclYhclhclJ,Xbl!YcC%ƆK !@16\clr!cC%ƆK !BmBvmB zgwBm6DQc5Ɔk !k6j !6j ![k !;wBmx6f6f6ĂAb(c5k !+6j !kk !wBm[w[hJ\Xcͳm&W,9 1W`XSjv:WƵZZ?#sZuB?|px:B^4FHG+sђGw-yhȣyhɣEK}.ZsQMŸ=M>F`hHG_G#E"o=^SF%Hp")zr:3 ר[N/Q\Dr˴h\EwɍOOww>|Vt^z/NF!JnO+-^ֳ.ǎ'v.u>蓛>蓛>蓛>蓛>K,HMDHA(Fh>蓛>Y HFFO 5}xw[#'75}rS#'75},FS#'>9 =F%>Y n+mDlHVFOnQNFO 65},x5}rh#y]ZFOVw_HuDl`m\HVbFOvw_H^YYFOnj$FOnj$FKnk$FOnj$FOnj$FOnj$d+F[#';6>K,%HA Fh# HtmDHZFO6m5}X蓝>K%ژ%ژ% .>Y HZ`FO6nk$d+F[#!wqr$N$eK')[8IْIʖ=A11X>7 +xg_Nm1w | sR>vWԂ| m| y>QcGcGch<ZPۥ<| <1#ÐG>fcF>"|ǐ&7~|,c鹍Q8nj<' @ms`GrnCwc yqnmyqnc'6<8 ƹ6O0m<t#O0y F#<pG qL@ڑ<& ]~{?Iiw HM؋:Mxx }!cKKC_ZҒЗ7C_v1% }Ȑл1|/W1%/-y }icKCVcKKC_ZҒЗ<1%/-y }iry/}G%jV%n}LݧPf\scr`Dn3¯) Xp f `oVp 9+p^p~ɸY%ZC%<%,%ఀN~4u< h~vgRyYZmNy[:~ԫ:Y<568>p}>.>¯>3.>>p}>|F [Q<,p 3.gxTU~0[Ս_>_ bKvUx*<%`C(U(Pq5 ' lF]:U(VTXd<^=yZՔjE0Υ"KR̥SZ1x<݊Y PE/ Q&ԥsOU"*R  ` SjT"SҩBTJ! T%ƛqV3N!>UUD*"Ն 7^* ]ZkܥSe mpF mqUxN`<'piq^YY PE/ .m&ܥSE pU  37^*]XܥU ܟY&F[k".\>.V V\ V+V,5ڊKF\D[pB`Vh+.V< ppm%ڊKp5`k篸j4^eOk *<,fA<ۭJEmExW<;Ks(PŲxurY4^V-uaέ3 pns lpU8[G'Av,UUUxt, i'*Åbo"*\tKxQۆ[b. T-H-AUxvxNc8HT;T!(QE:L˱txX: T:T:,UC*tHL:r$1^9.ӌc3eqUx*f*f*xA`tN3".*RSRU("E4n ׃YMA~ahnP'&Dik<) po7ca[ CaE7J>צ[೼UsݖC#b]1BO`}N.p\s~FܐhƜE}n:{6~עvKñ4~\kZnvs^pθ_ v E"n7KM85u~/RdpnoZdpKY[ZdpZdp5nZdp ǵ Z\ :\ zݼn3ǵ @Q *܏kոj5jju"3z="3{6ch-Ef7Vn "3p="3q"3kp?EfzEf v"3;~\n! Q=Ef=n[dpmը"3kP=EfעvkC-2^/C)2 "3[n)2ȬϭEf}n-2 "3q"3[n)2C-2C-2^`7/[)2 @Q *܏kոj5jju){l^; 0 v E܏kY[ZdpZdp5nZdp ǵ Z\ȬEfO?}b,,yE |\L7-5f~EPa$Sj~uBfӠ ͕ܒ+%Wp%WpKuS7s݄ۭp5n%pKZ\5pzyJn> =@Ec'n5p~6WpK!K,Q YG5dC͕\G5djpՐ}\C,Q YG5djpՐ>! }TC,}G5djpՐ>! }TC,Q YG5dqې>! }TC,Q Yѐe+ YFCѐe4dqGC]|4d YFCvC>>yyۏ~{>ky\[l.gbݎǫ+.j::0jq|]e3UM--ΝnBu5 MThi ql\>_今tFg 鋜s/]Mw_; ~3{_݇Zq|qC,UT}RpK-UT}R)gmTpRpZp5nZpKjujyJ-U7 ,íaݽgUj%v}W5yw*rq-v[;\n ʝA5w qMp-٢ #7=[&zHմ>YpC~ܐ7g!YR禎wT4\ߍ>[xp#kq=w:ށzy漧A(C{>7}avRkoݷp^pY"Nn[R7-p-տnb~QP[ Sş;[ :Smw@e;=o>~~ʕW~UCp Znun~ zzz q?'zB*\ո kp?'PO(\롞P^`7/یq=p@A(C| Wz'PO(\|=p=x ; PN( [9p#B[O(rB*\ո kp?'PO(\'Ѓ VN(zB@C{BmO(\q{BjT kP='E֞P=x [N(rB PB[O(-'n9p5nzB PC=pzBzݼn-'n!z >P zBj\5 kq ~\O(\/Ѓaa!v }n= Wz'VO(\q=p-zBs/}x-/\ܾ.N>L j@Zn8M r@qĘP /#cƋu \#(.1 kҪ%jq܈_/8@;d;)[5j'q~vRǝg NvR7 @b5Y8nI\ոvRz Iq\ۍl'qd;)zIqܒT;)[5j'qKRnMd;)[5j'q5n7-KN:\d;)vIqܒT;)zIq(Nɚi'qL;)Q=08AN:ԏvR z([5$knIܒ%YdM[5$knI\ۭ&knIܒCM\&k V5$kn!zjϭp?q=d 5jZn5Yp5Yp@^YY [-~\5}nM5Yp[M\qM\&kzܜoݧ>o\, rl ^SkNZ-kDsK"D];tׄƒUuR0'n9ypqu5N `>M,-|z===݂n%n =NsNsR9L['nFv:A~l [9Hnkؿ[Y]h'p J;i-Ms휻FιiqW,:;&ߌ7u3wͥ;_kW\ޛ}nWtvM]4M] =Ր"]_Cpp&n$yp&4;'O.i2@*\յcG[:?N ]npKvtA C!zt~Cp Znu zzz"Ǿ}npjn܏k1!j1!uj1!yf܏k1! =@C-&sk1!UbBq=bBkp=bBkqbBp?ń z(ń T[ u]qK1aUGPRMؿZMjB[ n&7\&jBk ApRMpZMpn^`RMpK5! =@C[MՄW~V\ꡭ&C[Mp-j:ԏjBz=jB[ n&jB[ ZMjB[ n&mLjކ&jB[ n&jB[ حTRMp@A(CP ZpK5!-ՄWzՄzՄvՄ~\  0 0 v E܏k5a[ ZMpZMp5nZMp ǵZ\Մ~-WH.J_t ׵\rp,]_S9pKs.?%kcVGܙ7u@ecn疱9pG[I#ܒCM\& 6~\7z=D\%pۭ$$nI\&V~\ Pw$nM(}[}nIܚ CM\ۭ&&Pz}v͸> =@CIܚ CM\&V~\ z}; 7s7~\rn#\Vr~\rz(}zyrnθ> =D"&嶹}P?nsWzhsנzhsעvksס~ sn#ܒ9pKn-}[s7n\ۭn#ܒC\ sn!zJn>U>ոjn\5p-n^/,,C-q?>n\Vs~\sz7_~/.\%z|.h/v:\`nU UM@;-w1]qmpmp׏q݇c\M7lApx1wsM2Ǹe(>(FrxYR j?iG)A[ jRPpkA -2Pe\ۭvZ\:\zݼn[-57 s@ϭ]-nY\] QǁY˫ާYq~W6/Fr4A\i6í嘧\q\{~[qX3͖FyGy 111sGyGyG;r#ja]Zr)5׬uzu탻+՟q׌̎kn\9g nO~}`W?G8 ff$`-n wYP*b宸q 6}߈4a@ɵ> $ 7*Ja\Ҁun(n/6}pim#\րx^b9w|iGA QEb * Ä/%@y+K"@U"@U/%P9ܥS tU3AR UE/HqN/Хㄫ"11U_*]:%@Etʀ.-UCU-e@APM.8ªH0x9/e0Ι0ARa*r* REʅa TaKdj*=Ve ^>[VN8R 9.o1>޽fOe 2n ^Sk\]/_Cb>&Cyh*,{h*B,}h*,h*¢B ,h*¢(& h*¢HB!b!ESMECx4aTaTGSMEPX4Bd GSAMEQx4FaTGSMERx4JaT,GSC=NJO'id[:m[*=f%Z'qkr,-YKfƔ˶ٶߎ\\[*u>WpMC3Mr7{[7szz_ k S })εȰ-tn8yp.N{v8}#f8} rS\#6\+:\p. vkwp.7J7oڸav" 7odx[6}L9nji`q5y pϢ{nipB{[_\/Y0qϝ=$뷒tvFsa:}n-Φ%z2!-n2!-z^`̦%VpC[KjoM㶽B-p55עvk^Ck}(nD禠>gEa~Qf{[f{[\롞ͬ.ͬ.zVF"v{[\q=p5zV\>Y}p?g 0 0 v E܏Y>ֳWzgV\q=p-zV6n_LKt.5msw8.p9>8\Ô{`?eX]>ֹ 1^elpUZZl[_4SEp19돀@D@Ab 0^ sS>8H{*RpU=xQK{KGtU-T":*x'.];| QE (QEV2^ v656 6-l'vK> T1KT1 T$ Eإb"*j+*U}S7^ ". )BY\)B9*x^`Yj]:EQU*DWnL]Z+ܥS4Tָ*R8T6*R<49Kkt(UUUxQ:.*Ҥ?L)"TaK ,3x%EQNEPi-֔eR$f!0ٶvSH3㖓u)t\׿T6_^7T+E-R[">)R pkjnH[-R&?]`zX:n^`R pK2 =@Cp4p?P\@[p\ !Y< 4q?E}npK2Uj2ոj25"ekq="ezyJ2q?.n! Q=E=n 65p563p 61p-j6/pmZz@h7@Ce-E @skQu4!2 jnj[PP Vn)A C!zE}n- ZT p5ZT p ZT p-nZT pǵz@@@A` [UϭEWzEWvE~\P{ܟ=bNrVg/Nw-i5-]x@kr8`A`} `#O{l%`+mCu(׃S#`7p9 3R?u~$+ X Zl%`+; ^ %Yp%2xx^J`祜*x K5SENBH1U+d6^.*6U$",)튫bޚ2# 1^Xc:Kai%$PŲxyQEbLnjm bz޲v";y?{W ?]Ԕ=7zo ^ZյրJ ^:-Xd{1^W/ jvs;vܼk6ZZXܘs1r M{Bqu>rMzХ6M/& qMp܇kqT{]X\㶜#u=xݼn3f܏Ma7=ZےWwõsStvε 7v!׎!"sh&n. =8n%K_~]#\3C~\wc7U z8 zRn7}W*V -Un:f[{ȧ*2R{Lvz>~[^|Ϩ=& on~[= pS0|2Sz֎i=e1o1=@Cqlquzp\pfOT/W['\+-.ɕ=P\9n؍q>lpdKuq ĕjndWkp?&[r\q]6TWKoTVKoTVKuoTVK5o%LVnTVKnTVKunTVK5nTVKmTVKmTVKumTVK5mTVKlTVKlejpձR[9.հR [9.կRZ9.ծRZ9.խRZ9.լRZ9.իRZ9.ժRZ9.թRZ9.ըᒍZ.٧R}Z9.զRmZ9.եR]Z9.դRMZ9.գR=Z9.բR-Z9.աRZ9.ՠR Z9.՟RY9.՞Y.ٝRY9.՜7+Dž%LkVKfTgV0'OqR6E?kɿ?QE?=m˟ry,K Rh:nZ]s?gg@a?O''JZ]I?iП_e)'П(F_(JdPdO%IsՒXZIz\*^_ƽ Iu'{}Aד^Ot'ս0^O{=ƻͷ=vG6޽pV?$O_ǻk/F׿N˖Ab_r|Uڲ:oeϝssKsSHqK8M^3-}N#Srq qU5rK85 nuC*rm.Gn^n\ -wpK8 n- \]>]Qn-JUOWѺ\mt~lkq=,0 Z.pgY{o|}}Mz=k3pR98JJ>`3m7ڼ/৵aء i 9M5t\z#`[q\#`OP$oLN$oLM$oLMf$oLNT &ys`*ɂIe`j7X05ɛS_,́/LMT &ys`S90UƂI ,$oLՀ`j7X05ɛSU`,́20LMT &ys`S`cT)JX0U ƁZ0L`3`cT9X0UƁz0Lq` SacTIJX0UƁ0Lq`(SUa cTY&80YƁ0Lq`0Sa cTiJX0UƁ0Lq`8SacTyX0UƁ0L1`@bcTJX0U#Ɓ1Lq`HSUbcTX0U'Ɓ:1Lq`PSbcT&K80Y+ƁZ1Lq`#3>#ꃀGgD}FgD}Pw8Y:w`iDU2֓6Am0O$b֑Q2!-TNO-7'}:ʼn׳8p.N[4rU[6iFݠs+ OrMxα\*$p B(TH88}U$G@dxc`SOr'厁5LUH;FE90+?/wr`*V~2^+Td *V~2^7+?/4+?/UAO#c'`&c'`Ux9LTdqǵXxΚSr-LO$;90+?/wTd &V~2^T+?/;~oq`*V~2^W+?/ÍGOˁ.O c,s`*V΂X9b,s`*V~2V+gTSrL90+gTSrL90+gTrL90+gTSrL90+gTSrL90+gTSrL90+gTSrL90+gTrL90+gT&V΁ +TSrc7wo퇏r`2Lq˂ߙ/Ku'lJe-S[K/7u~Omݸ}jS[7gںq?֍٧n>5q?֍٧#l7ljS[7gںq?֍٧n>u~Om)in~sF<+z#Tk>xO79%^fNS l6lk.jn~l=u/Fn91 Vfa7޸}Fp~)%gq?go>#x~޸}F3޸}F37gq?go>#x~~޸}F3oJ1$.f4sFM.ɕ76#&Avf2cB3onr ͼE.4#&@+|K   DžfH\Ќ\ |Տ76#&>vfG؏76#&>nߦ|=r\hF _q7|#DžfE$|uTsZt|gg*8Q8; WG:ECdé_԰n y1CzJ ry8{:]"Xz宺@ŜXqJ^|2|G\pcH ɀ 8dHd x$F2`$N#0#pɀ ɀHw%~|_ObCCGmCwķH%{%2iQߡA Ϲ'P@|Pӄ20H<"#?"'? xDGDO#?"#?;Ç/ߟ ^SkoR|_ATJvIrƩU2Uswgs{X-EYi0)Nf ]̀:JFY ^(8BFy V6 -oVV`'XX#Ow>2ɹzN_4nY_3DmU=/5ܞ; {~qQ1=laFlSy6'Qm2sD9 D9 @Qb Tu 9NQ%]NEZEgkT{%=噋KTg..Qm\Dpj#%KTUUx%KTQm\8vgզN p<=gCyf<౹ENg /RGTTSQmLEY0TTSQmDi0TTSQmLEY0TTSQmLEY0TTSQmLEY0TTSQmLEY0TTSQmLF90TTSQmLEY0TTSQmLEY0TTSQmLEY0TTSQmLEY0TTSQmLF90TTSQmLEY0TTSQmLEY0TTSQmLEY0TTSQmLEY0TTSQmLF90TTSQmLEY0TTSQmLEY0&5_N_t[P{>k.vOۤnѱϋ!lK#wg8O] GlAm..9/ =,(/8F0q1 x#(q1 x#(UAc<8FPAc<8FP8F|^O8 Pkg3.N^xLe"jHAk$G0pG0pG0pG0pG0pG0p)``  >͇7k:Rl~X{iZW.jGn?p?z`:OSA\ýд, *aԀ_1Zpk\MfZr wf87ohܼ/C!y[pcriK!+J@SSv&? LLU:PG%K@zԻ6K@:ְKul`Uulau\ T1KT1 T$ Eإۀz\t `+PE `'PE `/1ot  QE"JTqUԀ:u.]X TQTQ W \ T1KT1 T$ EK׀z\00 `alPVPK@{Z_&"SBꇵOS}!27Za 7e!=#9Z@x$ǥ㇃sC%KǏ%1"rs{s{s{s{sUG9(>G9(>G9(>G9(>>&u޹5m[š8¥ hI)+D{_N$Zŭ44RTRxNxFpY23)۱hNZ3ѓYM1u8 mwh?brt^:#7E_j.ǧH{q,]Q\ ;&yd s;?75pmkѷZc |k)nܐ0;!qb(n9eApCus6{>}Z Sm>#[kxO<.'^!-ռp8p*^x/f羞"ź us>N.>.>N.\7/C^@Co!Їⷷˀ>[~z!>{^f80܁"<Ǻs|;Ǻxx0~|ïhLC\#Hވ+ks<\I4E6\i z7J4q%OL+Y)Ar!WdHCQW  &EC܎ъ}6% q%#JF4ĕ|h+W!dCC\Ʌ&r MJ&4ĕ f~3CKYz̅ve NFc~ox|G;4ߑKꈍK:b#RT/#v=\%uĞGĥzIq^RGxD\%u~GĥzIq^RGvD\%u^G+Z%uNGĥzIq^RGsD\%u.GĥzIq^RGqD\[%uGzIq^RGoD\%uFĥzIq^RGmD\[%uFĥzIq^RGk\%uĮFĥwK=K:bK͖O^|}[8v.eX'ʐX X*CF`I` % 2d48ʐX X*CF`I` E2dt8ʐX X*CF`I` %)2d8ʐX XRXR XX XX XD0d0PXR XX XX XX XRXR XX XX XX XRXR XXXX XX XRXR XX XX XX XRXR XX XX XXXTXR XX XX XX XRXR XX XX XX XRXR XXXX XX XRWXddf'f/V"Z\+Z\+Z\+/V"_k%rD^_Z\+Z\+Z\+Z\+Z4KzDZ\+Z\+Z\+Z\+Z\+Z\+Z\+Z\+Z+T":~%DCoזIPӅCI?F+_.[mχONJVhUr/3dpz*8  68Q`} xfwk+Mm[E2t:XXrϾ.}}p̆N/X a7C0vi(p; WQm~*\ڰ4p$eϩK\d .K\%ܼSq0 Bs$?)pnĀ01>b1Z kRM6z{[>%IJf]ΊQZE"D'O wݔo?yQ:6Fqϵ Up[Up;K\nͯcʕ70! pPzVq+ReMnpc:~} K!~WEpw|WYeAqpr prpQr pQrpr 𨉊Z.x)"2`KGR%-K=w-][zA"*&*"*fbFzK/U}Y%JTc ׆|ݾ';wܦzwұKO-nml(M\ĶF폦 M!Q?+dnϊ>pT&<[]1VW "cSKO,y>?dT cSa l X}*`@% X~*`@k_-ꊋꪶڂkJVW\[]_o_u jCnu5>WU8`3Sfo>r7b2.8ӿ8p`3y@F $(8>Ip=S<€]€c>USX>?P1SX?3ԕ6Ac6`ƱREEjD]V!W\As5vEAZIw`X1(pp336 p'8i1o=6J˃ca"sʱi5 r쯐ͦ<:+{rk6ꔻpwʹ,9؆%NLFfNyHSIDZ۟>%c>ݓ0X*Pޱ\1`ƱwcձL5JNx\ǵJAxTvmSk&*VP[AJ<6Ā"*ʜE*"bA+tlma+ {/;/t ^9p~fc6>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>!AݽZ_u<6D!1=9G0>l=\#7Qrs3㏚{hƬ\smy?kY61\F05OѶbfvy82 g 7[=;(3mc^nq'jȘ#mxhs5|n;>R,mOu\< u}d}z~"Y.<"YjdS*_'6JǏ>\]i JֆM3nS,rAL,Y{ |cϸ7s,6sܤ6sSAR!֙.LXfM+UܔXe=5"čo[Wc=&? u +0M\4qGEb3n׍+tN\XM@pər>f $N\}:qc6@ĥJU|G~ݨcv?ꛏHW|G:c>&Z|D܎}6%Te*l>b#RuGlzD\="j>b#REGxD\ K4q#;".U|nGĥꙏ숸T9{f>b#RGt\qR#9".U|6Gĥ 券T*c>b#RUGlqD\K0q#7.W|Fĥ ݈T*_>bo#RGlmD\xK.q#5".U|ĶFĥ \*[>bO#z [^,'.U|ĆF[ oߋ{s-Yn;8Ynm>FcV45Nm2lʌEV+N;}N iV JtsK(6HClm̀ۜR%θK~bFCNHYl$`GK(K(G(.g̳(?Ō,ioA1L~ʀ)Kr[2 2E^ !rE^ :.sȋ!\\y1< y1[pS{lOמ>\{Ԟ>[pS{lOמ>\{J=}1ݡ6'pEzT=3I,5V7"hFpCm-ɀAKԘ_/H^r3C[K(z.Gч9expчKq=T1y*#+ǐF3Yf>.C& NU0jnx׉9鄭],9 <$͕\.i k7լ] YYY+YYY+Yd^ 6uOmLNC?\ҙ:t5m*;^LU sU,աBpnJIE+xJ C;u9e8g*NqlspBwTv|?!axrb?4Č^!`5|€ǹ->xLz$v$Iz$6BV"el~g" ܦL$.*ґ:]527U`;3`)  I8{( 5Y.Hjj:#pMGtdMG^tdMGtpMGtdMG^tdMGtpMGtdMG^t:yӏPJЍ딤Yֶy.bX>GRRk[Ю9 YkhKH1"`) XX XX XX XX XX XX XXXX XX XX XX XX XX XX XX XX XD0d0X XX XX XX XX XX XX XX XX XXXX XX XX XX XX XX XX XX XX XXXX XX XX XX XX XX XX XX XX XXXX XX XWXhhh'hwX뛃YϽ(y gcIŒ\=8fKAOOz ǺgvW|Oӻ].ϢRtk5rO}Up*)PT<q{j pl'p]v|b^NplFX}phBO%,Y,(bx)b!.b!.b!tT,BQ pG/R,$=b!4Q1(i)k+oR,b!BlDE9YM'Y>^2%w`JnK\\j&i_Bp//KŔ\njwh:N%A7|T)r1lh݊[~Fvn-rqRQJ47(/ }G}͹;kn uSrC|e#6yrx5#_87drcpnEtrq-<.:s#xS3o;cfuomZ=Z=Z=Z=Z=Z=Z=Z=_zwBu;΍N\3%߻tltNOh)≮9օcdЅ26 űSk\3vG9'1j3fyj%p:֧( c*fnz5 cOұ>8fm1 2iՐ\ Ր&5cQͺ[4:b޿O򆆸y\0a.ZORmI-R-sS-R-"$w):E.2-LKCRixH*cn{} .كiϟϴ``5aƽ9táWil=׵,7ywaB8phC}c!'>R(p଀R1탓E589]58+whP l (nHN.*\>p"廊pp+V |[o+&bb_XEJ[Ŗ?p?YAxNGoזs*R\[Ֆs[pm9W[m\m9זs3-r[/ڋzHtKDDKf8 C}D>l9gDu ro!`ih߆MfLc' np :/yBs6pXS,^M5 \>צ[pm\>osm>7%jhbsp.5W^s5W΀kkp͕\y͕\9++g5W^s5WVsw|{w5fAU]} R9WYUOC)BP _UWU*|U _UW> \U*|*|w \ӻC׭nW ϥc?/3ccg kI{]|5jd|rR`+v]=(}͖VEKjwTQA]3`r wj]տ+__WuUݿ~U\Wu Uݯ>WuWuFwlݵ&~uO.f>֦cu%~7"qǵqfps>*hqr0!A|b=oaǮz޳l,NZ**[&Wjჸe0- nKp_[\L-鿝euV!xYa%EaeEa%EaeEa%EaeEa%EaeEa%Eae"* œ+c,)uHoһ!uH\![p[nuHoһ!Ґ/~brC?!~A!gr\:hrn%\ ym;AGB`ٴF`?I$6e6%sd^*Qg.rh 4r֖ݮmز36x [s$ݰ:fqxh)`>b pwa̪>5+\eglRfEoXx) ό'~u : W;;& c({!0Ұ=0B;vP.Qh :bzTEȘ^Eӣz;ތ6@MzЖ"1=.BDHe,=ѳpA!&B*B&BjfG~E>ѸA!<9߾j?~X~x \\~X~X~X~X~X~X~X~~X~x \\\\\\\\퇿MKs2:{۹t=9 c>I-CwOz2?aIV |U_W*U |U_W>\_/% {eP9tM.8x-0xl 8e.G^ȁ2S.ajoz@խ(KARy2d,'Cpr%\LpK3-5ȅ;+s$]B -RԶw?HmPkO釻Se1b\Q1#1#p5FTcD5FTcƈjƈj`2F]7=Mav8tc?\4m46m&.5jSF{seNeb7U1Nݠz \A1N2lzP ࢉࢉ2ࢉࢉ2ࢉࢉ2ࢉࢉ2ࢉ`Y2-V'LPpcK4q[t;6έ~?%箝S\S\S\S\S\S\S\S+b,EkGɀrJ&*~>JJJD JՕX]ՕE?҈ь!Gh5\ӲBiӋU []վT'!`C.g.v3EB):q1K{ɨڇF}M!DmK1׸` oq3qQ1˲Ȳ Z ZiZ Z Z Z Z Z Z Z Z ZiZ Z Z Z j?2~'_Zc/P\ޗ꺋1p.Lӗ1F N]\ZNjY#37`I-Cŵl ܧ~ u' ]nɀ u"OU)WDŨ E/651r߇5ڧkkiFWk{F3ksm~7eݛ ppKA} pp RP'-KAw-u\u\uS>#f8էXN\Aؖʎ.`/n9!4(I7qAZ. phPLv0 9ݲuB6]܍ޙl7gי8Vhr-:'uٕL{ET^%#py3 s-`LF` ϿW+'5{oRE&/k&/1&/kReM^pM^eM^^eM^pM^eM^^*yyիckֹ˱4;O3vnJ&1P1iIKN0>$NiC*C6mxfsFnM2uJR"C4iC㘜Iʪ^u\*Wa UXp֫^+*Wa WUXz֯_}+9MUr.UN\LG ߠ]h@~եkG nh^:s(r0!`iDr.^B pBpB pBpB pBpB pBpB 𻟖B3߂k| k-7|^~{ ſ `P߂5`OgO? ى'rg64|^y._g$,ח|¸w^$3hB[ U[ SZe t,........ҕpMW ͩWW- X'-T2P>B+nǫIT$Hq*pe1!=on62\^FqwTØ#֭ux(<"(Cx(nE֭gqV(r\< xpxpxuu}\8b5$Q89JEn~9ݿ>ʴ6ȯ˹>䶻ձSVā$]E=eU̘.ܸ% }gqk9pBsyBs)~ s]yޥX{'$ϕ]87ݤ#C7| pl9pf(pnI^|T bN3sK-,s`scf#xs K<$Җ~J[l/ |T̕ S,^e=J[<(i)VJ-VJV.ҶVnҶVnҶVnҶVnҶVniӷ/ܳ4&|Hk&T{oDt{)Ɂ{7fm'{ 6ҫ^ǀW*UyWy{Uޫ^W= 佟ݿ_JZl+i}shTIS_x036nʱ[>.@P4I>VQ 勺jkښ[[ZyֳU] 3RLK0.X!XX!XX!XX!XX!XӚNQOQ\D`I\`I\D`I\`I\Dڥvۂkڥo ]j-v]ڥvۂ.}~C{jkaoÀ X;cǶ\хDbq9U;$e_ׁg(ϰ ϰ ϰ ϰ ϰ 㣬}0l_SQMDo8/('}|5XčM=-~ O%^Apwr>ז}#&WP(Ŷ &Q {-ms]6R^*~3R>W An.w%Ͱ^n%)mhIw⃮mxϹo!>xsއ_6췆;ߖmC|qF^bź9~ǭq0w ԜޮY;ЏF~Zm3Fm yqg܆3?M.zfݕQkp)Q́͜S95ӧ6s> \~0)**y!|!#iEoDVЛ֝c9>֝WăWè~D#!06tyms<\RA\QA\y"+Õ\ +M<"(dSW< : &hwD܎툸}6%q%#J^Gĕ+YWr:"tD\(rQ#J>Gĕl+Wr9"rD\䈸q%#JGĕ,+YWr8"pD\q%#JFĕ썀+Wt7"nD\܈q%o#JFĕ+YWr6"lD\؈q%_#JFĕl+Wr5"jD\pEO#JFĕ,+YWr4"hD\Јq%?#J~Fĕ쌈+Wr3"fD\̈q%/#J^Fĕ+ZWt2"dD\Ȉ^|K%ƈq%}GGb2qZZZZn2V+c2bp2>VjeVF[XʈXX[XʈXX[XZZqZNdO|'qū]0#O0WpϸC;:2M^3l{0~Z "l%3Nslq1dף|~Ut\K1!S.󱈛< S DŽ_K^ fS`)уg}Gy}&1lYfCtf]}PO 'KOa5-5-SoL 1 y8v> '3~66惯OY1kim |u=ޡ=Xw0-EhC۷?p8}ֵf:_*xp8_}x7?kkC7ϐk4LYMN|lt|JW_qdw4/ |L_zkۇi7ݏ7Mgz.ʏwz7/^xE'>[Գ?;e::/nӇ?<<}#/+;.q7.~Hfs'xy?ܟ <7۳rVV>"4tf=}ɗ^*M.fXEha`޶/޼-ͭr yy[~1tn9|K>{cW/M:0>I23s98[4Bȱ $O"턥ȣI=(M$l5VCn5NC4^C5A:NsNs^C!4j09L^RsUpss' 3f'sRk/ηr?*$Wlnb.sSBj1p6\OMPҹpF{шඩ>-ŝ_)bX_3čB &nÝ!$xHo~ w &gqk)n62>y>W%>Wx1ܐ2u'nG@]_Sm)nxlMݏ0CnTpM~\=p[`Ýo~`>P;*^6caZxu]\< psw?s~ +!S췽N{|A\,qwWKq~#1>P\pcGeKqHdH~Z -n~/auy\Qc^@p10\Sso5~꾓~=t?oǃVO`ӓ KQ 7wc>G1\< wTCuKݏu6wckxH>!ԺNn=mc;(aPăSăSăWWc;mxh>ZCkxh-n->n[~' c_N?n>и1k,.tsQSq˓yT&x\>J4ma>qP`RR1$=͊8Íb^GqM\KpKK5E![Zs}Hx;'Rq6'ox-e®q,z[vŒ;h(ol]/Wҭ\Q癖_wbp<nL?nt7->x/nQlsh\*6I'mʈ.Φn'ӱØI0؜ɓx9$]#~kw .kS'C]nɀ; $].xg]1`jl5vNq.:-^kWq:kfk op8~5Iqr5X1H)=>((""#fc&hd]և"ڱtrmnJpOqkL\Z"ӱ\Wd -ukus_4[d/&?JǦ7-~60nAnb݊?xx00~~6kxla܎_7)֭qta0()'u+EwXܱa495|<_6y 0v|<=cAnbD}.چ5|<n->}ܶ>.ڎO^ۯx=3ڔcMw-n.sMgm:η\?ǎ \lVɮrqd{lΔLRP@TiBsPj.WmW&1>{6 E[6\Eݖ,2\=wLJ3war643;g4nh0ܒ #sFc[2wh\ٜ 9Ap[>u3;sFx3 )!g4W[$@pG~37g4d4׭d4n`%p{E< u3 d4WèEFch\eFZ6 ۲h܎]eF>^f4ANN^n^n#Eܒ sF- 3 d4nh0ܒ 9pKF- ;(mP[h0ܒ ^^"F>JF k}d4 9Ap-nsF>3ahqoTh3ÜXto>\(]ng3&ڜp9\狪uΰ@>;iGh^yź>^~/s@6%dm9}<7Dl<8 s;H۠X7cCWLe:"FE<|<؆_7KWLev[b2~/0Altd^aPăSăSăW]1}ls0?캵td^fs0>`xOSw em~½vM#OXqm$)'pW;MDӱ.>w.wmnDܢܢܢqZwܢ\o@p[6Zu[jhhwPàܢ\X7XK-`;kY Y _Y -g-v|{ȵ>J=Oئc/ٟ=7]zs EbJ_y:l"6-26|8b\AiV0t=E41hbibibkVkVpTXnp+mGceí`eK.nG+Ar|j9rp=Ⱝ#$w)F{sq5Qȥ !.9喘wxȽo\2H`zMf=Oa:El,ƠYA*!~551jbcTĆm+h Z(vw9qa"6R։[A*bvf{bw&6&6&6ffGbw"6F) FkZ Vmm)ŭ`Rx~!5?65dgt3@7:S U0&>UĺeTGG7:kxpt3_7gusm*`-'dƚMWĥA5͠æX7yxA-M1\bM\y|.æ& e5|ʰ)y6ne6ZX5وFp ϝD>$>]7|tNnHKO n)nHI:N (Lf}a:>: nc>O@u>̢,XE>d%sqVr{*+%G9Gps*֢db-JY>| dmܜc%Gpsv|<,0(mP[iGpKzE;g#9Gp[>,u|sx| )!gW[1ܑ%Gp,Y>kx(Y>ku+Y>dnC1^bź,u>.Y>0*ada#FTY>k}\2Gp[6Y>۱ܞ,0(!gnܜc%Gps,>d#9pKZ~,Y>[|aܞ9Gpź uY>[|++aTC9Gp ,|0gnǯۜ#=,0())++m,|0gmܖsv|ڋ*w 6D\5u ߝ~c(D-NtܲD-NtܲD-NtܲeNt:Qd׉[ve׉[ve׉[ve׉[׉|ԉv(+gY͛>UEED'_.Σ_ܣ~`n1K>E I=oIo5R -ǣIj-vqH]%Х]<$ڦZq > zM(tR7AwֈC OFz,ZFZ PԌ$k"ī"dDH,8tkp27BFV!=DB@t+DFw2Bt',#FF^=у!;[hYFZQ= S6Գ} F!1FHej12ȍ3FO .BR""$v#d,ZF'Al #$c#!%,cn-cIa0=g0GA`0˘\( .Br9}A/cOo6z^2"i"ĩ"=6T,Ho}!DHhU1hLoYTN=yc’gHTkNP뜴ۣ/ѳ i& 9N҄vo/;9 r?GK8ܧ&1 8ܥCVpGMgA]pCM`Yhy)p@;ŝEEDF6w)R}O:yWo ɴlͲtRpHls!*LO\~Ħ/Q8?~8oq\q=NϞYM'u-uθu'Bu{r˱8Jd/]ݮS>Y7oN/>:Įdgn&Tq=x@A_FKI <SU=vs(ޛͱ['w^y󅚺o\1>6[ǯz~>2;i~v|l?mCh}nk c,_{W*oӿU!VwgC:BǃS`~ tS~[<[wy;żnNjǮ~g1bKbl zx̥F=xsP\~4A miH{76 ]qM]jh\n߀{t(ҥH+AX:_9{f|ԕ?Kh5S7oOoc cI tA=xU鬾CwfߢI\|i-TK{{Cރ>8T8w~@1OiqWW7=培=z = ϕק|pj|YD_r {~WS̕=C/:t-_'l/?QTNK[p? ~nk\CwmǤ9mO}M@"Ly߾BN^iːS$tKc&g(r(͂)EnSg2W09,SW2yPƠ XAZ1e7{0b#v{ac#-(7۟NPy丧ͨ=;}w l"+1&}?}k3º4njeK5L_]z^}= 6Xd8[vlF+,^oKoe_Ȏ ӻMN1 *7#a[fz[ %;֕`[~z4&t{vy!ݳ7dTh:v}2±CdSᣧ 9Z!8VVkq#p %9c7,3O>ޯf uͣ/[g;?1.S.}phbq) ŀ .;RԹǘ8`c1>fì?>7"/# ';2.#Cnxŀ&_cFVM~$5i^ 8[pw b7W9ܐ„{~b.  Zh6E ަ&S6nH==קEw^qi)#yzJ7PX{s'SlrT0`[h6oi-M;ETRAxCҒp)g.I k'%ӧ.8D|f{jKC`KGE.g"SQK(˅em3ݳQ1(i)k+ot.gt{4|Tĺ72*bA0xZ<*t*|Qa:>*LRɀ s-mc;`6*"*FMT|TFxŖ*Z>*l Qa;NxbK۞vDŠ Y9(WG<>#?lglܥD+&-KN^cod,€n< ܴ8OEƩ=:]6P^q58(7H\(W,^8PPn&_.O(FN8믻dnbS`.`Eȱsʹ14um{3 =wm9p:rΦ=œrh3YS=*;8 lfNyHY&q9˜q1}ϭ4p11p1{74D}n8pX47(ϥ! 5Q1Q1ۜls"y.6'lQ1X>*VCG)o+[zDڹ4cTc}¢/ %_K,|Y< &EϾ,l`@`I5`+8DϾ, /w{ B ɗ/ %_K,}Y,XeAB`ɗ՗|YK,x/ %_K,|Y, Xe`˒/ %_K,|Y, Xe!˂`ɗ/ %_K,|Y, Xe!˂`ɗ/ %_,}Y, Xe!˂`ɗ/ %_K,|Y, Xe!˂`ɗ/ %_K,|Y, XeB`ї/ %_K,|Y, Xe!˂`ɗ/ %_K,|Y, Xe!˂`ɗ/ %_,}Y, Xe!0_K,|Y, Xe_!CZx,Y~]o:&SOa>(3~D^?YͷGqջr]0ܼύ= W\3?it~z_(>iwNj;]_ ;Jhry«~~w&̚ii?R! )7j R\zn2w&uƻO xqZu%J9.Y q-ōj}շQ_s즠aэm(h4X>'ThR.|.5 ,|p1tG]Xi&f`.lxmxsӏSE6c<{s ش9 /MC}F6-ZT~KXz:M}\M9c2t+c2p: Gd7β4#z!;5g{ލ8ǩԥb9GK|TDA=cKxNx^pCw^g'(*O_*XnOH  ņl,XqrMzEd<8|I;)n.tkƮM=N~cYf\ R s9\ #vǿ{ōޕx&,+g,c{!p(1X`rWC~lwTT }~@NOj XjR=Z!px2b$ɀs<[< l$9ܼSn BjSKǀŀΓBfwγVDRxD(bdX< R,6B&[:*œl񤢢X<(Ofœ[y"ٸH<9Sb\98rX䫧'cX_=DvAr.?)I](r~Rd;'9;mQ.t$s~R>xU[kbcЬY.(ĆƨQ1-@y4C6=fVi*bc4m,B'c?L>.7g^Pj@΃(<G YJ .u¡Pj@c ERrYJ-f;Pj@6E6bGXM͌(r)j`ȝ"6NcƠYA; Ev=zMlxMl؈ r-)(w'Etl,RP䖎EW +hKA{zw/RPA&6cpy9Cۙ)rq}#&.cpaPw.cpaTw.c\Ac+mDϐ;ElN1}AƔccЬYm{g#\bLf2hABn y۰<fG^&a53d`%m9_/"sVAQm4EMaƋĀݳƀڈIcA`;f!g'j(m6D ݳ.6f;j#A) LQ`JBv$dh@mkcv(>G!]c8(/i(ԦzQ|vwE߽ңpvC╳;‹kGEsAq=quwp͜\&׬ 5gp͘\%l 5Wp͔,q+B̐\# zV9ם <݇.& W܍لkyw; n@k>k<\ιn;s׃ l"ĭq3pG3n=4pZ ho T[{p\܁mk-ny5z(U\3<5KpQ\3ι'sN\sLϟ>FFz7;mlx5mi_=7Fh\{g <3஦ +<]MM1GRg%yGEܼ wݜCiCVR]MµnVN֜F.\)p="[{ Fyrrris.n"ܑqH*MЃmm:8`q+x>nz($V!nqٴAE(aP 5k%\`kp5PSFP]A wzFP͂5PSFP­&q=T`+p#׃5nzFPj IBMz; z(N=[x[o'Zo'ᮽp#vnyl;p=Xo'fAE[vz; zhæ$@xIaIaIۦp3Mo'AEIko'ᮽvIko'Zo'Zo'ᮽvnqN]{; w$܁z; 7s=Xo'!nEIko'VAUCиppc$`p7$z; z(FA*ĭ qk<ppp׃vnqNMa}.ܰ>5 5     5 (aPU!n66wsnz?|p"my[=TAMCzsnyvZ]ql(ܳʵvm\^k?zv kyܼypnz?-BlpG>UC">#l7r=&A[y[=AQC&~_vp(|p =5\[=TAMCzBMW)F+|pnP=lp7ι>67&>׃nP!n6#c* zhT?ЧtqnyHDA[y{޿޿ ?{ǧpp7{dz01~~#}ٖ|`Kgm)M q\3-#o~LNgqpra±O"#$fqEm&'*衯EuGTe}q_ۻs޾k{wܾw}moWq^5}\.k.wnW_s\5}\ܮzO{Ẋ|MΨiS՜$ˁ;_Z?]ŴQU=>G@] pȮ}dWD>2s# ȆG@vEq# 8]QpȮ(}dW>+nG@֢/~tX/ܮfħqC梸M/lΖ?|]sM/uls}9w8 p=uu#.H=3ίwn[ pmn1d5p;p{w2 Zsw'nzdٝO.۴e*쟹e p}[7`[׶Lepm[׶Lepu p"m2Ee p* zh\e p˅ͶLnyl[W}r-'QЃ[ ''\o>97O䀻;p=ONYCV<'* zh׃>9nzpp׃;OOEC; zX}r­BVpc}r]}r \nq3pc wz0p"ĭq[}ryONUCШ6>)wny7R=l}rMT[pO'"zX}r5pWp'''\Ϲ䀻k>9F7w |r'>9!nE[=TAMCz0p'}r\nzpp7797O;p=O~ow{sW޽w{+^yʻW޽w{+^}nʻW޽w>{+^yʻW~۽.B%n˷p:矰swgwWݦ?]ke=U}[_rW_>g_\ʝ|?>ߝvҏ}dyq6\C9; SC!Lgr|kx~^ڞ=ip$FrMUϱeouE'E_7DǗywj>X#7\o\?g߾ ][ٲ\oFnIwX~9g{p_[pe{;K|ٝ='ܗo91#[m^Cs涒~*S?+E5~-.A~qӲܴ6p񴁋e.mwIV p+OoЖ)w.iYI|%mVsIJ@sIJ@sIJ,nZ&sIz=*ĭjbY4i׾8ǟϿk-F6 Հ4`pwp{ ++A pԀ#;9999999999999999999kj=ͰV~rknؕm\ntːۛ[?=?7ģvtk5eWi֎f+WZ?ĕ[3ݥbo?zZlA [~ 8 &2p6 GpGN{l$pi7Z~Kkâ  ?nCۆܵ>LO9xη>jfmׅGElx̾a|~uO?߿͓ݏʝ_sb+ۮ*ۓ_sǗoܾ~}x3+<3ӂ_s|Pth/7ۺ5E / iq<ԕ?~ۗ/7ogǿ>7FÆї_wUgVʧǍlS~|YǷ+u`;k_lp۳p]Dz. W<% v'>jhFUVnN``p 8({bx^o`Nx^*;Xyz 5+EE(TQl+AQv .AQn(A=E??{?9|xϿ><^Qf|l ~Ѿoӗϯuvu&_hj3poUZZVk.kZUjV֪Z-pUjw??ܼJg a޿tyÏ[ 򏅡撼 &]9<Ѭ.NC ʼ8I+mKj\.r8o?Lߗ/zxus/٫.Ng,nޥ6%#{{ˋ//o?`7|}yx߼yۙ{<?o.o~7ۿy<~#U+w AG_%iqvmߙi^6,u/y{w pXxc07qRC$`;Հ[8t )~E`~V+pP98{iD|D^aߜV/"ٹ8v"0[]|r vixHAL,1ŕ3ݶwoHLm:C ڬG7TV^R&,)SSIX%p^u>xJJԓr, '>8eͪG꫏f _ߊC]6jجXl֎1͛޽ t)&zL,}(#1iTsRA(ڷ6KQw:Ga=t38mEw^x&5;M:nNy0gpvBxi&kvvtI:x('8l"T!' UtI:x݅>%.ҁU UUxtZ ]:Ta*.v.FʌzTR*si.mZtDT*LQWks6¥MP"hT UF@f<(K[pik*U"1UXPEcƳxwi)\:}U UUx v Wkp*sVadZIwO%fu[ 7CLvX릀E~r(CNW-AL6LACT!r=qgv q*g~,C\q=fɽ\j͸sɚ A4qy2lbn>p}p, FpC62iB1;>7epCzfڻz-Zn覝+r=ĖA)v $܏%@ACzevP?@av: RU ܎X =xtazʕqlt)=VnJmw jƢCpn3jpSPȔ>r:3fTgfzDR=)L,GW-c \DCT!r=nvK[8`-C:E:tmvێqzzz "c9}LzHczHSݜvKC;8czp-CIǭTyű_sF֞_V*{+9K?$EIWQͅS .]<%Q%S@Ȓ* d$ Y,B|!K€%c@Ȓ2 N XP,yBm6FQ<= d? dF Shb!4bCU|H"4,YB4!K%@ȒI dI%Y ,Bt | !KFB%@VaU dI+rFI,rFI-Xk,(B] 4ڈmDyaZv o+V^>Cw,Gp 鱍^dNG.xOOѪ8 㥀%{8 c"&y5`S0mpį+nsr8\x4Rk$ b;hQUK3W<xs܇׷7V7J!g^dƟ8 n@i-}d'ўٝ>ݩ-O;iji^ppP k{ 6kdv8's68}I28/MLJ7W.D" ;iAnnn=Ƿ-c;xץ/^ܷwVŽu/1ܺϭܺϭ p}n}n羳܇_.6٦npnpnpw\7u[7Uǿ>r!~kmmmm]hv ߞlp͎O6 [ o]ه_/+OÂ[Ѻ[Ѻ[Ѻ[w3jhuo=1H ܽfu-nfnfnfnfwI۳0b4.dlrI]vK] wjg͏Y]@ԝn֝n֝n֝n龛a: ͥs mSwuw[wuw[wuw[wuw>n/Gqk { a0k+`Սh݈֍h݈֍h݈FnDkuivdz߭??^(:^YW{nn/nnxw7lޅ)hw{4[h/K,g{-)D' lyեmv quO\uO\uO\uO\f*J\!h ԝs9םs9םs9םs9;-p-Xij]ia{t~ ͯa_/1jw5ktMKӂ^?mrgW_Ƈ\mF{ZۑWIO(Ƙ譜h8#&p 8*qTCр6U/ `+$pk&m=x^ >;; ؍x^Txg5Sb򼖁cqw݉O q-5q(c|k0qNaDM$}VF9XR*s&p̟<:?QyfSt'#oyVpi3,rx >菋GϳALţ瑷Va[z\f< &hT U؆6 gXpik*U: w-7m5KN+T55 ]FK5 U8UbP)͌x)\9K7Sy%:+;m|֞^׎C|(-/O.xv;dnG6~\c{P^oǵݐ=^u~1ߟGcfySnaU\<.-O0d#W?.HkW'wŔ_j/r󮬬=+$.Y^,xT}I.5$n?nއ>:Z5Se[;z vGw|;fov @!NWmII`=B!f [0?N)13L)/2 =4Kl̸YTM\^矔`dS8vg"ܔq7NAs%{r3)K!ZnavnN-Tn;z y)@O=z =D"C0 [J0?)dz ZY†p,_Cn㜮!~5X^!T"nn*S5}ͨu5SpE5Xn1 ⦞ -׃iRt =xݼnu%o=34PACzHf7p ck Ӄ\)9`C0Va ԃWWW!(v܏m~2LzHIgRNmj:DvK)S!㔑azZ$=vW]M1Lv?d:|$:@xRB.'z֌ vFҢ3Ts/wl*{Y XnC~1Q=GV=[^ۗCM`?Gx,5;=l׀Ø{"|7ql*v>;Y;ߓgzRF|OJ;_ QT]:EQMAVToح4 UH<'xP:xs-b,;m~\[ĕ?wSp6Hp ˵_IKa+ɠ3^ddddddd.w ΒA oZjR=̒Af mf =x[p)9HAa[~v綝VkHsێܵ3a5|5[\y_v\p]cmz.p ydُ7(z =Dpن͚ǀk[ZuzH:Lvncq?^CCCP-(5\EaA!d7gݦ|c!=̾?bvW]YAӂ>y@֮NtJ~l$}5]ׇ;ӕ[ܐ6+o;z W>w_o7.n[~նP~;8-Q)<`M߳!zS2 ^. X#sQOO՟ MM\T)#e˸I9EC.8` <Mxx2w}vDU UU*xQapip0U8U1m*pVa<̥]]z~T: iT v UD*BmU6 㵆5 NKVqUiŎ+r'nHv0{R\斍}}mXRf eJ7}R+(G.r']Lq=߶ggib ݥ~4:ǩ8 F]p-0;il4[yz[ `v3}Xb ,5`-0R˳?ykt<{x+)O77.nm0逖ڳAXxXV_]eoR@2B; כme$)Mmʟ(KClm[;Nlrx+# ]vbv|b_\F kK+v-)ĕyg;am^iⅷ7W.L7.CO ҟ;]Ck?t^CECt vC ]vx#N 6^ٿ<*yAsv~Qy&mbZ>aLrC)V;}Vqx-N0{mg#@ [#7o}Ql;om}Ʊpu4Nm}hthlάB~2)C7(vK'1t(Ճkzp!՝39Ι;ص\zp׃zψ] v{Ǯ~BACzhnvk p?.3g.rgΜ]̜+Yg6pk\3ikSc {u8b:9gu-Cr=tCǵ^a7OWǵ="]P3kB8yxm| cohr=x#X3S-o:ǫ϶^CCCPMS('"PN6疓 p= WS('"PN6doPN6NELlB9pBACzBB롌r\PF9"PF9"PF9W+ WAF9nPMF9n~\F9:׆롌r\PF9v+q?.z(S+vZqZqq~\4qPt;i4Ƌ:NXY\v(<꿩xFVx4S=ꡌg\WM3gܠCP!*x}nq롌g\P3nV3ng\ЃWWW!(v܏x}nϸ-p=kxFu܏xFmx=2#]w,³?/S)We6Tw.Z5pC\}NX?Wt\\iWF #iit iWܠ[P-R?+sK2;M꡴+J2;Mڭ+vevՃҨ+Wح~lz&(z =Dpنp?N-LiCj`zH#Rmvێqjz = = =݂n܏S4ۊM7\[a PMiԏSCkEP>W/~xaq!@iϤ!Q]Yߵz}F},w﨣>vuGq>ꨏspQG},Qu x;9GpJpͶ!vݕWƝlg5߭_vX9^lt֏& UvqEq{ܘ~2"pk7oSZ>99nZz(#+,~%.X~a{]k9yzM=O\p=OyzM >qNlϲ%~& 8nOǓ` c~q` \\&i<4k72%I2@"6^^^1^Po. WEHCUDUrfxr㥄4tKVrUN)TKmZɛ^o%WC0+/iwi]]Xؿֵơx W.Wj`/sk`מV&gJ߶weLa_;_j㷕g!ai\=zHO0ԏ##p.$2WWܵr T%nJ\9,p* p-[J\9,p* p[RCJ\WM\JܠCP!*aRqJ\Pq=$mJUv܏KUzBBBAa[~\}nJ\Pr$u܏KU\*i;-y}saX2f\L /JNtCĜ^DI_ֶv|"Q2{wy 5,>nIhsK`|[+q8v9\V+q8J`pBQP\ r=8:ܖۭWq?.q =H`p{$0Aa7 n~\\ z(qn%0q nP)v I`p{%0ACz88Zy`p<0-<0y`pB^ W+q8J`|[\ r8J`p%0-C nPv I`p%0ACT!r=>p?.q\%0v+q8zBBBAa[~\8\V8\%0-WwkTi0'.ūG9wٳȗ+bG%=d"&~ZjMn\EѻpEfw!Eo+#o=lچ zkDm8ֆE^6LԆ0Q&0 Ն0Q&jĂ[&y0Q&jDmXpk"/T&>Oonvs_ga'U5.dm1QU "wF~7 %W 㖛sbZ?ja/ǵ{4Ӧ^ӵܴ2:yì\4ɀ}nks"2\}m]e0,k6uv=羭aڒ'Cx%=ޒܜ'\n-y}n=z­ǵqnz\ ׺n=4׊+v E)Zk]pqyz\+C=z­ǵ.[kg4/o^n W?i 3zZI I^[Ok w)TOkpi)aqiܖ4nPk"&k"&k"~[5_+ܚw0O%i4ܳD5cߐ%&ʐŋE\9o9& 2p{=÷Wr;s;+}vv7vwhkJnpsnp%-CnwASɫP\ 3ցp<`<n1z F=[8-$z Ƣ V8-$z Ƣ p;8usƃrɿ|4-['φel,]'}n|d-L>r8L>2#6#V2e>L>2e#淢L>`ypp2#G,׀e΅o+4îxHgNi;Ly;;39o7x0E 2W,o^~y[]uqedq,k%Nk%z@8jH] [ s):RrJQ):rStWWN\)\9EppBACz(sKQop-C)\Pv+E}q?.E}z =):{i+nPMN-E}p=StrStq?.nPNNWMNܞq9EpBQH0?Eg;/\Cx^a^a^-ۼp;> =x$ L\I&$Wɀ+}nI&sK2p% L\Vɀ+dd2\% CI&W+&dd2BQPܒL\$r=d2:Lܖۭ$~l/ _rB3Xr{znAa$%-d5\% ۭ$q?.dmJ2y[/t~;nURG `~QJ@mc~&ѷTj<*d؍69 D G,.br3"Y9Kk%.X^\&+TkT+T4 O慂61׮cPEl*Q"hƋ/:KG]: UĖ"v UN 1DWt pШBbl5 8٠Q66إa6X8;y [ly ;P{*BFBAc0^.=fN6 pUxT1\)g,7^A6t AU"ܠ*LP++\ܥS؍"(T5\)gny.m wz"ޠ*H7h<*)\vܥS+TkT+T4 EK]:*\UbpPeKQ9aIa8) UZYrkgr )\urQڥ7\e-ǟM^ 08h"tWn:w<4;> qqqC.8^onی\Gm׌\y#Ez.>_(n6nIM& hr%MI?l5\e6l{{+9Wfs]\W-]'\%ACT!r=uMnN&or=umu+|3F٩heeF~9h'\nN2pe&h[@mE$gHj;Wm\k\v1s;k7;\iqNן,>XK?~}n\\\ WWW]Wz(\v I?J BQH0+MP?zיznK62܎pB^\\\\\~}n\UUUz8Ͽy|yd8XdVđ I\H2.WƔ_4,հ`Z{z].{`{\ W{+=J`p[n\ +z =H`pn\sK\o[z+q=5\%ۭq?.q=mJ\p;n^a7n7(zT8ܤvP?R=zq=mvz[Y?ПП者Ëͣ.>b2?xxqo'Bͫ͟uص?r?m֏x]>΅8w>>N#4,ᦙv] ni#rs{Ej;7/|}}WYr?-H5QهЍm7p)/w^8H۝Ϟ| )7X_\OyHkY; k~~xyǛfϜ lm#fc#"&[poܡڐ{ܱ eJqv+Uk\aմێqNJîq\Æ݇8;l_>w>n]T;V7L1wXߠiu ׃3p ׃nry8[,&c;<m+mG.s'uYZz =Evr>7uYNEb;ܶvK]\-})'5 +'r:&WN@\>tCsK7$Z~K7$ྥJ7$nkp/J"݂nQaVAǕttnC܎tnKٗ}v-oQEփ@[j[n=mQEփ@[j[nm[nm6͸7ƾOjcߌ4}~+.U kLz4;əӂvqMK}rb4"}QCr~K nʫ/j&CwX÷%7ՍyMu!9EM+wd]n*\Yr}cX]rǜ+ӯMX妺\YsKj[rV+9+J p%gN nPrVv I p%gn݇i6i 7=򷔳2yNpG3nI\󩉃=SjQKms5 upG[oqB^îW!tvKt>7嬘J pMCϕl7ǀ+9+mWrVe=WMN\YnpS]YmqS]Yr9=Fjko䬶a#guT9-nKJp{ 6?>p%<5 P9 H9 9-w-ŕ倶jh+9 ]mq%k9-n~Fr@ܒ怶jhkVs@[\n9-nx5 =倶Bk9-nPm-ō܏Ws@ܒ怶a5ŵn9-~\9Un<}V4k`xnЧ~N?vNC3FiM7/ꗶ&0\8>w3ˁ@a+v4_hnppnpnpt+;Ͽݿ}&e9&|c.vHRפ/2b_Yӱ J(v\#lt3OHk#6\^qϤ#p#p#p#x59[lbW:p=Ncnpp[i =4~tnpܒqkY2+#ܒq%ǭxG\D^a7DW"cz =D"CsKd p \P"cJd p[n܎qW+++v E%2-}nz(1n%2qnP"c{ܳ(ws8_=xxPƗ\\5+,AЃrs}n7o{# k/aqRsμ]X"Ox>DNu\Vsϝ2 p1o0:q0?v =xݼn=^ =B\k\k|.u\e>ne>v^sW+ WAsnPMsn~\ze>J=h26yfzglW26+ Jf[26ܒ\dlr Jp%c-CnP26v Ip%cACT!r=>dlp?.\%cdlv+ zBBBAa[~\26ܒ疌 \V26 \%c=<=*l^`á-n]Z&jR]KwiKD]Kwiw?n~h]x.}ן[Gxܚ] n n En~¹^]Sjw[35[35!gpkh&jh&jh&jhb[C54ۄ&;:p0 LԣȦz{G}:ڑun  e#m{*:3#l"Q>5S>_g5EQ>A<у=у=у=XA|уǿ7_"ڧMypO?N5yS&ovmq]@\[msZp.+z( [:<87(ύ }nlo [4\rEGkE8\zCz yݒoǠCP!*l4nZhZCx\ R=kkøḶvruԏǵЏA= =HPp%\ Wz疠JPp%ۭWz+A=mJPp;\WMz+A= =B%q z(A=u\%-[ n+zzz "疠>p=Zn\z(A=n eTol ˨yq|e?]]Yθha .y_pDW"+@ Jp%\D+z =Hpn\sKp["+@5\%ۭDq?.@mJp;n^a7nD7(z+zX-QG4;;(Cx\K0zG~<nGղZַʭe}ղZw[벾=:sg)r>ړL [[ӱ/=(vޕp }[<?V4K%FEPcb0<yV{e͕gvK2<>=Y>-_~6vZ+ؿ~6'Am&r^2ȷ"8;hb͋H9AHNΔr[O):o W<}7jPqjL\n?8rq#|c5f1ڲ,&?ږږY!V'\ q>)EcV#\ e2髇p Ug %G Jpsp;n^a \^nP!(pAtɍ\sÒ%p?. pD/q=ŌܿdKhoug\0g+$3DΥgkٯ(h9!r?C\ȹ s !K !˦s"6 ‚Rȹ [6 ;6 Ƃ^c\Ƚ»& FQ1K' `!ژ!ژ!r-8+PC{D F^\ȹL s"B5DΕjń,j,j9!UXP 9W!r.YCV )ZCN )[CdX0W!r.]CFh#jڐ5B6D6 6D mH";6 [ ;wK)"{6FFFAc`TxԴ!QhC*,(m-m*!mdI-|qs??޾˗7&߻C|?ewX=䪭}8QDxP#h*&I$%S,nQ3Jy~*4Nj.+xY5 dWzy9 )\3Jpsp% 9LkܵJ \j|?Jq[RǖSulI[2Oױ%%[jcKNulI[2Oױ%ul<[ǖԱ%o[RǖӼulI[o}l$v߽ĮW#%v߅DiIXD➕*YIXsKp%a\IX$,W+ %,NWM+ =B$,%aqIXz( u\%a-[IXnǟ%a^Ѓ$,WAvF%a- \V\%aB^a7$,~\z =D:g&,jb[5aQ5aQ5aQ5a$,|y_ٿ\GBu5ŝj ۨ`>Bo/䅗adn^q5\5\5|[5GN>k5[;OB>WAR׀vS롢Pn=T4u>*-k5܏?CE-[I]nǟ%u ^Ѓ Br>(tP܏٠ܒܜ&\P\VN\ -C9p;n^a79 p{,P =D"=op y4Zy4:y4ni+z?WJqW\)\9pg+8[Jq7v+8+}nPJqz(8v )+8z =D"C9s[Jqp?.8kJ):R-[)܎q)\ЃWWW!(v܏K)>-8kJ)ZnRq)ܖ롔qg zpYw[wp\­w.[<n=sݟWsOui>pE>p|.9؋|>sOui>pE>p9_=3]ᇛcD핵W24O ɳam0H>y6~9olYq8=:pt6dV6k`=<:'͗)9UGp}K  W,C^dg!m;9tC`l׀X#lZ&x0|pCixq۱NaB p cid撁K[NZNapųw abϲk>e\]^;4.kcsZ0+ryAֳ0[ܴ]3.sqގpCam{!`=1gӇBJl81&i'!$'3zZcvy ]O?XN 7]r[.63WƲ`ec ecƒ ⲱ$`=.K>l,l,X6,K淢l,X6+8l,l,X6,K5`XSyn~>}p g|:=?7kُ~{e}д໵¤8tZXbw9|_Oڕ-¯ccoqMkY.p-ü.pü.p[:o =(\`GOVp| `~# n=raQȅE]#u[\Xs O޼-m2C m}>ct+g4ٛY\•=nȼk(-{܎{\=q2p%2p#Cn2pe#Z2pC-[yz =ȼGzxKe#Fe#_oʼG5\e#Zn2p2p[2p;j_ǢJuqx:hi:hg:hoX:j_G} n}sn}s;q>u.>ǹ,L)f;HPw"Cf`߉n}'R?. ;t3Dpunz\}'RnHt3DJ7Nv[Ww3D^^Ϋϻw"J7Nz( ;ڭt3Dǥ}'2=̾߼<<XVG]w՞Fh_Ia# m3_N.k]ouvQo5 ٸ_| bT Wr/Vp_•3~7||n"\y7n"NW-||nP!(z\R p R|z(5_{Y~l΍˵_&Ȍ9/N3dSdsddddd,2BL"T"\"[6$[N ɗ!rd99k555 »%wFȒ<#dɞ!QhCgl ";wK [6$O}?},m7K}v҆^]Yuw0_:wXGiv6&"^:wo#8t-Xg#C0r; #Eq#v0dak74;4,2m]fe/S:᎚qTKN!Ϡ8Ւn$zv[]df- \Yna-[uهzZz:n^aqwwz: =H>7n1>5܏>\^lq=x[nt [8F zBBBAa7̮Xz?~z(kJ'nGp;nң ^qJ&݂n?K>M5J&Zң hnVn\ЃWA eWAd7(&E2}n\)\PcrÕWnq4p2p0p.p,p*p(p&p$p"pBa^ǝWzWznK6܎pB^){N_ڗ}n)}nppp[RCw\WM]Wj]7(z =DR-U.k\pCoܖۭTnԶW+++v Eǥe[JZp Cg\VYq?.,r=J=ͅq"2Ɖx[GQu X|*QuD5QGM,uԄ|*QuD5QXGM~*a[1ı={߭}+eZwz]qxo;-X4|>~%MOl)IkS;s'3!;pRc 1b ʛO{d !̛{dyB#ΛR{d} Л{Fp Ƃԛ{d34NP !8#u_x5pcړw1f<}ʀx+\BRBrs حm(MGsu.QE7r(ȩ cX{KnS]O/y2|~{|p,/]p}yjjQ^quv1=OucJ$96m3Ixv>abql۝4Fu<}VTRFloUKgNk.DޛRI&rKahRK#qgU\)B UQ'7gʝ7q< kӌ27`h?OӣqіWz]zm7+0wLH.λڑ{r C=p\#6nzGF^_mpS`Dܐ߀z< `jS 2p-n)`nq]n0=!Az yR!z9(=\z =<b6neŵ3H.f\geJے+3He (3Hw -6eJe 2p-_$s ܖ?w s \[ ܠЃ`nTA e> \ \Pfz(3Hv+3H~\fW+++vS|ϗ$$2p CAۭ \?-CmCm^a7[6ܠCP!*{6\|m6\Pf{6\|m^Ѓ6^i$ܠ66&+Mp=&klu܏lmlz yݤa p{ǥa pBQH0oXP?6\K0oX\G0oXܖmްyzBR2p(pe JMl}n)I&+ +Mr&++Mz(Mz(MgJ@ྒྷLX7mGcy'9Χ?"xƙUbݍnWMj6ܠCPaTazȵM\p ǹ Z\pCm[m=ǹ zBBBAaqm&mnm!6\k86܎!6iq/2޾|]OD[_X>a7 (K^Q\xN rf:b'G䈝p;9b'G䈝\#vrN;=b'G䈝#vr{N;9b'G:3v˿~ÛꑓT/0)Vp뒉Q}y cXQms=V`T[-'gd֥ Pg Q} r)mG{T'm~qg<ר\pGnTxU@Z?* ,_F]RV@Q’tT@ܣ‘wd30⳿({;,wdY|Gߑw{dY|Gߑwd]Y|GߑwdY|׹G߿Lݟ%ݶE yB('M/!.~8Gp4|8Gh>͇p4Ѽ=͇p4|8?27}feifxnܸWVcv|Ͽ5/ { > [y~^Ҁݱ}uZ~y?zrZ~"WRWR 7nJ-'ܔZN)pSj9rM儛  )'W)@)B)D)F)H)J)L)N)P)R@* d r  QhCl""w mH{6$j^cA`  :@ƨƈQ"~"k! (a qD." 5m`"h"p"x""!KH%))VaA+ r , r, rІWhC 5 ""6FFBf d3 Qn4 UhCb ڐh"w J{얈"{6FFFAcਘy d =(!D JbvK;6$&A7nkv҄Kˀq_ϧn>/.|' .~o l<lu-pf UiSx}1{bߧr_'7 !n{)K)3xЀ x p/,~6*p/2vɪ mp\)bWb۱bgȥڿ-\)} [wE.}w+WJv˥WJ\)}C.}B^a7H\Aèo$F">D\F":|#p;n|#p{z =ȍDzv;yo$F"ʍD5\F"Zn|#pF"v\F" =xݼnr#p>D = =TF"ZF":F"vnD<.o$W+ 7Wn$H\r#pFbo$Fb؎rl>(o5Ըr#pF"ʍD+7Wn$H\^a7H\Aèo$F"ʍDkDu\F"vnF"|z = = =݂n#Fbo$F"|#p-[|#p;|#<~y+\e{B@9!G d{B@9!G ƴ 6e -!+@J p%\ BW!+z@H`!+@Z2 nGVB W+0pKnܑ;r 8|O!{B@9!G :#!7_ݾ~XXȆ{BX 9b!׹G,䈅#rBsK!Xq) rBsX 9b!G,䈅\#rBXL,sw}B針 Ӣ(4Q,[$~ݛƍU* J͉{a?CVj{T0*v^ EP-(6yl*ԸrX\9VW+U*ap rX\9W+&U*BB#C> |X\ap;n|Xܞ|X\ЃWaPaP!(v<·67V|X\kap C>rXY1gҺSrq,Yʌ7U9&i@yY=wo޽y/ߦIv/[}+nb3cWy}|2Mp-Cbz^Lݲp{>pB^AA[Pm8{1lsp Cbv^Lu|g/&v\ً7?޾t7i/8 /ؾ(<c{+cKg);fǺo~*_4bwWϲ3)r^=jofl|e2v~`ܮ8=&7O5?,7~}_eM'M7 *bˀilbޙk|qu0nYp׸\qnW\+[-ɕ=m⺭qGnu[sQ˧⺭q纭qU纭quT\5nnr.vݖ.<.]jy\W\jm9]3o뛯|{w_On+M4e@h?ͣ\?8m0.?"Mۇ+{$K5M.`j=w]2%~/r| *df`fpcC}Jr^!A4A`׹ ]JzNki pO1!?\[?`!/_:I_83K<`]m~}/5~qDw88/9X].l%8/,KthK4MD#0y`Y xP 8pp^8/w U,箨enR崖>RjoѴa;+Ϙ*? Z3nFq/JEROt#wqFn_NW zIl\?pI\R?p~"JD+W'O\d67's$s$sz܀rDp;nܞ\ЃWAwPA"v|(pz5\9"%^p^Rdn=zI"OGģ~Q?񨟸WGģ~Q?񨟸/?wSrɵ%<^^M;uppkj LJp]ww;up}/]몰+6Wݔ1h.yy"==J̓k`RqpRJN O+,W |+,W |C3RpFhuRxpeEq}q?ϊufh4DcnmKֻnoVq=Lcz y݆C n|p~k߿8Y@C٩,# Y@GБtdY@׹G?& # :,# ::,# ( ᛏ_w>?wGs1훻kMi5kaboy)q1vPR6 LI@ "[t*&Eus(; G~2J8W{ G~UYqg) Yqg) GxTOc rϊD6,Ei *}qK;+t mS{ɉ x!y8&yǔA^cm$.1t{-e|c7?1|G9͞6xֲ'q]7B]T,{y428 Ǐڌ!:W|;zOb'A1vr~{ |-6GxT݉IF h(~+)C46P,V:^^ ı>0x`?oWI35y <̻w;5& ,ؤql0[n9 K ,KuXn pWk7,$i b*FBc č !ۭlS:XiUWEL57^5pJǽ2Tר"D$*xAcO 1%b7c"@UČ`6`f̦tL:Sz*bTsUA{x߻8ǠPEH,xĪHyxem6tJ5 RU~~TؔNx=)M阁U.$PŠQESZ%@tJ$,6cVM `2 S"~M:.V3;ny n1i9O:c zq>ZࣥᛲYhi- !*16,+t`0Q' vF^ py( xЀPhǴg^  GU!8,mOS') hJx13 8٫4 U2G <*ylO }PUPgEX1jU:>Sv\WWLi^AAPEoToTLiwS:0pb:T,G4sx9ҮSuXÛo?ܮ7|`rI/?c(MɽݺY?J&=sӅ#w~J&pL2ۧ`염x+` 염{ܥ}$!6D> D ]yy{*bv/SEL WEL-7^LSzt|J^㪈ɽPcPOҹ*UHa8%"㕡U6xJbUaU+ptY^ F^AA1^PoS,1cPTkAUDoSE,2xb18oұTE1U:cPU5 )qlJRcTAQžƳ'nXm NikƠ*7"8Xp v )qlJǒcT^AA1^PoTLi;)ˎAU,8Xw "z*$o3cS:8{u7Ps~7 !$ MQ$~RVv'|dݥHA|aErmNpMbvIt[:,3X'-vc pL;^O6Uh=vc ӆ'ܜ!gvˉMGxyv\CLp+v |6z = =\psg5|6krgu\ vn |]ϝm+zHmwP!u!ܠ[lC#psgMmp=Hgµnنpنp;lCB^a7[lCنpBB#C٦-Ok<.Ok:2[{ܞ2^Ѓ!Uxb)fn 1:mHgMmW:v˝m7u!\lCl=Cl^a7[lCpBAQA:nlp-Cl!w܎-wܞpB^AA[Pm8wis 6krgn :>sgrg7GpZw֡%/7Ώdn?Wc\Ȟ[VyJz=n.n|Ґ\mI#nqnr7 W+n|Mn|7>&7> = /G_fq:qϟG\><ģO.WϞ=!'?"KO{BND,} 9 9wd 'dFnOVaߞS;6$ȽB @dXPݹ=!6F6F}\]bmDvXEh;l"8=ExF^!@"@#@$@%@& d 9E 9 *,(DNDNDڐ" mHƂ^c5@6@FhchcThCb,D6-D mHBB@NaA " rF@dцhchch#h,4[ ,B"6$VaA * Sn + rІYxGo޽z?իOn5U4ůu}Woei[&L<ƹܺXye?Ic9Fҵq I\Iܹi.䎩irc);&0qۜMMݗ΍(b&}(N=W9ܹ̩C&gz = = =݂nVlqcgk;Mv+p6gq=8\:_s.eK"9p CΥ\s)ys)zȹs=\J y>s.%BB#C.\J5|\J\9pCΥ܎-Dܞ\pB^)p`\)`WJ"\^EN#Z`Xj"8DhssM+5r+5Wj"n#Wj"nk"W+&5Wj"nP!(0*0R=5Zܲ&:˚kʚʚQ5󸬉^ЃD\Rp&JMmn+5Wj"6&eMֆRp&JM+5Wj"D\D\Aèk"9ap&JM\&:\p;n\p{>sM =xnAa\5\p C-D\qC▩ܽ{WM%&-~J_z^޿o[w<~͕?7scO?7mWW+wjB/2x瓛b:\b: ) !w7;ɽ c 9LNg4Jjss8'r8pMj[^8.cߟo_7]ojť ώy>?X?{7?"WM [86c[_IpgP|2I({O֏(ytk\i= vnj5xWۀ+m6wpŻ \nxWۀ+m6 =Tw-ۀ+K!wp-C\GPzv+ۀy\z+z6wpŻ \nxnswpŻ \햽ۀ+m6v\ٻ =CnW+&m6BB#Cnٻ \ۀwp;nܞ\ЃWaPaP!(v<67{\ۀkݲwpٻ Cn1O/|mV~xW~:2⣘6A棐Y9A폐t;vm?C) rrrJN9J7J7J7J7z+߀+߀v I7Jwsܜ Ϸ !~zȹ߀qo<ι߀z =H7 =H7$pG>swSWRp=on9܎!;W+v8|g8FF9q5tqTspC܎ڭtnOq\ЃWA+q8sp9ossq8sp-[v8Wq=d8\9^a78Wz = =\9f8>sp-Cvzqݲsp{>spB^AA[Pm8;ossp Cvvqu|g8v\9fy{_M mh724Ay4Zn dy%ƦPN yMNܿ,z9۔kph~tI/•_~ܔLR pS/•_ W~F'n%}4</i Xvn9=_wr@pB^BpnpG>s67474p=~krg?u|~q=~+v IG?<7(0*0R=Z22 hz(Q <.z = = =݂n#1qٷ M •J>J>J>J>zݼnҩp%Aè{9\r@p;nܞ\ЃWaPaP!(v<67kss@p Chv u|v\9ÛwL3ܸMW2W̬\K3dU-ǷK:gO{GkR!*euZKwbPҽ=o ͥ{{(AK:9PbPҽe!7go8c܎): wJU AL,ݜvsG^nO9 q=8 +v 7?ܐu ) AQ1CNnwx^uˏ\\sX;ˏn\~ p |'~yzE;v|N^a\pBQq|^8w\zv8w\ЃWaPaP!(8np;y|_ pT8*Vܣ"*pT8*JQ$pT8*GEUQpT8*o=oڟ 7u\|`WKG.\e&#{.G~[nc)p%pSJ<•6f"}# O)_pS# \&y+y{#8 L,&$p ǒG@G!n8WAwPA7(kHJ(8rzykrZnGGC#ܞ!xB71Rk\햯\C=C^a7\AèЃmss)67_\߯+WB+NW(nPu(i(N-_Q\ם|E p;|E p{|E pn^a|E pBAQ!:mssp 9Z!Gq=h9vn9Z=9Z^Ѓ:A)u Aa7)u #ǹi+Np=RkrSu|Rq=R+v IS<ΥN7(0*0R=N[2Z2Zꡌz(Qr<.zhy\X:\:\:\i+NWkrp)Jp;-ܞ!G+vR+r =FF\r5|h9Z-\qh9|h9zBBBAaqikrp-[8GzW_`37~,w3pZjlcdM9vP;;Rk}Ik'\5ɑORk p#p&G>ƚ&G>N§dz yݤ&G>BB#C#p '\ |u\gfKՇxɥS$ܒ#DD@쉂Yn@4rWv"m9B_ K!69B [s:ȝB @^  Xk,(yP|FF#FyI.l.l6";"8`@"@^ цܨ#$@dSG)LrS:@P":BND Jv!"w mH{6$h^cAܲ#8@FhchcTh#ߵd  Qn UhCBڐ "w J{@"{6FFFAcਘP |%F * UXP [ )!69^~RO5o߬kzg1?z`;vu -4!*/ g:_Cz6r+Ȁ\J62e#׸ {5d#^6r+Ȁ\zk\FܽlWw/ƕldFps6r\J62e#׸m7ƕldFq;lzFqn{5d#^6rzFqGwe6r[Fq ǕlR=Tk\GPFq;jJ6ry\FqB^F\F\F\F\FܽnFnss62J62J62Zn CFܞ!g#W+&Ȁ+Ȁz = =\9Ȁk<Ȁkr62: [Fܞ㜍 ^ààCP-(6yܜld5\9p-[F\qF܎!g#MNǷo_tN)+wΉ'3;'V1wc{qݷF2yv[Z -rzLr,l f$u{}̃` 96⽿ݓ߿Zwv7li6c姚TL||!qTښ}SXwĨ/޿Cqj!ڛ}| }bvXɀi]ż F~]\%Ϛ|'ǽ/} ur|znȒO<%M{PBr`d偑SaD爜*#r]`Dcx1?c8(4 !R(R8 McF'᪈Q1#U/E'SL-TxE*(RňL  K)D*7FXKE: tr^ܡxTdOP %S:Bz:JB*О0**)CoSZRB/nP sRbaoTP ߉K%x>z]=T46PO@Wõb=\+NÅIpuq yZi,VsbU؎oˍ`Xn+T54 F>UN U8UBr90s|J;ҮpVE|7Jeik^I쫇^}C‘OGH/G~I>R􋔹#E|#E$)%H/|#E$)%H/G~I>RK_|藉G~I>RK_| "@_X]}x9ɟ:mba_}zk՟f;\?e=N{*b:T(jA1c2|AsάG*Ɲ.Xڸ@oiDQ73k`Up*Ru3; aS0j#?8FPpA 1c5j#?8FPpA 1 c5j#?8FPpA 1c5*#?8FPp.G{vu^pyLxG_ɟxj9 7]X *p~c_jܣOӕuʊD+!yd<_ypἛ*ՠ 4NNתNUtZutWiugh8l: =,.N+\%f4o/l27+x.OYe&57L/gFzD)fO 75g y*Ta-Wu UXUa;(%3^ҶSz*BFBAc0ިvSڝXH(T W 9ˍbJ;ǧpU₻ON}tM!D{c^}G? !'9Ap*xh޼FAK]9hAw*tQN!ī#]fnSSSSSmt !2tQ"BK͎BlmB~My!آݩВgZ AK^AK^BK^AK^BK^AK^BK^AK^BK s^A>6>?/wyj<DAKൟ;bwlWђXxS6KjBXX aU$"tqUђo]&e AK BEŪhR& ) z/VGݪX ˾ZKƨ 7EG9-Fl},ܽ#)whB[ کNTngQE)Z\{*zoYG=guۂ{zwZEChB(h3uPZx./VGbwmz`UAͮא`{QF. |ҐڬM`iH`iH@Ґ!KClH X4$`iH@ҐVEِ;l!KC5 U U Ux#eC6؜0'ܐ WEnH@/7$ `ǧtnH@WEnH@=UEC)F! Sxuc36m* ^Oq~7_4N"/{xWemq1vTa \Z)N\=r{lsJ7ʍn܀+׹wָrp&7Enkmn;܀kvǶ9c3Ho69cmLnnwqkۀsLc%kRՋPꅋT/\Tz" ը^BE.*O=qiuKkS/\Tz ե^*EE.*IpQEꅋQ/\R pB^AA[Pm󸸵 rip6+zXKr˻7fvVS"P8 m̓I5QTX5l+x̓'sϲ6^S#WHQ9؟`Rl8x y*NS9N `u'/h ^/=`b)OAm*bX9_lƶY6cF[ 8~˕5ܭ$ཫ5pذ^yu=X%YXڭ6q첱WkJۃM]pĕ5^+m)k*WlR{5&m̫TOS=kT4Tu'{TuG6iy`Pu' ˍg4UݍSzkw\KTu7^a=ٗ'y*ZwF=z'4.hԓ=QOvA z dOhԓ]Ш'{BF=d4ɞШ'QOz'4ɞfG!k󂞳W7'6(oW׊A,9JaW Xl["pXz#_ڗ"prpQ5Ekfmp>":|Y|@" .JE M*.sh2 wf ^՛/jƍ{_rCZ.G*rӇMc=}wnս Ew9B֐?֏J7N5ݴ *,46,QX]ZjcWw2Kk;toxMw p9V pzכk@[jNvtBKВ|>#d#$d#$#tE'蜍NfE=TmUxIIOhJGoOvu9=3A9]3A{ͪ;YrG1U!w#Q(Dg.mPr{hv\!.;nb=EJ!^AA2cИq`DZBm(d3Xw.`O.h?}{mכIr}MGKr\ep>+/_(|,蝆ulz!o-gi[GwѲ}F蝆ulz!oא63A[󎘠eG;=vNutQ^:ګ5f4]R7:BRև2q}d h^A;sK/IOТkF'=A ړ }Z:l 6fO A}z{-g#hy{"Tc4Z&"=)h͕Mm"hQ ,hP!"T4fƌ)UW)k22hTf 3nGDiT!PȒB!jŒi&sA+DN߻ktns`?3xw7fC1j8Nv“4vlܿJ!Q77\ùәwZ7M˖r9;""nH3;/!7{XlZ3Qιmqشj9v-wփiM"yr̓c\'~W"FJc_%Wq9662Un>xsʃ%u^Z 6WkIdW1ϼV3O@0%(ϼ@x$ !A(Zn5󑗕f^4cQQBaler7fr43(0R:JI@LБ(QE3hFQͤEi&f<͓L(QE3hFQ͞Ƴ'n(SEshNQB43s)NShKG( {]-Avmq$ 7,{~izvMRwz]D?>}HN>wKq7tGKy_{wa7?yyM"u/g. |S"u񖟰u$y:rZ i~j }_Dۏ 367o>y:nِY]j>o3?$E( }PǥD/4d+prF짒?w󁣣2o~S-!S-!c-kKZza(u)$J#pb+( J#23oJaqA#pe8n98|G R<f BX)TqU;|0^=_ا<N7 'Q !'x (T1*7Xna 2/&*$XB^c<0\26tp˟TU: ׽N ;;*Z| =촫h1 tiWc@qg]CgAgAl*AYXj8d6;YD@oOu9{*i;U^*, 1Ua 9F*9T@věZS2*{heH!RQB q 3ΣfDO7 ,nQȠRȠQHP1h8.DP!P1Wܥ0/_~umo;m㟮(tK󦿈<|[f5f.sZ>[Z~KzûA v>Ƴl&kݜpLD`.0oͩ,s^nSEY]ʍ7K19/໚)9ͼ%9>Tr IR*ur͒.)r-X dVul\hV,ܼU#xJ둑!['wK*['O %Д EZpuPPn? K~#B?zgEJO|b:e58R68NN4zKJE?$w !U)9 ~C ~w CXnoqq '('w('o('g('_('W('O({k<'/(*G*T8aONOl* ';I6^$O뉫PUx*RS+-p1j՚@=+Nؤ:  8&`0x&E8&N*LPw,٫HWKV<,k*Bx#W=)xєlJ/^lfX2*2HV32xb_ˠ)mF^AA1^PoTL饸 1b).TBKq gs9ŔeؔvBp]CpsgӚ>LrKk؏bfTDÍ|=o .GLsͅ N!jWezǶx.&tooW)^aw&쾖?>_KT{[=_!?w}O_yMz}np/زb}k4E@{)Zb XXU/f-\h\MbD?-.j4(v'ip_ "(~H w%ѧf( q O?1 .e cU3"[j5[nT"a$XQ̠IK)8 "yRhp=%Hhp4Kٛ%eL~nn<۳G{Pb XGo}Ij~`67EN{76j פ"BqQvẔݒAB]nO#ybB iJ$$cin nHٕⶄ;,)21"7fp#::1v[uǤ-Jmt\KO3)A@PGn nXQHrz{k<)TKaiF 2q=Hy v<=RpBBBAaklve׮ڥ^ 6l9@z%_< 2K>UqI.F kկ'櫉I.*mm)}fG9oSV9]mÒ΄)Յ%#'}훚BtcOkز=x]<ʻW?ٜ̍͘籅bb_{WW2 OƸG270M׏V*u[st;^;*ՠ 4Ns;0M;0M;0M;0M;0 {0|&~]P[9ZbfTrv< Z4ϸrkqk< Z< Z< Z="&JtyyY:< Oou8n#sӼduɳG'k|t}ytBB[jШQ'F-'kZNNךMZNN-''A DrrBh99ZNNONONmv2TRGV99a_+?QNN=@ =99ڳ S)kV|r"A*AͪON="'&<9ɉ _ʓA[DЎ+<9tX< 4j;(hQj;(A2cИq< t> t> rin׷|?F·M{{^f-z{}%n~o}:m4,{2σUƂū5be^1׫k,j Ƥ}ݫJًN rH}_{4_n]VW^cvб=أݝTahfr.'_o榛|:.)s7ߛ=M^%ŭ#|vC}ng~48m% |X . xk 87{=q*:Cq$*8UAOޮئ|跳DrTM28\.\]X*ՠ 4NkWqZrvlђs@ВsВs@Вs6\GKBKAKBK@9mvIIdk_KIKh־V 6'J΁h9@oOr4r9kskVs@ЃfU94B9 Qq{Ʃ˜69 hW2瀠-WHs@Ў+9 莛9 O2瀠J!^AA2cИq9s@sB[iM6?ܾ}[;LW*5P?]ʜkm~Qi`ѿP)P⪋>8וp:erPiWz?M'⵬HˏSκF4; _;°[B0n[ΛC۞[sHxS.rw1;7Ft3a3s8vs@sx_\6?K,{nثH x\Cs誑SA6/plS`N qUTq;P߁7n&lT1hT1(T4 %'> *ro6\Sæ7;Ŕ΍S"7^x^aA1c6soNf=P@ORA \y)U;B`j 89.gZv8U'OxRFShF^Wo;_7Sh}4ނG-h}4ނߟ?^Ťl;L.T$v8UL*&5Qd>GbR*&[Qd>\d?\f]ڝG_d]ڥ~y'ۻ+:{&r?T#F~6eҍ|BF>F^h#h#/hOh4'4 mm6 6FFyAffFyA|B|1@FyA)kJdܙclZEKt%<'h #t#:mZ =*vbۏiiۏЖ+# )q3~D/U  * ƌ#ŶO7oqŏ~7r9ySig_]=28wσW m5hB; S%='+{KhO%E2-IJ,@\ =X#r-)K9U͎B6,[[~߀@~=@;l v vF;F;xA|B>^hh/htth/hOh4'4 v vF;F;xA|B>^hh/h_llh_z+EܻuYeȜ/ 7qoO}~͍{q휗XdnMsGtmpS>֊#rhϟiӏi?| }w 㺈y*~qݷwo^v\S)OJ/Yu)~uԾo.&\.4F$44"!  HhhDBAC#2PЈF$44"!  HhhDBAC#2PЈ HhlDBFC# ЈfH(HhhDBAC#2PЈF$44"!  HhjD/rS9L.t9 ˁ.=Gt9 ˁf]4CrA i4Ch+1c9 ˁfE "Čw@3tD!ť.d_'qvQWTFŧ_m1Q.d^ڨ~FBj(PPF!BAC2  e2(4Qh(PPF!BAC2  e64Qh,Jeu*@8C+>a}Lb^7jżP_9MҾd?.`vwn{ GuNmhn!w\oZq5cFe_t|s˄ZzߴlPfU!6q-ff>w{|{޽KVeP*Edt5]w*mt0鳼i>{glU87,>7c32;i팵zZaWUv"2y&W7NTMU n-'{SLsx?iaƽ־(_{B|own,|7?8Y]M=ږ }l[jK"j>-DӘn _@!ߋ27o{{{}=}ui3fWcv5w1zw1E1w1z]}̵̌xyg ۈfw`]T$pZ.|" /an8)F7\$uS /i q5pOK:,R\( m;Daf~g+ ; ??s\n-~ |Q`A닍lV(5o|Y{^bagm x4Լem"@C_f.4Լem?RPƗKKAC_f.Q 5o|YO4Լem?UPƗKhTFc3jXȂz{vï/.T@RW҃gVÙ}zmqyQ5[>~mDh#A[g(,YrABr#L.oN>}.NbqLq2i1Nl% f\i1|[#IBYI>+-Jg%ѳ)i1NYIwJZg׌Sb,A%A-yh;EK|PK|PK)ZNԒwS,A-A-yj{PVi1L6=h$Ac$d#!Kރś?~3CK6?V |׶}-:曵ۡ-mh9PSljׯ\/ްa>M |"8EJ0c|W⹮]+{>^#8!DJC\Dv#D*SI N"כK]o^׻a]{z!ইTD7etx&qs0'n>pMd ntp-]/tfڰoAq~CA% p]ol 99AƲ6NK `W^{_a,A=6AX/ItḥfȖJ/ٽ8n~v/Џ|kg Knޗ y{> 91U 75h7 ܘ+-|</R(ՃZ+@&qmA蹣r5?ʉ7p=(A|~E!=a/EŅ*sA.hj]'d'_>{^_Q]ѻR\9no͛'kѴ3g S:}.E黔>f5sn)^>j.]KMg7U`زa7 K_Ɗ^o7;.]5ி!߻7CǽumtE^?й& B]xth>G#||>>GaQMŹ|S_bP~[Gx_bV\TĬIÏ2Fm}V0-͢+#z Nۡ[Ci;Ci;Ci;C8[h7}׭ۓu|Wm”7C}oxǍp~]bckڂd5vH~\>ŻH^_"|R1ZZ6"]D6MIOgf4'=A/MIOKAytAD]D4'KAy1IS~'8KDh"z._"#'h+T=A; | h"z._"H˗"/./B%5KA\!/pGoD)K22KDf 3F/]DtAD!?w}do>.K"N8lwx %h#B ڊe貉?; [٢etC貉Ge&AM<.x]6lt#躉Gꨐcƴ&ɯrO'dsIJ7l⡻W6ݳ9EE;"UAƢP7z<&ASnt)lvGxBGWHGWHG7cGwvH!^YY 2c1nt#躉GD!QÐMww^]:s:=/nյEkKعW?'m?5pnc]|[}]Eh-AHV.ÙygtiԫtΌpf]3#2B ge83.Ù!t kl]3#hE(ı2op@m?5R>۞'^332e45G[DN9Cy*tCy*tC< :o!t)$ofm?VSBk\!ͶB\!ͶB[܌ͶB;ћm?"xBfBfBȌAbƈ;zGe˶Bfguq?n8v0,^m?۷e:xZZ6"]6gmhl2l!t#貉e&BM<.x]6vâ&A+B!aj6F՟~#-u|-|샩y,l+.w\pټ .3mk5.k\=p۝5VfpW`<3UC\KT%">h\wX T& ٧ܽ_|Fyon=ݗY;븝mu7]~溮],k >}r@/lWŶZ%YtzWz2 B :: NaPNS3t /G N-'=o tFb4li%jƸ͛CFmO!ti2Y Gk6v뇡^}.ch'^t^-ѳeL^:HoC[B/:AI`FYZI6}4vhD"i7]W{6^vx] ]9QUe硵em]Rʮ:/{mQ#7%n3g:=jB`E1!tVNT~?"h-N Kæ6Č ČIEf3!ABD!Q(P$f^:ŅZ Fo VbFo%ftGNޟ(dxf"nYN:d9!㖆l>:L[BiK@h)3r:'0tA: ι#mH3vVby ݖ+й C{BfBfB13-挡Dq($|AD%QȖČQXWW"4N1FJ[*{Ĝ. AC %o-S 뜰Ёq(RH$4!3|1E Y%w/knyTq!nya&nAR+j\AzC0np?^/Ü3Lw! Ŝ8N'\Q U5nhrZ܏-p=D'Ѓ V*pq =@C bvkW~FqFІpAoEoC\/Ѓa5w^OgXNPUoH}`jժu~*HKVZҸRV)BV\a ϢzHYLKlփ 6Ra x, C!z*AvnX+܏S C !Ea1=h!`1i+X;܏Sԃaa!vq bz0m`jf4ng܏`,a}z{T?页Ua. XO\[bRm=0L" LK&B,Xʲx0gPŃK%.x0\ /pD^YYpT\"x '*j%VUbKƫ*dJKLZc%,YʒSE,XcɃK|T% >W`+0S\IJLVce% +Y𱮒Se,XUɃJ|TI% >VT`)y0UNɂՔ<*dZJLRc%% & )90QGɃ2J|T% >P`+(y0U@ɂ<*dILOc$J'YrS,X7ɃI|dd$&j&y0U2ɂ<*dzILKc$%YVS,X)ɃBI|T$ >VI`Hk$y0U"ɂ,,D}$#Y:62S,Xɀ۠_oaK0lru;'5n~2z~߯ K,'_r-]6۫"u_ޘ~N'L{]CJ=M=s'|ЩADW'V"V^Ko%K_=| ^g3*ii>jU|7}gyYG],|Kf AZpMʺ Ic^Nr^{ɽ= \Ɣ73VDon^2zm!h; hיG+ ZҴ:,v{ۋ#ҝe/ "ver٥9ti؛/ۮ.;F'P@+z٨H\JA. Â.KܦÂ:=\B`E1!tV+T~?"h-N 3y.U:JIČ^dF/1㜽Bt)$HE IbF? U.*r!h-Qx#Q7x+13:{'ptOrS&6͇v"ls]f܃CYJ8f%!(8;("WB8}s8_-^|r8y9v+d1pIzcpSG%KFJ>ݔs.M*j+\5I5nGw隠GWEM#yc&tM# PE"⪨IyrjJ+ܥkBk\5 GV`<'p锉\&bbn>w?|_ݿ{k\h ,-mS\uj^'ysW%ΞȾ.6 r.X9v("eĂ,DOH)1H!GXP8`@QNU ]U (*k66ʹ D`br`>k#w6f6–xa; yq; {0{0|`H,& * @d+Іm('ІrmxĂռdA Fh# 'A ЂZ ;[k6Q P@!htxw:mzwjjK1K1K$  FwLm#6RCFP#Dc2hAcޝN]޽5z,h,6EsEًn}^_|( v_jMRg<=$L&!I>I*MROn }rTۤB&&'7I>I*MROn }rT蓛B$d/`T蓛B$ Fh# &6'7I>I*Z6'6ڤBll }xwT蓛B$&'m4I>9H,$(TP3Dn }hM*iW=7ڤBl&d+FT] IN&'{B< mROm4I>9ڸM*tȥSbۤB`M*mRO66n }XI*ۤB%ژ%ژ%h }rT蓛B$6%I>I*MROn }rT蓛B$d+FT蓝@mRO zgwI>9H$ڈmD6ڤB&d%6'k6ڤBlh }XM*NmROmx6f6f6ĂAb(6%I.M*J6'kۤBl&d+FT萛g-Tm7;_~Ŧ;'x`V>)I{_KXNܪrodFodF<2x?$God~"%a-yIna;h֒G<ڇ>%a Ya-ykɣ}XKZh֒G<ڇ>%?}ӏOw99F`d F`d upY߿F,c,cV~#bY4,,)K7oN{Dy$GҜ#Hs4Is<#iΑG'{ƟfE1? m16]&7j v9-DŽ\blB%ƆK !B.16\bl7&U`!cC3 \bl9d%ƆK Uri_@5+}B6w3Ҿ ![6j*$(16%,16\W!cCAcCFcB.16`nclYhclhclJ,Xbl!YcC%ƆK !@16\clr!cC%ƆK !BmBvmB zgwBm6DQc5Ɔk !k6j !6j ![k !;wBmx6f6f6ĂAb(c5k !+6j !kk !wBm[^/wєLpǚgLXshc.n?V"uwεZZ?#sZuB?o۳ti'>7%>Y9 F[#'w5}h蓛c}h蓽ĂMD< mD$hj$kFC^ݷ5}q[#'X5}Xݷ5}hchch蓛>蓛.>蓛>蓛>蓛> HNFO zgw5}rh#H%ڈm5]r[#'+w5}h蓍@mDllk$d'FOmx6f6f6ĂAb(FKnk$FOVm5}X蓍> HtmFo?NRd yl$eK')[8IْIʖłk%1¾I> _|p䑏qc#1| a+4}95m1h]JлS>ˇ_GcP 1з٣16GA| jAy>nc#16F>fc8nj| C<1#C|_Y>sKqnGy'`#Oc6~`GrnCwc yqnmyqnc'6<8 ƹ6O0m<t#O0y F#<pG aL@ڑ<& ݐpwIN=N@jw^mc AC_ZҒЗ7?o2/K͉>o ^/}>zUB_~{>3g3V3|F3g\p}>|F g <ع? 6u맒®xI]odf%tPY ׌8q5׻tEK߶UZ{|=^P~{5??VC-ŒWpyA`V.?< pp}pyC_U`*MpJZOx}MMЭF[a/^B˯Cv L TTV ;*@~LCy!*FGx_n{v\6X.E|+ \,hARjJ"KRȥSҩRD-zn,QE"HƋ[(VҹJzЧ*THTʇҩF5^*ҩDuT!B%IT͸K~KACPUD*@zUjC@i/.5ҩ2T6Kk#P*R]j<'0Kk/Q,P,QE"HƋ6ҩ"TQ*R@T?@/.m,ªVxkOT ^ɁVwbmm.hh+Vh+Vh+mE%l#V\D[!0~+jh+Y8F[pmE% g D[5`\sem-tNExO8:d^K`o2'vw Nz lu3Ǐ p^V ""U{<ς+WUha9pbY:,/r +ܖ08@s6*Bnxǂ ;p|@{*f*f*xA`t:t4،@qUTm%fqm-1whWEtUі*x~;gKo'ӱ{$p"K^X:br,pr*qr*xlC*ʡt@L:r&PE9Inj`iF䱙*@D@Ab 0^]:NYFX)͈B)*US72VwiePWrU('P 7 \Z͸KC*@QBO 7VNiF̥Bk\T mV`<'pip^ /P,Q,PE/.#fL*(\4#fזSW9ą6gk[C[m] pk@vY px첶ϝke--oiqm{!k[4nOcTg  v[mI9?n!zRS/dp?B~bzC0,nC/f7?׷/Ѓaޚ!YS7s&F܏cIoqSdp=Dۭfkp zCt vs^θ C! Q=\f6pmjTmTmZnm:ԏ,=xRyLBTR#UC4? GEsSCAzX\ZkGAzPP oo`vS[Jo(; wZp-eq=zyݒA~|&@Q!50 [Jk`~)Ak\)A\)M[~2@@@A` [XG܏S6Ӄp=dp=\f7qT~2EwoᄍŧܽkȔǡqٔ)ϩs ׃YMA~ahnP'&Dik<) po7ca[ CaE7J>צ[೼UsݖC#b]1BO`}N.p\s~FܐhƜE}n:{6~עvKñ4~\kZnvs^pθ_ v E"n7KM85u~/RdpnoZdpKY[ZdpZdp5nZdp ǵ Z\ :\ zݼn3ǵ @Q *܏kոj5jju"3z="3{6ch-Ef7Vn "3p="3q"3kp?EfzEf v"3;~\n! Q=Ef=n[dpmը"3kP=EfעvkC-2^/C)2 "3[n)2ȬϭEf}n-2 "3q"3[n)2C-2C-2^`7/[)2 @Q *܏kոj5jju){l^; 0 v E܏kY[ZdpZdp5nZdp ǵ Z\ȬEfO~x{b,,yE9>On sX&uUكAALiܷ> M 6WpK\9 [\9->MޤunJոj<-9xkq=M \9->! }TC,}G5djpՐZ\5Wp+jpՐ>! }TC>q YG5djpՐ>! }TC,Q YkpՐ>! }TC,Q YG5djpՐ}lC,Q YG5djpGC]|4d YFCѐe Yvѐe4d Y~ Y߽>|YsGdںdu9k>/vxKe_pSGF;nol*wiPչMTh&w =7W!n݇|Wq7}_?{Ebi⮂k\p/ra]P>N8U}}>uH%[>n[>\7M>v[>P>V>nCC^`7/[F"e:;v_.jF\jw]}U|"*2 ^L[*lu)k\٫_ox:NYa- :b?qӳe^TM!L97g! Ypc~ܘ}) }nx;qqKEUp#qՎw>Cx8\/m{[n\z=ļsf-u:}Kqo)ƞ[-pRw.ϭR)[ *\[ j}Q;[ ZSß;[ zf܏݌ z[(CFs7Z\)p^J q=n~zV\qp@^YY {PzBϭ'PO(\ۭPzBZ\u v͸ 7z=D\A=_O(\|=p5zB\| W=_O(\/Ѓ衜P@  7~\O(-'PO(\ۭPzBZ\u=xݼnq?'n! Q='zU'FОPC{BZn P?nO(\/Ѓ衜P-'n9p [N(B[O(rB Wv'n9p kq= z' VN(rB@Q롞Ps p?'PO(\롞P[=p=xffnA`q= }n=pzBjn5 z'z\?Żo?ܽf 1/~~0AH iSz"s\jWţud,x1.wk?P!zMZd[-%_1Yhl'qKR8/NzYB3,!Iq NFvR &k\-KN\d;)kq8l'q@T;)[5j'qKR8nI\íɚ>l'qKR8F%YpvRz Iq\l'qnT;)[5j'q@T;)zI6Y28Bi'q55vRעvcIq\1Nz@%YpKd -[5$kܚskd -qd -[5zp=d yJd =@CM5Yp5Yp5CM\ۭ&k&k 0 0 v E܏kϭɚ>&kP5Wvkp?kq=dM5_}|͛%lL K '9˶˔XI_ղVokˏY^N>$nI5HqM(\ ܭApU>p NvG-7uRpn`!n \/Ѓaa!v.>w4!uu:az:)@v3iccp?:AzH0=u3\ҾF;饷57ͩs):;~]}윛|3BE@7;7|}]}syo^97u7uWCz kwE ev6os:-E7-sIJ<庤qKp=W׎]npK[:?\[;t- V:?E@Qv~sk[:?j\5jkq~\;?\/Ѓaa!vc[;?UjqbBkp?ńzńzń vq?ń7z=D\ϭńW~\ P P V \/Ѓ^꺖b†]5K5!pϭՄTRMp5nZMpK5!-Մล:\zݼnjBz=D"m B&C[Mp Znm5!uՄ z(ՄTRMpK5!-ՄTϭՄTRMۘՄ O[MpK5!-ՄTRMpK5!-ՄT\/[&@QV`jB[ P P V V\/Ѓaa!vj>V*\jn܏k5!j5a {z5WH.J_t ֵrp,]_S9pKs.?%kcVGܙ7u@ecn疱9pG[I#ܒCM\& 6~\7z=D\%pۭ$$nI\&V~\ Pw$nM(}[}nIܚ CM\ۭ&&Pz}v͸> =@CIܚ CM\&V~\ z}; 7s7~\rn#\Vr~\rz(}zyrnθ> =D"&嶹}P?nsWzhsנzhsעvksס~ sn#ܒ9pKn-}[s7n\ۭn#ܒC\ sn!zJn>U>ոjn\5p-n^/,,C-q?>n\Vs~\sz7_ܽ/.\%z|.h/ǎv:`nU UM@;-w1]qmpmp׏q݇c\M7lApx1wsM2Ǹe(>(FrxYR j?hG)A[ jRPpkA -2Pe\ۭvZ\:\zݼn[-57 s@ϭ]-nY\w] QǁY˫ާYqaW6/Fr4A\i6í嘧\q\{~[qX3͖FyGy 111sGyGyG;r#B,sh2ϣ(>BB,sh2ϣ>BZ_.uMpɦbMG(fXtdu+@\wuszz_<]_:B#iWU[p/s/[Fxe#np/Gx!ԥe5npp=^ v#npM/`f7*pSKAF8ʛiK8nقܳdמkre;h4ǵz\{a,;,&tq?.nj顴WC%^ tne^ Dz^`7WC%pCX] ۗj=n^m۫\q^ jTm{5kP=Eֶ+%pg -{ە!܈EӮ D]ʐE`~Qەܮ ve7+C]uj2ە!Ү ve+ڮ F"Ү veW~\ە\롶+CmWp-nڮ :܏k2z===݂nڮ-nmWpڮ jn]5vezzܟ=N|2,ksm1^ht89yΥb9pVG:bw T_[˂x`.b>W!`/P,Q,PE/Ҍ渥[ -}n'~Ɖ!)c͗W; ( lQHϭE)Z[*RVɏokC""e6gN/ح)R p@A(CPf@:*܏ hq=z3Vg@\? hz=w!πFA`<F܏kr[g@R pZ p5nZ p ǵHZ\H:n^`R pg܏ hz=DTmrFBM\͌\M\ڭ͋\q^/C)e43n pKQ5-3ZT2̀[-jkq=Ԣjp=Ԣjvj[n!zjQu[U\U\U\ۭU\q-^/,,C-q?E}n-skQ5UjQ5ոjQ55עjkq=Ԣg_?U_*?Y))juqIqҟf^:_ _epÝ V?*s 6pGV6p˽qUeAlp)̟`? ~`-kHF`/|, 8KU Sa;s9dηBK1b`#` "-TS*bL9 /- p>DKJ⪘8H~uaNJ I 5mApĢXy1&7c,-kg,R Z_!/WyVu5f,#_tZ\t1bb_lkU*qKvE^{h7k9n:b!nB"Rpc>r\ϭgʵ*7 7A745y]Ks67#M_bo%yn!n-}A~+IALI 7p=b̺=8fRvccq=Sbr v͸cp?6A\7kmoK^YY זǪM9&܀͆\; ܇7n̵}pԖF.}Bu9Ïp ~z9ss9܏ǟ_7_7T5!T4!zH5Oݼ^p[[*V9_o!:`כ`zH0=} o={ ps?6ϛ\:.5dV'T=d=L= p=FǴ>ϸSz=D":Dϭ.ϕ=-ΕK&R\9n9 p^OT+W['\+ǝzr Ǖ}.ƕq+ո~Lpm pqjqqjJr$qޭjq֭qέjqƭqjqqjqqjpղ*c+ǥ:r\a+ǥr\_+ǥr\]+ǥڵr\[+ǥr\Y+ǥr\W+ǥzr\U+ǥZr\S+ǥ:r\Q+%2\O+ǥr\M+ǥڴr\K+ǥr\I+ǥr\G+ǥzr\E+ǥZr\C+ǥ:r\A+ǥr\?+ǥr\=+%۳2\;+ǥr\9+Dž%LoV K֬jqά$g?|0'OqR6EuuCZ/OThjOz_CCh?V?z}ÙÙùa0PF# 9"V?ARO? )'W~B I#''첼)#O%eySzIz\.w{=i.Vҽ4ʸ'{=qOHzR ^ƽ>!Iu'{}Bד^?ϧnYSk}wo㛏¿/??|sU]:/[V.:~ZVmkV\.>weN-M#-7{:tWOu<\-Uu:\ִ-,'/0O M˵ z1rq*Y-7A`(r>wtE\*WzX>]ݖFr5n^\'Ѓj8vg.s6uG`F=(mvϴHkֆa2×Ӧa36]pm]pi]>A909ɛSY05ɛSY05ɛ909ɛS_,́P& &ys`*ɂI*b$oLU`j7ʿX05ɛS_,́0LMT &y3`90UƂI*c$oLU`j7X05ɛSu`,́B0LUq`S`*cT-jX0U Fb0Tq`S`*cT=X0UƁ0LUq`"S%a* cTMjX0UƁ0LUq`*Sea , d]X0UƁ0LUq`2Sa* cTmjX0UƁ0LUq`:Sa*cT}X0U ƀ1LVq`BS%b*cTjX0U$Ɓ"1LUq`JSeb*cTX0U(ƁB1LUq`RSb ,djX0U,Ɓ S-Ɓ S.Ɓr1LՋf~ͻLvd^[$ǧ*:s8/QQQQQ <>#3>#ꃀGgD}FgD}yoggebtŮŌ6i+5TT-񤩮u{JATs\# 6O}n~޶k9npn1Q[lp~[Ԅ-k5ֹkN䷕6oˏNk6N`cb=7C92ps?:nگ`7 {nw%8حUo q5#cJ` C v+q1nC}%, 0 0 v EԏKH E =(uwVs\r÷o-ùJPԮevh˝Q4ϬW'd~YZЙj;>ʹWytxў:=8p>CwbgV{3+dXj*>BSмz9.p /p?}UAn@Ǵ4 'ÙiiLAN3:_t2XSJǚLU g>Vp`d83 d83nf+80Uir2&Lpc\S&'Ù LU gUT gUT gƍGU g>f+80Uir2WUir2WUir27Uir2tid2 ҄S&4aT *MX0UiJϰ*JLUp`҄S&4aT *MX0UiJLU0`҄&4aT *MX0UiJLUp`҄S&4aT *MX0UiJLUp`҄S&4aT &+M80YiJLUp`ϸ C! q=BHnaFAr\EdX8.41\B#?E.Uq-^T $uDvR%7hBT$ǝz 9n؍丑Ȭ0\ Yqjnd#5z +9ߦ*|T#ǥ9.UqGKU=r\RE$)z$L#ǥj9.UqGKUz;-lڧ{ȓ t|>X0(sD4?GsGs#x4`2ǁ@Gs#x44?Gs72P}x/fhɧ>Sy|iYO? G씛3HgStka>EwOˎSR%xzN,z$Eb^RD^p!DE'cp',p|ֿ Ru,_ʁWӿdHd x$F2`$N#0#pɀ ɀHdHG2`$דw^s|vX"q:'EWߦjby-i4BoLZwhvBsnt< T _'4  xDGDO#?"#GDG|{>i8&ou+jg) zTvwQ_h]@ӻ3칀="pլn4y'E|]Dn.fz%,O[!#zGf͖7@v{A`+0&@` F[@` %$ pJ(si MK`lhƦm`hjZCc6Fd047m0m` `hr. N fm9OB MvGw ŠRߴ)Ze Q_&-M}[}I,nuluK[b X%-n+`K[bWXĺ%1b7>'<)mO~W9TN!Wm3szfc֌,>+v}ž>ʸ8n Yfau$>-ITew9]ƀDe}I">S$Q p)pTDŨI18S\pVG"pVU!UnˀM=WUWUWUWUWUWUWUQ5WUm\UcjE&mWdU[;GceQpyۡm^<⶙U(pY2HK6K6K6K6K6K 6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K666K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K666K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K666K6K6K6K6K6K6K6K^Too~UvɯqEké(-GUe]ccmsۛZ&~/N9b[w.oq{DZMԽrͯaK2ܕCYOm]w p?iHp_"xzZF@TTTTTTTTTTTTTTTT(#w/_|=5qpTf;u|OmZgk)nVeNuEn~dv_Dc&hb&hb&hb61@M d&KO:} 븜J[חcgŞ8\IYt{,U钨/aQϞ^e[W~Z\7(v8WەN1ܾ4!Ō-e 761ܱt8fecoTG }{΢'El?O >)>)LTT33J!x3`OoROk⭕z\z\zkWDŠAQxQx#J1xQ `E'^xRObK/J=nQ(SDŢ^xbŖ^z5QQ1jbbQ `ҋRO"*ET,J=n(SlE'&*zET Q57*/J=vXzw]+DV pE?W?^{ո5VW1kc$nžKs[UP V"ڡq; ܣϋǍZttǏa>c94 'pwm`O|6`O|66XO|6`O|6w͟_˿YyϫO|w˱?[d?wH*uhOa\"&'c7I&q|my96u^1n,KH2y]~lg5n۬1~)n( p!s(p#Jʂ~w+m( n3ܨXdm@1dy ߂!=xxއ_\LÝoq!PJi}=s;E>@@BBDDFFHHJJLLNNPPRRTTVVXXZZ\\^^``b$;$;4;\4~|n_[%µJdD^s*W\DJG\DJ`DJ텰JdD^s*\DJ5*y͵JX:֭*q*\DJ5*y͵JdD^s*\DJ5*y͵JdD^sDloDS緖IPӅSIu?˱%+_)[ çcEe?P xk8?  -vQ`} xf\k)wKǝr729> NWl"bxKg2=S x,cpuk@q8u T nNx\# 5Gu! Q`TGMTP2xD *S3(rnP\ƽR`߆WDEȀ"*RC(.*Vx#xbKPܖ+Q `~ 0^%pyfc6<ӷ;</ Ǧ̜#T vej XDp0"€.<*jS]`O OGQx xl8q`O;>*n<n.uX, X2g!0Ց\c% 6gA0Փ jsYLu,̶,`sSyn9 <7؜Tkl΂`7 6gA0՜ sYL,`s,0ա jsYL,`sS]zn9 6=7؜Tl΂`Q 6gA0թksYL,`sSzn9 v=7؜Tl΂`a 6gA0ձ jsYL,`sS]{n9 =7؜Tߞl΂`qڜ7~׷ʶ=SmO[גw֫Z99~@bm>>>>>>>>>>>>>>(I K K K >>>>>>>> > >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>!AݿZ_me<뾘D!1M9I0=lB)c\JC*i&VjB 78|g.Uc9v *uR̔{KKeܼTeNUS+2Jp5o\iӞ0܁Ap@՗f4qSy)K3_qkN֔) [373T>M |*CRExH(uӃ~PCྤtKmېPm|{uZ>և9:Y8|=ؙac}xx0*u n\s:B9RUb$әK9Og.U|.H=Tx*ȯU|.G:\}xʛHW|.GzD#~GmxەoSKU6q3v=".U|ƦGĥʚ(r٪3<".U|ƎGĥjTIh>c#RgvD\͎K3qj3:".U|NG+*e>c#RglsD\]K1q238".U|GĥሸT *a>c#rgloD\ݍK/q36".U|FĥوT*]>c_#RglkD\p]-q34".E˙K%lrR5glhoC5ɷoLk)tcD8o%S{%ɦtZossx xgp, RG#_Z<=!ي;=!e U)r=a0Z2wVuh_|18 8*qm~3whrB+$88<8 3FqPu9;d@!8Ȳ3\O0e|4< 1xxq9 LG" :.sGC/2*(c!\Wn=W5kY=qdeqde5cS/,g4YiK!o< ̥k7Kt&k7vplJ,vF`) Rn+@n>g>g>g>g>g>g>g>g>POg>}{Զey\3pEzTsI,5Vw"FpC}-ɀFsԘH^r38Q$]s (ᢛ/lR>?S)篧9<_9k x5 |Ǭ o2%w<ZWQb>rB:}7?/a>>ܠ \ꘚ5/bu2+{2}tƔ@Ɣ\Ɣ\j&i۾BpLAwybJ.xh7NSr~ yJ\ ;>*B[1`/^ցyJ.yJ.AR SDEY^xe`;k6i_sn;W7]6JmWV!&rkL]wLN>ǣ[ت?fkU[lV=[UV=o{U[lV=[UV=o{UR?~sO[S ؉{^H&'LǺwn]xj2]YJձsk\7.Ƕ;%'1j3n}f%p:6擨 c*eWn~5 c18f}5 1ifH6Cܬƶ 7\pb*+bDŠYXiŀ1xbj2>*+U8(D[ET,LSDD{[z-|61`k9"%rZrZrZrn[9k9[9k9 ?C a!K8!N|.09>2~Sah5Q ~/[ιw5QA9KU7oÀ 3&x+Ì | :/yp#:!pXU,^M2l *S2uTL݃2*S`L=*S2uTL݃2*S`L=*S/o~ĂsF·M5}}[gk[gk[gk>7%jhⶔbwuqރ-Wnrlr˕[r r+\-Wnr˕3`˕[ro5W~wwa4|y ͟BϪ:nH)|g )|g )|g 6>SL# wo^rn8Vkǥ\\B:Z:3q9|T0(oqߴn8](|*J_lUfsk5;π\QAg1k8f<s yIol꾩_o꾩Wo>ޫ_}wźSiøXw}8ocYz؈1w\cq}hVqr0s*{/z<.[,z3:]\7(['Wjჸu0 nKp_[\N[޳(BlJʀJʀJʀJʀJʀ;ET')WXRXmH ݃mH ݃mH ݃mH ݃mH ݃mH/4[!O_PiHܾ*CcBzo:-s(C H,brvV,1˛ؗ ؗxLK7̥PM#諵em[6wqnM.–ݧ73x^(p5c9C࡙ܽbhL]LQ`7qAh?k~hQ1%A;ET @g;s v&4DMTDb1<V±J8`+=J8c+؃J8`+=J8c+؃*x~,'\]Ή>a<ٹ4朖oDb`snRgWwKs9x%]Nڍګ^*tР[vfϠ;Acн{jЃ}Ϡ_8sAXgY{,nRBܭBc?.>@[e""^ݯ.vEbtQELt'FwB{vP}~BS聹T(tdn^k="d/QXE[oArG.QhGH)!Uc"j{2Vq\ƎE;z8t^!*BMD2F2F2ѫ': }qv%Bプ~(~hC^~hC^~Xf?`V+lÒ4~x l 6a~Xf?`V 쇿N__f/iI.!^C{<Ԏ^&=y֓Q ;N>L3>L3>L3Og |&`oO?+ܩ ]]illұ7cly%ƶsצ\ fq RMu[O-P[=Sz޳K\ T $ȍ6xc>rK3E0*\wVDIr! ʅllll zP]~9Seq6c#al3F1Œ ،f0c##a3F0`3F[#rS'kڸx"67bGM?KMI Bn?}q/t͕ʳrD j| s7nP xVqN~ xy=(pmpD pDpD pDpD pDpD pDpD p,^T,^DpD&JM׶9•--|"A\Xj`=6?qls XDXD!XDXD!XDXD!XDXD!XDXD!XDXDXDXD!XDXD!XDXD!XDXD!XDXD!XDXD!XDXD!XDXD!XDXD!XDXDXDXD!XDXD!XDXD!XDXD!XDEpDo߿_E㢋éU tOg]tv(nnZ!fc!)!iIsH^C搼69$!ylIsHC 49$!׷^ݽ~}#9>Gտ9o@qcsJǶx]EDxz:ȀXY02u^v@å[]ď{/ݢI:]v]>J](* ** ** ** SDEY<֡WGMT*|J4W͕hDs%b͕(͕hDs%"p!n__iƓʐ[5bliYsi׉U63!5V]8peDsu9fERtgpˁ"'j7_6{Bx=w)wQ=1m&.*YWYZM{j`sVZ+\l 6WkZj`sVӞZ+\l 6Wk;Zn2՝n'?6mՓ/>CKzWOmY=N ?=uuѩZFn .i-7R'jY#3w`I-Cޥlz ~ t' Γԉ1WQ&*X3q׸7{61ݵZKm5`~K3 ٦d{ϯEmhnLT{5J=JxJ=J=J=^+8QV pK/Z'UgU'&*zET Q57[z/J=vXz(8(`iwXzkW,ޠҋRO&*"*FMT|T,J=^z[zQ WDŢࠈE'bw-(DEA"*fbFŖ^cE'NROb~J=nQ(Gտn_ǿ!>\8픮UCjoE_Ml$uAJZ>Vx WpV?VsFpFpFpFpFpFpFp&c巴8-qv$fn$c5}Y~nϡoo+z!nވkV7UඌtUy#"vzanx߰nd$MA0G!nĺU Ur;Hidg*nD<ō*P7bݪƭ["1*q+aPàXXUj#qڨxJYisK2g[0".'Z1g@SAn>f0{D{QoKdmbJ' 01πmL>1OmL5dg֐m'֐]I3`kȶO`kf ٮ$5d' 5do)\V\3~{NZ,X k~9r`KŒۈl#b^fZLkfZLkfZLkfZLkfZLkfZ ؚiY3=ؚiY3 xQmNx:8prxB:|ǂqٳ]_eǮ$A!i,22yӒr3gqEppSKgH\.w]L秚T/b9q) NPpkVz 3y$ 2~GPlxGB0q%r 9^K02I'O!W,Pţi̗4 &SD dN;{ bŖQH6Njm364%/-yiK %/%/-yi+`K^ZҒW%/-yiKK^^[r{-ct'ﶹ˱6=ʧ0ut|d;%ot礛g8Np1O$iC*o+C^|36 gxl>3,NFԗvI۰?)czcc1n}u ~k >-CHNbzź >CqxK};γԜoY׃N~ڂ}3F< A~ڂ."8g,lmì+Nrӛ9wӧ6snOmvジʃ"؆RCJ^XaȿeZ.ѥU:t #ݼ=uʴ"FFV]ǿEtzi D77.*!oݨ4{/c k[!nMC$PۗM 7e!r"MR(I }zpRxܗIQmo~XC/GC? c}X>ևQ#-6GuBVq%aq}+J<\RA\QA\e"+Õ\;(A2="nTyDQȦhyܱAt<"A4<"M;"nhwDܖ툸]6%q%#J^Gĕ+YWr:"tD\(rQ#J>Gĕl+Wr9"rD\䈸q%#JGĕ,+YWr8"pD\q%#JFĕ썀+Wt7"nD\܈q%o#JFĕ+YWr6"lD\؈q%_#JFĕl+Wr5"jD\pEO#JFĕ,+YWr4"hD\Јq%?#J~Fĕ쌈+Wr3"fD\̈q%/#J^Fĕ+ZWt2"dD\Ȉ^|K%ƈq%O@D2qhVF2phVF2 \2ѬlVhVF2\2ѬfeD\2ѬfeD\2ѬfeD\2Ѭfe\2Ѭ׬fe4+Y׬xp" Ѩɇ/_3?9+ӱ|z]gSOߘ?Ǧ,O>\$c1o%7NslۥjȘ]..cUͷI4[p=Մ0N@-"nqP'OK3'ZJ<ǼMc8y3@ƀ5.4. 9A[>*.'?(p7;Y: w^(pz xop̹_ g0xcNQQ,d`/\nS$Ȩ lT$C#oW,8xp='!(]Y p(sԣ~yz4 Mv2a~948ET$W,^=P7ļ;z4MǦ&Q1tH2*zBm3{ kg߼|ur1w?_ :?/c7d&Ϧgrpvr֯C v=5g}Oūm x P7/Yuo<_W,<[G<\8ff p,U 8*OCW ]XM-`Pjupt֓QHz2*SgW,^y--lTDETH{rŞ[)tS[LQ!1U,`N=1xDi=4|ۻ{qr䇓[ͷC-GwO<>lӏc.zb>},ǞaupXn*='iD=\\svXX]Nǟ~g5.Wqdwt_O93lғoVzX.lVɓ_&>ݛ^}?_\iRkS_nKn}^SlݩB6s'_A#ϟȫoG8E0Ͽfwg/_zp97©kg7i^TЌӱgﵹyEpuu_{(ErmuO00~ko^6ݭr >Hej .jG0 jY\ϾJ^1Lh(W>gZ/z`xrsi}6:"2(<'(א4VCn5NC4^6Ƀ9G 9jȣ9R YNϹ+ijij)`gg?Su)`gJ:'kAyx3kAyx3kAyx3kAkȽك^95A[ir<94{0h`<94ds0>+*PsŢMb$ƽ(Ǯu?+Vձ> ;b*b$e%yYg/$sCI|5ܠ2|[<n8'szΥ?:v|Q㊹h#͝ ;ԍ9:>xŭ oWLnȅ, 7wJO\:~TPN~{7U 5 w}O\9G|{qSWarVͱs,=O]7 /;@qu-'nG@]sm; 69.P盻Qa:6ι-ruBpK,Ý|Ý ec:6N[nTC tcC~1ݏFEv^T[5a*s@(no7%{[n)n |q1܎)ݏ6k-% v#C77uTn)Xܤu ncܤ;"ilnU[cx0(aPCT[Tc?84|!>b`]dY֏%!%wЊKQc̿1 j^Unez&fqiU{W$ 3MIG;MbK3s?}ņsfnbct~hՍ=t:rgo"t9ٽ$'l*䤯 0?<-f^'OdJA+A(pPOz؁;8.|xEYn,ΙhQ8hAn5Vr+RhJ{ADAs)G 8*<1k8`b2}c't<$w`lNgOa;d3y.kx;Icp[Zd2֗~76' p[ pC 7[AqCrZȽ8uͦQCyp$`iD,"aszKM!8Q!N VxҘ0. X"*Aa<(BQxҨ0ND) CB qZ{~qa-- q`w&A42 a, C`ifKCX0 `06 a, C`inKX0&A4: a,C`ivKX0A4> a,`'C`' C`iKX 1FA4C b, C`iKSX"1ƈA4G 9b, C`iKX$(1FA4K Yb, C`iKX&81ƉA4O yb, C`iKX(H1FA4S řb,C`iKSWXX10W b, <{k%NN`x%}8Ha!q9q!3 n@q. ׎rp=> mK3TDX4_d:*"=Np]X'_g|&Fp[>?+֭W[g#QQ"F>?1w\Fp=>?mub:;~'"x%Ipbj#}<|1wlx]izNpme^$ >[>Ɩa+֭W[(Cp~QQ"F6JQ1nu>^Fga!ub캭"c:-Bp{E)ܖ)Cʆp:ERxHIn|XǾqJ+aPàXX~qJp>RxHn݂->}Sꃋв<4%f텵+ǚZNۖcW!_co8hr D8z;n+pE%ř%S26OC=mSEb^VKnj۸Q7׌vųIp,2ڶYYdCܘEYifcqs8Ln_ KF. [2 f48֌]2qd4ahÒ -nKFv}gh^"JFx( V; ܑ5Ap- x u }\3 f4n^nbJF> 0*ada83ױx uF6 ۲h܎+aPàXX"cnh%ApKF֌- [3d4nhܒ`5ApKF֌+֭d4nhܨQ#5Apu>^2d4nahܖ_%Ap;~/ +WàAQnQn#1f4 %Ap=nKF~/ d47W*4G3̶ÒXuo>(Cn(nip}} %quvα@|#~/s@zݢbFv9 KOstD>^"p@6~׭WcGWLe:"FE<|<_7OWLev{b2}/Al<,m8 nL>td^WàAQntd^f+&2Ksda}:?y->0Ǿw;%ȓ'<mydžVo#;yM~6Op D?w:vchhhjWb"nnnk-nE\Z @p[vZZZ+jj7*-*mdZ 8.Z1wamnܖE @p{źu}h7*!*aTâs-:~/Z|<,Z |<,Zmu[xn^"E^cs-:>-z~-~/ZmxX#_c¸}̾O9u8/^<@J6b /Z;i\=琟, ȍLN~~:9$A?rvt9d[aգŐܻ#'ȑП,G 9F"GNܖR<ܕb<\r()roceEN#<"76l 22"'K1Oc7R{D>>gEN# <#O -G.y,\>/rL\GcXo $W#{ElD4aFl+[ &.cԠȽ&6zMl 45+5+8*vw*lL@Seí`帝J.nG/Arz 9`o8rzViۜpȝɥ8E5+kVp!9Mx`Fƨ2rZt0eK&-*6J22uNbbV$]RJ.51hbcXɵ!D"*h<.߃[bޑ#QK;R:x7Jmf`ޑ Z ͐=xLnZEl,FY^*!19jb#jbcƨ (V7NSsb{El>(b÷f;bw&6Ml ؈ۏElF9 Fp^+V0As.[3/>|G`'.8%Nmr>u/Gw[hꦣۧ]u[u[v[Vv[v[v[w[Vw[w[w ^Ė%^Ė5^ĖE^ĖU^Ėe^Ėu^Ė^Ė^Ė^Ė^Ė^Ė^Ė^Ė^Ė_Ė_Ė%_Ė5_/`eeeeeeeeeeeee e eeeeXdC!XdC%e)e-e1e5e9e=eAeEeIeMeQeUeYe]eaeeeiem8 @FlYFlYFlY FlY!FlY"FlY#FlY$FlY%FlY&FlY'FlY(FlY)FlY*FlY+FlY,FlY-FlY.FlY/l 6P[[֌[[V[[֍[[V[[֎[[V[[֏[[V[[֐Ȁ TdĖedĖudĖdĖdĖdĖdĖdĖd=npЍn ƹ~jgѨ-Q RCYntz.֥ܨlO7;q\ ])?,-C&tnl'~[׬ﳉ͠.t.vzؘK0"1"ևT@5}fPc rm !^063cͮ+͠j[>͠VænX˰)@7Z bt3հ) "˰)xt3հ)K7Z bb: ""zE)y6nu^MqͳxXM6'.&kT㹓IcnSS.;tNv9R9%0tr7pxM"d=sXcY>dn1ܚ#_%GpK,-Y>P| SCX^nY>0*af#Kz>, |<,Y>dnח,+dcQn%pG~,]|df׭fnq1ܖc"zźu+Y>;fnTèUQdc:Gp=, l<|em#Y>+WC1ܚ#%pk,íYcn%GpK,-Y>[| fnÒ#KuV| fnTCTè#K:~/Y>xX|7dn˯ے#,+aPàXXK[|w\Ò#_%Gp,mxX|G/wGBL0ẓ9uS\:v33MO-^_R?\ݗ_NyuGg˱7˻Ҿ3lOy} tBTR?$K,CTR?$KU,CTR?$K,CTRy?",CTRi?$K,CTRY?$KU,CTRI?$K,CTR9?$K,CTR)?",CTR?$KU,CTR ?$K,-7{uب F6pMQk*LbQ6P$ۨGdU&ۨ5F6pMQk*\mTl dU";U&ۨ5F6pMQk*\mTl dDn^ի(?՜?]IKm8Զ/"6_Oߪ>/f|,Z]}/QMa?GR5w '6QbD=&:6q϶{Mtܳm-k6&:6QdD=&:6q϶{MtܳmmlY_|D&: _DEV~oXn*o8uQ~V?|@LN~^PB:i)Z^nNi|˲xJhi|98]H Gw蹦ݓ!͑)PjI8tmϠK1 VBϟ=r JW ]36q:Aw؈CeU8V:)5#5 Z2 Nѣ"Gh/DHAB`t+,#D2bt'ltѽ! ѩSЃ!5U8 GaCtfp{$)"$2ɹC{2TS&9EHNd\teU8|=h6zbRR]G1葏`4䖱0^2ܣf0e, .BJz!%Am7z^Pf/U2h"dPEH7zjXƑ'( .B\yJ+``W" 8mB N?BCI3]k nKQG 8NGKc0z3LqV\ xTDȴ`ߔ8Fx&' .*|"·|Txaw[&*ET 7*th-GapQyxQbB/Ŗ-8 &*7oko~wf՝'xZ_/}rwݩ 嵷I(-ǖ7Gxt^?[cz#R>`KO>zKon}W_%6aj|=Ώ(ҿDɻG2UGs^~RݱO__y˅&l˜nk/ұԧGFrN+}]>M/~5pi:!aj5w?]_ǟ_U\.W[t}XuG'^TfRx3|ҤsXOdu?>/r|$\'^ށU7]^o=A*"af+׺tO~#I;=8>oy<(<`>`I?Wu?o~7g.?o{Gz4˧m_w'ɖc7m5VKl|jog,w~iH-*7ɐ-a_6j}ww7uzY{-ErKׂ|@^_nߞ\/ֺ Pԡ[pvcb d؎.."^5g]7?#.%ֵvœb6ٓ/5=V RO<6Ыs;p?0}O=z?0|^n;.0.O>wB=?G2y,Kr." 9FI˷4J"hEE!\cȡ4\-`ۭ14[Ƚ"6zUl T+U+8+CK5\l6hll$P z4?_z';(7]e'[c>}ny>xqCø<䳵sO߀פ7e{i896wN{l3+ Zn_Fy Sd, Cnmc+91xY_߮X4~|wb|?гr`kkm]^+cRY,߳[$;Xic't>Ϫ_b}>y<~VN%ǗG#? Fl233XJwDc,RO3x,,id? ~]slm(@piȀ\v6..1?pPJf*1ZR %N19pMʀS74&%]Jyql]IDEWk*p̞h<]JG> Mx.F:vE7IbSXkU,^_?aP,P:1{{Q/^4ܥF~bƀcD=mxIz"7HF \_qVx]nG;~%ى#.*MT eg^.0ҹ{F+V/^y ؕ ^9x8-̀CUDQzԐQzQkZ2id5Q̀GMTS\D"jJgf4Ԗ.}i6?=+ ' ' >x# xK?YѰQ+bDŠYXҥ k"ߑQ︨Hw⹠ҹҮUDkp"*j)5+oPli7[:g"*bDGo~Sli-"*ETGo[u-;~K^"*MT ŋ[ڏ"*BGEp*^lNLD"*zGEQ>*Vx}XN}%*Υ^pkz$+>e1pd&0#Aky=XY2wW1.+n?}mu0k'uށtݫ6ں]hr5"C}SnE8:sӅs nppK#wX&\~K8uT\~˗>f~k3 ױ~uwqje=}z~nz^DŽOa۠໱`nOF]}ҦpI{Y^^*_xyy~o}.e;OymxfĽ |[ xgm}}Bܰ^?+voXDg2"l mflךVq_]>|OO\)=Ļ : m94ܭ֦YjRpe(b }vޯޣ[]y߾]o7 ض |?ny^׾ꗟ9v ݻqs˚K5v7j3Kֹq,oݸ9sƚ8t;pwu874<;^(^LQ:AEC{ӚBU ;o(-A֌0|~B(.xY$| r;&QMh_ x<|% wx_n.23I~\\x^Go3w#y)'>[7Y+y$rgaCcϗr\ȷQ@Vp#׃;q=i3Z>VpC١šš[qԭ}F1W}c$N|A3׃Gܛ;뤻 z=i?mnaB l])no/sAњOӂp}m,63YN=WmzFzH+m瑵ovجMgrmho7F9 rg yf 3vӆp՘#ynQ7Mzs6+n7mW.%[qԭ}wmSs*N0)p=Lmn4}<\0%)9оǏ?/d۾9^߅6?8Pz=T6_x>j/rkI3dkxkV +Lm*zai]nXv :  +yRuKJJ3CRzHMQ>pCERuA6sn9ߩrzCgG9ߦ9;zXzXz(9z %\GOA+AP \%\GOA)Hp{pg nrS (:z %Cq:P APu$JA;q=Hp=v N=dzpzpn=Icvd; g; 7p=Hp#d; wX;s=HpCQ[vd; 8PzTl!w$@&Ia$܉a$ܙm$D&I١Cvnvnvnvnvnvd;W۳۳y$I=I=I3׃d; 7q=HpnQ$ܞ$Cq:P$ $d; 7r=Hp'v&NM|KpC١šš[qԭ},Nl'Jp׃d; 7Ip'%I3׃d;ǿ?G;~o:w =g # 0.8/^4w\57ܻ! |Uw88n+Jpq8\isqpJpqM+\8͎eGݤq8Cq:PqpqA;q=hpg^7mnXz=,=,=G݊ncmsqpmnuN|kpgmq{ໟ#=Q3Xm; kp߱\ezՃ w*JHpJHp?+WWCqԭ8&Ws1WnzЃyN|?&=QCq:P1WnX{+v~!;^xk8^µv\k?jv O{yݴ^;\k7;&wXnq"zp+o7Pa{p#׃܉A[Xnv!;88Pus|? \SЃ+wzЃzp:z zpCšCz(\GOAnzЃ;q=?u:z zpC١9Crpnrp+zWnzЃyN|?&nQ79 zpCաJ=rJZ? tonz܉a{pgGۃg~3wF3wހ{=G#.Sxws?ό-}O{K ->N]ʣXJzW1ZCsg]G/חo=2Ϗ?NN' [8xDܥ#Γ{X_[z8"dg|9wޟc{ϱsl{ݹsl0v s{ܹ]{ܹ]s9sc.wnׯ=??=*B5jd]—h%zL8t3|4b=y<k"ydDȮ=4yyd={5<kydȮ)]Sp# 8G@vMq=G)R}Hw@Bd#[S\N/lÿl]~y/\9< cpܛ^+{ઑ"6gb\-2[ p% bPסuM'CN>j:p׃7i:pX\1W%4 ɡ[vmX%-=CAcK>Vc p#׃K;q=3KKz=Cb,nqM%|tUc pXF^75wX%XCv-;&.|šCzKGܭ㭱ak,D5wuK>Kz=b,K+b,sX:檱b,KyX\1W%XfGݲnb,K[z(=T*׃K\57}F5wzPc pg^757}fCCCQ[XcK\57p=M%>Vc pg5Wc?~|!ŇTL_)^(R?<;_sDk?вOsvӀg(>v2 L\2}:Ȕ)•)SۧLL>epe)S1͎eG)•)S[z(=T*׃L|u)S>)S+wpӫwu;7}>9f'š8p'>9N|O''ܙA|rM=dGݲn nq8Pz\>Vp#׃;q=O3䀛䀛z=tpONQnX|rUpONA|rn;s=ONɡ[vԭ䄻},>9Car>9>9FO'ܙmnxnv!;}rpONn W|c䀫>9vp'>9vp'ܙA}rM\nv-;}rpCšCzp''܉A}ry'䀛z=,=,=G݊ncɏ'>9N|O3׃G܍OzzW~zc镟^镟^长=+?+?򗹧W~zW~zW2OO_^镟^镟^+?W?~| aZBܻ׮rvb|ӿs޶bok߯w׎Kk?ʯk_}<~߾ykxz%/aO_ǧW>ӷ+ozܯ ޭ]nk5kue\v-Cյ3 H͍!\W!>JnxumYb!v{WmBt6k :y;5x-G77od˖kn+㯚7Dc?n>)k??rg%2.+&&Mq//oGʹ \uWmY6Ql`;Հ[Ӏ;k^5^pP9i<)Q n[auWQsⵋ$]q`pr[n[߷[Kjd#` 6H]_]ptnqk|6azR[w=xQ|44m#.>z|/b lf,/ׯ[_?ί}rxun~|pW0_vUߞ>|֟9^Q%|֞モE'/wo~y֭iV.j__aL{< 믇߾|~;s>7Un6`7|k:W>mF?nfی4%<])%8Xb4`7Հ[xܞ ;&"psUtaa-8f8Q o`(F6 Հ4`pwp{ 8׀{8hAxk#v8Y}iScƞ#bLn^({yڞE by%UZڸ) YE)#HdxvNkʎܥtC0yy_QA9iEW<,]=V>xLpRkPy@f=ȟ.7 /8?!8j;c4)P:5nͨ6vvzϜS9Y|k/S@ݴA1(q<0!xx1pjApz` xz3p7@UtSc]Z <(6cUTx|)7cUj Ɲ`?lA 8m+8NdΡ*a(?+Nyv0xv|5ٖ祂Q<؎Un95|hhxŖuӇ;yJDU-{7{zz*ylxQش?\xņ gs99ҮUµTgy|s!0Ԁe˸§Yz /wNCxԴcҎqE8brg8"9wF!yE(Ay$)Bo%0_ 8-)oaR& L Eˍ]~ a*T[)T1務*x>oWt F!o8jTWV) 7.PlK5[q1TEJCU*R o\̍aOkUx*z*z*xAa]z\ ]:e*Z(Ta W ˍg¥Kp[*J ;*Jx^a^% APEԨ"rU0.h+K([*JPB%( x%( ¥KPF^^^1^P/*\E%( %( F`0^ St pPE %(zwᗷW߼~2ӿ~fs\{}|~}}0;3E;.4T춞 {k&֪ZZv\kjZU jV֪mkZUkS">?|p}qx8~cf0o, e61"7WfAfuqmOg85PI_ibd1wʤ |4hs Nf U͇) I4L4O`Cw3(V #4gpwY<;ؓf pO3WFAUD%3_M V KÔRFj0ë]h/:<[NN?; Sۻ?^L?_:7+?>tj?=-?/?=>xzO~yov!ٯy}qE E)BQOCN;y6U}={֝?C=߭}*=Y^WwWy+a*zëWxgg,&N^uq:cq.}U)=[^||u{U;?t[Ը~$o}}w?y7HUʝ+ijѡ~IzZrw±pKޞVF,} r$ iNn5VN(w jgXp⊃Gy/cW.7ՋH}f,lv.".]) V\<n/]1i`˼"|vqL]'R'pNx|6Eg :T KrkԔt_>Vh ļ_ļ}=> kgl cYѼq_bPGhx,6kGl=ui混w/~wr8~]u/xKHLl)\~TP:Jgos8@%NQ{ N[ѝINuy;-]9w{/ <>(b|2^>Jg <${cf' Ut*I:H(b|5^wq Kt*FBFAa1^.BG0UFݯKQ"u2UhԤ\8K"Ua: iTܥMpiUD*B6 ~=(\Z kH=xL)Tzl1^]v Nc*FBFAa1^.m¥]U*pF gU9)\ڵ\ŪW7֧CrSM>3$ =K5M 2.Hk|X##zr_}mtFگKP5֘ kqƼxO>֦kxS.Yps.r"V))`Eizp1S+vGn? nP!(z\~*݂~ ,Cp\Yry3.n.,BBM\^Nk'#}n>p􀛏)&\%>pôQ!ܐ qڧnNMnlkv-iJ.;=\z4v =xݼn9@=c!nP!*f]l5ԏgG+z@avns~<;VpB^1mrE1݀CJF1RkdhkیZT02"nΌ-ՙqum)TiJ$0+vK$<!(z\i m$@p?N(0=XNQ`z!f[:Ƕ~fA=xzznAaFiNӃkҘ>gҔ>f7gҐ>q?N3\KPw?tpq%մÿ~^~'9tq,8痕Jz3Ix%tsU,Asa*iK|"Op*&rIr Yr,Bl!K%_@Ȓ0 d hk,5!KހFAFTh$d(*Q2(9sX9M!k\fpv_. K%@ȒG dI$dYR ,Bd!K6%%%@ȒQ dF)UXdY *Q )QR 5 Jv{w!6Fkcc%ϓ lw l6BvXT!؂d!wػBmx6$@Ȓr d9$Y,i@.y@.B!Kꁐ‚%@Ȓ} dI?rFI@rFIAXk,(YB4!6FQFErIFQxwIGUh$$)QR*,X)%k555 »KzK~KB%EAVa d V%2?>޾ܚU㯚`i(/.]ӿ=vkFwe֎5m6-n\SO9Amg=#ONZFg-`8-]pN '7]~i<+q} Cط 0t<׌g][{׀ Q<zzl6׀4مӑ i*82x)`I^Nحx{ X4Ah==$x)+W%`32 îN;ZvT)Ҍ`F?awzxsw$չR9='k?Ipr{)w"uo;mq_ݿxvËÅc >s>s>w\u[u[>6Mwiܺܺܺ n ;}k񯏿\ߚ+c/mou{[u{[u{[u{[vs]4ȷ'\c unpW:<v{K⓭谠nEVnEVnEVnEV݌i[O R;>7w/vq {i3<.{l; -\}W6Rs6q8>qs{,F_u+u[wu[wu[wu[wfطEr9|s\3j}mmmmmݾQ>;BB=?41Xu#Z7u#Z7u#Z7;Z]AmZGdw+&{Olk^ wvJ0]~^o//$#4 ^C7Iv+??R6;ズ'{'{'{'{w3B\K~%qQsp4v ιιιι߇K,ٍb=^:uWmAvm ҏu?U~װoꚵv&iwkk6ڳ/^xN.׶d=뿤'zcL`V` 荑h88*hk *d|v ӀZ S5+ Ax^Px^؝ ϋϋ [=`^ض^b|kaǵ8qyf'0Q|"ݦ|g+ڜ ,)F98V (\ڌ<):瑷qqꖗɧax}Y2c? .p1=l(/^÷n׺Kkk~vzވW]ȋr{cZLui8|!qqAZ9+R,Wwee]1%qu >յOfţ:.^OKv8!qq>)!w*wܺpKwf;zSd 1{۰NOv =xݼn֏/L}~χHr!(z\)58fRfq0?NazHyYYr`cͅ_r8h"p#}9&N>p}Q}Cܐ q*"ܘ~+ L^5\r [tSp]vzmrcq= ԃW+OzǠCP!*RΆ-lRʆqN?elR=6fmvt 㔭z =d qspSyEܜ!\&wmFwkF.үnr4i7d8mL4LS+v맬+&z =D"C0ن-g[8egzHRnͶ u܏m8efBBBAa[~l#㔕azp CJ0=8r2nS![J0?z r 'Rhڜe['$Y“vy<гfM6 ܥ:|k4`ïVVjtNzNeBǮ8u9 淢t4pp߾vwm);֓0j{RUo)jzN  UxnEQWB 8yN5`C(R qkMLMm{`)iKyS;bt |+UE.FRCd|}y8lNsH<7g56=5|Q384v"l@ŀێA3nXZ_ \I/P&7'7'7'7'7'7'vd.w "ܤ_pTa "\G0KnK6KnNnNW+ ݪOA "ܷC8,ZCvxV箝A{5廨!pmǀnmvYe=W+&|~ ACT!r=؆6nd?\ZԪ`Caz-mvێ =xzznAaFǮzH-:LJ=0}!96;ص\=aՑb|д໵O/гRg_g F׳te7 J^ճϝ K߼ymrs4NN .Dj 5XS+,8z:{2Bl˸B8\ԓSxps~+s2mJ5vleC`;B2nmN5N==F p1^0!`FBFA1^T/*\5ܥLpUL[9 g*U9nisir0UuUx*xx¥].FQPEpUxk¥ӠҭUu\}/xJ2܉f/*7̞e#pyitVG7}RM_ 䑋#kGx\?n(YlaZfBw',. q*?'..v\b yz[ `=.fg<=-0<il%V@4@L.{ Xb `6hZD>:]?_zw,cM' [[$#L:el'6E;#WW0άg?f䧿j۫v2 ibqcg6 R%>[/V!sǎө-< pH7vBp]Xh]9_خץ`:/;n)7%#\>Wƒ%#/f܇gWvx(MӂdН4~ZֺӋJ*qecXWxpӷoZy9ݘ7W.L:=.NO ҟ;;]{wNkt^NEt v ]vx# u6^ٿ<5yAsv~QB&m+dZ>wLr,V;}dq4x-N0{-j&@4&7r}qt[mqq\ ņ[xql\9pH[zzA#D.[l3+'Lgrbv ҉qǃI<2AJgzH5nruq?v-׃k\:3b/#ߞCP!*چۭmZ5܏|4ki5x={+Ygk \mZo#zaZDÞ}}fru:Y]е\]qW\qmHzڨ}?^n7py>\>Lj,փǹvK[h꘴-W+++vS))SD5\DU))S75$r=SSAS( "PNAܠCP!*"P>"P>z(cq=))z =Gzv&z(cp=kGu܏GmGz yݤp{ǥp?Zq\lZVr\PF9v+q?.z("vޱTSO\ɏ;xRYԞjKvs;`;\sp<#''(pnAaHxڼ-Nz(jN~\ZTzHcn^aCP!*lfn7k[8 0=yXLe!bzH-nUح~l;ǩe+++v E6r?N-L,6p=o[<@6M'P?N-LiC\8|LJOG(3>kD tg*rV_q>c6Qu9>uG\[G}=ܽ:<7Cʴ'MW懘P6-߃Kp?One.Elm.cLsq`M\H\&L\y{*z*z*xAa1CP&XSF"6\)# U WEʙAEˍХ.[*bU;*bP/i?y'ozW_yG 0ߍk/ufvacrZjv* '\N \ݮ=_{Z ~[9+ibtf19bK7ೋz1pX:•t]g[WnKy,KGM~,czt)v >K?Ba˝~<Kaa-ۼp;> =xX:•t p倸}8vrq+nP܎z yqTBQ o85܏8µ<+9 p[ٓ4e^#r@<+bO n^9 pqkqk݆a˝h.ǝ9|=[֍IeϸٛRn[}n<,Y\'zvwkA|E|b )V+e.9?,p4az9,pZ/es˳p Ci\V\B\9,p4ai\[ AT%  ۭ q9,p[rX&v =xݼnr܏#eL>mP?ϧùWW\J\9,p7R* pL$n* pL$mJUv\* pn^a79,p* pBACz(esKUǥ* p-CJ\Pv+UIq?.UIz = = =݂nqJ2* p CJ\Vq?.UIr==,ͅa(Rldb`~Qv:w%V'J]϶%kٻk@aQ ЖpKBc[\ 58zn\ Wz =D8J`p%0q=8n%0܎q WA+ q I`p#8J`p C v+qu܏K`p[NWMs?.q =D"<0ǝP?R=qmqz =H`p%0\ W8J`p%0ۭW+qmJ`p;\WM+q =B%0q z(qu\%0-[ n+zzz ">p=8Zn\z(=n ߿p^;}vZL< ?vyg/^]<͹ΞF]1. -JzU[ǛAޅi4s6aZk& a[&y0Q&jDmXpk"/T&jDm  nmXjDm ab Pm&>}xͅq i2Pן kӁlYf:W8?#fGJn vo~]p^jNu*_qǝՀG`aboౙDZ+r#[Ck8o8%v sә-x2rp pl{ S^~scw?섳7-&*A|↑^{rs^^lVK_R-1Vޠz\rkwvX#\'o땻}:mm]O͢koeӮôܷ5L[d[+y~\%ϿϭǵZO<=ۭZk=Zy~ǵߣZznAaH8Zq n=4_kzǵZOEpq??yۍ~89u\pcZOk= Z?ki5.%in=5%?Zyq?. r={J}MD|MD|Mįqk"&k"~[5&i4ܳD< З{ p_D=i^~l_-[XBH2ǿh5IŐVC:fۚ\x9_k7m>DŽW7ngrJnpsnp%ϕ5mq-[nvz(.A~&y+2Pt:Ng{gX-z ]Ĩbp[XD1[XD1Nb7nxW=חßr?ٰL>˟ٸ-lYGG\&]p|D_q|D{\&L>G\&L>"`|VG,^\&p|2eL>1عpM8be1:`l;)m)ogx8톽$% $rd2:% -CI&qKśoѭY*T/J~y -~Y"%J]]G Q&x"66El]~Q$6g Xr\ˋ{*z*z*xAaɼP&8}pl WE4 UDUxrEpKVrUN)T5Ɠ .!6UH Fd 4<<bg`U1p7p]zj`QWרW"hƋإì)Uao0"ܠK7qN!7 rUTyzKt QU*F"ޠlÍ"oХ.BoPrUTu\)g[:Kێt QUx*z*z*xAapiKTk*R " 0U8aIQ8j<#,) G]:*\KU1ݿX^a__θ?嚫Ζ_-Y V~Wrֶ:yxϝSc> 1]Xm\ǵqǧA"n:5"nEڀ7[mM=⚑k75yĵHۥk5ۺo>6W4 I5Msɖp;G\\RrRr2pe6lv +D7(z =D{ s -Z2wpC-[2wpo(;h/g+q3 WѢUfm+2Hpv•Im\s-5a.s}f+\3YE?K?`ڿϵ-\+\+\kJ?J?J?+J?v\ pn^a7\)6ܠCP!*\{y BT:uT2mU&Q?W+ \+\+\+\+\+\ϵ-\+\[j?ל[j?ל[j?ל[0\~.$qB= uQc%LkOE` 0y`o[{+=J`p%\ nV{+=zB^ nPMz+q}nsK\p%r:%-CnЃW+&q=Ba4nZy\p<ny\p?^==uswxy_>TLƙ/n^?mDoyuxB.R|lw\3 ,?Olpc 4Bni`׵঑8*7?7'^īVsSrۗ爚xe)gӂtYqe7}v?9_wrW=e+iqA Prx[]6ʏ5ӰV~~{i̙ iߦy;m?`<6"K?`⾥ ; 9 P$79iRVuVMmw7z˕:l}+CܱÆsEcs ɝF\p=8p=8,[:0q\2n7v!~ =wR%^Ao[d+MsST$mneɞwr^r: +'hptMsK7>tCtC[:tCnV+ot-nP-(vn t\I :~K >.@~K ξĭ}[;W;jg߂[;@[j[n=mQEփ@[j[n=mQEƾEƾOkcߌ[>}3nm6͸Nc_l:/T kL/z4;əӂvqMH}rb4"}QCr~K nʫ/j&CwX÷%7ՍyMu!9EM+wd]n*\Yr}cX]rǜ+ӯMX妺\YsKj[rV+9+J p%gN nPrVv I p%gn݇i6i 7=򷔳2yNpG3nI\󩉃=SjQKms5 upG[oqB^îW!tvKt>7嬘J pMCϕl7ǀ+9+mWrVe=WMN\YnpS]YmqS]Yr9=Fjko䬶a#guT9-nKJp{ 6?>p%<5 P9 H9 9-w-ŕ倶jh+9 ]mq%k9-n~Fr@ܒ怶jhkVs@[\n9-nx5 =倶Bk9-nPm-ō܏Ws@ܒ怶a5ŵn9-~\9Un<}V4k`xnЧ~N?vNC3FiM7/ꗶ&0\8>w3ˁ@akv4_hnppnpnpt+;Ͽݿ}&e9&|d.vHRפ/2b_Yӱ J(v\#lt3OHk#6\^qϤ#p#p#p#x59[lbW:p=Ncnpp[i =4~tnpܒqkY2+#ܒq%ǭxG\D^a7DW"cz =D"CsKd p \P"cJd p[n܎qW+++v E%2-}nz(1n%2qnP"c{ܳ(—ws8_=xxPƗ\\5+,AЃrs}n7o{# k/aqRsμ]X"Ox>DNu\Vsϝ2 p1o0:q0?v =xݼn=^ =B\k\k|.u\e>ne>v^sW+ WAsnPMsn~\ze>J=h26yfzglW26+ Jf[26ܒ\dlr Jp%c-CnP26v Ip%cACT!r=>dlp?.\%cdlv+ zBBBAa[~\26ܒ疌 \V26 \%c=<=TZZG0z8mƵnq-yPpB\ Wz+A=>%\ v+A=JPp[܎+vJPpBACz(A}n ~\zkJPpC nVzq?.A= =xzznAa%-A=5\%ۭq?.A=mJPo[zyxxF*[2wiܮl9_lrhaWֺ32ZKp?}^"\"+@ Jp%\DW"+@ =x$BܠDW" Jp Cv+@u܏Kp[NWM"s?.@ =DVK@0MG"#,P?GR=#@m#Q?e}rkY_-e}]ֲ_<٣h_NG{riwkk|:>ebߎ\ֻ򏿾Sx|*<&v)$ܨ`[ Ɩ_7j:>vK22>=Y>-_~6vZ+ؿ~6'Am&r^2ȷ"8;hb͋H9AHNΔr[O):o W<}7jPqjL\n?8rqc|d5f1ڲ,&?ږږY!V'\ q>-EcV#\ e2髇p Ug %G Jpsp;n^a \^nP!(pAtɍ\sÒ%p?. pD/q=ŌܿdKhoug\0g+$3DΥgkٯ(h9!r?C\ȹ s !K !˦s"6 ‚Rȹ [6 ;6 Ƃ^c\Ƚ»& FQ1K' `!ژ!ژ!r-8+PC{D F^\ȹL s"B5DΕjń,j,j9!UXP 9W!r.YCV )ZCN )[CdX0W!r.]CFh#jڐ5B6D6 6D mH";6 [ ;wK)"{6FFFAc`TxԴ!QhC*,(m-m*!mdI-|ys??޾˗7&߻C|?ewX=䪭}8QDxP#h*&I$%S,nQ3Jy~*4Nj.+xY5 dWzy9 )\3Jpsp% 9LkܵJ \j|?Jq[RǖSulI[2Oױ%%[jcKNulI[2Oױ%ul<[ǖԱ%o[RǖӼulI[o}l$v߽ĮW#%v߅DiIXD➕*YIXsKp%a\IX$,W+ %,NWM+ =B$,%aqIXz( u\%a-[IXnǟ%a^Ѓ$,WAvF%a- \V\%aB^a7$,~\z =D:g&,jb[5aQ5aQ5aQ5a$,|u_ٿ\GBu5ŝj ۨ`>Bo/䅗adn^q5\5\5|[5GN>k5[;OB>WAR׀vS롢Pn=T4u>*-k5܏?CE-[I]nǟ%u ^Ѓ Br>(tP܏٠ܒܜ&\P\VN\ -C9p;n^a79 p{,P =D"=op y4Zy4:y4ni+z?WJqW\)\9pg+8[Jq7v+8+}nPJqz(8v )+8z =D"C9s[Jqp?.8kJ):R-[)܎q)\ЃWWW!(v܏K)>-8kJ)ZnRq)ܖ롔qg zpYw[wp\­w.[<n=sݟWsOui>pE>p|.9؋|>sOui>pE>p9_?3]ᇛcD핵W24O ɳam0H>y6~9olYq8=:pt6dV6k`=<:'͗)9UGp}K  W,C^dg!m;9tC`l׀X#lZ&x0|pCixq۱NaB p cid撁K[NZNapųw abϲk>e\]^;4.kcsZ0+ryAֳ0[ܴ]3.sqގpCam{!`=1gӇBJl81&i'!$'3zZcvy ]O?XN 7]r[.63WƲ`ec ecƒ ⲱ$`=.K>l,l,X6,K淢l,X6+8l,l,X6,K5`XSyn~>}p g|:=?7kُ~{e}д໵¤8tZXbw9|_Oڕ-¯c |-n?i-zzn[Gm^^ TS]OȕS]zB=raG., z¢.p }n=r>rÛC\—/˿BQy_I!洲aE\=JuX}n^H0,wϯWt żǝ1q_̀+_̀+_̀k_̀_̀RͿWW+z/f/f ">4\z0c݌v3q܏M`Zq=NWح~lz&(z =Dpنp?Zz-mvێ =xzznAaFǮzp ׃3\{aBvsm[A~cr=|1ܽun,7uZݸvV~N9<.Hku,0ҍg cfEf̓ )hnMkN4`VwlZgZ<*Q p:=1W)lZ=b[+bTJ=[.; XqY,6kǽnyV,֦_v%`aqہr-m8ץW ⺴]qof/ܶo9ٓзm83= =n)K{ ;-"LA`Rs?/-˓9iCޭom_\5Wv 8sۧ"c}WfgsF2{S"k+32W¼ǭ eo[ŕyqy+6.W=D]W=nz(ArV={\P=z(v+Ͼ2pB^Bo޾{{ C{\V=~\=nP=nCXT?}P?}s_#-Y_,Y_-k_G}c}cέ}c}:ܧ.\']8ł)>eL>'XϿJ7Nz( ;ڭt3Dǥ}'R=nHPw"ιλw"Bt3DjnHPw"Cf`߉ncn++vyy7N~\w"Cf`߉T}'RnHt3Dw⛗ߊh+ڳsS٨+36)Lu]9|sa8mkis.f]! KRj=[\3Պ7Kr//•/5_+&5_)v /•/ =BAj|~\jr=/u\k;ˏ͹q1Ri s s s s s s%QFȒ)C*C+CdІd)!2Dn"""{6FFFAc`TxYg,3D6 mH ‚ACdnɡ!rІdɳϣ'o~ٞsio{BЫk?8nrY&mpSޙ/S]ۿnl-`5_Z5_Z5_ƭҚ/n͗|i͗|i͗^1b/7祻]KC]_p8$lp夸䮳Oų _;#K1!K1!K1!K1 c@.]DŽ,mDŽ,}DŽl,DŽ,DŽ,DŽ*Q ShXk,(BX !6FQ1B^ m yЄ-Tz(,kJ5 :ǥp[Rɲǝyx0N5W8Qo:j8QO:j&ꨉO:j&:jB>먉Oſ߾^WCnn:u %Q{%9ȑFC92a r/#tx%o^Vpx/[ ./O}pO0J+9.8]qL$c&/Un<'S 9v&pڨ4gϪ`R*"{C2XʈxܗM`#ih{2X*O.x)> Wj8}$ "E*J5srt_s\0.dm1P̂'|vz4[ܘ? JR˝\mfpe& y[\;rcOAwvn˰~~Ē~yms>v#]oh+p->nrpS/T@ܘgsBs]{WzW2vs-lA-mq=9(P^a7[=D4Ţ #pBQgCsۆۭ v{ p^q Yc[re{ e a7 ٿX[ \Pf2p$NA$v$z, =H> $k$k u\e ne v܏  =xzzn2p#2d[fz(3Hr$z(Mz(M+v&z =D"CP|ϗ&/Mr=&lU|ϗ&/M+z&+ Dv&&2pe 2p-[mqm-CmB^a74n4nP!* k{y&k k kR~0C/n]2r; ϢQx޲>x,p3WU}࠸o< wP+ ȵލ X{먀K 8*W@X W@س,Y|FY|eOY|{ߞŷݳ,=o۳s,=o۳,=o۳,=:wzY]?8k!4rZ5$wGhѼ;wGhͻyw4Ѽ;yw4Ѽ;wG?^3؇5k/sL6_YgXFO^i2lֿ7xc7dlbziH6~YjYjg\I-\I-'ܔZN)pSj9rM儛R 7nnJ-'^W-y 7y 7(zz'\x r=ǟp׃x a\sMWiFW><h"<"["k" r-Xdz$ hk  " ,!B"""[%))ȝB[@^ . Xk, " 4mm mH%΀F1%ҀV 5 ShC ),(D["5m m mƂbvK䁐%@{@dІD*,(Dv-DڐD\!^Բc+ _ݗ_Lc|^8ff#b= \.`i&ZXmil*w|ӀPN/b8ľO O,oA$ CS&Sg '9: ZM*x9%2'3 sBf99N.)݃d24ϡl}ݓ/޽yUc7OXs "2糭r b_ϟ,cJ wrkmn)v[)v9vuS ]w+Wa\pȥ\pJ;nJ;w+zȥW+v+77(zz67H\q!H\o$no$n|#pB^Br#pnr#pG>67H\!H\o$8H܎!H^WMn$qAQ꡼7y\H\KPH\GPH܎ڭ=D =xF"ʍD+7Wn$Hls67H cָ{9bŠp^݂n#?A+U*ap rX\9VW+U*zݼnrX\9nP!(0*0r=jk<·U\ !VvˇU<·U =xnAa|Xmsa͇U5\ -Vyq=j+կnn~U9֝`dRf<:_bWf?HshL/n޾{YiZeX~ycWy}|2M<^pUƆnN|Og {뇀xЀqp^6t+Q 0'w _KcOsոfZ;̙qDV.ŏ ԯ/.%}5% D%en y`Y Xh"/,K4 K4%W %U,-p^J߽g?\YJ[6{4mv:z) &~v:C|̄Y;(Ne@yW'O\R?p~"JD+W'9܀+܀+܀kr27:܎-G8G+zdnz$"#9"JrDp Cv{Iܽ*p^R^?qO'{U2^?qO'{sgݏw={⭲C?lfrk$׵|vwuuZunw]vwun+r׽?*JUa/|8=J̓k`RqpRJF O+,W |+,W |C3RpFhuRxpeEq}q?ϊufh4DcnmKֻnoVq=Lcz y݆C n|p~k7߽8Y@C١,= hY@{ОgY@׹{?& = hڳ,= :wڳ,= ( nU?_^~vZg.@ZX<x^!eg]?ԳM>tPø]i IlQ}ݜ-Nfő^fő-c`VYJ`VYʂQe"ͼn:K'vBn1 /y_mpܒ'Ο-c)CxkCr"1^Hm1ePnWcXdIC ]^KY}$,G9O (Q7vg ^xwg {q!.JxЉC='Nz;9=I2뛻7=}s]hs5L:X^(\"a=8v?cF'ܼ x^y_zng7Rt.˱)+um=Vۺ*•lAshrslA•lAMق+ق W7,iMR(,DSh+Ynpsz @ܑ7@hs%ps:%N !Sz销qtJ)+zH锄;() 7() wX)7SnJ$\ 锄k$pǒNI׃SnЃW+) wX) 7(0*0R=MnN 2p-CN L܎ڭLܞ2pB^AA[Pm8Sy\SnNܔNIN )p%pS:%J:%tJ•tJM锄+a* yR:%J:%BB#׃SnN\qN\)q=tJr:%|tJ =xnAaNJ:%tJ5\9p-[N\qN܎!SQ?"eNL ީ; xԞ{Ne2\בۛW2$;{.;r<د` ]lIJ`D.%D\@.A#`}*G^a<1ް8]66 U U'7^3 lQL`*bTEp\1"tx1׀S:&)P^XMW F>sJ0ǔ`qތFvrU3ٔ^2bF01N㪈YPcU1  |B!e.Tr"e )]&`KU*b[SRE?`S:PtJ4cVBFNi7)BؔYX&`lOlM%Sǔb`kkmrp:A&b׊il$^)g 46 tl W7k*U: 74h^[ݬWkT1(T1hT |JQ1ck wP"apF92 lJ;ұ=S*"Z=ZXmth; kԡ;vϢSُp=Ӆiv-ѓU5JϸnIre`(RM3&*|b ).epw)Ejt\]~]QV=6fvgbͻ sth zq[ཥCЬ4- `UKCTb\b5,+t`0Q vF^ py( xЀPhǴg^  GU!8,mOS') hJx13 8٫4 U2G <*ylO }PUPgEX1jU:>Sv\WWLi^AAPEoToTLiwS:0pb:T,G4sx9ҮSuXË7ݟjnWsñ10\ˀ)[Wv5G{dC <':91rwX2cҗ|8'_TgC\Tg+.%% O% ا!I<$UPE/(7':) xL U{*br/Th*br/4hbr/ңS:&BUWEL{*xRU Ŕe8hT!uxԨB ) S,--,.6^Y] {0EJדIYUe좒v#9WAʵVvr+;95II&Une̴=m{g>VWO;_g}ܐ.BӎWh}6`N1pcoea'֩lF:nlCp-[l Jgrgrg yRg•6z = =\psg5|6krgu\ vn |6z = = =݂n#ǹM+m7w\;v˝my;n;۴9tǛҿ؇c7CK^n0?Wc\>&40&>O{ܘ]!\qF'\qnr7 W+n|Mn|zԟm>5>=s>=wO\%K?{BNnD,= 9Yrr#''%۞B=![s{BNaDڐ@" mH(Ƃ^cAsOȃbvN456nMr@dgw@dQamD"xvDmx6RSSSSS%N@(@)@*@d 9E 9 ShC+!!D zSSFAQQ (f*!Dv mH;%ȽbvKF^AA`XpTn 'Y lڐ"[%N1%ȝBXhsdw<}~Wb:j7Kiu~Wwoe^MEy_0sukʾxƎsks#\s3\&S?.0S!vM`,9\/nqɝQ"MnqɝPz-r6sCM&+zzz /L%&p=w8\V^lr &z(/p6ruzm)bylV3gډck\4v 5{>5v!w jrc\cnږpCnv&{jrc類cq9vcѵַ}!6W4 Iz6?>Vmn/פ[kbmɵ dҕ;uoۥ+wۥqۧ+wۧqv BB#׃?pCڗYrnפ} Z/eq=xwv|rn8D\ЃWaPaP!(v<ιmn.\J5\9p-[Υ\qΥ܎!Rns)+v<ιz = =\$Bs)ys)r=\Ju\9p;n\p{>sI =x$iip$ck\)Pp%<-rKMR&Bk"D\.D\Rp AԸRp{\pn^a7RpBAQꡬ5y\D\KPD\GPD܎ڭ=eM =x&JM+5Wj"DhssM67D\R1)k"6sMrML%j*?4iw?V 07Q|wWp4h?7m;T5DW!PMm1À .1VNܐܻRp1&osk'W%99 &ksVe/O˛. Mt?1/?qg/}GDv??J7=bddžyl_w_?  i' ~ޓ?J%xWZO0c+m6wpŻ \nxWۀ+m6wpŻ B#CnqK6R\KPzQ=mJ6tm =xĻ \nxWۀ+67{\nxre6wpŻ Cnnۀv wpŻ Aèmnn8{r=d6:܎-{8{+zzz F>w67{p=d6Zn\qnn-ny Ӌ>pw`,+>idj>  :\՝cWN3ϰ)\)\)\qz~~~~W_x Aa~~9͹߀k|˹߀kr7: [ܞ ^Ѓ~Ѓ~nPMRw8~9p%p CN\햝s67;p=d8Zn\qvn-nvw7wդaL\-Ff}04o&_b2=:9l<I!6Iv4~E oxZrѯv.)ER pS/•_ W~n*ER pS4J/(햳ƀ{c%k܎-4NhW+ ]wPAznPM:qঀp-[p;p{n^a7ǹFF_[4y\4R= uTe@p;j2=e@pB^AA[Pm84<.9)A\\\\\WM:47(zzr674ykr@pChnyz = = =݂n#9~|mnhz n9܎!4Zи{{_7]t+3?ff(̬\? 5nQ=]סL={;\: T1(-vcup]\sw2uycen.@ \1=́27u()@8c~ƎvL6)nC A bug^,s7?b:v{)n)n^Wm-ᆴnHAm = =Mwv5ܼz\~lj+\~ p?c;oc?p͋ p C/r78u|N=_wr78 |2wz0 =C p ǹZ pC[=ǹzBBBAa7y>wܑu|np{E"^`V t{E"^`Pr{Ew t{E"^`+{E"^`Ux{Cn~?EN].>0xAґKG9W}Isbߖۘn# \#ܔG@G)pHECWܔG@ArIJ&H # \zyq<n߾xuEo͏l5)ˀil]/<ָT{c Cr coK \'P <ٝuwN;];]wtݝuwN;]w&wwS;]x{ww/kP&Ű<Ǯ貌+{ ?Iccyg+eC+Cfo\&ͥdr.˱+`RUoWWJ\\)% Aa )% rc|C [.% Fn J)Y+`q=+`s=+`v I)Y+`z = =H)67ms0u_^rE)Rp{o,\gRK+Jk%u|WzWzW+vsp;-oq%Z͏޼鎝9`yt9cOh5CH}$qn5#p&G>J1M|•Zck;5 =W+vZcz = =\[+|5|#p-׃8 q=#qOUJG{>ģOW"!d''JdOrSDrYnHBYB,7(UX0ߚ#dGցDڐP" mH0Ƃ^cA=Gȃbvs456;tMr@dgw@dQamD"xvDmx6F! "˝:BNaD[u Ynr  UXP,9 ShCB+!AD z!"6FFB KbvKBB@dІSXP+fk544 G얀!w,!D6 mHP‚V@dX@N -9xwdv8 Ngקf_c??~(ccWBr"r|]khs6WFq%pk\FܭlWw+ƕldFq%pk\V6r+Ȁ\J62ne#׸ [nFns7k\Fܭlrmf#׸ [5n\\5Wm+ƕldFqB[5V6&Fnq+5󸒍\ZJ6r*5nGVFq{:+5W+ Ȁ+Ȁ+Ȁ+Ȁ+ȀUmnF\F\F\햳WWzȀs=ld y$p%pBAQ!g#9p 9p-CF\vȀy+zzz F>s6rܜ !g#vȀ<Ȁq=l7ygpJ] M<9ǴFߒ4~/MM6ADȳҚ"_n(_T.b(^υ!<읔⹮w~yp_l<;!&w?߽}ܾ~ugwå>دt&l,5/_k'O~[><*FG}4{ LddхfA.ڳiV'ߎI7߯G3y5J)G%ÄSi)Bj6 rcd0!d9W6SLiqUtJ>Í+9eYښWR>?Z@aO'=E=E$)EܞFSK_藉{~ISK_=E$)%yO/{~IS=E$)%yO/{~IS|XX>eO.ba_k՟f;\?u1< b :۔ey="`6[%`"TwdTM,8&~M}(Ta WEYCˍ;5~]tpP*b& +T5 )m>MШ"(T1jT1rUĆMx;6)m *Ta-Wu UXU6ANa^1mϧtlDU4FŔ#1*Q"&0U80x)s|JN QU?ܿy{~= rN^пv7J)Νb6,3,;]v٧),{77fsF rl R̴U `L)@ҼS,{}<x1 Y"<̀v M'-A+xS_Rxv R "N{*b:To(jA1c2|AqάG*ƍ&Xڸ@oaDQ7l3k`Up*Ru3; aC0{j#;FPw~A 1c5{j#;FPw~A 1 c5{j#;FPw~A 1c5{*#;FPw~&7?սxޮc ? ?ȯy?ݼGa8vaGl*h>`_&^sREsf/q7mUp\v nI]6qj^q=jM9;Ci-'aqnZ 7ݠ&ܴn? î#cz[c nP]9?y>)֞rX4nrnǵvG3 x>{SߠCXnølܢ3s+=} ,{7µTz(z2z(:2nGl~~馺Gݺ\!&CG h#M)%Zȫ(A;5xN.p^`egO<(8,P8p`pPK  pмTxBnSyc%K=+MptT3@2VncPEcf~I9Am%IŔ%ubJf@qxCP ,-TW!;)_,g {)_S3 ߼8"1 Acvx\\l U9Q!xSq Bx3xKkޱWA1g >̨X'ZAa<{ƳF13Z*媰N *l0dS|J[QWbШbP"hSڎ|JBK*pVat<5ecų/唻u$W:mUhA;iН m2h9^ zkYEo<譽gUځV[[:zkZCoB}hm6r LmVE.#J=OV[kkou%ר+T1hT1(TΞOΞm'lF}2`3hǧ* ++TnxfSzU5*:; I_X)`~U~5WTgxbJ۞O/TWbШbP"hSz鋀?pU,}*HK_pr-ٔ^")4Ͳ@ͫ_TceOd_\6g732f? ^e_kvШ;QF Z'4.hԥ=QvAF : jOhԬ]Ш]{B~Fl4jھYf}5n}*|qvFɆO?^%_+(^m.e%㝸҆be .g\ \T+k&(W3&(X4MpQ .Rh`UqCwxI4MV7] ݽmJ冤Zȇ_*}~~il|7xM=wGpZzelg>+k h6onZ ~u(,-@]˫K%۵b7|wȍ+hpXkۋk@[jNvtBKВ|>#d#$d#$#tE'蜍NR!2m6PU!w 9yL~d# ) ) kVͪ;tP)D:Rtk`mt _`mB`B`q3 F^QȠRȠQHP1h8^vh`#\Q`IP/6ѧ>= i77;CB_o'ˁkŗ6-ərEy쯼ǟ|>F7Ѳ}Fƺulzn-gh[G7Ѳ}FƺUt>Vc:hm5f[Gˎ7zѝF![r^^uWk8h&n"tP)$`2eDk-9ڦBЎ !ht蚠IOТkd(hV>S 69L3BZ=G:EЩCi~\MDh{Pњ+KI󋠭F!*$AP!Әv3TP2I^QȠRȠQHP1h8j&=QB!KrT3 81 3:)&:9߽ۻ?8? (F n~OxƎ)$;hk8w:N iR11pUX )}p%İ0f7Mk&9["-n<B-nz0]Dݽq'(Eіp˫Pد4vZ!L4KInX^E6 h_.Eyh9HDo 4'N}S})ؙq ϱnoyusz2,( $1bʞ d\2]I@@zeOr2+{+)Ш^ٓ\]LШ^ٓ\]LШ^ٓ\]LШ^ٓ\]LШ^ٓ\]LШ^ٓ\],Y'Y^x8B\ .->=soӋMQ>ta@@ice,BW2s%pm':25yADW-pp?(-l`[iN4N5^_rxЀ9qq}* ÜNum=}<ƍVpO%$ۧjmndȍ"CL6"y8>-ӄ w^0[=|-'"yj+NcCYjkSTm{^G3 w^+g͔ cjLɰ~b? GƓ#hl*~#xG>0pϧT@`PŠQŠPEOS3U{RT@`ˍ'*)-*XjUU~_'/N;ؚ$p W{mq xq==8Gh{mhWmG4n=@5t{_:@wW}~{m {=۴XWJzFZz8E Ro $[Z^ =_!=C/_Uhqa&S޽zNեxɧ9,Y0'J u\M۱ bZ JCk /a~*78:-ϭfn8I8>"^:FmX?g`[\gB?* r<=/30<4*^MXxN|L lf0 *TqUBXSw I)}jCJ!t!x8,p?.pRY~7Bxo C:0k"B+T5 %ns;NJUӁ_0lԠ?3/28b8y_N+;Zz4FhiM7AKo-Z4Fhi й7Am4 ɍ j̘4FhiM $W $W^eF1㠙7ABVH{lOA7AKo-Fh5AZtM}5ѹ7A^@|7B{<^=OA^C^=5Mй7A͔ɽ j{y($&Nc˛{ʗ{yW)k22hTf 3{ytMй7ABr/o3^4=&NύwoX?_ޫ=OcC:֤g!{skNN%ڪVv*Ӡ;GUco촫h1 iWc@ac]ENB;::l(bŊe*sKfQm'C!AНFN5rnU׬ Kjͪ0KBBBѣJ!c7Щ]3cV԰ ZeRH"ntw)D(Ȍh{> *k22hTf 3|K32"T9(b\ hn /7e㟮(tKӦ4|[f5f.sZ>[Z~KzûA v>Ƴl&kݜpLD`.0oͩ,s^nSEY]ʍ7K19/໚)9ͼ%9>Tr IR*ur͒.)r-X dVul\hV,ܼU#xJ둑!['wK*[' %Д EZpuPPn? K~#B?z7ϊ,sǭ⛹[դjpH5b,FZh8{88  ,rصW*!c4 )=0l N!n#pXjn#xLnr,xm8C 8C8yC 89C8B 8B8yB k,] 8yA 8hT| aUO 'xJ^O\+TzW_ixWLN 8_!ph&&ihw5[3)zw5wpUaz*Lc^EʸB`0^ʷBaY+8hT5*Aaŋ̼fSzb3UD/6SŒTAa R\Mi5 U U UxbJ/eД9PKq gX U80x)t,.æpUE tǛEk02Kˁ./~3]ҥ'~h#/|;ǧJ0W..\fp LT*,MKE8yl n27~Pxӫ_٦xM|-|:nx^gbݕ=?]mw 6e p6nigR.jpQ_Z,<Ю*śLS~[,,\biQfc O~)xq# /ܑs'2F/5\<\4/\FUÿnDniCRGj(cE1&}/Mwק$x^O wXؓHYwo AY,oK1=IlϞwXC;z/C=`]e%E:ajܘ-\B· 7& yEۅRvvK v{ ==HۃFi ܦ+i;d;y )pK!eWnHxĈܘ9n"ƎbmiKb+zs=,= Τlz~AqE)\KaGn OSaz=ئP-Z҃T \ 1Sح|Ka = = =݂n#vXa'BzJk Zn7Ac)ACtzs&\7W_G!B\ޖNY伶kmwfHKZyn.ip^U*ՠ 4N@KAK -56Zjl@hARc@klPFVW\ca5656O-56) ^#\cfU56zЬ ABA*H&F56UAЖ+AЎ+A7cYc{>U  * ƌ#e 56_FkWh~W dO=̒M֯KMKE%8Dx ylo5?G$y.%}fG9_s8R% S KG N yCM!?a['#w}߾ ь+ }[(~ULGzuW?axGS?a3 >Zժ5nłsXK4xuڪVv*Ӡ;Z@oøs4Aoøs4Aoøs4Aoøs4Aoøs4@oè9a\TV߀ڪתw9čWr&WНBN[3{6g\A97g\A97g\A9GBD69]ku:9]kV4$(hI0Q'AAZӵfA DrrBh99ZNN-''@AA U:ѵUANNsXɉD99!gtS>9!t׬ DЃfU''*ɉGBD'6<9Byr"hRq''A|!Fm5 Am=hTf 3|!·!·!vboe#wӡd"fyȽNg/h^_K'>mE]-a_ijX]xF|Z܋V0zu}[n\tI[a .)nGnu?!_Nc.~28/K53ۥ <=7%-͞aOpm\$*8UAO˜9n='4KAaƢ~ݼ7i͛7tQ3s˱Ec7]|7)xK?K;>NWjsuL~۩AGЍ2mˤFyA|BF>F^h#h#/hOh4'4 mm6 6F6 6 6FFb09'4 M9XS"ctWKD Z-y=Bm?BKӶ%HiۏiУb7 ~. mBm?B;bۏ7cGObۏ^QȠRȠQHP1h8^lQ_TwS.ߟ󟧿1{Fg/?|큖yq8xmUhA;iН -d=Yݓ\B{2-)=),hI%@VbAJ葬ĂɖkALYΩm6rO[ɲU! xyέ%?ёe[hh/hOh4'4 v vF;F;xA;;F;xA|B>^hh/hOh4'4 v vF;F;xAf;f;F;4u폧z3W9=?`_/uxvyu{W~2vk^ nyy)[wj\ٳolܭ+m5lwF[+uݺVVpոO[pظ*Tu 7ow6[+sw<ֽW6总uƕ]9nzq{v.ոܭ;o5lw[+;qzmx[[rr}z(ހQֺ>_黯^ܽҤZoNOoPZ3؋i?InnsYrӃ$_]f)Ʈ釿uELjx^4K[M_PdlHvEbBS &Pʌ=OqOPo?mF~\[i{W=۷\K_j{,ž1b~yv?eݪ4qO}"oz/Qq/^+ۗ>[_*7eMYfv>,Nɟ~My5'kpވE+Wķ˻{:xxJNzŪvә'y[t6xWݤ44 ME(hh*BFCS T"d44 ME(hh*BFCS T"lhl*BFcS2PT"4qcS2PT"44! MEhh*BACS2˩KFT%r:˱d]%Cr,n%d]%Cr,AcKFX26BcJX%Cr,A{BD!H!D!Ad 1c= d] :Qaqnry$i0_?NJ䋛 Ym16._BAAC|P򠠡AFC2  J"d4E(h(P"TBFC   J(lh,XN!V}~Jpᷯʣl3C& I9"\ڗ~R.,ᨸNmM2"΂M^ nX□*7֨l/}_uJ pWv#u-b,5y҆=9n qĒnk4N-DӘn_A@2w?}w{}=Uvui3Uqc\5w1zw1E1w1zW}̵|U&?|}/g ۠ew`]T$pZ.|G" /c]n8 F7\uS /i q5pAK:,R\( m;Daf~g+ ; ??s\n-Av9mY_QƭPk ŻXY3ó `hcAC-3jXP ƌZ04Ԃ1 `hcAC-3jXP ƌZ04Ԃ: J+ `,f|;vï/.T@RW҃OwmŇ3=_y~jFl继ZZmET;vS A.O5]j<tyATCUYXתVY~M_=j勛?9:͂:͂/nB &q`, q`+ Fq`+ `+ fƴq`+ q`+ Fq`+ q`+ w}vv5+޶V?ޱgZS(Z[tZ+CbUxϿl[X-\5z52R[G> Gd"0rz-Ȑl$d#![ JNBvh#@ȳg5 9HQB09:kNk}0-ɸ8Jgb䚃q=5o9_& Yg%ѳ҂>+D 8Yg%ѳ)i1~wJZ_3NIq䝢%-A-A-yh;EK|PK|PK)ZN^B=%A[0HރF444,y=o__ --Z]2HU^ao֦>lJ. .@M)WTk0p[21Zm\aʧI?+en& q$i禒8.ko0UxkC ȩ$NE:l'<"nQ rT&뷓8>%:Bכ.eXy}H-!!z.@7D*Mhe!n*!jC\:p eO(#uS87!uK8AK&6[pܴPhnI!u38aכ7w}NN~` ,6ǥj>8a"vBWwO9G jn[z\pMp-r :\7D>O%} y=D\z'nZ~Q9q5q=l}Hzآݴ~[dӃaa!vч`&\[<҃Qh>dm"d-1o|HƢz߿?pQ|wqb q9 ˤ.ھZ/k"-ɗOn//R\9no͛'kд3g S:}.E黔>f5sn)^>j.]K{-w8Ǚf0֒ʈz8ج?jOq}Ng3x6pk\#Z1}nb f40-ni^pK2[:ҷϭmڴ *B#umo*UNkиk2෕fe*NSp(ew}rgfi[_wwO^q  yoOaCum0e^oPϡ&:-<|@h1._ḥG&:],~ h1VԎZKH5)e&1GG\\GKG^#ho6@ho.EB]#h|H%or3Ich;z=3* ݬ<gHC~4itX2Z&@!%@!%ČNێaX^YY 2c1J};69zICgJjZ`ƒmF%ᎡO޿##||>>G#||}?~6p7]tM}ENj]C5yٗw|.9[qRn/z޺~?ϯo* ŵD?xn =>z =E;zC;zC;zC;hU|-cwx~Wup^]3/9ZLY{~\ӛ^o٣b9kۥ#q_"{~~IKh-Bk ڈF"t9 f4'=A;dD]D4'=A/MIOKAytTG/MIG 'qO%B6_"O$'% D%UON"'"z._"H˗&'%H!KnDKA+~ h+AWH%-nKA;/E "ČwK@/]D:Q?q> t,mGj:m.m-"m$h+BM>*&MA;de&AM<.x]6ltC貉u&ABӂ.&=&HRqM<&BM<9EE;"UAƢP7z<&AB&AGB&n7}tG *xqxmpxmq3xpGo7ڋ% E % "3#&@Mh-Bk ڈF"tğ2ǣE貉e&BM<.x]6l!thrP%x!tVnO+{xSXpGe;xಿ>fp]ಹFeo[.Y`xj}5ȓ<ˮX[x;e? D^YY 1^/.ຍu @i*%>yo}xF_7Kżoò[Smu7]~溮],k >yr@/lmJh]WU:*%گe0t]uӱ&;h%B+ zfm%hAцi6WĢȣC WMB㒊:#,^ ã^Vp>1k/^rW]Y2&lT $f\u<롭ƌ@oVms1m8 ~N/ ct&_[V;tf)4B>svcf˶eem]RjYm vnlT$nH.{}Msz#-NO?wE`!?XtG@Rک~DZrk>vyGm%ftV`F$ftNbF/2q:$ "DB$1fj,7* % Zo$ Fo%fVbF'qtBk_/VCYN:ni6áôE!tV[.>C-WsCΩ ;v4cWm%f,mB0(d)d(|C 1cb:nI@'BRTHTlY\L!QKuuA*Bs os oMr7A̩* @?~K*AY&2 + "D"AK2cQZe?ЊgWH# IcL!%k(!31hF;z:q@{BD!H!D!Ad 1cdG/)dP![SȖDȠBQi82GWV6S6(TrxČSrt$ "DB$1cJfJ)9:6(Tl"@h#P3>jF'qtH!^YY 2c1J=U n&B$PQBP!FK̘ @3#qtcnD! Zs?|njqx6ًu軴 U{պvOaJM^9϶\\]q6( ᖧ ]c\pt pƂ{{;?ڪ0d,'_.?fUN)6R_͋] &ރKS{eY< ܳ`s(K|VX`+y0U^ɂՕ )dm%J+Y𱲒S,XWɃJ|TQ% >T`+*y0UPɂ<*djJLSc-%J)Y𱒒T% >VQ`k(y0UBɂ<*dILOc$'YvS,X9ɃI|T$ >VM`h5<*dNJILLc$%YZSŒ,X+ɃRI|T$ >I`L$y0U$ɂ5<*d ILHr`>S,XɃ YɃ YɃH|dm/w̰%gq}\6޺` ?[?w=h>-5|7k/[N=S6,vyo FpGpGpGpG"  B<c_܍hوq-Ѳ-2k7vKe]v&\viG]v˶e{ˎ 'T# l^6*R.ð)󰠫NO?׬>A`!?XtG@2 A;ߏZKӂ{L?K3:+0s3:'1K8gosFD DB@!~O3zK ʵ\ZK@!H@!JČN Tc ćM᭻\@CYI8 N9]Ơ8=m8}sϥT: -pK/3mpi0,b,\+"ؖX9b\Ɠ4Y;`RpW/f ޯ^>9 u~1 Dspɩ#%x%c~n9&\5MG7^M#`tM#`p5{.D_\wXaIMr/_{75]o5Jo7%sq׏}SWm ^Qk_JZ_ shf-{M.Y`2Esa)0gro(UN#d ꁗ cbm6 oS8r)ӿma}bOK-8`0xRe0pȧ sP,Vc9l㴕T1a^U><UVָRhh/i lqUZ PH*x^bw8 \:*DQ"k`KkAbt"-[OuV.ɪ-{Zly v٥y YxUUx14^=o1`5PӉ*7͇w޼'ϿfڋӇeϷdϙeImU>V'/}*'/qDu1G9s2D4lC9,#9 YȒs"-s "-sI DNsM DN>{- s"-DQ(F ˡ,Ym:Cd-F:Cj#6! ĂN ;PX}PazN()ah#l.$L!4PQ(8 @Q {Q ,NSOhh#:?:6Q&%g ,xoG*0OAw9(*mTrrF9V^QU (+ &`_@1K+D!h+Dh&x_W@߃|ރ|ń|F:`1a>VP"[6hC96hK,%ޭ +Dm6DQ = ,ZJZ ZF mHA i лSDT^YY `X0 MDfh#2(!2ɇ.@ #t#fAcam)ܽ/^tb.uʞ\CMPo Flv?!`z6`M*MROn }rT蓛B&6'7I>I*MROn }rT蓛B$&'{B$&'6DQ6%I>I*MROmI>&d+`T蓝ۤB$&'7I>yhI*Ab&'Gw!rT蓕@mRON&d#6'[6ڤBjHOvm4I>K,$Yo }rhI*mRC. &d{mROְ6n }qT蓭ĂMROvw&d/,,FT蓛B$&%I.M*MROn }rT蓛B$&'[6ڤBh }XK,8 M*A Fh# &6'+wI>Y &d#FT蓭mROvn }hK1K1K$  FwI.M*tmROVmI>Y ,&d#6'[6ڤB$>}|w\R P:ms\|qvQZ7?7|RN=O3c'$,!U, 9yd [d@m2x2xw?!>GodF" 1#72xydF# ?{~GUú hvCZh֒G<ڇ>']1ڇȣ}XKZh֒G<ڇ5d5ڇ>%a-ykɣ}XKZh֒Ga?<>>ifEbz|Y%Y%'d S|YT#Ke g  C`ɮ e @NYhyOv}YIYT,-_O_O1fy0إ~ b\! v7?=瓹6^},{}lX{d?Ю uS (I'Ad^ L2Hs4Is<#iΑG|$9H9GI4#i>y$GҜ#Hs4IsB#>B#~FZֿǷΆC1B_<>\ܐG<\fKM 1B%dGH+n>#ʑFH}.#[!ݒ-yhɣEC}.nȣEK}.ZsђGBn_/Ɲi,#E0R#E@G`82:)|+q꧞"#E0R,yF#Hp")sby5%̿Jeoh_rDE+7GU+Z4¢բX!䚻5w5 h\n]r;1KnDrEe\4B.Ӣr%7>??{s[/q{f.v8}|۟zv+qo?xY>;r;؎ͺFOnj$FOnj$FOnj$FOnj$d/`S#'75}rS#'6DQFKnk$FOnj$d-F[#'6> ,HNmDHMDHɳDMD$lj$(end%FӮ{n5}xw[#'[6>9F';6>K,HɳHAFO6nk$:u1j>Y}[#'kX5}q[#'[>}[#'{6f6f6>蓛>.蓛>蓛>蓛>蓭@mDhk$d/Xpxw[#'6DQ(F[#%5}xw[#'k6>HV`FOvnk$d/цhchch#H,$nk$FKnk$d%F[#'k>蓭@mDfIʑ;!-yl$eK')[8IْIʟt8I#-yl$eK')[8Iِ8IْIʖ<~K1xL T#31ycF>!|nj| D!M>w},c鹍Q8nj<' @ms`GrnCwc yqnmyqnc'6<8 ƹ6O0m<t#O0y F#<p' ~L@ڑ<& ݐ~ۿ~x8Iiw HM؋:Mxx }!cKKC_ZҒЗ7C_v1% }Ȑл0|/71%/-y }icKCVcKKC_ZҒЗ<1%/-y }i}|xOWsCqy5W׵[ef6p)1g8w685Q [@ VV;% ul -fGbmG W엌+ Y88%g.Yotpy> 3.gߊ|gxg\<py>Y.g+vςM!+^Rg[/Fz v90<AC#5#+/w\.]&Ҩ-x#~u *WW_S9pylpp}3]p}!`_q}!`=?\}O"xoE}C׵7fܘR=|&YÒlojHv5y͗75]#~ .k]syM5#- p5ns/dyy&si pSÜJ u=xݼn-1);'1 =@C`~u[^ȏS^LAzC0u֟z=[ ; r*bd܈q,>7Nb8qՓUlm8Z\zCt=xݼnskz=D"֦:Bt\Mt\s\ڭMs\q^/Cj>!YJCJqj(?H}np(HUw (Hj4AM nJvK |NS,@^`7/[7ȏ՜D C! q=f7=vKi ̏8e50=h!%50=h!40i+X;܏SFԃaa!vqf`z0`f4n܏S&Ӄ>z~p?yo#SjeSW?jS"u8?Tٶv>=SP*v5sK ]^ 糼6./Epz̩wz%qʵwI\r{'>kS2 Waa|VB~\ pz}X'LqI}gto f`VS_ayv3[:ԉc:o|f.ڔ~b71߰- n!ۢIszkwzUsݖC#b]1BO`}N.p\s~FܐhƜE}n:{6,ENci:g ݜzqp3.vEn^חpk -~I+pz_n)2 ߦ "> *\ jn ܏kjujyf܏k =@C-2skU"3q="3kp="3kq"3p?Ef z(EflО[nح܈q-2sk-EfWzEfWvEf~\P v+Efw C!zhzܶ *ԏ"3Q=EfנzhE\q[dp@^RdpK-EfRdpKY[ZdpK-EfWvEfRdp-ZdpZdpn^`RdpK =@C-2skU"3q="3kp="3kq"3p?gSb\/ټ=wa!v"> *\ jn ܏kjY̞?{b,,yE>On sX&uUރAALiܷ> M 6WpK\9 [\9->MޤunJոj<-9xkq=M \9->! }RC,}'5dOjpԐZ\5Wp+OjpԐ>! }RC>i Y'5dOjpԐ>! }RC,I YOkpԐ>! }RC,I Y'5dOjpԐ}jC,I Y'5dOjpGC]|4d YFCѐe Yvѐe4d Y~ Y^ܽ{ݻ#qm]UȺ5v<^]%_ͯf77U6s\;|4By*Z\;AV랛ƫ7EIgtq 鯟=w"Uh14qWAS`9SU}U~W}>>:$`ϒZpK-UT}RpK-U}r֦MUL-UWzUWvUT}\V}\V}\/حT}Rpn2ZAp#r5_W#.\.hw}eݾyo}W{ng/- :izpS.qUտzݯa7uSMvgkr,k0Mq2A\/Cw&wB,1? n>ה>7u۝8縥nոj;K}q\!u`ԃ 6= -U7w. =Db{[:]Kqrc-R|?o)FHouk-p-p5Rϝ-p-ܩRϝ-pn3nƿj=-Sn|S crոj7?kp=n~vv^/,,CM=_O(܈q= Wz'VO(\q=p-zB:\yf܏ z=D" '{PC=p zB +' PN(YrB q?'zB Wz'VO(\q=p-zB:n^`rBθ 7z =n{B*ԏ WzhO(\=p-ju' PN(rB P-'zBϭ'n9p q P p= v+'n9p@A(CPO(U Wz'PO(\ۭPzBz@@@A` [Ps >P C=p5nzB܏ kq= =n퇇wb mLPrnqj}#WUxh p5^LKAqT^V}.VFzW whl'q!IqܒT;)K8?KvR7@Qíɚ>l'qKR8@NZnd;)p?&Iq\/Nd IqܒT;)[5j'pk%IqܒT;)q8nI\ǵvRz Iq\/Nd Iq NFvR$ML;)P?fIq\i'q ǵݘvRס~̴^/CIܒ%YpKd -ɚ>&kܚ%YpKjn5YpKd j:\5Ypn^`%Yp@A(CP5}nM\qM\&kP5vp?z===݂n㚬skϭp=d ոj܏kZ\5Yd͗{sq 48$lIβ-xE2%V:k#,M'm[A$Y ܸ&W]I r*M'W:)8[7uR 0 0 v  M`~u:az:AzH0=l m41o =Ns̺\ani_dum57ͩs):;~]}윛|3BE@7;7|}]}syo^97u7uWCz kwE ev6os:-E7-sIJ<庤qKp=W׎]npK[:?\[;t- V:?E@Qv~sk[:?j\5jkq~\;?\/Ѓaa!vc[;?UjqbBkp?ńzńzń vq?ń7z=D\ϭńW~\ P P V \/Ѓ^꺖b†]5K5!pϭՄTRMp5nZMpK5!-Մล:\zݼnjBz=D"m B&C[Mp Znm5!uՄ z(ՄTRMpK5!-ՄTϭՄTRMۘՄ O[MpK5!-ՄTRMpK5!-ՄT\/[&@QV`jB[ P P V V\/Ѓaa!vj>V*\jn܏k5!j5a sz-WH.J_tp[j]Zm. r5 t8]r<muD͝ nLpX[:<y}np<Wz(}q>-}kq=>ujrzݼn35p@A(CPOJr*܏Kr>5jrZn5p5p@%pgJr{G%>}p=>ոjr܏krZ\5p^`7/یqM C! q=>}p?}q=>5jrZn5p5p@^G@9pn9p#%pkn>UJnjn%p %p-GN/-q# C!zhr]n 6p56p 6p-j6pmnz@9pKn>-}sܒ5psn>ոjn>-}kq=>ujnzݼn9pKn@Qn\q\Psv}p?}z===݂nsKn>Ujnjn5p 5p-qsnݻ]?G(h:f^p\;\9 DA\Oy35.nwW}X?q&7}Gs>N/-C~+H[Ïb$ǟ%F}[ jn.A-5-*\[ոj [ jP jP j VeRPpn1dՂϛ?Uu:}jwe^Qm$MCĥf3Zyǵop1139c9c9s111sGyGy9__??{Bgٞ[- ^Qk_q5fnYr] w츖̵]s[wwO f~|pl&l& X J>.Aor"Vkg}`H)\Cmѽ`IҨ.x}h <p:N.% Xx NMMm? =.e  %ƛsFpD UD*֘8LR 4^H tи*R TE0*R TER 5]:e@^ /QE*1$PUxw]:N*S+\)"jܥS 4^4K H)0PH90T^`Ϣ=", h*FϢ =, h*NϢ@=", h*VϢ`=, h*^Ϣ=&# h*fϢ=, h*nϢ=", h*vϢ=, h*~Ϣ>", h2ϡ >, h*Ϣ@>", h*Ϣ`>, h*Ϣ>", h*Ϣ>, h2ϡ>", h*Ϣ>, h*Ϣ??q1}w4-x׶]}l?l ǭkⱺ~Yퟥ7D;uίې>זWWl*tbiEM\r u'[= w#p%#]?rFx]\Yu( '=7BeW[Fx: ^yM]J[Fx!\#^ Cpn^`< ^wݎaߔo &`v^ 7odʋ㪼T-=Kv&=Yk-]Yk]&/Ns\{,9pϲ[{ӘR[{n7Lg^ jJ{5[2ZnIg^ \nId^ ẬvKIqs{5[W7%[ګ߰}Im6պܶUFжWC^ Znm2[R>w߀r]_4nJ`~ڕ!ܮ y_]niWps2[ڕ\롶+]-nnWpK2p?n!z(nmWpǵ]ոj2kp=vev+^/,,C-q?Ү veWzVە\qmWp-ڮŋǓ6㕁O#/^\,!p (\~!s}pi)a*!`K λ| ~w,H廵, h ,s%UUUx):HsTS"ՔcH*UAE/U. ҩTE*R%9xtrD% D%qxm +إHְ*P6*XY.;^ /P,Q,PE/an#}p !DP WEyOix)2K(" eqU0" yfKwIDUUD\zOOR0tipNDPZHDPHDx .) T1KT1 T$ EK눻t*H1U"4S#,)YD]:EAU*>Z)g?J D߇϶Bt0ϭO@85"ej!\-j2آ)H"e[^WvKEʘj25 pzHRL v"e[n!z h[g@\q p5:\u4 hz p@^<=7g@#܈q-Rs h[PV)\)\'Ѓ Vqp@Q-RqUQ=kP=kQyP?n" z(Èy4-3n)et[\Uf@<WvEURT p-ZT pZT pn^`RT pKQ5 =@C-skQ5Uעjq=Ԣjkp=Ԣjkqբjp?E zzz"ǵϭE}n- C-[-ZT p-ZT~O_'k?8"E.^:)ZkZ@Kዻl.9G pz"@FΟJV^5ۆv7v3 81 .S'O%`- V%`Y Xy)g祔*x^ʩ`m0OXy[' ,Wϛ7Knb%~;s1p38lp.'Vxi1fp]쁀laUŘ*rREZ"\!ŰrQ"yaIiW\֔#iqXZI`5 T9;X+/RteE \>z񞫅.EjҸ U^{xYpN3K/:-Xd{1^/ fvs;v|2n曵7^7!n1su93cWZ| 䌛Kl^L<%չny/1 q׷azҼɎ~7n7> ?镤 n `&\QA1Lf }Wv3^)1Lm9Gzyf܏͌  o z6AA%,kKczknfCCD7>M\?@zpj?#TK l!Gcgp?vi9_篛篛oq*q='n^jr 8-UnpKo[ZtүOUMge0=R>|鷞ˇ?~QMW{M.{m|2Mon|2uOzJcZg\)i}=@Cqlquzp\pfOT/W['\+-.ɕ=P\9n؍q>lpdKuq ĕjndWkp?&[r\q]6TWKoTVKoTVKuoTVK5o%LVnTVKnTVKunTVK5nTVKmTVKmTVKumTVK5mTVKlTVKlejpձR[9.հR [9.կRZ9.ծRZ9.խRZ9.լRZ9.իRZ9.ժRZ9.թRZ9.ըᒍZ.٧R}Z9.զRmZ9.եR]Z9.դRMZ9.գR=Z9.բR-Z9.աRZ9.ՠR Z9.՟RY9.՞Y.ٝRY9.՜7+Dž%LkVKfTgVы|?ʧ?S\)"캺!^-S?W5bmyS/e~iuC?ZmCMz=L\0p? #Xӄ_Ir )gПqB3\?&3cE vY^NJ첼)w{=k.Zҽ5]+^ϚKecҽUzƸǤ{=qIzV^3ƽ>&Yux^O-k}GzO_}xAW_reˠusEWOJx>U֪mmي|ŷ|ιI\\u\rr>W֑꩎rSNruݚv\f:a u6#\^/fR.pv\rq; \7R..(\%*\˧h]|kp?6Vrqz[-n,ٽ7E~bW[&|5Ι 8ܨ%x#Sim0P~y4 c . .'`r7&'ys`j7 &ys`j7 &y3`r7&'ys`S90d$oL2Y05ɛS_,́/LMT &ys`S90UƂIc$oLq`r7jX05ɛSE`,́*0LMT &ys`S90UƂJ0LU`S`,T- H0S Fj0LU`S`,T= 80UƂ0LU`$S%a, TM 80UƂ0LU`,ea T] 80UƂ0LU`4Sa, Tm 80UƂ0LU`<Sa,T} 0Y Ɓ 1LU`DS%b,T 80U$Ƃ*1LU`LSeb,T 80U(ƂJ1LU`TbT 80aa80aa80U.Ƃz1\߽}|;IQdwIeEI2|oR3'QQQQ#3>#3>xD}FgD}Fԧ .Qw~?>.[/v-f<'N\SZIS]?JATs\# 6O}n~޶k9npn1Q[lp~[Ԅ-k(mkN䷕67?:6.:-܏4nzi(C` WYBc3ըJd C!z(1@%0ح09ԏsX y/,,C-Q?.!1KH ԉnY% Dυs=-?[{qs镠֩]nm=;o[%iYN83v|i0 =u:G{n'q|n2ܭpA8 gVȘTZÉ}0)y|[s\!@$ 9p9_4?~9/݀*E'ÙiiLAN3 g>90ud8󱦀S&'Ù549|4Tpf\TpfxTpfإJ̰*J̰*J̰J̰K&'ÙaU&̘*JǸ4*MN349|Vp`d81MJǸ4*MN349 49 49Ό49|Vp`d83 d83 d83nxO 8xi;#e6EAfM`5fb;3[;M!91 6 ӴgF=p# J[KoO)#t)ݟʒ N pk8 Kyff@(C'm'n^_q^-I [r$nIIs#M zVpSXCB^~,CXv.<`[ܴvVpo5Uo y$-ᛣZOr\끬|.\Ru{T#ǥ9.UqGK=\25yT#ǥJ9.UqGKj.̿z.`y\5k[> &Eމrl᷋^G( V8!*٦cA` j I9myoy M%Y{2іhmh JR!wb56* +Wf2`jpZ@&ept0`jtZS Cŀi\3 Ƨ$ 3|튘3aP\a-CT\4!>I,nuluK[b X%-n+`K[bWXĺ%1b7>'<)mO~W9TN!Wm3szfc֌,>+v}ž>ʸ8n Yfau$>-ITew9]ƀDe}I">S$Q p)pTDŨI18S\pVG"pVU!UnˀM=WUWUWUWUWUWUWUQ5WUm\UcjE&mWdU[;GceQpyۡm^<⶙U(pY2HK6K6K6K6K6K 6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K666K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K666K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K6K666K6K6K6K6K6K6K6K^Too~UvɯqEké(-GUe]ccmsۛZ&~/N9b[w.oq{DZMԽrͯaK2ܕCYOm]w p?iHp_"xzZF@TTTTTTTTTTTTTTTT(#w/_|=5qpTf;u|OmZgk)nVeNuEn~dv_Dc&hb&hb&hb61@M d&KO:} 븜J[חcgŞ8\IYt{,U钨/aQϞ^e[W~Z\7(v8WەN1ܾ4!Ō-e 761ܱt8fecoTG }{΢'El?O >)>)LTT33J!x3`OoROk⭕z\z\zkWDŠAQxQx#J1xQ `E'^xRObK/J=nQ(SDŢ^xbŖ^z5QQ1jbbQ `ҋRO"*ET,J=n(SlE'&*zET Q57*/J=vXzw]+DV pE?W?^{ո5VW1kc$nžKs[UP V"ڡq; ܣϋǍZttǏa>c94 'pwm`O|6`O|66XO|6`O|6w͟_˿YyϫO|w˱?[d?wH*uhOa\"&'c7I&q|my96u^1n,KH2y]~lg5n۬1~)n( p!s(p#Jʂ~w+m( n3ܨXdm@1dy ߂!=xxއ_\LÝoq!PJi}=s;E>@@BBDDFFHHJJLLNNPPRRTTVVXXZZ\\^^``b$;$;4;\4~|n_[%µJdD^s*W\DJG\DJ`DJ텰JdD^s*\DJ5*y͵JX:֭*q*\DJ5*y͵JdD^s*\DJ5*y͵JdD^sDloDS緖IPӅSIu?˱%+_)[ çcEe?P xk8?  -vQ`} xf\k)w?8T SKO#00~*`q@%ǟ X2*`q@%fWT+_ҿC+.*i+:*ٕ5ڃٕ5ڃٕ5ڃmVN.ڸ ^L+u'ůHԞձ#Y?_27sܠUpB揹U!ܪܪܪܪܪܪܪܪ Ǯc,!N!Kܔx?RL3Wj~(ss# q^+G\+G\ t¡c}XTCTCTèṰ[lu 31̥'x $r> $\\}:ss1@̥JU|.G~ݨsq?HW|.G:s>&Z7Xt>"nǃh|Dܮ|\mK6q36=".U|ƞGV5q3v<".U|ƆGĥJTE*h>c#RglvD\KU3qb3v:t\舸T)d>c#RgrD\MK1q*38".U|GĥjT `>c{#RgnD\~͍K/q36".U|Fĥj؈T\>c[#Rgj\nMK-qi-Z\Z/ak3Y>cCȭ7YnN=~cj\N#ǩ~+]K,><u~5]zQգGMVMVV309uzF6fz \ ^vਸKn\v3`k7Ǧ4'bn,uF` tF`c=}`c=}`c=}`c=}`c=}`c=}`c=}`c=}` yvݷkOmK_>WAձ;W+qRS`(z7*rn= 7Dْؗ g$/1?'yII9K%7~c)EO(9@lO.R\&."p侐sަ0 7sarO˜qIVE.w}ʀ\C\pԀ#o>ee,kgY+`YβvWe-kgY;][βv`v~svSO6iIܩ|L~@_:ښՐ g/&&S*P![%P`9- x\ǬGa. ܽbhɀՆ`hy I}CܧKlWhѮ9אbU#RHA$!$A$!$A$!$A$!$A$!$A$!$A$(!(!$A$!$A$!$A$!$A$!$A$!$A$!$A$!$A$!$A$ډ` ` !$A$!$A$!$A$!$A$!$A$!$A$!$A$!$A$!$A$(!(!$A$!$A$!$A$!$A$!$A$!$A$!$A$!$A$!$A$(!(!$A$!$A$!$A$!$A$!$A$!$A$!$A$!$A$!$A$(!(!$A$!$A$!0%%NWÂ]לvUFzA|)Pװ4MŗT,T|IuL!X٫X?%3 3rg3R7Ikx?gJ.˓/SrųFtKnSrbQ݊{~FvSr8Srb"*z+CQ_sNu`ݔܹr9Qm y~5#_8wdrcpUtrq-<uLFfwVͼm5^zު`=تz~y߃zު`=تz~y߃zܺRnN\7%B:69q'`>>ܸ֝;vuS;ه|ʒW2~&Eܘ[q9q?.]8Q'q7+ ӱ1D]H`8S)[:p#N}1\0iW M6C͐f5eIݶ[4: /Eᖄ mɪ- ı\ )zpQ@)XĎ".r \P . (>*Ӆ峊*\pb"*MT ŋūV ~[o+&bbSEJ-ĀO&Q|31Nfz -=^>W`k9g-`k9g-`k9g-v`k9圵ۃ圵ۀ_]!цG0h%ܐhI>yݜcNZ04Κ?-ܻN v}%}*Xa}Sɂ[ޕaxos{ϗssMX U,^*/&]q} lV[eUVj{UZelV[eUVj{UZelPeꗷw?b~ysK#æΚ>[|F5}ރ5}ރ5}ށuM[54q[J;غ8r+\9\-Wnrlr˕[r r+\-Wn+o`0wUmSL3>SL3>SL3Og )|`S7/q9L7v+ҿr.!e- >l \K oZ7]\^ yŮmRqҪhrI3๵imgCC3r wjm] `SM7u }SMݿ6u}SM7u+`SM7uMb )a\>|7~,|l=?l[EC;.1> n6O~4\8L9Y9A|b=oa-g}ęEh.qs WpV+A:%u/ Կq_[ V鿭esYV!xEa%UaeUa%UaeUa%UaeUa%UaeUa%Uae"*zœ+c,)6׆6׆6׆6׆6׆6WLxڧ/4Bn_H~L!_@!K=7ߖ9W!xt$z_19]+hzCMx\x\J&қDzR(&O`jFڲö-;8&OaonV I-GwOd~aÎ4>L3>L3>L&g |_///+$Oʠ8wj)ajcy60tl 4e)G^Ɂ-3†0G0TS##(:Z,-X*OZLdo'AnK[ʘ n-b&Vڼ:'J Q.D`f`fw?HmPkOvo+*cƈC#a3F0`3F1Œf`f0c#a3F11q;wݝB8]O?c?jYjN]n`rF{snP ʄnPcAuvb;ucN#Ak7\wlC&J&ʀ&J&ʀ&J&ʀ&J&ʀ&Jfb&ʀ&z ^4QhgliI,j R{ ?a+`s7`&& && && && && & &&& && && && && && && && && & &&& && && && &*&7Xu.]Nmj[Օ=:+ OmE9ts|RI0 oIlIsHC 49$!i+`sHCW49$! 9$}+ѿ<ͱ_}+S:2E.%gAwꄑ8.*0&~{OFW׹}QrE9%U9eU9%U9eU9%U9eU9%U9e"*zI]} *8jW4W͕xlDs%+͕hDlDs%+ypJ#F7Vݪc\sM˚{HN%շM~xHڏ7ɀ;/#p0<(8`.*(#8[<i<U8"KԸ`i3qQȲʲ \lj3WkZj`sVZ+\l 6WkZj`sVZ+zpqu{=i|9V_ֻzRmhy>vZaOcV7? N20:ukpIk:xVٟKj'(.eS.SSw/<p/h.rsOr"E< xuu}\6bWQ69=竺tx,s{[? #"j*rRYXs6P 1_.l=@ dmL&zbiJ ZC+yl yl ٬!ە<l<l֐Jb[C}b[C_!~ל=n.e<ǽN1 ˱R0͐&)o.WF`tQ`+]6"֚i58keʹ`keʹ`keʹ`keʹ`keʹv`k5ڃ5ڀ%onԎn[ 'w/cJZ`Wq},.=Qv JKKϛ9p"#7-X?=.7 8?.~g\dy74}̥rG/ ܕx~9Ni"b vn.^ 9~G oX-y$<Hy$> x\-Q(ai!Ü܍~pB{ LqP<|IȨZj;ET `KFg+oPla5Q4 h㤆Mn6cHSYҒ`K^ZR[Ғ%/-yylKK^Z ؒ%/7˻_>&Mwnk S|긾 SGGS2JHG}Ny sJ$Hr68b3֦ /l<DZ6 i: )Mq̉ a,qLo\ & `MX7a ؄uMX6a݄u֯MX7a݄+`MX7a ؄ݛ޺U YYwJ>;7ϲX^ }==y4Gn _ n%[O˱2S7hWx+gU]wsv9ߚ8^' 9{_Zq΄m@GA7{rs׀.38l26l7v3r4kQv{΀!7XU,^ v&ع!`R̀G~&xibIk-v- ^:0|T, U,^eZ[+bDŠ Z=jmvZ5jmvZ[݃jm`Z=jmv~Okm_~W{?MɽVɽxϤr9$`qJuriy[+=L3yg{&`L3y= l{&ǀ_/q%o+;1W>SⳙmKJeOt 3!˚YsGBs:ĥ{s#Uܛ̕*{QLx*`e3ZLk0X!XX!XX!XX!XX!XӚNQOQ\D`I\`I\D`I\`I\D`g]`g]`g]`g]`g]Kߋ7w|._q+,va1;u|Oj9 .UҗcCsrFosqyUm}ieߜ^ `|W34 gh>C^|36 gxl>3,NFԗvI۰?)czcc1n}u ~k >-CHNbzź >CqxK};γԜoY׃N~ڂ}3F< A~ڂ."8g,lmì+Nrӛ9wӧ6snOmvジʃ"؆RCJ^XaȿeZ.ѥU:t #ݼ=uʴ"FFV]ǿEtzi D77.*!oݨ4{/c k[!nMC$PۗM 7e!r"MR(I }zpRxܗIQmo~XC/GC? c}X>ևQ#-6GuBVq%aq}+J<\RA\QA\e"+Õ\;(A2="nTyDQȦhyܱAt<"A4<"M;"nhwDܖ툸]6%q%#J^Gĕ+YWr:"tD\(rQ#J>Gĕl+Wr9"rD\䈸q%#JGĕ,+YWr8"pD\q%#JFĕ썀+Wt7"nD\܈q%o#JFĕ+YWr6"lD\؈q%_#JFĕl+Wr5"jD\pEO#JFĕ,+YWr4"hD\Јq%?#J~Fĕ쌈+Wr3"fD\̈q%/#J^Fĕ+ZWt2"dD\Ȉ^|K%ƈq%O@D2qhVF2phVF2 \2ѬlVhVF2\2ѬfeD\2ѬfeD\2ѬfeD\2Ѭfe\2Ѭ׬fe4+Y׬xp" ٨ɇ/_3?9+ӱ|z]gSOߘ?Ǧ,O>\$c1o%7NslۥjȘ]..cUͷI4[p=Մ0N@-"nqP'OK3'ZJ<ǼMc8y3@ƀ5.4. 9A[>*.'?(p7;Y: w^(pz xop̹_ g0xcNQQ,d`/\nS$Ȩ lT$C#oW,8xp='!(]Y p(sԣ~yz4 Mv2a~948ET$W,^=P7ļ;z4MǦ&Q1tH2*zBm3{ kg߼|ur1w?_ :?/c7d&Ϧgrpvr֯C v=5g}Oūm x P7/Yuo<_W,<[G<\8ff p,U 8*OCW ]XM-`Pjupt֓QHz2*SgW,^y--lTDETH{rŞ[)tS[LQ!1U,`N=1xDi=4|ۻח='oZO6Ny}ǎg]pӱ|RY=vۃTy9zN(~m{jS|?ӱ[m/ݏ?p j8]@ԟ1sg'/{?DZ\b7L+٬ޓ'ÿM@}7/_|M''҂.~LغSm4'Oο|G?YWҵqa\E}g]_'r6oYSjٷoYmҼcwQ4ks%Bh#pG-k~[n_|nynYAU.WXn}wV;zYh/Wtwpb~UIg:FC98昼}q>8Kx!ssXsOcQ9AqC1ytGE9D4!r!wr!ؘ'H4+w.E{W䓈WMEyn\H-F7n1&(n\x|}bhDpC.davS2!+r2WkRmKx: ^?R[+󝺂 8lcn7y.W%Tx19;tn8p<Ƙl3m wqpw:ӱqm\ 6+[gp[^6|l/ӱq0Rp;E<..ds~ 7*⡔SNGy.WY@q~#)SRpSGeOqHd勋vH~Y ĭny/a>&t/ rKqҽ&gv;&Ig!u?j8-}'{j~]ߖW 'K[1!G1mpc2Q#Yާ-w?;~mz>! T!>b`]dY֏%!%wЊKQc̿1 j^Unez&fqiU{W$ 3MIG;MbK3s?}ņsfnbct~hՍ=t:rgo"t9ٽ$'l*䤯 0?<-f^'OdJA+A(pPOz؁;8.|xEYn,ΙhQ8hAn5Vr+RhJ{ADAs)G 8*<1k8`b2}c't<$w`lNgOa;d3y.kx;Icp[Zd2֗~76' p[ pC 7[AqCrZȽ8uͦQCyp$`iD,"aszKM!8Q!N VxҘ0. X"*Aa<(BQxҨ0ND) CB qZ{~qa-- q`w&A42 a, C`ifKCX0 `06 a, C`inKX0&A4: a,C`ivKX0A4> a,`'C`' C`iKX 1FA4C b, C`iKSX"1ƈA4G 9b, C`iKX$(1FA4K Yb, C`iKX&81ƉA4O yb, C`iKX(H1FA4S řb,C`iKSWXX10W b, <{k%NN`x%}8Ha!q9q!3 n@q. ׎rp=> mK3TDX4_d:*"=Np]X'_g|&Fp[>?+֭W[g#QQ"F>?1w\Fp=>?mub:;~'"x%Ipbj#}<|1wlx]izNpme^$ >[>Ɩa+֭W[(Cp~QQ"F6JQ1nu>^Fga!ub캭"c:-Bp{E)ܖ)Cʆp:ERxHIn|XǾqJ+aPàXX~qJp>RxHn݂->}SꃋвuhJ kW5ݵr9-Ǯ*#wCLpM:׉p*~q9vVnJv3%cKdm:zۦH7G17 ż|r+Զqn"ngYYdm#pb%1+ 76p=qܺ n5Ap]2d4nhܑ%q̭ d4lh\Ò %Ap[~ݖΒ "zE<P2 7*֭v #kF. [2 P3 V3 7f4nCh0Nbzź}\3 7*aT*q]g4c:Ap= l<3em  +WàAQnQn#Eܚ KFí [2 f4nh0ܚ %pkFí +֭W[h0ܚ QQ"F>jF. }d4ahÒ -nKFv>^2WCA"bݢbF~/cnh%ApKFz~ݖ >^2ahqoThtfmy%Go}QPf3&K>㘫% /2XGc+>;iGh^Eź>^/s@6%dm9}4Dl<,8 K;H[XǎLttd^fa9xX p@v<]1}LCA"bcOWLe6d-{Ku~ˇ[0|;a}/8wJ'OԵyq9-!7d F;7wm@p~+t01w!wmnDܪܪܪqZwܪ\o@pk-캭[[+WCnnT[Tp]c\â\ϯۢE -@p;>-u6xnTCTèE 8.Zu>^xXxXh^"E< xuu}hE 8.Zu|<,Z-Z >^hGxȅq_}%Ο|sqlӱ_xwm:<.<>/^$ wйz0$!?Y"tpsH~2)(r ɶG!w GN#ϡ?YrD -1 ͥx+51 xV1>QRZƐ˔#*GyE5n 9'rm+6ledf=xENFb]n/f&||0$ <=G.yv 6G.9[\>.(X) |^0䘼"FSu@HN<-G؈^i1(b#"W0L.]nA{Ml41hb#jV0jVpTTnp+m"ˆ[4iq;%\6 ^x8rp=Ұ#$9F;KqkV׬ Cr4pQ#e`r-jw2Ljw[Tlde%DFŬ`I(+ѻ]okbcư|k 4C EU y\9ļ#G}fwtȽo#t!{*bõY&.6\^fkU4C/crFƨQQo+bw{9ņY'n}PĆo+[ v;ι'26zMl 45+5+8*v;4"6rbW`bw\Ygb/^|ӏO\aqJʝ|:=: x#^ɷ@MG/iO?&"","","","","6x(-K-k---˼-뼈- -+-K-k---˽-뽈- -+-K-k D_/b˲/b˺/b/b/b/b/b/b/b/b/b0b 0b0b0b"0b*0b20b:ȆBȆJ0bR0bZ0bb0bj0br0bz0b˂0bˊ0b˒0b˚0bˢ0b˪0b˲0b˺0b0b0b0b0`q:ز<ز>ز@زBزDزFزHزJزLزNزPزRزTزVزXزZز\ز^ @0l#,##,##,##,##,##,##,##, # #,!#!6Ȉ-Ȉ-Ȉ- Ɉ-+Ɉ-KɈ-kɈ-Ɉ-"/nq{OݶAsCtt4 Q[.֥\G5K eQٞnHu9v>Fe@#RSB< Y[,MwOYg?åA]\t3˱1`0\Ec3\E,j8͠.:>XϯuB.`m3gƚ]WĥA5|AM1^naS7*n6pfPaSw6EpaSfPaS n6p[źu}}6Ep{E^MqͳxXMqͳxXMqͳu[Mqͳ} g :lWO@yoS6 iJAwړ^ckݔ*q96YXuňFpϝDnN:s㜚ZvsjEp԰এΑ)i]qNGOcny&31wa:;t:j9s8~4 d\wYTb[| fn1ܖc"zźu-nܨQ#5Gp,u>^|dnaܖ_%Gp;dn^%pE<,Íu+Y>;f#%p5p=n5pk|<,+֭W[1܁5p"FExXgn`a#-n,}^"J,-Y>[|dnsk.Y>[| fmܒc5Gp[>,xX|W[Xc5Gp""FE<|<,]|x\Ò#%Gp[~ݖ,}dn^"E^|ܚ#K:>,-Y>}dnÒ;~7w}[܍,a@Τ ;~a_y;ec7+nϟBB׾ ͵Fg].6нf{2NJH&B*BFM®C).c,})l At"! ѭ ;act/DDB`t9 DFG2F2FQ\=vI 6Br.^)An`7zdpdD!'!f{2;DdCב} z#0e, =e) f ( fK%EH_P/e^F 2BzU T鍞}*q7z> j悋h"dn0bn6gs=8NNi O8D Zs =0 uNH){tp|Sc!2Sc!2Scea|S`>B!|L)zhQ {M42"$j1qTlt?j6zhM4b,cfV!#dQr4ɚ3=dMM{P)mRRW\8ye=ߝ ]=KYࡤG<Lf cNjIL""iI\T dT.E]IGr//_ 7Ҵ'l7y;p쫆X߬[/ sTG+~w_ ›Pz oןܪYM.'u;|˝qw1 ^ծ tWo<BGEz^0g\ 1q2ؕN.Ӷ>P>e ng|ڂRpƀ=|!;:ӧ;lү< .f(pGQ1227%*Q,wy Im< 30-EXb:Ŗ=}A&*"*fF⍊-~KQ\TGE-^|TX ACo<ۿڛ_]Yu'(Kܾw?"]wvBy-E5xR>J˱}0|Öx}AވҮ"қoo_}sv:rM_D?/tѿL6vՑ`>e`jŽj,~wqWo^A?r +۟0~/ұԧGFrN+}]>M/~5pi:!aj5w?]_ǟ_U=\.9{?^Uo>ꐏO,ͲZgp{I$a属F+|^ 6VI5O_o_={q!Vnz)TGEJVu7<gvzp|N?gxrQx ,O|z.꣯n:0\~hONj-n~)bkj'JcM ժ76/p Y |ӐZUn![:þ@mլ0nR~q[Fᗮ2 zQ=?->j_u/r C6˱6ǂȰ]+Ͽ;]Ej6_=2o~x G]mWKNk'?l'_o|_ެO=w_u]y+l/(&Њ;y_^~~_^b{p7ۿ_y{~v?|j{"襞xy@Wϡ@xy<@?z[y2cۿa?}^nG׳}|9ͬ(hu}j [N0 xprwe~ 7bl}+׋v̫Ww@ʭC}wyImfpϮoѓ|{؛bᚻmݞ>B~frB%Z!8_P7<:̀c)^ <pK>ీCpHkwyu xⲵta%"ns ps r: Xk< cC)mhK1䖖 8|7)N1pҘw)%w#$]d1{w)8K'H7e ؕI<߰&͋Nb>*Vx}iHAxCƀcE#x)pbŋC Yhv% 3>*r}Qǁ[uud'~ 4Q1("#yzJ"7QX{KoJT0`W{P4eKVcGEQCFEOFEY>k aCpDEJ25Q1OCp+i RP[<tT4LT4TT4LTԎ╎4u.hfFFEA"*fbFzK>4̖w\TT|GFE"u'/WQbK;jKVu ,^XAo'Q#Q,oN㷴 QU,o)-{MT4Q1("j/*oTli?[:4 )"8>*W,^Ⅰ![:-L7ߡ*/$يB 75WOY2)VOʀ\Rq}0Q5g<`I8=HSw pUS to<N:y,}3&k9pfc%,cp Vzh5NiZ:X_<;f^KQ)^voY !~"QEqzTQ*4s~-K C9rUɡ.+n?:5X:ۏkoKUqg}m.4!ܾ 颀[[ʹ¹78qͥnuK;,Nnrpc]:[cz@pcoC:8{52|Ypݞ>=?=c0mXiX/Z07' >i_8,/bNSZ<lrۧ}Eܼ wq>CnX/j~Q_v7,3{6E3\kMnłͯ.W?~GkW݁\n־okSެ]zO ) ? i>;Wwq [S!N^Ux>krxj(&\֯\i;oq/izx$ w^.`qA.<#; GRtw8>=qq/r4v X'ORL? n~L?܎3qEK*0ST? }׈'{&x4zF= ,O'Kē%y ֈ'kG޼׈x7p5w{Z<N'7 gOe+wVxTQR-p$œ' 8 aZU!OD'PDh+5wO^^XI2Z?[7Y+y$rgaCcϗr\ȷQ@/=ç;{☫9MX+1K+)ɡ[vM ?pCšCzP+☫NՇ.N\Aw/ھ NT[spgZ㭱١Ѓ +b)8 +1Wc +nM'pHܙAmM\j"nv-;&šCur=wpUpjnzPp'5 wuSpjnv!;88Pu+U(8OpUp׃y"܉c5wzP{{s~?|o`x}tW¾_Zoynéy>[׮b11+fP& p~oߢkmn `CSGUoFyd훝66k촱sE+8ۀ Q4YrpiCmnjݴ!i5w^xMkp ʭM•KI8VukߝpԜJӅap=La \Su"4}l'\$Cv-;ֳ},N-=T*&yd; 7}vnzd; wzd; wud; 7}vnv!;г۳۳۳۳۳+Nl'l'l'F^7vnvnv NM\$[vԭg; g; 8Pz=Tvd; 7},N\$܉A;Ipǒ$Cvaqaq8Vu|Kp% $ Nn$܉cv C5/?xy]uD?l0F8) W bȷ;1r@<檁x6Jpq8\i4W\msq8\inuJpq3׃67q=hpnQ7i48Pz=TmsqcmnzN\8ܙM>fCCCQ[X\msqAyݴq8ܙAG8GcbHOh c38Ϊ=3\w(WspC \9\9rp?+!=88Pu+?\=wՃF^7=zpg=Anv-;}8Pz=T=wՃ>^;JEk_뵃gȎ,;^-׬pkp+׺ڏk?jp^;F^73׃7q=?͎?]>փ[z(Jۃ? GwzЃ;;>փz=,=,=G=/n{p)?u?&==Cq:PSЃN\zp==CvAЃ⨛;?F^7=zpg=ɡ[vMCuR=l҅m{pۃwzQDߙ;{g~37 )<Ļןgg}O|<b[p}G\b)u z91W/|zY{_{}#㟿}d~)_ɿI]:<9EeNNšs,.Nzc{w9{=ޝ{=c{=nא{<\˝˝u<\c.1;9rvc.}ӣ9"=LI0ύz]M.xKC4=nMM?:o>X}Gwy<{5<k"ydDHG@<<G@vMq={5<kydȮ)]Sp# 8G@zS>C zz?w).6k}]c^\Ilsu1Wg8M׿ p=epHxk kwF3lMg\-N\1(WɀкסuM's5 Aɀy4 b,K+\NCv-;}Cա1W% |A%XܙM%M}]%=dXš18&VX:檱b,nzPc p#K;}\j,nr!;uc pXCuR=l#X@XH5wzK;Ӻm%Mto%=dX\1W%c pX\1j,sX\1W%nj,K+\j,nzPc pnQ71W%-=CAcK>Vc p#׃K;q=3K>Vc pC١šš[qԭ}1WcKXN|3׃KGܫ??ZC*/os_)\GTW"\suhً\ۧ_i3UoN \WLN>epdʔ)SWLn2E2e p)M}fGݲn}ʔ)-=CALnɔ) |˔)•;wzU;\>VpCЃ[us|vONnW}r \nuSp'' >9&nQc8Pz=TW}r |OA}r'ܙM}rM}]}r=dONC''[ },>9O'' >9F^7 wX|r''Cv-;}r]>pCաJ[p[p#'܉aL7}7;z>9O''\+>1W|rUpONnuSpON>9&7;u>9OšCur=OnX}r\>9μnnX}r=dnQ\W}r \nuSp''ܙA}#'=+?1OO_^镟^镟^+?+?+{zW~zW~z/sOOOe镟^+?<]߄0-O%vݖ۷\?wkm+~<[{/7?O{g }(^.7owX+yy|?>:a0Z6\s -mpzh-mC=vՇDk[\oa~[[qlA[(g=z nqk˥S8Gܿ p:C O\n KN%o4XvIK=ӿMn>+I)י 47o?\t틿/won/_rQ7͕WM݋Ë0؏s磼໏x?eǵw~Wt쯄WD|IJiZ;}q?/k>-F6 Հ4`pwp{ ++A pԀ#;9999999999999999999kj(Zo}p旇mݚf墆G?`~/_n_Ϝ}|%o~'ۇ /ͣ/ų2~;%ګάdя6#;G H5gGz,H Nwe_1H4 6^Žw\ SG`U3U:⸶KNkT<DXk{*R]3^/ O]:-cVkl*嘱gȢXy1i?zްg´zPЏemHD: AR1p3+ܥ8c`=/ 4^[j.o5:  Ux30Ecs3kOg`pFaIq gKqf<g`.Z*8Pn\1 gc2.i‹Әxz"1pz"5-LE8b*\,J؉is \eOE|~ނ৺S&|8-)IJ1?o 8NE+(=l[T@VahoavS  UĖ"v ULU]L^c'^1 8hT35ȉ]p*ԂO[(6إ-VŸ"jAU*R4޸.=.65 UU Uxt0`U1[`P1\*g,7q .}n(1x(ryzK3*BQUQ¸\l.]l(AQv U( 㕠(w .AQUx*z*z*xAap((*JPx%( N%( B%(_O?~o/WA7C}>{x[yׇ 㴻:YKӅ|N5nk֪mkZUjV֪ZZVkj֪ZߺVnn?wo\o0_:ݼǭ?ffPasI^.\szevhV2ųʼ8I+m58eͪGf _ߊգ6jجȷXl1͛޽ t)&zL,}(#1iTsRAڷ6KQw:Ga=t38mEw^x&5;M:nNn0gpvxi&kvvywx%xI`KUϻCU*wx;jBaAUx*z*z*xAcH]:.c0B_`PE~eK=xIq 6-WE:Ht\Ө+5K^$=QET"*Tl0^c.m¥媰VԃTaB϶uܥmp4kT+TkT E6*\:KT*ҹtL(TΥcsVat.si.Z bUy}im쐀TӧOG !_R{MS %=ȷǹ\W@[8sl55'im1/^O)qzT }nV'\Kp #\;EMRuSp"vs?9vc!nЃW+OՄOmÄz =D"T8U3MHg T,T܊% 7/$k.E|v2vSM>vg~ڿnaڨnF8S7f Nc76\L{W5\rEݴs%\p[r=Hp;n^aD ܞ7(zT .wvdzR=NV \G0;Xp[jٹ Q?@^Ø6LX"n!%NJS ᎵA X5|mFn*|Bz ZnTgL~r:\ÔH4%av %C~lPz =D4c6ni ckczH(0=XQ`vncq?NBBBAa[~l#45\iLӃ3\iJniHc}Lz(遻~8Ւj_?/Z8}vJeo%Gp~r$X[\9*Jv~4Kb't$ d YR,Bd!K%]@Ȓ/ dId YRi5 Jڀ%o@AFh#*Q\l]l(Bv m9_,俜յ_.r3p8/I%@ȒF d#$Y2 ,B\!K2%@ȒNOP d(Qh*,X ,iBn(B(B z%@Ƚ»K~FQ11IB6ػiBXD!;y[ly;t!{6Fq dI9Y,YB  !K恐%@Va| d>Uh$ Sh k,5,!KFAFTh"$#(#*Q() Bn,I B]5mmmƂQ%=%?%AAF d`IRSxwISrFITgo_nM?WL4B~|._zsoǿs5#Ȼ2k6S|7]'t 곞'OB'-Nv~.Kр 4Vvyz>؏s!u[x :kF3.^q݊kCgpH{Ba==qkaBC v4Z]qd`~Vd<qV CҞ Քt pUq@`FJcaWl-;~iF{qg{o?=yfcF) ҞAMh=-X߿$S6Gv;6@62"`; U[ S; +^^ pЀamfq+\ڷ[.; Xq׀ef<CޭpR6Ub6ٝ]tnwx-w0_|샧v1vUt&7Vaggw-_fږ'̵cd&w/0IG}ÅP|a;-;ܺí;ܺí;ܺí;ܺ}vgvŽ}lqŋ׶_<1u[u[uܺϭܺϭwv Ŧ|;۴ n n nnp _.o͕ズۺۺۺ_q{ .ۓ 1wa7+??R~etVtXPu+Zu+Zu+Zu+nFZ 'dRӛvq {i3<.{l; -\}W6Rs6q8>qs{,F_u+u[wu[wu[wu[wfطEr9|s\3j}mmmmmݾQ>BB=?41Xu#Z7u#Z7u#Z7;Z]AmZGdw+&{Olk^ wvJ0]~^o//$#4 ^C7Iv+??R6;ズ'{'{'{'{w3B\K~%qQrp4v ιιιι߇K,ٍb=^:uWmAvm ҏu?U~װoꚵv&iwkk6ڳ/^xN.׶d=뿤'zcL`V` 荑h88*hk *d|v ӀZ S5+ Ax^Px^؝ ϋϋ [=`^ض^b|kaǵ8qyf'0Q|"ݦ|g+ڜ ,)F98V (\ڌ<):瑷qqꖗɧax}Y2c? .p1=l(/^÷n׺Kkk~vzވ+㮎{Ng1WrWL>Ð8^ ]\WߜS~iͻغfy'Qɧ%xtאys~wܻkLE;n݇ c%;~3=L)v|2mm'vSp;n^aQ&>CO$9z =Da~R3n)38ef CJ0= C,,_d1/f9SA4qy_|Zr8>wL be\>pӋC>pS!nF8nNϕ y΄kH/hR-)K.;=\S1CR+v=܏cP!(zT)gs6n)e8l26kf uT| uԏsq`=xrpS}x9WC<"nNn\;w6L;5#Xn7cR4z2\zHI)v S֕pP@=B!gl3̏~3Lr= Ӄu\)7f[:Ƕ~23P^^^[P-r?q0=!%ezH9f-dO=ȏSFaj9zO]vuw4m2-̓YC`YIimw>r?<6'xW9aAޛ~>YMFPr];oWzW6NbmW 7,~-/]$zE(OOAAAAAAAY2h;Kn/imi\K0Kz%v%7'7'+znU ݂nq!~vzX!m;g?ܠCP!*lfn7k~l-Cjaz!u0=ؖͶ u܏mzBBBAa[~l#cp=i%Cbzݜv ȏ~ZԞC0n~~]uH\~1K>hZ'OՉN~ݏ/гYpgvrp pGZ|oqcN ԥso^޼69o"j5XS){?Doq:{2Bl˸B8\ԓSxps~+s2mJ5vleC`;B2nmN5N==F p1^0!`FBFA1^T/*\5ܥLpUL[9 g*U9nisir0UuUx*xx¥].FQPEpUxk¥ӠҭUu\}/xJ2܉f/*7̞e#pyitVG7}RM_ 䑋#kGx\?n(YlaZfBw',. q*?'..v\b yz[ `=.fg<=-0<il%V@4@L.{ Xb `6hZD>:]?_zw,cM' [[$#L:el'6E;#WW0άg?f䧿j۫v2 ibqcg6 R%>[/V!sǎө-< pH7vBp]Xh]9_خץ`:/;n)7%#\>Wƒ%#/f܇gWvx(MӂdН4~ZֺӋJ*qecXWxpӷoZy9ݘ7W.L:=.NO ҟ;;]{wNkt^NEt v ]vx# u6^ٿ<5yAsv~QB&m+dZ>wLr,V;}dq4x-N0{-j&@4&7r}qt[mqq\ ņ[xql\9pH[zzA#D.[l3+'Lgrbv ҉qǃI<2AJgzH5nruq?v-׃k\:3b/#ߞCP!*چۭmZ5܏|4ki5x={+Ygk \mZo#zaZDÞ}}fru:Y]е\]qW\qmHzڨ}?^n7py>\>Lj,փǹvK[h꘴-W+++vS))SD5\DU))S75$r=SSAS( "PNAܠCP!*"P>"P>z(cq=))z =Gzv&z(cp=kGu܏GmGz yݤp{ǥp?Zq\lZVr\PF9v+q?.z("vޱTSO\ɏ;xRYԞjKvs;`;\sp<#''(pnAaHxڼ-Nz(jN~\ZTzHcn^aCP!*lfn7k[8 0=yXLe!bzH-nUح~l;ǩe+++v E6r?N-L,6p=o[<@6M'P?N-LiC\8|LJOG(3>kD tg*rV_q>c6Qu9>uG\[G}=ܽ:<7Cʴ'MW懘P6-߃Kp?One.Elm.cLsq`M\H\&L\y{*z*z*xAa1CP&XSF"6\)# U WEʙAEˍХ.[*bU;*bP/ipH.i6[]ky8•7Gr@>Wr@pqk8•z(nu =xݼn8spBACz7nr@r@ZwG-Ipײ\[\Ѓ^9 p{W'7H85\8nڰOo~sa4TmwҞ-Ƥ۲gM)t[\>7EϬ =S[[j;N۵y>"w{|vw޿Քo+B2OӜ xLUh 2Y4ev+eT xL4eWح~\ܠ9?,p4aRqJ\Pq=$mJUv^+z2WAܠ q9,s[W\P\V\ -C9,p;n^a79}p{2&6aGG\+UI+eT% k\JRrX&JUZnRrX&JU\* p;R^a7 RACT!r=2* p RT%z(UIr$$ =xzznAaT%saRT%v+UI$mJUw[zp°`{uir)621`Z0(Y;; szQgs%}Y.gۉD5bװ(tdhK%-}n WJ`p=[ W+q =D"C sK`p%0\PJ`p[n\ n+ qz8$0q sK`p%0r8:%0-C nЃW+&q8BakkquT8n8vԏq =x$0\ W+}n sK`p%0\V+q8\%0C W+&q8BQP\r=8:ܖۭ~\z = = =݂nq sK`|[kJ`p-[ ~\r=_]8F>;P-]tTQioq]Yr=n9wo/6%^lx\+oYGXM9m;]M{,7]L> 6.r'Շf5H\v ͲVh[ias-y~2W-y~y~•˟ٸ-lYGG\&]p|D_q|D{\&L>G\&L>"`|VG,^\&p|2eL>1عpM8be1:`l;)m)ogx8톽$% $rd2:% -CI&qKśoѭY*T/J~y -~Y"%J]]G Q&x"66El]~Q$6g Xr\ˋ{*z*z*xAaɼP&8}pl WE4 UDUxrEpKVrUN)T5Ɠ .!6UH Fd 4<<bg`U1p7p]zj`QWרW"hƋإì)Uao0"ܠK7qN!7 rUTyzKt QU*F"ޠlÍ"oХ.BoPrUTu\)g[:Kێt QUx*z*z*xAapiKTk*R " 0U8aIQ8j<#,) G]:*\KU1ݿX^a__θ?嚫Ζ_-Y V~Wrֶ:yxϝSc> 1]Xm\ǵqǧA"n:5"nEڀ7[mM=⚑k75yĵHۥk5ۺo>6W4 I5Msɖp;G\\RrRr2pe6lv +D7(z =D{ s -Z2wpC-[2wpo(;h/g+q3 WѢUfm+2Hpv•Im\s-5a.s}f+\3YE?K?`ڿϵ-\+\+\kJ?J?J?+J?v\ pn^a7\)6ܠCP!*\{y BT:uT2mU&Q?W+ \+\+\+\+\+\ϵ-\+\[j?ל[j?ל[j?ל[~7\~.$qB= uQc%LkOE` 0y`o[{+=J`p%\ nV{+=zB^ nPMz+q}nsK\p%r:%-CnЃW+&q=Ba4nZy\p<ny\p?^=+=uswxy_>TLƙ/n^?mD_oyuxB.R|lw\3 ,?Olpc 4Bni`׵঑8*7?7'^īVsSrۗ爚xe)gӂtYqe7}v?9_wrW=e+iqA Prx[]6ʏ5ӰV~~{i̙ iߦy;m?`<6"K?`⾥ ; 9 P$79iRVuVMmw7z˕:l}+CܱÆsEcs ɝF\p=8p=8,[:0q\2n7v!~ =wR%^Ao[d+MsST$mneɞwr^r: +'hptMsK7>tCtC[:tCnV+ot-nP-(vn t\I :~K >.@~K ξĭ}[;W;jg߂[;@[j[n=mQEփ@[j[n=mQEƾEƾOkcߌ[>}3nm6͸Nc_l:/T kL/z4;əӂvqMH}rb4"}QCr~K nʫ/j&CwX÷%7ՍyMu!9EM+wd]n*\Yr}cX]rǜ+ӯMX妺\YsKj[rV+9+J p%gN nPrVv I p%gn݇i6i 7=򷔳2yNpG3nI\󩉃=SjQKms5 upG[oqB^îW!tvKt>7嬘J pMCϕl7ǀ+9+mWrVe=WMN\YnpS]YmqS]Yr9=Fjko䬶a#guT9-nKJp{ 6?>p%<5 P9 H9 9-w-ŕ倶jh+9 ]mq%k9-n~Fr@ܒ怶jhkVs@[\n9-nx5 =倶Bk9-nPm-ō܏Ws@ܒ怶a5ŵn9-~\9Un<}V4k`xnЧ~N?vNC3FiM7/ꗶ&0\8>w3ˁ@akv4_hnppnpnpt+;Ͽݿ}&e9&|d.vHRפ/2b_Yӱ J(v\#lt3OHk#6\^qϤ#p#p#p#x59[lbW:p=Ncnpp[i =4~tnpܒqkY2+#ܒq%ǭxG\D^a7DW"cz =D"CsKd p \P"cJd p[n܎qW+++v E%2-}nz(1n%2qnP"c{ܳ(—ws8_w=xxPƗ\\5+׊,AЃrs}n7o{# k/aqRsμ]X"Ox>DNu\Vsϝ2 p1o0:q0?v =xݼn=^ =B\k\k|.u\e>ne>v^sW+ WAsnPMsn~\ze>J=h26yfzglW26+ Jf[26ܒ\dlr Jp%c-CnP26v Ip%cACT!r=>dlp?.\%cdlv+ zBBBAa[~\26ܒ疌 \V26 \%c=<=p?.A=\%v+A=zBBBAa[~\z疠\Vz\%-A<|} -a;4nW]TgK+kw-v%>/ .@ Jp%\DW"+@ zB^nPM"+}nsKp%Dr :%-CnЃW+&@ BqE%j #~z@Pe#k@uT ԏ@ײZWVղZW.rkY{]WnQ4/~=9ʴ໵_>{R2oG.]i_ `Gp)zm<^qzLσo}?cJGXnTj0-cC񯏛nW\?G|N %ڇ?Þ,M/_^?;? _?Jva h:l󮁀4Vn5N4`{ W{ 8(A pTۆ=]7Z4`] oEZK+\ڷ[.rk}Rp1^ewDc/%jobm"[n\İ8x.xHڥ!=:=ݶo/یNSgYEnan nBIDXWg'rsx+>n5(sW&.XWU98m>|RLmYkvmEmˬg.O| GǢl.O2pCr*3T WP\vC#psp%z9zAB^a7[^D/7(z F^̹aibmk^PJbƍK_2%Ӻ3c.³os"3DεgWIg9ן!r.@C\ȹeӉȹ BRVaADC\ȭBRȝBR^cA`HC^RAFژեgilwJbm̊am!r{V^ FRC\ȹN s"J5DbBZ5Bb5Dj*,(k+9!rІ!rІ!Xk,+9!rh#h5ڈ mH!K"wK "[6 BRƆȭ‚RȆȝ» F^^^`X0*[JYjY(!eml6Dv 6Dnڐ}{Ͽӟo_˛ UsV!O^ݲ}; nkr>}Y"m~Xlq$d)Nx7(Wn/$ot] kqZa-6j#kqQÃǵ>Awl(>zp z8yq0+W\oM>sM>sM>_sM>ϚdV0Oր$kW5+d Jf[5ܒ\I$krd Jp%Y-CInP5v Ip%YACT!r=d>$kp?.\%Y$kv+d zBBBAa[~\5ܒd \V5d \%Y-ɚ˛yPL]"_3u;\״໴o]5ƇWJqz(8q=R yOR =B로-8kR\pC)ܖۭnW+++v Eǥg[R5\p-[)\nPJqy=[wpk">փ;%_wփ;zp"ϭwփ;O|.փ;\ws ܹիw9':4Ku" ui>pE>w[`9':4Ku" ?n~n1ګnfFƧq˿ٰ6MWJ$gvyk<ǜ7, 8vӎk8u:x|\~ǵ wV˔`* 8vž%o+! p3!~|0ka,x 6-xx~ͅ_{>q@~|xxs{w>hZtaR~rQwnl,R1;{^?oU{{kakoF?Yoy>7ߴR=Q=Uح6 \ЃvD `. ͧǩ.q=r#u[\Xn=raQȅE]>^ÛC\—/˿BQy_I!洲aE\=JuX}n^H0,wϯWt żǝ1q_̀+_̀+_̀k_̀_̀RͿWW+z/f/f ">4\z0c݌v3q܏M`Zq=NWح~lz&(z =Dpنp?Zz-mvێ =xzznAaFǮzp ׃3\{aBvsm[A~cr=|1ܽfIX"oOqW.8m/ {" SXMcNKtnZ.qKۅQuip^m&r'o3qf4zf m2zR29vZ$Enk 84^Z'oAs4[1޿0kA4qN0O ;E}Х3H[dDWfdpey[;2qʼ߶:q+:+W=nm\={\{P=zۭ{\{\P=nV=nǟ}e#zB2p{R}q2p Cۭ{\{ܖ{NױRy:p~\:ZGZ=ZY=Z[=־Q:j_ǂ[:j_ǜ[:j_ǜuŅO]˹Oq.3>S|ʢ@;}N;'R=nHPw"[f`߉ԏK7Nz( ;t3Dl7sw3Dǥ}'b=D"Cf`߉n}'R?. ;t3D: ;WW!(nHt3DJ7Nv+ ;qf`߉L7/?#ֿh+ڳsS٨+36)Lu]9|sa8mkis.f]! KRj=[\3Պ7Kr//•/5_+&5_)v /•/ =BAj|~\jr=/u\k;ˏ͹q1Ri s s s s s s%QFȒ)C*C+CdІd)!2Dn"""{6FFFAc`TxYg,3D6 mH ‚ACdnɡ!rІdɳϣ'o~ٞsio{BЫk?8nrY&mpSޙ/S]ۿnl-`5_Z5_Z5_ƭҚ/n͗|i͗|i͗^1b/7祻]KC]_p8$lp夸䮳Oų _;#K1!K1!K1!K1 c@.]DŽ,mDŽ,}DŽl,DŽ,DŽ,DŽ*Q ShXk,(BX !6FQ1B^ m yЄ-Tz(,kJ5 :ǥp[Rɲǝyx0N5W8Qo:j8QO:j&ꨉO:j&:jB>먉Oſ߾^WCnn:u %Q{%9ȑFC92a r/#tx%o^Vpx/[ ./O}pO0J+9.8]qL$c&/Un<'S 9v&pڨ4gϪ`R*"{C2XʈxܗM`#ih{2X*O.x)> Wj8}$ "E*J5srt_s\0.dm1P̂'|vz4[ܘ? JR˝\mfpe& y[\;rcOAwvn˰~~Ē~yms>v#]oh+p->nrpS/T@ܘgsBs]{WzW2vs-lA-mq=9(P^a7[=D4Ţ #pBQgCsۆۭ v{ p^q Yc[re{ e a7 ٿX[ \Pf2p$NA$v$z, =H> $k$k u\e ne v܏  =xzzn2p#2d[fz(3Hr$z(Mz(M+v&z =D"CP|ϗ&/Mr=&lU|ϗ&/M+z{&9n#_ޟB6*(Rh J_F1Q3!iOv tuiP:3Օ?D6AHAa7m#ǹIk6\kv˵MyknknЃW+&w8_XܠèHP^Xkq kk<.kz(/z(/nGV^XܞzBRp%)p JNJm67$ JFJmn J>Jmrmrm yݤ Jm =FF\ۤ͵MykzȵMq=&q&ykW+0(0(v |&mnm&krmn :>smrm,7>=m}am&4|.{VGׯosgp̴N;=vN;c'{d챓=vrN;c'{:w챓=vNufꑓĺ>_`{fhX}K&VN2@Y4 {[~bG-VX}R {>owܣT@XyX @)<{Tx^}`檪 ǝߣwsֻQq]Wk}pptIYG K^!r {ߞ"6ϾoQĞŷgY|=o۳,=:w۳,=oݳ,=o۳s,,ۿxW/Kлg-W2V `7DhѼ;wGhͻyw4Ѽ;wG6ww4Ѽ;wGhs4b{c}8Z2Ǵn3g`n<q:m)䵝,cϟμ&{xaK?z7ƞ{O?HV!V4`s__}_}ȕrrM儛R 7nJ-'ܔZN)pSj9&?rz yݒǟpǟpBAQA<+5|ǟp-׃x q=ǿ5=}&oxeO|xy| =Ur  r r  r r  r r  r r  r Yblڐp"[%`)bȝB3@^  Xk,<(f9h1j1bm6 (b6("w؂E{SF`*W< xP 8pp$q[#OY{]jC+%WʭUnM3wߖK\-r;U"kss;w+rw+WJ܎!^WMn$HܠCPaTaz7|#p F"Z|#pC[=_D =xF" =ȍD ɍD<7|#pF"|#p-[|#p;|#p{n^a7F"FFFb[H\Cqy#p-Cy#pCy#p;jF"t7+z+7Wn$H\r#7|#1\rl>>(o5Ըr#pF"ʍD+7Wn$H\^a7H\Aèo$F"ʍDkDu\F"vnF"|z = = =݂n#Fbo$F"|#p-[|#p;|#<~qÕ@H4Wz=B@=B@1-! oimx@J p%\ BW!+@J pGF2>X@J p% z(!Q<.!z = !$Bww@=B@!{ d@/W7^|5=rc!{,d챐=BX c!׹U,d_ _ c!׹{,d챐=BsX c!{,&Z!aBh]LAf(~o<@y wHMV*qĽßAa+a;/"(vzȇUu\ [>nq>W+0(0(v |jmn>zȇUn |X܎!V[\9~ysws͉s'ˀx2|*0^Pd쇫gۻ+ 0MzC~zUF^quw9v7)ӤcɓerZrsǭRnSnWRnWRnWRnWRnWRnWRnWRnWRnWRn+zz I JMSnܜrr!v)7<)7q=9VRn_ҋ9\bx1W+^L/&}'\?|2eM=^LTpCnn5x1W+^Lt)7+)7+)7+)7+)7+)7mnbً \bv^L/&p;ܞ!{1+v/&pBAQ!{1\qbz^Lu\ً [bnqbW+0(0(v |g/fmnbz^Lnً ܎!{1[cp5O;v0\2rKV? 0 nWM_vÛo޾/j:xT}Ŵ3;8`r'oÍrdmqu \qnW\+[+pu [7#~u[ Wݖ:POu[ pu[Znu[:nk܎w?\-]jy\Zt5kf>w_MŮx63壝EPw~xphlGs7mђ.I4vܝ>DvɔhKdοil*w|ϓ <* p@_' ΍mWa:NpIџ1&\q4>wB˪;̙qDV.ŏ ԯ/.%}5% D%en y`Y Xh"/,K4 K4%W %U,-p^J߾g?\YJ[6{4mv:z)+&~v:Cr̄Y;(Ne@yW'O\R?p~"JD+W'9܀+܀+܀kr27:܎-G8G+zdnz$"#9"JrDp Cv{Iܽ*p^R^?qO'{U2^?qO'{sgOw={⍲C?lfrk$׵|vwuuZunw]vwunr׽?*JUa/|03RpFhuRxpeEq}q?ϊufh4DcnmKֻnoVq=Lcz y݆C n|p~k޾8Y@C١,= hY@{ОgY@׹{?' = hڳ,= :wڳ,= ( nU?_^~vZg.@ZX<x^!eg]?ԳM>tPø]i IlQ}ݜ-Nfő^fő-c`VYJ`VYʂQe"ͼn:K'vBn1 /y_mpܒ'Ο-c)CxkCr"1^Hm1ePnWcXdIC ]^KY}$,G9O (Q7vg ^xwg {y!.JxЉC='Nz;9=I277=}}W]hs5L:X^(\"a=8v?cF'ܼ x^y_zng7Rt.˱)+um=Vۺ*•lAshrslA•lAMق+ق W7,iMR(,DSh+Ynpsz @ܑ7@hs%ps:%N !Sz销qtJ)+zH锄;() 7() wX)7SnJ$\ 锄k$pǒNI׃SnЃW+) wX) 7(0*0R=MnN 2p-CN L܎ڭLܞ2pB^AA[Pm8Sy\SnNܔNIN )p%pS:%J:%tJ•tJM锄+a* yR:%J:%BB#׃SnN\qN\)q=tJr:%|tJ =xnAaNJ:%tJ5\9p-[N\qN܎!SQ?"eNL ީ; xԞ{Ne2\֑ۛdHv]v8?y_y6eEO>insڊ{fU!(Kưw !lHkI <*0J_FF ^N)rrg[{}+y_%20HCk$>` ]lIJ`D.%D\@.A#`}*G^a<1ް8]66 U U'7^3 lQL`*bTEp\1"tx1׀S:&)P^XMW F>sJ0ǔ`qތFvrU3ٔ^2bF01N㪈YPcU1  |B!e.Tr"e )]&`KU*b[SRE?`S:PtJ4cVBFNi7)BؔYX&`lOlM%Sǔb`kkmrp:A&b׊il$^)g 46 tl W7k*U: 74h^[ݬWkT1(T1hT |JQ1ck wP"apF92 lJ;ұ=S*"Z=ZXmth; kԡ;vՓ΢Sُp=Ӆiv-U5JϸnIre`(RM3&*|b ).epw)Ejt\]~]QV=6fvgbW sth zq[ཥCЬ4- `UKCTb\b5,+t`0Q vF^ py( xЀPhǴg^  GU!8,mOS') hJx13 8٫4 U2G <*ylO }PUPgEX1jU:>Sv\WWLi^AAPEoToTLiwS:0pb:T,G4sx9ҮSuXË_jnWsñ10\ˀG)[Wv5G{dC <':91rwH2cҗ|('_TgC\Tg+.%% O% ا!I<$UPE/(7':) xL U{*br/Th*br/4hbr/ңS:&BUWEL{*xRU Ŕe8hT!uxԨB ) S,--,.6^Y] {Sx/ClI3EJדIYUٓe좒v#9WAʵVvr+;95II&Une̴=m{g>VWO;_g}ܐ.BӎWh}6`N1pcoea'֩lF:nlCp-[l Jgrgrg yRg•6z = =\psg5|6krgu\ vn |6z = = =݂n#ǹM+m7w\;v˝my;n;۴9t槛Mwñ֡%/7NdMfaEdYVyJz=n.n|Ґ\mI#nqnr7 W+n|Mn|7>&7> = {fq6qOG|`yG;'=!'?"KG{BND\,] 99Yrrrl@dmOFݞ‚=!0"w mH {6$^cA'A1s{BmmXe&  (6"w؂Ep{<"{6F)B)D)F)H)J)L@' d  r r  UXP)!Dڐ"{Ƃ)j)lAƨƨІYl[lڐ";6$ȝ‚D@^1%^ ƠƠFX0h,8*fY ,D6 mHH‚T@dV@N ,9n޼|ϿԫOn5U4{:o˻2pY&L<ƹܺXye?Ic9Fҵq I\Iܹa.䎩irc);&0qۜMMݗ΍(b&}(=W9̡ܹC&gz = = =݂nVlqcgk;Mv+p6gq=8\:_sM67DhssM5\&Zn\pǹ&v\&B[~rM5🚴n+?on~xqo?|Õ?791ye[<jU UH-T|r[L0KLǠS!q7$.~1wwL67~lFImngCgImܫerŏeǛW. Mt?1/?qg/}GDv??J7=bddžyl_˷^?  i' ~ޓ?J%xWZO0c+m6wpŻ \nxWۀ+m6wpŻ B#CnqK6R\KPzQ=mJ6tm =xĻ \nxWۀ+67{\nxre6wpŻ Cnnۀv wpŻ Aèmnn8{r=d6:܎-{8{+zzz F>w67{p=d6Zn\qnn-ny ˋ>pw`,+>idj>  :\֝cWN3ϰ)\)\)\qz~~~~W_x Aa~~9͹߀k|˹߀kr7: [ܞ ^Ѓ~Ѓ~nPMRw8~9p%p CN\햝s67;p=d8Zn\qvn-nv7wդaL\-Ff}04o&_b2=:9l<I!6Iv4~E oxZrѯv.)ER pS/•_ W~n*ER pS4J/(햳ƀ{c%k܎-4NhW+ ]wPAznPM:qঀp-[p;p{n^a7ǹFF_[4y\4R= uTe@p;j2=e@pB^AA[Pm84<.9)A\\\\\WM:47(zzr674ykr@pChnyz = = =݂n#9~|mnhz n9܎!4Zи{s_7]t+3߫ff(̬\? 5nQ=]סL={;\: T1(-vcup]\sw2uycen.@ \1=́27u()@}1ncqƸS`u;AlY!9G^nO9 q=8 +v nH:ܠèØ!tnͻ\~ <:6FR~7C.?>vkhqY?oټp=npk"w\ם p;npu'w\q.sAqЃ8\>yzq=npqnpyW+0(0(vSs78%p%pC#܎-nq#\ЃЃnPMא<•<Ppp=<n9p9p;G=C# xB<{!w/ij# xB<{!w/ij#-C/<V^y-ؐB<{!^g B<{!o7?i~y/jk~d3N0LYjtݝuwNN;]wtݝuwN;]7_ۻۿ Gί\a^ Kyy/=.Aپ'46.J|ָRV=>=4nNer\J*ba.=]l| p,0RR+W>71Rk\햯\C=C^a7\AèЃmss)67_\߯+WB+NW(nPu(i(N-_Q\ם|E p;|E p{|E pn^a|E pBAQ!:mssp 9Z!Gq=h9vn9Z=9Z^Ѓ:A)u Aa7)u #ǹi+Np=RkrSu|Rq=R+v IS<ΥN7(0*0R=N[2Z2Zꡌz(Qr<.zhy\X:\:\:\i+NWkrp)Jp;-ܞ!G+vR+r =FF\r5|h9Z-\qh9|h9zBBBAaqikrp-[8GzW͛`Mw\ˣi&~C\w)Ǯ7tgGj##ps6W+79 Wjnr'X'ܩQAB^a7'ܠCPaTaz\qXkđOA{جR/>!}r,'>=P"{Dr< %ܕ#@r[G2r/@d1GF|g‚!;$rІWhC5 9B;ߟ#ƨƈQޡk"<"["4k r-Xdz hk!79 Yr  ܪ#( |%TrS‚.@d]G)`ȝB2@^  Xk,(99h45wYl[lڐ";6$ȝ‚F@^1%^ ƠƠFX0h,8*f9߿d ) QhC l";"w mHhMα^%&8.O͊6~v3(P~3> .Ǯ.3:_E"Hٺl?\J62ne#׸ [5d#V6r+Ȁ\J62ne#׸^lWw+ƕldFq%p+ܜnf#׸ [5vFq%pk܎a36k\V6r+Ȁ\kQlMnVk\Cq%ƵTlQ=Tk܎ڭ\tWk\ЃWAWWWWw(nܜ -g#d#d#nzȀv I62J62BB#CFnss62>s62Z !g#n햳8g#W+0(0(v |l67g#9p CF\햳yz-ݽy4||/Jwᔲr^<9紵F?~T&u& "mi{fhog*cf1O}3{'%x+ݮ6|cW4- N齷gwoo^ipOs19]~I5tɓ?n~7ʟƑGj?9rtelcRh ukqGL^ C"d0!TZ AY2L٤#B3Mc<#]Zc9-#w m q_jh#L{ Γ3r*!} 9h1j1* ‚SLϮ`l;̻T֍%Ǵ9gw AmNai,+fw;x6b1S &l(j`sf l*RQEJánfGU!Y8y{A 1c5;jwT#9FPs~A 1c5;jw#9FP{~A 1c5;jw#9FPs~A1c5;jw#ۛxە~bֵz1{5?7H< .MM8=m4;~NoVx̕e8\͵ UpNM75nZ˱5nGMi1'\xg7;,MK9ԄVrMwquuLyklMc2''3XnrKfM.uvҎh&^cws~qzYz @[tfnrţԢ/3eFAy@EOfuTEGfݖ?T7Xhݱ[י+tsth|ᓱ~a?Y yF?6vc'k5` xЀ N,Swr~I9!TwSyW \00p*<cdxg!|}@I!Wjxc@m{,Ì/)'sY͔58C`$㰤NpPLXX \'o~ws>o~7( zO[n~Zrrz(7?Qw~7o۟Ursz6G_}|eY i*zmKVFF APB^(fHh;h?$h#Jh%4%4 mF m6H}ybןEde_em_eDz͏/R_.]Ua–nN7W2uE|=w,Wn/វ:[q݆qj\1^7TZ!5WVpe\YeW%p.Uy}isfxX\ju\d\:))+^  nPp;*#F7&7&}72͸xIiM:L3.oEi-eA.o)upkAfdv8n ?g`#h˞+XÕ՝o}2 2ٗr:˫? ^rG*ՠ 4N6vUr񬢷vu޳|[*zkYGo@-h 7wU>6 Xm6J"MՑ][}[%1x Jpy^8YKWk6+{[+KW,] Z+A\v%`J@ҕ+KWvXeWʮ,] Xר+T1hT1(T4 xJ] `sP*rW6\+[nܕҹ+w\+TiOΐ+aH3L lSur~=ݼ6a?/caE_~w%1({\Mذ~uvmUp\v \=r5pf6ʽlkـ+Wd\ rͷ|p͆jsPuW?ء 8_M`܎k'_ܞkgϿmc-Ym/+.{YieY.6J7 =xnAa5kׄkl]G.z]v/nV3qvVSbN8 f̓/3k`Tk౪֖WOemj yu 8(fUYa^ MuvTg7K_PŨQUa5ٹOH"O'k[;*:S|J/}*BFBAc0ިK_4fbT~GX" oiΦMiiEX_p- %`֚4xyBF5h4jўШGQFm'4.hԫ=QvAv ulOhԲ]Шif]mOhԸ]sjŪGf%>W'4E6ȠiempB;&;OiFgegmmc5ݸU /7$?~]rwG>|WٔӇMc=y7onս;";Lu}.c?]Ykȟ~_|Gӳy|;t6jӯذ}YMo^bz?|X\/t?}hIΔ+߰ g? 4oX3Bo4֭euh>#Fc:ZX3Bo4֭F}&h1V:Zv+4 [Glʭʌ^cA3%uJ!+$ l}(#:^mA6vd h^AENz]'@At2eIu0alڧGв}F!=!/N5vzL j"BۃŒ\^M_m5 V% *$P ƌӘ12tI*xBBBʌAcQ315* YӠBQ(YU9DwN1ї5aȉv`?sC:Ǿ;aŨ;ͯ{ Oرq*Dtp Ngi"x>6-[ʁ7&!ciD9vKōgbZͶY5Hۻ>Oyruܿz"VD)u>-}\JncW-_DC|-fJibi .kPJ&#d'7?PMSDSyɰ$M2 'ϑo:Yta@@ice,BW2s%pm':25yAD7-pp?(-l`[iN4N5^_rxЀ9qq}* ÜNum=}<ƍVpO%$ۧjmndȍ"CL6"y8>-ӄ w^0[=|-'"yj+NcCYjkSTm{^G3 w^+g͔ cjLɰ~b? GƓ#hl*~#x@>0pϧT@`PŠQŠPEOS3U{RT@`ˍ'*)-*XjUU~/N;ؚ$p W{mq xq==8Gh{mhWmG4n=@5t{:@w㗷}v{m {=۴XWRzFZz8E Ro $[Z^ =_!=C/_Uhqa&S'Zѝ yy#K'$1ݹOrXԙa?cŴ l_T'n>pt4Z[768#qq p%}%Dt`zW ~^65 `8D 8~ qUqe4xZ{_f`yMi<,.hU, <ǃU c`4AU4;*N*|0'ߓS:CCa#pX<*>~\<<o8*U1Xˍ7<8AtaeDWWkƛK0w˕J83Ha>uۨA3/28b8y_7_cН -=Z#4&hi7BKo- Z#4so6m5f̍ Z#4&W[ W[ h2טqLJ!+l=6e槠l7BKo]#蚠E-&hi>{˛s/o =e/o!e/oR&˛f^m5 ɽ i{yt1cMнf˽ ګ5 T 4 *3GDϽ:&˛F!7A[s/ov{ytQx~7ݯNEاt!kHՐ^ }kq_틒 mUhA;iН m죪h17vUo촫h1 Ӯǀac]EǍv } } m6rP ZbŲV[ƹ%(l 6 ! N#qVE9[*kVQ5|׃fU%m J!!GQ1Ԯ1@+pjXVtoҲ )$@ 7 RH"ndyŒ=ZōB5 T 4 *3G>ѥr* 1B.w}47ˆ߿}UrzOWrii_HuXw>q3rq3F9--NNuu=ݠywR X YEXX6fn 8&Y"IT9qT7.KJN%И]͔fޒ x\*9$)Q:9pfI{A`Sn9 UXDc2T:6K.4+an*Ñw<%CH-Nrl-hJ"wRk-d((A%bmn=gEJ9O-tjR5p81lK#pL-4=KifK_r9rҋ+1d6WN78,5N7x\i<&7 Z`YX} 6ܡ|\<5K~P4H>P5HPR」W? 8?XŪ(|* 'wxߓ{< 'ZCUHͯx؝$d+.38|S]%"X<ŋpy7旛}f<կlS&l??_KT{<ͳzGB~xxՋMz}npزc}8k4E@{)Zb XXU/f-\h\MbD?-.j4(Ov籄 'OX0znAac;y,0w!=H% 5\Rp- \ ܎!:?r+֯!HqXoKm,!9g]D!^޼16*bXx|ϸcELc_a_xI\c#? NyK VSݩRch hRcBK -56Zjl \cs 6 U1ꪐkl9RcAw9kkl׬ AU! R QD56A*56r56q56f,klt'zYcJ!^AA2cИqйFkWh~ͯ]ڙ?~V2lYð)c(S眔ot!pFX~h8$// }u[jత3!pJu!q HI!_xPSHG{X+Ė cwH2c+o^|o3GsqB4c;bBYMrX? ʼne:23GN!0/2?=Kg?Zn^rp#d29W?KVwz|<{t~rgONGNN $U: uLhIPrrVh=tلDrrBh99ZNN-''A DDfC!C-eytmUS9Vc|r"?QNN-''F)ONk5B>9YɉJ!rr"Q995ɩ.ONmPr''v\!ɉ;n0D=aQAA{BPAAƌ#aaa,yȿyuݧojDt(Yro,;?ڢW҉O[{{}yoaGy<'5t/^-+;5^]cOUk/`\o~xy{cB5[rwa9X^<_<;) [)$ 4 .,4 K5A4c {ԱG;A6:Ѱ)l䬁Y\NοܾM7t.̭|o0yb#7ﺍobe_/~iK]^rj —x𙁁Rfϰ'NEg8n.eRΠ'yGO<,Y8ثK K R#̀fUܽG`GL߶8.; qP+7(4 QEPbԨb䪈&̈K@c&?ϾԵo ޿7xorsW|p+b_˃RDzoW\|{"9eep9ظ"]*?ZX*ՠ 4NkWqZr6\%瀠%%瀠%%瀠%%瀠%%sA6 HIdk_KIKh־V 69'JBKAw95r95B9 A**HA*g 9h˜6|U(sr9Bʜ˜D/sګ5 T 4 *3G>˜9n='4KAaƢ~ݼ7itQ3s˱Ec7]|w)xF^h#h#/hOh4'4 mm6 mmm6 6`nsOhrDƍ9: 鮬hZ-zN~=Bm?BKӶӶGn@]l:m:mr~v\!Ŷ;nbۏ=ŶJ!^AA2cИqAm69n"\ns??Oc^_|~-~p o4xڪVv*Ӡ;Zc*{ 'd ZRd z SXВ$KЁĂd˕#Y=-ׂΙSe l(ݟekBVc[K~#˶>^hh/hOh4'4 v vF;MwMw vF;F;xA|B>^hh/hOh4'4 v vF;v v vi0σͫ=IO/`#fsz =ӿ*7_|OlOleƵ::Spոg6[Wj\ٰ֍Wv뀻uƕ:ngqe1঱q[U\̡lnޢmW+ y9x{o5lw[+rݺV l]zqe?[wj\ٌ֕Wv;* ܅p p-C\GPnv+ݭu'n}|yww_{yI (?ft~ӓTݪ3(!IIVcR]51~늘$TMixzm8?l6p#=W3ahKqa [(vu3Հl+ԟnv2#gexfKfiΕzfﴹf7\1^Qϭußx(߰Nj'bi?j?E6Ln5Pݤ44 MEhh*BACS*PT"44 MEhh*BACS*PT"hl*BAcS PT"tqcS PT"T44 ME(hh*BECS ˩KFT%r:d]%Cz,y%d]%Cz,AcKFX26BcJX%Cz,A{BD!A QH1J̘pG%v,A&n(䴸V79ar<7~#i.g7AxE% ^~ՉY}16,>o%hͅƙr媡AEC郂 e J!T4D(h(PPDBECr  e J'T4PXFBASI֏o_Gûز͸=N1$c^$/ py_rA^QC{`s}6m%47HחHכVAܸq ĭCUnjQ!wW_K;\9:n޷F,f[>Ywka҇=9nEybIsok6Nz>z>_f\9:}WZvW {ᗿ?D%J G_et.H?mpGn\op%{1\';9% NnPin~\#ZFa_/ pp( %WokT݁\/5s V7 ??s\n-t}ATCS AקZVhgUAc] j[eYٷ\oNTk#/r`|7 r`7 Zʞs |05 SdY05S-_Y05S _Y053^i03S^Y05S^Y05S^Y05Sm^Yݾ+&G#\z=Ӻuw򯨵_|GGO?wKhr]^}Y ϛ7|/^-9FpS }dj-3"E@Ki 2^S9؎dZB6l%d'!; |P (!G 9I &7'rb>W'ry1~͸8'[}`^_s\s\3=狑"!K$zVZpg%ѳY'K$zV;%/3Nɋk)y1NS䝢%>%>%-yhjj;EK)ZZK^B=o&{HރFFF41%AK?񙡵E߂[;|U}~cjmvdb[!r ԴJ5OOf Cl5\p~ 5c߸^pq|3)'-rݤ?!7-\Õw ez(\Aܭ9ĩq7'R'µ{A>0 PANKq~2R܇U'z޵ #j R n tOܜVq7-a[N(#rBn@ܴ n[^2p׵؂ ZEpk n޲@srumd7mvskz=nQ`N}Hf!=aCvg.Bvcɇ`,=;.\3Xycݢ}=f ^E[3 /__A]ѻoP\:9ڄaoͫ7>ig,o52eNu]pw)}u[ps|7\:}.a-{Lwt3`ۉ5H_'q[>Oq}Nf\-jFnmc,-nm`pk2[ڼ ev.o٘ږiUNG@96U2O\נqneonmUp-֧ :\;Q&qon} 4јG+BZGc%fDbm% h'QդG{ČAOѩ7VHX#ѵ#Z@.7ArC )7AW]Ck]u /O>]g$7A9ҥ1˞c J0+GG1t!]B03L:VKch-PHͧch#PHMch+1<#sث&1($$ "3Fcs$;a yv  v fv m^n_ow#|~#|~Ϗ>?G#|~Ϗ>? ܝ[tM}A;+jq]r₵w9?|_\U*9C9=s=s=s=Т{TKܼKww^o=ο#Ӗi֞>{wQxgÝ9[ۥqn_"{~WIKh-Bk ڈF"t,h"Oz}fAy%< tAD~ h"Oz]D4'KAy銦IS}Ÿۗ tADR D%UoDNDR~ h"z]D4T_":RDKdDŸ ָB/mp_"fDA^/QH)$HEf3&/ݾDtABᏋ?{H3E>ֶ?5p6\6@kZKF6&>&Vv&BM!]30fl]v/F買'PjTve"qG to#K&:?j˃B`EЩ!t*V#JahAkɽvZp`8,ѦY9Ȍ^bPB:% I"$B"1_fj,7* % Zo$ Fo%fVbF'qt p5ӯݗeuv't,rб A"'4dq#:.{rB=LB=WKC. ;v4cWm%fB]0($$ :J̘3N{AED!{SH3&}2c[]ѿ7tJ7LMV&S؛ TvE ڟ`~O*A yb^DE'B5] ( ChE|ϳh+15FRƐk4d 8H!^ RH($%fL 25 *d!c ٓȠBrT3*-02GWFJצb E QN/21H='AGqX!Q$RH(D/38hF$㠣"@h-P>(T6h+1cNftGNڋ% "BȌQb$q\-:Y$ 1@!FI @-1c.Dhэ8*H[+fóީtN}Vj/"Iŷ2ɾvkk9!4[wPnYn(*[,x] pC抣qd̍ nvB\U^WzC4-nhvsGq=xB0 C,9 vK%pi) 17-*Ap=$-inɔ 5'!Y\zHN/حV܀q=D@ CbvW~GqFЇpAoEoC\/Ѓ!@!ln>>r6_9X =Zin_ U4nUw@ЪMzXórtvR* pzH=$\Y%nzckqbzCa0=(,mp=,f7mvskqz=@Q`([X'܏sӃYp=h+p=P+f7q8+~l,cQ=z/3` s]@rSm[唣o!uq($GpT``*tς,S{lNEY<^"Zz ok%u T$U$Gj%Nz:p[`%PE+Z`Vj RK|T% >Y`̒,y0Udɂ5<*d KLXs}%+Y𹺒3ŕ4Ti% >WV`*y0UVɂU<*dJLTsE% *Y𹞒S,\MɃbJ|T)% >WR`u<*d*JLQs %J(Y𹂒S,\?ɃI|T$ >N`t+'y0U8ɂu<*dILMr`fS%,\1ɃI|T$ >WK`Xk%y0U*ɂϕ<*d:ILIs$$YFS%,\!ɂILG`<#y0a!k#y0a!+#y0Uɂu ᏿{xv=O毴qv'gW<ڧep>\?b-Lh=0G[\i0_p;S ۳`*lρ z`*lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lπɰ=& ۳`*lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lO= f ۳`*lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lπɰ=& ۳`*lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lπɰ=& ۳`*lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lπɰ=& ۳`*lρ x s`*lς= nazxu8k,l+]7,w_ߘ~.',{Y\BJ=M=/sC9O](A'U'z E+ZI[c qCh+AomQƚA䌵/%_W?z0tqUYmQk(ACк knBצ!k/^rCeL |C(1kA5V}yuIA2.MZ?+Wb{qsT5W.NB.#.;{e=xuLj\R*h^.+_)eaXe{yXU租V@`бyn 3x۞yn{>yn sۿy{%`:^}0^m 槥jM_>}U^AQקJ&}_IN8x`u 5 TB9[Eíu:9Vji}8O֎˗Bcb{.״:ޯW\sFspͨ#(0^ͧ#Tc[JWEK#`%ƍR.hy=zl<<K<U$*9']%UhxlsΙx̥["{*D߻xxu??^û?fυ;.;돂&Ԯm9/Û쿵)Ε vo%s.3Ǧݯ־Wk;xU?mJhf-{,]Y`2%Ja90g]Jo(UI#fi  cbm6kv ؖS8FJ)3mq{bϵk-8`ʉy28IxR9SGV6ipX0/MkxV4^24*rpUZ T^`Gƺ[M̺MsvQSV>\_˓8{&#ےNȥ`"|D6\Jr(49-QrYr @d!r@d` r)90r9g/`0a r09J$HmE`,Ȓ?Dm36h#@J,1 ލ|BaDqtA(`zNG)@mEHJ߃}NZ`||'#dޝ@ IQ2Ad/`9ɿ<%E6R1"k@G>S6 Ļ DXxF=Wh@,XV,g |C{zzFh#WC9W3Y- :., |b|P"Dm(+Іrm('цXK,ޭ~"G6DI$І^-@ j%|nG-@mh#І6ma ԂNݹu" /Fh#H% &w׶,m#6rCFP#Dc2hAcޝO]޽7z,h,>EÛ_=pҝw׎y{gݝ]=-.`e_%~SR}R,rT˜%.0&wI!O* }RaL crT˜%.0&wI1K*]RaL vI1K*]RaLm$6@}RaH crT˜ chO*V`>0&;wI1K*]RaL crhK*Qb.0&'w礂 O*J>0&] cxwT@}RaLv-$=&;6˜% cr<˜% crqTk&ĂI1Y}T5˜l`m\'d+`TI1K$mtI1K*]RaL CrT˜%.0&wI1K*]RaL chO*N>0&{ĂA}RaLmD6DI>0$I1Y O*Z>0&6˜l cxwTD^ Fh#J,%L CrT˜ cXO*F}RaLmIK*|?ݿ Թm[Ά;_y@>%|goff" 1373xyff# ?{~OL7-0ۇ ><ۇ>'a=yɳ}؏vc;g<ۇ>'a=yjɳ}XOzl֓g<ۇ>'a=IÞF04yN!mz]3K03K0>Y8V,z#Kjcf ,c,cV~#b(Y4,,9K7N{Bkŷn%s/ kof2'((HB>I9a@"H-P$LϤ9GI43i>y&gҜ#ϤLs4Is<3iΑg|&9LϤ9GI43i'O{̘;mrVl2!Ҿ_p]mՠ='OcCȵ}B16\clr!c"/4rk !B6r!HZ!B16WcCȵ}BVm8B Uِ͐k*lhhXrm_k !G6j !'X}mHcl!d k!dk!d+`!d{wcC>ƆD5Ɔk !B16blr!cC5Ɔk !B16lh16h16% wBmD6DIc-Ɔ[ !k6Z !6Z ![[ !;wBmx6DA(`X0 rcCJcCZ`cCF-Ɔ@-6$1oz={4%S,ܹv+ 1Wa\cjv;ǯwZ " sZu=yɳEO}.:sqE}.zsѓg<\Tr(bL>f`hLG_G3E"o=^Sf%Lp")/}ǿvuv4n6$n6&w5crW#1&w5crW#1&w5crW#1&w5crW#1&{119J$Hm5Cr_#1&w5crW#1&k61HV`FbLvk$FbLj$FbLmt5crXcCr@kLλHF}Ęlk$$j$d/`W#1&D]Ę`m\H bԂ5cFbLְ6k$dkFbL v5cFbLm6D]ĘH]ĘH }ĐH]ĘH]ĘH]ĘHVFbLvm5cXK,HQ(Fh# H }ĘHZFbL6m5cX1K%m6ĂQb$FbHk$FbLVm5cX1 H }F>|?ORd =!}Ǡژ,~F6J>Kv_9zw@;{+|_| jAy>6{R>Ն<~1w1w1h4_A-(ǀ| yB>| Ga3313g>fcHr/߿{1湍Q<<' @ms`rnCwc Nyynmyyn'6<< 湍>O0m< 3O0y f#<p' ~9@:tEO@/۷7w.yg읺5)qL-yw!mBЗ<9'ϡ/=o0:sKO! }!?/w?a C_sKOC_zғЗЗ<9'ϡ/=y}sKOC_zғ->~}@.WsCi}5ʂW{un>r)1gtX68ئ-Q ۼ@ VV;% el -f'\bG W׌+ p#[IYkx5,p\K_?)p[YYcny4wofR×˼[[m.y_*~ٴ:Y>568=p{>!=¯=31=p{>|F [ў>pqp{>| >8? N6uۧ®xM]ndf5:tQY _s5t;},Wy?o|A?T\XWXps3^{C[pqp{ p}!o +G0U$U&8' Vu#0o!`mlXFZD^ G!p<,x8m W "y "֨Kj G!o\+rҥTr\*tQk2o[$UDxi/EjA]T@\%"P[:׈%"[:.+D@Uy;*@^b [:\" T \O+x4tiqΕ!*]Z*UBP9]Z{*@A(PE/ .mܥsE pU 37^.]XܥUQ < |-!]>V nVܢvnV+nV,-ڊku nFܢF[pB`Vh+V GܢE[p"mA1p ؍<@`]nGu}K|x~?sѠ6m1 V~[ Ux+=\˩[] #\!`WB2H; ⰩB;W,́@Ap,ex]cXX .Nׅ<΀u.3 UK l;or0.d!"HTEXA6c3-UW>SER*閘ƍ\:ܥ"Y\ TG[*Oc8JTQ:T!$QE>LtxX: T:T:جUC*ʙtHL:z$1^=.]Ҍc3gqUx*DA(1^/.]ҌK,#fT@JGA)OK+U(B9*K Vw|UE"ITpUE`x >g2G5ܛ-^;붓j>m-M7{VY㚸_zka75"~ ȮkaǮkP_wȮkn}K\m -l9o=di?ncz@\'Ѓ <n! zHrS/dp?B~bzC4-nC/f7?G/Ѓ!Mn!T& TcnZp=\q-)\Ivk'~!\qzyBk܀q=D@ Cu`vSW~g:F':A9E֧9Cr\/Ѓ!7k,ͥ}!8r5CpZ17g8u{ EZ f7qJUzPCNn`zPN/-*37 zH=$\9M/rZcp?Y LZzI Lz9 n p?z=nQ`Nlz LFzȹ nFv˩ ̏8g20=oGܿ}KȔ硚iݔ)O(sn*d_W@lu ߴqG>)kӳf7z0)/@P-ؔ1w7qm93pׇ'emN\q zoփ7 zm$MR}̵6:=IY*n![nbC1xO`}I.֗pCI.PQ7 $n䘛둍?)kQuΔd.5Yp-n7gq9/^p.~nQ`$[5~} 8ےׯw%p="3[nMmڊn-2s[٘ۊЊ֊\\\/-~܊n! zHZ٘ۊ\\\ۭ\q+2^/C-2f  FjM"1ZdpVdp5nVdp ǭ Z\ :n^`Zdpǭ F@ C_d6EfW~\/2C_dp-j :ԏ"3z="3[n-2 "3[Vd6"3[n-2[+2 "3kq="3p="3v"3[n! zHZ٘ۊ\\\ۭ\5%=ܚ{@Q`([lmEfWzhEfWvkEf~܊ЊFRd7y?Ԙ5vZ}s0erXu}9n1=ktڟ}K<(sn͕(E͕ܚ+sRM\vk9x\ۭnܚC\9n^`5p@Q$CmQ4Xp[ܬ_ϕܚ+c'5dOj2>! }RC,I Yrzhr,I Y'5ds֐>! }RC,I Y'5dOjpԐ>!˘,I Y'5dOjpԐ>! }RC,I YFܧ6dOjpԐ>! }RC,w6d9gCِe6d Yِ+ YfCِݐ_~|Y.+d]ɚ!WWgvn W7vtt^ #ה77wPzٸ}ؾ97:Qp9sn_ -'*Hv) w"gM U絇 سU}ZpkUV}Zpkǘ떒ss!SqkUZոZUzhUzhU vUV}$[" Ug\vܝ wFza_=8쫈#΂wfĭ v;izRps.qU5zۯa7wSgkJ,k0qٲ@\/CM7lʳ,< n*Bʳp5a'9nh.}q5nRGz0=!wvQ$C*{17avkR7R絇o)zz=-E8r=߾n[ n[j|!}K\}K\/ڷ5s}K\?wڷus}K\/[;U:&7ژ۾\J p?TJ\uCp-n:܏[7?z=@Q`7|;p˜N(\록P[;p  p= v  7 zH=$\Q=N(\|;p5vB\|Ϸ W=N(\/Ѓ衞PAzBF p?n'vB Wzh'N(\q;p-vB:n^`zB܏ zH=$T ?p Q='AПP[B:ԏ z'n=p [O(zB cn;0 Pո [O(zBZ\u v PQ(C!zh'vB*܏ q= zh'N(\q;p@^ C! vK cn;0 Wzh'N(\q;p-vBa-sl]3 }LPznqRjc^#WUxh p5^LkAqTޒVc.V&zW 7C8nM\u%Iq\?KvR7Ǎ=P8nj'p[f%IqܚT;)q=8@N:܏vR @5YpvR&k.Nd I1ܖsvR&k.Njnd;)[5j'q-uvR F5YpvR7 @I5#.N*ԏvRWz`Iq\i'q-j7u38 P5&knMܚ5Ypkfmɚ1%knMܚ[Kܚ5Yp-CK\/ح&knM(C! p=d͘ے5W~ܒ5Wzhkp=d Z:܏[z@A C- p?nɚ1%kܖ CK\ۭ%k%kВ5#nI|zۯ\\ƬN r ^Qk?ωZk?)k|;D %wV17m ՐwR0*'n=ypqu5N `>͝,ĭ|z=@Q`(t 揹{9HiIѸNsiC4lEv/<]N^q~#Ugyq7߬:; ng kJw1n7E67w7wWCz kEv| uv6_~ Pp&n$Myp&<;'or]dUZ[ǎ!v~m@ vnp@Q$C:?np5\Zp?n z=Dݢn curq[1u~ Cp5nVLp ǭZ\:\zݼnVLp@Q$CЊ VLpǭj\\Zn:܏[1!=xj1epk1nk9n-&=T1V\ ܪ VMpk5!ՄWkՄVZMp-![ Ъ  V n&Q(C!z Gܾ*ԏjBQ=Մנz EW\q_Mp@^ZMpk5!ՄVZMpk5۪ VMpk5!ՄI_M8ՄVZMpk5!ՄVZMpk5!jB[ n! zHZ5 6n&j\\Zn:܏[5!=x@A([-~ܪ VM8jBp=jBqjBkp?nՄzhՄ#n&\!aSOg __TXׇr|ru~[pKg[;2ֱu@uDޘ[:6">Ujrjn5pkrZ\-p^`7/[%n! zHjr[M#\qM#ܚCK\ۭ%%&n&nMר}[cnMܖ CK\ۭ%%Вzh}v܏[rF@I&nK\qK\%Вvk}p?n}z=> =>>M>m}[rWz}q>5>µjn:n^`GGQ$CB>p}njT}nT}nZn}n:ԏ>=xJn>-}[sn폹5p[n>­}q>-}[szh}p=>yJn>=D@ Cܖ C\r~r z=nQ`q폹5p[n*\-p5nC폸%o; gl kN 3:nryqUpUps'qu9pk}fp\[p\[9c\aaW :[ n1 n*\ss e 1 n ?OQ jn-ւ1VPpk p=nWvk2n-C+C+^`7/[pkA Ms[W [>6WwjLS[tWp(TzWo#9n .4r̛\q^{~[qY'| ޚ-11ܙc9c9c͝9c9c9ܙc9c9po~>};1ja[Zrn)-׭uzm]u'p-#sZ :948 1$',8,`}|X=]FX+a~' h}PN*% Xx Nt{klK?ؕ G*DI-&, n9.5U U-nBpΙ/ХKTK ɹ/TQ`(1^]:g@N mƔ WEHw 9t*r TEr*r UK[΂.@ͫ>CpUaJ" 2^΄a.]2aЃ>0UT %"'0.0xu \:`Ux*@AtNKK)1̥sJ VReHV[1xu : oyylK-*YyWTź6:VL>6r4^js/<[Z=V >Ր -T@yn5u-<3޺7kSK\I=jP^ PE" %KK$p|h SYȧ0U%P~l 2skK#p|p S*֋o?<~ i;-/xE}ujG%^?{,, h2Ρ;b, h*΢0;, h*΢P;b, h*΢p;, h*΢;b, h2Ρɰ;, h*~:kUTݱh*΢;, h*΢<", h*Ϣ <, h*Ϣ@<&# h*Ϣ`<, h*Ϣ<", h*&Ϣ<, h*.Ϣ<", h*6ϢϢ=", h*FϢ =, h*NϢ@=", h*VϢ`=, h*^Ϣ=&# h*fϢ=, h*nϢ=", h*vϢ=, h*~Ϣ>", h2ϡ >, h*Ϣ@>", h*Ϣ`>, h*Ϣ>", h*Ϣ>, h2ϡ>", h*Ϣ>, h*Ϣ?wbN1}|me'k@?]̪l,ͬm}-!:p׮s~ۆuƦG([,:hr亍k u;rzz_<^:A#yW;vjȭDn/>r/[Gxum#np/[Fx!ܥu5npp=^ v+#np͉/`f7*psKAF8*iK8n݂[ɮ#ה:rkW`{+unA 7s\GV %poe-~1Jm0%܏k{5۫aznh1WC5pK{5[sYWC5pK{5-'=-n_X*nmp7%ڈ۵WrjW~ܷWC^ T}{5kQnM }txJ2Pڕܜ"+Cޛ](9/Z2[ڕ!ڮ ve+CkWpK2[ەҮ ve7~ڕ$CPە֮ *܏[2q=vezhڕ\qkWp@^ C! vKvecnmWp[2p=veWvk+CkW6~tE`][n@ɑ/jt.sXv8 p*9184XRư`U>*X]>e dlpUZl^4SEte  {*DA(1^/@IekAUrLTER*r=9hqjrХ]:גHWE$U@^b:K!8JTQp8ITQp#p]` `` u%U*@Qb(0^] 9B)\yh5p5>3p >1p-j>/p}Zz@̀Fu4E΀s[Q h[f@#:jn֢j[ЊЊ Vn-Q(C!zhEcn+ VT p5VT p VT p-nVT pǭz@A C- p?nEcn+s[Q5UZQ5ոZQ55jkq=oU_*?餥)juS74aK r)|qu1޾3PV.5XX_H[ ۷z&C.p% Z ~"+ X Zl%`+; ^ p`*)U,S;?a`0OXy9 %$$$%%fWÚ[ӫW!x^x^x^x^x^x^x^x^x^x^x^ܺ^> 䝗$$$$T"7a|ܤRK~.b"\`#\g0p!RNYbx%Xêȋ1U+SEɹBˋa㕢"\`#`/QE< ’Ӯ*ޔGyq\[I`T9;NX,rtum"eyk63r\up8H@^qnhR&*ryT)1BIR\` VǺT/!B{Ru#`;6ױUh83D&\? " :T%Ƌ%CH'Ya*̂(*UaxF3F)4wic0U/^?>p'֖;"Ny(IY𪬽lCOp,fyz%˝w&vZ{gnSu,k/jWk9n>bj!nI"zҖgյ˜Nv\U*Jna[ܬ]Tw2nnaS ,z9^j!S=\/[ =R qn9X S7J!=W[ o:LE!>q܂]xAzo9LA v܏MD܏Ma7=VAZ,kX5 Mzm(7vCB;7c[p^%p'3t\޸Cu܏rcs;?ǟ._oq.p=>n^jI-[[ h6@ _o!aכObzM0=|uH?~56ek+Ӯ {E*}践."7WCE:|Ӻ\k=aZzuô@Q$CFsEd%s\]p`=\:ǭ]D.q."jqkK[A:ǍQ9n"2n"p^Wz [s\ۍq dukq=}9+ߦjq.q&jqq$iNrqjqqjqqjqqjqq WQs\:ǥڪs\:ǥs\:ǥs\:ǥzs\:ǥZs\:ǥ:s\:ǥs\:ǥs\:ǥک3\:%s\:ǥs\:ǥzs\:ǥZs\:ǥ:s\:ǥs\:ǥs\:ǥڨs\:ǥs\:ǥ3\:%{s\:ǥZs\8^tPpiqNr?x˟G}<Wʦ?n_K)*UXo_^s_^]ph?4-CCOo? Hal?LϞ&gJ^I?П_e!)gП)F*Jd?TdO%YwՒXZIz]*^3ƽ>$Ysg{}H׳^tgͽ1!^Ϛ{=Ż_ݺ6?#W߽NW=O?˷ *:[;ZQ-/ǤZ[K~xN91177xV\ n-sun^!7[ !W[Av˟ vPѐkK9ubvJn-A7 Q`$r1,8\%*\f;5ոOWz Z.s@k7r>7՝š|}}M|kapRmpӕ|nmqϼk2ӗ'3f6Cp؁mCpف]9A5gGg8Mڮn-8p,^0UłU T(붱X& 6*/lƣXk{!*b^ *0ƣ*Xp;8`WYƂ kxd 6Ke`, X*cT%*X0U ƁR0LՂq`S`$)L5X0UƁr0LՃq`Sa*cTE*X0UƁ0LՄq`&SEa* cTUX0Uƀɲ0Lօq`.Sa* cTe*X0UƁ0LՆq`6Sa*cTuX0UƁ0LՇq`>Sb ,d*X0U"Ɓ1LՈq`FSEb*cTX0U&Ɓ21LՉq`NSb*cT*X0U*ƀR1L֊q`VSb0b0b*cT i_{|w=$S5.9{w~C%q\̨ό̨ό̨ό̨ό̨QQA33>33>Cp|gurgÝ݊OGm.i/@5T+xֺϽZPu\-jF-3[Z[E=ipC{p֑us_yxm* BXS 2/Bek"$NgX b9 <_ĂE`| ,:_āE,:_āJLUp`҄S&4aT *MX0UiJLU0`҄OUp`҄S&4aT *MX0UiJLUp`҄S&4aT *MX0UiJLUp`҄S&$4a'S&4aT *MX0UiJLUp`҄S&4aT *MX0UiJLUp`҄S&4aT &+MAT *MX0UiJLUp`҄S&4aT *MX0UiJLUp`҄S&4aT *MX0Ui€Jv;UiJLUp`҄S&4aT *MX0UiJLUp`҄S&4aT *MX0UiJLU0`҄&4aT #,L #,L *MX0UiBK7u{_՝r`:Xo1},5X>~U/QH`έM,nD6h&c1Bf,\nmb pkKkY;ה]"3wn@skK둙; Y;6Q`nyӚXfКX\5q?v3-܏КX\޹N/-~R܈qkK pSi* pӚ*UmJ3?inwyFI]`:E[Lk1lW<)-mk=C1 ح;ܙǝzܙm؆"@nD- gF=pJ[oO)#t)ʒN pk8[ Kyp@(Cw. p=WWW%*pkR֜9 [S7g RpsF^W"'_zԑ [o & i{Vk=8|s. zĴp(C! p=BHnqFAr\EdX8.41RB#?.E.Uq-^T $uDvR%hBT$ =P7 F?rDdV.Ypӂ끬~ Yq5n7܏Gkq=וoSK>r\Ru*{T#ǥ9.UqG=\R5*yT#ǥ*9.UqGK46pQu轊Ime},9G"6l?9l9<'0d 9=,A^wP|B.a=.vۑwk8u+>FKD /@J}6^dE"[< Bښ_+Y*W`4t;:c52<|! S)FZ\`A̵2‚|&_drۅ`)*п5M\k2@ d&4pEd&4pMh2 X Փ_n_8t%!]NLJ {03دb,4|,4(y@_O2<$*rgD%Y|"*ƚ>!'Q՞__IvϪvC=U{..6.6.6.6.6.6.6v5Q*,Xj3jgUϪ6o;̽"ة58< w;ǀͤj853`IՆ`IF`IՆ`IF`IՆ`I@Ֆ@F`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`I`QF`QF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`I`QF`QF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`I`QF`QF`IՆ`IF`IՆ`IF`IՆ`IF`IՆ`I竢v񏓨_Dm]U5z1lc,^2!;D7#eQ{_5qlSq 90ĥoRqs!BRFDE׀ 0iH"%p]a`-#2eeeeeeee%eeeeeeeeen_%vƯ.};U> ?_:c/9kZ.E7JɢvkCaSm*b*b*bX@U T1b->k{}=8JWc/ГlOC头Xۏ{~dwa*]9ZX9, / ?݃n ~OsmVp n[*]vij<q73;871\h^p}nsApks}nR;;6)FuĨuϙzf}R{f}RIIa(DT~TwK[zK/zQT pG/R'EgE'CMT QjUDY<_x#J>xV `SROmJ=n+"*fQ1+xYb\ŖzkWDX#ROg-=+VDŬ"*fw7+ҳRO*D _xbƊ-=+Y'ROMETJ=;.zw]*Y?^xjA͘ͱqžs;UP V"C-z8G ǍZtΘ~ND&  p]=>-X}߂'>-X}߂'> V}߂'>-X}߂'>-a}-P?<;{Nsp>6:ӱ~dVmx*uq>ϳmǮNȍFcڬi>6v^>sH<޹ϝ~ddg65n[1s͍ nH됸Qf17dHq ov!qus17;~+-}l; 6|֝cx0Vǃou n1 q y#"@p%qWr!n'݈+nĕC\{ pEJ3ĕg+9W2!d@.̎2;>@.̎2;>@.̎2;>@.̎24pr0성Mid oG; ܦnmd 6&#LG>Mf~3CKYz̅ve NFc~ox| O<4x| O<4߮}`}`}`}`}`}`}`}`}wϧ߿|?wq_.&eD: ]BB}PB}A ]Bbw^R{I%[%oT^R{I%[%oT^R{I%[%T/x%oT^R{I%[%oT^R{I%[%oT^Rl4o1 %u&m~q^RܦW%umvq^R%uH~ݨ^RܦV%uG:^R~%uGzݸ^R}1K꘭t".K}K:b#R(r^RGlzD\{%uĖGĥzIq^RGlxD\%uvGĥzIq^RGlvD\{W:huD\;%uFGĥzIq^RGlsD\%u&GĥzIq^RGlqD\;%uGĥzIq^RGloD\%uFĥzIq^RGlmD\;%uFĥzIp^RGlkD\K{%uĖF-=?oeKЍkK$`1Ϥc?[XVI=~p}8;bFny0[&,6N !`) X*CF`I` %2d$8ʐX X*CF`I` %2de8ːX X*CF`I` %%2d8ʐX X*CF`I`IC`I`IC`I`IC`I`I@@C`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`I`QC`QC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`I`QC`QC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`IC`I`I`QC`QC`I`IC`I`IC`^aKKΚ^%)w^rsg<&6NvO[ECn20&4ě &ڸkGw]ō~JW\)c:h plT$ÕOw|+DM]\_ U]jì 9.IR6rV@J-z؝$m8܅h .>yEpWMcc7\[ܶVp n̹R1ݚ_"n/+#n~`C.': q+B2WTu I#.*.|Yem \t\} f!Q1,^r prpr "&*^ड़K z.tT,]QTt pG/R%=.jb W"*|-uKga+QQ$xC}/wt/Q9Ϥc(?}je(dv[2[2[2[2[2[2[2[27=)d{iJo2tR3xtR3xĕz# qV+G\8]|}-B\q;SPWW7.tʱwV)w;%rl݇RՑNLF/ߣSMꔇMdN]_u>e>ݓ0h5\QWL?fǞ5=QWB05㺢&p_x\[jꋚ. Q`1j:&XTkQz&IoC VDE;΀ۊQŋQ+tlmahwPe :ab79p~fc6<H (W1<S )3HLuXb%N!Lb񨦔gS:RfPT[ vQA`_xTc S:s)oUjM 7e[a[lNf,uN J X*U@`?eT\T\T\T\ &7T.7T67T>7TF7TN7TV7T^7Tf7Tn7TRUf0կ*@0հ*@0ձ*@0ղ*@0ճ*@0մ*@0յ*@0ն*@0շ* 0׸*@0չ*@0պ*@0ջ*@0ռ*@0ս*@0վ*@0տ*@0*@0* 0*@0*@0*@0*@0fQ?N/OM,%^ˮ9%S-Hscpr@1š3,*|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,*|P$>>>>V)|,)|,)|,)|,)|,)|,)|,)|"(|2(|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,*|,*|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,*|,*|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,)|,*|,*|,)|,)|,)|,)|+,@C`I`IE{6K?ym6MBb9={rv|P7z9wᎧ3q}.CY޹ϝ~0%v x&=Lm*amN n,CY;oϽ=Or=;T[ EůU{ Wg;#;2fm>\p XҺ!׭mS92m}v|U93ܾ"u*8UR>NE\رg9nr9UnR v\*OU9n*y!|!TAhPoDVL ue[Z,3ݲ=n?5"čo[Wc=&? u +0M\_T}i@Fn,/\ui+.r_CIܒ %%ApKFFu!b1!oTEx(QC|pR;x<4Xggosm.6&~kXw{uv_\? ǺXOT;Ǻ+aX̭ou 0ĥ'ɇcS<\z|86I*r>f$aN\ {:qc?@U8_7ݏu:rc6?7Gm},:A4>"nM .U|ĶGĥ T]*k>bϣeTQ;i>b#R%GwD\펈K4qz#6;".U|^GĥꈸT1;Wt:htD\}KU2qB#v9".U|&Gĥʘ㈸T[*b>b#R5GlpD\U0q#v7".U|FĥʗۈT[*^>bg#RGllD\t}KU.q#v5.W|ĦFĥʖӈ^-'.5ˉK,QCo^j25!jC۟XMj͐\Wuy+C'[>'H |i4d+d[W vAh ߹[ $ס}A66fmNgܥ?1zF'$٬~B7R7a)p FqPu9;d@!/f|dY.g|PM{ӌ)GdSLY"/$.Pےa`)bxx+bxqE^ zrȋ!dTPȋ!\W~<5,kY]k2o1 g`|&+]|)$ “c.E] sn\v3`k7&7'bn,uF` tF`=}`=}`=}`=}`=}`=}`=}`=}`+yr{tۤcROpyzPlJ&Ab+rf= 7Dْ Ԙ7I^Rc$y]7H^r3C[K`= ~Q!@o8:\R\&cyLrzӕcaNr,N3YEjsr!s^B 7sarOǜqNtVE.}ʀ]JQ`4Wk7iNvXvӬf4kY+`iNvWӬf5kY;afރ݋_CNmɩs+_:pX/ЗNmj gpmKuۭl(mR 3:~Hrmx]xNNǙg9>ܺ]je|;o8$.wpg.S` \ϓ&p:P1j=\ґi:RӑXӑt#5+`MGj:RӑWt#5HMG^k:r}駗(%ixuJ,kۃmNc:RA(p5kKcjHp,:\٫~J.G  rgSrś~ -xo2%ݧɗSrFh:N%A7|T)r1lh݊[~Fvn-rqRQJQ1,Pxy`5nܬM NofAx|Mܐˎ¹!xǵ΍Mͼ*ͼu6^z^`-Xz~ y߂z^`-Xz~ y߂zת{ݿQnNsL}&0ZJ/53nuX3.?t̾M.,y9n5qq,׌݆q΀I5qrLIߡ;VØ^vE%֭MĦ/r-qS-r-E%!L<"VZnzvg"$w)⺊x+mdqi}\dZ*JKCRixX[Wp=IL VfܛC7Z{噛s]zc7x&6ԧ8z! (>89]ZE.a]JM~"Y6_଀Rtx"峊*\P&*\ETW>pVLMfGqŀ oREJ-Ā[~KϟL bfb}ET 57T,ңĀܶk9m9k9m9k9m9k˹-- 5?zqD^C>`\#&\0]ХO'O_}T&jd9P>7 }ԇI~<4y1,LfL}5 MMM\/!Ry .Κ+\5Wr͕3`͕k\s+g+\5W΀5Wr͕\?~;CPUr7{hg|*?WաӐD \!(§ *|§ *|§ *|I`UTSO> ߻ݟ~xukyUs13دJ̘}XYd5ZR^Wߣi]TIUfK%̀Ck5 ;π].yOZ9;πTBG^Vw꾪_꾪W׷?\áhn=ؤׯɥtl9?f[DC;16 n.~]_E"!S!"wR-Up|{M7\[ܶVp nL\_ &e/- nKp=[2W8p/vbOսgVXYgQ1,Pxze} %=W-X-X-X-X-XJCzɹB3دɹMpy,PbUern+{ WLf <&y<<Ͻ ;FC'0x]x}km-;cmWaonV \;-][,y6Yu&{kLMLQ`SV,+ ۊGkY󮫈 T+B.y--ZS7!kn@ȿWh -؂CK8`--XK8c -؂CK8`--XK8c _=,h9g !xŸٸ~nCN6|sv`\9YҜ^q6#Uh[nm Bwot/h]zr/], . ]|  :9y_PdKp*n*t;F,ै: c⨠;&2{! s;(!=)cnқU_k=VEȘ^Eӣz;ތ6@MzЖ"1=.BDHe,=ѳp*BqUj"W-YƑEc6z䟸A'O~4n&G|TSO>TSO>TSO |*`}??ow/gf8+̡kmv>vkco(.s9B]羷צ\ .0TS= #(:R,5X*ORLdVns˘ n)b&꼳2'J Q.D`Զ`Զx(l굧BQ wϻʨ1b5F1B XjPc##5F0`5F1Bj`j]#~ C̦i쉰;Ԉ.6~6v`Xi#^l'蜫+rD j| S7nP 8S'?lL<۴tje6hh hh hh hh h,X2ࢉgMϚ(.ms[Z|"A\Xj`=V?quW,i,i,i,i,i,i,i,i,i,i,i,j,j,i,i,i,i,i,i,i,i,i,i,i,i,i,i,i,i,i,i,j,j,i,i,i,i,i,i,i,i"h}^uQc~E;w|Q͢㠋.4~8K94JNExu6z] >J];+( (( (( (( f.Z>J\Sk7TWՕxDu%+ՕDDu%+y{zyv-CfшkeҦrM-3`X}!pNW<"vU`.*Jx YOF>\6ýn !do]Ɲۊ 7,K,ˀZj-=uZ X]VWkZj-`uZiO]VWkӫ+P͡z򅭵銞|>[e}9z N B4{0}itjPԵ%JDࠖ5?s2.Q]\f}*Q)y2APv R'^kktFwaaioZhF/5-n69G{~K.jFnwe]( ({R ^*( ([zRO;zJ=.J=.J=jb W"*|-TROgzl+oV p[gK}Y'C *`_"*ƚz<+TlY'"*fQ1+XY'}Ŗz.RFCRڨxHJ.4K܁喷ƎˆJ;T,GD,\T]Lo}¥,I<]O3@ nbmbXmv%1π!61O!6dgڐm'ڐM]I3`mȶM`m+5dОZP>mp&VK4C@f?_WgQL0[6u6U`;uD6jpLKimLKimLKimLKimLKimLkk3-mk3-mJ/ߝЍ~]!m I~6]hz\l{3dGپ+(>.ɦ 29O"#l܀pMEx'Mq"1s)ыyt0O5é>ݐrR NPq|uxqa6HaucwH,7ybpH<r<}( a2 ?6ąnSl+3qmţɵ̗8 UWD[2ǝ=PxbK;'D+$G7=&sMEJ%kRX&/5y+`M^jRW&/5yJ^>4ur,M+xS y;|d7%o4 d ^RZFA!]!ϸ6mxfsFnM2uJR"Cj҆>15se*.UXWa]+`UXWa XuUXVa]u֯UXWa]+`_ae3 r IY7ХJ]'I,/ǶC9E4G7fUM-؉K+: hn{h/q+O_] h/CGsԲyC=*[bNΫ.b(.b(.b(.b(.b(.b(+bY"bC3Kv[v[v[vvj?pSwnI+\ppxo(?& Nsl4;a^Xmg45M /hj4C\7;RŽؑ*M\$qы-MRLK0.u3RL%q%q%q%q%q%q%q%q%qkZI"!,,,,]K]K]K]K]Kv{W_ }Fd> -Fo\%}>m.7\%j˩& 8,,XGPP}3V gx>C X}3T g>+`&GYp:L66ߊi;_<kQN4kbű$z[Z\K g9 }-/GpM&Qm)ALp)n:Zlۥƽ 7j+T5f}!%Cźܵ6Öu-I}lCKRt mC|5~k 1>ĵa5>n;>3670TPnǭq}xs};ZmjNo,MÝ^ǏC#y66B߼ซ3n˟&kp[=3(5)Q́͜S95ӧ6s> \~0UU0 UB CpGӊnw>Rס7yuƷݲӊn?5jmz;[DO~ z z z_NJxxs <+.Nf %ApK4 Cpc;>,2(rP0'?qoC]u:6gBLr͵|ܽu|9r=,tnc9>֝cx0Vǃou nqUA\IG\J<9d|DNH {D^Ȩ d{DGĕ|+W9"rD\券q%#JGĕ<+YW8"pD\ሸq%#JFĕ+W7nD\݈q%s#JFĕ+YW6"lD\وq%c#JFĕ|+W5"jD\ՈpES#Fĕ<+YW4"hD\шq%C#J~Fĕ+W3"fD\͈q%3#J^Fĕ+YW2dD\ɈqiKq%#J.Fރje㪕QjeT+#કQjejeT+Z1XQjejeT+ZʈjeT+ZʈjeT+ZʈjeT+ZjeT+ZZʨVF2"Zxp" TI忯gO?_?೻??p96yIpiI/|=a+qco\/g_CFp=?W5M'Ѭ?8M?C0%AϜpLHZi9i21=(ppggD[2?8K 8(p K Q)Ad)V8켦{À}R`)!FG>*b&;x`<6Lm b2Q dTL6*#[Xl{ xH, >( .(K,]88< hƊvMIn^3P&g*"pbZ<&c>ԣi:651 WDEt>Q1,PxRHm&/q?/oT.f_pޮٗx]L +g|prrC 56k#N.-nKg~fRkl6i 2e.o/Yu.o/t6j oV7{3ހKP٬ 8*œlCp6``>)"}Ss'X1͵: t֓Qz2*RgoX[s[:٨Q1DGEtؓ- bK'=[ۊ\U,`bK >{ jbk`W[=+wi{our`,}ӣ͚Ck]o߮±Yךrb6~v>%|tHȿя^_mg_c9g2y:v2c˯cS}O'xVp:' i8cBǭңoÿ}Vz/qJ{Vtw //d߇M^LnkS|2'A;sM~Ns0`?_ϯ쐾1Jܸ!ͱO\\屛_˓z}>Clj޷oYRXXЌӱ(' T\lr\˟m<_ m};>*ǐAUn.XOW?_ ìWt7Owpb~uIg:FC>اq:8Ix&s.sXs+F蓴R9AqC1y4GE)Dm !5䮆Րr_C*bc:x\g ՜9g_C5䱆-ŝ_)bX_3čB &nÝ!$xHo~ w &gqk)n62>y>W%>Wx1ܐ2u'nG@]_Sm)nxlMݏ0CnTpM~\=p[`Ýo~`>P;VlLcps:+!uq0&K!1\_eDLz2ܞ w]Hn6p]zb=ecE<|<$yZZ7k}ls1kx$S`[>O*֭}lx*Uă_nbF~ۑmC>ZCkuk-nIħq8IT<;_DV X\gұ_DNŝc/OqL(q?*bӴXCiKqKK5ǐ7+ 7y7s/--nni#uZ}܂fK܂Z>|<ɲ܏sBnK碔> urh^Unez$8ϴ*n[FۇFpcpAli>/}[)q҉z۩2 {t0.Ϩ?^GY!= $ۃ'?q6VrҗtQ!!9Gs. ݕKq^^;ܦJ VOz؀ _\6q\3'm֢p[n+] \hJAD`Ws)\5/_H#uk7W$bv!(Bގa: alalb, `iK X!1f!4C !b, `iKS X#1!4G Ab, `iX%(1f!4K ab, `iK X'81!4O b, `iK X)H1f8S šb, `i +!4W b"'O`m')=>,8""#fc&hd]և"ڱ_trmnJpOq+"%kNjLs]y\}0< Y~l8nng#}E< 6T[g#"|E<00~~6kxla܎_7U[} a\W>> XRHpG~%>F\hu-ncp[~c00TPne u>}E^EPCE<pPwMKQqO-1%kk1%bx0qn1#bx0ql1!­[4#r!8?v|b ܺٮbz~۞1BP"\E.چ5|<n->}ܶ>.ڎ<ӗwhJ3kS5ݵr>.*#7CǺrc4D8r8;+pY%ř9S26KCmSE ѿύC1_\ 7m\ۧkp$CRniHp]Rv[듲p}`1) w.}nɭV2wh\ǟ 9pKF|}nh9Ap gsFZ>mx3mhܞ ;TP9p]E<V: ܑ%Ap kx( ku+ d4nCh0ܾ"u*-g4qh0\_cEwxJF1l;9Ea}Uby8m͹˝ܚ\k|:]`: [ wH;B2W2da9x["p@vsCs0C }lLǃ"F>lï+&2-]1x p@66]7KWLev[b2~/0TăWbcKWLe6d׭+&2'0|;^1tJ'Oyq>v~ۅ6wamnY @p{>f-6T\_"Ɗxx}\Y Y -@p;~f->;TP"\EjANCB~(\"tpKA?rr9d[aţŐܻ#GȑCO#}##AD#w"!w"&!"6<2J\rrDcebˑ}~AKCʼn욊ydf>xAFl]fςRzD^ "GE.ӂ";ǑE3! 7PdTT]i?+OǑmElx[q8b\Aլ`tr{O FeP n]),mC&tfd'~l͠dž{:; |O% "և1nEX@5}tt3󱆏G7:kus_7צ ۲Bf4~E\TɡQc j1l}<""fPaS n6EpaSx6Ep-n6pfPaS XæPCE.ænC6px9koy6æy<8~\w?j7݌c֛n)y6; "g˰)y6ne<^Mͳx(æt< 6T[6E6Ƭ/Mͳx+a "gVMͳ}\Mͳx(æl| dmܜc%Gpsv|<,+aXbJ=[|Wă"F>JY>k}^fea#-,u[fne0TC1ܒ#9pK,-Y}n9Gps,Y>| dnÜ#=s6T[1ܒ#"|E<0P|w\9Gp-s|6gn9Gpx*Uă_nbF~Y}n9Gp sZ~,m}y4b:xuOkU,5+4_g]܇k) l>i~WVt듸yZ^6,CTR?$K,CTR?$KE,CTR?$K,CTޏbu?",CTRe?$K,CTRU?$KE,CTRE?$K,CTR5?$K,CTʏb%?",CTR?$KE,CTR?$K2y~ {?_1:pEQK*\uTᒬ #9ztT*: dU$%YG.:pIQK*\uTᒬ d dU$%YG.:pIQK*\uT,7%7u{n_xSڃtDٶY( ?ғpjS(Nn!,W?Ol.痢,_ E̍ae:KգOxI':JleD-[':n:q։[Ntܲe\':D[':leD-[':n:q։[Ntܲu-:ёaDG[8ʯ_SZT^m=GT}y|z{;؍z=B|3ǹhaz[:-rezt5D8Gr.גp.AbmS8=ݦ}^)tϠTkġKxݧb#=,P.QI_!cM®C1.}) 2 "VnNXFe^ !B z"cvˡ!kW-(lt)EH>hS!1FHe,cLe=f2؍2\D!)EHIGPC2:]FOY 2BXʡ>=Rr2憞2s{ 9EHN`P"$/2F/ j!CUqU}V,Ho}!м!b&سBzZǴ%:|7N?Bw֜B1Uг2鸞2={oJ=d:[f=d:[fJ`:w> 6l7% #d2GȔ"q:b6 "|v*B\M5論qvmS!mS!DHk+5ضmk6zUDH2?MfoL|7璝/Yi .BY^tpA蕵8;O \1l-r,Qޚ Yh)pDEEȨZq c ܥH`kxU]T&p6C}V xigQMY/57!8-F`pQa[>* .*lGzfp_x}ŖP"*\MT57V,Xۆi"|Tbږ_mo4_ro8v.,O뛿.ҧO?ܽBO7fQ(7G8Ŗ@mA߈Ҧ"ӏ,ߝ^^`c Z*iױ|~;x@9\hs B^~Zͱ~\gw/^~&o<^GFtNՖ+Ͻ.}e4}no@4~^ϖWw?|KtBw[K!!X:xVyKuϸ{uҤ7XOdu??|t$l\'Ӌ ÿb+'!HE_|%lZ \~Ó?^翢},@ۣt~x)0?M:^}t;bnNjǮ~1bKb'Jͥj=xsP\~ qoMCj)uIQRfpݸKMkpo._4iQW%rQ狿>>j_.u/~CΧcձ27֣K>y%Us9`{e>2zGmWsNGo?lv'_>zv7ߓdO2xo>88wuJ?~7ɯ&9}]%jk ;\>Y8v2dCQ~u~C9>ګ7+7+o'w_})扰h{^9Owϡ=twmx{N[(7e'[1G]ӿ޷Vz.eKs7~ٿ~v&ݘK/۫o<2:6uNelo\l#y cd, !7ݶ>a<ҁ+f__V3/^=+ -燼hwWƤ6A,޳[$鞽9&[B״ձy*dj6߽? h78C8dff> ω3ݤZ'.8Yĵu䬸?>w$/5 'O4.#Cɀ&_cQVM~$5i^ 8pLw b*o sr6So/ ŋynm 7΋j!'rxjTp"X>=DޏS&*\ETx3/QOT_Ľ#+qcǹM lrT`[9ڼx[yK"*Ǝأkf%3ҟ$%3`_>) x1}*삳HD-^Llܗҹ/!"wa"]u+z$ٲP\#!$w qBg6sfsyV;wA@?׻ߗHm& QL'ki`"n6mi4Tɠ٢٠l)^6nshHK; w᪨*;:9o=}炡wdP*\4BNp/7Zͼ|lPEpUx‹睡-AsU`P\~2OECK['*AEARl(^1/ŠpΠ*7/x^ -o0T&KB?i^>'!=LqQu/\{⒍7y9Cn#5p^C by(\? ;xZV j1wGວ_y&jM װ_z3co̗ 5^ a5 Gk,q2B7Hh\8"|{T6YM^]݃nǬS2m1S7" uyvcz޽##=rEĀ쑯Gߖ!2 kFűG<F GN39dn/yb cpn3 X-\_Oh9Glu^k։P8h(^%Kxmg*AŢUcNcNnE`97"y H"MPhhyKtGR$pn_L |x\ 4( ġ@%\ v`?qh`52,[*x2/|Up$p4pldPlQlP(G, ˬr}Aܴnlxj8Ľ -ܾu2p&:$?wz!׭5b]uLF힡NtZ[k1#n1Ż?~=}uhp=p]]ۛf>5,:4PΧ_GO2,.~[J7 ض |?ny^n׾mz.lrYsƖ{6#*[emXv#,7k2nnI؄-}mK#pK^5лkzoSZحT<n8)!\uC>XPٷ| !Uو|%a}C:ys59Z,L ^l'&AAAPl[},Nl'Jp׃d; Ipcv C{^ӿ~|an':C|K F8ga5v8k@po.|3!n qG1osz^qqqC877 u=dAos:}p=C87wuyM=$ffnPos1ozy}p'qpm>+##>Qg0=}p3\wl/Ws?uw ;p%rp%rp?+WBz+w6a6! u+1\u7>wz7r= uKͼ?=dA;xv\}vnwz7 uK?y z(=?Sкm}=a{pNEۃg~3wF3wހ{$FMYbWIw.zfvtG@# ϸ&G@vH{m"yr# {ywp# Mq=6<nSp# Mq=6<nSp# mSǟ?QO<ěC BȼGMq9Yu=sJbg8s gyw)ۍ\H]3;l1b+Wɀ+J:p Zd5h= 롧t2b,K;q=t2FnPq77 z(=n,sq7s=tc pC7wuFލ%M=$X٠17&X:vc pX\Ѝ%nXK;q=tc pAPdK;>fAak,q:[c p=X@5wuKio%M=$X\1W%c pX\1X:vc pX\1uc pX\1wzFn,n2-&٠lC1p=tcۍ%uK[77>&AAAPl[}܍cn7X\Ѝ%nXK;q=tc鈻K>}+?ĬJ7}+ȳ1J+{>.Win| y'ۖ)SnKʔ)SM"\_2E2e p۔)•)SۦLL6epc:Pd[2E2e pA٠bCz)S.n2epc2Er> p'^~F'dЃ; >9fC [|r>9:u>9' >9FnPq7 z(=xwp=C7p=tp'^n'dC2;|r͆5p c|ru\upc wzpAPd[ w},>9fAar>9:[p='@wuio}rM=$ONn W|rm>9O~pO''\upON}r\'d[2ԭ+>9fAŠ >9vpz>9}rOɠdllC6-Vxw+>9vpCup}#'͇^镟^{zW~zW~zW~zW~zW~{zW~zW~zW~zW~zW~{zW~zW~zW~zk8vC՝Ko)? ֖k+]<[{o6um{۵_'xo_+\>ׇy{xz%/nO_W+I)י 47o>po_p}s{x򗫏ijG^^|~ܘ?})k??rg%2.+&&Mq//oGʹ \uWmY6Ql`;Հ[Ӏ;k^5^pP9i<)>~ֆ?ӭW֔_]XZ;k\\5÷kpWnt}ii1o",#G0a{#0p;]Km>g/= (qX㭰GG:O+9E|.xG8-p7-[ӭފ%su~T\w k.M׏ .?:t7 >mr0=)-s;ߞn 鶑_F=>6m3vW/u>9:|c7Ow?>^b+wvS_qloO~___sqfL KkA֢}듗79>lxo}))|^uf|&ی~Ͷ1ig;Kg%x|R[Kpinzp =nwܥLDpZ p`q`(Ql`[iNn5V4Npp pЀ<9x^(;.`Vx^`S5+Gx<>gGz=opT<,2~@ڦibfڔf =[aULǵ-6^Z?oAHSFt+> 86yKa p[S: c:M~ 2*lƋ/&`7U"\Sb3Ux|Bpp-*BXpԨ"t+S o\ U<w UP9{x¥KFAQE(a\.V6 .AQ U(;*JP[JP;K({*BFBAc0^Tt KPKPB%( Va`pVKP/oχ<a,X:l. bEoN΃4۞p:k̋dO6cbv&9I@xif0"6S.tiiȟtfQl`G3)-iVHxw '4gp*5"n]joNY\X\Ds]~Rܭ.>y?^cߑ4ROt^[Y% Mq(ϻKb; CUx*z*z*xAc]FK5 U8UBr90sܥSk*\UW7֧CrSM>3$ =K5M 2.Hk|X##zr_}mtFگKP5֘ kqƼxO>֦kxS.Yps.r"V))`Eizp1S+vGn? nP!(z\~*݂~ ,Cp\Yry3.n.,BBM\^Nk'#}n>p􀛏)&\%>pôQ!ܐ qڧnNMnlkv-iJ.;=\z4v =xݼn9@=c!nP!*f]l5ԏgG+z@avns~<;VpB^1mrE1݀CJF1RkdhkیZT02"nΌ-ՙqum)TiJ$0+vK$<!(z\i m$@p?N(0=XNQ`z!f[:Ƕ~fA=xzznAaFiNӃkҘ>gҔ>f7gҐ>q?N3\KPw?tpq%մÿ~^~'9tq,8痕Jz3Ix%tsU,Asa*iK|"Op*&rIr Yr,Bl!K%_@Ȓ0 d hk,5!KހFAFTh$d(*Q2(9sX9M!k\fpv_. K%@ȒG dI$dYR ,Bd!K6%%%@ȒQ dF)UXdY *Q )QR 5 Jv{w!6Fkcc%ϓ lw l6BvXT!؂d!wػBmx6$@Ȓr d9$Y,i@.y@.B!Kꁐ‚%@Ȓ} dI?rFI@rFIAXk,(YB4!6FQFErIFQxwIGUh$$)QR*,X)%k555 »KzK~KB%EAVa d V%2?>޾ܚU㯚`i(/.]ӿ=vkFwe֎5m6-n\SO9Amg=#ONZFg-`8-]pN '7]~i<+q} Cط 0t<׌g][{׀ Q<zzl6׀4مӑ i*82x)`I^Nحx{ X4Ah==$x)+W%`32 îN;ZvT)Ҍ`F?awzxsw$չR9='k?Ipr{)w"uo;mq_ݿxvËÅc >s>s>w\u[u[>6Mwiܺܺܺ n ;}k񯏿\ߚ+c/mou{[u{[u{[u{[vs]4ȷ'\c u+npW:<v{K⓭谠nEVnEVnEVnEV݌i[O R;>7w/qa3fx\P7u3\7u3\7u3\7u3e$ve1m2Z6$lr.mrp;}v{Y`Ǎ.V NtNtNtNtͰo~sxRQjgڶۺۺۺۺ}v}7ޅ=݅0k{~ icFnDFnDFnDwu#Z7ڴrs;?YVLo/n׬fu7\wu7\w×u7\wu76Byla^_zIFvi%̳oW6~եmv quO\uO\uO\uO\f*J\!h ԝs9םs9םs9םs9;-p-Xij]ia{t~ ͯa/1jw5ktMKӂ^?mrgW_Ƈ\mF{ZۑIO(Ƙ譜h8#&p 8*qTCр6U/ `+$pk&m=x^ >;; ؍x^Txg5Sb򼖁cqw݉O q-5q(c|k0qNaDM$}VF9XR*s&p̟<:?QyfSt'#oyVpi3,rx >菋GϳALţ瑷Va[z\f< &hT U؆6 gXpik*U: w-7m5KN+T55 ]FK5 U8UbP)͌x)\9K7Sy%:+;m|֞^'׎C|(-/O.xv;dn6~\c{P^oǵݐ=^u~1ߟW]ȋr{cZLui8|!qqAZ9+R,Wwee]1%qu >յOfţ:.^OKv8!qq>)!w*wܺpKwf;zSd 1{۰NOv =xݼn֏/L}~χHr!(z\)58fRfq0?NazHyYYr`cͅ_r8h"p#}9&N>p}Q}Cܐ q*"ܘ~+ L^5\r [tSp]vzmrcq= ԃW+OzǠCP!*RΆ-lRʆqN?elR=6fmvt 㔭z =d qspSyEܜ!\&wmFwkF.үnr4i7d8mL4LS+v맬+&z =D"C0ن-g[8egzHRnͶ u܏m8efBBBAa[~l#㔕azp CJ0=8r2nS![J0?z r 'Rhڜe['$Y“vy<гfM6 ܥ:|k4`ïVVjtNzNeBǮ8u9 淢t4pp߾vwm);֓0j{RUo)jzN  UxnEQWB 8yN5`C(R qkMLMm{`)iKyS;bt |+UE.FRCd|}y8lNsH<7g56=5|Q384v"l@ŀێA3nXZ_ \I/P&7'7'7'7'7'7'vd.w "ܤ_pTa "\G0KnK6KnNnNW+ ݪOA "ܷC8,ZCvxV箝A{5廨!pmǀnmvYe=W+&|~ ACT!r=؆6nd?\ZԪ`Caz-mvێ =xzznAaFǮzH-:LJ=0}!96;ص\=aՑb|д໵O/гRg_g F׳te7 J^ճϝ K߼ymrs4NN .Dj 5XS+,8f)]uddwN/qp'nO&ZW&ne.*۔jN 2we$ۜ!`kz{SAVcNa<;B>;"{*z*z*BAc0^TkKO*᪘rLrU80sxҮ.=M?`pW4 UxzzK]*BQhZÍKA ̥[PE*_^bǕem7_$fiUn=).sF9| 6L) qo2dL)ُ#ۓG.&oQܳ´`OFqOXV?\nsTfO \b \b .4@{\b yz[`xKl<=-0;ilٙ>OOc \b ,lu<絈 |^u =YƔקN|I~Gt@l Omv,Fra7) NٝY~OնW2eĔ&6l̡̥K|_^׋BaS[6ynZ. erf{rv]/K#u^%w SnKFb}%\KFy,JZn7KFy,d>r@l,d)v dǒnP!(z\2 pe,2p-׃%#\ cvIcL#\ЃW!O#^=6ӟk3k3}fErVKY]_r,gu XNl+guEm> [*Y]jJB"`9 { X*guǐX"`K]z~V;V5AR\R`t"NU)jJgYv+z*BAc0^%lOUr˙sl[:Xo[:EXKo*Lj9Uܥ7-A?  UD*qHi\34^̌5CN㚙KqPi\3sij}Kb:SSt\:k5 UxQi\3s$i\3RԆT,4^̌5CN㚙K;V9j]\rTn&7֮ys+?EyJyJyJyc9yE)O{K)^ͼg+\()- RRRR-ۼ<p<p<pB^96pT TԏǦsM=6UsޅcS}8y_޹lo0Qu Q(Eɡ;i& uUʼư6w4q[o+r;\[{>Ƿ׋?AĻ.|Fq ~;]ٳ/7wwmyk4%8-Xd^.LXjWȴ }xfXvTiZ4aZf'MxY9ib?''Mnߗ{ŏ\0RlQ@ > krb:7L'>8F:]mqLgVN,\?rv  ѓxd:5\p=8jԙݜvK%̏~Zr=u =g^|/G =cs?vACT!r= [pqk4i.Ӏk{Wܳ^qzȵFEô5\멉=:=4nvgukùZڞqo.(sǵQ<~6nv74g}\k<}Ys)xK햂n1i[\ЃWWW!(즈)SWS( s)k))SWS( njHfz( nЃ"PNA\ELACT!r=EL}\EL}\P>z(cWS(cWS(c+z+ c7(&c7r?.cAMlP>z(crr=)v I]9܏K]9~6P?sxj(V+cR+ZYxjͲ\BxjͲBC(GV+NVF9Z4ՊVꡌrdTe#zݼn2pe#BQPF9s(G5܏(G\e#:2p[n2p;e#zBBBAa[~\F9s(}n롌r\VF9~\F9nPF9qE|?=lIJci+~Jw.+ u="5+r;vJ*w &*Jk3:yGTOxO'QHk3݂ny[ZT<@PZn<@6LbA=xݼn=cs?6ACT!r=؆6np?qj`zHRCZl[v܏SԃWWW!(v܏m~Z9XlzH"Lӷ>ymjO~Z ,zpx[?ϏQgL .|&:JU;~/0c1|l|G>ꨏspQG}먏:cx>Vomۙ1?.Sm=ϟn뮜2lg;1.nm7f/TS~4QW^jc5>7S,ҏL);'\ -y~sJQ!uӂGlfYak$oc]o{z{\ޫg{sp={w~ޫG#W;#yzD^="\ȫG䝃'G=lΤnpLY`tvϸ ]⨜JjE}z{uxOo͕iO1mZ0%%yۧt,d{-sI |vs4~:<\#<\ǘ"6.O1X ,1M< UU UxcpM4TEl*RF"3Ƌ/%KG]: UĖ"v UN _m?y'ozW_yG 0ߍk/ufvacrZjv* '\N \ݮ=_{Z ~[9+ibtf19bK7ೋz1pX:•t]g[WnKy,KGM~,czt)v >K?Ba˝~<Kaa-ۼp;> =xX:•t p倸}8vrq+nP܎z yqTBQ o85܏8µ<+9 p[ٓ4e^#r@<+bO n^9 pqkqk݆a˝h.ǝ9|=[֍IeϸٛRn[}n<,Y\'zvwkA|E|b )V+e.9?,p4az9,pZ/es˳p Ci\V\B\9,p4ai\[ AT%  ۭ q9,p[rX&v =xݼnr܏#eL>mP?ϧùWW\J\9,p7R* pL$n* pL$mJUv\* pn^a79,p* pBACz(esKUǥ* p-CJ\Pv+UIq?.UIz = = =݂nqJ2* p CJ\Vq?.UIr==,ͅa(Rldb`~Qv:w%V'J]϶%kٻk@aQ ЖpKBc[\ 58zn\ Wz =D8J`p%0q=8n%0܎q WA+ q I`p#8J`p C v+qu܏K`p[NWMs?.q =D"<0ǝP?R=qmqz =H`p%0\ W8J`p%0ۭW+qmJ`p;\WM+q =B%0q z(qu\%0-[ n+zzz ">p=8Zn\z(=n ߿p^;}vZL< ?vyg/^]<͹ΞF]1. -JzU[ǛAޅi4s6aZk& a[&y0Q&jDmXpk"/T&jDm  nmXjDm ab Pm&>}xͅq i2Pן kӁlYf:W8?#fGJn vo~]p^jNu*_qǝՀG`aboౙDZ+r#[Ck8o8%v sә-x2rp pl{ S^~scw?섳7-&*A|↑^{rs^^lVK_R-1Vޠz\rkwvX#\'o땻}:mm]O͢koeӮôܷ5L[d[+y~\%ϿϭǵZO<=ۭZk=Zy~ǵߣZznAaH8Zq n=4_kzǵZOEpq??yۍ~89u\pcZOk= Z?ki5.%in=5%?Zyq?. r={J}MD|MD|Mįqk"&k"~[5&i4ܳD< З{ p_D=i^~l_-[XBH2ǿh5IŐVC:fۚ\x9_k7m>DŽW7ngrJnpsnp%ϕ5mq-[nvz(.A~&y+2Pt:Ng{gX-z ]Ĩbp[XD1[XD1Nb7؜`\{/'M ?ɳam|4a?ɳq[&ٲx ,;.L>r2 2L>"`|.L>`|D2(X;+8L>2e#5`|csq ct+v|S=6SΎ=p {- bx| &1Bk[n?9tW]\5)?h\09k Ӛeo^/Z/rkk(Vr>Rr>StWWN\)ܠCP!*):R[)\Pq=>mJQv܏KQzBr^):vSt7r?.sKQ>5\nu܏):r=StS+vSt~\NܠCT!R=O΋P?zznK6/܎pB^I&$Wɀ+dd2J2y[ܒL\I&$rd2J2p% -CI&nPɀv I2p% ACT!r=d>$p?.d\% $v+dKC\å ^^[P-r?.}nI&sK2p CI&v+du܏K2p[L07?[Tѩq?-_P[سDK-_ vMa(Elm.vQ#\ Hk7mZ <> UU UxyMp̵(Th"ZƋNqB媈BSk'6.]Bl4G*$ȶNA6hy vy -V<bhoi<^ PEQEPE/(KχYS 4\)Ua WE Aˍ"nХ.BnPH17 )T5 6=wv UD*"WE Aن/EޠK[]:ޠ*H7 *R ϶ u w~ UU UxQ6rN!8 pUTEj`p<’pxGXRt AUb}:ٿq=-H5W-kZviA imYup;|5c7>ݕ۸k5 OEt\kDܐ7!n*6#nj{5#"njkK.Jku}mghpE;j +vI-vҏ2p C2pppe6l+s+vs WfnP!(z\2wp}@[ \e::2wp[n2wp;e:J3ߌQv*3AiѾ_*3 W$gE\ Vd&h[ +1U۹j;WmZpk;k\Wڹfܳ~.~.pϵk[WWrÕ~.~.~.mWŕ~.J?zݼnRlACT!R=J5ԏ&ku&e&RͫL~]H2,2+H$w{.$ gd헩+/K~5,֞^g/a>W{+=J`p%ܖۭW{+= =x$BܠWz疸J\p Cv+q=u܏K\p[NWMzs?.q= =D"<7iq=5ԏq=T:y\p[:CqzO=W8g{b|D3=^ܼ扐zsrg1vO\<-QP'gX~;vݧi%4kyM# qUn~noqۑ"Xov#!n+7uذ0Vc  pNJ7N#+t\;zp&wzpYnt`8g;eozC޻q pe7z.Kx2[ pBAR.WN.˩Hl6n˒=[3F9ptWN@\$ +n}n\oܷtQܖۭt-WߞEZܠ[P-*J 踒.@u.@m}(]q.@}[;v}Cvξv- Զ(zPۢpAm - Զ(zPۢpAm } }ƾ6}Zfimqߝƾ/PQ]xuܧ_|׺ٙn_hv,3#ӧi>?jiŒiDd;>ܔW_ lqM\)ܱoCwKnBos-W_̻T\)ư]9W_?Mucq%g疜>WrV+9+1vK p+9+m܎+vJ pSAqm7nH{0o)ge,H&f݂-wS{բ|zkmvrzB雇]oC:,(,r?.9}nY1=n+9+n+9+uُWrVf=z\>1ɧZsV{܍P?Ymq-Fj6rV[ܖm#ŕm~|(Jp#yhkཙs@}r@/Vs@[\Zh+9 ]mq;Wr@Jpr@[x5ō =6%]mq r=怶a5mVs@[܎jhzXmq{r@[ܠZh6%]mq jhkVs@[\x5mVs@ܒyxukrlۍ-tz(ƀkJ1J1\p zidp.%?ֲdWF\-% AKy[# n#nqn^a7D7(z =D%2Dq=n%2\ЃWWW!(v܏Kdl["c\P"ckJd pܖDgQ/7pvWr3 z.|ׯ5~/ ^a7k.W=XrBQ7np?&G^2:+7pyŻDW.,}n<ϝۭ\ǟ;e>cߖau`~z yz)z =D"Cϵ-p?.r=\|.m|.s\ЃWAsnЃܠ:s|.^5+zdlV36{;dlW26+>dl%c\v+ Jp[܎dl+v JpBACz(}n~\26kJpCnV26q?. =xzznAadl%c-5\%cۭdlq?.mJf{yzxql;~פ͒V6o-nyF㤍2Hv1H^:΀+g3Jp% p\ 86[\ 8jj-Q%ZZKTkj-Q%D(Q~W{QcKۍy!ϤCX^cooɵ/e %BqmMo{k`A w84ŭKD]Kw.-wiKw.m.͕]Iϥ}5[3ܚܚܚȭ"w?\8׫kjCqkfpkfp? n MD MD MD Mskh&~ķwW.vPĒ^&Qdy= Tգ>@Ur[hjH M M :hj7텲rwEFQQ/բ(bvAAAskF>o^qOݏf'?i ˵_z?tZTZZG0z8mƵnq-yPpB\ Wz+A=>%\ v+A=JPp[܎+vJPpBACz(A}n ~\zkJPpC nVzq?.A= =xzznAa%-A=5\%ۭq?.A=mJPo[z27TeT<Ҹ]rvQٲ.®uge~D/DW"+@ Jp%\DW"z =Hp{$Aa7D%-@ \V" \%B^a7D~\"z ==#`DGAY~<zGQ=#R?G~\jY_-[ֲZWjY_-ȭe}uY߿^xGȿ(ӂ~tK}pgk/ľw}7\E}<{1==hǏUx*MRbIQԫط-ǿ>n^Ysu|,:-HdU;kd| {4 |Z0|Y{lX;#V.,l/N+م%xx|K@ͻv Ӏ[Հ;Ӏ5^5 8*Qn`>Bo/䅗adn^q5\5\5|[5{N>k5[;O8xŭHV s([ _xW$l;MwJ*x I`wе6mH&s% % 9JIV7V WRS+UͩU•v *JjpBACz*9Tt[R׀knq[n܎?KpB^9!p{|P 頀A%u 9uM로 ۭ q9p[r"(v =xݼnr(܏Yz =D9{y4iTiuTim}ӀQ?MW+ ' Rr'J)>WJqn.!\)\VJqWN\)ܖ롔nPJq+vS>WJq7(z =Dr>~\Jqr=Ru\p[nRR^CCCP-(R}n9s[Jqp=RnpR-C)3n=y­Ӌ>փ;O[~=Y\p|>Y<փ;O[\sy%zp"?WY`p|.9؋|.9ا\­s}n]`p|.9؋|.ྟst_7Ͽ~af7Lj+ke9i -Γg4]a(}ls6زx l'pqp{tL;l ql*{Y xtN/Sr}..@ 0+Xއ+88Cڊws膀"ppG1شpM8Aa޵c„)@f 8Ȇ% gֻÏfĞe |˸໼v>'i]4`X5V)󪃬gaiϻg\vxᆴ]߿-|Cn,{b.!Φmq݅Z8ĝqcLҬOCIOf#$8A6ÿ<~o`gc췺_?]l,ge Ʋ%~ecI{\6,}pXpXl, X6oEXl, W{ 8ppXpXl, X6k!|M57~0?Nȕ ȅ z¢.p G.,ȅȅ޼Wh$7%2#s+k/{ݑyP=y[\Y2p{n2pe#Jpe#F2+7ne#ʼG\e#:2p[n2p;++zy+˼G܏˼GPp=ykʼGne#:e#\e#v =ԾEׁ >u:2uz2u2uԾQ:Q:Q:w/.}•]}sY,S߉wb߉;t3DJ7N~\w"Cf`߉T}'b뼛}'R?. ;!*J7Nv+ ;qf`߉T}'R=nq?8>f`߉XBBAa7Ww3Dǥ}'R=nHPw"[f`߉ԏK7Ndz}'yyyG]w՞Fh_Ia# m3_O.k]ouvQo5 ٸ_| bT Wr/Vp_•3~7||n"\y7n"NW-||nP!(z\R p R|z(5_{Y~l΍˵_&Ȍ9/O3dSdsddddd,2BL"T"\"[6$[N ɗ!rd99k555 »%wFȒ<#dɞ!QhCgl ";wK [6$O}?},m7K}v҆^]Yuw0_:wXGiv6&"^:wo#8t-Xg#C0r; #Eq#v0dak74;4,2m]fe/S:᎚qTKN!Ϡ8Ւn$zv[]df- \Yna-[uهzZz:n^aqwwz: =H>7n1>5܏>\^lq=x[nt [8F zBBBAa7̮Xz?~z(kJ'nGp;nң ^qJ&݂n?K>M5J&Zң hnVn\ЃWA eWAd7(&E2}n\)\PcrÕWnq4p2p0p.p,p*p(p&p$p"pBa^ǝWzWznK6܎pB^){N_ڗ}n)}nppp[RCw\WM]Wj]7(z =DR-U.k\pCoܖۭTnԶW+++v Eǥe[JZp Cg\VYq?.,r=J=ͅq"2Ɖx[GQu X|*QuD5QGM,uԄ|*QuD5QXGM~*a[1ı={߭}+eZwz]qxo;-X4|1~%MOl)IkS;s'3!;pRc 1b ʛO{d !̛{dyB#ΛR{d} Л{Fp Ƃԛ{d34NP !8#u_x5pcړw1f<}ʀx+\BRBrs حm(MGsu.QE7r(ȩ cX{KnS]O/y2|~{|p,/]p}yjjQ^quv1=OucJ$96m3Ixv>abql۝4Fu<}VTRFloUKgNk.DޛRI&rKahRK#qgU\)B UQ'7gʝ7q< kӌ27`h?OӣqіWz]zm7+0wLH.λڑ{r C=p\#6nzGF^_mpS`Dܐ߀z< `jS 2p-n)`nq]n0=!Az yR!z9(=\z =<b6neŵ3H.f\geJے+3He (3Hw -6eJe 2p-_$s ܖ?w s \[ ܠЃ`nTA e> \ \Pfz(3Hv+3H~\fW+++vS|ϗ$$2p CAۭ \?-CmCm^a7[6ܠCP!*{6\|m6\Pf{6\|m^Ѓ6^i$ܠ66&+Mp=&klu܏lmlz yݤa p{ǥa pBQH0oXP?6\K0oX\G0oXܖmްyzBR2p(pe JMl}n)I&+ +Mr&++Mz(Mz(M+ޮَHӽ}c*jQۦa$ǼQllGgUH`*,u"R}6y|THܣUU8)n> ;)YZ/wZfōw]B2* 蒲 RQ!r Gߑ"6ڢ#;vGߑwdY|GmwdY|Gߑw{dY|GߑwdY|c^e Fw]ࢅ:Aj!T .p\?͇y{8Gh>͇p4|8Gh|8Gh>d{ػ1Y2Ǵn3}dܹW6cv^>_]xM~m T )l'79@9B9D9F9H9J9L9N9P9R@* d r QhCl"" mHG6$j^cA` :@ƬƌQ*~*k! ڨ<` VqD" 5m`"h"p"x""!KH%99VaA+ r, r, ІyThC 5 ""6FFBf d3 Qn4 UhCb ڐh" JG얈"{6FFFAcଘy d =(!D JbvK6$'WA7_ܷcoԄoi8/XNٓAXrW |8x8]1>U XXcu0R*?`?(E Ǟ؏2W%M^]C=➵kA}Nhٌ>'u崤{0py~AC6odUX}yc7yc3M2^q m;p=[\]K7kZo.5Z{f~NG櫿ݿ|/jWhi@h?ͣ?8sa6C?vڣUι[W(%K-M&MZ`CdSD<_"sEnc`ß!0+X\?<)88 C:w oDr \)|+ ֓fgcLȯ*7֟|fW/NΌΌ%z|z~u~{/u~qD8,\9X].l%,,Kt\h.K4MD#0e`Y xR' 8ppY,w M,heR~K=oM:^ʱ up]ww;upsA߽/ R`KUث2%ʕ*H_r-\)p8\)r`'uw.W '.W X˕+}pRJ˕+_ER!I4J+,W X˕^=:kWaOPm-YdWJEF ;7 x׷~OioF*#7#c ,[Mp]6mˍq㕘qcmږ== pcA qWWaa] q~[nPwms^E;!u2HC\\{Pڻ]t=vs|-|~g;0'N,<64ˊ9< E~4h%o-hR=<2mt9]pE߬qzXR=#8*v M9]p|pgp#t\ o^p.4%S/Y@GБ=,# :ns,,,# :,# :,,|xGQy|>?Wc_>Vg7\ŵ<x])gg\>ԗ9RI@ *[t&fEuK(; G2gp0+e_$főY0<+<8x;asJa3oXR[LoKW$a/X*bJ6+ޱq,UtidLRչ_ݿ~wӷ>nq:6WlC%+n%ccy9lG-WEΪ7v'EJRf3셿mXoAl~\4.d }n$\ܜ-H-9[p%[pCJk"ܐG7g!G\B\v[z ğ@p\B+销[)ptJ\%pCI܁ۭSםN ^CN$INIAaNI3ǒN %ps:%I$\&锄K:%ZN 롤SV)wSW+0)0)v |t>W)Sz(销kJ:%:>K:%\%ǽjyc+\֩)Ӏ/{SN|tjg^'SʵxI~y O%}loWq}^ƴM{uyZ5^ĝw\;e;ri$<> |+6gxV݉IF l4`px3vI𐻌 ~ߚ <m@C }4wӺ{3OYkrM.G6 ؒ vD.'D\@!A#`c.G^a<1ޔI.;  U*f*\É/@C[ lS:XiUWEL57^5pJǽ2Tר"D$*xAcO 1%b^7c"@UČ`6SF03^fS:&)=\1b*ft x^cbsP"EJN- GKãXa  #,*7<8z5'm *x]QWB@g^&JOb7 4=? =?ccs g*Ri g?:Ƌmvn(><Oo߿kjt7^Xo,.4s%ۜ;l+=dC &:]81JwdǤ/sے]lsB^qr!<^co$10`ӆgUUABAc0ޚt97/cr/TEeɽP᪈ɽxƋɽpJώO U1\1bIU1SQY ),^d: O麴[;xuu1ˋר+T1iT1)T4 xJ%Xb "z*b1cEƠ7/VS:yДeƠ*7"8 1WoRLcS: UU\0=qjcpJ[çt,7UqLTE1UĂcxvPoTLcS: ULUL UxbJۙOXv "y*b1cpÒqx{X7MXz "z*3˿y#ߍx0bK𑩪5Oʦ®ϞI%.-F r /sWvrkr>wLvG뱹K#m{g>VWO^g}ܐ/BӎWh}6`N1pcoea'֩lF:nlCp-[l JgJgJg yrg•6z = =\pKg5|6kJgu\ n |6z =L =L =݂n3ǥM+mt\P:v+my\:P:%1iZrHθϤs3v>#kF3O n4ǍōO7>i-n|n|7>f7>ppōٍO'QAhPlP?o7'>cX'NdgOў=!g?"KW{BD\:YzQht'd`oO9 ȃB@Q  Xk,(} yR鞐FF3FKll6";*4`@*<^ F r r r r r Y#Cl`"h"p" mHG6$d^cA` r rh#h1k1+!B""[6$N ! 򠰠yTn # hk1i1i4  Ί-Bx!K@BR@d)fyPhC }r,7^<ǟXưčEjU xQNo~vpwWBU&|loCZn]4V^Oy }zd\BR+WwmFqZusg`f % E6gks%.svk#X˭rvkӈU.wmszBBBAabշ8{顾gk+]\.WNo-Wv#=x8O lNSkJנ.76u;A]nm w8O=kOkJ.7/k9c79C|mcIwo)kpE+9g+sScRpM!v{݆\[@v._\WZvCrCcrc.^a7۔knP!(0+0s=?} sC&Kr=x)+sm懜s#ǥ$zBBBAaqɥsKI>Rz(kJ.%:>K.%\%pGK ^a7qɥܠCPaVaz(%ܒK K Rz(;p;y\J"W+ %L+%lJIkiˈXj".5Rp&JMp&JM;ŕ;r=v IMz = =TuM&Z&:&nuMD\Pj"v+5y\j"Pj"u*'/߽k&-~ ??|_ۻoƟ[cʖq)lFI}n gC gmܛezeWk.vZq?1/֗?qg|#?{\pd1Ǎc:-/W۟wOMdnw;TJI;flqŻ \nxWۀ+m6wpŻ \nxwVaz=n\Y Wۀkj6:ڻ [ܑڻ ^ЃxWۀ+m6wpŻv[ۀ+m6Zn\nxwz(mwpn^a7nx7(zzw-m5|6Z\Pۀ;p6|6zBBBAaqnŻ6\Vۀ<.mwǭ77owtw`,>edZ> tv^8APro>&p%p%pS ^~J7J7݂n >~~z(߀J7n%pG>K7zB B Aa7Iܙoo5\%p-[q8wz(qz y99AYvsp ǵsp-C\GP;wv;y\;+z8sp9\q8ssp9\V+q8\9#CqW+&q8BB3Cq9\Pspnܑ\ЃWaRaR!(v<.>8\Pk݊sp9Cq9}8-9׉ˢePXlMˤ[6QLf$\'畗B9)6;nr~omKي_V)o%EW~n.ER ps63J/EW~nΒ&\)EJh ߤ1`;p|) =xN =H? I?<. \Pzv+y\PЃW+&wܠìLPq:Z:h@V4whW+0)0)v tǀu߾>474W+=W+W+W+Wv I>BB3C疀>K@p-C hz( J@pG>K@pB^II[Pm4ҏ- 5\%ۭ4y\;p=F[o^{hg]uū3>jff(̬R? -nU=MP=]w ױkm:.w.ܵ;A{{(A{{(A{(1(s3uCv 60v5sNqr`p7b;{n)AAFn^a懛!7(0+0rH6݉pJ[K1 |Pʏzu6x6/J785\Z(ut܁;|)+6y\nPA€;+ >sK785|npkJ78u\n|npz =L =L = pg><.GE"Q`=*l莊GE"QQ@莊GE"{T$GE" ëmwv"'XsK)ٛܶz xr0R+WWJnPBJ\sX:nVJQp-[RJp \ \ zݼnRJp BBRJ-dr p>"W<\Q }:\A 3YR}n;ZnrE p_w%%% y&>% =ffR-r5|h9Z-\P;ph9|h9zBRp')ݤ)|R}n:\PJv+Ny\JPJЃW+&Nw:ܠìLP:qh9:h9Z:Zꡎ@VGw󸎖WAsa]p%ZRp%ZRp%ZR}n:\v+rR+rJpG-\WMJD7(zzJ>Dy\kJpCV;y\z =L =L =݂n3%ZR}nz(rn%Z-܁D{\ w;7p7k wnƖ;Fc7 #đX+|•Zc+7; Wjnvnov(|I QWMjnvnP!(0+0s=ko}8 y,|µ\'\ |=l6)Wc}r>t|L[r17ڴe̠C3P|U g:_S\ov6r+ȀJ62e# {-d#^6r+Ȁz[\FܽlWw/ŕldFnpK6rJ62e#m7ŕldFnqlwzFnqn{-d#^6rzFnqgwu6rFnq ǍlR=4[\GFnqjF6r;yFnqB^F\F\F\F\Fܽ nFsK62J62J62Zn CFܑd#W+&Ȁ+Ȁz = =\%-Ȁk<.ȀkJ62: [Fܑ㒍 ^ääCP-(6y\ܒld5\%p-[F\qF܁d#z-Not.)wῈ'8'V1wcKUq=F2yu[ZzywʟGY=&~2z2oVA.ڋi&ߎE74߯OG+y3I9G%Äsi)Bj6!r00dGgdyF3r<ZFژ0Fܙ5\'id\ C:rhchcVh# '&(fwXw)Ǵ9gw AmAa0h,8*fw;x6b1S &SLi7pUvJ~7Jei[^Ic_=/}B>R/G~M>Rk_)#E&)5HѯG~x|#E&)5HѯG~M>Rk_|#EN<>Rk_|#E_KI*_p~OM]c՟ǯ{Ik1eq]mɌ2}^OhXmd)9d X8&x8W`#_K.6 UUwxrNM_*<(Taث Œ UxxbJOi4 UU\a4=qŎMpJ[ç UXUaBqUĦMxvPoTLi;)6QUx*&*&*xAaY1̧tjp' gI-L*,7s)nP TOo=C/{8&}߿7Jɖ`њaahk}~%br￱lIhSJ]Ƕ-LZ,͛ 8x{ɯyW?޿Gƻt7 G3G; xگIsW?έ\;m_qO}Up\ nI]7kqj^mq=j͋9!ܼ3r7 7䄛Onr uLyolc1Y'3XnrKf.uv_iGz4Ўs>yON=~B!ݞ%Y9mܪ3s+=V} פZ=T= Q=T wvKonuwöZ!&C;7|27yZn/)uU^oy܂wbA5QO;{4I!UCA| %vJAO)'S  pм\xBnsyc%&o8^a:N | <(TXoL)'sYݔ-8C`dxRLyJSS:67dzz`h* iBl5`9m8n;BI0W-oX7ר+T1iT1)T4 ͊)mg>IDpF g*UYn<S9>ݠP* _j3nFߎ?;s&<DR`;D ^ E(<:G&EKp%3tT"*zI•5D,zҬ DRH["RH]U%B*TL\!U WHD聛d"'zV`@5 T 4 *3g>F&:Q8\Rkv)ˮܞ\mgޔבF6Qe ½LFFSb3{\ d3JN֖+~+~+~+~+~+~+~+~+A.9'~}n\^d3Xn~DW2w)~$omm!~{w/EZܽ@X+~v\w-d֙~=n{AR=ԙ~L?݋{y,o[}! [vC?fg3ql~ϱ96?O;rz>p'>pBYǭ7?k蜯7?k:z[q�]]%?Gaw)|.7?i0omUh h 4e4 2mCCF;F["AMQF]Ѿ(Hhklolwh{$hA* dW""{s7UeDzv,kDzv,k=fU+lVrsu+XWe}>..s!q%/:ŪSu \AqGJ-5;re\YhWUpe\YbwX[֗>.k \tYq\ z+;)A ΔDDf\<ߤ4&=70͸xU Ϸ=x1;o_(fԫhFv`;w>z=o7Dz'F2peo&c 'G,v{,z4XN{GbyS VS=.S6Mγ{6{6zoD?hm6-.݇6fG!W FiSz|9[Գou۱M7wo{] OU>[`Jpkft%yo[t% `Jҕ+A\w%,] Xt% `JJ6^ݕ+KWUx*&*&*xAaO+AlN UWEJ@t% `ˍWSt% t% "o_C30C^ :x=v>޼l>޹⿬Ey1FbS?秗atq}Up\ Ξ\=r5pf6ʽlkـ+Wd\ r-rp͎ZsPu7?ة ۸\M`܁k\ܑkg;mg-(+}GYieY.6J7 =x&&nAa5kׄknb]Ǹ.zM/߼ofۻ}8/` `|Ͳ@fٌql5v̋7NruN{#n/U"&/$I ,b֎ݾv+q}E]pzč7([7\_lGh_p}+ i_f^xX^ PŤQŤP:{9:{9L=*Re*g,7Tg7O*RTg7^aJVeM<`]&tn#qY~ pYyjs^)XnHw6|9 ۗZz|ݷ3GwgN\1rZC;>\SͰl*Km?* !*KKK1齼x~)SdSL7_tw_ݹr#Z(յ m5hB; zP%|hI>Z ZZ2 ZRZ ZZ ZZRtF'hs|6;{֪P:Vc_&?QZv=hT=jTv5B FГfU(:"zV)D:uug> FІ ug0\!ug0v\!ug0`=^w#hR(dR)d($4fD;DZBmn(j$W/?yWow/*ҁk׎6OL" ip>/>GwѲ}Fƺmlzn-giFwѲ}FƺMt>^c6hRm5fFˎwzуF!{rQ^mWk8i&n"tP)$`2eDsrіm !hGvv4: ZtM'h5A{+A)sOMz3e>=3BO=y~ts_-Wڞf&m"hQ d4xC*3AcƜ c^& ګ5 T 4 *3gDb4wR($%A8P3:0sb57`ȉ[< ~gn̴bp ҝ׽'yCnFs3Pn<-sw]EEܐgw]B {o~fsqj9-wՃM*?'<9O^=C;fE":_Ϳ>ˮzllu#eܖ/}DS|+fKibi&LO%|P2Γk&%FSdHIS -x4%2ɣk$ۮ$ֹ ]DbCW!]p͏o{FuthJ>ݰ΅ƵhWJ,Ex-p\N&Ν=8&2{r+҂'`oS)'. A|'AOLiM5>IcqSId3 Ꮉf{%G>rȠMJ>uO΁e4i]^UtIJ| Z1'ߎD~zi5]S+G7 O <^؛Aa3F7KO <c0b?,Lɰ~<|.)֏ǦjLɰ~<.%PfJui}O1\4SZD;H{ "xpٟCIO_ܾL74܃F`*> EHڈ"_UBj D*#EgG'N{dbόD|JK  ULUL U{8=S?gH͔*Z[n[~u'٣ﶡBOWH[ϐ7{g"zqmZٔ擇vΝ y}#k'Ybfs>)aQg. (_~Poݎ]kT_K\R'>pt4Z^[7>8#99I81"Q:FmX?od`K3!Q\c\A9^V헙xyKZOEb<8#x:*Ia`l<_& UcUxPy0Vxc{"<!y xV|<<7B᪘xƛo S>0p5U!ry֒p9ÿFU_gԠ>TZ2ip)IJs**gThF7AKo-Z4FhiM7@](4&h1ciM7A4HkD4HkD{ƌfT X!u﹋w?uo-ZE-Fh5AKoųE^]zy^D{y#?u/ox {y#א7A^m4S&hQHMN˛K/o5+_M^QȤRȤQHP1h8k&z Х7A^m4 ) jXzyL˛B?77? |<^^=ڻq|7i,\{ǚ<:j(^o>RֵEɌ*ՠ 4AvQMA;;&Z| wvMzi7c@谳nǀN.>.>6; Z-gjYk ڒs@hqHӼwpkG潃[5BjT Y)!tP)$|=2Pyە13[h تmXZ!H!FA w7Bč̸Vq=@+QBF!J!F!AeƠ1't0#].r@B!P!9m֎ߜwוˎ0M;~#!cy2q%jp(]|898RzûA v>Ƴl&:ݜpLD`/0oͩ,s2^nSY]ʍ7K19/໚99ͼ xNHEJF^p"7ۥ1EԱ tJM8&C#$IX觵yW G+ ##C&'8;M'O%М EZpuPPn?M)bma;/,sm[դZp5b$K#pL-4=Kحif'_r9zɕ2MCN?L;ksrC ~; !YQ 4OAR݆?;73/+'xJ5FJFJ}*'g'KxXVE${tUk*Bwg|jQ |ўslrjNNFν *g,7{ν xЀ 3*TaK*r{rOi QEPbo檰'Miyыͦtb3UD/6SExdHe*f2xbOeД^ PŤQŤPE/(7+t*.tqHe*Q"ApVa}7 7N;Dўgr?CY[o_QōyZZ\Mܘ,Eo&R { #=HۃNi ܦĕ4HH2FNynnٕ㶄;,921"7fp#::1vKm кcr̖p6:\r[pGԓLf'9Qõ>pIx@\3׃\|rp 6j r=fHR!p׃ Aac;y,1+0)0)v |ۙc))N 0p=H µnRpRpMaXB /b%ym>* y~ZssNELkwgXӘ3}0(/\4(;tsσsvVaڪVv*ӠZjl -56-56Zjl@hARcAK ]jltAfG!%\J<ؼ ?Qjl A#RcGJ U I*T ="56F] hWA[A;A܌u DklW)k22iTf 3|56ݯ]]c;7߽x>+pM6CȤlqOy6g,US>Uuɉ.Fwk5n'֫*m] BJz2O]tY) s )3g}BƻtgO[غ=|7\<~_ʻ?} \\pC1a,c+ ϿH/72 OθG24Nwôɿ<Ԫ5. .j9mw9GmUhA;iЃ - wa@9wa@9wa@9wa@9wa@9aM{0w zo@kU([ջM~Nh9GNA!7УFN;3nM;3nM;3nMгJ!rst] U>G Bs4C·TGgCip99ju99jV4$(hI0Q'AAVӭfA DrrBh99ZNN-''@AALM:ѭUANNsXɉD99!gS99!׬ DГfU(''*ɉgBE'>>9B}r"hRq''A|ׇ!Fm5 Am=iTf 3|ׇ!.!.!vjo洑O͈P*fy*g/vxg^_I'1oE;G~[5 +?^ut#)CxF|^ڋV0vu^^2g)F߷+X1\.Q `yHw~1O!akepeeX^zulaO:a;hس=+INѱ]MNak&g \OzrtOKfOW(vIq?H-wОnؙ!vLa׏Llvԕ%_ |Xj ئnߵ87{=q.:Cqp\u=3#z)UfAc"*R S OAfB`z p,wf/(,iȪ B*w<*T5 M)-#8hT5*b 3#pj4xۤ7v|o >7__o=d)"==2UI\rvHWnr,@[jNvBK8-9;Wqђs@ВsВs@ВsВs@ВsВs@ВsВs%瀠KA\ ZoedkJIs%%瀠JA9UYJAB$瀠gB3N]uA*9mBv\!uA܌uA|9U L*Lƌ3u@f3z΃%0GcQa]ۻѼuiy] ε6";.~w<wܴF^2&K< agqXv}lXyQvkvcHsW߅a{<)8oď+W'Z=WUmʹ=vsa+ZyҠ{vhk3P7giНA=tr"c3N h4k"ł8wC`[ p"<(_v KxepII1^P/C8C5uTQ`mSL%*Jp(]kƛS:6w`St '|vwiV( Ԭ$AO@&O4t&@`8'O|xRssF^KVphBpK8V%~ >]¯GK5ÿ?~]d\*\Cw&JlqUOOt|t.RnI\T$qQEN:I\T$qQEEN8I\T$qQ}EM7I\T$qQeEM5\V$rYME%M~A8Y=ELoCL2I\T$qQ!EeLU1I\T$qQ EL/I\T$qQEKU.I\TdҲ% -I\T$qQŒEK+I\T$qQEJ*I\T$qQEEJ(I\T$qQ}EI'I\T$qQe-LͪR߬*C*/}y`v>ئRg]>=c=kRܾr0X\ rWb܀+1n;m•76JpNpNpgv[ 7 7 R=T;muTNpjjM#NpB^II[Pmiiשs{ô]oc{>,E}^g+X{= .ͽ m5hB; zP%2z$ GuhO渠%Ŕ'2-I -@Z=EZ3n%t4%jJfG!WlZހTY6F[F{wA{F>^hh/hh4ɯhhh4g4 m3vFF;{A}Fͽ>^hh/hh4'4g4g4hN;7 xw~;+kg3/^}ӭb Bq~c3&M??W. CKՔ6iqmƌcNm;ҳ$m N[+,d^}J-$Ur=z᏿Vm jc?wնߵ{_+qn@H6*>Fh?zxi8u+F}j(mu͉c[m&}7I;|~]@>zsW+ƒuX7BfV&.q#8jSиǙ*f|ڌOKuӦ%]p\EAis<CmTK ʧ pϨ!bp\kq=θOp67 P>mzӦm?mB}Cip ZnM﹓?_]q-ѯƸRU[ծZ~BݪqOM"oz/Qk/^ԗ>[_*7e(LYfv>oOߦJ 58WoD"敫Y߽yqp<;'2q;EV75ѿ.U7i M(hh@FCS *T d44U M(hh@FCS *T d44U*T 44U bT 44U  Mhh@ACS2*PT r*g9rA#}t{(AS F`0.Gt9 x03F^/Q,R,QH1HqGo z`A&NrX\@09?I׏Ӥ}0/~qs4k-Ż=Y UCɃ   d4B(h(P1$b^$צpi_A^KQC`s{:Ŷ%47 H; 7ya[X] v~ue+]oۍYHm(*vmH3M?B={^πa|(@f2ڮ;6zpy^{xp4Ҽ3v*|~ޱ@ ,cv;=+ $qz'dpr7 چޓu4otw|&̹u#ɼ2eIC⋧^ߕfu5bh[67m:,+S kNc<,~%z/ط߽ݛίᬲ\K1y{YCq;Cq-ZqCq;̸c29?^좒g%orp ~V"0 pfpp EWoKT݁\/%s6 ;[WYevopoӦJ,h}m jx]53<+XP ƌZ04Ԃ1 `hcAC-3jXP ƌZ04Ԃ1 `hcAC-74ւ1 `,f|{vï/.T@RW҃vmŇ3=_y~jFl继ZZmET;vS A.O5]j<tyATCUYXתVY~M_=j勛?9:͂:͂/nB q`, &q`+ Fq`+ f`+ fq`+ q`+ Ƥq`+ q`+ w}vv5+޶V?ܱgZS(Z[tZ+CbUxϿz-^,J.pc }dj-#I@Sn 2^S9dZB6l%d'!; }P Yrͳ䚃$(!G\ޜ}N\^55>dbl%J3i1~ArAr͸b/FV,ѳYi}VZpDJgSb,ѳY;%-Ư8YJZNђwS䝢%>%>%-yhjj/!{ YZZԒƿbl$A#y{HރHFB ы7x3CK6V |׶}#:曵ۡ-mh9PSljxmiR-pݤ?.!7-Tw ur(\Aܵ9ĩqW'R'µ[A>0 PANJqv2\܇UGzޥ #;7="]%H),M3]6yKn>p en 'q3n 'zɤ3]ֆ} J -)dn'zf ol6aTu=_b_wCw Þg)a zoo}I ϝ.7= -5DtUDU -p}qK]7w7ǵ}7x!\~_;[p\pُnAA\n)}BZ2a\m C @ɝPN!\A<擖7DspöB!O~QAOM+܏"*85-A\[t9܏xcz===݂ncq?"̄aCz0 ͇\!?6-XT[G...\W!.gӘpEW}e \>%p8#WϜCZkC;ٲ|`Rq2R8n9p([!GC_q4! [-7*CM-]nQpՉvV;1ٸk7ܴwOf⃳Q^>8kHcJf=7uږ{ǻw'CQ8b鈿w |-p]5̺.~W[d4s<| @h1.ḥ&:Q<|@h1ḥD!13RMytChI1PMy(jṚȌ^bYہOѩ'+$Wy,RWA) ZM!!t5.E'.3tɛC iRÎd1 r}7+G1t!MBo03L:VIch-PHɧch#PHIch+1<#sث$1(d)d($$fGߎa^z;7)1(1d18zIch|gwލE>>G#||>>G>>e.mKŮʡ;zc`f=o]r?O ᳂mq-C1xCoc=c=c=c-zG>n X^{}{^]3/9ZLY{~\ӛ^أb9kۥ#q_"{~~IKh-Bk ڈF"t9 f4'=A;dD]D4'=A/MIOKAytTG/MIG 'qO%B6_"O$'% D%UON"'"z._"H˗&'%H!KnDKA+~ h+AWH%-nKA;/E "ČwK@/]D:Q?q>~ t,mGj:m.m-"m$h+BM>*&MA;de&AM<.x]6ltC貉u&ABӂ.&=&HRqM<&BM<9EE;"UAƢP7z<&AB&AGB&n7}tG *xqxmpxmq3xpGo7ڋ% E % "3#&@Mfp]ಹFeo[.Y`xj}5ȓ<ˮX[x;e? D^YY 1^/.ຍu @i*%O~xso{Ooba٭uTպٛ.[Jqs]׮ O_Kl*['l~r[Z,zUku+u, EWtEɎ(ZJ^D[ گhP|id0tM?U|;=u<'4wiB=jU|f"N'9!;h-n#1ke $ڋU׻C`:7{i7]W]Y.f 9;$.{PvϜݘYz3xv0B>ZV%][/>R^~^6sHݬf!?X!tVB`.=v*kڭbmA[9ы%f7B9{#"BH!Q?I' c CkB(B([I;{y>˼:r:d9A儠c[ p0mf-jB89ssh2: "U[1v[B/ % E % ):H3[AID![SH3F}0c]]ߤz:yF+yl\Ms C,a3ߒJz L1xs C"H!C.XtV!"YRrƈBrSH# )icȌ%o ᎞3džD^/Q,R,QH1HqG/dK TȖC%A,2%fTZ`Fe$ѕ(dM D!^dF/1,q=%aBH!Q=I̘8zJ @!۠P!Č)I];k/R(d)d($$fGOI3 bD!T3BЌH+Q24֜}v1cLE.-"H^>-xS)Dge?vk9!4kwPnYUpXMG'H&naT.*4`p=!Xn p?z=9pgB [9q?SNqUN\!jnQv&8Z\zCt=xݼnθ C! Q=P.f6 pmjTmTmZnm:ԏ-=x\ptH[6OM}n *HKVZרiժuq)-h"j:,fa=xݼns.߀Pʂz=D"d7=vKX̏8b1=0RӃ6R9܏8_A=xffnA`+3zHVLFzHVnFvKqV̏X\ƢzgwoΟ}5=*e}e,)EߦCjky+${pT``*tς,S{lEY<^"Rz OK%8I<J%z:p[`%PE-Z`Zj RK|T% >Y`̒,y0Udɂ5<*d KLXc}%+Y𱺒3ŕ4Ti% >VV`*y0UVɂU<*dǚJLTcE% *Y𱞒S,XMɃbJ|T)% >VR`u<*d*JLQc %J(Y𱂒S,X?ɃI|T$ >N`t+'y0U8ɂu<*dǪILMr`fS%,X1ɃI|T$ >VK`Xk%y0U*ɂ<*d:ILIc$$YFS%,X!ɂILG`<#y0a!k#y0a!+#y0Uɂu v=/[,qg[v'gW<ڧ%5}fmſxg׆.1mR  B<#@8#@G,@-2)M=\f]Ғ :T8M֡=wv.h݁}zqOدa"E{U`kHўa"E{x )y[֋x )eS<ρ= z`*lρ  ۳`*lρ=  ۳`*lρ=  ۳`*lρ= s`2lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lρ= $ `&lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lρ= s`2lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lρ= s`2lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lρ=  ۳`*lρ= s`2lρ= 0a{GX=, ۓp_ޕa#W_%FZ{{U_.ӯѩi{s_'z@O:S :HQtQ޺co{qST5ۛW.LB.#.; {e=xeLj\R*h^[/_)eaXe{۔yXUkVC~B:# ]`G%iv&ХJA[9ы%f7B9{#"BH!Q?I'ʥ\ZZ.% Zo$ Fo%fVbF'qtBn1æNs ތ{pZB!K Ǭ$GE.cPRx綏qn{>ǹqnǹ#x綏qn{>ǹqnǹ#xGmu__pmT{. Cb%)ީ~eSy;E]R*x}sG 8684 lb 1f g ltrr1.p0p)8O3NW W/N^݊:Y \x}\9pQGA`OG1?`7 vG WEM#`]&UQ8yجy+y<.]8T%*jR<UVָRhh/i lqUZ PH*x^bw8 \:*DQ"k`KkAbt"-[OuV.ɪ-{Zly v٥y YxUUx14^=o1`5PӉ*7޼g_3}pGƲ[M̲yZzۦzjO!+EsW%ΞȾ.6 r.X9v("eĂ,DOH)1H!GXP8`@QNU ]U (*k66ʹ D`br`>k#w6f6–xa; yq; {0{0|`H,& * @d+Іm('ІrmxĂռdA Fh# 'A ЂZ ;[k6Q P@!htxw:mzwjjK1K1K$  FwLm#6RCFP#Dc2hAcޝN]޽5z,h,6EsEًn}^_ٳ|( v_jMRg<;$L&!I>I*MROn }rTۤB&&'7I>I*MROn }rT蓛B$d/`T蓛B$ Fh# &6'7I>I*Z6'6ڤBll }xwT蓛B$&'m4I>9H,$(TP3Dn }hM*iW=7ڤBl&d+FT] IN&'{B< mROm4I>9ڸM*tȥSbۤB`M*mRO66n }XI*ۤB%ژ%ژ%h }rT蓛B$6%I>I*MROn }rT蓛B$d+FT蓝@mRO zgwI>9H$ڈmD6ڤB&d%6'k6ڤBlh }XM*NmROmx6f6f6ĂAb(6%I.M*J6'kۤBl&d+FT萛g-Tm7;_~Ŧ;'x`V~>)I{_KXNܪrodFodF<2xH- D2x6~D< ~L<л#72x#God A<<2x#ǑG={Uú hvCZh֒G<ڇ>']1ڇȣ}XKZh֒G<ڇ5d5ڇ>%a-ykɣ}XKZh֒Ga>><>ifEbz|Y%Y%Gd S|YT#Ke g  C`ɮ e @NYhyOv}#YQYT,-__1fy0إ~ b\! v7ջ?=|6^},{}lX{d?Ю uS (I'Ad^ L2Hs4Is<#iΑG|$9H9GI4#i>y$GҜ#Hs4IsB yGh}Gh}Gh>=OGHۋsqC}.ZsqU.5Q!1\*GƳ!hcnctK#[!ݒG<\%> y!>-yhɣEK}. I|w)HM)"hURz|H")/7*ӣ}߰=Wpj &W"bQ\, k Ek X/@3ru.EK!qLFeXtxO*}sK4sHԓ#_ɍ|zev4n%n'75}rS#'75}rS#'75}rS#'75}rS#'{>蓛>9H%ڈm5]r[#'75}rS#'k6>HV`FOvnk$FOnj$FO%hj$ `S#'Gw(v'+6 Vvs蓍> H1>IH^bFOOFOm45}rq[#!Q H >Yڸ >J,H>K1K1KHMDHMDHtmDHMDHMDHMDlhk$d'F[#'{Ă>9H$ڈmD6.蓕>Y HFFO 5}xw[#'{6DDDAb `xw[#%5]r[#'+6>Y ,HFmDlhk$:6}ɸ8IْIʖ#|̏3GA>{cPm|? B ٗS`]f9%;c|{D><}=*jC~T4/Ǡcvi><"jccF>#|0䑏#31$=cL<=46~'y<?<qnHm(n8}Ә׵_䯟aG/={=^ei9m_ŗgSPH/wgUs|||F |F{\<| 3oE}>|Fاlf㷢py!Y%.?\x.?\rSETmSzkjnV7 C9Z~V`VjD/JIT[d'xT1@x8vDUHE"*T>45N5"RN%"K P*yN /Po]Z[:T" TTO+x4tiqN!*]Z*UBP9]Z{*f*f*@Ab(0^pN!*Uz*_)xticq6VE's^sBd]gLDhksD[-68F[p.F[¯F[h+.>fpmE% [QD[,p5 kh+.V~"l*U!`B`y\B;W,́@ApexYcXX ,<8΀uΝ3 Ur l;W T1KT1 T$ ӱfm%pUl-1Eont4KG+PE*"U%U< \z; QEPD\:2-c逃SKScJGTQg!U3*ʑtxH:f<tN3"͔eU%"9͈t2ªHiFLJ Tt4Ҹ2K++P*B9*x^`Yj]:BGUUD\zOOtJ3b.@ZF mpUh+09KkUx*f*f*xA`(piq6@fUa@F0x%1<’ӌK+P*>yk>g2G%ܛ,^:֓jok7u-Ǎ7f{Traְ$.9[] ~2oM p׈e+_Z+żc}\^w.knyK\m m^s޺w{ܔ0<q@^`7/oKL I p@A(Coz!֧ԦCи `qmz198x@$=A`37~Kzύ* E!jnd5[/kp?C@^`7/ۜw8@Q!:0P?n3Wzhנzhעvkס~f9 czH}>`R !e8R-b2 zr:]= ҃Z"M~S~ҸRzCԢukq=(!%70=('Ѓ c537z=D\)MORZcp?NY LZzHI LzH9 n p?zzz":~̄!%30=!20-20?6`,OݽO?{)eC5)[SuQ)I:*x*O] ?msry׆uCܿVܵs״㖀;\Z9N$]6Vn6U(\pvge ^/z%7׋݇yWn6>`VS}0(\ ѸҡN̏MӉpW33wy8=kSos$î4A o&n̕}My-j7- n)F8}ǵb\5Ͽ 9p!'n$9)p&t<\l *\ jn ܏kjujyf܏k =@C-2skU"3q="3kp="3kq"3p?Ef z(EflО[nح܈q-2sk-EfWzEfWvEf~\P v+Efw C!zhzܶ *ԏ"3Q=EfנzhE\q[dp@^RdpK-EfRdpKY[ZdpK-EfWvEfRdp-ZdpZdpn^`RdpK =@C-2skU"3q="3kp="3kq"3p?gSb\/ټ=wa!v"> *\ jn ܏kjY̞ݿp?4]YXbZ-x3 |Ln7-5fS-#R8o}6m\9-r(r[r}rI&n5pq<-9x[rz9xp=8'Ѓ Vrn!z(-n7?v} r[r}TC,Q Y5djpՐ>! j:\5WpՐ>! }TC,}G5djpՐ>! }TC,Q YG5dsא>! }TC,Q YG5djpՐ>!K؆,Q YG5djpՐ,\h2,!ˎ;r!h2{˻?}ݽȚǵuV!r|_xu|n7ᦎZw4`WqUpӠn qKGs:jsM|pSZ{n:C4"&Y=7o"~|Wp]N_LÞWAV}1_q\|ꐀ=Kj-UT}RpK-UT}nY>7U}2T}\V}\ۭV}Rp-ZpZpn^`RpKE"*pkuewX]|1z_Ds/v9on_ET.eT4.wxS>MUW>uNA7u۽9ɝ%7=[u~gq@6Bܙgs9? nB,1? \S*nw㖊RGWv.}q-ӃqR;P^`7/ۜ4Tܐ߹7zy9n[t--u\ :Rɍ=|K[ |P!]~[[׭R/U~K\?ws~K\?w͸LyQo>OR*܏ʕWzP\ۭvz@@@A`7|=p#B[O(\롞P[=p  p= vq?'n!z{PzBj\5 +'{P^/C9pg v+'nPs [N(\롞P[=p  zy ;~\O( C!zhO( P?nO(\=p  ס~ܞP^/C9p [N(rB Ps >P-'VO(rB z'PO(\/حP =@C= W~\O(\롞PC=p-nzB:܏ z===݂nzBϭ'zB*\ո kp?'PO(~w~{c.n_@'&l ^`Z?p=PsD1*‹GXbb] BsɶZ7Kb@;d;)+Nd Iq\_l'qgYBAǍ=PnMd;)[5j'q55vRv#Iq\1NzvR$k.Nd IqܒT;)[5}.Nd Iq\ۍl'qKR8@NzݨvR$k.NvR7 @"meIq\1NjTL;)kP=08Eƴc=xJd -[5$knI5Yd -[5Wv[5$kP5zvd -z=D"sk*܏kj\5Yp [M\qM\/Ѓaa!vdM[5}nM\&kV5~\5zɚ7'k71K3C&,,ۂW/Sb%}|VZ-?ym:oܒ%pb 5p5rN ֗UD>-'/n: t&tIA%p@^YY [MoܭiiC4ahn[9ȏx4!u`r wK"kh'iN]~sH97 Eg.z⮾t1ws{M]ι _dp\+2k(]n$-1?ndf')%M[:?\v~vrK[:? -npn^`.z7z=D\C[;?WzP;?\ۭv~z@@@A` [7{ϭP;?\ۭ\q-&C-&C-&^`7/یq-&A C!zń}n-& ZLp5ZLp ZLp-nZLpǵz@@uP׵6\u U\ .Մ Մ}n&jBqjB[ n&-ՄzՄ v+ՄT C! Q=Մ=n[Mpm5!ըjBkP=Մעvk C&^/C&jB[ n&ϭՄ}n&jƤ&mxjB[ n&jB[ n&zJ5!-Մ7z=D\ϭTRMp5ZMp ZMp-nZMpǵz@@@A` [VϭՄWzՄWvՄ~\ P {\Mo_oBpQrݧۂW]on t9T8ͮ௩d9O5o#nLpKg: 2sX[GܜG CI#\ۭ$nI\&P vq?}z=D"~VW~\$Pv}p?}z(}; P7&k>->$nM\&V~\z}p=>yf܏kr@Q$nM\qM\&Pv}p?}z=>z}v˹}q?.}[s7PrWv+}kp?.}kq=>u=xݼn9pg܏Kn@Cr>U}Q=}kP=}kQ}P?ns zȹ}[r7nܜG%>}sVs7n\Ps v˹}[r7z=D\%pkn*܏knj\5p [\q\/Ѓaa!v~[rPsWv}kp?}kq=~s/pvǎv.q=@YVsG;l@ngt0 d7N |;wͮ6w6wsǸ1&t6A csu+j5n4_/ٯ׵WwW?2ܘsΞr˟zNaȉ!o~p̈́$+XIZ'%A6Up li€;œk}=7IoU#N)V P^mۜGv{xs@A(PT 7^Jz VWEJ{WE{7^J|sK T%H%f 0^/._K WE\7cc`"@UDtJƋw]:Z\)":\) %ƛ[ʂ.@Ϋ郛>]pUar" 2^ʄa.3aЃ>0UT 9"%00xu \:`Ux*f*f*)!/.2b>0N)1XJ!uX|)T8 {*~w}͕xdq_9PڀXy lpc/ంA: N31؃^EmZ X>jLZ TVcXªH1-kq: N-U%%": \:ZTa&*ҩ5LF T[gx\:\Ta,-߿r|Q3洶/M3ܬO_ñb>΢;&# h*΢ ;, h*΢@;", h*΢`;, h*΢;", h*΢;& h*΢;"VMb, h*΢;, h*Ϣ&c h*Ϣ0>, h*ϢP>b, h*Ϣp>, h*Ϣ>b, h*Ϣ>& h*Ϣ>b, h*Ϣ>, 3O}wOcۂWym5W܇[ϖ~ܺ&ׯEIYm-!qs~݆*udS#3M[,:h纕k ;ٺ^p=~wD/ !݇4+rzΪ-Dn8y-#2 ^7Be#nR 2 7BVu/v^v {xS0b) #S^W4]lYk59p2]{n p\{4A~qs@g =w0{stvsa:j7WPګ!ܒr}nnpK: jnnpK" je=\/[Oz۫!ܒ!W,^ Kj{iBmp55jעvkەܒ=}nDiWpSԮ yove"x0nnWpK2ە!Ү :\]niWps2[ڕ܀qmWp@CiWpk2p?Pە\롶+[mWpǵ]=xffnA`qmWve+ CmWp5nڮ ܏k2kq=ve='/^|M'~>9 4t:yD̍f1yS@A ǜCH~8Ly V \Zu#`U`WE/߭eV`Ec0Ug`+bb"HKAbrPSE(UTO/jxthpN*U*AUD'P8$(a8%(q8׏CkqX.FUцU:vvUx*f*f*xA`tASTE !`%PR*xJKADХ]:EAU("AU('P 7 \Z͸KH" PE"ГxzKkt&WE 'WE'V`<'pipNET^YY 1^/ \ZGܥSTTEv"AUi* aIEx")" Ùy4-3Vn)Z\:\zݼnjz=D"ZT֢jp?EWzEzEvE~\ 0 0 v E܏kQu[ZT pZT p5nZT p ǵZ\ş'e׿O~:qEZ]8uRܵ״Ηw\s;ՏA\E?~k, ;ro2f\.G!pc\ .O`%+XKZ6l`';K>0< ARFK)U,S:?a`m0OXy) %7 ?镤 n `&\QA1Lf }Wv3^)1Lm9Gzyf܏͌  o z6AA%,kKczknfCCD7>M\?@zpj?#TK l!Gcgp?vi9_篛篛oq*q='n^jr 8-UnpKo[ZtүOUMge0=R>|鷞ˇ?~QMW{M.{m|2Mon|2uOzJcZg\)i}=@Cqlquzp\pfOT/W['\+-.ɕ=P\9n؍q>lpdKuq ĕjndWkp?&[r\q]6TWKoTVKoTVKuoTVK5o%LVnTVKnTVKunTVK5nTVKmTVKmTVKumTVK5mTVKlTVKlejpձR[9.հR [9.կRZ9.ծRZ9.խRZ9.լRZ9.իRZ9.ժRZ9.թRZ9.ըᒍZ.٧R}Z9.զRmZ9.եR]Z9.դRMZ9.գR=Z9.բR-Z9.աRZ9.ՠR Z9.՟RY9.՞Y.ٝRY9.՜7+Dž%LkVKfTgVɋ|?ʧ?S\)"캺!^-S?W5bmyS/e~iuC?ZmCMz=L\0p? #X_Ir )'ПpB\?%SE vY^짊첼)w{=i.Zҽ4]+^OKeSҽTz¸ק{=qOIzR ^ƽ>%Iuxۿ{[֦?G׵޾7?}G_}|x?k/F׿N˖AbOKx>U֪mmي|ŷ|ιI\\u\rr>W֑꩎rSNruݚv\f:a u6#\^/fR.pv\rq; \7R..(\%*\˧h]|kp?6Vrqz[-n,ٽ7E~bW[&|5Ι 8ܨ%x#Sim0P~y4 c . .'`r7&'ys`j7 &ys`j7 &y3`r7&'ys`S90d$oL2Y05ɛS_,́/LMT &ys`S90UƂIc$oLq`r7jX05ɛSE`,́*0LMT &ys`S90UƂJ0LU`S`,T- H0S Fj0LU`S`,T= 80UƂ0LU`$S%a, TM 80UƂ0LU`,ea T] 80UƂ0LU`4Sa, Tm 80UƂ0LU`<Sa,T} 0Y Ɓ 1LU`DS%b,T 80U$Ƃ*1LU`LSeb,T 80U(ƂJ1LU`TbT 80aa80aa80U.Ƃz1\o{pw`dv;ߤPgN#3>#3>#3>#3>#CGgD}FgD}ψO\>?<[>Ll.vصpb\ƥ90Uir2TpcS&'ÙoT g>ƥ90Uir2TpfPLpfPLpfxTpcS&'ÙqUP&'ÙqUP&'ÙqQ&'ÙAf*MNf(ê +MX0UiJLUp`҄S&49 4aT *MX0UiJLUp`҄S&4aT &+M80YiJLUp`҄S&4aT *MX0UiJLUp`҄S&4aT *MX0UiJLU0`҄&4aT #,L #,L *MX0UiBs7uׯ>Xkn[;e ^nkUKԬ)ٙGqKK<-M,n̚eƳϭo?Wm}[XdV5cȌ,~CfnzdȬލ[X [ib p׼ܩM,\3zM,PX\,a&z zM,Cfno\'Ѓ 6~\R܀qmK pcn* p*UmJ3?+inyF,P}5?u&|SUtl+6֘l=6 Dl"@n,ۜ/ NӞ j?&)n.=K}ptV*K&p:3[l.,k8"o{ =|@׃𷽟pyy$%nIܒ%%pSxүU7e$u['MaQL)* =|zqB@aa`mqsYYmoWMbm6Uسzgof gk=BbZg\k}=@C*&nd$UDB#?U.41\REK@r\GdW8.Uq&KU@rYݨG %np=ՏWz 9F>r\1Yq-m pGK=r\Re*{T#ǥ9.UHrG`\r){ q)d/¾T. r`U/#0#pɀ ɀHdH:G2`$F2<#0' ɀd݇$!0_'H }Q7)y^|Q[.$!O ~U! e8M(#?"#GDG<"#?"'?#߿b?N[}]ZY5~TvwQߤh]@ӻ3김="pլn4y'E|]Dn.fz%,O[!#zGfvOvGyPT> M%Y{2іhmh JR!wb56* +WfR O5 *˓r(p ϣ-(p x R(\AiLL+`jhZsC2ԴƦeg057-0ep ,`jrZLFe05:i2DťH/XXĺ%֯-nuK_[bXĺ%-~luK[b-'|“2wsK5?r59>g9:oi͸rn'飌eF _wNےD%]/)pe /ITܗ$*.3JGETnCN=˅=gU{t,gU{`xQ\U\ spU pUpU pUpU pUpU 𠉊AQxQxUfU>/6^Tm\v{EVS[py<\v.; #nY8py+jCj#jCj#jCj`j`j#jCj#jCj#jCj#jCj#jCj#jCj#jCj#jCj#jCjj#j#jCj#jCj#jCj#jCj#jCj#jCj#jCj#jCj#jCjj#j#jCj#jCj#jCj#jCj#jCj#jCj#jCj#jCj#jCjj#j#jCj#jCj#jCj#jCjEWEmןgQY6q[U5z1<9XeB҉#eQ{_Ww۔N;!tM..c])9deJQuph%/B GAae@[A[A[A[A[A[A[A[AuI[A[A[A[A[A[A[A[A2^5S .LnlS_˱?߬u^~9f\\WDI LNiE>hb&hb&hb&J`M 41@lb^߾˰˩}}9zViخ9[ MzDz?A\.r-UA+p?{qUh^ nPp*mqicny5[]tAp˛KS[^Ph^pcisApkKcnV[;69FuI,J=y}R{`듲DEUꉨJ=J=J=JxJ=J=J=^+8QV pK/Z'UgU'&*zET Q57[z/J=vXz(8(VRO;ET,J=5+oPlE'QQ&*F>*/J=v-(+bQ pPDŢVxRO;Ŗ^zkWDŠAQxQxbK/J1xQ `E'|'ڵRONkX#pU/W]#hq5XV;I2X 4\,]UŰ)`k%j=J(x܈ȩHGw3S+Iq7qfOO|6`O|6`O|o5`O|6`O|~>P?;ٚzEMsR?+br>>vs$n2G cSձˎ"]ܱ4- Gp] qK<_xH#lX)wp27,7Rܮ,w񐹽b݆Ҙ_?ÍuK~jֿY sI P-8>n}u4~Z.r) 3SCX^ns S s cApzMIc}f8qx|\4F~`@=/`q"P!Es@Mouˀ~w]zCy: ]v""և9&{>t;¡c}X>և!*!*aTClu n1 q y#"/@p%qC+nĕLi r7J4-e W!ɑQn! qGA\яcǃhGC\ǃFC\ϯhFCcы- qmJp%'JF4ĕh+W!dCC\Ɇ M&4ĕLh+yW!dAC\ɂ q%J4ĕ h+W!d?C\~ q%J3ĕg+yWh=C\z q%J3ĕg+W!d;C\v q%J3ĕLg+yW!d9C\r pE3ĕ g+W!d7C\n q%Jf3ĕf+yW!d5C\j q%JF3ĕf+Wh3C\f qiK q%J3[,fOW\fQPe6pKf2ÿs]2mev~G.;rߑ\fw2;#ev~G.;rߑ\fw2;#ev~G.̓ :a?N[𼉚:7G+FicRmy?"TKLo7b=$\A\kmWi$N8׹ =wi<#Oyx~G;4ߑv=X[o[o[o[o[o[o[o[o}>y/}ﺭbR\Qwa ]\]|@\]| (wa ]\].ܷK*sz/}뽤ܷK*sz/}뽤2ܷK*sz/}뽤2%}2ܷK*sz/}뽤2ܷK*sz/}뽤ܷK\l:{ϯ .K\< RϮ .K\|zIԹ8%uGĥzIq^Rgl{D\E.KMK:c#RT/3v<".K K:c#RT/3v;".K͎K:c#^GK:c#R舸T/39".KmK:c#R䈸T/38".K-K:c#rT/37".K퍈K:cw#R܈T/36".KꌭK:cg#R؈T/35.KmK:cW#zɻ%uƞFĥzIQK/_xowqCa<8z? OWָͱ~{RO~:O@ȭE}kѕ\É2d,Ke, p,!#ATR2KKe,p,!#AT b2K:Ke, q,!#ATR2KZKe,q,q,q,q,q,q,q, r"r2(r,)r,Ir,Ir,ir,ir,r,r,r,r,r,r,r,r, s, s,)s,)s,Is,Js,js,is,s,s,s,s,s,s,s,s, t, t,)t,)t,It,It,it,it,t,t,t,t,t,t,t,t, u, u,)u,)u,Iu,Iu,iu,iu,u,u,u,u,u,u,u,u, v, v,)v+,@C`I`IEW//U"/\DJ5*yŵJdD~ĵJdD~ JdD^DJ5*y͵JdD^s*\D~c**y͵JdD^s*\DJ5*y͵JdD^s*\DJ5*JϦo^J;u~ki5?]=51T_Yp9|:VZ&cZ?{WSaR`?O{9ǀ'ke8pƝb|ǃ'SK?5U|gܦ*YG+_Q?Lw|T=crŜdyAM89"N~ns xJ01PnB$Xq݆&{:prqxP规i7*(O~>@lj&Chp; |sS|t3BswW76uGō>Mf=V`aY|UI٧9lbA0<&( [&* 8. kAj/Kb. \d K\d1x^ु .;7pFA(piĀ0.pm^<ܕO,v^fiGkGMT}LGMTo!1ūLbDfˁs{:*j*ʤ2Lfj2[%ykWD5p.$]6pqs%".e.e.e~ \~Ǘ- zX5zXzXG\b[wn^b[\b[\b[\b[\ݲr!Zb[qwK?f[w˚k[w˚k[w˚k[w˚k[w˚k[w˚k[w˚k[~-߾{}oq|xj qs^'%.dے0CI:<\odHp,cpl5IJےfmɊQZԓUD ^mg?+~|l\7(fsTLW ʈ[^n_ ny`PFVq+SGk`纄 W{"2W|_Ee"*zU)W)W-GMTT1jxr.v^Qt pb^K;zK5]kWDŠAQxQx#׺1xu "`w%*걿+%ގkP?^}]?KoiNpұ.[+Cj(wNܼƉGϦ M~ٲ k H+Z;wT:n.ͮIfW 6"ͮ8T SKO,>?8T8ǟ X~*`q@%ǟ X*`kvK5"%;46š]Y=ؚ]Y=ؚ]Y=6j⩍pT[wr^W?AY>RȚnS/Z!s1+^ nPp[*d[2̭        p[=VM#4s෉:<:ۺPF2MQTQNcnSES?.\T22{~ (udNq{5xux7H\7 Fr;mk]JPgv˓n>+mE_!_)W\NN+:;{hKb{[%rj݇rՑNO NxG)M2ɜ|Uҧ|OfTK-18uDR@:{5N=Qkzn`)j㺢fpX<-jţf߆(05&*Ψ2tJpS(wBů;$gncbH(*~}cQnqgkȘ74|E\և=W-Cǿ ,z>և\L0>DE$\\|#aN\\̏t#nqE#|c#RegylU[*j>c#R5glxD\KU4q3v;".U|fGĥʙ눸T5[*f>c#NGK2qJ39".U|.Gĥ䈸T{b>c#REgpD\ K0p 37".U|Fĥ܈T{^>ck#RglD\vK.q35".U|ƮFԈT{Kآ̥f9s364jh|^7ߡS7qN51|귒ѵTͲK.ssx xgp, RG#_Z<=!ي;=!e U)r=a0Z2wVuh_|18 8*qm~3whrB+$88<8 3FqPu9;d@!8Ȳ3\O0e|4< 1xxq9 LG" :.sGC/2*(c!\Wn=W5kY=qdeqde5cS/,g4YiK!o< ̥k7Kt&k7vplJ,vF`) Rn+@n>g>g>g>g>g>g>g>g>POg>}{Զey\3pEzTsI,5Vw"FpC}-ɀFsԘH^r38Q$]s (ᢛ/lR>?S)篧9<_9k x5 ve+p?[W"ṋqݸ xJĨs`JϸLؘO.$0N-_ L'\>.kմ+DƄf! fHs2$rNn-y"ypK„|dՖ RE[.xz~g͖d]ߨ]Qc~;VX7ժʵMʵD2-Y!rfgܻS۟c빮eils0Ohq-#Qzc p̆ \c(x,obtj Nu . (v~EJYEgU~W1^&*ETDEO+\˷^>SDEb`b_勉~K/L bfb"*z[z-|61`k9"%rZrZrZrn[9k9[9k9 ?C a!K8!N|.09>2~Sah5Q ~/[ιw5QA9KU7oÀ 3&x+Ì | :/yp#:!pXU,^M2l *S2uTL݃2*S`L=*S2uTL݃2*S`L=*S/o~ĂsF·M5}}[gk[gk[gk>7%jhⶔbwuqރ-Wnrlr˕[r r+\-Wnr˕3`˕[ro5W~wwa4|y ͟BϪ:nH)|g )|g )|g 6>SL# wo^rn8Vkǥ\\B:Z:3q9|T0(oqߴn8](|*J_lUfsk5;π\QAg1k8f<s yIol꾩_o꾩Wo>ޫ_}wźSiøXw}8ocYz؈1w\cq}hVqr0s*{/z<.[,z3:]\7(['Wjჸu0 nKp_[\N[޳(BlJʀJʀJʀJʀJʀ;ET')WXRXmH ݃mH ݃mH ݃mH ݃mH ݃mH/4[!O_PiHܾ*CcBzo:-s(C H,brvV,1˛ؗ ؗxLK7̥PM#諵em[6wqnM.–ݧ73x^(p5c9C࡙ܽbhL]LQ`7qAh?k~hQ1%A;ET @g;s v&4DMTDb1<V±J8`+=J8c+؃J8`+=J8c+؃*x~,'\]Ή>a<ٹ4朖oDb`snRgWwKs9x%]Nڍګ^*tР[vfϠ;Acн{jЃ}Ϡ_8sAXgY{,nRBܭBc?.>@3}9x-,vA;.:n8薉8NHBt*Oh =0IXU2cte]#Ph(# {Le*1R=jG.co"= WEHA!&BjfG~WU>ѸC!~vpf?f?4~Xf?4~Xf?`V+l 6aIVf?6a~Xf?`V+l_/4ˤe K=yjL}|/Z<Æ'i |&g |&g |&'M3> |w_^^WH'ןAqԆS.Ǯ4xm6`6viRAac[kg. SajajoGͭG,Puҵ>Y[T :KW3axPq\T Q(EGqx,1x2ve#qM!Dgsbq'^Qfbe peZ+\մg 6WkZj`sVZ+\l 6Wk5홫Zj`sV𿃫+Pݩz#[kV=r?Tmwј|3͟\WǬn~@:e`tr#u"5?s2N.Q]Z˦].I(p_y2^Px(< Hs{U Q1jBы59wy8o]Ԭf^s 48l mJV\֍FDŻwQ3J!x3`OoROk⭕z\z\zkWDŠAQxQx#J1xQ `E'^xRObK/J=f pE'fz -(8j"*bDGŢE'N{ET,J=Xz*oQ pҋRO{MT4Q1("j/*oTlE?/J=^zQ(+oQ 0?gVR.J^?~ɅSNZ5t?V.$[IRձ#m ϽWk͍\z7(Am*cn1oooooooo±+n9X~K{7)jGrlN±+n9XPWY#ܗF6H[7[7[72mVv5FܪMgC~bQ=">VэX42ױ{Jn)lRYi!+mr<'\f0{hO`cI+Ka!{M s?_7gS\0[>w>W`mD5kpL˚iL˚iL˚iL˚iL˚iLk[3-k[3-k/JOwͩOݶ@'}No_H~X]4=.{닣dw727m3rEF}wnezN{42hzVA4/Kcc'.eN7oЮxhԣ Er+^<7ԃ= 6;Źw4rʺw4hM/hj8xES ^ԄFW45$)M /hjPxES ZS*Ү W@&473MޙKM\jwRӽ3t̥{g.5;sޙKM\jwRӽ3tNt̥{g.5;sޙKM\jwRӽ3t̥{g.5;sޙKM\jwRӽ3t̥{g.5;q5;q5;sXjtly}Wu?ΰ v9vsJ5q 1IW zOFY7psn ۀݿn n]gq 8QeFs)~ smyn wF3bvv|M o5&fi֚&CnH}X < M,sC, 87-M, ĒZ[[jm(\u`XjmpXZkˀ;~- WDŠAVkk{ZlkZlVk[Vkk{Zھ埯${1{ڟIs*Iؽ "Z Vz&g6y=L#&g{=L3y y^JZ+iW}w c}4g3c3nC=6y˗:ڕʞ&0ΥgԯC: |Q5ttKUbG7;R+Ur,.FֳU\ˀ p-f:`\ $.B$."$.B$."$.B$."$.B$."$.B5$.֥Ϻ֥Ϻ֥Ϻ֥Ϻ֥Ϻio )\VX<"c |wX?s]/dž䮍hDmSq9U;$˾9 334 gh>C^|36 gxl>C |gY>v'm/aRN/yԓ>?Ǻrpu,&V7fÍE cc;1wy\W* nb% nRb# s^OqC&mnpBo\F*K^+m(]{ nj3)nT[jIJc?$;AP>s[p|<cp}Z>3u_"zźu}~0wgkQϷ9>7z?1ݫ_=C0> |QQ"F>bï[lu넬 J<W7x q[!q;!qDV+wPădzDܨX7󈸣M\cǃxD\ǃhxD\ϯwDc-qmJp%#J^Gĕ+YW:"tD\鈸Q>Gĕ|+W9"rD\券q%#JGĕ<+YW8"pD\ሸq%#JFĕ+W7nD\݈q%s#JFĕ+YW6"lD\وq%c#JFĕ|+W5"jD\ՈpES#Fĕ<+YW4"hD\шq%C#J~Fĕ+W3"fD\͈q%3#J^Fĕ+YW2dD\ɈqiKq%#J.F'=fe<⚕Ѭfe4+#Ѭfefe4+Y1جѬfefe4+Yʈfe4+Yʈfe4+Yʈfe4+Yfe4+YYhVF2"Yߩ?DQD/^|ϫfs/Wpc?w ПZ1MYן|88-IϋbJnؤKՐ1]\˫ohz ar[ENgN8%$=䕈y9y21=(ppgk+ . \$i\?8{7ns|Tt]N~PnvtY+ <&PZ8p0s8`nƜ#}X.^ȁ 6HQ1بH2*&G-^*Xp(=z gO?(C6eQ!pqPGS?*hesԣipH.*Xl{o٘Ow& p*J;p̀X2pT,d཯75Ac=N[{ 5Q7c𠉊{iwG/{=!Nn5軟mޝ?|cO?Ϻc{Na9rQ~oԎv?ss-c'ca9^:v9p\nlj?uc<ΰKO_~ZocnV߳Y'Owo^zN}4ϕ,v1{e:֝(n?9xr?/쐮}S *kv>{g>7y*fV˾~~SjO8[z_~^+G\W_/> m\ vwp`w<ȲҭrwYB~p{˵ѻ%B{/c~Vc7󳯒WL:01쫏Y2 s=꜃|sȩ $O"턧ȣ=($5! Ր[ Ӑ; Wt>A9AsQC!4j09L^Zs:?g~y2<\Vs=9j9jΙt0}ι#FCijs.ள44gJ:'kiϔt0gJ:?gɚ=4{k)^L=5{k)^L=5{k)^L=5{r!kAyzsV`4y =4y! Y s~|} ԜpvX3q/ʱkϊUguŽl$InYI^EY~Nj'c.P_17(9Vv\^qs)ηs?.ǽ*$DTbnb.ssBj17u#lnv69GqkSG#r! M}ŝ_)^3MB 'nÝo_aN:^AlfspyS7v*‹9-7PyݦkFpKIP7goMc3; 6Gusn\p]yR=p;pdCx٘džju)!uq&-C tcQu$Qq=nY;Y'Sk#|nnؗnc =Yا>Oow>"zE< x6؏> !8>!x~݂->Y§!l<|nᄍEݩN?Vq>tISq'Mn.ʉWĦiC˱֖j7!(nQnZ[n* 7 ^[[" 1RiK z;4{*Ζ=1w:'r7n~, uW,V\RdaUz=v+5a4L˯ڻ&edݜnJ]>nrww[w(6;5S.vSeD;ήn٧ӱX>.x{73E S ^"E#S\<CJ~p |<, d4nw+d4`Qn}\3whܒ``_`5p[>jFvx+֭d4`Q"F6VC:Ap xXg4n`a -n}h^"E< xuu}.8֌]2d4nhܒ`5ApKF֌- [3d4nh^nbJF֌xx0P3wh\%Ap=KF>mu[2 "zE< x6xhskF. xX2d4n -KF㈻h<pB{4l8;,9U~{M?2k6 חp]\M.ah|9_`:[ dH;B2-*md{sDl<,-8 nKG!da9xX!p@zzź >vtd^!*aTǃoutd^f+&2KscOWLe:zE< xFWLev{b2}/?l<,8 nL>^p@6𓗯_>܂ {pǹS-z~-~/ZmxXhW[XNj@p""FE<|<,Z1w\ââܖ_E -x0(aPCT[TE 8.Z1wamnܖE 8~ . r|ObA]*b}*b}HeTǁnu90͠.z~ϯr l93". Ш j5lu} "Qt3հ)K7Z "˰)} "H7Z bt3հ)*֭˰)+WC6pE΢㡗,XU1f%sqVr&+y|5G%GpK*֢fb-j.Y>[| fmܒc5GpK|<,+֭W[mGpkFEd#%GpK-Y>%Gp{E;(dnT[1ܑ5Gp,-Y>xY>uY>}\| fn^nbJ>Y>0*ada#FT/Y>}\:Gp,mu[gnuxP| fn1ܚ#%pk[|wܒc5Gp=nK,íY>dnÒ#bzź,íY>0*af#Kz>, |<,Y>dn%Gp{E,/o7룿nd!r&mpM )w.[]q|䙦?U ՟ZrYןmqKq:؛]i_'q󼾄 :!YdJH !Yd*H!Yd H !Yd~D!Yd~H !Yd~H!Yd~H !Ydj~H!YdJ~D !Yd*~H!Yd ~H e替`lTl dU&ۨ5F&r1بBU(mT#*\mTl dU&ۨ5F6pMQk*\*\mTl dU&ۨ5F6pMQk\Z"wwqKjNޟܮ$%6pjsvOH惧oUCqr 3xCdEiǗWC]&e;kՓo(mmlgD=&:6qϖ5rhWl(mmlgD=&:6q϶{DG>Nlme"+y7,O[QyՇ7:t?Oǟ^>~ 'SR[x!-L/c7'4}eYgm5еuk"WEȠA!QQbQCh"$8EfCPl4= -!۟iMin'kl{OEJi .4+9<%XpĀ7g)p_2_ x~o΂%=ʀ`5lxpRHbIK"M$b7w)O:x௿}7=fɛu_d_5\fzI蟛dB?"_ۿo[x<Vj:v9[g][g\ro]v=w_\+dG~VG17>'o"L8*49|TV鍓a ~aTfp6C>2(𨈊ig)Qq b;Mȧ7NjK\TGEEoT/)-{MT 4QQ57*oTl[:"8>*, n"x/^-Z~KqLT,o}o^OSwͪ;OD_oS//?ko9`-,QZ-o{ᓏ~S7 F4|v|l~{׷1Kl:'z1Pwe9/.S+U?vfaw%c|O_߿z 5MX1xx}>?2cv_~nzYQ-L? S&*?tڮUr~EwH}U|xbEuh-Պ/?LJ+-M:'+4ZIVG?bP.)OL^~?ozߋ z\uֳOo>*VjrK_<?@sz߼>ǓS`y ֛tS}[wwywG3|zܖuwRkl9vH[Vc8Wkj`V_ܾyyK(nO?vq盆Rr QjsfpqwS,72]$7 t-hEYX֋\iqUb+qWM1_|l9\-@=_y-UxѕyK82o;Zrj]nW_<)~as= 0AG8c'@6imfEA?VH:Dp씅asMm v%7ǀ?/+t`f/<._^>g^zVn=|lm ZۿˋveLj3{v}>߳w 5msdYKL5'Og/ hwx<MffKphLీ]iSEZ_7͓įk}N .-pP඀cpˮ\9TNJlS%F]!d)#.IpƤK)9/-+!jM%̀ǼK)q_:A2)ט(_H5i^ pJw8QѷKG< J6so/ Ky/^,plBC/IO>ר08Q:*˭(p$;\`EŠA,FS:qzE+XZ|3`W+6G_p([[>*R2*R}2*zYKf? ̀&*bV𨉊1*HD-^Llҗҥ/!taavgt!tG6K76*zET Q57[at-5|T;2*Rs>xZ<[:WQ[ڵp-SDE8efz -~K>lTDETb|/w-WD|T b|XN}oikWDŠAQxQxbKҡQDEhNQb/ŖҡUDEh٨`rȽU}x'?V|_~ʒIz75WVD28f 9LbGmz%+""C&Zda+aa]8gaeȯaط5UootâᎽ3hE6[Ŀx=uM&8az2c̗ 0UOC'3n|x-׹禀Vtś= px?%3|(€\k[n'&[ӛr-_[I 0\nmY#[Fr;rͨ8v\horiuf-'"KX-یi@ Z5[k!g=1,/ ŋ/^h(^/7x^ p"TQ,(\==[{*H*d(^ ŋ%"_)Q> [S4(G, ~Y9OB#uC͵굱}xov9ڧ}^t9;ޣko.9^|% _?_68ձmwmDzw?uhЛOgÚs}[΍ڌmҾk:la7XqsnN^c֖F>"i='3лkzoSZح_T<ncהGPwlXykGo6/*8f#6\Fxū]ϊ'c^"u'ÇPFD$vMA?_]$ ng^.`qA.<#; G(Hmn#φlgw l݀oD֋Փz(p'J,?,x4OG3T_ߣx9b ڷnWzx?G4h $`xD< X"f59-\MC&f!c{"Sd)^;lCv g*`S.U!X"x D"6L *$ T"H')D~F^Nw=4q9a/vRvp"R^ |9|9DvzwLr˝kgU|xzqݻX%;<@Dv'Dn_[lDh~!t< sDxͪFm$KW?-yD=Dmd6EŠj &dgXiBm 9v "\ _9U{7wƇR+v"Vȩ鈐LJR+yCr^' Pj\V/LJRr{rJVVneΠ ,PaF,y2hLmhFm$Km: "φ]E٢bFڨ~f$";73)cmlR rL@ Wp3#^ݛ,Hm\[8jcnǘrN~oTz1"_8{nVs6\=ԝZiSݙw+輡ռpF$zB pAվX d`TA]]۪9T٢bF1hzb`51ΰAƀc RhX>Vwu26EEERl`1n_ PbF363h#xC7T0&P|4?Q<ҔBY:[fݣzyܣ6oTbpΡ5C\Πw_{Ξ8vwpŜ\&W gpŘ\%Wl WpŔhC2-&٠lC1p=t+۝u|wp=Cw!7p=t^;p7 q} 9!ov=΁\1 Wp}\1Wpy\1w8vpu\=nq\1wzvFn6n2-&N|wpAŠB[p][p=^@5wuZ : zH=b*x +b(spvb&uVb$m\Dd[2MpA٠bCz1[:znnzNn2q7 7 z z zȆeC _(8vmu\$\- |wp'nq'ee]~pm0 ܆S~^n6nkՠM槿wڹ}sVֱ [ z7=߬gp[ Qܾp]{/\SWBz+WBz+W6l\p%pgfnP77s?u\}z^p_}N\}FpnPpA٠bCz}:{p~o=$3Kg6lxfkp^1ڏ^;z^k?zp'k7n2M6q٠E?-߿ [ۍ? \}NE?M=$ffnߗoa6?5?;q= z0?5?=dA!z }z }zpCBBɠdЃl٠P77l\7u7u77n4! u;u7n6P@NB?Tۍw2-uwޙ;{g~o={g~ g~A~_?~T{܃ۿ^zXvzėwrCsπ;/[/k/.o2OS ;ϝtĹWqsAX]:L/>sl9{qϱ;{Zܮ!syq1; p1;sy<\c.ws\Gu\E|I0ύĮ"Y/u׳Di[SzF,V֝- 4:~n9<[@vM$=H{n5R=;l]Sp- 8[@vMq={n5kds Ȯ)O?=~T!x ^( k~^x\ٽ<>pb^6]*?{Jv#.W7n gm}l1b+dp% t2ܞN\ɀyz:pX\1W%z:pAPdq77 z(=n,sn,zn,֍%sK zH=Ab,n6M%-|wcۍ%c pC7uc p_X܉K zH%CXܙn,n6Pwk,xk,zKNn[c p#][c pAɠ1W%c pX\1Wcn7X\1W%nX\1W%K uKb,n6!P z(\X:vc p_X\Ѝ% \X܉׭K:&AAAPl[Kn,sKyݺn,Ѝ#b,}Ǐ񏚯4?D+K7.#W*+ڏ}h]^i=Uo[L;•)SۧLn2E?2E2e p۔)•)SۦLL6epc:Pd[2E2e pA٠bCz)S.n2ep_2ep . \}zNn .|wpAlЃ䀛 u3|wONnO׭:>96p' 7 uK|wpA٠bCzpOz>9}rs䀛 zH=4pgONPnX|r>96p׃y''ױ;q=ONѠd[2ԭ;u,>9fAar>9:>9zOaD7u7 zh>9O''\+>1W|r>96p'\}rm>9OC7r=tpnP䀛 z= ׃}ru|wp=C7p=tp'^n䀛 zH===dCݲns'z>9z^n;q=t_~ᯧW~zW>^镟^镟^}镟^镟^^镟^镟^}镟^镟^^镟^镟^}镟^+?>]8懧u/]=x0ݵ应oϮ7n_z(޻^.`>ׇy{xz7ϧ锇)at$kn10ڰ^+zYg>="nM=-uDP@a}߫E~=V ϋ\ן)5丹XlAknKkfiUp|*UZ@ۯn?gAUQ_6vתP pl.AdPlQlPE/W-.-| .*;SEqUw/x[Ze2b}@(Ѡ]"Y' Kd8[T! .UHD,xی ;!X۔ mL'\mN#^۠ '*AEARl(^KZ,7 wX_-*㪨qX int main() { using namespace date; static_assert( std::is_nothrow_destructible{}, ""); static_assert( std::is_nothrow_default_constructible{}, ""); static_assert(!std::is_copy_constructible{}, ""); static_assert(!std::is_copy_assignable{}, ""); static_assert( std::is_nothrow_move_constructible{}, ""); static_assert(!std::is_move_assignable{}, ""); } date-3.0.1/test/tz_test/validate.cpp000066400000000000000000000113071403643451100174030ustar00rootroot00000000000000#include "date/tz.h" #include void test_info(const date::time_zone* zone, const date::sys_info& info) { using namespace date; using namespace std::chrono; auto begin = info.begin; auto end = info.end - microseconds{1}; auto mid = begin + (end - begin) /2; using sys_microseconds = sys_time; using zoned_microseconds = zoned_time; zoned_microseconds local{zone}; if (begin > sys_days{jan/1/1700}) { auto prev_local = local; local = begin; prev_local = begin - seconds{1}; auto slocal = local.get_local_time(); auto plocal = prev_local.get_local_time(); if (plocal < slocal - seconds{1}) { assert(sys_microseconds{local} == begin); try { local = plocal + (slocal - seconds{1} - plocal) / 2; assert(false); } catch (const nonexistent_local_time&) { } } else if (plocal > slocal - seconds{1}) { try { local = slocal - seconds{1} + (plocal - (slocal - seconds{1})) / 2; assert(false); } catch (const ambiguous_local_time&) { } } } local = mid; assert(sys_microseconds{local} == mid); if (end < sys_days{jan/1/3000}) { local = end; auto next_local = local; next_local = info.end; auto slocal = local.get_local_time(); auto nlocal = next_local.get_local_time(); if (nlocal < slocal + microseconds{1}) { try { local = nlocal + (slocal + microseconds{1} - nlocal) / 2; assert(false); } catch (const ambiguous_local_time&) { } } else if (nlocal > slocal + microseconds{1}) { assert(sys_microseconds{local} == end); try { local = slocal + microseconds{1} + (nlocal - (slocal + microseconds{1})) / 2; assert(false); } catch (const nonexistent_local_time&) { } } } } void tzmain() { using namespace date; using namespace std::chrono; auto& db = get_tzdb(); std::vector names; #if USE_OS_TZDB names.reserve(db.zones.size()); for (auto& zone : db.zones) names.push_back(zone.name()); #else // !USE_OS_TZDB names.reserve(db.zones.size() + db.links.size()); for (auto& zone : db.zones) names.push_back(zone.name()); for (auto& link : db.links) names.push_back(link.name()); std::sort(names.begin(), names.end()); #endif // !USE_OS_TZDB std::cout << db.version << "\n\n"; for (auto const& name : names) { std::cout << name << '\n'; auto z = locate_zone(name); auto begin = sys_days(jan/1/year::min()) + seconds{0}; auto end = sys_days(jan/1/2035) + seconds{0}; auto info = z->get_info(begin); std::cout << "Initially: "; if (info.offset >= seconds{0}) std::cout << '+'; std::cout << make_time(info.offset); if (info.save == minutes{0}) std::cout << " standard "; else std::cout << " daylight "; std::cout << info.abbrev << '\n'; test_info(z, info); auto prev_offset = info.offset; auto prev_abbrev = info.abbrev; auto prev_save = info.save; for (begin = info.end; begin < end; begin = info.end) { info = z->get_info(begin); test_info(z, info); if (info.offset == prev_offset && info.abbrev == prev_abbrev && info.save == prev_save) continue; auto dp = floor(begin); auto ymd = year_month_day(dp); auto time = make_time(begin - dp); std::cout << ymd << ' ' << time << "Z "; if (info.offset >= seconds{0}) std::cout << '+'; std::cout << make_time(info.offset); if (info.save == minutes{0}) std::cout << " standard "; else std::cout << " daylight "; std::cout << info.abbrev << '\n'; prev_offset = info.offset; prev_abbrev = info.abbrev; prev_save = info.save; } std::cout << '\n'; } } int main() { try { tzmain(); } catch(const std::exception& ex) { std::cout << "An exception occured: " << ex.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; } date-3.0.1/test/tz_test/zone.pass.cpp000066400000000000000000000031341403643451100175310ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "tz.h" #include int main() { using namespace std; using namespace date; static_assert( is_nothrow_destructible{}, ""); static_assert(!is_default_constructible{}, ""); static_assert(!is_copy_constructible{}, ""); static_assert(!is_copy_assignable{}, ""); static_assert( is_nothrow_move_constructible{}, ""); static_assert( is_nothrow_move_assignable{}, ""); } date-3.0.1/test/tz_test/zoned_time.pass.cpp000066400000000000000000000501131403643451100207120ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2017 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // template // class zoned_time // { // public: // using duration = typename std::common_type::type; // // zoned_time(); // zoned_time(const sys_time& st); // explicit zoned_time(const time_zone* z); // explicit zoned_time(std::string_view name); // // template , // sys_time>::value // >::type> // zoned_time(const zoned_time& zt) NOEXCEPT; // // zoned_time(const time_zone* z, const local_time& tp); // zoned_time(std::string_view name, const local_time& tp); // zoned_time(const time_zone* z, const local_time& tp, choose c); // zoned_time(std::string_view name, const local_time& tp, choose c); // // zoned_time(const time_zone* z, const zoned_time& zt); // zoned_time(std::string_view name, const zoned_time& zt); // zoned_time(const time_zone* z, const zoned_time& zt, choose); // zoned_time(std::string_view name, const zoned_time& zt, choose); // // zoned_time(const time_zone* z, const sys_time& st); // zoned_time(std::string_view name, const sys_time& st); // // zoned_time& operator=(const sys_time& st); // zoned_time& operator=(const local_time& ut); // // explicit operator sys_time() const; // explicit operator local_time() const; // // const time_zone* get_time_zone() const; // local_time get_local_time() const; // sys_time get_sys_time() const; // sys_info get_info() const; // // template // friend // bool // operator==(const zoned_time& x, const zoned_time& y); // // template // friend // std::basic_ostream& // operator<<(std::basic_ostream& os, const zoned_time& t); // }; // // using zoned_seconds = zoned_time; // // template // inline // bool // operator!=(const zoned_time& x, const zoned_time& y); // // template // zoned_time(sys_time) // -> zoned_time>; // // template // zoned_time(Zone, sys_time) // -> zoned_time>; // // template // zoned_time(Zone, local_time, choose = choose::earliest) // -> zoned_time>; // // template // zoned_time(Zone, zoned_time, choose = choose::earliest) // -> zoned_time>; #include "tz.h" #include #include #include int main() { using namespace std; using namespace std::chrono; using namespace date; static_assert( is_nothrow_destructible{}, ""); static_assert( is_default_constructible{}, ""); static_assert( is_nothrow_copy_constructible{}, ""); static_assert( is_nothrow_copy_assignable{}, ""); static_assert( is_nothrow_move_constructible{}, ""); static_assert( is_nothrow_move_assignable{}, ""); static_assert(is_same::duration, seconds>{}, ""); static_assert(is_same{}, ""); static_assert(is_same::duration, milliseconds>{}, ""); // zoned_time(); { zoned_seconds zt; assert(zt.get_sys_time() == sys_seconds{}); assert(zt.get_time_zone()->name() == "Etc/UTC"); } // zoned_time(const sys_time& st); { static_assert(!is_convertible{}, ""); static_assert( is_constructible{}, ""); static_assert( is_convertible{}, ""); static_assert(!is_convertible, zoned_seconds>{}, ""); static_assert(!is_constructible>{}, ""); auto now = floor(system_clock::now()); zoned_seconds zt = now; assert(zt.get_sys_time() == now); assert(zt.get_time_zone()->name() == "Etc/UTC"); } // explicit zoned_time(const time_zone* z); { static_assert(!is_convertible{}, ""); static_assert( is_constructible{}, ""); zoned_seconds zt{locate_zone("America/New_York")}; assert(zt.get_sys_time() == sys_seconds{}); assert(zt.get_time_zone()->name() == "America/New_York"); } // explicit zoned_time(std::string_view name); { static_assert(!is_convertible{}, ""); static_assert( is_constructible{}, ""); static_assert( is_constructible{}, ""); static_assert( is_constructible{}, ""); zoned_seconds zt{"America/New_York"}; assert(zt.get_sys_time() == sys_seconds{}); assert(zt.get_time_zone()->name() == "America/New_York"); } // template , // sys_time>::value // >::type> // zoned_time(const zoned_time& zt) NOEXCEPT; { static_assert( is_convertible, zoned_seconds>{}, ""); static_assert(!is_constructible, zoned_seconds>{}, ""); zoned_time zt1{"America/New_York", sys_days{2017_y/jul/5}}; zoned_seconds zt2 = zt1; assert(zt2.get_sys_time() == sys_days{2017_y/jul/5}); assert(zt2.get_time_zone()->name() == "America/New_York"); } // zoned_time(const time_zone* z, const local_time& tp); { static_assert( is_constructible{}, ""); zoned_seconds zt = {locate_zone("America/New_York"), local_days{2017_y/jul/5}}; assert(zt.get_local_time() == local_days{2017_y/jul/5}); assert(zt.get_time_zone()->name() == "America/New_York"); try { zoned_seconds zt1 = {locate_zone("America/New_York"), local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}}; assert(false); } catch(const nonexistent_local_time&) { } try { zoned_seconds zt1 = {locate_zone("America/New_York"), local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}}; assert(false); } catch(const ambiguous_local_time&) { } } // zoned_time(std::string_view name, const local_time& tp); { static_assert( is_constructible{}, ""); static_assert( is_constructible{}, ""); zoned_seconds zt = {"America/New_York", local_days{2017_y/jul/5}}; assert(zt.get_local_time() == local_days{2017_y/jul/5}); assert(zt.get_time_zone()->name() == "America/New_York"); try { zoned_seconds zt1 = {"America/New_York", local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}}; assert(false); } catch(const nonexistent_local_time&) { } try { zoned_seconds zt1 = {"America/New_York", local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}}; assert(false); } catch(const ambiguous_local_time&) { } } // zoned_time(const time_zone* z, const local_time& tp, choose c); { static_assert( is_constructible{}, ""); zoned_seconds zt = {locate_zone("America/New_York"), local_days{2017_y/jul/5} + hours{2} + minutes{15}, choose::earliest}; assert(zt.get_sys_time() == sys_days{2017_y/jul/5} + hours{6} + minutes{15}); assert(zt.get_time_zone()->name() == "America/New_York"); zt = {locate_zone("America/New_York"), local_days{2017_y/jul/5} + hours{2} + minutes{15}, choose::latest}; assert(zt.get_sys_time() == sys_days{2017_y/jul/5} + hours{6} + minutes{15}); assert(zt.get_time_zone()->name() == "America/New_York"); static_assert( is_constructible{}, ""); zoned_seconds zt1 = {locate_zone("America/New_York"), local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}, choose::earliest}; assert(zt1.get_sys_time() == sys_days{2017_y/mar/12} + hours{7}); assert(zt1.get_time_zone()->name() == "America/New_York"); zoned_seconds zt2 = {locate_zone("America/New_York"), local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}, choose::latest}; assert(zt2.get_sys_time() == sys_days{2017_y/mar/12} + hours{7}); assert(zt2.get_time_zone()->name() == "America/New_York"); zoned_seconds zt3 = {locate_zone("America/New_York"), local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}, choose::earliest}; assert(zt3.get_sys_time() == sys_days{2017_y/nov/5} + hours{5} + minutes{15}); assert(zt3.get_time_zone()->name() == "America/New_York"); zoned_seconds zt4 = {locate_zone("America/New_York"), local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}, choose::latest}; assert(zt4.get_sys_time() == sys_days{2017_y/nov/5} + hours{6} + minutes{15}); assert(zt4.get_time_zone()->name() == "America/New_York"); } // zoned_time(std::string_view name, const local_time& tp, choose c); { static_assert( is_constructible{}, ""); static_assert( is_constructible{}, ""); zoned_seconds zt = {"America/New_York", local_days{2017_y/jul/5} + hours{2} + minutes{15}, choose::earliest}; assert(zt.get_sys_time() == sys_days{2017_y/jul/5} + hours{6} + minutes{15}); assert(zt.get_time_zone()->name() == "America/New_York"); zt = {"America/New_York", local_days{2017_y/jul/5} + hours{2} + minutes{15}, choose::latest}; assert(zt.get_sys_time() == sys_days{2017_y/jul/5} + hours{6} + minutes{15}); assert(zt.get_time_zone()->name() == "America/New_York"); static_assert( is_constructible{}, ""); zoned_seconds zt1 = {"America/New_York", local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}, choose::earliest}; assert(zt1.get_sys_time() == sys_days{2017_y/mar/12} + hours{7}); assert(zt1.get_time_zone()->name() == "America/New_York"); zoned_seconds zt2 = {"America/New_York", local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}, choose::latest}; assert(zt2.get_sys_time() == sys_days{2017_y/mar/12} + hours{7}); assert(zt2.get_time_zone()->name() == "America/New_York"); zoned_seconds zt3 = {"America/New_York", local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}, choose::earliest}; assert(zt3.get_sys_time() == sys_days{2017_y/nov/5} + hours{5} + minutes{15}); assert(zt3.get_time_zone()->name() == "America/New_York"); zoned_seconds zt4 = {"America/New_York", local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}, choose::latest}; assert(zt4.get_sys_time() == sys_days{2017_y/nov/5} + hours{6} + minutes{15}); assert(zt4.get_time_zone()->name() == "America/New_York"); } // zoned_time(const time_zone* z, const sys_time& st); { static_assert( is_constructible{}, ""); zoned_seconds zt = {locate_zone("America/New_York"), sys_days{2017_y/jul/5} + hours{2} + minutes{15}}; assert(zt.get_sys_time() == sys_days{2017_y/jul/5} + hours{2} + minutes{15}); assert(zt.get_time_zone()->name() == "America/New_York"); } // zoned_time(std::string_view name, const sys_time& st); { static_assert( is_constructible{}, ""); static_assert( is_constructible{}, ""); zoned_seconds zt = {"America/New_York", sys_days{2017_y/jul/5} + hours{2} + minutes{15}}; assert(zt.get_sys_time() == sys_days{2017_y/jul/5} + hours{2} + minutes{15}); assert(zt.get_time_zone()->name() == "America/New_York"); } // zoned_time& operator=(const sys_time& st); { static_assert( is_assignable{}, ""); zoned_seconds zt{"America/New_York"}; zt = sys_days{2017_y/jul/5}; assert(zt.get_sys_time() == sys_days{2017_y/jul/5}); assert(zt.get_time_zone()->name() == "America/New_York"); } // zoned_time& operator=(const local_time& st); { static_assert( is_assignable{}, ""); zoned_seconds zt{"America/New_York"}; zt = local_days{2017_y/jul/5}; assert(zt.get_local_time() == local_days{2017_y/jul/5}); assert(zt.get_time_zone()->name() == "America/New_York"); try { zt = {"America/New_York", local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}}; assert(false); } catch(const nonexistent_local_time&) { assert(zt.get_local_time() == local_days{2017_y/jul/5}); assert(zt.get_time_zone()->name() == "America/New_York"); } try { zt = {"America/New_York", local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}}; assert(false); } catch(const ambiguous_local_time&) { assert(zt.get_local_time() == local_days{2017_y/jul/5}); assert(zt.get_time_zone()->name() == "America/New_York"); } } // explicit operator sys_time() const; { static_assert(!is_convertible{}, ""); static_assert( is_constructible{}, ""); auto now = floor(system_clock::now()); const zoned_seconds zt = {"America/New_York", now}; assert(sys_seconds{zt} == now); } // explicit operator local_time() const; { static_assert(!is_convertible{}, ""); static_assert( is_constructible{}, ""); auto now = local_days{2017_y/jul/5} + hours{23} + minutes{1} + seconds{48}; const zoned_seconds zt = {"America/New_York", now}; assert(local_seconds{zt} == now); } // const time_zone* get_time_zone() const; { const zoned_seconds zt{"America/New_York"}; assert(zt.get_time_zone() == locate_zone("America/New_York")); } // local_time get_local_time() const; { const zoned_seconds zt{"America/New_York", sys_days{2017_y/jul/6} + hours{3} + minutes{7} + seconds{9}}; assert(zt.get_local_time() == local_days{2017_y/jul/5} + hours{23} + minutes{7} + seconds{9}); } // sys_time get_sys_time() const; { const zoned_seconds zt{"America/New_York", sys_days{2017_y/jul/6} + hours{3} + minutes{7} + seconds{9}}; assert(zt.get_sys_time() == sys_days{2017_y/jul/6} + hours{3} + minutes{7} + seconds{9}); } // sys_info get_info() const; { const zoned_seconds zt{"America/New_York", sys_days{2017_y/jul/6} + hours{3} + minutes{7} + seconds{9}}; auto info = zt.get_info(); assert(info.begin == sys_days{2017_y/mar/12} + hours{7}); assert(info.end == sys_days{2017_y/nov/5} + hours{6}); assert(info.offset == hours{-4}); assert(info.save != minutes{0}); assert(info.abbrev == "EDT"); } // template // bool // operator==(const zoned_time& x, const zoned_time& y); { const zoned_seconds zt{"America/New_York", sys_days{2017_y/jul/6} + hours{3} + minutes{7} + seconds{9}}; const zoned_seconds zt1{"America/New_York", sys_days{2017_y/jul/6} + hours{3} + minutes{7} + seconds{10}}; assert(zt == zt); assert(!(zt == zt1)); } // template // bool // operator!=(const zoned_time& x, const zoned_time& y); { const zoned_seconds zt{"America/New_York", sys_days{2017_y/jul/6} + hours{3} + minutes{7} + seconds{9}}; const zoned_seconds zt1{"America/New_York", sys_days{2017_y/jul/6} + hours{3} + minutes{7} + seconds{10}}; assert(!(zt != zt)); assert(zt != zt1); } // template // std::basic_ostream& // operator<<(std::basic_ostream& os, const zoned_time& t); { const zoned_seconds zt{"America/New_York", sys_days{2017_y/jul/6} + hours{3} + minutes{7} + seconds{9}}; std::ostringstream test; test << zt; assert(test.str() == "2017-07-05 23:07:09 EDT"); } } date-3.0.1/test/tz_test/zoned_time_deduction.pass.cpp000066400000000000000000000177131403643451100227610ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) 2019 Tomasz Kamiński // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "tz.h" #include "OffsetZone.h" #include #include #include #if HAS_DEDUCTION_GUIDES #include template void testDeductionFrom(Source&& s) { using namespace date; using namespace std::chrono; // No time point { zoned_time zt(std::forward(s)); static_assert(std::is_same>::value, ""); } // sys_time { sys_days sd(2017_y/feb/20); zoned_time ztd(std::forward(s), sd); static_assert(std::is_same>::value, ""); sys_time ss(sd); zoned_time zts(std::forward(s), ss); static_assert(std::is_same>::value, ""); sys_time sms(ss); zoned_time ztms(std::forward(s), sms); static_assert(std::is_same>::value, ""); } // local_time { local_days ld(2017_y/feb/20); zoned_time ztd(std::forward(s), ld); static_assert(std::is_same>::value, ""); local_time ls(ld); zoned_time zts(std::forward(s), ls); static_assert(std::is_same>::value, ""); local_time lms(ls); zoned_time ztms(std::forward(s), lms); static_assert(std::is_same>::value, ""); } // local_time, choose { local_days ld(2017_y/feb/20); zoned_time ztd(std::forward(s), ld, choose::earliest); static_assert(std::is_same>::value, ""); local_time ls(ld); zoned_time zts(std::forward(s), ls, choose::earliest); static_assert(std::is_same>::value, ""); local_time lms(ls); zoned_time ztms(std::forward(s), lms, choose::earliest); static_assert(std::is_same>::value, ""); } // zoned_time { zoned_time zd(sys_days(2017_y/feb/20)); zoned_time ztd(std::forward(s), zd); static_assert(std::is_same>::value, ""); zoned_time zs(zd); zoned_time zts(std::forward(s), zs); static_assert(std::is_same>::value, ""); zoned_time zms(zs); zoned_time ztms(std::forward(s), zms); static_assert(std::is_same>::value, ""); } // zoned_time, choose { zoned_time zd(sys_days(2017_y/feb/20)); zoned_time ztd(std::forward(s), zd, choose::earliest); static_assert(std::is_same>::value, ""); zoned_time zs(zd); zoned_time zts(std::forward(s), zs, choose::earliest); static_assert(std::is_same>::value, ""); zoned_time zms(zs); zoned_time ztms(std::forward(s), zms, choose::earliest); static_assert(std::is_same>::value, ""); } } struct MyString { MyString(std::string s) : ms(std::move(s)) {} operator std::string_view() const { return ms; } private: std::string ms; }; struct OnlyLValueString { OnlyLValueString(std::string s) : ms(std::move(s)) {} operator std::string_view() & { return ms; } private: std::string ms; }; #endif // HAS_DEDUCTION_GUIDES template T const& to_const(T& t) { return t; } int main() { using namespace date; using namespace std::chrono; #if HAS_DEDUCTION_GUIDES // no arguments { zoned_time zt{}; static_assert(std::is_same>::value, ""); } // zoned_time { zoned_time zd(sys_days(2017_y/feb/20)); zoned_time ztd(zd); static_assert(std::is_same>::value, ""); zoned_time zs(zd); zoned_time zts(zs); static_assert(std::is_same>::value, ""); zoned_time zms(zs); zoned_time ztms(zms); static_assert(std::is_same>::value, ""); } // sys_time { sys_days sd(2017_y/feb/20); zoned_time ztd(sd); static_assert(std::is_same>::value, ""); sys_time ss(sd); zoned_time zts(ss); static_assert(std::is_same>::value, ""); sys_time sms(ss); zoned_time ztms(sms); static_assert(std::is_same>::value, ""); } // time_zone const* { time_zone const* tz = current_zone(); testDeductionFrom(tz); testDeductionFrom(to_const(tz)); testDeductionFrom(std::move(tz)); } // char const* { char const* tz = "Europe/Warsaw"; testDeductionFrom(tz); testDeductionFrom(to_const(tz)); testDeductionFrom(std::move(tz)); } // std::string { std::string tz = "Europe/Warsaw"; testDeductionFrom(tz); testDeductionFrom(to_const(tz)); testDeductionFrom(std::move(tz)); } // std::string_view { std::string_view tz = "Europe/Warsaw"; testDeductionFrom(tz); testDeductionFrom(to_const(tz)); testDeductionFrom(std::move(tz)); } // MyString { MyString tz("Europe/Warsaw"); testDeductionFrom(tz); testDeductionFrom(to_const(tz)); testDeductionFrom(std::move(tz)); } // custom time zone { OffsetZone tz(minutes(45)); testDeductionFrom(tz); testDeductionFrom(to_const(tz)); testDeductionFrom(std::move(tz)); } // OnlyLValue { OnlyLValueString tz("Europe/Warsaw"); testDeductionFrom(tz); //testDeductionFrom(to_const(tz)); //testDeductionFrom(std::move(tz)); } #endif // HAS_DEDUCTION_GUIDES } date-3.0.1/test_fail.sh000077500000000000000000000001111403643451100147330ustar00rootroot00000000000000#!/bin/bash echo $1 eval $1 if [ $? -eq 0 ]; then exit 0; fi exit 1;