Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimize build time (move stuff from hpp to cpp) #1787

Closed
wants to merge 13 commits into from
2 changes: 2 additions & 0 deletions QuantLib.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2237,6 +2237,7 @@
<ClCompile Include="ql\legacy\libormarketmodels\lmlinexpvolmodel.cpp" />
<ClCompile Include="ql\legacy\libormarketmodels\lmvolmodel.cpp" />
<ClCompile Include="ql\math\abcdmathfunction.cpp" />
<ClCompile Include="ql\math\array.cpp" />
<ClCompile Include="ql\math\bernsteinpolynomial.cpp" />
<ClCompile Include="ql\math\beta.cpp" />
<ClCompile Include="ql\math\bspline.cpp" />
Expand Down Expand Up @@ -2271,6 +2272,7 @@
<ClCompile Include="ql\math\integrals\integral.cpp" />
<ClCompile Include="ql\math\integrals\kronrodintegral.cpp" />
<ClCompile Include="ql\math\integrals\segmentintegral.cpp" />
<ClCompile Include="ql\math\interpolations\cubicinterpolation.cpp" />
<ClCompile Include="ql\math\interpolations\chebyshevinterpolation.cpp" />
<ClCompile Include="ql\math\matrix.cpp" />
<ClCompile Include="ql\math\matrixutilities\basisincompleteordered.cpp" />
Expand Down
6 changes: 6 additions & 0 deletions QuantLib.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -4841,6 +4841,9 @@
<ClCompile Include="ql\math\abcdmathfunction.cpp">
<Filter>math</Filter>
</ClCompile>
<ClCompile Include="ql\math\array.cpp">
<Filter>math</Filter>
</ClCompile>
<ClCompile Include="ql\math\bernsteinpolynomial.cpp">
<Filter>math</Filter>
</ClCompile>
Expand Down Expand Up @@ -7162,6 +7165,9 @@
<ClCompile Include="ql\pricingengines\asian\turnbullwakemanasianengine.cpp">
<Filter>pricingengines\asian</Filter>
</ClCompile>
<ClCompile Include="ql\math\interpolations\cubicinterpolation.cpp">
<Filter>math\interpolations</Filter>
</ClCompile>
<ClCompile Include="ql\math\interpolations\chebyshevinterpolation.cpp">
<Filter>math\interpolations</Filter>
</ClCompile>
Expand Down
2 changes: 2 additions & 0 deletions ql/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ set(QL_SOURCES
legacy/libormarketmodels/lmlinexpvolmodel.cpp
legacy/libormarketmodels/lmvolmodel.cpp
math/abcdmathfunction.cpp
math/array.cpp
math/bernsteinpolynomial.cpp
math/beta.cpp
math/bspline.cpp
Expand Down Expand Up @@ -375,6 +376,7 @@ set(QL_SOURCES
math/integrals/kronrodintegral.cpp
math/integrals/segmentintegral.cpp
math/interpolations/chebyshevinterpolation.cpp
math/interpolations/cubicinterpolation.cpp
math/matrix.cpp
math/matrixutilities/basisincompleteordered.cpp
math/matrixutilities/bicgstab.cpp
Expand Down
1 change: 1 addition & 0 deletions ql/cashflows/dividend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define quantlib_dividend_hpp

#include <ql/cashflow.hpp>
#include <ql/errors.hpp>
#include <ql/utilities/null.hpp>
#include <vector>

Expand Down
1 change: 1 addition & 0 deletions ql/cashflows/simplecashflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
FOR A PARTICULAR PURPOSE. See the license for more details.
*/

#include <ql/errors.hpp>
#include <ql/cashflows/simplecashflow.hpp>

namespace QuantLib {
Expand Down
1 change: 1 addition & 0 deletions ql/currency.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define quantlib_currency_hpp

#include <ql/math/rounding.hpp>
#include <ql/shared_ptr.hpp>
#include <ql/errors.hpp>
#include <iosfwd>
#include <set>
Expand Down
7 changes: 4 additions & 3 deletions ql/errors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,11 @@ namespace QuantLib {
Error::Error(const std::string& file, long line,
const std::string& function,
const std::string& message) {
message_ = ext::make_shared<std::string>(
format(file, line, function, message));
message_ = format(file, line, function, message);
}

const char* Error::what() const noexcept { return message_->c_str(); }
const char* Error::what() const noexcept {
return message_.c_str();
}
}

97 changes: 29 additions & 68 deletions ql/errors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@
#ifndef quantlib_errors_hpp
#define quantlib_errors_hpp

#include <ql/qldefines.hpp>
#include <ql/shared_ptr.hpp>
#include <boost/assert.hpp>
#include <boost/current_function.hpp>
#include <exception>
#include <sstream>
Expand All @@ -49,94 +46,58 @@ namespace QuantLib {
const char* what() const noexcept override;

private:
ext::shared_ptr<std::string> message_;
std::string message_;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, having ext::shared_ptr<std::string> makes the copy constructor not throwing, as required by the standard. With std::string, it can throw. On the other hand, if it throws, it probably means we're out of memory anyway so all bets are off. I'd try and measure the effect of shared_ptr only, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I had to look that requirement to be honest.

};

}

#define QL_MULTILINE_FAILURE_BEGIN do {

/* Disable warning C4127 (conditional expression is constant) when
wrapping macros with the do { ... } while(false) construct on MSVC
*/
#if defined(BOOST_MSVC)
#define QL_MULTILINE_FAILURE_END \
__pragma(warning(push)) \
__pragma(warning(disable:4127)) \
} while(false) \
__pragma(warning(pop))
#else
#define QL_MULTILINE_FAILURE_END } while(false)
#endif


#define QL_MULTILINE_ASSERTION_BEGIN do {

/* Disable warning C4127 (conditional expression is constant) when
wrapping macros with the do { ... } while(false) construct on MSVC
/*! \def QL_ASSERT
\brief throw an error if the given condition is not verified
*/
#if defined(BOOST_MSVC)
#define QL_MULTILINE_ASSERTION_END \
__pragma(warning(push)) \
__pragma(warning(disable:4127)) \
} while(false) \
__pragma(warning(pop))

