C++ Mathematical Expression Library (ExprTk)  https://www.partow.net/programming/exprtk/index.html
diff --git a/exprtk.hpp b/exprtk.hpp
index 8320539..4cce6f4 100644
--- a/exprtk.hpp
+++ b/exprtk.hpp
@@ -3919,6 +3919,81 @@
       };
    }
 
+   template <typename T>
+   class vector_view
+   {
+   public:
+
+      typedef T* data_ptr_t;
+
+      vector_view(data_ptr_t data, const std::size_t& size)
+      : size_(size),
+        data_(data),
+        data_ref_(0)
+      {}
+
+      vector_view(const vector_view<T>& vv)
+      : size_(vv.size_),
+        data_(vv.data_),
+        data_ref_(0)
+      {}
+
+      inline void rebase(data_ptr_t data)
+      {
+         data_ = data;
+
+         if (data_ref_)
+         {
+            (*data_ref_) = data;
+         }
+      }
+
+      inline data_ptr_t data() const
+      {
+         return data_;
+      }
+
+      inline std::size_t size() const
+      {
+         return size_;
+      }
+
+      inline const T& operator[](const std::size_t index) const
+      {
+         return data_[index];
+      }
+
+      inline T& operator[](const std::size_t index)
+      {
+         return data_[index];
+      }
+
+      void set_ref(data_ptr_t* data_ref)
+      {
+         data_ref_ = data_ref;
+      }
+
+   private:
+
+      std::size_t size_;
+      data_ptr_t  data_;
+      data_ptr_t* data_ref_;
+   };
+
+   template <typename T>
+   inline vector_view<T> make_vector_view(T* data,
+                                          const std::size_t size, const std::size_t offset = 0)
+   {
+      return vector_view<T>(data + offset,size);
+   }
+
+   template <typename T>
+   inline vector_view<T> make_vector_view(std::vector<T>& v,
+                                          const std::size_t size, const std::size_t offset = 0)
+   {
+      return vector_view<T>(v.data() + offset,size);
+   }
+
    template <typename T> class results_context;
 
    template <typename T>
@@ -4442,6 +4517,11 @@
             return control_block_->size;
          }
 
+         inline data_t& ref()
+         {
+            return control_block_->data;
+         }
+
          inline void dump() const
          {
             #ifdef exprtk_enable_debugging
@@ -4983,6 +5063,8 @@
                return value_at(0);
             }
 
+            virtual void set_ref(value_ptr*) {}
+
          protected:
 
             virtual value_ptr value_at(const std::size_t&) const = 0;
@@ -5052,6 +5134,40 @@
             sequence_t& sequence_;
          };
 
+         class vector_view_impl : public vector_holder_base
+         {
+         public:
+
+            typedef exprtk::vector_view<Type> vector_view_t;
+
+            vector_view_impl(vector_view_t& vec_view)
+            : vec_view_(vec_view)
+            {}
+
+            void set_ref(value_ptr* ref)
+            {
+               vec_view_.set_ref(ref);
+            }
+
+         protected:
+
+            value_ptr value_at(const std::size_t& index) const
+            {
+               return (index < vec_view_.size()) ? (&vec_view_[index]) : const_value_ptr(0);
+            }
+
+            std::size_t vector_size() const
+            {
+               return vec_view_.size();
+            }
+
+         private:
+
+            vector_view_impl operator=(const vector_view_impl&);
+
+            vector_view_t& vec_view_;
+         };
+
       public:
 
          typedef typename details::vec_data_store<Type> vds_t;
@@ -5069,6 +5185,10 @@
          : vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::vector>(vec))
          {}
 
+         vector_holder(exprtk::vector_view<Type>& vec)
+         : vector_holder_base_(new(buffer)vector_view_impl(vec))
+         {}
+
          inline value_ptr operator[](const std::size_t& index) const
          {
             return (*vector_holder_base_)[index];
@@ -5084,6 +5204,11 @@
             return vector_holder_base_->data();
          }
 
+         void set_ref(value_ptr* ref)
+         {
+            return vector_holder_base_->set_ref(ref);
+         }
+
       private:
 
          mutable vector_holder_base* vector_holder_base_;
@@ -6666,7 +6791,9 @@
          vector_node(vector_holder_t* vh)
          : vector_holder_(vh),
            vds_((*vector_holder_).size(),(*vector_holder_)[0])
-         {}
+         {
+            vector_holder_->set_ref(&vds_.ref());
+         }
 
          vector_node(const vds_t& vds, vector_holder_t* vh)
          : vector_holder_(vh),
@@ -15382,6 +15509,14 @@
             }
          };
 
+         struct tie_vecview
+         {
+            static inline std::pair<bool,vector_t*> make(exprtk::vector_view<T>& v, const bool is_const = false)
+            {
+               return std::make_pair(is_const,new vector_t(v));
+            }
+         };
+
          struct tie_stddeq
          {
             template <typename Allocator>
@@ -15408,6 +15543,11 @@
             return add_impl<tie_stdvec,std::vector<T,Allocator>&>(symbol_name,v,is_const);
          }
 
+         inline bool add(const std::string& symbol_name, exprtk::vector_view<T>& v, const bool is_const = false)
+         {
+            return add_impl<tie_vecview,exprtk::vector_view<T>&>(symbol_name,v,is_const);
+         }
+
          template <typename Allocator>
          inline bool add(const std::string& symbol_name, std::deque<T,Allocator>& v, const bool is_const = false)
          {
@@ -16268,6 +16408,18 @@
             return local_data().vector_store.add(vector_name,v);
       }
 
