19template<
class SetA,
class SetB,
typename Compare = std::less<>>
21share_element(SetA&& setA, SetB&& setB, Compare comp = Compare{}){
22 auto xA = setA.begin();
23 auto xB = setB.begin();
24 while (xA != setA.end() && xB != setB.end()){
27 }
else if (
comp(*xB, *xA)) {
42 if (--indices)
return std::bit_width(indices);
57 if (v.size()==1)
return 0;
63 auto it = std::ranges::find(v, value);
64 if (it != v.end())
return std::distance(v.begin(), it);
77 return (std::ranges::find(v, value)!=v.end());
94 set(minimum, maximum);
108 previous = current - 1;
124 previous = current - 1;
131 previous = values.back();
142 previous = values[
index];
173 if ((
index == values.size() - 1) || (
index == 0 && current != values.front())) {
175 next = values.front();
186 next = values[
index];
195 if (
m_empty or other.m_empty)
return true;
201 if (
isBounded() and other.isEnumerated() ){
203 for (
const auto & v:
ev) {
209 for (
const auto & v:
ev){
210 if ((v >= other.m_minimum) and (v <= other.m_maximum))
return (
true);
216 return share_element(
get_values(), other.get_values());
238 if (minimum == maximum) {
257 if (std::ranges::binary_search(*p, value))
return;
259 std::ranges::sort(*p);
276 std::ranges::sort (*p);
326 set(other.get_values ());
343IdentifierField::operator std::string ()
const {
348 const auto & [minimum, maximum] =
get_minmax();
349 if (minimum == maximum) {
350 result = std::to_string(minimum);
360 result = std::format(
"{}:{}", minimum, maximum);
362 catch (
const std::format_error& e) {
375 if (
m_data != other.m_data)
return false;
384 std::cout <<
"values ";
386 std::cout << v <<
" ";
388 std::cout <<
"indexes ";
390 std::cout << idx <<
" ";
392 std::cout <<
"indices " <<
m_size <<
" ";
394 std::cout <<
"next " <<
m_next <<
" ";
395 std::cout <<
"mode ";
397 std::cout <<
"unbounded ";
399 std::cout <<
"both_bounded ";
401 std::cout <<
"enumerated ";
403 std::cout <<
"cont mode ";
406 std::cout <<
"none ";
409 std::cout <<
"has_next ";
412 std::cout <<
"has_previous ";
415 std::cout <<
"has_both ";
418 std::cout <<
"has_wrap_around ";
421 std::cout << std::endl;
461 m_indexes = std::vector<size_type>(size, 0);
464 auto &v = std::get<element_vector>(
m_data);
465 for (
const auto & thisValue: v) {
466 if (
const auto idx=(thisValue -
m_minimum); idx < (int)size) {
470 std::cout <<
"size, value, index, i "
471 << size <<
" " << thisValue <<
" "
472 <<
index <<
" " << i++ <<
" min, max "
491 while (std::isspace(is.peek())){is.ignore();}
497 if (c ==
'+') is.ignore();
503 std::vector<int>
vec(1,v);
505 vec.insert(
vec.end(), restOfList.begin(), restOfList.end());
507 }
else if (c ==
':'){
518 std::string
msg{
"Stream extraction for IdentifierField: "};
522 throw std::invalid_argument(
msg);
std::vector< size_t > vec
std::ostream & operator<<(std::ostream &out, const IdentifierField &c)
std::istream & operator>>(std::istream &is, IdentifierField &idf)
boost::container::small_vector< element_type, 12 >::size_type size_type
This is the individual specification for the range of one ExpandedIdentifier IdentifierField.
ExpandedIdentifier::size_type size_type
bool operator==(const IdentifierField &other) const
static constexpr auto minimum_possible
IdentifierField()=default
Create a wild-card value.
size_type get_indices() const
std::pair< element_type, element_type > BoundedRange
void set_previous(int previous)
bool get_previous(element_type current, element_type &previous) const
Returns false if previous/next is at end of range, or not possible.
void add_value(element_type value)
void set(element_type minimum, element_type maximum)
static constexpr auto maximum_possible
bool overlaps_with(const IdentifierField &other) const
Check whether two IdentifierFields overlap (Are there any values which satisfy the constraints of bot...
std::vector< element_type > element_vector
std::pair< element_type, element_type > get_minmax() const
continuation_mode m_continuation_mode
bool check_for_both_bounded()
Check mode - switch from enumerated to both_bounded if possible.
size_type get_value_index(element_type value) const
bool isEnumerated() const
void operator|=(const IdentifierField &other)
Find the union of two fields.
void optimize()
Optimize - try to switch mode to both_bounded, set up lookup table for finding index from value.
bool get_next(element_type current, element_type &next) const
ExpandedIdentifier::element_type element_type
void create_index_table()
Create index table from value table.
bool match(element_type value) const
The basic match operation Given a value, test to see if it satisfies the constraints for this field.
static constexpr int m_maxNumberOfIndices
element_type get_value_at(size_type index) const
const element_vector & get_values() const
size_type get_bits() const
Return the number of bits needed to store a value of this field.
std::variant< element_vector, BoundedRange > m_data
bool isDigit(const char c)
IdentifierField::element_type parseStreamDigits(std::istream &is)
IdentifierField::element_vector parseStreamList(std::istream &is)
DataModel_detail::iterator< DVL > unique(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of unique for DataVector/List.