You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Cigarette/Cigarette/MvIMPACT/common/STLHelper.h

361 lines
13 KiB
C++

//-----------------------------------------------------------------------------
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
//
// This software is provided by MATRIX VISION GmbH "as is"
// and any express or implied warranties, including, but not limited to, the
// implied warranties of merchantability and fitness for a particular purpose
// are disclaimed.
//
// In no event shall MATRIX VISION GmbH be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused and
// on any theory of liability, whether in contract, strict liability, or tort
// (including negligence or otherwise) arising in any way out of the use of
// this software, even if advised of the possibility of such damage.
//-----------------------------------------------------------------------------
#ifndef STLHelperH
#define STLHelperH STLHelperH
//-----------------------------------------------------------------------------
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <functional>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
//=============================================================================
//==================== std::pair related stuff ================================
//=============================================================================
//-----------------------------------------------------------------------------
template<class _Ty1, class _Ty2>
const _Ty1& GetFirst( const std::pair<_Ty1, _Ty2>& data )
//-----------------------------------------------------------------------------
{
return data.first;
}
//-----------------------------------------------------------------------------
template<class _Ty1, class _Ty2>
const _Ty2& GetSecond( const std::pair<_Ty1, _Ty2>& data )
//-----------------------------------------------------------------------------
{
return data.second;
}
//-----------------------------------------------------------------------------
template<class _Ty1, class _Ty2>
void DeleteFirst( std::pair<_Ty1, _Ty2>& data )
//-----------------------------------------------------------------------------
{
delete data.first;
data.first = 0;
}
//-----------------------------------------------------------------------------
template<class _Ty1, class _Ty2>
void DeleteSecond( std::pair<_Ty1, _Ty2>& data )
//-----------------------------------------------------------------------------
{
delete data.second;
data.second = 0;
}
//-----------------------------------------------------------------------------
template<class _Ty1, class _Ty2>
class ContainsFirst : public std::unary_function<std::pair<_Ty1, _Ty2>, bool>
//-----------------------------------------------------------------------------
{
std::map<_Ty1, _Ty2> m_;
public:
explicit ContainsFirst( const std::map<_Ty1, _Ty2>& m ) : m_( m ) {}
bool operator()( const std::pair<_Ty1, _Ty2>& x )
{
return m_.find( x.first ) != m_.end();
}
};
//-----------------------------------------------------------------------------
template<class _Ty1, class _Ty2>
class FirstMatches : public std::unary_function<std::pair<_Ty1, _Ty2>, bool>
//-----------------------------------------------------------------------------
{
std::pair<_Ty1, _Ty2> value_;
FirstMatches<_Ty1, _Ty2>& operator=( const FirstMatches<_Ty1, _Ty2>& ); // do not allow assignments
public:
explicit FirstMatches( const std::pair<_Ty1, _Ty2>& val ) : value_( val ) {}
bool operator()( const std::pair<_Ty1, _Ty2>& x )
{
return x.first == value_.first;
}
};
//-----------------------------------------------------------------------------
template<class _Ty1, class _Ty2>
class SecondMatches : public std::unary_function<std::pair<_Ty1, _Ty2>, bool>
//-----------------------------------------------------------------------------
{
std::pair<_Ty1, _Ty2> value_;
SecondMatches<_Ty1, _Ty2>& operator=( const SecondMatches<_Ty1, _Ty2>& ); // do not allow assignments
public:
explicit SecondMatches( const std::pair<_Ty1, _Ty2>& val ) : value_( val ) {}
bool operator()( const std::pair<_Ty1, _Ty2>& x )
{
return x.second == value_.second;
}
};
//-----------------------------------------------------------------------------
template<typename _Ty1, typename _Ty2>
bool SecondSmaller( const std::pair<_Ty1, _Ty2>& a, const std::pair<_Ty1, _Ty2>& b )
//-----------------------------------------------------------------------------
{
if( a.second < b.second )
{
return true;
}
if( a.second > b.second )
{
return false;
}
return ( a.first < b.first );
}
//=============================================================================
//==================== various ================================================
//=============================================================================
//-----------------------------------------------------------------------------
template<class _Ty>
void DeleteElement( _Ty& data )
//-----------------------------------------------------------------------------
{
delete data;
data = 0;
}
//-----------------------------------------------------------------------------
template<class _Ty>
void DeleteArrayElement( _Ty& data )
//-----------------------------------------------------------------------------
{
delete [] data;
data = 0;
}
//-----------------------------------------------------------------------------
/// \brief Proxy reference for ObjectDeleter copying.
template<class _Ty>
struct ObjectDeleterReference
//-----------------------------------------------------------------------------
{
// construct from generic pointer to ObjectDeleter pointer
explicit ObjectDeleterReference( _Ty* rhs ) : pReference_( rhs ) {}
_Ty* pReference_; // generic pointer to ObjectDeleter pointer
};
//-----------------------------------------------------------------------------
/// \brief Simple wrapper class to make sure an object is deleted at the end of the scope
/**
* This of course could also be done using std::auto_ptr but as this template has been
* declared deprecated it causes new compilers to spit out warnings/failures.
*
* The nice way of doing this would be by the use of std::unique_ptr these days but then
* the client code would force people to have a C++11 or greater compliant compiler...
*/
template<class _Ty>
class ObjectDeleter
//-----------------------------------------------------------------------------
{
_Ty* pObject_;
public:
explicit ObjectDeleter( _Ty* pObject = 0 ) : pObject_( pObject ) {}
/// \brief Pass ownership to the new object.
ObjectDeleter( ObjectDeleter<_Ty>& rhs ) : pObject_( rhs.release() ) {}
~ObjectDeleter()
{
DeleteElement( pObject_ );
}
/// \brief Pass ownership. Old buffer on the left hand side object is
/// freed, the lhs object takes ownership of the pointer of the rhs object.
ObjectDeleter<_Ty>& operator=( ObjectDeleter<_Ty>& rhs )
{
if( this != &rhs )
{
DeleteElement( pObject_ );
pObject_ = rhs.release();
}
return *this;
}
template<class _Other>
operator ObjectDeleterReference<_Other>()
{
// convert to compatible ObjectDeleterReference
_Other* p = pObject_; // test implicit conversion
ObjectDeleterReference<_Other> reference( p );
pObject_ = 0; // pass ownership to ObjectDeleterReference
return ( reference );
}
ObjectDeleter<_Ty>& operator=( ObjectDeleterReference<_Ty> rhs )
{
// assign compatible rhs.pReference_ (assume pointer)
_Ty* p = rhs.pReference_;
rhs.pReference_ = 0;
reset( p );
return ( *this );
}
operator _Ty* ()
{
return pObject_;
}
_Ty* operator->()
{
return pObject_;
}
_Ty* get( void )
{
return pObject_;
}
const _Ty* get( void ) const
{
return pObject_;
}
_Ty* release( void )
{
_Ty* p = pObject_;
pObject_ = 0;
return p;
}
void reset( _Ty* pObject = 0 )
{
if( pObject_ != pObject )
{
DeleteElement( pObject_ );
pObject_ = pObject;
}
}
};
//-----------------------------------------------------------------------------
/// This could in theory be accomplished with a call to the for_each template:
///
/// for_each( s.begin(), s.end(), ptr_fun(DeleteElement<_Ty*>) );
///
/// But some ports of the STL always return const_iterators for sets (e.g. gcc 4.1.2)
template<class _Ty>
void ClearSetWithHeapAllocatedKeys( std::set<_Ty>& s )
//-----------------------------------------------------------------------------
{
typename std::set<_Ty>::iterator it = s.begin();
typename std::set<_Ty>::iterator itEnd = s.end();
while( it != itEnd )
{
delete *it;
++it;
}
s.clear();
}
//-----------------------------------------------------------------------------
/// \brief Assigns a new value to a variable when this objects goes out of scope.
///
/// Can be useful if a variable must be set to a defined value at the end of a
/// code block that might rise an exception.
template<class T>
class VarScopeMod
//-----------------------------------------------------------------------------
{
T& var_;
T valAtEndOfScope_;
VarScopeMod( const VarScopeMod& ); // do not allow copy constructor
VarScopeMod& operator=( const VarScopeMod& ); // do not allow assignments
public:
explicit VarScopeMod( T& var, T valAtEndOfScope ) : var_( var ), valAtEndOfScope_( valAtEndOfScope ) {}
explicit VarScopeMod( T& var, T valWithinScope, T valAtEndOfScope ) : var_( var ), valAtEndOfScope_( valAtEndOfScope )
{
var = valWithinScope;
}
~VarScopeMod()
{
var_ = valAtEndOfScope_;
}
};
//-----------------------------------------------------------------------------
template<class T>
void removeDuplicates( T& container )
//-----------------------------------------------------------------------------
{
std::sort( container.begin(), container.end() );
typename T::iterator it = std::unique( container.begin(), container.end() );
container.erase( it, container.end() );
}
//-----------------------------------------------------------------------------
template<class _Elem>
_Elem mv_tolower( _Elem c )
//-----------------------------------------------------------------------------
{
return static_cast<_Elem>( tolower( c ) );
}
//-----------------------------------------------------------------------------
template<class _Elem, class _Traits, class _Ax>
void makeLowerCase(
/// The string to convert
std::basic_string<_Elem, _Traits, _Ax>& s )
//-----------------------------------------------------------------------------
{
std::transform( s.begin(), s.end(), s.begin(), std::ptr_fun<_Elem, _Elem>( mv_tolower ) );
}
//-----------------------------------------------------------------------------
template<class _Elem, class _Traits, class _Ax>
std::basic_string<_Elem, _Traits, _Ax> makeLowerCase(
/// The string to convert
const std::basic_string<_Elem, _Traits, _Ax>& s )
//-----------------------------------------------------------------------------
{
std::basic_string<_Elem, _Traits, _Ax> lc( s );
std::transform( lc.begin(), lc.end(), lc.begin(), std::ptr_fun<_Elem, _Elem>( mv_tolower ) );
return lc;
}
//-----------------------------------------------------------------------------
template<class _Elem>
_Elem mv_toupper( _Elem c )
//-----------------------------------------------------------------------------
{
return static_cast<_Elem>( toupper( c ) );
}
//-----------------------------------------------------------------------------
template<class _Elem, class _Traits, class _Ax>
void makeUpperCase(
/// The string to convert
std::basic_string<_Elem, _Traits, _Ax>& s )
//-----------------------------------------------------------------------------
{
std::transform( s.begin(), s.end(), s.begin(), std::ptr_fun<_Elem, _Elem>( mv_toupper ) );
}
//-----------------------------------------------------------------------------
template<class _Elem, class _Traits, class _Ax>
std::basic_string<_Elem, _Traits, _Ax> makeUpperCase(
/// The string to convert
const std::basic_string<_Elem, _Traits, _Ax>& s )
//-----------------------------------------------------------------------------
{
std::basic_string<_Elem, _Traits, _Ax> uc( s );
std::transform( uc.begin(), uc.end(), uc.begin(), std::ptr_fun<_Elem, _Elem>( mv_toupper ) );
return uc;
}
#endif // STLHelperH