Procházet zdrojové kódy

Adds Mean and Range Reduce classes. Integrates Function type into
Filters. Reimplements TH2-based containers using new class hierarchy.

Caleb Fangmeier před 8 roky
rodič
revize
cbfd3422eb
2 změnil soubory, kde provedl 77 přidání a 21 odebrání
  1. 49 8
      filter.hpp
  2. 28 13
      value.hpp

+ 49 - 8
filter.hpp

@@ -1,35 +1,76 @@
+/**
+ * @file
+ * @author  Caleb Fangmeier <caleb@fangmeier.tech>
+ * @version 0.1
+ *
+ * @section LICENSE
+ *
+ *
+ * MIT License
+ *
+ * Copyright (c) 2017 Caleb Fangmeier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * @section DESCRIPTION
+ * A Filter is a special type of derived value that can only return a boolean.
+ * Container objects have a vector of filters that control if a "fill" call
+ * actually places data into the container or not. This file contains a variety
+ * of generic filters to aide in analysis.
+ */
 #ifndef filter_h
 #define filter_h
 #include <iostream>
 #include <functional>
 #include "value.hpp"
-/* A Filter is a special type of derived value that can only return a boolean.
- * Container objects have a vector of filters that control if a "fill" call
- * actually places data into the container or not.
- */
 namespace fv {
 
 class Filter : public DerivedValue<bool>{
     private:
-        std::function<bool()> filter_function;
+        Function<bool()>& filter_function;
+
         void update_value(){
             value = filter_function();
         }
     public:
-        Filter(const std::string& name, std::function<bool()> filter_function)
+        Filter(const std::string& name, std::function<bool()> filter_function, const std::string& impl="")
           :DerivedValue<bool>(name),
-           filter_function(filter_function){ }
+           filter_function(GenFunction::register_function<bool()>("filter::"+name, filter_function, impl)){ }
 
+        /** Return a new filter that is the conjuction of the two source
+         * filters.
+         */
         Filter* operator*(Filter *f){
             auto new_name = this->get_name() + "&&" + f->get_name();
             return new Filter(new_name, [this, f](){return this->get_value() && f->get_value();});
         }
 
+        /** Return a new filter that is the disjunction of the two source
+         * filters.
+         */
         Filter* operator+(Filter *f){
             auto new_name = this->get_name() + "||" + f->get_name();
             return new Filter(new_name, [this, f](){return this->get_value() || f->get_value();});
         }
 
+        /** Return a new filter that is the negation of the source filter.
+         */
         Filter* operator!(){
             auto new_name = std::string("!(") + this->get_name() + std::string(")");
             return new Filter(new_name, [this](){return !this->get_value();});
@@ -44,7 +85,7 @@ class RangeFilter : public Filter{
           Filter(name, [test_value, range_low, range_high]{
                   T val = test_value->get_value();
                   return (val >= range_low) && (val < range_high);
-                  }){ }
+                  }) { }
 };
 }
 #endif // filter_h

+ 28 - 13
value.hpp

@@ -59,7 +59,7 @@
  */
 namespace fv{
 
-bool in_register_function = false;
+/* bool in_register_function = false; */
 template<typename> class Function; // undefined
 /**
  * Parent class to all Function classes. Holds a class-level collection of all
@@ -69,6 +69,8 @@ class GenFunction {
     private:
         std::string name;
         std::string impl;
+    protected:
+        inline static bool in_register_function=false;
 
     public:
         /**
@@ -123,7 +125,7 @@ class GenFunction {
             if (GenFunction::function_registry[name] != nullptr){
                 func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
                 if (func == nullptr){
-                    ERROR("Trying to register function which has already been registerd with a different type");
+                    ERROR("Trying to register function which has already been registered with a different type");
                 }
             } else {
                 func = new Function<T>(name, impl, f);
@@ -155,7 +157,7 @@ class Function<R(ArgTypes...)> : public GenFunction {
         Function(const std::string& name, const std::string& impl, std::function<R(ArgTypes...)> f)
           :GenFunction(name, impl), f(f){
             if (!in_register_function) {
-                WARNING("Don't instantiate Function objects directly! Use register_function instead.");
+                WARNING("Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
             }
           }
         Function(const std::string& name, std::function<R(ArgTypes...)> f)
@@ -385,7 +387,6 @@ class DerivedValue : public Value<T>{
  * object containing the array itself as well as another Value object
  * containing the size of that array. Currently, update_value will simply copy
  * the contents of the array into the interally held vector.
- * \todo avoid an unneccessary copy and set the vectors data directly.
  */
 template <typename T>
 class WrapperVector : public DerivedValue<std::vector<T> >{
@@ -396,10 +397,7 @@ class WrapperVector : public DerivedValue<std::vector<T> >{
         void update_value(){
             int n = size->get_value();
             T* data_ref = data->get_value();
-            this->value.resize(n);
-            for (int i=0; i<n; i++){
-                this->value[i] = *(data_ref+i);
-            }
+            this->value.assign(data_ref, data_ref+n);
         }
 
     public:
@@ -532,8 +530,9 @@ template <typename T>
 class Min : public Reduce<T>{
     public:
         Min(const std::string& v_name, const std::string alias="")
-          :Reduce<T>(new Function<T(std::vector<T>)>("min", [](std::vector<T> vec){
-                         return *std::min_element(vec.begin(), vec.end());}),
+          :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
+                      FUNC(([](std::vector<T> vec){
+                         return *std::min_element(vec.begin(), vec.end());}))),
                      v_name, alias) { }
 };
 
@@ -544,10 +543,25 @@ template <typename T>
 class Mean : public Reduce<T>{
     public:
         Mean(const std::string& v_name, const std::string alias="")
-          :Reduce<T>(new Function<T(std::vector<T>)>("mean", [](std::vector<T> vec){
+          :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
+                      FUNC(([](std::vector<T> vec){
                         int n = 0; T sum = 0;
                         for (T e : vec){ n++; sum += e; }
-                        return n>0 ? sum / n : 0; }),
+                        return n>0 ? sum / n : 0; }))),
+                     v_name, alias) { }
+};
+
+/**
+ * Calculate the range of the values in a vector
+ */
+template <typename T>
+class Range : public Reduce<T>{
+    public:
+        Range(const std::string& v_name, const std::string alias="")
+          :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
+                      FUNC(([](std::vector<T> vec){
+                        auto minmax = std::minmax_element(vec.begin(), vec.end());
+                        return (*minmax.second) - (*minmax.first); }))),
                      v_name, alias) { }
 };
 
@@ -558,7 +572,8 @@ template <typename T>
 class ElementOf : public Reduce<T>{
     public:
         ElementOf(Value<int>* index, const std::string& v_name, const std::string alias="")
-          :Reduce<T>(new Function<T(std::vector<T>)>("elementOf", [index](std::vector<T> vec){return vec[index->get_value()];}),
+          :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
+                      FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
                      v_name, alias) { }
         ElementOf(const std::string& name, int index, const std::string& v_name, const std::string alias="")
           :Reduce<T>(name, [index](std::vector<T> vec){return vec[index];}, v_name, alias) { }