lmi-commits
[Top][All Lists]
Advanced

[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
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]