Skip to content
Snippets Groups Projects
CompositeValidator.cpp 3.1 KiB
Newer Older
#include "MantidKernel/CompositeValidator.h"

using namespace Mantid::Kernel;

namespace Mantid {
namespace Kernel {
/// Default constructor
CompositeValidator::CompositeValidator() : IValidator(), m_children() {}
/// Destructor
CompositeValidator::~CompositeValidator() { m_children.clear(); }
/**
 * The allowed values for the composite vaidator. This returns
 * the intersection of the allowedValues for the child validators
 * @return
 */
std::vector<std::string> CompositeValidator::allowedValues() const {
  std::set<std::string> elem_unique;
  std::multiset<std::string> elem_all;
  // how many validators return non-empty list of allowed values
  int n_combinations(0);
  std::list<IValidator_sptr>::const_iterator itrEnd = m_children.end();
  for (std::list<IValidator_sptr>::const_iterator itr = m_children.begin();
       itr != itrEnd; ++itr) {
    std::vector<std::string> subs = (*itr)->allowedValues();
    if (subs.empty())
      continue;
    elem_unique.insert(subs.begin(), subs.end());
    elem_all.insert(subs.begin(), subs.end());
    n_combinations++;
  }
  // empty or single set of allowed values
  if (n_combinations < 2)
    return std::vector<std::string>(elem_unique.begin(), elem_unique.end());
  // there is more then one combination and we have to identify its union;
  for (std::set<std::string>::const_iterator its = elem_unique.begin();
       its != elem_unique.end(); ++its) {
    std::multiset<std::string>::iterator im = elem_all.find(*its);
    elem_all.erase(im);
  }
  std::set<std::string> rez;
  for (std::multiset<std::string>::const_iterator im = elem_all.begin();
       im != elem_all.end(); ++im) {
    rez.insert(*im);
  }
  return std::vector<std::string>(rez.begin(), rez.end());
}
/**
 * Clone the validator
 * @return A newly constructed validator object. Each child is also cloned
 */
Kernel::IValidator_sptr CompositeValidator::clone() const {
  boost::shared_ptr<CompositeValidator> copy =
      boost::make_shared<CompositeValidator>();
  std::list<IValidator_sptr>::const_iterator itrEnd = m_children.end();
  for (std::list<IValidator_sptr>::const_iterator itr = m_children.begin();
       itr != itrEnd; ++itr) {
    copy->add((*itr)->clone());
  }
  return copy;
}
/** Adds a validator to the group of validators to check
 *  @param child :: A pointer to the validator to add
 */
void CompositeValidator::add(Kernel::IValidator_sptr child) {
  m_children.push_back(child);
}
/** Checks the value of all child validators. Fails if any child fails.
 *  @param value :: The workspace to test
 *  @return A user level description of the first problem it finds otherwise ""
 */
std::string CompositeValidator::check(const boost::any &value) const {
  std::list<IValidator_sptr>::const_iterator itrEnd = m_children.end();
  for (std::list<IValidator_sptr>::const_iterator itr = m_children.begin();
       itr != itrEnd; ++itr) {
    std::string error = (*itr)->check(value);
    // exit on the first error, to avoid passing doing more tests on invalid
    // objects that could fail
    if (error != "")
      return error;
  }
  // there were no errors
  return "";
}
} // namespace Mantid