summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorNick Bofferding <bofferdn@us.ibm.com>2011-08-16 12:40:36 -0500
committerNicholas E. Bofferding <bofferdn@us.ibm.com>2011-08-23 14:10:24 -0500
commit213b45cd7d8b0367f85ee68b79941f6d548c1e9c (patch)
tree8f78e3999420f6b1b2ca00ccb79f88cf54441d5c /src/include
parent91b39e52483cc5a8cc1cb7c7d15c281a150d9572 (diff)
downloadtalos-hostboot-213b45cd7d8b0367f85ee68b79941f6d548c1e9c.tar.gz
talos-hostboot-213b45cd7d8b0367f85ee68b79941f6d548c1e9c.zip
Add target iterator and predicate support
Change-Id: I728bb312277591d81c0575e74878fba9f816b962 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/260 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com> Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com>
Diffstat (limited to 'src/include')
-rw-r--r--src/include/usr/targeting/attributeenums.H1
-rw-r--r--src/include/usr/targeting/iterators/rangefilter.H323
-rw-r--r--src/include/usr/targeting/iterators/targetiterator.H257
-rw-r--r--src/include/usr/targeting/predicates/predicatebase.H111
-rw-r--r--src/include/usr/targeting/predicates/predicatectm.H118
-rw-r--r--src/include/usr/targeting/predicates/predicatepostfixexpr.H204
-rw-r--r--src/include/usr/targeting/targetservice.H95
7 files changed, 1093 insertions, 16 deletions
diff --git a/src/include/usr/targeting/attributeenums.H b/src/include/usr/targeting/attributeenums.H
index c4cd5c28a..6d7eed93d 100644
--- a/src/include/usr/targeting/attributeenums.H
+++ b/src/include/usr/targeting/attributeenums.H
@@ -34,6 +34,7 @@ namespace TARGETING
*/
enum ATTRIBUTE_ID
{
+ ATTR_NA = 0x00,
ATTR_CLASS = 0x01,
ATTR_TYPE = 0x02,
ATTR_MODEL = 0x03,
diff --git a/src/include/usr/targeting/iterators/rangefilter.H b/src/include/usr/targeting/iterators/rangefilter.H
new file mode 100644
index 000000000..b582cb0b6
--- /dev/null
+++ b/src/include/usr/targeting/iterators/rangefilter.H
@@ -0,0 +1,323 @@
+
+#ifndef TARG_RANGEFILTER_H
+#define TARG_RANGEFILTER_H
+
+/**
+ * @file rangefilter.H
+ *
+ * @brief Interface describing an object which takes an iterator range and
+ * allows caller to iterate through the elements which match a supplied
+ * predicate (filter)
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+
+// Other Host Boot Components
+
+// Targeting Component
+#include <targeting/target.H>
+#include <targeting/predicates/predicatebase.H>
+#include <targeting/iterators/targetiterator.H>
+
+//******************************************************************************
+// Macros
+//******************************************************************************
+
+#undef TARG_NAMESPACE
+#undef TARG_CLASS
+#undef TARG_FUNC
+
+//******************************************************************************
+// Interface
+//******************************************************************************
+
+namespace TARGETING
+{
+
+#define TARG_NAMESPACE "TARGETING::"
+
+#define TARG_CLASS "RangeFilter<IteratorType>::"
+
+/**
+ * @brief Templated class which which takes an iterator range of arbitrary type
+ * and allows caller to iterate through the elements which match a supplied
+ * predicate (filter)
+ */
+template<typename IteratorType>
+class RangeFilter
+{
+ public:
+
+ /**
+ * @var Forward the type of iterated elements to help build the
+ * class generically
+ */
+ typedef typename IteratorType::value_type value_type;
+
+ /**
+ * @var fake_bool is a pointer to a member function of RangeFilter
+ * which takes no arguments and returns void.
+ * Used to implement ability to check if range iterator is valid
+ */
+ typedef void (RangeFilter::*fake_bool)() const;
+
+ /**
+ * @brief Create a range object and locate first item in the range that
+ * matches the predicate (or the first if no predicate)
+ *
+ * @param[in] i_begin Iterator pointing to first item in range
+ * @param[in] i_end Iterator pointing to last item in range
+ * @param[in] i_pPredicate Predicate evaluated against each pointed to
+ * item
+ *
+ * @note Begin iterator must point to element prior to end iterator,
+ * otherwise result is undefined
+ */
+ RangeFilter(
+ const IteratorType& i_begin,
+ const IteratorType& i_end,
+ const PredicateBase* i_pPredicate = NULL);
+
+ /**
+ * @brief Destroy a range object (nothing to do)
+ */
+ ~RangeFilter()
+ {
+ }
+
+ /**
+ * @brief Dummy function used to implement ability to check if range
+ * iterator is valid
+ */
+ operator fake_bool() const
+ {
+ return (iv_current != iv_end)
+ ? &RangeFilter::notComparable : NULL;
+ }
+
+ /**
+ * @brief Pre-increment operator which advances the range's iterator
+ * to point to the next valid element
+ *
+ * @return Reference to this range filter
+ */
+ RangeFilter& operator++();
+
+ /**
+ * @brief Dereference the range filter, returning the element pointed
+ *
+ * @return The element pointed to by the range filter
+ */
+ value_type operator*() const
+ {
+ return *iv_current;
+ }
+
+ /**
+ * @brief Dereference the range filter, returning the element pointed
+ * for use by the dereference and call member operator
+ *
+ * @return The element pointed to by the range filter
+ */
+ value_type operator->() const
+ {
+ return *iv_current;
+ }
+
+ /**
+ * @brief Reset the range's internal iterator to point to the first
+ * item in the range that matches the predicate (or the first if no
+ * predicate)
+ */
+ void reset();
+
+ /**
+ * @brief Set the range's predicate filter
+ *
+ * @param[in] i_pPredicate Predicate to evaluate against elements
+ * pointed to by the range
+ */
+ void setPredicate(
+ const PredicateBase* i_pPredicate);
+
+ /**
+ * @brief Assignment operator; assign one range filter to another
+ *
+ * @param[in] i_rhs Range filter to assign
+ */
+ RangeFilter& operator=(
+ const RangeFilter& i_rhs);
+
+ /**
+ * @brief Copy constructor; create range filter using another range
+ * filter as a prototype for it
+ *
+ * @param[in] i_rhs Range filter to assign on create
+ */
+ RangeFilter(
+ const RangeFilter& i_rhs);
+
+ private:
+
+ /**
+ * @brief Update internal cursor to point to the next element of the
+ * underlying range
+ *
+ * @note If the internal cursor is at the end of the range, then do
+ * nothing
+ */
+ void advance();
+
+ /**
+ * @brief Update internal cursor to point to the next element of the
+ * underlying range only if not past the end of the range and the
+ * predicate doesn't match the current item
+ *
+ * @note If the internal cursor is at the end of the range, then do
+ * nothing
+ */
+ void advanceIfNoMatch();
+
+ /**
+ * @brief Dummy function used to implement ability to check if range
+ * iterator is valid
+ */
+ void notComparable() const
+ {
+ }
+
+ IteratorType iv_current; ///< Iterator pointing to the
+ ///< current element
+ IteratorType iv_begin; ///< Iterator pointing to first
+ ///< element in range
+ IteratorType iv_end; ///< Iterator to past the end
+ ///< element in range
+ const PredicateBase* iv_pPredicate; ///< Range filter
+};
+
+typedef RangeFilter<TargetIterator> TargetRangeFilter;
+typedef RangeFilter<ConstTargetIterator> ConstTargetRangeFilter;
+
+//******************************************************************************
+// RangeFilter::RangeFilter
+//******************************************************************************
+
+template<typename IteratorType>
+RangeFilter<IteratorType>::RangeFilter(
+ const IteratorType& i_begin,
+ const IteratorType& i_end,
+ const PredicateBase* const i_pPredicate)
+: iv_current(i_begin),
+ iv_begin(i_begin),
+ iv_end(i_end),
+ iv_pPredicate(i_pPredicate)
+{
+ advanceIfNoMatch();
+}
+
+//******************************************************************************
+// RangeFilter::operator=
+//******************************************************************************
+
+template<typename IteratorType>
+RangeFilter<IteratorType>& RangeFilter<IteratorType>::operator=(
+ const RangeFilter& i_rhs)
+{
+ iv_current = i_rhs.iv_current;
+ iv_begin = i_rhs.iv_begin;
+ iv_end = i_rhs.iv_end;
+ iv_pPredicate = i_rhs.iv_pPredicate;
+}
+
+//******************************************************************************
+// RangeFilter::RangeFilter (copy constructor)
+//******************************************************************************
+
+template<typename IteratorType>
+RangeFilter<IteratorType>::RangeFilter(
+ const RangeFilter& i_rhs)
+: iv_current(i_rhs.iv_current),
+ iv_begin(i_rhs.iv_begin),
+ iv_end(i_rhs.iv_end),
+ iv_pPredicate(i_rhs.iv_pPredicate)
+{
+}
+
+//******************************************************************************
+// RangeFilter::setPredicate
+//******************************************************************************
+
+template<typename IteratorType>
+void RangeFilter<IteratorType>::setPredicate(
+ const PredicateBase* const i_pPredicate)
+{
+ iv_pPredicate = i_pPredicate;
+ advanceIfNoMatch();
+}
+
+//******************************************************************************
+// RangeFilter::reset
+//******************************************************************************
+
+template<typename IteratorType>
+void RangeFilter<IteratorType>::reset()
+{
+ iv_current = iv_begin;
+ advanceIfNoMatch();
+}
+
+//******************************************************************************
+// RangeFilter::operator++
+//******************************************************************************
+
+template<typename IteratorType>
+RangeFilter<IteratorType>& RangeFilter<IteratorType>::operator++()
+{
+ advance();
+ return *this;
+}
+
+/**
+ * @brief Disable meaningless "bool" comparisons that can occur when
+ * evaluating a range as a bool by forcing a compilation failure.
+ * Function interfaces not documented since they are not used.
+ */
+template <typename T>
+bool operator!=(const TargetRangeFilter& i_lhs, const T& i_rhs)
+{
+ i_lhs.notComparable();
+ return false;
+}
+
+template <typename T>
+bool operator==(const TargetRangeFilter& i_lhs, const T& i_rhs)
+{
+ i_lhs.notComparable();
+ return false;
+}
+
+template <typename T>
+bool operator!=(const ConstTargetRangeFilter& i_lhs, const T& i_rhs)
+{
+ i_lhs.notComparable();
+ return false;
+}
+
+template <typename T>
+bool operator==(const ConstTargetRangeFilter& i_lhs, const T& i_rhs)
+{
+ i_lhs.notComparable();
+ return false;
+}
+
+#undef TARG_CLASS
+#undef TARG_NAMESPACE
+
+} // End namespace TARGETING
+
+#endif
+
diff --git a/src/include/usr/targeting/iterators/targetiterator.H b/src/include/usr/targeting/iterators/targetiterator.H
new file mode 100644
index 000000000..6f250cbb5
--- /dev/null
+++ b/src/include/usr/targeting/iterators/targetiterator.H
@@ -0,0 +1,257 @@
+
+#ifndef TARG_TARGETITERATOR_H
+#define TARG_TARGETITERATOR_H
+
+/**
+ * @file targetiterator.H
+ *
+ * @brief Interface describing iterator/const iterator used to iterate through
+ * target service targets
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+#include <stddef.h>
+
+// Other Host Boot Components
+#include <builtins.h>
+
+// Targeting Component
+
+//******************************************************************************
+// Macros
+//******************************************************************************
+
+#undef TARG_NAMESPACE
+#undef TARG_CLASS
+#undef TARG_FUNC
+
+//******************************************************************************
+// Interface
+//******************************************************************************
+
+namespace TARGETING
+{
+
+#define TARG_NAMESPACE "TARGETING::"
+
+#define TARG_CLASS "_TargetIterator<T>::"
+
+class Target;
+
+/**
+ * @brief Class which iterates through targets managed by the target service.
+ * Provides "Target*" and "const Target*" versions via templates
+ */
+template<typename T>
+class _TargetIterator
+{
+ public:
+
+ /**
+ * @brief Maps type of iterated element to common alias (Target* or
+ * const Target*)
+ */
+ typedef T iterator;
+ typedef T value_type;
+
+ /**
+ * @brief Create an iterator to a (const/non-const) target handle.
+ * Defaults to end()
+ */
+ ALWAYS_INLINE
+ _TargetIterator()
+ : iv_pCurrent(NULL)
+ {
+ }
+
+ /**
+ * @brief Create an iterator to a (const/non-const) target handle
+ *
+ * @param[in] i_pTarget Target handle (pointer or const pointer
+ * depending on flavor) the iterator should reference
+ */
+ ALWAYS_INLINE
+ explicit _TargetIterator(T i_pTarget)
+ : iv_pCurrent(i_pTarget)
+ {
+ }
+
+ /**
+ * @brief Destroy an iterator to a (const/non-const) target handle
+ *
+ * @note Iterator does not own any resources to destroy
+ */
+ ALWAYS_INLINE
+ ~_TargetIterator()
+ {
+ }
+
+ /**
+ * @brief Dereference the iterator (return what it points to)
+ *
+ * @return Target handle in form of Target* or const Target*
+ *
+ * @note Returns NULL if it points to end(), should not be
+ * dereferenced in this case.
+ */
+ ALWAYS_INLINE
+ T operator* () const
+ {
+ // Only return copy of the target pointer (instead of a reference)
+ // because a reference will go out of scope when the iterator
+ // advances
+ return iv_pCurrent;
+ }
+
+ /**
+ * @brief Dereference the iterator (return what it points to)
+ * and (outside this function) call a function/member of
+ * the referenced target
+ *
+ * @return Target handle in form of Target* or const Target*
+ *
+ * @note Returns NULL if it points to end(), causing an
+ * assert when automatically dereferenced.
+ */
+ ALWAYS_INLINE
+ T operator->() const
+ {
+ // Only return copy of the target pointer (instead of a reference)
+ // because a reference will go out of scope when the iterator
+ // advances
+ return iv_pCurrent;
+ }
+
+ /**
+ * @brief Pre-increment the iterator
+ *
+ * @return The reference to the same iterator after advancing it
+ */
+ ALWAYS_INLINE
+ _TargetIterator& operator++();
+
+ /**
+ * @brief Post-increment the iterator
+ *
+ * @param[in] UNNAMED Dummy parameter used to distinguish
+ * this interface from pre-increment
+ *
+ * @return Copy of the original iterator before it advanced
+ */
+ ALWAYS_INLINE
+ _TargetIterator operator++(int);
+
+ /**
+ * @brief Determine if two iterators of same type are logically equal
+ *
+ * @param[in] i_rhs The other iterator to compare
+ *
+ * @return bool indicating whether the iterators point to the same
+ * entity
+ *
+ * @retval true Iterators point to same entity
+ * @retval false Iterators do not point to same entity
+ */
+ ALWAYS_INLINE
+ bool operator==(const _TargetIterator& i_rhs) const
+ {
+ return (iv_pCurrent == i_rhs.iv_pCurrent);
+ }
+
+ /**
+ * @brief Determine if two iterators of same type are logically not
+ * equal
+ *
+ * @param[in] i_rhs The other iterator to compare
+ *
+ * @return bool indicating whether the iterators point to a different
+ * logical entity
+ *
+ * @retval true Iterators point to different entity
+ * @retval false Iterators point to same entity
+ */
+ ALWAYS_INLINE
+ bool operator!=(const _TargetIterator& i_rhs) const
+ {
+ return (iv_pCurrent != i_rhs.iv_pCurrent);
+ }
+
+ /**
+ * @brief Assignment operator; assign iterator to another (such that
+ * they logically point to same entity)
+ *
+ * @param[in] i_rhs The iterator to assign
+ *
+ * @return Reference to the iterator, now updated to point to the same
+ * entity as the input iterator points to
+ */
+ ALWAYS_INLINE
+ _TargetIterator& operator=(const _TargetIterator& i_rhs)
+ {
+ iv_pCurrent = i_rhs.iv_pCurrent;
+ return *this;
+ }
+
+ /**
+ * @brief Copy constructor; assign iterator to a new iterator (such
+ * that they logically point to same entity)
+ *
+ * @param[in] i_rhs The iterator to assign
+ */
+ ALWAYS_INLINE
+ _TargetIterator(const _TargetIterator& i_rhs)
+ : iv_pCurrent(i_rhs.iv_pCurrent)
+ {
+ }
+
+ private:
+
+ /**
+ * @brief Advance the iterator to point to the next item maintained by
+ * the target service (or end() if end of list)
+ */
+ void advance();
+
+ T iv_pCurrent; // Pointer to current target
+};
+
+/**
+ * @brief Type aliases to simplify user code
+ */
+typedef _TargetIterator<Target*> TargetIterator;
+typedef _TargetIterator<const Target*> ConstTargetIterator;
+
+//******************************************************************************
+// _TargetIterator::operator++ (postincrement)
+//******************************************************************************
+
+template<typename T>
+_TargetIterator<T> _TargetIterator<T>::operator++(int)
+{
+ _TargetIterator l_originalIterator(*this);
+ advance();
+ return l_originalIterator;
+}
+
+//******************************************************************************
+// _TargetIterator::operator++ (preincrement)
+//******************************************************************************
+
+template<typename T>
+_TargetIterator<T>& _TargetIterator<T>::operator++()
+{
+ advance();
+ return *this;
+}
+
+#undef TARG_CLASS
+#undef TARG_NAMESPACE
+
+} // End namespace TARGETING
+
+#endif // TARG_TARGETITERATOR_H
+
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
diff --git a/src/include/usr/targeting/targetservice.H b/src/include/usr/targeting/targetservice.H
index 2797890c5..77e4b23f4 100644
--- a/src/include/usr/targeting/targetservice.H
+++ b/src/include/usr/targeting/targetservice.H
@@ -28,6 +28,8 @@
#include <targeting/attributeenums.H>
#include <targeting/target.H>
#include <targeting/entitypath.H>
+#include <targeting/iterators/targetiterator.H>
+#include <targeting/predicates/predicatebase.H>
//******************************************************************************
// Interface Definitions
@@ -140,6 +142,52 @@ class TargetService
void init();
/**
+ * @brief Map iterator types to common aliases
+ */
+ typedef TargetIterator iterator;
+ typedef ConstTargetIterator const_iterator;
+
+ /**
+ * @brief Return iterator which points to first target service target
+ * (or end() if none)
+ *
+ * @return Iterator pointing to first target service target
+ */
+ iterator begin();
+
+ /**
+ * @brief Return iterator to const which points to first target service
+ * target (or end() if none)
+ *
+ * @return Iterator to const pointing to first target service target
+ */
+ const_iterator begin() const;
+
+ /**
+ * @brief Return iterator which points to the "past the end of the
+ * list" target maintained by the target service
+ *
+ * @return Iterator pointing to the "past the end of the list" target
+ * maintained by the target service
+ */
+ iterator end();
+
+ /**
+ * @brief Return iterator to const which points to the "past the end of
+ * the list" target maintained by the target service
+ *
+ * @return Iterator to const pointing to the "past the end of the list"
+ * target maintained by the target service
+ */
+ const_iterator end() const;
+
+ /**
+ * @brief Allow iterator access to the target service's target store
+ */
+ friend class _TargetIterator<Target*>;
+ friend class _TargetIterator<const Target*>;
+
+ /**
* @brief Returns the top level physical target
*
* Returns the top level (usually system) target. Caller must check
@@ -272,25 +320,31 @@ class TargetService
* for said source target, the routine will return all targets
* contained within the processor chip.
*
+ * @param[out] o_list List of target handles that match the specified
+ * criteria
* @param[in] i_pTarget Target from which to search for other targets
* @param[in] i_type Type of association linking the specified target
* to candidate result targets
* @param[in] i_recursionLevel Whether to return candidate targets
* immediately associated to the specified target or recursively
* associated to it.
- * @param[out] o_list List of target handles that match the specified
- * criteria
+ * @param[in] i_pPredicate Pointer to a predicate to be evaluated
+ * against each candidate target (as determined by the source
+ * target, type, and recursion level parameters). If the predicate
+ * returns true, the target will be added to the result list. A
+ * value of NULL acts as a predicate that always returns true.
*
* @pre N/A
*
* @post Caller's list cleared; list of target handles matching the
* specified criteria returned
*/
- void getAssociated(
- const Target* i_pTarget,
- ASSOCIATION_TYPE i_type,
- RECURSION_LEVEL i_recursionLevel,
- TargetHandleList& o_list) const;
+ void getAssociated(
+ TargetHandleList& o_list,
+ const Target* const i_pTarget,
+ const ASSOCIATION_TYPE i_type = CHILD,
+ const RECURSION_LEVEL i_recursionLevel = IMMEDIATE,
+ const PredicateBase* i_pPredicate = NULL) const;
/**
* @brief Dump the target service for debug only
@@ -387,6 +441,10 @@ class TargetService
* @param[in] i_recursionLevel Whether to provide immediate or
* recursive results
* @param[in] i_entityPath Entity path to start search from
+ * @param[in] i_pPredicate Pointer to a predicate to be evaluated
+ * against each candidate target. If the predicate returns true,
+ * the target will be added to the result list. A value of NULL
+ * acts as a predicate that always returns true.
* @param[out] o_list List of returned target handles
*
* @pre Target service must be initialized
@@ -396,10 +454,11 @@ class TargetService
* path returned
*/
void _getInwards(
- ATTRIBUTE_ID i_attr,
- RECURSION_LEVEL i_recursionLevel,
- EntityPath i_entityPath,
- TargetHandleList& o_list) const;
+ ATTRIBUTE_ID i_attr,
+ RECURSION_LEVEL i_recursionLevel,
+ EntityPath i_entityPath,
+ const PredicateBase* i_pPredicate,
+ TargetHandleList& o_list) const;
/**
* @brief Returns handles to the targets associated to the
@@ -418,6 +477,10 @@ class TargetService
* @param[in] i_recursionLevel Whether to provide immediate or
* recursive results
* @param[in] i_entityPath Entity path to look from
+ * @param[in] i_pPredicate Pointer to a predicate to be evaluated
+ * against each candidate target. If the predicate returns true,
+ * the target will be added to the result list. A value of NULL
+ * acts as a predicate that always returns true.
* @param[out] o_list List of returned target handles
*
* @pre Target service must be initialized
@@ -427,13 +490,13 @@ class TargetService
* entity path returned.
*/
void _getOutwards(
- ATTRIBUTE_ID i_attr,
- RECURSION_LEVEL i_recursionLevel,
- EntityPath i_entityPath,
- TargetHandleList& o_list ) const;
+ ATTRIBUTE_ID i_attr,
+ RECURSION_LEVEL i_recursionLevel,
+ EntityPath i_entityPath,
+ const PredicateBase* i_pPredicate,
+ TargetHandleList& o_list ) const;
// Instance variables
-
bool iv_initialized; ///< Is service initialized or not
Target (*iv_targets)[]; ///< Pointer to array of target objects
uint32_t iv_maxTargets; ///< Maximum # target objects in the array
OpenPOWER on IntegriCloud