Your IP : 216.73.216.48
| Current Path : /usr/include/grantlee/ |
|
|
| Current File : //usr/include/grantlee/containeraccessor.h |
/*
This file is part of the Grantlee template system.
Copyright (c) 2010 Stephen Kelly <steveire@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either version
2.1 of the Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONTAINERACCESSOR_H
#define CONTAINERACCESSOR_H
#include <QtCore/QVariant>
#include <map>
namespace Grantlee
{
/// @headerfile containeraccessor.h grantlee/containeraccessor.h
/**
@internal Used as a convenience base class for container %iterator access.
*/
template<typename Container_>
struct Getter
{
/**
* @internal Used to extract a list from the container.
*/
typedef Container_ Container;
};
/// @headerfile containeraccessor.h grantlee/containeraccessor.h
/**
Trait for retrieving a key from a container %iterator.
This can be trivially specialized in rare cases if supporting a third party container.
@see @ref third_party_containers
*/
template<typename Container>
struct KeyGetter : public Getter<Container>
{
/**
Returns the key available through the container %iterator @p it.
*/
static typename Container::key_type get( const typename Container::const_iterator it ) {
return it.key();
}
};
/// @headerfile containeraccessor.h grantlee/containeraccessor.h
/**
Trait for retrieving a mapped value from a container %iterator.
This can be trivially specialized in rare cases if supporting a third party container.
@see @ref third_party_containers
*/
template<typename Container>
struct MappedValueGetter : public Getter<Container>
{
/**
Returns the key available through the container %iterator @p it.
*/
static typename Container::mapped_type get( const typename Container::const_iterator it ) {
return *it;
}
};
#ifndef Q_QDOC
template<typename T, typename U>
struct KeyGetter<std::map<T, U> > : public Getter<std::map<T, U> >
{
static T get( typename std::map<T, U>::const_iterator it ) {
return it->first;
}
};
template<typename T, typename U>
struct MappedValueGetter<std::map<T, U> > : public Getter<std::map<T, U> >
{
static U get( typename std::map<T, U>::const_iterator it ) {
return it->second;
}
};
template<typename Container>
struct ValueGetter : public Getter<Container>
{
static typename Container::value_type get( const typename Container::const_iterator it ) {
return *it;
}
};
template<typename Container, typename T = typename Container::key_type>
struct Finder
{
static typename Container::const_iterator find( const Container &container, const QString &nextPart )
{
{
// Compile error if key_type is not a number.
static const QString s = QString::number( T() );
Q_UNUSED( s )
}
QVariant v = nextPart;
if ( !v.convert( QVariant::Double ) )
return container.end();
typename Container::key_type key = v.value<typename Container::key_type>();
return container.find( key );
}
};
template<typename Container>
struct Finder<Container, QString>
{
static typename Container::const_iterator find( const Container &container, const QString &nextPart )
{
return container.find( nextPart );
}
};
#endif
namespace {
template<typename Getter>
QVariantList getList( const QVariant &obj )
{
const typename Getter::Container c = obj.value<typename Getter::Container>();
typename Getter::Container::const_iterator it = c.begin();
const typename Getter::Container::const_iterator end = c.end();
QVariantList list;
#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0))
list.reserve( static_cast<int>( std::distance( it, end ) ) );
#endif
for ( ; it != end; ++it ) {
list << QVariant::fromValue( Getter::get( it ) );
}
return list;
}
template<typename Container>
struct SequentialContainerAccessor
{
static QVariantList doToList( const QVariant &obj )
{
return getList<ValueGetter<Container> >( obj );
}
};
template<>
struct SequentialContainerAccessor<QVariantList>
{
static QVariantList doToList( const QVariant &obj )
{
return obj.toList();
}
};
template<typename Container>
struct AssociativeContainerAccessor
{
static QVariantList doToList( const QVariant &obj )
{
return getList<KeyGetter<Container> >( obj );
}
};
}
}
#endif