As an extension to this question Are const_iterators faster?, I have another question on const_iterators
. How to remove constness of a const_iterator
I thought it would be fun to come up with a solution to this that works for containers that aren't in the standard library and don't include the erase() method.
Attempting to use this causes Visual Studio 2013 to hang on compile. I'm not including the test case because leaving it to readers who can quickly figure out the interface seems like a good idea; I don't know why this hangs on compile. This occurs even when the const_iterator is equal to begin().
// deconst.h
#ifndef _miscTools_deconst
#define _miscTools_deconst
#ifdef _WIN32
#include
#endif
namespace miscTools
{
template < typename T >
struct deconst
{
static inline typename T::iterator iterator ( typename T::const_iterator*&& target, T*&& subject )
{
typename T::iterator && resultant = subject->begin ( );
bool goodItty = process < 0, T >::step ( std::move ( target ), std::move ( &resultant ), std::move ( subject ) );
#ifdef _WIN32
// This is just my habit with test code, and would normally be replaced by an assert
if ( goodItty == false )
{
OutputDebugString ( " ERROR: deconst::iterator call. Target iterator is not within the bounds of the subject container.\n" )
}
#endif
return std::move ( resultant );
}
private:
template < std::size_t i, typename T >
struct process
{
static inline bool step ( typename T::const_iterator*&& target, typename T::iterator*&& variant, T*&& subject )
{
if ( ( static_cast ( subject->begin () + i ) ) == *target )
{
( *variant ) += i;
return true;
}
else
{
if ( ( *variant + i ) < subject->end () )
{
process < ( i + 1 ), T >::step ( std::move ( target ), std::move ( variant ), std::move ( subject ) );
}
else { return false; }
}
}
};
};
}
#endif