# define QL_ASSERT(condition, message) \
do { \
if (!(condition)) { \
std::ostringstream _ql_msg_stream; \
_ql_msg_stream << message; \
throw QuantLib::Error(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, \
_ql_msg_stream.str()); \
} \
__pragma(warning(push)) __pragma(warning(disable : 4127)) \
} while (false) __pragma(warning(pop))

#else
#define QL_MULTILINE_ASSERTION_END } while(false)
#endif

# define QL_ASSERT(condition, message) \
do { \
if (!(condition)) { \
std::ostringstream _ql_msg_stream; \
_ql_msg_stream << message; \
throw QuantLib::Error(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, \
_ql_msg_stream.str()); \
} \
} while (false)

#endif

/*! \def QL_FAIL
\brief throw an error (possibly with file and line information)
*/
#define QL_FAIL(message) \
QL_MULTILINE_FAILURE_BEGIN \
std::ostringstream _ql_msg_stream; \
_ql_msg_stream << message; \
throw QuantLib::Error(__FILE__,__LINE__, \
BOOST_CURRENT_FUNCTION,_ql_msg_stream.str()); \
QL_MULTILINE_FAILURE_END


/*! \def QL_ASSERT
\brief throw an error if the given condition is not verified
*/
#define QL_ASSERT(condition,message) \
QL_MULTILINE_ASSERTION_BEGIN \
if (!(condition)) { \
std::ostringstream _ql_msg_stream; \
_ql_msg_stream << message; \
throw QuantLib::Error(__FILE__,__LINE__, \
BOOST_CURRENT_FUNCTION,_ql_msg_stream.str()); \
} \
QL_MULTILINE_ASSERTION_END
#define QL_FAIL(message) QL_ASSERT(false, message)

/*! \def QL_REQUIRE
\brief throw an error if the given pre-condition is not verified
*/
#define QL_REQUIRE(condition,message) \
QL_MULTILINE_ASSERTION_BEGIN \
if (!(condition)) { \
std::ostringstream _ql_msg_stream; \
_ql_msg_stream << message; \
throw QuantLib::Error(__FILE__,__LINE__, \
BOOST_CURRENT_FUNCTION,_ql_msg_stream.str()); \
} \
QL_MULTILINE_ASSERTION_END
#define QL_REQUIRE(condition, message) QL_ASSERT(condition, message)

/*! \def QL_ENSURE
\brief throw an error if the given post-condition is not verified
*/
#define QL_ENSURE(condition,message) \
QL_MULTILINE_ASSERTION_BEGIN \
if (!(condition)) { \
std::ostringstream _ql_msg_stream; \
_ql_msg_stream << message; \
throw QuantLib::Error(__FILE__,__LINE__, \
BOOST_CURRENT_FUNCTION,_ql_msg_stream.str()); \
} \
QL_MULTILINE_ASSERTION_END

