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-03-29 15:49:56 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          78 :     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 registered, CE_Failure otherwise.
      76             :      *
      77             :      * @since 3.11
      78             :      */
      79             :     virtual CPLErr Compile() = 0;
      80             : 
      81             :     /**
      82             :      * Evaluate the expression.
      83             :      *
      84             :      * @return CE_None if the expression was successfully evaluated, CE_Failure otherwise.
      85             :      *
      86             :      * @since 3.11
      87             :      */
      88             :     virtual CPLErr Evaluate() = 0;
      89             : 
      90             :     /**
      91             :      * Access the results from the last time the expression was evaluated.
      92             :      *
      93             :      * The returned vector may be reused on subsequent evaluations of the expression.
      94             :      *
      95             :      * @return a reference to the vector in which results are stored.
      96             :      *
      97             :      * @since 3.11
      98             :      */
      99             :     virtual const std::vector<double> &Results() const = 0;
     100             : };
     101             : 
     102             : /*! @cond Doxygen_Suppress */
     103             : 
     104             : #if GDAL_VRT_ENABLE_EXPRTK
     105             : 
     106             : /**
     107             :  * Class to support evaluation of an expression using the exprtk library.
     108             :  */
     109             : class ExprtkExpression : public MathExpression
     110             : {
     111             :   public:
     112             :     explicit ExprtkExpression(std::string_view osExpression);
     113             : 
     114             :     virtual ~ExprtkExpression();
     115             : 
     116             :     void RegisterVariable(std::string_view osVariable,
     117             :                           double *pdfLocation) override;
     118             : 
     119             :     void RegisterVector(std::string_view osVariable,
     120             :                         std::vector<double> *padfLocation) override;
     121             : 
     122             :     CPLErr Compile() override;
     123             : 
     124             :     CPLErr Evaluate() override;
     125             : 
     126             :     const std::vector<double> &Results() const override;
     127             : 
     128             :   private:
     129             :     class Impl;
     130             : 
     131             :     std::unique_ptr<Impl> m_pImpl;
     132             : };
     133             : 
     134             : #endif
     135             : 
     136             : #if GDAL_VRT_ENABLE_MUPARSER
     137             : 
     138             : /**
     139             :  * Class to support evaluation of an expression using the muparser library.
     140             :  */
     141             : class MuParserExpression : public MathExpression
     142             : {
     143             :   public:
     144             :     explicit MuParserExpression(std::string_view osExpression);
     145             : 
     146             :     virtual ~MuParserExpression();
     147             : 
     148             :     void RegisterVariable(std::string_view osVariable,
     149             :                           double *pdfLocation) override;
     150             : 
     151             :     void RegisterVector(std::string_view osVariable,
     152             :                         std::vector<double> *padfLocation) override;
     153             : 
     154             :     CPLErr Compile() override;
     155             : 
     156             :     CPLErr Evaluate() override;
     157             : 
     158             :     const std::vector<double> &Results() const override;
     159             : 
     160             :   private:
     161             :     class Impl;
     162             : 
     163             :     std::unique_ptr<Impl> m_pImpl;
     164             : };
     165             : 
     166             : #endif
     167             : 
     168             : inline std::unique_ptr<MathExpression>
     169          78 : MathExpression::Create([[maybe_unused]] const char *pszExpression,
     170             :                        const char *pszDialect)
     171             : {
     172          78 :     if (EQUAL(pszDialect, "exprtk"))
     173             :     {
     174             : #if GDAL_VRT_ENABLE_EXPRTK
     175             :         return std::make_unique<gdal::ExprtkExpression>(pszExpression);
     176             : #else
     177           0 :         CPLError(CE_Failure, CPLE_IllegalArg,
     178             :                  "Dialect '%s' is not supported by this GDAL build. A GDAL "
     179             :                  "build with ExprTk is be needed.",
     180             :                  pszDialect);
     181             : #endif
     182             :     }
     183          78 :     else if (EQUAL(pszDialect, "muparser"))
     184             :     {
     185             : #if GDAL_VRT_ENABLE_MUPARSER
     186          78 :         return std::make_unique<gdal::MuParserExpression>(pszExpression);
     187             : #else
     188             :         CPLError(CE_Failure, CPLE_IllegalArg,
     189             :                  "Dialect '%s' is not supported by this GDAL build. A GDAL "
     190             :                  "build with muparser is be needed.",
     191             :                  pszDialect);
     192             : #endif
     193             :     }
     194             :     else
     195             :     {
     196           0 :         CPLError(CE_Failure, CPLE_IllegalArg, "Unknown expression dialect: %s",
     197             :                  pszDialect);
     198             :     }
     199           0 :     return nullptr;
     200             : }
     201             : 
     202             : /*! @endcond */
     203             : 
     204             : }  // namespace gdal

Generated by: LCOV version 1.14