From c5f327ccccf504b55620302c981df228f8bb3ba7 Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Mon, 7 Oct 2024 13:47:36 -0500 Subject: [PATCH] Synchronised with QL 1.36 release candidate, rolled micro version --- ChangeLog | 9 ++++++ DESCRIPTION | 4 +-- src/Makevars.in | 1 - src/Makevars.win.in | 1 - src/ql/errors.cpp | 2 +- src/ql/optional.cpp | 33 -------------------- src/ql/optional.hpp | 10 ++----- src/ql/patterns/observable.hpp | 4 +-- src/ql/patterns/singleton.hpp | 16 ---------- src/ql/shared_ptr.hpp | 6 +--- src/ql/time/calendar.hpp | 16 +++++++++- src/ql/time/calendars/poland.cpp | 34 ++++++++++++++++++--- src/ql/time/calendars/poland.hpp | 16 ++++++++-- src/ql/time/calendars/southkorea.cpp | 1 + src/ql/time/date.hpp | 32 +++++++++----------- src/ql/utilities/dataformatters.cpp | 6 +--- src/ql/utilities/null.hpp | 45 +++++++++++----------------- 17 files changed, 108 insertions(+), 128 deletions(-) delete mode 100644 src/ql/optional.cpp diff --git a/ChangeLog b/ChangeLog index aff9adb..38d7478 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2024-10-07 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): Roll micro version and date + + * src/ql/time/calendars/poland.?pp: Updated from QuantLib 1.36 (rc) + * src/ql/time/calendars/southkorea.cpp: Idem + + * src/ql/*: Small updates from 1.36 (rc) to nine more files + 2024-09-03 Dirk Eddelbuettel * DESCRIPTION (Authors@R): Added diff --git a/DESCRIPTION b/DESCRIPTION index 83a0518..d05ee2e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: qlcal Type: Package Title: R Bindings to the Calendaring Functionality of 'QuantLib' -Version: 0.0.12 -Date: 2024-07-23 +Version: 0.0.12.1 +Date: 2024-10-07 Authors@R: c(person("Dirk", "Eddelbuettel", role = c("aut", "cre"), email = "edd@debian.org", comment = c(ORCID = "0000-0001-6419-907X")), person("QuantLib Authors", role = "aut")) diff --git a/src/Makevars.in b/src/Makevars.in index a97c204..4de97d6 100644 --- a/src/Makevars.in +++ b/src/Makevars.in @@ -65,7 +65,6 @@ SOURCES = \ ql/utilities/dataformatters.cpp \ ql/utilities/dataparsers.cpp \ ql/errors.cpp \ - ql/optional.cpp \ ql/settings.cpp \ calendars.cpp \ dates.cpp \ diff --git a/src/Makevars.win.in b/src/Makevars.win.in index a97c204..4de97d6 100644 --- a/src/Makevars.win.in +++ b/src/Makevars.win.in @@ -65,7 +65,6 @@ SOURCES = \ ql/utilities/dataformatters.cpp \ ql/utilities/dataparsers.cpp \ ql/errors.cpp \ - ql/optional.cpp \ ql/settings.cpp \ calendars.cpp \ dates.cpp \ diff --git a/src/ql/errors.cpp b/src/ql/errors.cpp index aa6b008..1a6c57b 100644 --- a/src/ql/errors.cpp +++ b/src/ql/errors.cpp @@ -22,7 +22,7 @@ namespace { - #if defined(_MSC_VER) || defined(__BORLANDC__) + #if defined(_MSC_VER) // allow Visual Studio integration std::string format( #ifdef QL_ERROR_LINES diff --git a/src/ql/optional.cpp b/src/ql/optional.cpp deleted file mode 100644 index 9c6dd36..0000000 --- a/src/ql/optional.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* - Copyright (C) 2023 Jonathan Sweemer - - This file is part of QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - - QuantLib is free software: you can redistribute it and/or modify it - under the terms of the QuantLib license. You should have received a - copy of the license along with this program; if not, please email - . The license is also available online at - . - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -#include - -namespace QuantLib { - - namespace ext { - - #if !defined(QL_USE_STD_OPTIONAL) - const boost::none_t& nullopt = boost::none; - #endif - - } - -} - diff --git a/src/ql/optional.hpp b/src/ql/optional.hpp index bb7c27d..e9fe910 100644 --- a/src/ql/optional.hpp +++ b/src/ql/optional.hpp @@ -32,22 +32,16 @@ #include #endif -namespace QuantLib { - - namespace ext { +namespace QuantLib::ext { #if defined(QL_USE_STD_OPTIONAL) using std::optional; // NOLINT(misc-unused-using-decls) - // here we can assume C++17 inline constexpr const std::nullopt_t& nullopt = std::nullopt; #else using boost::optional; // NOLINT(misc-unused-using-decls) - // here we can't - extern const boost::none_t& nullopt; + inline constexpr const boost::none_t& nullopt = boost::none; #endif } -} - #endif diff --git a/src/ql/patterns/observable.hpp b/src/ql/patterns/observable.hpp index f7536c7..0d366f4 100644 --- a/src/ql/patterns/observable.hpp +++ b/src/ql/patterns/observable.hpp @@ -64,7 +64,7 @@ namespace QuantLib { friend class ObservableSettings; public: // constructors, assignment, destructor - Observable(); + Observable() = default; Observable(const Observable&); Observable& operator=(const Observable&); // delete the move operations because the semantics are not yet clear @@ -158,8 +158,6 @@ namespace QuantLib { // inline definitions - inline Observable::Observable() = default; - inline void ObservableSettings::registerDeferredObservers(const Observable::set_type& observers) { if (updatesDeferred()) { deferredObservers_.insert(observers.begin(), observers.end()); diff --git a/src/ql/patterns/singleton.hpp b/src/ql/patterns/singleton.hpp index 9b1ab56..c067673 100644 --- a/src/ql/patterns/singleton.hpp +++ b/src/ql/patterns/singleton.hpp @@ -108,22 +108,6 @@ namespace QuantLib { #endif - // backwards compatibility - -#if defined(QL_THREAD_KEY) - /*! \deprecated This typedef is obsolete. Do not use it. - Deprecated in version 1.29. - */ - QL_DEPRECATED - typedef QL_THREAD_KEY ThreadKey; -#else - /*! \deprecated This typedef is obsolete. Do not use it. - Deprecated in version 1.29. - */ - QL_DEPRECATED - typedef Integer ThreadKey; -#endif - } #endif diff --git a/src/ql/shared_ptr.hpp b/src/ql/shared_ptr.hpp index 90bc28d..64e09b9 100644 --- a/src/ql/shared_ptr.hpp +++ b/src/ql/shared_ptr.hpp @@ -34,9 +34,7 @@ #include #endif -namespace QuantLib { - - namespace ext { +namespace QuantLib::ext { #if defined(QL_USE_STD_SHARED_PTR) using std::shared_ptr; // NOLINT(misc-unused-using-decls) @@ -56,8 +54,6 @@ namespace QuantLib { } -} - #endif diff --git a/src/ql/time/calendar.hpp b/src/ql/time/calendar.hpp index 35b6032..8933ca8 100644 --- a/src/ql/time/calendar.hpp +++ b/src/ql/time/calendar.hpp @@ -108,6 +108,12 @@ namespace QuantLib { weekend for the given market. */ bool isWeekend(Weekday w) const; + /*! Returns true iff in the given market, the date is on + or before the first business day for that month. + */ + bool isStartOfMonth(const Date& d) const; + //! first business day of the month to which the given date belongs + Date startOfMonth(const Date& d) const; /*! Returns true iff in the given market, the date is on or after the last business day for that month. */ @@ -240,8 +246,16 @@ namespace QuantLib { return impl_->isBusinessDay(_d); } + inline bool Calendar::isStartOfMonth(const Date& d) const { + return d <= startOfMonth(d); + } + + inline Date Calendar::startOfMonth(const Date& d) const { + return adjust(Date::startOfMonth(d), Following); + } + inline bool Calendar::isEndOfMonth(const Date& d) const { - return (d.month() != adjust(d+1).month()); + return d >= endOfMonth(d); } inline Date Calendar::endOfMonth(const Date& d) const { diff --git a/src/ql/time/calendars/poland.cpp b/src/ql/time/calendars/poland.cpp index b5ff3d1..747f794 100644 --- a/src/ql/time/calendars/poland.cpp +++ b/src/ql/time/calendars/poland.cpp @@ -18,16 +18,27 @@ */ #include +#include namespace QuantLib { - Poland::Poland() { + Poland::Poland(Poland::Market market) { // all calendar instances share the same implementation instance - static ext::shared_ptr impl(new Poland::Impl); - impl_ = impl; + static auto settlementImpl = ext::make_shared(); + static auto wseImpl = ext::make_shared(); + switch (market) { + case Settlement: + impl_ = settlementImpl; + break; + case WSE: + impl_ = wseImpl; + break; + default: + QL_FAIL("unknown market"); + } } - bool Poland::Impl::isBusinessDay(const Date& date) const { + bool Poland::SettlementImpl::isBusinessDay(const Date& date) const { Weekday w = date.weekday(); Day d = date.dayOfMonth(), dd = date.dayOfYear(); Month m = date.month(); @@ -60,5 +71,20 @@ namespace QuantLib { return true; } + + bool Poland::WseImpl::isBusinessDay(const Date& date) const { + // Additional holidays for Warsaw Stock Exchange + // see https://www.gpw.pl/session-details + Day d = date.dayOfMonth(); + Month m = date.month(); + + if ( + (d == 24 && m == December) + || (d == 31 && m == December) + ) return false; // NOLINT(readability-simplify-boolean-expr) + + return SettlementImpl::isBusinessDay(date); + } + } diff --git a/src/ql/time/calendars/poland.hpp b/src/ql/time/calendars/poland.hpp index 459ef8f..abbe909 100644 --- a/src/ql/time/calendars/poland.hpp +++ b/src/ql/time/calendars/poland.hpp @@ -50,13 +50,23 @@ namespace QuantLib { */ class Poland : public Calendar { private: - class Impl final : public Calendar::WesternImpl { + class SettlementImpl : public Calendar::WesternImpl { public: - std::string name() const override { return "Poland"; } + std::string name() const override { return "Poland Settlement"; } + bool isBusinessDay(const Date&) const override; + }; + class WseImpl final : public SettlementImpl { + public: + std::string name() const override { return "Warsaw stock exchange"; } bool isBusinessDay(const Date&) const override; }; public: - Poland(); + //! PL calendars + enum Market { Settlement, //!< Settlement calendar + WSE, //!< Warsaw stock exchange calendar + }; + + explicit Poland(Market market = Settlement); }; } diff --git a/src/ql/time/calendars/southkorea.cpp b/src/ql/time/calendars/southkorea.cpp index 12d6d51..b31ff20 100644 --- a/src/ql/time/calendars/southkorea.cpp +++ b/src/ql/time/calendars/southkorea.cpp @@ -206,6 +206,7 @@ namespace QuantLib { // Special temporary holiday || (d == 17 && m == August && y == 2020) || (d == 2 && m == October && y == 2023) + || (d == 1 && m == October && y == 2024) // Harvest Moon Day || ((d == 27 || d == 28 || d == 29) && m == September && y == 2004) diff --git a/src/ql/time/date.hpp b/src/ql/time/date.hpp index 6571566..7e209d4 100644 --- a/src/ql/time/date.hpp +++ b/src/ql/time/date.hpp @@ -207,6 +207,10 @@ namespace QuantLib { static Date maxDate(); //! whether the given year is a leap one static bool isLeap(Year y); + //! first day of the month to which the given date belongs + static Date startOfMonth(const Date& d); + //! whether a date is the first day of its month + static bool isStartOfMonth(const Date& d); //! last day of the month to which the given date belongs static Date endOfMonth(const Date& d); //! whether a date is the last day of its month @@ -291,7 +295,7 @@ namespace QuantLib { #include std::unordered_set set; - Date d = Date(1, Jan, 2020); + Date d = Date(1, Jan, 2020); set.insert(d); assert(set.count(d)); // 'd' was added to 'set' @@ -370,28 +374,20 @@ namespace QuantLib { } - #ifdef QL_NULL_AS_FUNCTIONS - //! specialization of Null template for the Date class - template <> - inline Date Null() { - return {}; - } - - #else + // inline definitions - template <> - class Null { - public: - Null() = default; - operator Date() const { return {}; } - }; + inline Date Date::startOfMonth(const Date& d) { + Month m = d.month(); + Year y = d.year(); + return Date(1, m, y); + } - #endif + inline bool Date::isStartOfMonth(const Date& d) { + return (d.dayOfMonth() == 1); + } #ifndef QL_HIGH_RESOLUTION_DATE - // inline definitions - inline Weekday Date::weekday() const { Integer w = serialNumber_ % 7; return Weekday(w == 0 ? 7 : w); diff --git a/src/ql/utilities/dataformatters.cpp b/src/ql/utilities/dataformatters.cpp index 69af7ba..00bb262 100644 --- a/src/ql/utilities/dataformatters.cpp +++ b/src/ql/utilities/dataformatters.cpp @@ -20,9 +20,7 @@ #include #include -namespace QuantLib { - - namespace detail { +namespace QuantLib::detail { std::ostream& operator<<(std::ostream& out, const ordinal_holder& holder) { @@ -58,5 +56,3 @@ namespace QuantLib { } -} - diff --git a/src/ql/utilities/null.hpp b/src/ql/utilities/null.hpp index 2c6b70a..915786a 100644 --- a/src/ql/utilities/null.hpp +++ b/src/ql/utilities/null.hpp @@ -32,37 +32,20 @@ namespace QuantLib { - namespace detail { - - template - struct FloatingPointNull; - - // null value for floating-point types - template <> - struct FloatingPointNull { - constexpr static float nullValue() { - // a specific values that should fit into any Real - return (std::numeric_limits::max)(); - } - }; - - // null value for integer types - template <> - struct FloatingPointNull { - constexpr static int nullValue() { - // a specific values that should fit into any Integer - return (std::numeric_limits::max)(); - } - }; - - } - #ifdef QL_NULL_AS_FUNCTIONS //! template function providing a null value for a given type. template T Null() { - return T(detail::FloatingPointNull::value>::nullValue()); + if constexpr (std::is_floating_point_v) { + // a specific, unlikely value that should fit into any Real + return (std::numeric_limits::max)(); + } else if constexpr (std::is_integral_v) { + // this should fit into any Integer + return (std::numeric_limits::max)(); + } else { + return T(); + } } #else @@ -77,7 +60,15 @@ namespace QuantLib { public: Null() = default; operator T() const { - return T(detail::FloatingPointNull::value>::nullValue()); + if constexpr (std::is_floating_point_v) { + // a specific, unlikely value that should fit into any Real + return (std::numeric_limits::max)(); + } else if constexpr (std::is_integral_v) { + // this should fit into any Integer + return (std::numeric_limits::max)(); + } else { + return T(); + } } };