/*
* Copyright 2012 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3, as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranties of
* MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 3 along with this program. If not, see
*
*
* Authored by: Sam Spilsbury
*
*/
#ifndef _UNITY_ABSTRACT_INTERFACE_GENERATOR_H
#define _UNITY_ABSTRACT_INTERFACE_GENERATOR_H
#include
#include
namespace unity
{
namespace internal
{
template
class ReverseWrapper
{
private:
ConcreteCollection const& collection_;
public:
ReverseWrapper(ConcreteCollection const& collection)
: collection_(collection)
{
}
decltype(collection_.rbegin ()) begin() const { return collection_.rbegin(); }
decltype(collection_.rend ()) end () const { return collection_.rend(); }
};
}
/*
* This can be passed to objects which want to visit some interfaces
* they can use from a collection of concrete objects they do not need
* to know about
*/
template
class AbstractInterfaceGenerator
{
public:
typedef std::shared_ptr > Ptr;
typedef std::function InterfaceVisitor;
virtual ~AbstractInterfaceGenerator () {}
virtual void VisitEachInterface (InterfaceVisitor const& visit) = 0;
virtual void VisitEachInterfaceReverse (InterfaceVisitor const& visit) = 0;
};
/*
* This is a helper template to retrieve abstract interfaces from collections
* containing concrete types. For example a CompWindowList or CompWindowVector
* for which you might want to retreive a relevant FooInterface from each
* element.
*/
template
class AbstractInterfaceCollectionGenerator :
public AbstractInterfaceGenerator
{
public:
typedef AbstractInterfaceGenerator InterfaceGenerator;
typedef typename InterfaceGenerator::InterfaceVisitor Visitor;
typedef std::function
ElementRetrievalFunc;
AbstractInterfaceCollectionGenerator (ConcreteCollection const& collection,
ElementRetrievalFunc const& retrieval)
: collection_(collection)
, retrieval_(retrieval)
{
}
void VisitEachInterface(Visitor const& visit)
{
VisitEachInterfaceInternal(collection_, visit);
}
void VisitEachInterfaceReverse(Visitor const& visit)
{
VisitEachInterfaceInternal(internal::ReverseWrapper (collection_), visit);
}
private:
template
void VisitEachInterfaceInternal(Container const& container,
Visitor const& visit)
{
for (typename ConcreteCollection::value_type const& item : container)
{
AbstractInterface& interface (retrieval_ (item));
visit (interface);
}
}
ConcreteCollection const& collection_;
ElementRetrievalFunc retrieval_;
};
}
#endif