[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 4a80821 3/4: Implement a new database query f
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 4a80821 3/4: Implement a new database query function with a distinct name |
Date: |
Mon, 5 Nov 2018 19:33:45 -0500 (EST) |
branch: master
commit 4a80821e4ff6033a6bdeb39e442f0cec3a7afeaa
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>
Implement a new database query function with a distinct name
Soon, the names of all such functions will be changed--see:
https://lists.nongnu.org/archive/html/lmi/2018-11/msg00009.html
This one is changed first, and will be put into service first, in order
to solve an actual problem with a nonconforming proprietary compiler:
https://lists.nongnu.org/archive/html/lmi/2018-11/msg00007.html
---
database.cpp | 9 ++-------
database.hpp | 27 +++++++++++++++++++++++++++
2 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/database.cpp b/database.cpp
index 022d1a3..3cbf87a 100644
--- a/database.cpp
+++ b/database.cpp
@@ -76,8 +76,8 @@ product_database::product_database(yare_input const& input)
///
/// Almost all database queries use the default index, so caching this
/// value improves performance. For a query with an overridden index
-/// that modifies issue age, the cached value is incorrect, so Query()
-/// never relies on it.
+/// that modifies issue age, this cached value is incorrect, so member
+/// functions that use a different index don't rely on it.
int product_database::length() const
{
@@ -128,11 +128,6 @@ void product_database::Query(std::vector<double>& dst,
e_database_key k) const
///
/// Return a double because it is convertible to the most common
/// arithmetic types.
-///
-/// An idea like this:
-/// template<typename T, typename DBValue>
-/// void Query(T&, e_database_key) const;
-/// might prove useful someday.
double product_database::Query(e_database_key k, database_index const& i) const
{
diff --git a/database.hpp b/database.hpp
index 12b0722..e843242 100644
--- a/database.hpp
+++ b/database.hpp
@@ -24,6 +24,7 @@
#include "config.hpp"
+#include "bourn_cast.hpp"
#include "dbindex.hpp"
#include "dbnames.hpp" // e_database_key
#include "mc_enum_type_enums.hpp"
@@ -31,6 +32,7 @@
#include <memory> // shared_ptr
#include <string>
+#include <type_traits> // is_integral_v, underlying_type_t
#include <vector>
class database_entity;
@@ -74,6 +76,9 @@ class LMI_SO product_database final
double Query(e_database_key, database_index const&) const;
double Query(e_database_key) const;
+ template<typename T>
+ void query_into(T&, e_database_key) const;
+
bool are_equivalent(e_database_key, e_database_key) const;
bool varies_by_state(e_database_key) const;
@@ -92,5 +97,27 @@ class LMI_SO product_database final
std::shared_ptr<DBDictionary> db_;
};
+/// Query database, using default index; write result into scalar argument.
+///
+/// Casts result to type T, preserving value by using bourn_cast.
+///
+/// Throw if the database entity is not scalar, or if casting fails
+/// (because T is neither enumerative nor arithmetic, or because the
+/// result cannot be represented exactly in type T).
+
+template<typename T>
+void product_database::query_into(T& dst, e_database_key k) const
+{
+ double d = Query(k, index_);
+ if constexpr(std::is_enum_v<T>)
+ {
+ dst = static_cast<T>(bourn_cast<std::underlying_type_t<T>>(d));
+ }
+ else
+ {
+ dst = bourn_cast<T>(d);
+ }
+}
+
#endif // database_hpp