/* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* * Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011 Ciaran McCreesh * * This file is part of the Paludis package manager. Paludis is free software; * you can redistribute it and/or modify it under the terms of the GNU General * Public License version 2, as published by the Free Software Foundation. * * Paludis 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 General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace paludis; namespace paludis { template struct Imp > { const Environment * const env; const std::shared_ptr package_id; std::list > specs; std::set recursing_sets; Imp(const Environment * const e, const std::shared_ptr & i) : env(e), package_id(i) { } }; template <> struct WrappedForwardIteratorTraits::ConstIteratorTag> { typedef std::list >::const_iterator UnderlyingIterator; }; template <> struct WrappedForwardIteratorTraits::ConstIteratorTag> { typedef std::list >::const_iterator UnderlyingIterator; }; template <> struct WrappedForwardIteratorTraits::ConstIteratorTag> { typedef std::list >::const_iterator UnderlyingIterator; }; } template DepSpecFlattener::DepSpecFlattener( const Environment * const env, const std::shared_ptr & id) : _imp(env, id) { } template DepSpecFlattener::~DepSpecFlattener() { } template typename DepSpecFlattener::ConstIterator DepSpecFlattener::begin() const { return ConstIterator(_imp->specs.begin()); } template typename DepSpecFlattener::ConstIterator DepSpecFlattener::end() const { return ConstIterator(_imp->specs.end()); } namespace { template struct HandleNamedSet { inline static void handle(const typename Heirarchy_::template NodeType::Type &, DepSpecFlattener &) { } }; template struct HandleNamedSet { inline static void handle(const typename Heirarchy_::template NodeType::Type & node, DepSpecFlattener & f) { f.template handle_named_set(*node.spec()); } }; } template void DepSpecFlattener::visit(const typename Heirarchy_::template NodeType::Type & node) { HandleNamedSet::Type>::value>::handle(node, *this); } namespace { template struct HandleItem { inline static void handle(const typename Heirarchy_::template NodeType::Type &, DepSpecFlattener &) { } }; template struct HandleItem { inline static void handle(const typename Heirarchy_::template NodeType::Type & node, DepSpecFlattener & f) { f.handle_item(*node.spec()); } }; } template void DepSpecFlattener::visit(const typename Heirarchy_::template NodeType::Type & node) { HandleItem::Type>::value>::handle(node, *this); } template void DepSpecFlattener::visit(const typename Heirarchy_::template NodeType::Type & node) { HandleItem::Type>::value>::handle(node, *this); } template void DepSpecFlattener::visit(const typename Heirarchy_::template NodeType::Type & node) { HandleItem::Type>::value>::handle(node, *this); } template void DepSpecFlattener::visit(const typename Heirarchy_::template NodeType::Type &) { } template void DepSpecFlattener::visit(const typename Heirarchy_::template NodeType::Type & node) { std::for_each(indirect_iterator(node.begin()), indirect_iterator(node.end()), accept_visitor(*this)); } namespace { template struct HandleAny { inline static void handle(const typename Heirarchy_::template NodeType::Type &, DepSpecFlattener &) { } }; template struct HandleAny { inline static void handle(const typename Heirarchy_::template NodeType::Type & node, DepSpecFlattener & f) { std::for_each(indirect_iterator(node.begin()), indirect_iterator(node.end()), accept_visitor(f)); } }; } template void DepSpecFlattener::visit(const typename Heirarchy_::template NodeType::Type & node) { HandleAny::Type>::value>::handle(node, *this); } namespace { template struct HandleConditional { inline static void handle(const typename Heirarchy_::template NodeType::Type &, DepSpecFlattener &, const Environment * const, const std::shared_ptr &) { } }; template struct HandleConditional { inline static void handle(const typename Heirarchy_::template NodeType::Type & node, DepSpecFlattener & f, const Environment * const env, const std::shared_ptr & id) { if (node.spec()->condition_met(env, id)) std::for_each(indirect_iterator(node.begin()), indirect_iterator(node.end()), accept_visitor(f)); } }; } template void DepSpecFlattener::visit(const typename Heirarchy_::template NodeType::Type & node) { HandleConditional::Type>::value>::handle( node, *this, _imp->env, _imp->package_id); } template template void DepSpecFlattener::handle_named_set(const NamedSetDepSpec & spec) { if (! _imp->recursing_sets.insert(spec.name()).second) throw RecursivelyDefinedSetError(stringify(spec.name())); std::shared_ptr set(_imp->env->set(spec.name())); if (! set) throw NoSuchSetError(stringify(spec.name())); set->top()->accept(*this); _imp->recursing_sets.erase(spec.name()); } template void DepSpecFlattener::handle_item(const Item_ & spec) { _imp->specs.push_back(std::static_pointer_cast(spec.clone())); } namespace paludis { template class DepSpecFlattener; template class DepSpecFlattener; template class DepSpecFlattener; template class WrappedForwardIterator::ConstIteratorTag, const std::shared_ptr >; template class WrappedForwardIterator::ConstIteratorTag, const std::shared_ptr >; template class WrappedForwardIterator::ConstIteratorTag, const std::shared_ptr >; }