9 #ifndef LARDATAALG_UTILITIES_MULTIPLECHOICESELECTION_H 
   10 #define LARDATAALG_UTILITIES_MULTIPLECHOICESELECTION_H 
   19 #include <type_traits>  
   27 namespace util::details {
 
   30   template <
typename... Strings>
 
   32     = std::conjunction_v<std::is_convertible<Strings, std::string>...>;
 
   38     static bool equal(std::string 
const& 
a, std::string 
const& b);
 
   41     static bool less(std::string 
const& a, std::string 
const& b);
 
   44     static bool cmp_lower(
unsigned char a, 
unsigned char b);
 
   45     static bool eq_lower(
unsigned char a, 
unsigned char b);
 
   51   template <
typename Comparer>
 
   53     bool operator() (std::string 
const& 
a, std::string 
const& b) 
const;
 
   72   template <
typename Choices>
 
   83     template <
typename... Aliases>
 
   88     template <
typename... Aliases>
 
   90     addAlias(std::string alias, Aliases... moreAliases);
 
   93     bool match(std::string 
const& label) 
const;
 
  106     operator std::string()
 const { 
return name(); }
 
  121     std::string 
dump() 
const;
 
  145     static bool equal(std::string 
const& 
a, std::string 
const& b)
 
  158 namespace util { 
class MultipleChoiceSelectionBase; }
 
  174     virtual const char* 
what() 
const noexcept
 override { 
return s.c_str(); }
 
  184     std::string 
const& 
label()
 const { 
return s; }
 
  192     std::string 
const& 
label()
 const { 
return s; }
 
  214 template <
typename Choices>
 
  240   template <
typename... Options>
 
  251   std::size_t 
size() 
const;
 
  273   template <
typename... Aliases>
 
  287   template <
typename... Aliases>
 
  303   template <
typename... Aliases>
 
  313   bool hasOption(std::string 
const& label) 
const;
 
  343   Option_t const& 
get(std::string 
const& label) 
const;
 
  369     (std::string 
const& indent, std::string 
const& firstIndent) 
const;
 
  386     std::string, std::size_t,
 
  413   void recordLabel(std::string&& label, std::size_t index);
 
  418   template <
typename... Aliases>
 
  420   recordLabels(std::size_t index, std::string alias, Aliases... moreAliases);
 
  442   static constexpr 
auto npos = std::numeric_limits<std::size_t>::max();
 
  448 namespace util::details {
 
  456   template <
typename Choices>
 
  458     MultipleChoiceSelectionOption_t<Choices> 
const& 
option,
 
  461   template <
typename Choices>
 
  464     MultipleChoiceSelectionOption_t<Choices> 
const& 
option 
  470   template <
typename Choices>
 
  472     MultipleChoiceSelectionOption_t<Choices> 
const& 
option,
 
  475   template <
typename Choices>
 
  478     MultipleChoiceSelectionOption_t<Choices> 
const& 
option 
  484   template <
typename Choices>
 
  486     MultipleChoiceSelectionOption_t<Choices> 
const& 
option,
 
  487     std::string 
const& label
 
  489   template <
typename Choices>
 
  491     std::string 
const& label,
 
  492     MultipleChoiceSelectionOption_t<Choices> 
const& 
option 
  498   template <
typename Choices>
 
  500     MultipleChoiceSelectionOption_t<Choices> 
const& 
option,
 
  501     std::string 
const& label
 
  503   template <
typename Choices>
 
  505     std::string 
const& label,
 
  506     MultipleChoiceSelectionOption_t<Choices> 
const& 
option 
  515   template <
typename Choices>
 
  516   std::ostream& 
operator<<
 
  517     (std::ostream& out, MultipleChoiceSelectionOption_t<Choices> 
const& 
option);
 
  530 template <
typename B1, 
typename E1, 
typename B2, 
typename E2, 
typename Comp>
 
  534     if (b2 == e2) 
return false; 
 
  536     if (less(*b1, *b2)) 
return true;
 
  537     if (less(*b2, *b1)) 
return false;
 
  546   (std::string 
const& 
a, std::string 
const& b)
 
  547   { 
return std::equal(a.begin(), a.end(), b.begin(), b.end(), eq_lower); }
 
  552   (std::string 
const& a, std::string 
const& b)
 
  554   return std::lexicographical_compare
 
  555     (a.begin(), a.end(), b.begin(), b.end(), cmp_lower);
 
  561   (
unsigned char a, 
unsigned char b)
 
  562   { 
return std::tolower(a) < std::tolower(b); }
 
  567   (
unsigned char a, 
unsigned char b)
 
  568   { 
return std::tolower(a) == std::tolower(b); }
 
  572 template <
typename Comparer>
 
  574   (std::string 
const& 
a, std::string 
const& b) 
const 
  575   { 
return Comparer::less(a, b); }
 
  579 namespace util::details {
 
  581   template <
typename Value, 
typename >
 
  585     template <
typename T>
 
  586     static std::optional<std::string> 
convert(T 
const&) { 
return {}; }
 
  590   template <
typename Value>
 
  594     template <
typename T>
 
  598           { 
std::to_string(
static_cast<std::underlying_type_t<T>
>(value)) }; 
 
  603   template <
typename Value>
 
  606       std::is_convertible_v<Value, std::string>
 
  607       || std::is_constructible_v<std::string, Value>
 
  611     template <
typename T>
 
  613       { 
return { std::string{ value } }; }
 
  617   template <
typename Value>
 
  619     <Value, 
std::
void_t<decltype(std::to_string(std::declval<Value>()))>>
 
  622     template <
typename T>
 
  633 template <
typename Choices>
 
  634 template <
typename... Aliases>
 
  639   fLabels.reserve(1U + 
sizeof...(aliases));
 
  640   addAlias(std::move(name), std::move(aliases)...);
 
  645 template <
typename Choices>
 
  646 template <
typename... Aliases>
 
  648   (std::string alias, Aliases... moreAliases)
 
  651   fLabels.push_back(std::move(alias));
 
  652   if constexpr(
sizeof...(moreAliases) > 0)
 
  653     return addAlias(std::move(moreAliases)...);
 
  659 template <
typename Choices>
 
  661   (std::string 
const& label) 
const 
  664     fLabels.begin(), fLabels.end(),
 
  665     [&label](std::string 
const& alias){ 
return equal(label, alias); }
 
  671 template <
typename Choices>
 
  674   (std::string 
const& defValue) 
const 
  675   { 
return value_as_string(
value(), defValue); }
 
  679 template <
typename Choices>
 
  682   { 
return value_as_string(
name()); }
 
  686 template <
typename Choices>
 
  687 std::optional<std::string>
 
  696 template <
typename Choices>
 
  701   return value_as_string(value).value_or(defValue);
 
  706 template <
typename Choices>
 
  710   auto iLabel = fLabels.begin();
 
  711   auto const lend = fLabels.end();
 
  712   std::string 
s { 
'"' };
 
  715   auto const valueStr = value_as_string();
 
  716   if (valueStr != *iLabel) {
 
  721   if (++iLabel != lend) {
 
  722     s += 
" (aliases: \"";
 
  725     while (++iLabel != lend) {
 
  738 template <
typename Choices>
 
  739 bool util::details::operator==
 
  743 template <
typename Choices>
 
  744 bool util::details::operator==
 
  746   { 
return option == 
value; }
 
  750 template <
typename Choices>
 
  751 bool util::details::operator!=
 
  755 template <
typename Choices>
 
  756 bool util::details::operator!=
 
  758   { 
return option != 
value; }
 
  762 template <
typename Choices>
 
  765   std::string 
const& label
 
  767   { 
return option.
match(label); }
 
  769 template <
typename Choices>
 
  771   std::string 
const& label,
 
  774   { 
return option == label; }
 
  778 template <
typename Choices>
 
  781   std::string 
const& label
 
  783   { 
return !option.
match(label); }
 
  785 template <
typename Choices>
 
  787   std::string 
const& label,
 
  790   { 
return option != label; }
 
  794 template <
typename Choices>
 
  795 std::ostream& util::details::operator<<
 
  797   { out << option.
name(); 
return out; }
 
  803 template <
typename Choices>
 
  804 template <
typename... Options>
 
  808   for (
Option_t option: options) addOption(std::move(option));
 
  813 template <
typename Choices>
 
  815   { 
return fOptions.size(); }
 
  819 template <
typename Choices>
 
  821   { 
return fOptions.empty(); }
 
  825 template <
typename Choices>
 
  826 template <
typename... Aliases>
 
  830   return addOption({ 
value, std::move(label), std::move(aliases)... });
 
  835 template <
typename Choices>
 
  836 template <
typename... Aliases>
 
  842   std::size_t 
const index = findOptionIndex(value);
 
  843   if (index >= fOptions.size())
 
  845   recordLabels(index, aliases...);
 
  846   return fOptions[index].addAlias(std::move(aliases)...);
 
  851 template <
typename Choices>
 
  852 template <
typename... Aliases>
 
  858   return addAlias(option.
value(), std::move(aliases)...);
 
  863 template <
typename Choices>
 
  865   { 
return findOption(value) != fOptions.end(); }
 
  869 template <
typename Choices>
 
  871   (std::string 
const& label) 
const 
  873   return fLabelToOptionIndex.find(label) != fLabelToOptionIndex.end();
 
  878 template <
typename Choices>
 
  881   { 
return hasOption(option.
value()); }
 
  885 template <
typename Choices>
 
  889   auto const iOption = findOption(value);
 
  890   if (iOption == fOptions.end())
 
  897 template <
typename Choices>
 
  901   auto const iLabelIndexPair = fLabelToOptionIndex.find(label);
 
  902   if (iLabelIndexPair == fLabelToOptionIndex.end()) {
 
  905   assert(iLabelIndexPair->second < fOptions.size());
 
  906   return fOptions[iLabelIndexPair->second];
 
  911 template <
typename Choices>
 
  913   (std::string 
const& label) 
const -> 
Option_t const&
 
  920 template <
typename Choices>
 
  922   (std::string 
const& sep ) 
const 
  924   using namespace std::string_literals;
 
  926   auto iOption = fOptions.begin();
 
  927   auto const oend = fOptions.end();
 
  929   if (iOption == oend) 
return "<no options>"s;
 
  931   std::string 
s { *iOption };
 
  932   while (++iOption != oend) {
 
  941 template <
typename Choices>
 
  943   (std::string 
const& indent, std::string 
const& firstIndent) 
const 
  945   using namespace std::string_literals;
 
  947   auto iOption = fOptions.begin();
 
  948   auto const oend = fOptions.end();
 
  950   if (iOption == oend) 
return firstIndent + 
"<no options>\n"s;
 
  952   std::string 
s { firstIndent };
 
  953   s += iOption->dump();
 
  955   while (++iOption != oend) {
 
  957     s += iOption->dump();
 
  965 template <
typename Choices>
 
  969   std::size_t 
const newOptionIndex = 
size();
 
  971   fOptions.push_back(std::move(option));
 
  972   Option_t const& newOption = fOptions.back();
 
  974   for (
auto iLabel = 
labels.begin(); iLabel != 
labels.end(); ++iLabel) {
 
  976       recordLabel(std::string{ *iLabel }, newOptionIndex);
 
  984       for (
auto iNewLabel = 
labels.begin(); iNewLabel != iLabel; ++iNewLabel)
 
  985         unregisterLabel(*iNewLabel);
 
 1000 template <
typename Choices>
 
 1002   (std::string&& label, std::size_t index)
 
 1005   auto const iOption = fLabelToOptionIndex.lower_bound(label);
 
 1012   if ((iOption != fLabelToOptionIndex.end())
 
 1013     && !OptionLabelMap_t::key_compare()(label, iOption->first))
 
 1019   fLabelToOptionIndex.emplace_hint(iOption, std::move(label), index);
 
 1025 template <
typename Choices>
 
 1026 template <
typename... Aliases>
 
 1028   (std::size_t index, std::string alias, Aliases... moreAliases)
 
 1032     recordLabel(std::move(alias), index);
 
 1033     if constexpr(
sizeof...(moreAliases) > 0U)
 
 1034       recordLabels(index, std::move(moreAliases)...);
 
 1037     unregisterLabel(alias); 
 
 1044 template <
typename Choices>
 
 1046   (std::string 
const& label)
 
 1047   { fLabelToOptionIndex.erase(label); }
 
 1051 template <
typename Choices>
 
 1053   -> 
typename OptionList_t::const_iterator
 
 1055   auto const matchValue
 
 1057   return std::find_if(fOptions.begin(), fOptions.end(), matchValue);
 
 1062 template <
typename Choices>
 
 1064   -> 
typename OptionList_t::iterator
 
 1066   auto const matchValue
 
 1068   return std::find_if(fOptions.begin(), fOptions.end(), matchValue);
 
 1073 template <
typename Choices>
 
 1077   auto const d = 
static_cast<std::size_t
> 
 1079   return (d >= 
size())? npos: d;
 
 1084 template <
typename Choices>
 
 1086   (std::string 
const& label) 
const 
 1088   auto const iOption = fLabelToOptionIndex.find(label);
 
 1089   return (iOption == fLabelToOptionIndex.end())? npos: iOption->second;
 
 1094 template <
typename Choices>
 
 1096   auto const iOption = findOption(value);
 
 1097   if (iOption == fOptions.end()) {
 
 1109 #endif // LARDATAALG_UTILITIES_MULTIPLECHOICESELECTION_H 
Choices Choices_t
Type of the underlying choice. 
 
Request for unknown option. 
 
std::string const & label() const 
 
bool my_lexicographical_compare(B1 b1, E1 e1, B2 b2, E2 e2, Comp less)
 
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
 
bool hasOption(Choices_t value) const 
Returns whether the selector has an option with the specified value. 
 
std::vector< std::string > const & labels() const 
Returns an iterable object with all the labels of the option. 
 
std::enable_if_t< AllConvertibleToStrings_v< Aliases...>, Option_t & > addAlias(std::string alias, Aliases...moreAliases)
Adds aliases. 
 
OptionLabelMap_t fLabelToOptionIndex
Map from labels to option index in fOptions. 
 
static std::optional< std::string > convert(T const &value)
 
static std::optional< std::string > convert(T const &)
 
Option_t const & parse(std::string const &label) const 
Returns the option matching the specified label. 
 
bool operator==(Option_t const &option) const 
Returns whether the two options are the same (same value and name). 
 
static bool cmp_lower(unsigned char a, unsigned char b)
 
static std::optional< std::string > convert(T const &value)
 
std::string optionListString(std::string const &sep=", ") const 
Returns a string with the (main) name of all options. 
 
void recordLabel(std::string &&label, std::size_t index)
 
std::size_t size(FixedBins< T, C > const &) noexcept
 
Base class of util::MultipleChoiceSelection with basics independent of the option type...
 
static constexpr auto npos
Special value. 
 
Option_t const & addOption(Choices_t value, std::string label, Aliases...aliases)
Adds a new option to the selector. 
 
std::enable_if_t< details::AllConvertibleToStrings_v< Aliases...> > recordLabels(std::size_t index, std::string alias, Aliases...moreAliases)
 
bool operator!=(Option_t const &option) const 
Returns whether the two options are not the same. 
 
Class representing one of the available options to be selected. 
 
Choices_t fValue
The value associated to the option. 
 
std::vector< std::string > fLabels
All the labels. 
 
std::vector< Option_t > OptionList_t
Type of collection of options. 
 
static bool eq_lower(unsigned char a, unsigned char b)
 
OptionAlreadyExistsError()
 
std::string optionListDump(std::string const &indent="") const 
Returns a string with all the options, one per line. 
 
MultipleChoiceSelectionOption_t(Choices_t value, std::string name, Aliases...aliases)
Constructor: assigns value, name and aliases. 
 
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode. 
 
Option_t const & get(Choices_t value) const 
Returns the specified option. 
 
typename std::enable_if< B, T >::type enable_if_t
 
std::map< std::string, std::size_t, details::SorterFrom< details::CaseInsensitiveComparer > > OptionLabelMap_t
Type of label index (associative container: label to option index). 
 
std::string value_as_string() const 
 
void unregisterLabel(std::string const &label)
Removes the specified label from the register. 
 
static std::optional< std::string > convert(T const &value)
 
std::string name() const 
Returns the name of the option (i.e. the main label). 
 
static bool equal(std::string const &a, std::string const &b)
 
bool operator()(std::string const &a, std::string const &b) const 
 
bool equal(double a, double b)
Comparison tolerance, in centimeters. 
 
UnknownOptionError(std::string const &label)
 
constexpr auto AllConvertibleToStrings_v
 
OptionList_t::const_iterator findOption(Choices_t value) const 
Returns an iterator to the option with label, or npos if none. 
 
std::string dump() const 
Returns in a string the name and all the aliases. 
 
bool empty() const 
Returns whether there is no available option. 
 
static constexpr bool can_convert
 
std::string optionListDump(std::string const &indent, std::string const &firstIndent) const 
Returns a string with all the options, one per line. 
 
std::string to_string(WindowPattern const &pattern)
 
then echo File list $list not found else cat $list while read file do echo $file sed s
 
typename make_void< Ts...>::type void_t
 
static bool less(std::string const &a, std::string const &b)
Returns whether a is lexicographically smaller than b. 
 
bool match(std::string const &label) const 
Returns whether this option matches the specified label (name or alias). 
 
OptionAlreadyExistsError(std::string const &label)
 
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker options
 
std::string const & label() const 
 
bool operator!=(infinite_endcount_iterator< T > const &, count_iterator< T > const &)
Never admit a infinite_endcount_iterator to be equal to anything else. 
 
std::size_t findOptionIndex(Choices_t value) const 
Returns the index of the option with label, or npos if none. 
 
Adding an option that already exists. 
 
Helper to select one among multiple choices via strings. 
 
std::size_t size() const 
Returns the number of available options. 
 
static bool equal(std::string const &a, std::string const &b)
Returns whether strings a and b are equal. 
 
std::enable_if_t< details::AllConvertibleToStrings_v< Aliases...>, Option_t const & > addAlias(Choices_t value, Aliases...aliases)
Adds aliases to an existing option. 
 
Exception(std::string const &s)
 
bool operator==(infinite_endcount_iterator< T > const &, count_iterator< T > const &)
 
TimeTrackTreeStorage::TriggerInputSpec_t convert(TimeTrackTreeStorage::Config::TriggerSpecConfig const &config)
 
Choices_t value() const 
Returns a copy of the value of the option. 
 
virtual const char * what() const noexceptoverride
 
OptionList_t fOptions
The list of registered objects. 
 
MultipleChoiceSelection()=default