14 #ifndef _ZOLTAN2_INTEGERRANGELIST_HPP_
15 #define _ZOLTAN2_INTEGERRANGELIST_HPP_
17 #include <Zoltan2_config.h>
19 #include <Teuchos_ParameterEntryValidator.hpp>
20 #include <Teuchos_ValidatorXMLConverter.hpp>
21 #include <Teuchos_XMLObject.hpp>
22 #include <Teuchos_ValidatorMaps.hpp>
23 #include <Teuchos_DummyObjectGetter.hpp>
24 #include <Teuchos_StrUtils.hpp>
59 template <
typename Integral>
62 typedef typename Teuchos::Array<Integral>::size_type arraySize_t;
63 arraySize_t len = vals.size();
67 Integral flag = vals[len-1];
89 template <
typename Integral>
93 throw std::runtime_error(
"list is not a valid range list");
111 template <
typename Integral>
114 if (!e.isType<Teuchos::Array<Integral> >())
115 throw std::runtime_error(
"Should not call until modified");
117 Teuchos::Array<Integral> *valPtr=NULL;
118 Teuchos::Array<Integral> &vals = e.getValue(valPtr);
136 template <
typename Integral>
140 throw std::runtime_error(
"list is not a valid range list");
158 template <
typename Integral>
161 if (!e.isType<Teuchos::Array<Integral> >())
162 throw std::runtime_error(
"Should not call until modified");
164 Teuchos::Array<Integral> *valPtr=NULL;
165 Teuchos::Array<Integral> &vals = e.getValue(valPtr);
183 template <
typename Integral>
184 bool IsInRangeList(
const Integral val,
const Teuchos::Array<Integral> &valList,
bool sorted=
true)
192 typename Teuchos::Array<Integral>::const_iterator flag = valList.end();
194 if (std::binary_search(valList.begin(), flag, val))
200 for (
typename Teuchos::Array<Integral>::size_type i=0; i < valList.size()-1; i++){
201 if (valList[i] == val)
218 template <
typename Integral>
221 if (!e.isType<Teuchos::Array<Integral> >())
222 throw std::runtime_error(
"Should not call until modified");
224 Teuchos::Array<Integral> *valPtr=NULL;
225 Teuchos::Array<Integral> &valList = e.getValue(valPtr);
228 RCP<const irl_t> irl;
231 RCP<const Teuchos::ParameterEntryValidator> valtor = e.validator();
232 if (!valtor.is_null()){
234 irl = rcp_dynamic_cast<
const irl_t>(valtor);
245 throw std::runtime_error(
"wrong type of parameter entry");
247 bool sorted = irl->inputListWillBeSorted();
260 template <
typename Integral>
261 Teuchos::ArrayView<Integral>
getList(Teuchos::Array<Integral> &irl)
263 Teuchos::ArrayView<Integral> av;
267 av = irl.view(0, irl.size()-1);
280 template <
typename Integral>
288 Teuchos::ArrayView<const Integral> view =
289 irl.view(0, irl.size()-1);
357 template <
typename Integral>
358 class IntegerRangeListValidator :
public Teuchos::ParameterEntryValidator
362 #ifndef DOXYGEN_SHOULD_SKIP_THIS
368 static const std::string listDelim_;
369 static const std::string rangeDelim_;
370 static const std::string allText_;
372 static void checkValid(
char c);
373 static bool listSaysAll(std::string &l);
374 static int breakRange(std::string &range, std::string &from, std::string &to);
396 bool unsorted=
false);
402 void printDoc(std::string
const& docString, std::ostream &out)
const;
406 void validate( Teuchos::ParameterEntry
const& entry,
407 std::string
const& paramName, std::string
const& sublistName
411 std::string
const& sublistName, Teuchos::ParameterEntry * entry
444 template <
typename Integral>
445 const std::string IntegerRangeListValidator<Integral>::listDelim_(
",");
447 template <
typename Integral>
448 const std::string IntegerRangeListValidator<Integral>::rangeDelim_(
"-");
450 template <
typename Integral>
451 const std::string IntegerRangeListValidator<Integral>::allText_(
"all");
453 template <
typename Integral>
454 void IntegerRangeListValidator<Integral>::checkValid(
char c)
456 if (std::isspace(c) || std::isdigit(c) || (c ==
',') || (c ==
'-'))
459 throw std::runtime_error(
"invalid integer range list");
462 template <
typename Integral>
463 bool IntegerRangeListValidator<Integral>::listSaysAll(std::string &l)
465 std::transform(l.begin(), l.end(), l.begin(), (int(*)(int)) tolower);
466 if (l.find(allText_) != std::string::npos)
472 template <
typename Integral>
473 int IntegerRangeListValidator<Integral>::breakRange(
474 std::string &range, std::string &from, std::string &to)
478 std::string::size_type loc = range.find(rangeDelim_);
479 if (loc == std::string::npos){
483 from = range.substr(0, loc);
484 to = range.substr(loc+1, range.size());
487 std::istringstream iss1(from);
491 std::istringstream iss2(to);
496 return (b != a) ? 2 : 1;
500 template <
typename Integral>
502 bool unsorted): min_(1), max_(0), unsorted_(unsorted)
506 template <
typename Integral>
508 Integral validMin, Integral validMax,
bool unsorted) :
509 min_(validMin), max_(validMax), unsorted_(unsorted)
511 if (min_ < max_) std::swap(min_,max_);
516 template <
typename Integral>
520 std::string className(
"IntegerRangeListValidator");
521 std::string classType(
"("+Teuchos::TypeNameTraits<Integral>::name()+
")");
522 return std::string(className + classType);
525 template <
typename Integral>
527 std::string
const& docString, std::ostream &out)
const
529 Teuchos::StrUtils::printLines(out,
"# ",docString);
530 out <<
"#\tAn integer range list is a string which can contain:\n";
531 out <<
"#\t\tthe text \"all\", which indicates all values\n";
532 out <<
"#\t\ta list of integer ranges separated by commas.\n";
533 out <<
"#\tA range is one value, or two values separated by a dash.\n";
534 out <<
"#\tExample: \"all\" or \"1-10\" or \"3, 10-12\" or \"25\"\n";
536 out <<
"#\tThe range of valid integers is [";
537 out << min_ <<
"," << max_ <<
"]\n";
541 template <
typename Integral>
544 return Teuchos::null;
547 template <
typename Integral>
549 Teuchos::ParameterEntry
const& entry,
550 std::string
const& , std::string
const& )
const
552 if (!entry.isType<std::string>()){
555 std::string *sptr=NULL;
556 std::string &rangeList = entry.getValue(sptr);
557 std::string inValue(rangeList);
559 if (listSaysAll(inValue))
563 std::for_each(inValue.begin(), inValue.end(), checkValid);
566 std::string::const_iterator rangeBegin = inValue.begin();
567 std::string::const_iterator valueEnd = inValue.end();
569 while (rangeBegin != valueEnd){
570 std::string::const_iterator rangeEnd = std::search(
571 rangeBegin, valueEnd, listDelim_.begin(), listDelim_.end());
572 std::string range(rangeBegin, rangeEnd);
573 std::string aHalf, bHalf;
574 int count = breakRange(range, aHalf, bHalf);
577 std::istringstream iss1(aHalf);
580 std::istringstream iss2(bHalf);
586 if ((a < min_) || (b > max_)){
587 std::ostringstream oss;
588 oss <<
"input range [" << a <<
"," << b <<
"] ";
589 oss <<
"exceeds valid range [" << min_ <<
"," << max_ <<
"] ";
590 throw std::runtime_error(oss.str());
592 if (rangeEnd == valueEnd)
593 rangeBegin = rangeEnd;
595 rangeBegin = ++rangeEnd;
600 template <
typename Integral>
602 std::string
const& , std::string
const& ,
603 Teuchos::ParameterEntry * entry)
const
605 typedef typename Teuchos::Array<Integral>::size_type arraySize_t;
606 if (!entry->isType<std::string>()){
610 std::string *sptr=NULL;
611 std::string &rangeList = entry->getValue(sptr);
612 Teuchos::Array<Integral> valueList;
614 std::string inValue(rangeList);
616 if (listSaysAll(inValue)){
621 std::for_each(inValue.begin(), inValue.end(), checkValid);
623 std::string::const_iterator rangeBegin = inValue.begin();
624 std::string::const_iterator valueEnd = inValue.end();
626 while (rangeBegin != valueEnd){
627 std::string::const_iterator rangeEnd = std::search(rangeBegin,
628 valueEnd, listDelim_.begin(), listDelim_.end());
629 std::string range(rangeBegin, rangeEnd);
630 std::string aHalf, bHalf;
631 int count = breakRange(range, aHalf, bHalf);
634 std::istringstream iss1(aHalf);
637 std::istringstream iss2(bHalf);
643 if ((max_ >= min_) && ((a < min_) || (b > max_))){
644 std::ostringstream oss;
645 oss <<
"input range [" << a <<
"," << b <<
"] ";
646 oss <<
"exceeds valid range [" << min_ <<
"," << max_ <<
"] ";
647 throw std::runtime_error(oss.str());
649 for (Integral i=a; i <=b; i++)
650 valueList.push_back(i);
651 if (rangeEnd == valueEnd)
652 rangeBegin = rangeEnd;
654 rangeBegin = ++rangeEnd;
656 if (!unsorted_ && valueList.size() > 1){
657 std::sort(valueList.begin(), valueList.end());
658 arraySize_t listEnd = 0;
659 arraySize_t length = valueList.size();
660 for (arraySize_t i=1; i < length; i++){
661 if (valueList[i] > valueList[listEnd]){
664 valueList[listEnd] = valueList[i];
667 if (++listEnd < length)
668 valueList.resize(listEnd);
672 if (valueList.size() == 0){
675 else if (max_ >= min_){
676 Integral allSize = max_ - min_ + 1;
677 if (valueList.size() == allSize){
682 valueList.push_back(flag);
684 entry->setValue(valueList);
703 template <
typename Integral>
709 RCP<Teuchos::ParameterEntryValidator>
convertXML(
710 const Teuchos::XMLObject& xmlObj,
711 const Teuchos::IDtoValidatorMap& validatorIDsMap)
const;
714 const RCP<const Teuchos::ParameterEntryValidator> validator,
715 Teuchos::XMLObject& xmlObj,
716 const Teuchos::ValidatortoIDMap& validatorIDsMap)
const;
718 #ifdef HAVE_TEUCHOS_DEBUG
720 RCP<const Teuchos::ParameterEntryValidator> getDummyValidator()
const{
721 return Teuchos::DummyObjectGetter<IntegerRangeListValidator<Integral> >::getDummyObject();
726 template <
typename Integral>
727 RCP<Teuchos::ParameterEntryValidator>
729 const Teuchos::XMLObject& xmlObj,
730 const Teuchos::IDtoValidatorMap& )
const
732 Integral minValue=0, maxValue=0;
733 bool unsorted=
false, hasMin=
false, hasMax=
false;
735 if (xmlObj.hasAttribute(std::string(
"min"))) {
736 minValue = xmlObj.getRequired<Integral>(std::string(
"min"));
740 if (xmlObj.hasAttribute(std::string(
"max"))) {
741 maxValue = xmlObj.getRequired<Integral>(std::string(
"max"));
745 if (xmlObj.hasAttribute(std::string(
"unsorted")))
746 unsorted = xmlObj.getRequired<
bool>(std::string(
"unsorted"));
748 RCP<Teuchos::ParameterEntryValidator> toReturn;
750 if (hasMin && hasMax)
752 else if (!hasMin && !hasMax)
755 throw std::runtime_error(
"invalid XML representation");
760 template<
typename Integral>
762 const RCP<const Teuchos::ParameterEntryValidator > validator,
763 Teuchos::XMLObject& xmlObj,
764 const Teuchos::ValidatortoIDMap& )
const
766 RCP<const IntegerRangeListValidator<Integral> > castedValidator =
771 Integral maxValue = castedValidator->getAllowedMaximum();
772 bool unsorted = castedValidator->inputListWillBeSorted();
774 if (minValue < maxValue){
775 xmlObj.addAttribute<Integral>(std::string(
"min"), minValue);
776 xmlObj.addAttribute<Integral>(std::string(
"max"), maxValue);
779 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.