patterncppMinor
Container for list of ranges
Viewed 0 times
rangeslistforcontainer
Problem
I made a C++ container of an ordered list of integers, that, in order to save space, I save as ranges:
For example, the list \$ \{1,2,3,5,6,7,8,9,20\} \$ is saved in memory as \$ \{(1,3), (5,9), (20,20)\} \$.
I have doubts of the iterator used to show all the numbers that are include on one list is right. Mainly because my iterator doesn't allow to modify elements on the container.
And in general, I wrote it in C++11.
```
template::value>::type>
class RangeListIterator; // undefined
template
class RangeListIterator{
public:
using value_type = T;
using RangeItem = std::pair;
using RangeItemList = std::list;
using RangeItem_iterator = typename RangeItemList::iterator;
RangeListIterator( RangeItem_iterator it, value_type val,
RangeItem_iterator itEnd );
bool operator!=( const RangeListIterator & b ) const;
RangeListIterator& operator++();
RangeListIterator operator++( int );
const value_type& operator*() const;
private:
RangeItem_iterator m_listIt;
RangeItem_iterator m_listEnd;
value_type m_val;
};
template
RangeListIterator::RangeListIterator( RangeItem_iterator it,
value_type val,
RangeItem_iterator itEnd)
: m_listIt{ it }, m_listEnd{ itEnd }, m_val{ val }
{
// empty
}
template
bool RangeListIterator::operator!=( const RangeListIterator & b ) const{
return (m_listIt != b.m_listIt) or (m_val != b.m_val);
}
template
RangeListIterator& RangeListIterator::operator++() {
if( m_val == std::numeric_limits::max() ){
++m_listIt;
m_val = 0;
}else{
++m_val;
if( m_val > m_listIt->second ){
++m_listIt;
if( m_listIt == m_listEnd ){
m_val = 0;
}else{
m_val = m_listIt->first;
}
}
}
return *this;
}
template
RangeListIterator RangeListIterator::operator++( int ) {
auto t
For example, the list \$ \{1,2,3,5,6,7,8,9,20\} \$ is saved in memory as \$ \{(1,3), (5,9), (20,20)\} \$.
I have doubts of the iterator used to show all the numbers that are include on one list is right. Mainly because my iterator doesn't allow to modify elements on the container.
And in general, I wrote it in C++11.
```
template::value>::type>
class RangeListIterator; // undefined
template
class RangeListIterator{
public:
using value_type = T;
using RangeItem = std::pair;
using RangeItemList = std::list;
using RangeItem_iterator = typename RangeItemList::iterator;
RangeListIterator( RangeItem_iterator it, value_type val,
RangeItem_iterator itEnd );
bool operator!=( const RangeListIterator & b ) const;
RangeListIterator& operator++();
RangeListIterator operator++( int );
const value_type& operator*() const;
private:
RangeItem_iterator m_listIt;
RangeItem_iterator m_listEnd;
value_type m_val;
};
template
RangeListIterator::RangeListIterator( RangeItem_iterator it,
value_type val,
RangeItem_iterator itEnd)
: m_listIt{ it }, m_listEnd{ itEnd }, m_val{ val }
{
// empty
}
template
bool RangeListIterator::operator!=( const RangeListIterator & b ) const{
return (m_listIt != b.m_listIt) or (m_val != b.m_val);
}
template
RangeListIterator& RangeListIterator::operator++() {
if( m_val == std::numeric_limits::max() ){
++m_listIt;
m_val = 0;
}else{
++m_val;
if( m_val > m_listIt->second ){
++m_listIt;
if( m_listIt == m_listEnd ){
m_val = 0;
}else{
m_val = m_listIt->first;
}
}
}
return *this;
}
template
RangeListIterator RangeListIterator::operator++( int ) {
auto t
Solution
A fairly minor point, but I'm not a huge fan of using
range_iter.cpp: In function 'int main()':
range_iter.cpp:53:21: error: no type named 'type' in 'struct std::enable_if'
RangeList double_range;
range_iter.cpp:53:21: error: template argument 2 is invalid
range_iter.cpp:53:35: error: invalid type in declaration before ';' token
RangeList double_range;
This also requires adding "clutter" like:
Instead, I'd rather just use a
This has the benefit of cutting down on the above clutter, as well as giving nicer compiler error messages:
range_iter.hpp: In instantiation of 'class RangeList':
range_iter.cpp:53:23: required from here
range_iter.hpp:92:5: error: static assertion failed: T must be an integral type!
static_assert(std::is_integral::value, "T must be an integral type!");
enable_if here. For example, if we declare a RangeList, we'll get the following as errors:range_iter.cpp: In function 'int main()':
range_iter.cpp:53:21: error: no type named 'type' in 'struct std::enable_if'
RangeList double_range;
range_iter.cpp:53:21: error: template argument 2 is invalid
range_iter.cpp:53:35: error: invalid type in declaration before ';' token
RangeList double_range;
This also requires adding "clutter" like:
template::value>::type>
class RangeListIterator; // undefined
template::value>::type>
class RangeList; // undefinedInstead, I'd rather just use a
static_assert at the top of each class:static_assert(std::is_integral::value, "T must be an integral type!");This has the benefit of cutting down on the above clutter, as well as giving nicer compiler error messages:
range_iter.hpp: In instantiation of 'class RangeList':
range_iter.cpp:53:23: required from here
range_iter.hpp:92:5: error: static assertion failed: T must be an integral type!
static_assert(std::is_integral::value, "T must be an integral type!");
Code Snippets
template<typename T,
typename = typename std::enable_if<std::is_integral<T>::value>::type>
class RangeListIterator; // undefined
template<typename T,
typename = typename std::enable_if<std::is_integral<T>::value>::type>
class RangeList; // undefinedstatic_assert(std::is_integral<T>::value, "T must be an integral type!");Context
StackExchange Code Review Q#46739, answer score: 5
Revisions (0)
No revisions yet.