LCOV - code coverage report
Current view: top level - frmts/vrt - vrtexpression.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 5 8 62.5 %
Date: 2025-01-18 12:42:00 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  Virtual GDAL Datasets
       4             :  * Purpose:  Implementation of MathExpression
       5             :  * Author:   Daniel Baston
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2024, ISciences LLC
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #pragma once
      14             : 
      15             : #include "cpl_error.h"
      16             : 
      17             : #include <string_view>
      18             : #include <vector>
      19             : 
      20             : namespace gdal
      21             : {
      22             : 
      23             : /**
      24             :  * Class to support evaluation of a mathematical expression
      25             :  */
      26             : class MathExpression
      27             : {
      28             :   public:
      29          19 :     virtual ~MathExpression() = default;
      30             : 
      31             :     /**
      32             :      * Create a MathExpression using a specified dialect.
      33             :      * @param pszExpression The body of the expression, e.g. "X + 3"
      34             :      * @param pszDialect The expression dialect, e.g. "muparser"
      35             :      * @return a MathExpression using the specified dialect, or nullptr on error.
      36             :      */
      37             :     static std::unique_ptr<MathExpression> Create(const char *pszExpression,
      38             :                                                   const char *pszDialect);
      39             : 
      40             :     /**
      41             :     * Register a variable to be used in the expression.
      42             :     *
      43             :     * The value of the variable may be changed during repeated evaluations of
      44             :     * the expression, but its location in memory may not.
      45             :     *
      46             :     * @param osVariable The name of the variable
      47             :     * @param pdfLocation The location of the variable's value
      48             :     *
      49             :     * @since 3.11
      50             :     */
      51             :     virtual void RegisterVariable(std::string_view osVariable,
      52             :                                   double *pdfLocation) = 0;
      53             : 
      54             :     /**
      55             :      * Register a vector to be used in the expression.
      56             :      *
      57             :      * The values and size of the vector may be changed during repeated evaluations
      58             :      * of the expression, but its location in memory may not.
      59             :      *
      60             :      * @param osVariable The name of the vector
      61             :      * @param padfLocation The location of the vector
      62             :      *
      63             :      * @since 3.11
      64             :      */
      65             :     virtual void RegisterVector(std::string_view osVariable,
      66             :                                 std::vector<double> *padfLocation) = 0;
      67             : 
      68             :     /**
      69             :      * Compile the expression.
      70             :      *
      71             :      * If not called explicitly, the expression will be compiled the first time
      72             :      * the expression is evaluated.
      73             :      *
      74             :      * @return CE_None if the expression can be successfully parsed and all
      75             :      *                 symbols have been registe          vrtexpression_exprtk.cpp
      76             :           vrtexpression_muparser.cppred, CE_Failure otherwise.
      77             :      *
      78             :      * @since 3.11
      79             :      */
      80             :     virtual CPLErr Compile() = 0;
      81             : 
      82             :     /**
      83             :      * Evaluate the expression.
      84             :      *
      85             :      * @return CE_None if the expression was successfully evaluated, CE_Failure otherwise.
      86             :      *
      87             :      * @since 3.11
      88             :      */
      89             :     virtual CPLErr Evaluate() = 0;
      90             : 
      91             :     /**
      92             :      * Access the results from the last time the expression was evaluated.
      93             :      *
      94             :      * The returned vector may be reused on subsequent evaluations of the expression.
      95             :      *
      96             :      * @return a reference to the vector in which results are stored.
      97             :      *
      98             :      * @since 3.11
      99             :      */
     100             :     virtual const std::vector<double> &Results() const = 0;
     101             : };
     102             : 
     103             : /*! @cond Doxygen_Suppress */
     104             : 
     105             : #if GDAL_VRT_ENABLE_EXPRTK
     106             : 
     107             : /**
     108             :  * Class to support evaluation of an expression using the exprtk library.
     109             :  */
     110             : class ExprtkExpression : public MathExpression
     111             : {
     112             :   public:
     113             :     explicit ExprtkExpression(std::string_view osExpression);
     114             : 
     115             :     virtual ~ExprtkExpression();
     116             : 
     117             :     void RegisterVariable(std::string_view osVariable,
     118             :                           double *pdfLocation) override;
     119             : 
     120             :     void RegisterVector(std::string_view osVariable,
     121             :                         std::vector<double> *padfLocation) override;
     122             : 
     123             :     CPLErr Compile() override;
     124             : 
     125             :     CPLErr Evaluate() override;
     126             : 
     127             :     const std::vector<double> &Results() const override;
     128             : 
     129             :   private:
     130             :     class Impl;
     131             : 
     132             :     std::unique_ptr<Impl> m_pImpl;
     133             : };
     134             : 
     135             : #endif
     136             : 
     137             : #if GDAL_VRT_ENABLE_MUPARSER
     138             : 
     139             : /**
     140             :  * Class to support evaluation of an expression using the muparser library.
     141             :  */
     142             : class MuParserExpression : public MathExpression
     143             : {
     144             :   public:
     145             :     explicit MuParserExpression(std::string_view osExpression);
     146             : 
     147             :     virtual ~MuParserExpression();
     148             : 
     149             :     void RegisterVariable(std::string_view osVariable,
     150             :                           double *pdfLocation) override;
     151             : 
     152             :     void RegisterVector(std::string_view osVariable,
     153             :                         std::vector<double> *padfLocation) override;
     154             : 
     155             :     CPLErr Compile() override;
     156             : 
     157             :     CPLErr Evaluate() override;
     158             : 
     159             :     const std::vector<double> &Results() const override;
     160             : 
     161             :   private:
     162             :     class Impl;
     163             : 
     164             :     std::unique_ptr<Impl> m_pImpl;
     165             : };
     166             : 
     167             : #endif
     168             : 
     169             : inline std::unique_ptr<MathExpression>
     170          19 : MathExpression::Create([[maybe_unused]] const char *pszExpression,
     171             :                        const char *pszDialect)
     172             : {
     173          19 :     if (EQUAL(pszDialect, "exprtk"))
     174             :     {
     175             : #if GDAL_VRT_ENABLE_EXPRTK
     176             :         return std::make_unique<gdal::ExprtkExpression>(pszExpression);
     177             : #else
     178           0 :         CPLError(CE_Failure, CPLE_IllegalArg,
     179             :                  "Dialect '%s' is not supported by this GDAL build. A GDAL "
     180             :                  "build with ExprTk is be needed.",
     181             :                  pszDialect);
     182             : #endif
     183             :     }
     184          19 :     else if (EQUAL(pszDialect, "muparser"))
     185             :     {
     186             : #if GDAL_VRT_ENABLE_MUPARSER
     187          19 :         return std::make_unique<gdal::MuParserExpression>(pszExpression);
     188             : #else
     189             :         CPLError(CE_Failure, CPLE_IllegalArg,
     190             :                  "Dialect '%s' is not supported by this GDAL build. A GDAL "
     191             :                  "build with muparser is be needed.",
     192             :                  pszDialect);
     193             : #endif
     194             :     }
     195             :     else
     196             :     {
     197           0 :         CPLError(CE_Failure, CPLE_IllegalArg, "Unknown expression dialect: %s",
     198             :                  pszDialect);
     199             :     }
     200           0 :     return nullptr;
     201             : }
     202             : 
     203             : /*! @endcond */
     204             : 
     205             : }  // namespace gdal

Generated by: LCOV version 1.14