[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master b321588 05/11: Demonstrate PETE assignment to
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master b321588 05/11: Demonstrate PETE assignment to std::vector |
Date: |
Tue, 16 Feb 2021 13:06:22 -0500 (EST) |
branch: master
commit b3215884eaba6c1fb7cb13ad4b08c0b3af3bc8fd
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Demonstrate PETE assignment to std::vector
This just documents that there's no much better way than what's
already been done.
---
expression_template_0_test.cpp | 84 +++++++++++++++++++++++++++++-------------
interest_rates.cpp | 2 +
2 files changed, 60 insertions(+), 26 deletions(-)
diff --git a/expression_template_0_test.cpp b/expression_template_0_test.cpp
index be30f46..5b1292e 100644
--- a/expression_template_0_test.cpp
+++ b/expression_template_0_test.cpp
@@ -345,27 +345,6 @@ void mete_ublas_typical()
}
#endif // defined USE_UBLAS
-/// Syntactic sugar: "assignment" operator for expression templates.
-///
-/// PETE doesn't support this:
-/// std::vector<double> v2 = v0 - v1;
-/// because it's impossible to intrude a copy-assignment operator into
-/// the standard class template.
-///
-/// operator^=() or operator<<=() would probably be better, but would
-/// require changing the PETE sources, whereas the normally-undefined
-/// macro PETE_ALLOW_SCALAR_SHIFT leaves operator<<() available without
-/// any such change. But is this syntactic sugar sweet enough?
-
-template<typename T, typename V>
-std::vector<T>& operator<<(std::vector<T>& t, V v)
-{
-#if defined PETE_ALLOW_SCALAR_SHIFT
-# error PETE_ALLOW_SCALAR_SHIFT must not be defined.
-#endif // defined PETE_ALLOW_SCALAR_SHIFT
- return assign(t, v);
-}
-
void mete_pete_typical()
{
for(int i = 0; i < n_iter; ++i)
@@ -475,15 +454,68 @@ void time_one_array_length(int length)
std::cout << std::endl;
}
+/// Syntactic sugar: "assignment" operator for expression templates.
+///
+/// PETE doesn't support this:
+/// std::vector<double> v2 = v0 - v1;
+/// because it's impossible to intrude a copy-assignment operator into
+/// the standard class template.
+///
+/// operator^=() or operator<<=() would probably be better, but would
+/// require changing the PETE sources, whereas the normally-undefined
+/// macro PETE_ALLOW_SCALAR_SHIFT leaves operator<<() available without
+/// any such change. But is this syntactic sugar sweet enough?
+
+template<typename T, typename V>
+std::vector<T>& operator<<(std::vector<T>& t, V v)
+{
+#if defined PETE_ALLOW_SCALAR_SHIFT
+# error PETE_ALLOW_SCALAR_SHIFT must not be defined.
+#endif // defined PETE_ALLOW_SCALAR_SHIFT
+ return assign(t, v);
+}
+
+/// Assigning PETE expressions to a std::vector
+///
+/// std::vector<>::operator= is necessarily a member function, and
+/// cannot be overloaded. This function shows some alternatives,
+/// none of which seems ideal:
+///
+/// assign(v, expression);
+/// v = std::vector(intended_size); v << expression;
+/// v = std::vector(intended_size); v += expression;
+
void test_pete_assignment()
{
+ std::vector<double> const v0 = {1.1, 2.2, 3.3, 4.4, 5.5};
+ std::vector<double> const v1 = {0.1, 0.2, 0.3, 0.4, 0.5};
+ std::vector<double> const v2 = {1.0, 2.0, 3.0, 4.0, 5.0};
// With the operator<<() above, this:
-// std::vector<double> pv7a(pv0.size()); assign(pv7a, pv0 - pv1);
+ std::vector<double> v7a(v0.size());
+ assign(v7a, v0 - v1);
+ BOOST_TEST(std::operator==(v2, v7a));
// could be written thus:
-// std::vector<double> pv7b(pv0.size()); pv7b << pv0 - pv1;
-// but these still wouldn't work:
-// std::vector<double> pv7c << pv0 - pv1;
-// std::vector<double> pv7d(pv0 - pv1);
+ std::vector<double> v7b(v0.size());
+ v7b << v0 - v1;
+ BOOST_TEST(std::operator==(v2, v7b));
+// though these still wouldn't compile:
+// std::vector<double> v7c << v0 - v1;
+// std::vector<double> v7d(v0 - v1);
+// and, although this compiles:
+ std::vector<double> v7e; v7e << v0 - v1;
+// it doesn't do what one might hope--instead, the vector is empty:
+ BOOST_TEST(0 == v7e.size());
+
+// On the other hand, this syntax is almost natural, even though it's
+// silly to add zero to everything.
+ std::vector<double> v7f(v0.size());
+ v7f += v0 - v1;
+ BOOST_TEST(std::operator==(v2, v7f));
+// But that may be the best that can easily be done with PETE: where
+// std::vector<double> v7f += v0 - v1;
+// is wanted, instead write
+// std::vector<double> v7f(intended_size);
+// v7f += v0 - v1;
}
int test_main(int, char*[])
diff --git a/interest_rates.cpp b/interest_rates.cpp
index 81f0047..6810fc3 100644
--- a/interest_rates.cpp
+++ b/interest_rates.cpp
@@ -547,6 +547,7 @@ void InterestRates::InitializeSeparateAccountRates()
// X = zero_vector_of_desired_length;
// X += 0.5 * Y;
// but it's forbidden to add such an operator to std::vector.
+ // See test_pete_assignment() in 'expression_template_0_test.cpp'.
SepAcctGrossRate_[mce_annual_rate][mce_sep_half] = Zero_;
SepAcctGrossRate_[mce_annual_rate][mce_sep_half] +=
0.5 * SepAcctGrossRate_[mce_annual_rate][mce_sep_full];
@@ -954,6 +955,7 @@ void InterestRates::Initialize7702Rates()
// ET !! This ought to be implicit, at least in some 'safe' mode:
// LMI_ASSERT_EQUAL(MlyGlpRate_.size(), SpreadFor7702_.size());
// _without_ assigning from Zero_ first; but it's not.
+ // See test_pete_assignment() in 'expression_template_0_test.cpp'.
MlyGlpRate_ = Zero_;
assign(MlyGlpRate_, apply_binary(greater_of<double>(), iglp(),
annual_guar_rate));
LMI_ASSERT(MlyGlpRate_.size() == SpreadFor7702_.size());
- [lmi-commits] [lmi] master updated (3143a30 -> c90e25a), Greg Chicares, 2021/02/16
- [lmi-commits] [lmi] master b321588 05/11: Demonstrate PETE assignment to std::vector,
Greg Chicares <=
- [lmi-commits] [lmi] master bcec152 08/11: Amend PETE header and footer for generated files, Greg Chicares, 2021/02/16
- [lmi-commits] [lmi] master 2741732 07/11: Break a makefile dependency cycle, Greg Chicares, 2021/02/16
- [lmi-commits] [lmi] master 2a92707 04/11: Move a comment block that will soon become a test, Greg Chicares, 2021/02/16
- [lmi-commits] [lmi] master 431bdbb 01/11: Do not include PETE in any header except "et_vector.hpp", Greg Chicares, 2021/02/16
- [lmi-commits] [lmi] master acac3ad 03/11: Accommodate 21st-century hardware, Greg Chicares, 2021/02/16
- [lmi-commits] [lmi] master c90e25a 11/11: No longer invoke std::operator==() explicitly for vectors, Greg Chicares, 2021/02/16
- [lmi-commits] [lmi] master 2844ba0 10/11: Suppress PETE's operator==() for std::vector, Greg Chicares, 2021/02/16
- [lmi-commits] [lmi] master 7f3f834 06/11: Rewrite '*clean*' targets, Greg Chicares, 2021/02/16
- [lmi-commits] [lmi] master 088d2a8 09/11: Regenerate PETE, Greg Chicares, 2021/02/16
- [lmi-commits] [lmi] master 38d5ece 02/11: Further improve physical design, Greg Chicares, 2021/02/16