#define QL_ENSURE(condition, message) QL_ASSERT(condition, message)

#endif

1 change: 1 addition & 0 deletions ql/event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
FOR A PARTICULAR PURPOSE. See the license for more details.
*/

#include <ql/errors.hpp>
#include <ql/event.hpp>
#include <ql/patterns/visitor.hpp>
#include <ql/optional.hpp>
Expand Down
2 changes: 2 additions & 0 deletions ql/experimental/commodities/paymentterm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include <ql/experimental/commodities/paymentterm.hpp>

#include <ostream>

namespace QuantLib {

std::map<std::string, ext::shared_ptr<PaymentTerm::Data> >
Expand Down
1 change: 1 addition & 0 deletions ql/experimental/math/isotropicrandomwalk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#ifndef quantlib_isotropic_random_walk_hpp
#define quantlib_isotropic_random_walk_hpp

#include <ql/errors.hpp>
#include <ql/math/array.hpp>
#include <ql/math/randomnumbers/mt19937uniformrng.hpp>
#include <ql/mathconstants.hpp>
Expand Down
1 change: 1 addition & 0 deletions ql/experimental/math/multidimintegrator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#ifndef quantlib_math_multidimintegrator_hpp
#define quantlib_math_multidimintegrator_hpp

#include <ql/shared_ptr.hpp>
#include <ql/types.hpp>
#include <ql/errors.hpp>
#include <ql/math/integrals/integral.hpp>
Expand Down
1 change: 1 addition & 0 deletions ql/experimental/volatility/noarbsabr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#define quantlib_noarb_sabr

#include <ql/qldefines.hpp>
#include <ql/shared_ptr.hpp>
#include <ql/types.hpp>
#include <ql/math/integrals/gausslobattointegral.hpp>

Expand Down
1 change: 1 addition & 0 deletions ql/handle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#ifndef quantlib_handle_hpp
#define quantlib_handle_hpp

#include <ql/errors.hpp>
#include <ql/patterns/observable.hpp>

namespace QuantLib {
Expand Down
71 changes: 71 additions & 0 deletions ql/instrument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
FOR A PARTICULAR PURPOSE. See the license for more details.
*/

#include <ql/errors.hpp>
#include <ql/instrument.hpp>
#include <ql/settings.hpp>

Expand Down Expand Up @@ -46,4 +47,74 @@ namespace QuantLib {
QL_FAIL("Instrument::setupArguments() not implemented");
}

void Instrument::calculate() const {
if (!calculated_) {
if (isExpired()) {
setupExpired();
calculated_ = true;
} else {
LazyObject::calculate();
}
}
}

void Instrument::setupExpired() const {
NPV_ = errorEstimate_ = 0.0;
valuationDate_ = Date();
additionalResults_.clear();
}

void Instrument::performCalculations() const {
QL_REQUIRE(engine_, "null pricing engine");
engine_->reset();
setupArguments(engine_->getArguments());
engine_->getArguments()->validate();
engine_->calculate();
fetchResults(engine_->getResults());
}

void Instrument::fetchResults(
const PricingEngine::results* r) const {
const auto* results = dynamic_cast<const Instrument::results*>(r);
QL_ENSURE(results != nullptr, "no results returned from pricing engine");

NPV_ = results->value;
errorEstimate_ = results->errorEstimate;
valuationDate_ = results->valuationDate;

additionalResults_ = results->additionalResults;
}

Real Instrument::NPV() const {
calculate();
QL_REQUIRE(NPV_ != Null<Real>(), "NPV not provided");
return NPV_;
}

Real Instrument::errorEstimate() const {
calculate();
QL_REQUIRE(errorEstimate_ != Null<Real>(),
"error estimate not provided");
return errorEstimate_;
}

const Date& Instrument::valuationDate() const {
calculate();
QL_REQUIRE(valuationDate_ != Date(),
"valuation date not provided");
return valuationDate_;
}

const std::map<std::string, ext::any>&
Instrument::additionalResults() const {
calculate();
return additionalResults_;
}

void Instrument::results::reset() {
value = errorEstimate = Null<Real>();
valuationDate = Date();
additionalResults.clear();
}

}
Loading