diff options
Diffstat (limited to 'src/include/usr/targeting/predicates')
-rw-r--r-- | src/include/usr/targeting/predicates/predicatebase.H | 111 | ||||
-rw-r--r-- | src/include/usr/targeting/predicates/predicatectm.H | 118 | ||||
-rw-r--r-- | src/include/usr/targeting/predicates/predicatepostfixexpr.H | 204 |
3 files changed, 433 insertions, 0 deletions
diff --git a/src/include/usr/targeting/predicates/predicatebase.H b/src/include/usr/targeting/predicates/predicatebase.H new file mode 100644 index 000000000..e555092b9 --- /dev/null +++ b/src/include/usr/targeting/predicates/predicatebase.H @@ -0,0 +1,111 @@ + +#ifndef TARG_PREDICATEBASE_H +#define TARG_PREDICATEBASE_H + +/** + * @file predicatebase.H + * + * @brief Interface for an abstract targeting predicate which filters a set of + * targets based on the programmed criteria. Concrete predicates must + * provide the interface specified here. + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD + +// Other Host Boot Components + +// Targeting Component + +//****************************************************************************** +// Macros +//****************************************************************************** + +/** + * @brief Disable copy constructor / assignment operators + */ +#undef TARG_DISABLE_COPY_AND_ASSIGNMENT_OPERATORS +#define TARG_DISABLE_COPY_AND_ASSIGNMENT_OPERATORS(Type) \ + Type(const Type& i_other); \ + Type& operator=(const Type& i_other) + +/** + * @brief Ensure trace macros are undefined + */ +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FN + +//****************************************************************************** +// Interface +//****************************************************************************** + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "PredicateBase::" + +class Target; + +/** + * @brief Abstract predicate class which specifies an interface for all + * concrete predicates. A predicate acts as a filter on a set of targets. + */ +class PredicateBase +{ + public: + + /** + * @brief Destroys the predicate base class (nothing to do) + */ + virtual ~PredicateBase(); + + /** + * @brief Predicate function call interface + * + * @par Detailed Description: + * This abstract interface must be declared/implemented by all + * derived predicates. A concrete version of this function accepts + * a target, applies the associated predicate logic, and returns + * whether the target met the predicate criteria or not. Caller + * must always supply a valid Target*, or routine will assert. + * + * @param[in] i_pTarget Pointer to target to apply predicate to + * + * @return Boolean indicating whether target matches criteria specified + * by the concrete predicate + * + * @retval true Target matches the predicate criteria + * @retval false Target does not match the predicate criteria + */ + virtual bool operator()( + const Target* i_pTarget) const = 0; + + protected: + + /** + * @brief Create the predicate base class (nothing to do) + * + * @note Constructor protected to allow access from the derived class + */ + PredicateBase() + { + #define TARG_FN "PredicateBase()" + #undef TARG_FN + } + + private: + + TARG_DISABLE_COPY_AND_ASSIGNMENT_OPERATORS(PredicateBase); +}; + +#undef TARG_CLASS +#undef TARG_NAMESPACE + +} // End namespace TARGETING + +#endif // TARG_PREDICATEBASE_H diff --git a/src/include/usr/targeting/predicates/predicatectm.H b/src/include/usr/targeting/predicates/predicatectm.H new file mode 100644 index 000000000..760f0d02d --- /dev/null +++ b/src/include/usr/targeting/predicates/predicatectm.H @@ -0,0 +1,118 @@ + +#ifndef TARG_PREDICATECTM_H +#define TARG_PREDICATECTM_H + +/** + * @file predicatectm.H + * + * @brief Interface for a predicate which fiters a target based on its class, + * type, and model. + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD + +// Other Host Boot Components + +// Targeting Component +#include <targeting/target.H> +#include <targeting/attributeenums.H> +#include <targeting/predicates/predicatebase.H> + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FN + +//****************************************************************************** +// Interface +//****************************************************************************** + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "PredicateCTM::" + +class Target; + +/** + * @brief Predicate class which filters a target based on its class, type, + * and model + */ +class PredicateCTM : public PredicateBase +{ + public: + + /** + * @brief Create a target class, type, model predicate + * + * @param[in] i_class Class of matching target, default NA (any) + * @param[in] i_type Type of matching target, default NA (any) + * @param[in] i_model Model of matching target, default NA (any) + */ + PredicateCTM( + CLASS i_class = CLASS_NA, + TYPE i_type = TYPE_NA, + MODEL i_model = MODEL_NA); + + /** + * @brief Destroy a class, type, model predicate + */ + virtual ~PredicateCTM() + { + #define TARG_FUNC "~PredicateCTM()" + #undef TARG_FUNC + } + + /** + * @brief Returns whether target matches the specified class, type, + * model + * + * @par Detailed Description: + * Returns whether target matches the specified class, type, model. + * Note that all three fields are always compared, so wildcards + * (CLASS_NA, TYPE_NA, MODEL_NA) must be used for any fields that + * do not matter. See PredicateBase class for parameter/return + * description. + */ + virtual bool operator()( + const Target* i_pTarget) const; + + private: + + CLASS iv_class; ///< Class to compare with that of target + TYPE iv_type; ///< Type to compare with that of target + MODEL iv_model; ///< Model to compare with that of target + + TARG_DISABLE_COPY_AND_ASSIGNMENT_OPERATORS(PredicateCTM); +}; + +//****************************************************************************** +// PredicateCTM::PredicateCTM +//****************************************************************************** + +inline PredicateCTM::PredicateCTM( + const CLASS i_class, + const TYPE i_type, + const MODEL i_model) +: iv_class(i_class), + iv_type(i_type), + iv_model(i_model) +{ + #define TARG_FUNC "PredicateCTM(...)" + #undef TARG_FUNC +} + +#undef TARG_CLASS +#undef TARG_NAMESPACE + +} // End namespace TARGETING + +#endif // TARG_PREDICATECTM_H diff --git a/src/include/usr/targeting/predicates/predicatepostfixexpr.H b/src/include/usr/targeting/predicates/predicatepostfixexpr.H new file mode 100644 index 000000000..12388fc46 --- /dev/null +++ b/src/include/usr/targeting/predicates/predicatepostfixexpr.H @@ -0,0 +1,204 @@ + +#ifndef TARG_PREDICATEPOSTFIXEXPR_H +#define TARG_PREDICATEPOSTFIXEXPR_H + +/** + * @file predicatepostfixexpr.H + * + * @brief Interface for predicate which allows callers to chain multiple other + * predicates together in complex logical expressions, and then evaluate + * them against a target + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <vector> + +// Other Host Boot Components + +// Targeting Component +#include <targeting/predicates/predicatebase.H> + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FN + +//****************************************************************************** +// Interface +//****************************************************************************** + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "PredicatePostfixExpr::" + +class Target; + +/** + * @brief Predicate which can compute aribtrarily complex logical expressions + * of other predicates using postfix notation + */ +class PredicatePostfixExpr : public PredicateBase +{ + public: + + /** + * @brief Create empty postfix predicate expression which will always + * evaluate true if not otherwise modified. Any updates to the + * expression completely replace the initial "always true" + * behavior. + */ + PredicatePostfixExpr(); + + /** + * @brief Destroy a postfix predicate expression + * + * @note: Nothing extra to do here since object does not own the + * predicates + */ + virtual ~PredicatePostfixExpr(); + + /** + * @brief Updates the postfix predicate expression by pushing the given + * predicate onto the expression stack + * + * @param[in] i_pPredicate Pointer to existing concrete predicate. + * Passing a NULL predicate is not allowed (results in assert) + * + * @verbatim + * Example: + * + * Stack before calling push(&P2): P1 + * Stack after calling push(&P2): P1 P2 + * @endverbatim + * + * @return Reference to the same predicate expression, for chaining + */ + PredicatePostfixExpr& push( + const PredicateBase* i_pPredicate); + + /** + * @brief Updates the postfix predicate expression by pushing the + * logical "AND" operation onto the expression stack. + * + * @verbatim + * Example: + * + * Stack before calling And(): P1 P2 + * Stack after calling And(): P1 P2 AND + * Stack after evaluation: (P1 && P2) + * @endverbatim + * + * @return Reference to the same predicate expression, for chaining + */ + PredicatePostfixExpr& And(); + + /** + * @brief Updates the postfix predicate expression by pushing the + * logical "NOT" operation onto the expression stack. + * + * @verbatim + * Example: + * + * Stack before calling Not(): P1 + * Stack after calling Not(): P1 NOT + * Stack after evaluation: (!P1) + * @endverbatim + * + * @return Reference to the same predicate expression, for chaining + */ + PredicatePostfixExpr& Not(); + + /** + * @brief Updates the postfix predicate expression by pushing the + * logical "OR" operation onto the expression stack. + * + * @verbatim + * Example: + * + * Stack before calling Or(): P1 P2 + * Stack after calling Or(): P1 P2 OR + * Stack after evaluation: (P1 || P2) + * @endverbatim + * + * @return Reference to the same predicate expression for chaining + */ + PredicatePostfixExpr& Or(); + + /** + * @brief Returns whether the given target matches the criteria + * specified by the postfix predicate expression + * + * @par Detailed Description: + * Returns whether the given target matches the criteria + * specified by the postfix predicate expression. The routine + * sequentially evaluates a predicate against the supplied target + * or applies a logical operation to one or more prior predicate + * evaluations using a postfix algorithm. Routine will assert + * if postfix expression is not formatted properly, final result + * stack does not have exactly one result, target is NULL, or + * invalid logical operator was requested. See PredicateBase class + * for parameter/return description. + * + * @verbatim + * Example: + * + * PredicatePostfixExpr l_expr; + * l_expr.push(&P1).push(&P2).Or().push(&P3).And().Not(); + * + * Equivalent infix expression: !((P1 || P2) && P3) + * Assume predicate results of: P1 = 0, P2 = 1, P3 = 0 + * Expression stack prior to evaluation: P1 P2 OR P3 AND NOT + * Evaluation step 1: 1 P3 AND NOT (evaluated P1 P2 OR) + * Evaluation step 2: 0 NOT (evaluated 1 P3 AND) + * Evaluation step 3: 1 (evaluated 0 NOT; final result) + * @endverbatim + */ + virtual bool operator()( + const Target* i_pTarget) const; + + private: + + /** + * @brief Enumeration describing the type of logical operator to + * apply to one or more previous predicate evaluations + */ + enum LogicalOperator + { + EVAL, ///< Special logical operator - evaluate a predicate + AND, ///< Logically AND the result of the preceding two evaluations + OR, ///< Logically OR the result of the preceding two evaluations + NOT, ///< Logically negate the result of the preceding evaluation + }; + + /** + * @brief Structure describing one unit of the postfix predicate + * expression under evaluation + */ + struct Operation + { + LogicalOperator logicalOp; ///< Logical operator to + ///< apply to result stack + const PredicateBase* const pPredicate; ///< Predicate to evaluate, + ///< if logicalOp == EVAL + }; + + std::vector<Operation> iv_ops; ///< Expression operations to perform + + TARG_DISABLE_COPY_AND_ASSIGNMENT_OPERATORS(PredicatePostfixExpr); +}; + +#undef TARG_CLASS +#undef TARG_NAMESPACE + +} // End namespace TARGETING + +#endif // TARG_PREDICATEPOSTFIXEXPR_H |