Exheredludis/paludis/util/graph.hh
Saleem Abdulrasool 64ba7d5be8 modernize: use default method synthesis
Convert a number of destructors to default synthesized functions.  Try to
inline a few instances into the header.  It should be possible to inline all of
them, however, gcc seems to emit a number of warnings.  Furthermore, some of the
destructors are pure-virtualed, but provide an implementation.  Placing the
definition into the header causes ODR violations.
2016-08-06 11:58:04 -07:00

258 lines
6.7 KiB
C++

/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
* Copyright (c) 2007, 2008, 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
*/
#ifndef PALUDIS_GUARD_PALUDIS_UTIL_GRAPH_HH
#define PALUDIS_GUARD_PALUDIS_UTIL_GRAPH_HH 1
#include <paludis/util/graph-fwd.hh>
#include <paludis/util/pimp.hh>
#include <paludis/util/exception.hh>
#include <paludis/util/stringify.hh>
#include <memory>
/** \file
* Declarations for DirectedGraph and related utilities.
*
* \ingroup g_data_structures
*
* \section Examples
*
* - None at this time.
*/
namespace paludis
{
/**
* Base class for DirectedGraph errors.
*
* \ingroup g_data_structures
* \ingroup g_exceptions
* \nosubgrouping
*/
class PALUDIS_VISIBLE GraphError :
public Exception
{
protected:
///\name Basic operations
///\{
GraphError(const std::string & msg) noexcept;
///\}
};
/**
* Thrown if a DirectedGraph operation relies upon a node being present when it is not.
*
* \ingroup g_exceptions
* \ingroup g_data_structures
* \nosubgrouping
*/
class PALUDIS_VISIBLE NoSuchGraphNodeError :
public GraphError
{
public:
///\name Basic operations
///\{
template <typename Node_>
NoSuchGraphNodeError(const Node_ & node) noexcept :
GraphError("Node '" + stringify(node) + "' does not exist")
{
}
template <typename Node_>
NoSuchGraphNodeError(const std::shared_ptr<Node_> & node) noexcept :
GraphError("Node '" + stringify(*node) + "' does not exist")
{
}
///\}
};
/**
* Thrown if a DirectedGraph operation relies upon an edge being present when it is not.
*
* \ingroup g_exceptions
* \ingroup g_data_structures
* \nosubgrouping
*/
class PALUDIS_VISIBLE NoSuchGraphEdgeError :
public GraphError
{
public:
///\name Basic operations
///\{
template <typename Node_>
NoSuchGraphEdgeError(const Node_ & e1, const Node_ & e2) noexcept :
GraphError("Edge '" + stringify(e1) + "' -> '" + stringify(e2) + "' does not exist")
{
}
///\}
};
/**
* Thrown if no ordering is available for a DirectedGraph::topological_sort.
*
* \ingroup g_data_structures
* \ingroup g_exceptions
* \nosubgrouping
*/
class PALUDIS_VISIBLE NoGraphTopologicalOrderExistsError :
public GraphError
{
public:
class RemainingNodes;
private:
std::shared_ptr<const RemainingNodes> _remaining_nodes;
public:
///\name Basic operations
///\{
NoGraphTopologicalOrderExistsError(const std::shared_ptr<const RemainingNodes> &) noexcept;
~NoGraphTopologicalOrderExistsError() = default;
///\}
/**
* The nodes remaining in the graph.
*/
std::shared_ptr<const RemainingNodes> remaining_nodes() const;
};
/**
* A simple directed graph.
*
* \ingroup g_data_structures
* \nosubgrouping
*/
template <typename Node_, typename Edge_, typename Comparator_>
class PALUDIS_VISIBLE DirectedGraph
{
private:
Pimp<DirectedGraph<Node_, Edge_, Comparator_> > _imp;
void operator= (const DirectedGraph &);
public:
///\name Basic operations
///\{
DirectedGraph();
DirectedGraph(const DirectedGraph &);
~DirectedGraph();
///\}
///\name Node related functions
///\{
/**
* Add a node, if it does not already exist.
*/
void add_node(const Node_ &);
/**
* Delete a node, if it exists.
*/
void delete_node(const Node_ &);
/**
* Return whether a node exists.
*/
bool has_node(const Node_ &) const;
///\}
///\name Iterate over our nodes
///\{
class NodeConstIterator;
NodeConstIterator begin_nodes() const;
NodeConstIterator end_nodes() const;
///\}
///\name Edge related functions
///\{
/**
* Add an edge, if it does not already exist.
*
* \throw NoSuchGraphNodeError if either node is not in the graph.
*/
void add_edge(const Node_ &, const Node_ &, const Edge_ &);
/**
* Delete an edge, if it exists.
*/
void delete_edge(const Node_ &, const Node_ &);
/**
* Delete all edges leaving a node.
*/
void delete_outgoing_edges(const Node_ &);
/**
* Delete all edges entering a node.
*/
void delete_incoming_edges(const Node_ &);
/**
* Return whether an edge exists.
*/
bool has_edge(const Node_ &, const Node_ &) const;
/**
* Fetch an edge.
*
* \throw NoSuchGraphEdgeError if the edge does not exist.
*/
const Edge_ fetch_edge(const Node_ &, const Node_ &) const;
/**
* Return whether a node has outgoing edges.
*
* \throw NoSuchGraphNodeError if the node does not exist.
*/
bool has_outgoing_edges(const Node_ &) const;
///\}
///\name Ordering functions
///\{
/**
* Place our nodes, topological sorted, into OutputIterator_.
*
* \throw NoGraphTopologicalOrderExistsError if no such order exists.
*/
template <typename OutputIterator_>
void topological_sort(OutputIterator_ i) const;
///\}
};
}
#endif