50 #ifndef _ZOLTAN2_INTEGERRANGELIST_HPP_
51 #define _ZOLTAN2_INTEGERRANGELIST_HPP_
53 #include <Zoltan2_config.h>
55 #include <Teuchos_ParameterEntryValidator.hpp>
56 #include <Teuchos_ValidatorXMLConverter.hpp>
57 #include <Teuchos_XMLObject.hpp>
58 #include <Teuchos_ValidatorMaps.hpp>
59 #include <Teuchos_DummyObjectGetter.hpp>
60 #include <Teuchos_StrUtils.hpp>
95 template <
typename Integral>
98 typedef typename Teuchos::Array<Integral>::size_type arraySize_t;
99 arraySize_t len = vals.size();
103 Integral flag = vals[len-1];
125 template <
typename Integral>
129 throw std::runtime_error(
"list is not a valid range list");
147 template <
typename Integral>
150 if (!e.isType<Teuchos::Array<Integral> >())
151 throw std::runtime_error(
"Should not call until modified");
153 Teuchos::Array<Integral> *valPtr=NULL;
154 Teuchos::Array<Integral> &
vals = e.getValue(valPtr);
172 template <
typename Integral>
176 throw std::runtime_error(
"list is not a valid range list");
194 template <
typename Integral>
197 if (!e.isType<Teuchos::Array<Integral> >())
198 throw std::runtime_error(
"Should not call until modified");
200 Teuchos::Array<Integral> *valPtr=NULL;
201 Teuchos::Array<Integral> &
vals = e.getValue(valPtr);
219 template <
typename Integral>
220 bool IsInRangeList(
const Integral val,
const Teuchos::Array<Integral> &valList,
bool sorted=
true)
228 typename Teuchos::Array<Integral>::const_iterator flag = valList.end();
230 if (std::binary_search(valList.begin(), flag, val))
236 for (
typename Teuchos::Array<Integral>::size_type i=0; i < valList.size()-1; i++){
237 if (valList[i] == val)
254 template <
typename Integral>
257 if (!e.isType<Teuchos::Array<Integral> >())
258 throw std::runtime_error(
"Should not call until modified");
260 Teuchos::Array<Integral> *valPtr=NULL;
261 Teuchos::Array<Integral> &valList = e.getValue(valPtr);
264 RCP<const irl_t> irl;
267 RCP<const Teuchos::ParameterEntryValidator> valtor = e.validator();
268 if (!valtor.is_null()){
270 irl = rcp_dynamic_cast<
const irl_t>(valtor);
281 throw std::runtime_error(
"wrong type of parameter entry");
283 bool sorted = irl->inputListWillBeSorted();
296 template <
typename Integral>
297 Teuchos::ArrayView<Integral>
getList(Teuchos::Array<Integral> &irl)
299 Teuchos::ArrayView<Integral> av;
303 av = irl.view(0, irl.size()-1);
316 template <
typename Integral>
324 Teuchos::ArrayView<const Integral> view =
325 irl.view(0, irl.size()-1);
393 template <
typename Integral>
394 class IntegerRangeListValidator :
public Teuchos::ParameterEntryValidator
398 #ifndef DOXYGEN_SHOULD_SKIP_THIS
404 static const std::string listDelim_;
405 static const std::string rangeDelim_;
406 static const std::string allText_;
408 static void checkValid(
char c);
409 static bool listSaysAll(std::string &l);
410 static int breakRange(std::string &range, std::string &from, std::string &to);
432 bool unsorted=
false);
438 void printDoc(std::string
const& docString, std::ostream &out)
const;
442 void validate( Teuchos::ParameterEntry
const& entry,
443 std::string
const&
paramName, std::string
const& sublistName
447 std::string
const& sublistName, Teuchos::ParameterEntry * entry
480 template <
typename Integral>
481 const std::string IntegerRangeListValidator<Integral>::listDelim_(
",");
483 template <
typename Integral>
484 const std::string IntegerRangeListValidator<Integral>::rangeDelim_(
"-");
486 template <
typename Integral>
487 const std::string IntegerRangeListValidator<Integral>::allText_(
"all");
489 template <
typename Integral>
490 void IntegerRangeListValidator<Integral>::checkValid(
char c)
492 if (std::isspace(c) || std::isdigit(c) || (c ==
',') || (c ==
'-'))
495 throw std::runtime_error(
"invalid integer range list");
498 template <
typename Integral>
499 bool IntegerRangeListValidator<Integral>::listSaysAll(std::string &l)
501 std::transform(l.begin(), l.end(), l.begin(), (int(*)(int)) tolower);
502 if (l.find(allText_) != std::string::npos)
508 template <
typename Integral>
509 int IntegerRangeListValidator<Integral>::breakRange(
510 std::string &range, std::string &from, std::string &to)
514 std::string::size_type loc = range.find(rangeDelim_);
515 if (loc == std::string::npos){
519 from = range.substr(0, loc);
520 to = range.substr(loc+1, range.size());
523 std::istringstream iss1(from);
527 std::istringstream iss2(to);
532 return (b != a) ? 2 : 1;
536 template <
typename Integral>
538 bool unsorted): min_(1), max_(0), unsorted_(unsorted)
542 template <
typename Integral>
544 Integral validMin, Integral validMax,
bool unsorted) :
545 min_(validMin), max_(validMax), unsorted_(unsorted)
547 if (min_ < max_) std::swap(min_,max_);
552 template <
typename Integral>
556 std::string className(
"IntegerRangeListValidator");
557 std::string classType(
"("+Teuchos::TypeNameTraits<Integral>::name()+
")");
558 return std::string(className + classType);
561 template <
typename Integral>
563 std::string
const& docString, std::ostream &out)
const
565 Teuchos::StrUtils::printLines(out,
"# ",docString);
566 out <<
"#\tAn integer range list is a string which can contain:\n";
567 out <<
"#\t\tthe text \"all\", which indicates all values\n";
568 out <<
"#\t\ta list of integer ranges separated by commas.\n";
569 out <<
"#\tA range is one value, or two values separated by a dash.\n";
570 out <<
"#\tExample: \"all\" or \"1-10\" or \"3, 10-12\" or \"25\"\n";
572 out <<
"#\tThe range of valid integers is [";
573 out << min_ <<
"," << max_ <<
"]\n";
577 template <
typename Integral>
580 return Teuchos::null;
583 template <
typename Integral>
585 Teuchos::ParameterEntry
const& entry,
586 std::string
const& , std::string
const& )
const
588 if (!entry.isType<std::string>()){
591 std::string *sptr=NULL;
592 std::string &rangeList = entry.getValue(sptr);
593 std::string inValue(rangeList);
595 if (listSaysAll(inValue))
599 std::for_each(inValue.begin(), inValue.end(), checkValid);
602 std::string::const_iterator rangeBegin = inValue.begin();
603 std::string::const_iterator valueEnd = inValue.end();
605 while (rangeBegin != valueEnd){
606 std::string::const_iterator rangeEnd = std::search(
607 rangeBegin, valueEnd, listDelim_.begin(), listDelim_.end());
608 std::string range(rangeBegin, rangeEnd);
609 std::string aHalf, bHalf;
610 int count = breakRange(range, aHalf, bHalf);
613 std::istringstream iss1(aHalf);
616 std::istringstream iss2(bHalf);
622 if ((a < min_) || (b > max_)){
623 std::ostringstream oss;
624 oss <<
"input range [" << a <<
"," << b <<
"] ";
625 oss <<
"exceeds valid range [" << min_ <<
"," << max_ <<
"] ";
626 throw std::runtime_error(oss.str());
628 if (rangeEnd == valueEnd)
629 rangeBegin = rangeEnd;
631 rangeBegin = ++rangeEnd;
636 template <
typename Integral>
638 std::string
const& , std::string
const& ,
639 Teuchos::ParameterEntry * entry)
const
641 typedef typename Teuchos::Array<Integral>::size_type arraySize_t;
642 if (!entry->isType<std::string>()){
646 std::string *sptr=NULL;
647 std::string &rangeList = entry->getValue(sptr);
648 Teuchos::Array<Integral> valueList;
650 std::string inValue(rangeList);
652 if (listSaysAll(inValue)){
657 std::for_each(inValue.begin(), inValue.end(), checkValid);
659 std::string::const_iterator rangeBegin = inValue.begin();
660 std::string::const_iterator valueEnd = inValue.end();
662 while (rangeBegin != valueEnd){
663 std::string::const_iterator rangeEnd = std::search(rangeBegin,
664 valueEnd, listDelim_.begin(), listDelim_.end());
665 std::string range(rangeBegin, rangeEnd);
666 std::string aHalf, bHalf;
667 int count = breakRange(range, aHalf, bHalf);
670 std::istringstream iss1(aHalf);
673 std::istringstream iss2(bHalf);
679 if ((max_ >= min_) && ((a < min_) || (b > max_))){
680 std::ostringstream oss;
681 oss <<
"input range [" << a <<
"," << b <<
"] ";
682 oss <<
"exceeds valid range [" << min_ <<
"," << max_ <<
"] ";
683 throw std::runtime_error(oss.str());
685 for (Integral i=a; i <=b; i++)
686 valueList.push_back(i);
687 if (rangeEnd == valueEnd)
688 rangeBegin = rangeEnd;
690 rangeBegin = ++rangeEnd;
692 if (!unsorted_ && valueList.size() > 1){
693 std::sort(valueList.begin(), valueList.end());
694 arraySize_t listEnd = 0;
695 arraySize_t length = valueList.size();
696 for (arraySize_t i=1; i < length; i++){
697 if (valueList[i] > valueList[listEnd]){
700 valueList[listEnd] = valueList[i];
703 if (++listEnd < length)
704 valueList.resize(listEnd);
708 if (valueList.size() == 0){
711 else if (max_ >= min_){
712 Integral allSize = max_ - min_ + 1;
713 if (valueList.size() == allSize){
718 valueList.push_back(flag);
720 entry->setValue(valueList);
739 template <
typename Integral>
745 RCP<Teuchos::ParameterEntryValidator>
convertXML(
746 const Teuchos::XMLObject& xmlObj,
747 const Teuchos::IDtoValidatorMap& validatorIDsMap)
const;
750 const RCP<const Teuchos::ParameterEntryValidator> validator,
751 Teuchos::XMLObject& xmlObj,
752 const Teuchos::ValidatortoIDMap& validatorIDsMap)
const;
754 #ifdef HAVE_TEUCHOS_DEBUG
756 RCP<const Teuchos::ParameterEntryValidator> getDummyValidator()
const{
757 return Teuchos::DummyObjectGetter<IntegerRangeListValidator<Integral> >::getDummyObject();
762 template <
typename Integral>
763 RCP<Teuchos::ParameterEntryValidator>
765 const Teuchos::XMLObject& xmlObj,
766 const Teuchos::IDtoValidatorMap& )
const
768 Integral minValue=0, maxValue=0;
769 bool unsorted=
false, hasMin=
false, hasMax=
false;
771 if (xmlObj.hasAttribute(std::string(
"min"))) {
772 minValue = xmlObj.getRequired<Integral>(std::string(
"min"));
776 if (xmlObj.hasAttribute(std::string(
"max"))) {
777 maxValue = xmlObj.getRequired<Integral>(std::string(
"max"));
781 if (xmlObj.hasAttribute(std::string(
"unsorted")))
782 unsorted = xmlObj.getRequired<
bool>(std::string(
"unsorted"));
784 RCP<Teuchos::ParameterEntryValidator> toReturn;
786 if (hasMin && hasMax)
788 else if (!hasMin && !hasMax)
791 throw std::runtime_error(
"invalid XML representation");
796 template<
typename Integral>
798 const RCP<const Teuchos::ParameterEntryValidator > validator,
799 Teuchos::XMLObject& xmlObj,
800 const Teuchos::ValidatortoIDMap& )
const
802 RCP<const IntegerRangeListValidator<Integral> > castedValidator =
807 Integral maxValue = castedValidator->getAllowedMaximum();
808 bool unsorted = castedValidator->inputListWillBeSorted();
810 if (minValue < maxValue){
811 xmlObj.addAttribute<Integral>(std::string(
"min"), minValue);
812 xmlObj.addAttribute<Integral>(std::string(
"max"), maxValue);
815 xmlObj.addAttribute<
bool>(std::string(
"unsorted"), unsorted);
void validateAndModify(std::string const ¶mName, std::string const &sublistName, Teuchos::ParameterEntry *entry) const
the listed values are in the Array<int>
ValidStringsList validStringValues() const
Integral getAllowedMinimum() const
Return the minimum value permitted in the list.
XML conversion code for IntegerRangeListValidator.
RangeType
Codes that indicate how to interpret the Array<int> representing the user's integer range list...
void convertValidator(const RCP< const Teuchos::ParameterEntryValidator > validator, Teuchos::XMLObject &xmlObj, const Teuchos::ValidatortoIDMap &validatorIDsMap) const
A ParameterList validator for integer range lists.
const std::string getXMLTypeName() const
bool validIntegralRangeList(const Teuchos::Array< Integral > &vals)
A helper function that indicates whether an array is a valid integer range list.
Integral getAllowedMaximum() const
Return the maximum value permitted in the list.
bool IsInRangeList(const Integral val, const Teuchos::Array< Integral > &valList, bool sorted=true)
A helper function that determines if a value is in the list.
Teuchos::RCP< const Teuchos::Array< std::string > > ValidStringsList
static const std::string fail
void validate(Teuchos::ParameterEntry const &entry, std::string const ¶mName, std::string const &sublistName) const
bool noValuesAreInRangeList(const Teuchos::Array< Integral > &vals)
A helper function that determines if no values are in the list.
IntegerRangeListValidator(bool unsorted=false)
Constructor: any Integral is valid.
void printIntegralRangeList(std::ostream &os, Teuchos::Array< Integral > &irl)
A helper function that prints the meaning of an encoded integer range list.
Teuchos::ArrayView< Integral > getList(Teuchos::Array< Integral > &irl)
A helper function that returns a view of the list.
bool inputListWillBeSorted() const
Return whether the list is sorted or not.
void printDoc(std::string const &docString, std::ostream &out) const
RCP< Teuchos::ParameterEntryValidator > convertXML(const Teuchos::XMLObject &xmlObj, const Teuchos::IDtoValidatorMap &validatorIDsMap) const
bool allValuesAreInRangeList(const Teuchos::Array< Integral > &vals)
A helper function that determines if all values are in the list.