+      inline bool add_vector(const std::string& vector_name, exprtk::vector_view<T>& v)
+      {
+         if (!valid())
+            return false;
+         else if (!valid_symbol(vector_name))
+            return false;
+         else if (symbol_exists(vector_name))
+            return false;
+         else
+            return local_data().vector_store.add(vector_name,v);
+      }
+
       inline bool remove_variable(const std::string& variable_name, const bool delete_node = true)
       {
          if (!valid())
diff --git a/exprtk_test.cpp b/exprtk_test.cpp
index 10dba03..b2c1d74 100644
--- a/exprtk_test.cpp
+++ b/exprtk_test.cpp
@@ -1796,6 +1796,7 @@
       for (std::size_t r = 0; r < rounds; ++r)
       {
          bool loop_result = true;
+
          for (std::size_t i = 0; i < expr_list_size; ++i)
          {
             T v[]     = { T(0.0), T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) };
@@ -1838,6 +1839,66 @@
                       expr_list[i].c_str(),
                       (double)1.0,
                       (double)result);
+
+               loop_result = false;
+            }
+         }
+
+         if (!loop_result)
+         {
+            return false;
+         }
+      }
+
+      for (std::size_t r = 0; r < rounds; ++r)
+      {
+         bool loop_result = true;
+
+         for (std::size_t i = 0; i < expr_list_size; ++i)
+         {
+            T v_[]     = { T(0.0), T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) };
+            T index_[] = { T(0)  , T(1)  , T(2)  , T(3)  , T(4)  , T(5)   };
+
+            T x = T(6.6);
+            T y = T(7.7);
+            T z = T(8.8);
+
+            exprtk::vector_view<T> v     = exprtk::make_vector_view(v_    ,6);
+            exprtk::vector_view<T> index = exprtk::make_vector_view(index_,6);
+
+            exprtk::symbol_table<T> symbol_table;
+            symbol_table.add_variable("x",x);
+            symbol_table.add_variable("y",y);
+            symbol_table.add_variable("z",z);
+            symbol_table.add_vector  ("v",v);
+            symbol_table.add_vector  ("i",index);
+
+            exprtk::expression<T> expression;
+            expression.register_symbol_table(symbol_table);
+
+            {
+               exprtk::parser<T> parser;
+
+               if (!parser.compile(expr_list[i],expression))
+               {
+                  printf("run_test01() - Error: %s   Expression: %s\n",
+                         parser.error().c_str(),
+                         expr_list[i].c_str());
+
+                  loop_result = false;
+
+                  continue;
+               }
+            }
+
+            T result = expression.value();
+
+            if (not_equal(result,T(1)))
+            {
+               printf("run_test01() - Computation Error:  Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n",
+                      expr_list[i].c_str(),
+                      (double)1.0,
+                      (double)result);
                loop_result = false;
             }
          }
@@ -6125,6 +6186,84 @@
          return false;
    }
 
+   {
+      bool failure = false;
+
+      typedef exprtk::symbol_table<T> symbol_table_t;
+      typedef exprtk::expression<T>     expression_t;
+      typedef exprtk::parser<T>             parser_t;
+
+      std::vector<T> v0 { 0, 0, 0, 0, 0,  0,  0 };
+      std::vector<T> v1 { 0, 2, 4, 6, 8, 10, 12 };
+      std::vector<T> v2 { 1, 3, 5, 7, 9, 11, 13 };
+      std::vector<T> v3 { 0, 1, 2, 3, 4,  5,  6 };
+
+      const std::string expr_string = "sum(v + 1)";
+
+      exprtk::vector_view<T> v = exprtk::make_vector_view(v0,v0.size());
+
+      symbol_table_t symbol_table;
+      symbol_table.add_vector("v",v);
+
+      expression_t expression;
+      expression.register_symbol_table(symbol_table);
+
+      parser_t parser;
+
+      if (!parser.compile(expr_string,expression))
+      {
+         printf("run_test18() - Error: %s\tExpression: %s\n",
+                parser.error().c_str(),
+                expr_string.c_str());
+
+         failure = true;
+      }
+
+      T sum = { T(0) };
+
+      sum = expression.value();
+
+      if (not_equal(sum,T(7)))
+      {
+         printf("run_test18() - Error in evaluation! (6) Expression: %s\n",
+                expr_string.c_str());
+         failure = true;
+      }
+
+      v.rebase(v1.data());
+      sum = expression.value();
+
+      if (not_equal(sum,T(49)))
+      {
+         printf("run_test18() - Error in evaluation! (7) Expression: %s\n",
+                expr_string.c_str());
+         failure = true;
+      }
+
+      v.rebase(v2.data());
+      sum = expression.value();
+
+      if (not_equal(sum,T(56)))
+      {
+         printf("run_test18() - Error in evaluation! (8) Expression: %s\n",
+                expr_string.c_str());
+         failure = true;
+      }
+
+      v.rebase(v3.data());
+      sum = expression.value();
+
+      if (not_equal(sum,T(28)))
+      {
+         printf("run_test18() - Error in evaluation! (9) Expression: %s\n",
+                expr_string.c_str());
+         failure = true;
+      }
+
+      if (failure)
+         return false;
+   }
+
    return true;
 }