25 #ifndef INCLUDED_ValueOrRange_h_GUID_CAAC3116_82B6_4FB9_D32D_BC3391D2D072
26 #define INCLUDED_ValueOrRange_h_GUID_CAAC3116_82B6_4FB9_D32D_BC3391D2D072
32 #include <boost/iterator/iterator_facade.hpp>
33 #include <boost/assert.hpp>
37 #include <type_traits>
44 template <
typename ValueType>
45 class ValueOrRangeIterator
46 :
public boost::iterator_facade<
47 ValueOrRangeIterator<ValueType>, ValueType const,
48 boost::forward_traversal_tag, ValueType const> {
50 ValueOrRangeIterator() =
delete;
51 explicit ValueOrRangeIterator(ValueType initial)
55 friend class boost::iterator_core_access;
56 void increment() { m_value++; }
58 bool equal(ValueOrRangeIterator
const &other)
const {
59 return this->m_value == other.m_value;
62 ValueType
const dereference()
const {
return m_value; }
71 typedef ValueType value_type;
72 typedef detail::ValueOrRangeIterator<ValueType> const_iterator;
73 typedef const_iterator iterator;
75 typedef ValueType size_type;
77 static_assert(std::is_integral<ValueType>::value,
78 "Ranges only available with integral types");
93 static ValueOrRange RangeMaxMin(ValueType maxVal, ValueType minVal) {
99 template <
typename T>
bool contains(T val)
const {
100 static_assert(std::is_integral<T>::value,
101 "Ranges only available with integral types");
102 return !empty() && getMin() <= val && val <= getMax();
108 ValueType getMin()
const {
109 BOOST_ASSERT_MSG(!empty(),
"Should only call if not empty!");
116 ValueType getMax()
const {
117 BOOST_ASSERT_MSG(!empty(),
"Should only call if not empty!");
122 bool isValue()
const {
return (m_begin + 1) == m_end; }
125 bool isNonEmptyRange()
const {
return m_end > (m_begin + 1); }
129 bool empty()
const {
return m_begin == 0 && m_end == 0; }
131 size_type
size()
const {
return m_end - m_begin; }
133 value_type getValue()
const {
134 BOOST_ASSERT_MSG(isValue(),
"Should only call getValue if you know "
135 "it's an initialized value!");
140 void setValue(ValueType val) {
159 void setRangeMaxMin(ValueType maxVal, ValueType minVal = 0) {
160 if (minVal > maxVal) {
176 auto newMax = std::min(this->getMax(), other.getMax());
177 auto newMin = std::max(this->getMin(), other.getMin());
178 other.setRangeMaxMin(newMax, newMin);
184 void extendRangeToMax(ValueType maxVal) {
186 throw std::logic_error(
187 "Can't extend an empty range with a new max!");
189 if (maxVal >= m_end) {
196 const_iterator begin()
const {
return const_iterator(m_begin); }
200 const_iterator end()
const {
return const_iterator(m_end); }
204 explicit ValueOrRange(ValueType val) : m_begin(val) { m_setMax(val); }
207 ValueOrRange(ValueType maxVal, ValueType minVal) : m_begin(minVal) {
208 if (maxVal >= minVal) {
215 void m_setMax(ValueType maxVal) {
222 bool m_isInitialized;
228 #endif // INCLUDED_ValueOrRange_h_GUID_CAAC3116_82B6_4FB9_D32D_BC3391D2D072
apply_list< quote< or_ >, transform< Haystack, detail::is_< Needle >>> contains
Determines if type Needle is in the list Haystack - is an alias for a type that inherits std::true_ty...
Class providing a unified container-like interface to either a single value or a range of integers...
The main namespace for all C++ elements of the framework, internal and external.
detail::size< coerce_list< Ts...>> size
Get the size of a list (number of elements.)