Test and verify patches

This commit is contained in:
Antony Polukhin
2013-10-30 16:00:43 +04:00
parent 83e02d83c4
commit 868328d2f6
27 changed files with 562 additions and 7682 deletions

2
.gitignore vendored
View File

@ -374,4 +374,4 @@
/more/
/status/
/tools/
stage/
/stage/

5
patched/README.md Normal file
View File

@ -0,0 +1,5 @@
patches for Boost libraries to work without RTTI
==========
Here are the patches that are TESTED and work well with RTTI disabled and enabled.
Patches add tests for some of the libraries to make sure that library compile and work without RTTI.

View File

@ -1,239 +0,0 @@
// See http://www.boost.org/libs/any for Documentation.
#ifndef BOOST_ANY_INCLUDED
#define BOOST_ANY_INCLUDED
// what: variant type boost::any
// who: contributed by Kevlin Henney,
// with features contributed and bugs found by
// Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
// when: July 2001
// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
#include <algorithm>
#include <typeinfo>
#include "boost/config.hpp"
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/throw_exception.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_index.hpp>
namespace boost
{
class any
{
public: // structors
any()
: content(0)
{
}
template<typename ValueType>
any(const ValueType & value)
: content(new holder<ValueType>(value))
{
}
any(const any & other)
: content(other.content ? other.content->clone() : 0)
{
}
~any()
{
delete content;
}
public: // modifiers
any & swap(any & rhs)
{
std::swap(content, rhs.content);
return *this;
}
template<typename ValueType>
any & operator=(const ValueType & rhs)
{
any(rhs).swap(*this);
return *this;
}
any & operator=(any rhs)
{
rhs.swap(*this);
return *this;
}
public: // queries
bool empty() const
{
return !content;
}
type_index type() const
{
return content ? content->type() : type_id<void>();
}
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
private: // types
#else
public: // types (public so any_cast can be non-friend)
#endif
class placeholder
{
public: // structors
virtual ~placeholder()
{
}
public: // queries
virtual type_index type() const = 0;
virtual placeholder * clone() const = 0;
};
template<typename ValueType>
class holder : public placeholder
{
public: // structors
holder(const ValueType & value)
: held(value)
{
}
public: // queries
virtual type_index type() const
{
return type_id<ValueType>();
}
virtual placeholder * clone() const
{
return new holder(held);
}
public: // representation
ValueType held;
private: // intentionally left unimplemented
holder & operator=(const holder &);
};
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
private: // representation
template<typename ValueType>
friend ValueType * any_cast(any *);
template<typename ValueType>
friend ValueType * unsafe_any_cast(any *);
#else
public: // representation (public so any_cast can be non-friend)
#endif
placeholder * content;
};
class bad_any_cast : public std::bad_cast
{
public:
virtual const char * what() const throw()
{
return "boost::bad_any_cast: "
"failed conversion using boost::any_cast";
}
};
template<typename ValueType>
ValueType * any_cast(any * operand)
{
return operand &&
operand->type() == type_id<ValueType>()
? &static_cast<any::holder<ValueType> *>(operand->content)->held
: 0;
}
template<typename ValueType>
inline const ValueType * any_cast(const any * operand)
{
return any_cast<ValueType>(const_cast<any *>(operand));
}
template<typename ValueType>
ValueType any_cast(any & operand)
{
typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// If 'nonref' is still reference type, it means the user has not
// specialized 'remove_reference'.
// Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
// to generate specialization of remove_reference for your class
// See type traits library documentation for details
BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
#endif
nonref * result = any_cast<nonref>(&operand);
if(!result)
boost::throw_exception(bad_any_cast());
return *result;
}
template<typename ValueType>
inline ValueType any_cast(const any & operand)
{
typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// The comment in the above version of 'any_cast' explains when this
// assert is fired and what to do.
BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
#endif
return any_cast<const nonref &>(const_cast<any &>(operand));
}
// Note: The "unsafe" versions of any_cast are not part of the
// public interface and may be removed at any time. They are
// required where we know what type is stored in the any and can't
// use type_id<>() comparison, e.g., when our types may travel across
// different shared libraries.
template<typename ValueType>
inline ValueType * unsafe_any_cast(any * operand)
{
return &static_cast<any::holder<ValueType> *>(operand->content)->held;
}
template<typename ValueType>
inline const ValueType * unsafe_any_cast(const any * operand)
{
return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
}
}
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#endif

12
patched/any/Jamfile.patch Normal file
View File

@ -0,0 +1,12 @@
Index: .
===================================================================
--- . (revision 86520)
+++ . (working copy)
@@ -8,6 +8,7 @@
test-suite any :
[ run ../any_test.cpp ]
+ [ run ../any_test.cpp : : : <rtti>off : testing_any_no_rtti ]
[ run any_test_rv.cpp ]
[ compile-fail any_cast_cv_failed.cpp ]
[ compile-fail any_test_temporary_to_ref_failed.cpp ]

91
patched/any/any.patch Normal file
View File

@ -0,0 +1,91 @@
Index: .
===================================================================
--- . (revision 86520)
+++ . (working copy)
@@ -15,7 +15,7 @@
// when: July 2001, April 2013 - May 2013
#include <algorithm>
-#include <typeinfo>
+#include <boost/type_index/type_info.hpp>
#include "boost/config.hpp"
#include <boost/type_traits/remove_reference.hpp>
@@ -29,17 +29,6 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_const.hpp>
-// See boost/python/type_id.hpp
-// TODO: add BOOST_TYPEID_COMPARE_BY_NAME to config.hpp
-# if defined(__GNUC__) \
- || defined(_AIX) \
- || ( defined(__sgi) && defined(__host_mips)) \
- || (defined(__hpux) && defined(__HP_aCC)) \
- || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
-# define BOOST_AUX_ANY_TYPE_ID_NAME
-#include <cstring>
-# endif
-
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable: 4172) // Mistakenly warns: returning address of local variable or temporary
@@ -149,9 +138,9 @@
any().swap(*this);
}
- const std::type_info & type() const BOOST_NOEXCEPT
+ const boost::type_info & type() const BOOST_NOEXCEPT
{
- return content ? content->type() : typeid(void);
+ return content ? content->type() : boost::type_id<void>();
}
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
@@ -170,7 +159,7 @@
public: // queries
- virtual const std::type_info & type() const BOOST_NOEXCEPT = 0;
+ virtual const boost::type_info & type() const BOOST_NOEXCEPT = 0;
virtual placeholder * clone() const = 0;
@@ -194,9 +183,9 @@
#endif
public: // queries
- virtual const std::type_info & type() const BOOST_NOEXCEPT
+ virtual const boost::type_info & type() const BOOST_NOEXCEPT
{
- return typeid(ValueType);
+ return boost::type_id<ValueType>();
}
virtual placeholder * clone() const
@@ -237,7 +226,12 @@
lhs.swap(rhs);
}
- class BOOST_SYMBOL_VISIBLE bad_any_cast : public std::bad_cast
+ class BOOST_SYMBOL_VISIBLE bad_any_cast :
+#ifndef BOOST_NO_RTTI
+ public std::bad_cast
+#else
+ public std::exception
+#endif
{
public:
virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
@@ -251,11 +245,7 @@
ValueType * any_cast(any * operand) BOOST_NOEXCEPT
{
return operand &&
-#ifdef BOOST_AUX_ANY_TYPE_ID_NAME
- std::strcmp(operand->type().name(), typeid(ValueType).name()) == 0
-#else
- operand->type() == typeid(ValueType)
-#endif
+ operand->type() == boost::type_id<ValueType>()
? &static_cast<any::holder<ValueType> *>(operand->content)->held
: 0;
}

View File

@ -0,0 +1,61 @@
Index: .
===================================================================
--- . (revision 86520)
+++ . (working copy)
@@ -91,7 +91,10 @@
check_true(value.empty(), "empty");
check_null(any_cast<int>(&value), "any_cast<int>");
+#ifndef BOOST_NO_RTTI
check_equal(value.type(), typeid(void), "type");
+#endif
+ check_equal(value.type(), boost::type_id<void>(), "type boost");
}
void test_converting_ctor()
@@ -100,7 +103,10 @@
any value = text;
check_false(value.empty(), "empty");
+#ifndef BOOST_NO_RTTI
check_equal(value.type(), typeid(std::string), "type");
+#endif
+ check_equal(value.type(), boost::type_id<std::string>(), "type boost");
check_null(any_cast<int>(&value), "any_cast<int>");
check_non_null(any_cast<std::string>(&value), "any_cast<std::string>");
check_equal(
@@ -158,7 +164,10 @@
any * assign_result = &(value = text);
check_false(value.empty(), "type");
+#ifndef BOOST_NO_RTTI
check_equal(value.type(), typeid(std::string), "type");
+#endif
+ check_equal(value.type(), boost::type_id<std::string>(), "type boost");
check_null(any_cast<int>(&value), "any_cast<int>");
check_non_null(any_cast<std::string>(&value), "any_cast<std::string>");
check_equal(
@@ -191,7 +200,10 @@
check_true(original.empty(), "empty on original");
check_false(swapped.empty(), "empty on swapped");
+#ifndef BOOST_NO_RTTI
check_equal(swapped.type(), typeid(std::string), "type");
+#endif
+ check_equal(swapped.type(), boost::type_id<std::string>(), "type boost");
check_equal(
text, any_cast<std::string>(swapped),
"comparing swapped copy against original text");
@@ -264,8 +276,12 @@
check_false(value1.empty(), "type");
check_false(value2.empty(), "type");
+#ifndef BOOST_NO_RTTI
check_equal(value1.type(), typeid(const char*), "type");
check_equal(value2.type(), typeid(const char*), "type");
+#endif
+ check_equal(value1.type(), boost::type_id<const char*>(), "type boost");
+ check_equal(value2.type(), boost::type_id<const char*>(), "type boost");
check_non_null(any_cast<const char*>(&value1), "any_cast<const char*>");
check_non_null(any_cast<const char*>(&value2), "any_cast<const char*>");

View File

@ -1,135 +0,0 @@
#ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
#define BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_typeinfo.hpp
//
// Copyright 2007 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#if defined( BOOST_NO_TYPEID )
#include <boost/current_function.hpp>
#include <functional>
namespace boost
{
namespace detail
{
class sp_typeinfo
{
private:
sp_typeinfo( sp_typeinfo const& );
sp_typeinfo& operator=( sp_typeinfo const& );
char const * name_;
public:
explicit sp_typeinfo( char const * name ): name_( name )
{
}
bool operator==( sp_typeinfo const& rhs ) const
{
return this == &rhs;
}
bool operator!=( sp_typeinfo const& rhs ) const
{
return this != &rhs;
}
bool before( sp_typeinfo const& rhs ) const
{
return std::less< sp_typeinfo const* >()( this, &rhs );
}
char const* name() const
{
return name_;
}
};
template<class T> struct sp_typeid_
{
static sp_typeinfo ti_;
static char const * name()
{
return BOOST_CURRENT_FUNCTION;
}
};
#if defined(__SUNPRO_CC)
// see #4199, the Sun Studio compiler gets confused about static initialization
// constructor arguments. But an assignment works just fine.
template<class T> sp_typeinfo sp_typeid_< T >::ti_ = sp_typeid_< T >::name();
#else
template<class T> sp_typeinfo sp_typeid_< T >::ti_(sp_typeid_< T >::name());
#endif
template<class T> struct sp_typeid_< T & >: sp_typeid_< T >
{
};
template<class T> struct sp_typeid_< T const >: sp_typeid_< T >
{
};
template<class T> struct sp_typeid_< T volatile >: sp_typeid_< T >
{
};
template<class T> struct sp_typeid_< T const volatile >: sp_typeid_< T >
{
};
} // namespace detail
} // namespace boost
#define BOOST_SP_TYPEID(T) (boost::detail::sp_typeid_<T>::ti_)
#else
#include <typeinfo>
namespace boost
{
namespace detail
{
#if defined( BOOST_NO_STD_TYPEINFO )
typedef ::type_info sp_typeinfo;
#else
typedef std::type_info sp_typeinfo;
#endif
} // namespace detail
} // namespace boost
#define BOOST_SP_TYPEID(T) typeid(T)
#endif
#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED

View File

@ -0,0 +1,23 @@
Index: .
===================================================================
--- . (revision 86520)
+++ . (working copy)
@@ -59,6 +59,10 @@
/boost/test//boost_test_exec_monitor/<link>static
../build//boost_graph
../../regex/build//boost_regex : --log_level=all ]
+ [ run graphviz_test.cpp
+ /boost/test//boost_test_exec_monitor/<link>static
+ ../build//boost_graph
+ ../../regex/build//boost_regex : --log_level=all : : <rtti>off : testing_graphviz_no_rtti ]
[ run metis_test.cpp : $(METIS_INPUT_FILE) ]
[ run gursoy_atun_layout_test.cpp ]
[ run layout_test.cpp : : : <test-info>always_show_run_output <toolset>intel:<debug-symbols>off ]
@@ -124,6 +128,7 @@
[ run two_graphs_common_spanning_trees_test.cpp ]
[ run random_spanning_tree_test.cpp ../build//boost_graph ]
[ run graphml_test.cpp ../build//boost_graph : : "graphml_test.xml" ]
+ [ run graphml_test.cpp ../build//boost_graph : : "graphml_test.xml" : <rtti>off : testing_graphml_no_rtti ]
[ run mas_test.cpp ../../test/build//boost_unit_test_framework/<link>static : $(TEST_DIR) ]
[ run stoer_wagner_test.cpp ../../test/build//boost_unit_test_framework/<link>static : $(TEST_DIR) ]
[ compile filtered_graph_properties_dijkstra.cpp ]

View File

@ -1,352 +0,0 @@
// Copyright (C) 2006 Tiago de Paula Peixoto <tiago@forked.de>
// Copyright (C) 2004 The Trustees of Indiana University.
//
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Authors: Douglas Gregor
// Andrew Lumsdaine
// Tiago de Paula Peixoto
#ifndef BOOST_GRAPH_GRAPHML_HPP
#define BOOST_GRAPH_GRAPHML_HPP
#include <boost/config.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/any.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/graph/dll_import_export.hpp>
#include <boost/graph/graphviz.hpp> // for exceptions
#include <boost/type_index.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/find.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/property_tree/detail/xml_parser_utils.hpp>
#include <boost/throw_exception.hpp>
#include <exception>
#include <sstream>
namespace boost
{
/////////////////////////////////////////////////////////////////////////////
// Graph reader exceptions
/////////////////////////////////////////////////////////////////////////////
struct parse_error: public graph_exception
{
parse_error(const std::string& err) {error = err; statement = "parse error: " + error;}
virtual ~parse_error() throw() {}
virtual const char* what() const throw() {return statement.c_str();}
std::string statement;
std::string error;
};
class mutate_graph
{
public:
virtual ~mutate_graph() {}
virtual bool is_directed() const = 0;
virtual boost::any do_add_vertex() = 0;
virtual std::pair<boost::any,bool> do_add_edge(boost::any source, boost::any target) = 0;
virtual void
set_graph_property(const std::string& name, const std::string& value, const std::string& value_type) = 0;
virtual void
set_vertex_property(const std::string& name, boost::any vertex, const std::string& value, const std::string& value_type) = 0;
virtual void
set_edge_property(const std::string& name, boost::any edge, const std::string& value, const std::string& value_type) = 0;
};
template<typename MutableGraph>
class mutate_graph_impl : public mutate_graph
{
typedef typename graph_traits<MutableGraph>::vertex_descriptor vertex_descriptor;
typedef typename graph_traits<MutableGraph>::edge_descriptor edge_descriptor;
public:
mutate_graph_impl(MutableGraph& g, dynamic_properties& dp)
: m_g(g), m_dp(dp) { }
bool is_directed() const
{
return is_convertible<typename graph_traits<MutableGraph>::directed_category,
directed_tag>::value;
}
virtual any do_add_vertex()
{
return any(add_vertex(m_g));
}
virtual std::pair<any,bool> do_add_edge(any source, any target)
{
std::pair<edge_descriptor,bool> retval = add_edge(any_cast<vertex_descriptor>(source),
any_cast<vertex_descriptor>(target), m_g);
return std::make_pair(any(retval.first), retval.second);
}
virtual void
set_graph_property(const std::string& name, const std::string& value, const std::string& value_type)
{
bool type_found = false;
try
{
mpl::for_each<value_types>(put_property<MutableGraph,value_types>
(name, m_dp, m_g, value, value_type, m_type_names, type_found));
}
catch (bad_lexical_cast)
{
BOOST_THROW_EXCEPTION(
parse_error("invalid value \"" + value + "\" for key " +
name + " of type " + value_type));
}
if (!type_found)
{
BOOST_THROW_EXCEPTION(
parse_error("unrecognized type \"" + value_type +
"\" for key " + name));
}
}
virtual void
set_vertex_property(const std::string& name, any vertex, const std::string& value, const std::string& value_type)
{
bool type_found = false;
try
{
mpl::for_each<value_types>(put_property<vertex_descriptor,value_types>
(name, m_dp, any_cast<vertex_descriptor>(vertex),
value, value_type, m_type_names, type_found));
}
catch (bad_lexical_cast)
{
BOOST_THROW_EXCEPTION(
parse_error("invalid value \"" + value + "\" for key " +
name + " of type " + value_type));
}
if (!type_found)
{
BOOST_THROW_EXCEPTION(
parse_error("unrecognized type \"" + value_type +
"\" for key " + name));
}
}
virtual void
set_edge_property(const std::string& name, any edge, const std::string& value, const std::string& value_type)
{
bool type_found = false;
try
{
mpl::for_each<value_types>(put_property<edge_descriptor,value_types>
(name, m_dp, any_cast<edge_descriptor>(edge),
value, value_type, m_type_names, type_found));
}
catch (bad_lexical_cast)
{
BOOST_THROW_EXCEPTION(
parse_error("invalid value \"" + value + "\" for key " +
name + " of type " + value_type));
}
if (!type_found)
{
BOOST_THROW_EXCEPTION(
parse_error("unrecognized type \"" + value_type +
"\" for key " + name));
}
}
template <typename Key, typename ValueVector>
class put_property
{
public:
put_property(const std::string& name, dynamic_properties& dp, const Key& key,
const std::string& value, const std::string& value_type,
const char** type_names, bool& type_found)
: m_name(name), m_dp(dp), m_key(key), m_value(value),
m_value_type(value_type), m_type_names(type_names),
m_type_found(type_found) {}
template <class Value>
void operator()(Value)
{
if (m_value_type == m_type_names[mpl::find<ValueVector,Value>::type::pos::value])
{
put(m_name, m_dp, m_key, lexical_cast<Value>(m_value));
m_type_found = true;
}
}
private:
const std::string& m_name;
dynamic_properties& m_dp;
const Key& m_key;
const std::string& m_value;
const std::string& m_value_type;
const char** m_type_names;
bool& m_type_found;
};
protected:
MutableGraph& m_g;
dynamic_properties& m_dp;
typedef mpl::vector<bool, int, long, float, double, std::string> value_types;
static const char* m_type_names[];
};
template<typename MutableGraph>
const char* mutate_graph_impl<MutableGraph>::m_type_names[] = {"boolean", "int", "long", "float", "double", "string"};
void BOOST_GRAPH_DECL
read_graphml(std::istream& in, mutate_graph& g);
template<typename MutableGraph>
void
read_graphml(std::istream& in, MutableGraph& g, dynamic_properties& dp)
{
mutate_graph_impl<MutableGraph> mg(g,dp);
read_graphml(in, mg);
}
template <typename Types>
class get_type_name
{
public:
get_type_name(const type_index& type, const char** type_names, std::string& type_name)
: m_type(type), m_type_names(type_names), m_type_name(type_name) {}
template <typename Type>
void operator()(Type)
{
if (type_id<Type>() == m_type)
m_type_name = m_type_names[mpl::find<Types,Type>::type::pos::value];
}
private:
const type_index m_type;
const char** m_type_names;
std::string &m_type_name;
};
template <typename Graph, typename VertexIndexMap>
void
write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index,
const dynamic_properties& dp, bool ordered_vertices=false)
{
typedef typename graph_traits<Graph>::directed_category directed_category;
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
using boost::property_tree::xml_parser::encode_char_entities;
BOOST_STATIC_CONSTANT(bool,
graph_is_directed =
(is_convertible<directed_category*, directed_tag*>::value));
out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
<< "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\n";
typedef mpl::vector<bool, short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long, float, double, long double, std::string> value_types;
const char* type_names[] = {"boolean", "int", "int", "int", "int", "long", "long", "long", "long", "float", "double", "double", "string"};
std::map<std::string, std::string> graph_key_ids;
std::map<std::string, std::string> vertex_key_ids;
std::map<std::string, std::string> edge_key_ids;
int key_count = 0;
// Output keys
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
{
std::string key_id = "key" + lexical_cast<std::string>(key_count++);
if (i->second->key() == type_id<Graph*>())
graph_key_ids[i->first] = key_id;
else if (i->second->key() == type_id<vertex_descriptor>())
vertex_key_ids[i->first] = key_id;
else if (i->second->key() == type_id<edge_descriptor>())
edge_key_ids[i->first] = key_id;
else
continue;
std::string type_name = "string";
mpl::for_each<value_types>(get_type_name<value_types>(i->second->value(), type_names, type_name));
out << " <key id=\"" << encode_char_entities(key_id) << "\" for=\""
<< (i->second->key() == type_id<Graph*>() ? "graph" : (i->second->key() == type_id<vertex_descriptor>() ? "node" : "edge")) << "\""
<< " attr.name=\"" << i->first << "\""
<< " attr.type=\"" << type_name << "\""
<< " />\n";
}
out << " <graph id=\"G\" edgedefault=\""
<< (graph_is_directed ? "directed" : "undirected") << "\""
<< " parse.nodeids=\"" << (ordered_vertices ? "canonical" : "free") << "\""
<< " parse.edgeids=\"canonical\" parse.order=\"nodesfirst\">\n";
// Output graph data
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
{
if (i->second->key() == type_id<Graph*>())
{
// The const_cast here is just to get typeid correct for property
// map key; the graph should not be mutated using it.
out << " <data key=\"" << graph_key_ids[i->first] << "\">"
<< encode_char_entities(i->second->get_string(const_cast<Graph*>(&g))) << "</data>\n";
}
}
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
vertex_iterator v, v_end;
for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v)
{
out << " <node id=\"n" << get(vertex_index, *v) << "\">\n";
// Output data
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
{
if (i->second->key() == type_id<vertex_descriptor>())
{
out << " <data key=\"" << vertex_key_ids[i->first] << "\">"
<< encode_char_entities(i->second->get_string(*v)) << "</data>\n";
}
}
out << " </node>\n";
}
typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
edge_iterator e, e_end;
typename graph_traits<Graph>::edges_size_type edge_count = 0;
for (boost::tie(e, e_end) = edges(g); e != e_end; ++e)
{
out << " <edge id=\"e" << edge_count++ << "\" source=\"n"
<< get(vertex_index, source(*e, g)) << "\" target=\"n"
<< get(vertex_index, target(*e, g)) << "\">\n";
// Output data
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
{
if (i->second->key() == type_id<edge_descriptor>())
{
out << " <data key=\"" << edge_key_ids[i->first] << "\">"
<< encode_char_entities(i->second->get_string(*e)) << "</data>\n";
}
}
out << " </edge>\n";
}
out << " </graph>\n"
<< "</graphml>\n";
}
template <typename Graph>
void
write_graphml(std::ostream& out, const Graph& g, const dynamic_properties& dp,
bool ordered_vertices=false)
{
write_graphml(out, g, get(vertex_index, g), dp, ordered_vertices);
}
} // boost namespace
#endif // BOOST_GRAPH_GRAPHML_HPP

View File

@ -0,0 +1,83 @@
Index: .
===================================================================
--- . (revision 86520)
+++ . (working copy)
@@ -18,7 +18,7 @@
#include <boost/type_traits/is_convertible.hpp>
#include <boost/graph/dll_import_export.hpp>
#include <boost/graph/graphviz.hpp> // for exceptions
-#include <typeinfo>
+#include <boost/type_index/type_info.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/find.hpp>
@@ -218,16 +218,16 @@
class get_type_name
{
public:
- get_type_name(const std::type_info& type, const char** type_names, std::string& type_name)
+ get_type_name(const boost::type_info& type, const char** type_names, std::string& type_name)
: m_type(type), m_type_names(type_names), m_type_name(type_name) {}
template <typename Type>
void operator()(Type)
{
- if (typeid(Type) == m_type)
+ if (boost::type_id<Type>() == m_type)
m_type_name = m_type_names[mpl::find<Types,Type>::type::pos::value];
}
private:
- const std::type_info &m_type;
+ const boost::type_info &m_type;
const char** m_type_names;
std::string &m_type_name;
};
@@ -262,18 +262,18 @@
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
{
std::string key_id = "key" + lexical_cast<std::string>(key_count++);
- if (i->second->key() == typeid(Graph*))
+ if (i->second->key() == boost::type_id<Graph*>())
graph_key_ids[i->first] = key_id;
- else if (i->second->key() == typeid(vertex_descriptor))
+ else if (i->second->key() == boost::type_id<vertex_descriptor>())
vertex_key_ids[i->first] = key_id;
- else if (i->second->key() == typeid(edge_descriptor))
+ else if (i->second->key() == boost::type_id<edge_descriptor>())
edge_key_ids[i->first] = key_id;
else
continue;
std::string type_name = "string";
mpl::for_each<value_types>(get_type_name<value_types>(i->second->value(), type_names, type_name));
out << " <key id=\"" << encode_char_entities(key_id) << "\" for=\""
- << (i->second->key() == typeid(Graph*) ? "graph" : (i->second->key() == typeid(vertex_descriptor) ? "node" : "edge")) << "\""
+ << (i->second->key() == boost::type_id<Graph*>() ? "graph" : (i->second->key() == boost::type_id<vertex_descriptor>() ? "node" : "edge")) << "\""
<< " attr.name=\"" << i->first << "\""
<< " attr.type=\"" << type_name << "\""
<< " />\n";
@@ -287,7 +287,7 @@
// Output graph data
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
{
- if (i->second->key() == typeid(Graph*))
+ if (i->second->key() == boost::type_id<Graph*>())
{
// The const_cast here is just to get typeid correct for property
// map key; the graph should not be mutated using it.
@@ -304,7 +304,7 @@
// Output data
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
{
- if (i->second->key() == typeid(vertex_descriptor))
+ if (i->second->key() == boost::type_id<vertex_descriptor>())
{
out << " <data key=\"" << vertex_key_ids[i->first] << "\">"
<< encode_char_entities(i->second->get_string(*v)) << "</data>\n";
@@ -325,7 +325,7 @@
// Output data
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
{
- if (i->second->key() == typeid(edge_descriptor))
+ if (i->second->key() == boost::type_id<edge_descriptor>())
{
out << " <data key=\"" << edge_key_ids[i->first] << "\">"
<< encode_char_entities(i->second->get_string(*e)) << "</data>\n";

View File

@ -0,0 +1,30 @@
Index: .
===================================================================
--- . (revision 86520)
+++ . (working copy)
@@ -16,6 +16,7 @@
#include <iostream>
#include <fstream>
#include <stdio.h> // for FILE
+#include <boost/type_index/type_info.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/graph/graph_traits.hpp>
@@ -489,7 +490,7 @@
bool first = true;
for (dynamic_properties::const_iterator i = dp->begin();
i != dp->end(); ++i) {
- if (typeid(key) == i->second->key()) {
+ if (boost::type_id<Descriptor>() == i->second->key()) {
if (first) out << " [";
else out << ", ";
first = false;
@@ -518,7 +519,7 @@
bool first = true;
for (dynamic_properties::const_iterator i = dp->begin();
i != dp->end(); ++i) {
- if (typeid(key) == i->second->key()
+ if (boost::type_id<Descriptor>() == i->second->key()
&& i->first != *node_id) {
if (first) out << " [";
else out << ", ";

View File

@ -1,858 +0,0 @@
//=======================================================================
// Copyright 2001 University of Notre Dame.
// Copyright 2003 Jeremy Siek
// Authors: Lie-Quan Lee, Jeremy Siek, and Douglas Gregor
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#ifndef BOOST_GRAPHVIZ_HPP
#define BOOST_GRAPHVIZ_HPP
#include <boost/config.hpp>
#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include <stdio.h> // for FILE
#include <boost/property_map/property_map.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/subgraph.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/property_map/dynamic_property_map.hpp>
#include <boost/graph/overloading.hpp>
#include <boost/graph/dll_import_export.hpp>
#include <boost/spirit/include/classic_multi_pass.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/xpressive/xpressive_static.hpp>
#include <boost/foreach.hpp>
#include <boost/type_index.hpp>
namespace boost {
template <typename directed_category>
struct graphviz_io_traits {
static std::string name() {
return "digraph";
}
static std::string delimiter() {
return "->";
} };
template <>
struct graphviz_io_traits <undirected_tag> {
static std::string name() {
return "graph";
}
static std::string delimiter() {
return "--";
}
};
struct default_writer {
void operator()(std::ostream&) const {
}
template <class VorE>
void operator()(std::ostream&, const VorE&) const {
}
};
template <typename T>
inline std::string escape_dot_string(const T& obj) {
using namespace boost::xpressive;
static sregex valid_unquoted_id = (((alpha | '_') >> *_w) | (!as_xpr('-') >> (('.' >> *_d) | (+_d >> !('.' >> *_d)))));
std::string s(boost::lexical_cast<std::string>(obj));
if (regex_match(s, valid_unquoted_id)) {
return s;
} else {
boost::algorithm::replace_all(s, "\"", "\\\"");
return "\"" + s + "\"";
}
}
template <class Name>
class label_writer {
public:
label_writer(Name _name) : name(_name) {}
template <class VertexOrEdge>
void operator()(std::ostream& out, const VertexOrEdge& v) const {
out << "[label=" << escape_dot_string(get(name, v)) << "]";
}
private:
Name name;
};
template <class Name>
inline label_writer<Name>
make_label_writer(Name n) {
return label_writer<Name>(n);
}
enum edge_attribute_t { edge_attribute = 1111 };
enum vertex_attribute_t { vertex_attribute = 2222 };
enum graph_graph_attribute_t { graph_graph_attribute = 3333 };
enum graph_vertex_attribute_t { graph_vertex_attribute = 4444 };
enum graph_edge_attribute_t { graph_edge_attribute = 5555 };
BOOST_INSTALL_PROPERTY(edge, attribute);
BOOST_INSTALL_PROPERTY(vertex, attribute);
BOOST_INSTALL_PROPERTY(graph, graph_attribute);
BOOST_INSTALL_PROPERTY(graph, vertex_attribute);
BOOST_INSTALL_PROPERTY(graph, edge_attribute);
template <class Attribute>
inline void write_attributes(const Attribute& attr, std::ostream& out) {
typename Attribute::const_iterator i, iend;
i = attr.begin();
iend = attr.end();
while ( i != iend ) {
out << i->first << "=" << escape_dot_string(i->second);
++i;
if ( i != iend )
out << ", ";
}
}
template<typename Attributes>
inline void write_all_attributes(Attributes attributes,
const std::string& name,
std::ostream& out)
{
typename Attributes::const_iterator i = attributes.begin(),
end = attributes.end();
if (i != end) {
out << name << " [\n";
write_attributes(attributes, out);
out << "];\n";
}
}
inline void write_all_attributes(detail::error_property_not_found,
const std::string&,
std::ostream&)
{
// Do nothing - no attributes exist
}
template <typename GraphGraphAttributes,
typename GraphNodeAttributes,
typename GraphEdgeAttributes>
struct graph_attributes_writer
{
graph_attributes_writer(GraphGraphAttributes gg,
GraphNodeAttributes gn,
GraphEdgeAttributes ge)
: g_attributes(gg), n_attributes(gn), e_attributes(ge) { }
void operator()(std::ostream& out) const {
write_all_attributes(g_attributes, "graph", out);
write_all_attributes(n_attributes, "node", out);
write_all_attributes(e_attributes, "edge", out);
}
GraphGraphAttributes g_attributes;
GraphNodeAttributes n_attributes;
GraphEdgeAttributes e_attributes;
};
template <typename GAttrMap, typename NAttrMap, typename EAttrMap>
graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap>
make_graph_attributes_writer(const GAttrMap& g_attr, const NAttrMap& n_attr,
const EAttrMap& e_attr) {
return graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap>
(g_attr, n_attr, e_attr);
}
template <typename Graph>
graph_attributes_writer
<typename graph_property<Graph, graph_graph_attribute_t>::type,
typename graph_property<Graph, graph_vertex_attribute_t>::type,
typename graph_property<Graph, graph_edge_attribute_t>::type>
make_graph_attributes_writer(const Graph& g)
{
typedef typename graph_property<Graph, graph_graph_attribute_t>::type
GAttrMap;
typedef typename graph_property<Graph, graph_vertex_attribute_t>::type
NAttrMap;
typedef typename graph_property<Graph, graph_edge_attribute_t>::type
EAttrMap;
GAttrMap gam = get_property(g, graph_graph_attribute);
NAttrMap nam = get_property(g, graph_vertex_attribute);
EAttrMap eam = get_property(g, graph_edge_attribute);
graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap> writer(gam, nam, eam);
return writer;
}
template <typename AttributeMap>
struct attributes_writer {
attributes_writer(AttributeMap attr)
: attributes(attr) { }
template <class VorE>
void operator()(std::ostream& out, const VorE& e) const {
this->write_attribute(out, attributes[e]);
}
private:
template<typename AttributeSequence>
void write_attribute(std::ostream& out,
const AttributeSequence& seq) const
{
if (!seq.empty()) {
out << "[";
write_attributes(seq, out);
out << "]";
}
}
void write_attribute(std::ostream&,
detail::error_property_not_found) const
{
}
AttributeMap attributes;
};
template <typename Graph>
attributes_writer
<typename property_map<Graph, edge_attribute_t>::const_type>
make_edge_attributes_writer(const Graph& g)
{
typedef typename property_map<Graph, edge_attribute_t>::const_type
EdgeAttributeMap;
return attributes_writer<EdgeAttributeMap>(get(edge_attribute, g));
}
template <typename Graph>
attributes_writer
<typename property_map<Graph, vertex_attribute_t>::const_type>
make_vertex_attributes_writer(const Graph& g)
{
typedef typename property_map<Graph, vertex_attribute_t>::const_type
VertexAttributeMap;
return attributes_writer<VertexAttributeMap>(get(vertex_attribute, g));
}
template <typename Graph, typename VertexPropertiesWriter,
typename EdgePropertiesWriter, typename GraphPropertiesWriter,
typename VertexID>
inline void
write_graphviz
(std::ostream& out, const Graph& g,
VertexPropertiesWriter vpw,
EdgePropertiesWriter epw,
GraphPropertiesWriter gpw,
VertexID vertex_id
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag))
{
BOOST_CONCEPT_ASSERT((EdgeListGraphConcept<Graph>));
typedef typename graph_traits<Graph>::directed_category cat_type;
typedef graphviz_io_traits<cat_type> Traits;
std::string name = "G";
out << Traits::name() << " " << escape_dot_string(name) << " {" << std::endl;
gpw(out); //print graph properties
typename graph_traits<Graph>::vertex_iterator i, end;
for(boost::tie(i,end) = vertices(g); i != end; ++i) {
out << escape_dot_string(get(vertex_id, *i));
vpw(out, *i); //print vertex attributes
out << ";" << std::endl;
}
typename graph_traits<Graph>::edge_iterator ei, edge_end;
for(boost::tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) {
out << escape_dot_string(get(vertex_id, source(*ei, g))) << Traits::delimiter() << escape_dot_string(get(vertex_id, target(*ei, g))) << " ";
epw(out, *ei); //print edge attributes
out << ";" << std::endl;
}
out << "}" << std::endl;
}
template <typename Graph, typename VertexPropertiesWriter,
typename EdgePropertiesWriter, typename GraphPropertiesWriter>
inline void
write_graphviz(std::ostream& out, const Graph& g,
VertexPropertiesWriter vpw,
EdgePropertiesWriter epw,
GraphPropertiesWriter gpw
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag))
{ write_graphviz(out, g, vpw, epw, gpw, get(vertex_index, g)); }
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
// ambiguous overload problem with VC++
template <typename Graph>
inline void
write_graphviz(std::ostream& out, const Graph& g
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag))
{
default_writer dw;
default_writer gw;
write_graphviz(out, g, dw, dw, gw);
}
#endif
template <typename Graph, typename VertexWriter>
inline void
write_graphviz(std::ostream& out, const Graph& g, VertexWriter vw
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag))
{
default_writer dw;
default_writer gw;
write_graphviz(out, g, vw, dw, gw);
}
template <typename Graph, typename VertexWriter, typename EdgeWriter>
inline void
write_graphviz(std::ostream& out, const Graph& g,
VertexWriter vw, EdgeWriter ew
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag))
{
default_writer gw;
write_graphviz(out, g, vw, ew, gw);
}
namespace detail {
template <class Graph_, class RandomAccessIterator, class VertexID>
void write_graphviz_subgraph (std::ostream& out,
const subgraph<Graph_>& g,
RandomAccessIterator vertex_marker,
RandomAccessIterator edge_marker,
VertexID vertex_id)
{
typedef subgraph<Graph_> Graph;
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
typedef typename graph_traits<Graph>::directed_category cat_type;
typedef graphviz_io_traits<cat_type> Traits;
typedef typename graph_property<Graph, graph_name_t>::type NameType;
const NameType& g_name = get_property(g, graph_name);
if ( g.is_root() )
out << Traits::name() ;
else
out << "subgraph";
out << " " << escape_dot_string(g_name) << " {" << std::endl;
typename Graph::const_children_iterator i_child, j_child;
//print graph/node/edge attributes
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
typedef typename graph_property<Graph, graph_graph_attribute_t>::type
GAttrMap;
typedef typename graph_property<Graph, graph_vertex_attribute_t>::type
NAttrMap;
typedef typename graph_property<Graph, graph_edge_attribute_t>::type
EAttrMap;
GAttrMap gam = get_property(g, graph_graph_attribute);
NAttrMap nam = get_property(g, graph_vertex_attribute);
EAttrMap eam = get_property(g, graph_edge_attribute);
graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap> writer(gam, nam, eam);
writer(out);
#else
make_graph_attributes_writer(g)(out);
#endif
//print subgraph
for ( boost::tie(i_child,j_child) = g.children();
i_child != j_child; ++i_child )
write_graphviz_subgraph(out, *i_child, vertex_marker, edge_marker,
vertex_id);
// Print out vertices and edges not in the subgraphs.
typename graph_traits<Graph>::vertex_iterator i, end;
typename graph_traits<Graph>::edge_iterator ei, edge_end;
for(boost::tie(i,end) = vertices(g); i != end; ++i) {
Vertex v = g.local_to_global(*i);
int pos = get(vertex_id, v);
if ( vertex_marker[pos] ) {
vertex_marker[pos] = false;
out << escape_dot_string(pos);
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
typedef typename property_map<Graph, vertex_attribute_t>::const_type
VertexAttributeMap;
attributes_writer<VertexAttributeMap> vawriter(get(vertex_attribute,
g.root()));
vawriter(out, v);
#else
make_vertex_attributes_writer(g.root())(out, v);
#endif
out << ";" << std::endl;
}
}
for (boost::tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) {
Vertex u = g.local_to_global(source(*ei,g)),
v = g.local_to_global(target(*ei, g));
int pos = get(get(edge_index, g.root()), g.local_to_global(*ei));
if ( edge_marker[pos] ) {
edge_marker[pos] = false;
out << escape_dot_string(get(vertex_id, u)) << " " << Traits::delimiter()
<< " " << escape_dot_string(get(vertex_id, v));
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
typedef typename property_map<Graph, edge_attribute_t>::const_type
EdgeAttributeMap;
attributes_writer<EdgeAttributeMap> eawriter(get(edge_attribute, g));
eawriter(out, *ei);
#else
make_edge_attributes_writer(g)(out, *ei); //print edge properties
#endif
out << ";" << std::endl;
}
}
out << "}" << std::endl;
}
} // namespace detail
// requires graph_name graph property
template <typename Graph>
void write_graphviz(std::ostream& out, const subgraph<Graph>& g) {
std::vector<bool> edge_marker(num_edges(g), true);
std::vector<bool> vertex_marker(num_vertices(g), true);
detail::write_graphviz_subgraph(out, g,
vertex_marker.begin(),
edge_marker.begin(),
get(vertex_index, g));
}
template <typename Graph>
void write_graphviz(const std::string& filename, const subgraph<Graph>& g) {
std::ofstream out(filename.c_str());
std::vector<bool> edge_marker(num_edges(g), true);
std::vector<bool> vertex_marker(num_vertices(g), true);
detail::write_graphviz_subgraph(out, g,
vertex_marker.begin(),
edge_marker.begin(),
get(vertex_index, g));
}
template <typename Graph, typename VertexID>
void write_graphviz(std::ostream& out, const subgraph<Graph>& g,
VertexID vertex_id)
{
std::vector<bool> edge_marker(num_edges(g), true);
std::vector<bool> vertex_marker(num_vertices(g), true);
detail::write_graphviz_subgraph(out, g,
vertex_marker.begin(),
edge_marker.begin(),
vertex_id);
}
template <typename Graph, typename VertexID>
void write_graphviz(const std::string& filename, const subgraph<Graph>& g,
VertexID vertex_id)
{
std::ofstream out(filename.c_str());
std::vector<bool> edge_marker(num_edges(g), true);
std::vector<bool> vertex_marker(num_vertices(g), true);
detail::write_graphviz_subgraph(out, g,
vertex_marker.begin(),
edge_marker.begin(),
vertex_id);
}
#if 0
// This interface has not worked for a long time
typedef std::map<std::string, std::string> GraphvizAttrList;
typedef property<vertex_attribute_t, GraphvizAttrList>
GraphvizVertexProperty;
typedef property<edge_attribute_t, GraphvizAttrList,
property<edge_index_t, int> >
GraphvizEdgeProperty;
typedef property<graph_graph_attribute_t, GraphvizAttrList,
property<graph_vertex_attribute_t, GraphvizAttrList,
property<graph_edge_attribute_t, GraphvizAttrList,
property<graph_name_t, std::string> > > >
GraphvizGraphProperty;
typedef subgraph<adjacency_list<vecS,
vecS, directedS,
GraphvizVertexProperty,
GraphvizEdgeProperty,
GraphvizGraphProperty> >
GraphvizDigraph;
typedef subgraph<adjacency_list<vecS,
vecS, undirectedS,
GraphvizVertexProperty,
GraphvizEdgeProperty,
GraphvizGraphProperty> >
GraphvizGraph;
// These four require linking the BGL-Graphviz library: libbgl-viz.a
// from the /src directory.
// Library has not existed for a while
extern void read_graphviz(const std::string& file, GraphvizDigraph& g);
extern void read_graphviz(FILE* file, GraphvizDigraph& g);
extern void read_graphviz(const std::string& file, GraphvizGraph& g);
extern void read_graphviz(FILE* file, GraphvizGraph& g);
#endif
class dynamic_properties_writer
{
public:
dynamic_properties_writer(const dynamic_properties& dp) : dp(&dp) { }
template<typename Descriptor>
void operator()(std::ostream& out, Descriptor key) const
{
bool first = true;
for (dynamic_properties::const_iterator i = dp->begin();
i != dp->end(); ++i) {
if (type_id<Descriptor>() == i->second->key()) {
if (first) out << " [";
else out << ", ";
first = false;
out << i->first << "=" << escape_dot_string(i->second->get_string(key));
}
}
if (!first) out << "]";
}
private:
const dynamic_properties* dp;
};
class dynamic_vertex_properties_writer
{
public:
dynamic_vertex_properties_writer(const dynamic_properties& dp,
const std::string& node_id)
: dp(&dp), node_id(&node_id) { }
template<typename Descriptor>
void operator()(std::ostream& out, Descriptor key) const
{
bool first = true;
for (dynamic_properties::const_iterator i = dp->begin();
i != dp->end(); ++i) {
if (type_id<Descriptor>(key) == i->second->key()
&& i->first != *node_id) {
if (first) out << " [";
else out << ", ";
first = false;
out << i->first << "=" << escape_dot_string(i->second->get_string(key));
}
}
if (!first) out << "]";
}
private:
const dynamic_properties* dp;
const std::string* node_id;
};
namespace graph { namespace detail {
template<typename Vertex>
struct node_id_property_map
{
typedef std::string value_type;
typedef value_type reference;
typedef Vertex key_type;
typedef readable_property_map_tag category;
node_id_property_map() {}
node_id_property_map(const dynamic_properties& dp,
const std::string& node_id)
: dp(&dp), node_id(&node_id) { }
const dynamic_properties* dp;
const std::string* node_id;
};
template<typename Vertex>
inline std::string
get(node_id_property_map<Vertex> pm,
typename node_id_property_map<Vertex>::key_type v)
{ return get(*pm.node_id, *pm.dp, v); }
} } // end namespace graph::detail
template<typename Graph>
inline void
write_graphviz_dp(std::ostream& out, const Graph& g,
const dynamic_properties& dp,
const std::string& node_id = "node_id"
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag))
{
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
write_graphviz_dp(out, g, dp, node_id,
graph::detail::node_id_property_map<Vertex>(dp, node_id));
}
template<typename Graph, typename VertexID>
void
write_graphviz_dp(std::ostream& out, const Graph& g,
const dynamic_properties& dp, const std::string& node_id,
VertexID id
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag))
{
write_graphviz
(out, g,
/*vertex_writer=*/dynamic_vertex_properties_writer(dp, node_id),
/*edge_writer=*/dynamic_properties_writer(dp),
/*graph_writer=*/default_writer(),
id);
}
/////////////////////////////////////////////////////////////////////////////
// Graph reader exceptions
/////////////////////////////////////////////////////////////////////////////
struct graph_exception : public std::exception {
virtual ~graph_exception() throw() {}
virtual const char* what() const throw() = 0;
};
struct bad_parallel_edge : public graph_exception {
std::string from;
std::string to;
mutable std::string statement;
bad_parallel_edge(const std::string& i, const std::string& j) :
from(i), to(j) {}
virtual ~bad_parallel_edge() throw() {}
const char* what() const throw() {
if(statement.empty())
statement =
std::string("Failed to add parallel edge: (")
+ from + "," + to + ")\n";
return statement.c_str();
}
};
struct directed_graph_error : public graph_exception {
virtual ~directed_graph_error() throw() {}
virtual const char* what() const throw() {
return
"read_graphviz: "
"Tried to read a directed graph into an undirected graph.";
}
};
struct undirected_graph_error : public graph_exception {
virtual ~undirected_graph_error() throw() {}
virtual const char* what() const throw() {
return
"read_graphviz: "
"Tried to read an undirected graph into a directed graph.";
}
};
struct bad_graphviz_syntax: public graph_exception {
std::string errmsg;
bad_graphviz_syntax(const std::string& errmsg)
: errmsg(errmsg) {}
const char* what() const throw () {return errmsg.c_str();}
~bad_graphviz_syntax() throw () {};
};
namespace detail { namespace graph {
typedef std::string id_t;
typedef id_t node_t;
// edges are not uniquely determined by adjacent nodes
class edge_t {
int idx_;
explicit edge_t(int i) : idx_(i) {}
public:
static edge_t new_edge() {
static int idx = 0;
return edge_t(idx++);
};
bool operator==(const edge_t& rhs) const {
return idx_ == rhs.idx_;
}
bool operator<(const edge_t& rhs) const {
return idx_ < rhs.idx_;
}
};
class mutate_graph
{
public:
virtual ~mutate_graph() {}
virtual bool is_directed() const = 0;
virtual void do_add_vertex(const node_t& node) = 0;
virtual void
do_add_edge(const edge_t& edge, const node_t& source, const node_t& target)
= 0;
virtual void
set_node_property(const id_t& key, const node_t& node, const id_t& value) = 0;
virtual void
set_edge_property(const id_t& key, const edge_t& edge, const id_t& value) = 0;
virtual void // RG: need new second parameter to support BGL subgraphs
set_graph_property(const id_t& key, const id_t& value) = 0;
};
template<typename MutableGraph>
class mutate_graph_impl : public mutate_graph
{
typedef typename graph_traits<MutableGraph>::vertex_descriptor bgl_vertex_t;
typedef typename graph_traits<MutableGraph>::edge_descriptor bgl_edge_t;
public:
mutate_graph_impl(MutableGraph& graph, dynamic_properties& dp,
std::string node_id_prop)
: graph_(graph), dp_(dp), node_id_prop_(node_id_prop) { }
~mutate_graph_impl() {}
bool is_directed() const
{
return
boost::is_convertible<
typename boost::graph_traits<MutableGraph>::directed_category,
boost::directed_tag>::value;
}
virtual void do_add_vertex(const node_t& node)
{
// Add the node to the graph.
bgl_vertex_t v = add_vertex(graph_);
// Set up a mapping from name to BGL vertex.
bgl_nodes.insert(std::make_pair(node, v));
// node_id_prop_ allows the caller to see the real id names for nodes.
put(node_id_prop_, dp_, v, node);
}
void
do_add_edge(const edge_t& edge, const node_t& source, const node_t& target)
{
std::pair<bgl_edge_t, bool> result =
add_edge(bgl_nodes[source], bgl_nodes[target], graph_);
if(!result.second) {
// In the case of no parallel edges allowed
boost::throw_exception(bad_parallel_edge(source, target));
} else {
bgl_edges.insert(std::make_pair(edge, result.first));
}
}
void
set_node_property(const id_t& key, const node_t& node, const id_t& value)
{
put(key, dp_, bgl_nodes[node], value);
}
void
set_edge_property(const id_t& key, const edge_t& edge, const id_t& value)
{
put(key, dp_, bgl_edges[edge], value);
}
void
set_graph_property(const id_t& key, const id_t& value)
{
/* RG: pointer to graph prevents copying */
put(key, dp_, &graph_, value);
}
protected:
MutableGraph& graph_;
dynamic_properties& dp_;
std::string node_id_prop_;
std::map<node_t, bgl_vertex_t> bgl_nodes;
std::map<edge_t, bgl_edge_t> bgl_edges;
};
} } } // end namespace boost::detail::graph
#ifdef BOOST_GRAPH_USE_SPIRIT_PARSER
# ifndef BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS
# define BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS
# endif
# include <boost/graph/detail/read_graphviz_spirit.hpp>
#else // New default parser
# include <boost/graph/detail/read_graphviz_new.hpp>
#endif // BOOST_GRAPH_USE_SPIRIT_PARSER
namespace boost {
// Parse the passed string as a GraphViz dot file.
template <typename MutableGraph>
bool read_graphviz(const std::string& data,
MutableGraph& graph,
dynamic_properties& dp,
std::string const& node_id = "node_id") {
#ifdef BOOST_GRAPH_USE_SPIRIT_PARSER
return read_graphviz_spirit(data.begin(), data.end(), graph, dp, node_id);
#else // Non-Spirit parser
return read_graphviz_new(data,graph,dp,node_id);
#endif
}
// Parse the passed iterator range as a GraphViz dot file.
template <typename InputIterator, typename MutableGraph>
bool read_graphviz(InputIterator user_first,
InputIterator user_last,
MutableGraph& graph,
dynamic_properties& dp,
std::string const& node_id = "node_id") {
#ifdef BOOST_GRAPH_USE_SPIRIT_PARSER
typedef InputIterator is_t;
typedef boost::spirit::classic::multi_pass<is_t> iterator_t;
iterator_t first(boost::spirit::classic::make_multi_pass(user_first));
iterator_t last(boost::spirit::classic::make_multi_pass(user_last));
return read_graphviz_spirit(first, last, graph, dp, node_id);
#else // Non-Spirit parser
return read_graphviz_new(std::string(user_first, user_last), graph, dp, node_id);
#endif
}
// Parse the passed stream as a GraphViz dot file.
template <typename MutableGraph>
bool read_graphviz(std::istream& in, MutableGraph& graph,
dynamic_properties& dp,
std::string const& node_id = "node_id")
{
typedef std::istream_iterator<char> is_t;
in >> std::noskipws;
return read_graphviz(is_t(in), is_t(), graph, dp, node_id);
}
} // namespace boost
#ifdef BOOST_GRAPH_USE_MPI
# include <boost/graph/distributed/graphviz.hpp>
#endif
#endif // BOOST_GRAPHVIZ_HPP

View File

@ -1,615 +0,0 @@
// Copyright 2004 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Peter Gottschling
// Andrew Lumsdaine
#ifndef BOOST_PARALLEL_DISTRIBUTION_HPP
#define BOOST_PARALLEL_DISTRIBUTION_HPP
#ifndef BOOST_GRAPH_USE_MPI
#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
#endif
#include <cstddef>
#include <vector>
#include <algorithm>
#include <numeric>
#include <boost/assert.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/type_index.hpp>
namespace boost { namespace parallel {
template<typename ProcessGroup, typename SizeType = std::size_t>
class variant_distribution
{
public:
typedef typename ProcessGroup::process_id_type process_id_type;
typedef typename ProcessGroup::process_size_type process_size_type;
typedef SizeType size_type;
private:
struct basic_distribution
{
virtual ~basic_distribution() {}
virtual size_type block_size(process_id_type, size_type) const = 0;
virtual process_id_type in_process(size_type) const = 0;
virtual size_type local(size_type) const = 0;
virtual size_type global(size_type) const = 0;
virtual size_type global(process_id_type, size_type) const = 0;
virtual void* address() = 0;
virtual const void* address() const = 0;
virtual type_index type() const = 0;
};
template<typename Distribution>
struct poly_distribution : public basic_distribution
{
explicit poly_distribution(const Distribution& distribution)
: distribution_(distribution) { }
virtual size_type block_size(process_id_type id, size_type n) const
{ return distribution_.block_size(id, n); }
virtual process_id_type in_process(size_type i) const
{ return distribution_(i); }
virtual size_type local(size_type i) const
{ return distribution_.local(i); }
virtual size_type global(size_type n) const
{ return distribution_.global(n); }
virtual size_type global(process_id_type id, size_type n) const
{ return distribution_.global(id, n); }
virtual void* address() { return &distribution_; }
virtual const void* address() const { return &distribution_; }
virtual type_index type() const { return type_id<Distribution>(); }
private:
Distribution distribution_;
};
public:
variant_distribution() { }
template<typename Distribution>
variant_distribution(const Distribution& distribution)
: distribution_(new poly_distribution<Distribution>(distribution)) { }
size_type block_size(process_id_type id, size_type n) const
{ return distribution_->block_size(id, n); }
process_id_type operator()(size_type i) const
{ return distribution_->in_process(i); }
size_type local(size_type i) const
{ return distribution_->local(i); }
size_type global(size_type n) const
{ return distribution_->global(n); }
size_type global(process_id_type id, size_type n) const
{ return distribution_->global(id, n); }
operator bool() const { return distribution_; }
void clear() { distribution_.reset(); }
template<typename T>
T* as()
{
if (distribution_->type() == type_id<T>())
return static_cast<T*>(distribution_->address());
else
return 0;
}
template<typename T>
const T* as() const
{
if (distribution_->type() == type_id<T>())
return static_cast<T*>(distribution_->address());
else
return 0;
}
private:
shared_ptr<basic_distribution> distribution_;
};
struct block
{
template<typename LinearProcessGroup>
explicit block(const LinearProcessGroup& pg, std::size_t n)
: id(process_id(pg)), p(num_processes(pg)), n(n) { }
// If there are n elements in the distributed data structure, returns the number of elements stored locally.
template<typename SizeType>
SizeType block_size(SizeType n) const
{ return (n / p) + ((std::size_t)(n % p) > id? 1 : 0); }
// If there are n elements in the distributed data structure, returns the number of elements stored on processor ID
template<typename SizeType, typename ProcessID>
SizeType block_size(ProcessID id, SizeType n) const
{ return (n / p) + ((ProcessID)(n % p) > id? 1 : 0); }
// Returns the processor on which element with global index i is stored
template<typename SizeType>
SizeType operator()(SizeType i) const
{
SizeType cutoff_processor = n % p;
SizeType cutoff = cutoff_processor * (n / p + 1);
if (i < cutoff) return i / (n / p + 1);
else return cutoff_processor + (i - cutoff) / (n / p);
}
// Find the starting index for processor with the given id
template<typename ID>
std::size_t start(ID id) const
{
std::size_t estimate = id * (n / p + 1);
ID cutoff_processor = n % p;
if (id < cutoff_processor) return estimate;
else return estimate - (id - cutoff_processor);
}
// Find the local index for the ith global element
template<typename SizeType>
SizeType local(SizeType i) const
{
SizeType owner = (*this)(i);
return i - start(owner);
}
// Returns the global index of local element i
template<typename SizeType>
SizeType global(SizeType i) const
{ return global(id, i); }
// Returns the global index of the ith local element on processor id
template<typename ProcessID, typename SizeType>
SizeType global(ProcessID id, SizeType i) const
{ return i + start(id); }
private:
std::size_t id; //< The ID number of this processor
std::size_t p; //< The number of processors
std::size_t n; //< The size of the problem space
};
// Block distribution with arbitrary block sizes
struct uneven_block
{
typedef std::vector<std::size_t> size_vector;
template<typename LinearProcessGroup>
explicit uneven_block(const LinearProcessGroup& pg, const std::vector<std::size_t>& local_sizes)
: id(process_id(pg)), p(num_processes(pg)), local_sizes(local_sizes)
{
BOOST_ASSERT(local_sizes.size() == p);
local_starts.resize(p + 1);
local_starts[0] = 0;
std::partial_sum(local_sizes.begin(), local_sizes.end(), &local_starts[1]);
n = local_starts[p];
}
// To do maybe: enter local size in each process and gather in constructor (much handier)
// template<typename LinearProcessGroup>
// explicit uneven_block(const LinearProcessGroup& pg, std::size_t my_local_size)
// If there are n elements in the distributed data structure, returns the number of elements stored locally.
template<typename SizeType>
SizeType block_size(SizeType) const
{ return local_sizes[id]; }
// If there are n elements in the distributed data structure, returns the number of elements stored on processor ID
template<typename SizeType, typename ProcessID>
SizeType block_size(ProcessID id, SizeType) const
{ return local_sizes[id]; }
// Returns the processor on which element with global index i is stored
template<typename SizeType>
SizeType operator()(SizeType i) const
{
BOOST_ASSERT (i >= (SizeType) 0 && i < (SizeType) n); // check for valid range
size_vector::const_iterator lb = std::lower_bound(local_starts.begin(), local_starts.end(), (std::size_t) i);
return ((SizeType)(*lb) == i ? lb : --lb) - local_starts.begin();
}
// Find the starting index for processor with the given id
template<typename ID>
std::size_t start(ID id) const
{
return local_starts[id];
}
// Find the local index for the ith global element
template<typename SizeType>
SizeType local(SizeType i) const
{
SizeType owner = (*this)(i);
return i - start(owner);
}
// Returns the global index of local element i
template<typename SizeType>
SizeType global(SizeType i) const
{ return global(id, i); }
// Returns the global index of the ith local element on processor id
template<typename ProcessID, typename SizeType>
SizeType global(ProcessID id, SizeType i) const
{ return i + start(id); }
private:
std::size_t id; //< The ID number of this processor
std::size_t p; //< The number of processors
std::size_t n; //< The size of the problem space
std::vector<std::size_t> local_sizes; //< The sizes of all blocks
std::vector<std::size_t> local_starts; //< Lowest global index of each block
};
struct oned_block_cyclic
{
template<typename LinearProcessGroup>
explicit oned_block_cyclic(const LinearProcessGroup& pg, std::size_t size)
: id(process_id(pg)), p(num_processes(pg)), size(size) { }
template<typename SizeType>
SizeType block_size(SizeType n) const
{
return block_size(id, n);
}
template<typename SizeType, typename ProcessID>
SizeType block_size(ProcessID id, SizeType n) const
{
SizeType all_blocks = n / size;
SizeType extra_elements = n % size;
SizeType everyone_gets = all_blocks / p;
SizeType extra_blocks = all_blocks % p;
SizeType my_blocks = everyone_gets + (p < extra_blocks? 1 : 0);
SizeType my_elements = my_blocks * size
+ (p == extra_blocks? extra_elements : 0);
return my_elements;
}
template<typename SizeType>
SizeType operator()(SizeType i) const
{
return (i / size) % p;
}
template<typename SizeType>
SizeType local(SizeType i) const
{
return ((i / size) / p) * size + i % size;
}
template<typename SizeType>
SizeType global(SizeType i) const
{ return global(id, i); }
template<typename ProcessID, typename SizeType>
SizeType global(ProcessID id, SizeType i) const
{
return ((i / size) * p + id) * size + i % size;
}
private:
std::size_t id; //< The ID number of this processor
std::size_t p; //< The number of processors
std::size_t size; //< Block size
};
struct twod_block_cyclic
{
template<typename LinearProcessGroup>
explicit twod_block_cyclic(const LinearProcessGroup& pg,
std::size_t block_rows, std::size_t block_columns,
std::size_t data_columns_per_row)
: id(process_id(pg)), p(num_processes(pg)),
block_rows(block_rows), block_columns(block_columns),
data_columns_per_row(data_columns_per_row)
{ }
template<typename SizeType>
SizeType block_size(SizeType n) const
{
return block_size(id, n);
}
template<typename SizeType, typename ProcessID>
SizeType block_size(ProcessID id, SizeType n) const
{
// TBD: This is really lame :)
int result = -1;
while (n > 0) {
--n;
if ((*this)(n) == id && (int)local(n) > result) result = local(n);
}
++result;
// std::cerr << "Block size of id " << id << " is " << result << std::endl;
return result;
}
template<typename SizeType>
SizeType operator()(SizeType i) const
{
SizeType result = get_block_num(i) % p;
// std::cerr << "Item " << i << " goes on processor " << result << std::endl;
return result;
}
template<typename SizeType>
SizeType local(SizeType i) const
{
// Compute the start of the block
std::size_t block_num = get_block_num(i);
// std::cerr << "Item " << i << " is in block #" << block_num << std::endl;
std::size_t local_block_num = block_num / p;
std::size_t block_start = local_block_num * block_rows * block_columns;
// Compute the offset into the block
std::size_t data_row = i / data_columns_per_row;
std::size_t data_col = i % data_columns_per_row;
std::size_t block_offset = (data_row % block_rows) * block_columns
+ (data_col % block_columns);
// std::cerr << "Item " << i << " maps to local index " << block_start+block_offset << std::endl;
return block_start + block_offset;
}
template<typename SizeType>
SizeType global(SizeType i) const
{
// Compute the (global) block in which this element resides
SizeType local_block_num = i / (block_rows * block_columns);
SizeType block_offset = i % (block_rows * block_columns);
SizeType block_num = local_block_num * p + id;
// Compute the position of the start of the block (globally)
SizeType block_start = block_num * block_rows * block_columns;
std::cerr << "Block " << block_num << " starts at index " << block_start
<< std::endl;
// Compute the row and column of this block
SizeType block_row = block_num / (data_columns_per_row / block_columns);
SizeType block_col = block_num % (data_columns_per_row / block_columns);
SizeType row_in_block = block_offset / block_columns;
SizeType col_in_block = block_offset % block_columns;
std::cerr << "Local index " << i << " is in block at row " << block_row
<< ", column " << block_col << ", in-block row " << row_in_block
<< ", in-block col " << col_in_block << std::endl;
SizeType result = block_row * block_rows + block_col * block_columns
+ row_in_block * block_rows + col_in_block;
std::cerr << "global(" << i << "@" << id << ") = " << result
<< " =? " << local(result) << std::endl;
BOOST_ASSERT(i == local(result));
return result;
}
private:
template<typename SizeType>
std::size_t get_block_num(SizeType i) const
{
std::size_t data_row = i / data_columns_per_row;
std::size_t data_col = i % data_columns_per_row;
std::size_t block_row = data_row / block_rows;
std::size_t block_col = data_col / block_columns;
std::size_t blocks_in_row = data_columns_per_row / block_columns;
std::size_t block_num = block_col * blocks_in_row + block_row;
return block_num;
}
std::size_t id; //< The ID number of this processor
std::size_t p; //< The number of processors
std::size_t block_rows; //< The # of rows in each block
std::size_t block_columns; //< The # of columns in each block
std::size_t data_columns_per_row; //< The # of columns per row of data
};
class twod_random
{
template<typename RandomNumberGen>
struct random_int
{
explicit random_int(RandomNumberGen& gen) : gen(gen) { }
template<typename T>
T operator()(T n) const
{
uniform_int<T> distrib(0, n-1);
return distrib(gen);
}
private:
RandomNumberGen& gen;
};
public:
template<typename LinearProcessGroup, typename RandomNumberGen>
explicit twod_random(const LinearProcessGroup& pg,
std::size_t block_rows, std::size_t block_columns,
std::size_t data_columns_per_row,
std::size_t n,
RandomNumberGen& gen)
: id(process_id(pg)), p(num_processes(pg)),
block_rows(block_rows), block_columns(block_columns),
data_columns_per_row(data_columns_per_row),
global_to_local(n / (block_rows * block_columns))
{
std::copy(make_counting_iterator(std::size_t(0)),
make_counting_iterator(global_to_local.size()),
global_to_local.begin());
random_int<RandomNumberGen> rand(gen);
std::random_shuffle(global_to_local.begin(), global_to_local.end(), rand);
}
template<typename SizeType>
SizeType block_size(SizeType n) const
{
return block_size(id, n);
}
template<typename SizeType, typename ProcessID>
SizeType block_size(ProcessID id, SizeType n) const
{
// TBD: This is really lame :)
int result = -1;
while (n > 0) {
--n;
if ((*this)(n) == id && (int)local(n) > result) result = local(n);
}
++result;
// std::cerr << "Block size of id " << id << " is " << result << std::endl;
return result;
}
template<typename SizeType>
SizeType operator()(SizeType i) const
{
SizeType result = get_block_num(i) % p;
// std::cerr << "Item " << i << " goes on processor " << result << std::endl;
return result;
}
template<typename SizeType>
SizeType local(SizeType i) const
{
// Compute the start of the block
std::size_t block_num = get_block_num(i);
// std::cerr << "Item " << i << " is in block #" << block_num << std::endl;
std::size_t local_block_num = block_num / p;
std::size_t block_start = local_block_num * block_rows * block_columns;
// Compute the offset into the block
std::size_t data_row = i / data_columns_per_row;
std::size_t data_col = i % data_columns_per_row;
std::size_t block_offset = (data_row % block_rows) * block_columns
+ (data_col % block_columns);
// std::cerr << "Item " << i << " maps to local index " << block_start+block_offset << std::endl;
return block_start + block_offset;
}
private:
template<typename SizeType>
std::size_t get_block_num(SizeType i) const
{
std::size_t data_row = i / data_columns_per_row;
std::size_t data_col = i % data_columns_per_row;
std::size_t block_row = data_row / block_rows;
std::size_t block_col = data_col / block_columns;
std::size_t blocks_in_row = data_columns_per_row / block_columns;
std::size_t block_num = block_col * blocks_in_row + block_row;
return global_to_local[block_num];
}
std::size_t id; //< The ID number of this processor
std::size_t p; //< The number of processors
std::size_t block_rows; //< The # of rows in each block
std::size_t block_columns; //< The # of columns in each block
std::size_t data_columns_per_row; //< The # of columns per row of data
std::vector<std::size_t> global_to_local;
};
class random_distribution
{
template<typename RandomNumberGen>
struct random_int
{
explicit random_int(RandomNumberGen& gen) : gen(gen) { }
template<typename T>
T operator()(T n) const
{
uniform_int<T> distrib(0, n-1);
return distrib(gen);
}
private:
RandomNumberGen& gen;
};
public:
template<typename LinearProcessGroup, typename RandomNumberGen>
random_distribution(const LinearProcessGroup& pg, RandomNumberGen& gen,
std::size_t n)
: base(pg, n), local_to_global(n), global_to_local(n)
{
std::copy(make_counting_iterator(std::size_t(0)),
make_counting_iterator(n),
local_to_global.begin());
random_int<RandomNumberGen> rand(gen);
std::random_shuffle(local_to_global.begin(), local_to_global.end(), rand);
for (std::vector<std::size_t>::size_type i = 0; i < n; ++i)
global_to_local[local_to_global[i]] = i;
}
template<typename SizeType>
SizeType block_size(SizeType n) const
{ return base.block_size(n); }
template<typename SizeType, typename ProcessID>
SizeType block_size(ProcessID id, SizeType n) const
{ return base.block_size(id, n); }
template<typename SizeType>
SizeType operator()(SizeType i) const
{
return base(global_to_local[i]);
}
template<typename SizeType>
SizeType local(SizeType i) const
{
return base.local(global_to_local[i]);
}
template<typename ProcessID, typename SizeType>
SizeType global(ProcessID p, SizeType i) const
{
return local_to_global[base.global(p, i)];
}
template<typename SizeType>
SizeType global(SizeType i) const
{
return local_to_global[base.global(i)];
}
private:
block base;
std::vector<std::size_t> local_to_global;
std::vector<std::size_t> global_to_local;
};
} } // end namespace boost::parallel
#endif // BOOST_PARALLEL_DISTRIBUTION_HPP

View File

@ -0,0 +1,40 @@
Index: .
===================================================================
--- . (revision 86520)
+++ . (working copy)
@@ -22,7 +22,7 @@
#include <boost/iterator/counting_iterator.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/shared_ptr.hpp>
-#include <typeinfo>
+#include <boost/type_index/type_info.hpp>
namespace boost { namespace parallel {
@@ -71,7 +71,7 @@
virtual void* address() { return &distribution_; }
virtual const void* address() const { return &distribution_; }
- virtual const std::type_info& type() const { return typeid(Distribution); }
+ virtual const boost::type_info& type() const { return boost::type_id<Distribution>(); }
private:
Distribution distribution_;
@@ -106,7 +106,7 @@
template<typename T>
T* as()
{
- if (distribution_->type() == typeid(T))
+ if (distribution_->type() == boost::type_id<T>())
return static_cast<T*>(distribution_->address());
else
return 0;
@@ -115,7 +115,7 @@
template<typename T>
const T* as() const
{
- if (distribution_->type() == typeid(T))
+ if (distribution_->type() == boost::type_id<T>())
return static_cast<T*>(distribution_->address());
else
return 0;

View File

@ -1,163 +0,0 @@
// Copyright John Maddock 2010.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifdef _MSC_VER
# pragma once
#endif
#ifndef BOOST_MATH_CONSTANTS_INFO_INCLUDED
#define BOOST_MATH_CONSTANTS_INFO_INCLUDED
#include <boost/math/constants/constants.hpp>
#include <boost/type_index.hpp>
#include <iostream>
#include <iomanip>
namespace boost{ namespace math{ namespace constants{
namespace detail{
template <class T>
const char* nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
{
return type_id<T>().name_demangled();
}
template <>
const char* nameof<float>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(float))
{
return "float";
}
template <>
const char* nameof<double>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(double))
{
return "double";
}
template <>
const char* nameof<long double>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(long double))
{
return "long double";
}
}
template <class T, class Policy>
void print_info_on_type(std::ostream& os = std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(Policy))
{
using detail::nameof;
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
os <<
"Information on the Implementation and Handling of \n"
"Mathematical Constants for Type " << nameof<T>() <<
"\n\n"
"Checking for std::numeric_limits<" << nameof<T>() << "> specialisation: " <<
(std::numeric_limits<T>::is_specialized ? "yes" : "no") << std::endl;
if(std::numeric_limits<T>::is_specialized)
{
os <<
"std::numeric_limits<" << nameof<T>() << ">::digits reports that the radix is " << std::numeric_limits<T>::radix << ".\n";
if (std::numeric_limits<T>::radix == 2)
{
os <<
"std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n" << std::numeric_limits<T>::digits << " binary digits.\n";
}
else if (std::numeric_limits<T>::radix == 10)
{
os <<
"std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n" << std::numeric_limits<T>::digits10 << " decimal digits.\n";
os <<
"std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n"
<< std::numeric_limits<T>::digits * 1000L /301L << " binary digits.\n"; // divide by log2(10) - about 3 bits per decimal digit.
}
else
{
os << "Unknown radix = " << std::numeric_limits<T>::radix << "\n";
}
}
typedef typename boost::math::policies::precision<T, Policy>::type precision_type;
if(precision_type::value)
{
if (std::numeric_limits<T>::radix == 2)
{
os <<
"boost::math::policies::precision<" << nameof<T>() << ", " << nameof<Policy>() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n";
}
else if (std::numeric_limits<T>::radix == 10)
{
os <<
"boost::math::policies::precision<" << nameof<T>() << ", " << nameof<Policy>() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n";
}
else
{
os << "Unknown radix = " << std::numeric_limits<T>::radix << "\n";
}
}
else
{
os <<
"boost::math::policies::precision<" << nameof<T>() << ", Policy> \n"
"reports that there is no compile type precision available.\n"
"boost::math::tools::digits<" << nameof<T>() << ">() \n"
"reports that the current runtime precision is \n" <<
boost::math::tools::digits<T>() << " binary digits.\n";
}
typedef typename construction_traits<T, Policy>::type construction_type;
switch(construction_type::value)
{
case 0:
os <<
"No compile time precision is available, the construction method \n"
"will be decided at runtime and results will not be cached \n"
"- this may lead to poor runtime performance.\n"
"Current runtime precision indicates that\n";
if(boost::math::tools::digits<T>() > max_string_digits)
{
os << "the constant will be recalculated on each call.\n";
}
else
{
os << "the constant will be constructed from a string on each call.\n";
}
break;
case 1:
os <<
"The constant will be constructed from a float.\n";
break;
case 2:
os <<
"The constant will be constructed from a double.\n";
break;
case 3:
os <<
"The constant will be constructed from a long double.\n";
break;
case 4:
os <<
"The constant will be constructed from a string (and the result cached).\n";
break;
default:
os <<
"The constant will be calculated (and the result cached).\n";
break;
}
os << std::endl;
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}
template <class T>
void print_info_on_type(std::ostream& os = std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
{
print_info_on_type<T, boost::math::policies::policy<> >(os);
}
}}} // namespaces
#endif // BOOST_MATH_CONSTANTS_INFO_INCLUDED

View File

@ -1,488 +0,0 @@
// Copyright 2008 Gautam Sewani
// Copyright 2008 John Maddock
//
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_PDF_HPP
#define BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_PDF_HPP
#include <boost/math/constants/constants.hpp>
#include <boost/math/special_functions/lanczos.hpp>
#include <boost/math/special_functions/gamma.hpp>
#include <boost/math/special_functions/pow.hpp>
#include <boost/math/special_functions/prime.hpp>
#include <boost/math/policies/error_handling.hpp>
#ifdef BOOST_MATH_INSTRUMENT
#include <boost/type_index.hpp>
#endif
namespace boost{ namespace math{ namespace detail{
template <class T, class Func>
void bubble_down_one(T* first, T* last, Func f)
{
using std::swap;
T* next = first;
++next;
while((next != last) && (!f(*first, *next)))
{
swap(*first, *next);
++first;
++next;
}
}
template <class T>
struct sort_functor
{
sort_functor(const T* exponents) : m_exponents(exponents){}
bool operator()(int i, int j)
{
return m_exponents[i] > m_exponents[j];
}
private:
const T* m_exponents;
};
template <class T, class Lanczos, class Policy>
T hypergeometric_pdf_lanczos_imp(T /*dummy*/, unsigned x, unsigned r, unsigned n, unsigned N, const Lanczos&, const Policy&)
{
BOOST_MATH_STD_USING
BOOST_MATH_INSTRUMENT_FPU
BOOST_MATH_INSTRUMENT_VARIABLE(x);
BOOST_MATH_INSTRUMENT_VARIABLE(r);
BOOST_MATH_INSTRUMENT_VARIABLE(n);
BOOST_MATH_INSTRUMENT_VARIABLE(N);
BOOST_MATH_INSTRUMENT_VARIABLE(type_id<Lanczos>().name_demangled());
T bases[9] = {
T(n) + Lanczos::g() + 0.5f,
T(r) + Lanczos::g() + 0.5f,
T(N - n) + Lanczos::g() + 0.5f,
T(N - r) + Lanczos::g() + 0.5f,
1 / (T(N) + Lanczos::g() + 0.5f),
1 / (T(x) + Lanczos::g() + 0.5f),
1 / (T(n - x) + Lanczos::g() + 0.5f),
1 / (T(r - x) + Lanczos::g() + 0.5f),
1 / (T(N - n - r + x) + Lanczos::g() + 0.5f)
};
T exponents[9] = {
n + T(0.5f),
r + T(0.5f),
N - n + T(0.5f),
N - r + T(0.5f),
N + T(0.5f),
x + T(0.5f),
n - x + T(0.5f),
r - x + T(0.5f),
N - n - r + x + T(0.5f)
};
int base_e_factors[9] = {
-1, -1, -1, -1, 1, 1, 1, 1, 1
};
int sorted_indexes[9] = {
0, 1, 2, 3, 4, 5, 6, 7, 8
};
#ifdef BOOST_MATH_INSTRUMENT
BOOST_MATH_INSTRUMENT_FPU
for(unsigned i = 0; i < 9; ++i)
{
BOOST_MATH_INSTRUMENT_VARIABLE(i);
BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]);
}
#endif
std::sort(sorted_indexes, sorted_indexes + 9, sort_functor<T>(exponents));
#ifdef BOOST_MATH_INSTRUMENT
BOOST_MATH_INSTRUMENT_FPU
for(unsigned i = 0; i < 9; ++i)
{
BOOST_MATH_INSTRUMENT_VARIABLE(i);
BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]);
}
#endif
do{
exponents[sorted_indexes[0]] -= exponents[sorted_indexes[1]];
bases[sorted_indexes[1]] *= bases[sorted_indexes[0]];
if((bases[sorted_indexes[1]] < tools::min_value<T>()) && (exponents[sorted_indexes[1]] != 0))
{
return 0;
}
base_e_factors[sorted_indexes[1]] += base_e_factors[sorted_indexes[0]];
bubble_down_one(sorted_indexes, sorted_indexes + 9, sort_functor<T>(exponents));
#ifdef BOOST_MATH_INSTRUMENT
for(unsigned i = 0; i < 9; ++i)
{
BOOST_MATH_INSTRUMENT_VARIABLE(i);
BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]);
}
#endif
}while(exponents[sorted_indexes[1]] > 1);
//
// Combine equal powers:
//
int j = 8;
while(exponents[sorted_indexes[j]] == 0) --j;
while(j)
{
while(j && (exponents[sorted_indexes[j-1]] == exponents[sorted_indexes[j]]))
{
bases[sorted_indexes[j-1]] *= bases[sorted_indexes[j]];
exponents[sorted_indexes[j]] = 0;
base_e_factors[sorted_indexes[j-1]] += base_e_factors[sorted_indexes[j]];
bubble_down_one(sorted_indexes + j, sorted_indexes + 9, sort_functor<T>(exponents));
--j;
}
--j;
#ifdef BOOST_MATH_INSTRUMENT
BOOST_MATH_INSTRUMENT_VARIABLE(j);
for(unsigned i = 0; i < 9; ++i)
{
BOOST_MATH_INSTRUMENT_VARIABLE(i);
BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]);
}
#endif
}
#ifdef BOOST_MATH_INSTRUMENT
BOOST_MATH_INSTRUMENT_FPU
for(unsigned i = 0; i < 9; ++i)
{
BOOST_MATH_INSTRUMENT_VARIABLE(i);
BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]);
BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]);
}
#endif
T result;
BOOST_MATH_INSTRUMENT_VARIABLE(bases[sorted_indexes[0]] * exp(static_cast<T>(base_e_factors[sorted_indexes[0]])));
BOOST_MATH_INSTRUMENT_VARIABLE(exponents[sorted_indexes[0]]);
{
BOOST_FPU_EXCEPTION_GUARD
result = pow(bases[sorted_indexes[0]] * exp(static_cast<T>(base_e_factors[sorted_indexes[0]])), exponents[sorted_indexes[0]]);
}
BOOST_MATH_INSTRUMENT_VARIABLE(result);
for(unsigned i = 1; (i < 9) && (exponents[sorted_indexes[i]] > 0); ++i)
{
BOOST_FPU_EXCEPTION_GUARD
if(result < tools::min_value<T>())
return 0; // short circuit further evaluation
if(exponents[sorted_indexes[i]] == 1)
result *= bases[sorted_indexes[i]] * exp(static_cast<T>(base_e_factors[sorted_indexes[i]]));
else if(exponents[sorted_indexes[i]] == 0.5f)
result *= sqrt(bases[sorted_indexes[i]] * exp(static_cast<T>(base_e_factors[sorted_indexes[i]])));
else
result *= pow(bases[sorted_indexes[i]] * exp(static_cast<T>(base_e_factors[sorted_indexes[i]])), exponents[sorted_indexes[i]]);
BOOST_MATH_INSTRUMENT_VARIABLE(result);
}
result *= Lanczos::lanczos_sum_expG_scaled(static_cast<T>(n + 1))
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(r + 1))
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(N - n + 1))
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(N - r + 1))
/
( Lanczos::lanczos_sum_expG_scaled(static_cast<T>(N + 1))
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(x + 1))
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(n - x + 1))
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(r - x + 1))
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(N - n - r + x + 1)));
BOOST_MATH_INSTRUMENT_VARIABLE(result);
return result;
}
template <class T, class Policy>
T hypergeometric_pdf_lanczos_imp(T /*dummy*/, unsigned x, unsigned r, unsigned n, unsigned N, const boost::math::lanczos::undefined_lanczos&, const Policy& pol)
{
BOOST_MATH_STD_USING
return exp(
boost::math::lgamma(T(n + 1), pol)
+ boost::math::lgamma(T(r + 1), pol)
+ boost::math::lgamma(T(N - n + 1), pol)
+ boost::math::lgamma(T(N - r + 1), pol)
- boost::math::lgamma(T(N + 1), pol)
- boost::math::lgamma(T(x + 1), pol)
- boost::math::lgamma(T(n - x + 1), pol)
- boost::math::lgamma(T(r - x + 1), pol)
- boost::math::lgamma(T(N - n - r + x + 1), pol));
}
template <class T>
inline T integer_power(const T& x, int ex)
{
if(ex < 0)
return 1 / integer_power(x, -ex);
switch(ex)
{
case 0:
return 1;
case 1:
return x;
case 2:
return x * x;
case 3:
return x * x * x;
case 4:
return boost::math::pow<4>(x);
case 5:
return boost::math::pow<5>(x);
case 6:
return boost::math::pow<6>(x);
case 7:
return boost::math::pow<7>(x);
case 8:
return boost::math::pow<8>(x);
}
BOOST_MATH_STD_USING
#ifdef __SUNPRO_CC
return pow(x, T(ex));
#else
return pow(x, ex);
#endif
}
template <class T>
struct hypergeometric_pdf_prime_loop_result_entry
{
T value;
const hypergeometric_pdf_prime_loop_result_entry* next;
};
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4510 4512 4610)
#endif
struct hypergeometric_pdf_prime_loop_data
{
const unsigned x;
const unsigned r;
const unsigned n;
const unsigned N;
unsigned prime_index;
unsigned current_prime;
};
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
template <class T>
T hypergeometric_pdf_prime_loop_imp(hypergeometric_pdf_prime_loop_data& data, hypergeometric_pdf_prime_loop_result_entry<T>& result)
{
while(data.current_prime <= data.N)
{
unsigned base = data.current_prime;
int prime_powers = 0;
while(base <= data.N)
{
prime_powers += data.n / base;
prime_powers += data.r / base;
prime_powers += (data.N - data.n) / base;
prime_powers += (data.N - data.r) / base;
prime_powers -= data.N / base;
prime_powers -= data.x / base;
prime_powers -= (data.n - data.x) / base;
prime_powers -= (data.r - data.x) / base;
prime_powers -= (data.N - data.n - data.r + data.x) / base;
base *= data.current_prime;
}
if(prime_powers)
{
T p = integer_power<T>(data.current_prime, prime_powers);
if((p > 1) && (tools::max_value<T>() / p < result.value))
{
//
// The next calculation would overflow, use recursion
// to sidestep the issue:
//
hypergeometric_pdf_prime_loop_result_entry<T> t = { p, &result };
data.current_prime = prime(++data.prime_index);
return hypergeometric_pdf_prime_loop_imp<T>(data, t);
}
if((p < 1) && (tools::min_value<T>() / p > result.value))
{
//
// The next calculation would underflow, use recursion
// to sidestep the issue:
//
hypergeometric_pdf_prime_loop_result_entry<T> t = { p, &result };
data.current_prime = prime(++data.prime_index);
return hypergeometric_pdf_prime_loop_imp<T>(data, t);
}
result.value *= p;
}
data.current_prime = prime(++data.prime_index);
}
//
// When we get to here we have run out of prime factors,
// the overall result is the product of all the partial
// results we have accumulated on the stack so far, these
// are in a linked list starting with "data.head" and ending
// with "result".
//
// All that remains is to multiply them together, taking
// care not to overflow or underflow.
//
// Enumerate partial results >= 1 in variable i
// and partial results < 1 in variable j:
//
hypergeometric_pdf_prime_loop_result_entry<T> const *i, *j;
i = &result;
while(i && i->value < 1)
i = i->next;
j = &result;
while(j && j->value >= 1)
j = j->next;
T prod = 1;
while(i || j)
{
while(i && ((prod <= 1) || (j == 0)))
{
prod *= i->value;
i = i->next;
while(i && i->value < 1)
i = i->next;
}
while(j && ((prod >= 1) || (i == 0)))
{
prod *= j->value;
j = j->next;
while(j && j->value >= 1)
j = j->next;
}
}
return prod;
}
template <class T, class Policy>
inline T hypergeometric_pdf_prime_imp(unsigned x, unsigned r, unsigned n, unsigned N, const Policy&)
{
hypergeometric_pdf_prime_loop_result_entry<T> result = { 1, 0 };
hypergeometric_pdf_prime_loop_data data = { x, r, n, N, 0, prime(0) };
return hypergeometric_pdf_prime_loop_imp<T>(data, result);
}
template <class T, class Policy>
T hypergeometric_pdf_factorial_imp(unsigned x, unsigned r, unsigned n, unsigned N, const Policy&)
{
BOOST_MATH_STD_USING
BOOST_ASSERT(N < boost::math::max_factorial<T>::value);
T result = boost::math::unchecked_factorial<T>(n);
T num[3] = {
boost::math::unchecked_factorial<T>(r),
boost::math::unchecked_factorial<T>(N - n),
boost::math::unchecked_factorial<T>(N - r)
};
T denom[5] = {
boost::math::unchecked_factorial<T>(N),
boost::math::unchecked_factorial<T>(x),
boost::math::unchecked_factorial<T>(n - x),
boost::math::unchecked_factorial<T>(r - x),
boost::math::unchecked_factorial<T>(N - n - r + x)
};
int i = 0;
int j = 0;
while((i < 3) || (j < 5))
{
while((j < 5) && ((result >= 1) || (i >= 3)))
{
result /= denom[j];
++j;
}
while((i < 3) && ((result <= 1) || (j >= 5)))
{
result *= num[i];
++i;
}
}
return result;
}
template <class T, class Policy>
inline typename tools::promote_args<T>::type
hypergeometric_pdf(unsigned x, unsigned r, unsigned n, unsigned N, const Policy&)
{
BOOST_FPU_EXCEPTION_GUARD
typedef typename tools::promote_args<T>::type result_type;
typedef typename policies::evaluation<result_type, Policy>::type value_type;
typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
typedef typename policies::normalise<
Policy,
policies::promote_float<false>,
policies::promote_double<false>,
policies::discrete_quantile<>,
policies::assert_undefined<> >::type forwarding_policy;
value_type result;
if(N <= boost::math::max_factorial<value_type>::value)
{
//
// If N is small enough then we can evaluate the PDF via the factorials
// directly: table lookup of the factorials gives the best performance
// of the methods available:
//
result = detail::hypergeometric_pdf_factorial_imp<value_type>(x, r, n, N, forwarding_policy());
}
else if(N <= boost::math::prime(boost::math::max_prime - 1))
{
//
// If N is no larger than the largest prime number in our lookup table
// (104729) then we can use prime factorisation to evaluate the PDF,
// this is slow but accurate:
//
result = detail::hypergeometric_pdf_prime_imp<value_type>(x, r, n, N, forwarding_policy());
}
else
{
//
// Catch all case - use the lanczos approximation - where available -
// to evaluate the ratio of factorials. This is reasonably fast
// (almost as quick as using logarithmic evaluation in terms of lgamma)
// but only a few digits better in accuracy than using lgamma:
//
result = detail::hypergeometric_pdf_lanczos_imp(value_type(), x, r, n, N, evaluation_type(), forwarding_policy());
}
if(result > 1)
{
result = 1;
}
if(result < 0)
{
result = 0;
}
return policies::checked_narrowing_cast<result_type, forwarding_policy>(result, "boost::math::hypergeometric_pdf<%1%>(%1%,%1%,%1%,%1%)");
}
}}} // namespaces
#endif

View File

@ -1,692 +0,0 @@
// Copyright John Maddock 2007.
// Copyright Paul A. Bristow 2007.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MATH_POLICY_ERROR_HANDLING_HPP
#define BOOST_MATH_POLICY_ERROR_HANDLING_HPP
#include <stdexcept>
#include <iomanip>
#include <string>
#include <cerrno>
#include <complex>
#include <boost/config/no_tr1/cmath.hpp>
#include <stdexcept>
#include <boost/math/tools/config.hpp>
#include <boost/math/policies/policy.hpp>
#include <boost/math/tools/precision.hpp>
#include <boost/cstdint.hpp>
#ifdef BOOST_MSVC
# pragma warning(push) // Quiet warnings in boost/format.hpp
# pragma warning(disable: 4996) // _SCL_SECURE_NO_DEPRECATE
# pragma warning(disable: 4512) // assignment operator could not be generated.
// And warnings in error handling:
# pragma warning(disable: 4702) // unreachable code
// Note that this only occurs when the compiler can deduce code is unreachable,
// for example when policy macros are used to ignore errors rather than throw.
#endif
#include <boost/format.hpp>
#include <boost/type_index.hpp>
namespace boost{ namespace math{
class evaluation_error : public std::runtime_error
{
public:
evaluation_error(const std::string& s) : std::runtime_error(s){}
};
class rounding_error : public std::runtime_error
{
public:
rounding_error(const std::string& s) : std::runtime_error(s){}
};
namespace policies{
//
// Forward declarations of user error handlers,
// it's up to the user to provide the definition of these:
//
template <class T>
T user_domain_error(const char* function, const char* message, const T& val);
template <class T>
T user_pole_error(const char* function, const char* message, const T& val);
template <class T>
T user_overflow_error(const char* function, const char* message, const T& val);
template <class T>
T user_underflow_error(const char* function, const char* message, const T& val);
template <class T>
T user_denorm_error(const char* function, const char* message, const T& val);
template <class T>
T user_evaluation_error(const char* function, const char* message, const T& val);
template <class T, class TargetType>
T user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t);
template <class T>
T user_indeterminate_result_error(const char* function, const char* message, const T& val);
namespace detail
{
//
// Helper function to avoid binding rvalue to non-const-reference,
// in other words a warning suppression mechansim:
//
template <class Formatter, class Group>
inline std::string do_format(Formatter f, const Group& g)
{
return (f % g).str();
}
template <class E, class T>
void raise_error(const char* function, const char* message)
{
if(function == 0)
function = "Unknown function operating on type %1%";
if(message == 0)
message = "Cause unknown";
std::string msg("Error in function ");
msg += (boost::format(function) % type_id<T>().name_demangled()).str();
msg += ": ";
msg += message;
E e(msg);
boost::throw_exception(e);
}
template <class E, class T>
void raise_error(const char* function, const char* message, const T& val)
{
if(function == 0)
function = "Unknown function operating on type %1%";
if(message == 0)
message = "Cause unknown: error caused by bad argument with value %1%";
std::string msg("Error in function ");
msg += (boost::format(function) % type_id<T>().name_demangled()).str();
msg += ": ";
msg += message;
int prec = 2 + (boost::math::policies::digits<T, boost::math::policies::policy<> >() * 30103UL) / 100000UL;
msg = do_format(boost::format(msg), boost::io::group(std::setprecision(prec), val));
E e(msg);
boost::throw_exception(e);
}
template <class T>
inline T raise_domain_error(
const char* function,
const char* message,
const T& val,
const ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>&)
{
raise_error<std::domain_error, T>(function, message, val);
// we never get here:
return std::numeric_limits<T>::quiet_NaN();
}
template <class T>
inline T raise_domain_error(
const char* ,
const char* ,
const T& ,
const ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>&)
{
// This may or may not do the right thing, but the user asked for the error
// to be ignored so here we go anyway:
return std::numeric_limits<T>::quiet_NaN();
}
template <class T>
inline T raise_domain_error(
const char* ,
const char* ,
const T& ,
const ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>&)
{
errno = EDOM;
// This may or may not do the right thing, but the user asked for the error
// to be silent so here we go anyway:
return std::numeric_limits<T>::quiet_NaN();
}
template <class T>
inline T raise_domain_error(
const char* function,
const char* message,
const T& val,
const ::boost::math::policies::domain_error< ::boost::math::policies::user_error>&)
{
return user_domain_error(function, message, val);
}
template <class T>
inline T raise_pole_error(
const char* function,
const char* message,
const T& val,
const ::boost::math::policies::pole_error< ::boost::math::policies::throw_on_error>&)
{
return boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>());
}
template <class T>
inline T raise_pole_error(
const char* function,
const char* message,
const T& val,
const ::boost::math::policies::pole_error< ::boost::math::policies::ignore_error>&)
{
return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>());
}
template <class T>
inline T raise_pole_error(
const char* function,
const char* message,
const T& val,
const ::boost::math::policies::pole_error< ::boost::math::policies::errno_on_error>&)
{
return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>());
}
template <class T>
inline T raise_pole_error(
const char* function,
const char* message,
const T& val,
const ::boost::math::policies::pole_error< ::boost::math::policies::user_error>&)
{
return user_pole_error(function, message, val);
}
template <class T>
inline T raise_overflow_error(
const char* function,
const char* message,
const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&)
{
raise_error<std::overflow_error, T>(function, message ? message : "numeric overflow");
// we never get here:
return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
}
template <class T>
inline T raise_overflow_error(
const char* ,
const char* ,
const ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&)
{
// This may or may not do the right thing, but the user asked for the error
// to be ignored so here we go anyway:
return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
}
template <class T>
inline T raise_overflow_error(
const char* ,
const char* ,
const ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&)
{
errno = ERANGE;
// This may or may not do the right thing, but the user asked for the error
// to be silent so here we go anyway:
return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
}
template <class T>
inline T raise_overflow_error(
const char* function,
const char* message,
const ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&)
{
return user_overflow_error(function, message, std::numeric_limits<T>::infinity());
}
template <class T>
inline T raise_underflow_error(
const char* function,
const char* message,
const ::boost::math::policies::underflow_error< ::boost::math::policies::throw_on_error>&)
{
raise_error<std::underflow_error, T>(function, message ? message : "numeric underflow");
// we never get here:
return 0;
}
template <class T>
inline T raise_underflow_error(
const char* ,
const char* ,
const ::boost::math::policies::underflow_error< ::boost::math::policies::ignore_error>&)
{
// This may or may not do the right thing, but the user asked for the error
// to be ignored so here we go anyway:
return T(0);
}
template <class T>
inline T raise_underflow_error(
const char* /* function */,
const char* /* message */,
const ::boost::math::policies::underflow_error< ::boost::math::policies::errno_on_error>&)
{
errno = ERANGE;
// This may or may not do the right thing, but the user asked for the error
// to be silent so here we go anyway:
return T(0);
}
template <class T>
inline T raise_underflow_error(
const char* function,
const char* message,
const ::boost::math::policies::underflow_error< ::boost::math::policies::user_error>&)
{
return user_underflow_error(function, message, T(0));
}
template <class T>
inline T raise_denorm_error(
const char* function,
const char* message,
const T& /* val */,
const ::boost::math::policies::denorm_error< ::boost::math::policies::throw_on_error>&)
{
raise_error<std::underflow_error, T>(function, message ? message : "denormalised result");
// we never get here:
return T(0);
}
template <class T>
inline T raise_denorm_error(
const char* ,
const char* ,
const T& val,
const ::boost::math::policies::denorm_error< ::boost::math::policies::ignore_error>&)
{
// This may or may not do the right thing, but the user asked for the error
// to be ignored so here we go anyway:
return val;
}
template <class T>
inline T raise_denorm_error(
const char* ,
const char* ,
const T& val,
const ::boost::math::policies::denorm_error< ::boost::math::policies::errno_on_error>&)
{
errno = ERANGE;
// This may or may not do the right thing, but the user asked for the error
// to be silent so here we go anyway:
return val;
}
template <class T>
inline T raise_denorm_error(
const char* function,
const char* message,
const T& val,
const ::boost::math::policies::denorm_error< ::boost::math::policies::user_error>&)
{
return user_denorm_error(function, message, val);
}
template <class T>
inline T raise_evaluation_error(
const char* function,
const char* message,
const T& val,
const ::boost::math::policies::evaluation_error< ::boost::math::policies::throw_on_error>&)
{
raise_error<boost::math::evaluation_error, T>(function, message, val);
// we never get here:
return T(0);
}
template <class T>
inline T raise_evaluation_error(
const char* ,
const char* ,
const T& val,
const ::boost::math::policies::evaluation_error< ::boost::math::policies::ignore_error>&)
{
// This may or may not do the right thing, but the user asked for the error
// to be ignored so here we go anyway:
return val;
}
template <class T>
inline T raise_evaluation_error(
const char* ,
const char* ,
const T& val,
const ::boost::math::policies::evaluation_error< ::boost::math::policies::errno_on_error>&)
{
errno = EDOM;
// This may or may not do the right thing, but the user asked for the error
// to be silent so here we go anyway:
return val;
}
template <class T>
inline T raise_evaluation_error(
const char* function,
const char* message,
const T& val,
const ::boost::math::policies::evaluation_error< ::boost::math::policies::user_error>&)
{
return user_evaluation_error(function, message, val);
}
template <class T, class TargetType>
inline T raise_rounding_error(
const char* function,
const char* message,
const T& val,
const TargetType&,
const ::boost::math::policies::rounding_error< ::boost::math::policies::throw_on_error>&)
{
raise_error<boost::math::rounding_error, T>(function, message, val);
// we never get here:
return T(0);
}
template <class T, class TargetType>
inline T raise_rounding_error(
const char* ,
const char* ,
const T& val,
const TargetType&,
const ::boost::math::policies::rounding_error< ::boost::math::policies::ignore_error>&)
{
// This may or may not do the right thing, but the user asked for the error
// to be ignored so here we go anyway:
return std::numeric_limits<T>::is_specialized ? (val > 0 ? (std::numeric_limits<T>::max)() : -(std::numeric_limits<T>::max)()): val;
}
template <class T, class TargetType>
inline T raise_rounding_error(
const char* ,
const char* ,
const T& val,
const TargetType&,
const ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&)
{
errno = ERANGE;
// This may or may not do the right thing, but the user asked for the error
// to be silent so here we go anyway:
return std::numeric_limits<T>::is_specialized ? (val > 0 ? (std::numeric_limits<T>::max)() : -(std::numeric_limits<T>::max)()): val;
}
template <class T, class TargetType>
inline T raise_rounding_error(
const char* function,
const char* message,
const T& val,
const TargetType& t,
const ::boost::math::policies::rounding_error< ::boost::math::policies::user_error>&)
{
return user_rounding_error(function, message, val, t);
}
template <class T, class R>
inline T raise_indeterminate_result_error(
const char* function,
const char* message,
const T& val,
const R& ,
const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::throw_on_error>&)
{
raise_error<std::domain_error, T>(function, message, val);
// we never get here:
return std::numeric_limits<T>::quiet_NaN();
}
template <class T, class R>
inline T raise_indeterminate_result_error(
const char* ,
const char* ,
const T& ,
const R& result,
const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::ignore_error>&)
{
// This may or may not do the right thing, but the user asked for the error
// to be ignored so here we go anyway:
return result;
}
template <class T, class R>
inline T raise_indeterminate_result_error(
const char* ,
const char* ,
const T& ,
const R& result,
const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::errno_on_error>&)
{
errno = EDOM;
// This may or may not do the right thing, but the user asked for the error
// to be silent so here we go anyway:
return result;
}
template <class T, class R>
inline T raise_indeterminate_result_error(
const char* function,
const char* message,
const T& val,
const R& ,
const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::user_error>&)
{
return user_indeterminate_result_error(function, message, val);
}
} // namespace detail
template <class T, class Policy>
inline T raise_domain_error(const char* function, const char* message, const T& val, const Policy&)
{
typedef typename Policy::domain_error_type policy_type;
return detail::raise_domain_error(
function, message ? message : "Domain Error evaluating function at %1%",
val, policy_type());
}
template <class T, class Policy>
inline T raise_pole_error(const char* function, const char* message, const T& val, const Policy&)
{
typedef typename Policy::pole_error_type policy_type;
return detail::raise_pole_error(
function, message ? message : "Evaluation of function at pole %1%",
val, policy_type());
}
template <class T, class Policy>
inline T raise_overflow_error(const char* function, const char* message, const Policy&)
{
typedef typename Policy::overflow_error_type policy_type;
return detail::raise_overflow_error<T>(
function, message ? message : "Overflow Error",
policy_type());
}
template <class T, class Policy>
inline T raise_underflow_error(const char* function, const char* message, const Policy&)
{
typedef typename Policy::underflow_error_type policy_type;
return detail::raise_underflow_error<T>(
function, message ? message : "Underflow Error",
policy_type());
}
template <class T, class Policy>
inline T raise_denorm_error(const char* function, const char* message, const T& val, const Policy&)
{
typedef typename Policy::denorm_error_type policy_type;
return detail::raise_denorm_error<T>(
function, message ? message : "Denorm Error",
val,
policy_type());
}
template <class T, class Policy>
inline T raise_evaluation_error(const char* function, const char* message, const T& val, const Policy&)
{
typedef typename Policy::evaluation_error_type policy_type;
return detail::raise_evaluation_error(
function, message ? message : "Internal Evaluation Error, best value so far was %1%",
val, policy_type());
}
template <class T, class TargetType, class Policy>
inline T raise_rounding_error(const char* function, const char* message, const T& val, const TargetType& t, const Policy&)
{
typedef typename Policy::rounding_error_type policy_type;
return detail::raise_rounding_error(
function, message ? message : "Value %1% can not be represented in the target integer type.",
val, t, policy_type());
}
template <class T, class R, class Policy>
inline T raise_indeterminate_result_error(const char* function, const char* message, const T& val, const R& result, const Policy&)
{
typedef typename Policy::indeterminate_result_error_type policy_type;
return detail::raise_indeterminate_result_error(
function, message ? message : "Indeterminate result with value %1%",
val, result, policy_type());
}
//
// checked_narrowing_cast:
//
namespace detail
{
template <class R, class T, class Policy>
inline bool check_overflow(T val, R* result, const char* function, const Policy& pol)
{
BOOST_MATH_STD_USING
if(fabs(val) > tools::max_value<R>())
{
*result = static_cast<R>(boost::math::policies::detail::raise_overflow_error<R>(function, 0, pol));
return true;
}
return false;
}
template <class R, class T, class Policy>
inline bool check_overflow(std::complex<T> val, R* result, const char* function, const Policy& pol)
{
typedef typename R::value_type r_type;
r_type re, im;
bool r = check_overflow<r_type>(val.real(), &re, function, pol) || check_overflow<r_type>(val.imag(), &im, function, pol);
*result = R(re, im);
return r;
}
template <class R, class T, class Policy>
inline bool check_underflow(T val, R* result, const char* function, const Policy& pol)
{
if((val != 0) && (static_cast<R>(val) == 0))
{
*result = static_cast<R>(boost::math::policies::detail::raise_underflow_error<R>(function, 0, pol));
return true;
}
return false;
}
template <class R, class T, class Policy>
inline bool check_underflow(std::complex<T> val, R* result, const char* function, const Policy& pol)
{
typedef typename R::value_type r_type;
r_type re, im;
bool r = check_underflow<r_type>(val.real(), &re, function, pol) || check_underflow<r_type>(val.imag(), &im, function, pol);
*result = R(re, im);
return r;
}
template <class R, class T, class Policy>
inline bool check_denorm(T val, R* result, const char* function, const Policy& pol)
{
BOOST_MATH_STD_USING
if((fabs(val) < static_cast<T>(tools::min_value<R>())) && (static_cast<R>(val) != 0))
{
*result = static_cast<R>(boost::math::policies::detail::raise_denorm_error<R>(function, 0, static_cast<R>(val), pol));
return true;
}
return false;
}
template <class R, class T, class Policy>
inline bool check_denorm(std::complex<T> val, R* result, const char* function, const Policy& pol)
{
typedef typename R::value_type r_type;
r_type re, im;
bool r = check_denorm<r_type>(val.real(), &re, function, pol) || check_denorm<r_type>(val.imag(), &im, function, pol);
*result = R(re, im);
return r;
}
// Default instantiations with ignore_error policy.
template <class R, class T>
inline bool check_overflow(T /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&){ return false; }
template <class R, class T>
inline bool check_overflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&){ return false; }
template <class R, class T>
inline bool check_underflow(T /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&){ return false; }
template <class R, class T>
inline bool check_underflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&){ return false; }
template <class R, class T>
inline bool check_denorm(T /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&){ return false; }
template <class R, class T>
inline bool check_denorm(std::complex<T> /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&){ return false; }
} // namespace detail
template <class R, class Policy, class T>
inline R checked_narrowing_cast(T val, const char* function)
{
typedef typename Policy::overflow_error_type overflow_type;
typedef typename Policy::underflow_error_type underflow_type;
typedef typename Policy::denorm_error_type denorm_type;
//
// Most of what follows will evaluate to a no-op:
//
R result = 0;
if(detail::check_overflow<R>(val, &result, function, overflow_type()))
return result;
if(detail::check_underflow<R>(val, &result, function, underflow_type()))
return result;
if(detail::check_denorm<R>(val, &result, function, denorm_type()))
return result;
return static_cast<R>(val);
}
template <class T, class Policy>
inline void check_series_iterations(const char* function, boost::uintmax_t max_iter, const Policy& pol)
{
if(max_iter >= policies::get_max_series_iterations<Policy>())
raise_evaluation_error<T>(
function,
"Series evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
}
template <class T, class Policy>
inline void check_root_iterations(const char* function, boost::uintmax_t max_iter, const Policy& pol)
{
if(max_iter >= policies::get_max_root_iterations<Policy>())
raise_evaluation_error<T>(
function,
"Root finding evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
}
} //namespace policies
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
}} // namespaces boost/math
#endif // BOOST_MATH_POLICY_ERROR_HANDLING_HPP

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,69 +0,0 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_TOOLS_H
#define BOOST_MSM_BACK_TOOLS_H
#include <string>
#include <iostream>
#include <boost/msm/back/common_types.hpp>
#include <boost/msm/back/metafunctions.hpp>
#include <boost/type_index.hpp>
namespace boost { namespace msm { namespace back
{
// fills the array passed in with the state names in the correct order
// the array must be big enough. To know the needed size, use mpl::size
// on fsm::generate_state_set
template <class stt>
struct fill_state_names
{
fill_state_names(char const** names):m_names(names){}
template <class StateType>
void operator()(boost::msm::wrap<StateType> const&)
{
m_names[get_state_id<stt,StateType>::value]= type_id<StateType>().name_demangled();
}
private:
char const** m_names;
};
// fills the typeid-generated name of the given state in the string passed as argument
template <class stt>
struct get_state_name
{
get_state_name(std::string& name_to_fill, int state_id):m_name(name_to_fill),m_state_id(state_id){}
template <class StateType>
void operator()(boost::msm::wrap<StateType> const&)
{
if (get_state_id<stt,StateType>::value == m_state_id)
{
m_name = type_id<StateType>().name_demangled();
}
}
private:
std::string& m_name;
int m_state_id;
};
// displays the typeid of the given Type
struct display_type
{
template <class Type>
void operator()(boost::msm::wrap<Type> const&)
{
std::cout << type_id<Type>().name_demangled() << std::endl;
}
};
} } }//boost::msm::back
#endif //BOOST_MSM_BACK_TOOLS_H

View File

@ -1,345 +0,0 @@
#ifndef DYNAMIC_PROPERTY_MAP_RG09302004_HPP
#define DYNAMIC_PROPERTY_MAP_RG09302004_HPP
// Copyright 2004-5 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// dynamic_property_map.hpp -
// Support for runtime-polymorphic property maps. This header is factored
// out of Doug Gregor's routines for reading GraphML files for use in reading
// GraphViz graph files.
// Authors: Doug Gregor
// Ronald Garcia
//
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/any.hpp>
#include <boost/function/function3.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <typeinfo>
#include <boost/mpl/bool.hpp>
#include <stdexcept>
#include <sstream>
#include <map>
#include <boost/type.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/type_index.hpp>
namespace boost {
namespace detail {
// read_value -
// A wrapper around lexical_cast, which does not behave as
// desired for std::string types.
template<typename Value>
inline Value read_value(const std::string& value)
{ return boost::lexical_cast<Value>(value); }
template<>
inline std::string read_value<std::string>(const std::string& value)
{ return value; }
}
// dynamic_property_map -
// This interface supports polymorphic manipulation of property maps.
class dynamic_property_map
{
public:
virtual ~dynamic_property_map() { }
virtual boost::any get(const any& key) = 0;
virtual std::string get_string(const any& key) = 0;
virtual void put(const any& key, const any& value) = 0;
virtual type_index key() const = 0;
virtual type_index value() const = 0;
};
//////////////////////////////////////////////////////////////////////
// Property map exceptions
//////////////////////////////////////////////////////////////////////
struct dynamic_property_exception : public std::exception {
virtual ~dynamic_property_exception() throw() {}
virtual const char* what() const throw() = 0;
};
struct property_not_found : public dynamic_property_exception {
std::string property;
mutable std::string statement;
property_not_found(const std::string& property) : property(property) {}
virtual ~property_not_found() throw() {}
const char* what() const throw() {
if(statement.empty())
statement =
std::string("Property not found: ") + property + ".";
return statement.c_str();
}
};
struct dynamic_get_failure : public dynamic_property_exception {
std::string property;
mutable std::string statement;
dynamic_get_failure(const std::string& property) : property(property) {}
virtual ~dynamic_get_failure() throw() {}
const char* what() const throw() {
if(statement.empty())
statement =
std::string(
"dynamic property get cannot retrieve value for property: ")
+ property + ".";
return statement.c_str();
}
};
struct dynamic_const_put_error : public dynamic_property_exception {
virtual ~dynamic_const_put_error() throw() {}
const char* what() const throw() {
return "Attempt to put a value into a const property map: ";
}
};
namespace detail {
// Trying to work around VC++ problem that seems to relate to having too many
// functions named "get"
template <typename PMap, typename Key>
typename boost::property_traits<PMap>::reference
get_wrapper_xxx(const PMap& pmap, const Key& key) {
using boost::get;
return get(pmap, key);
}
//
// dynamic_property_map_adaptor -
// property-map adaptor to support runtime polymorphism.
template<typename PropertyMap>
class dynamic_property_map_adaptor : public dynamic_property_map
{
typedef typename property_traits<PropertyMap>::key_type key_type;
typedef typename property_traits<PropertyMap>::value_type value_type;
typedef typename property_traits<PropertyMap>::category category;
// do_put - overloaded dispatches from the put() member function.
// Attempts to "put" to a property map that does not model
// WritablePropertyMap result in a runtime exception.
// in_value must either hold an object of value_type or a string that
// can be converted to value_type via iostreams.
void do_put(const any& in_key, const any& in_value, mpl::bool_<true>)
{
using boost::put;
key_type key = any_cast<key_type>(in_key);
if (in_value.type() == type_id<value_type>()) {
put(property_map_, key, any_cast<value_type>(in_value));
} else {
// if in_value is an empty string, put a default constructed value_type.
std::string v = any_cast<std::string>(in_value);
if (v.empty()) {
put(property_map_, key, value_type());
} else {
put(property_map_, key, detail::read_value<value_type>(v));
}
}
}
void do_put(const any&, const any&, mpl::bool_<false>)
{
BOOST_THROW_EXCEPTION(dynamic_const_put_error());
}
public:
explicit dynamic_property_map_adaptor(const PropertyMap& property_map_)
: property_map_(property_map_) { }
virtual boost::any get(const any& key)
{
return get_wrapper_xxx(property_map_, any_cast<key_type>(key));
}
virtual std::string get_string(const any& key)
{
std::ostringstream out;
out << get_wrapper_xxx(property_map_, any_cast<key_type>(key));
return out.str();
}
virtual void put(const any& in_key, const any& in_value)
{
do_put(in_key, in_value,
mpl::bool_<(is_convertible<category*,
writable_property_map_tag*>::value)>());
}
virtual type_index key() const { return type_id<key_type>(); }
virtual type_index value() const { return type_id<value_type>(); }
PropertyMap& base() { return property_map_; }
const PropertyMap& base() const { return property_map_; }
private:
PropertyMap property_map_;
};
} // namespace detail
//
// dynamic_properties -
// container for dynamic property maps
//
struct dynamic_properties
{
typedef std::multimap<std::string, boost::shared_ptr<dynamic_property_map> >
property_maps_type;
typedef boost::function3<boost::shared_ptr<dynamic_property_map>,
const std::string&,
const boost::any&,
const boost::any&> generate_fn_type;
public:
typedef property_maps_type::iterator iterator;
typedef property_maps_type::const_iterator const_iterator;
dynamic_properties() : generate_fn() { }
dynamic_properties(const generate_fn_type& g) : generate_fn(g) {}
~dynamic_properties() {}
template<typename PropertyMap>
dynamic_properties&
property(const std::string& name, PropertyMap property_map_)
{
boost::shared_ptr<dynamic_property_map> pm(
boost::make_shared<detail::dynamic_property_map_adaptor<PropertyMap> >(property_map_));
property_maps.insert(property_maps_type::value_type(name, pm));
return *this;
}
iterator begin() { return property_maps.begin(); }
const_iterator begin() const { return property_maps.begin(); }
iterator end() { return property_maps.end(); }
const_iterator end() const { return property_maps.end(); }
iterator lower_bound(const std::string& name)
{ return property_maps.lower_bound(name); }
const_iterator lower_bound(const std::string& name) const
{ return property_maps.lower_bound(name); }
void
insert(const std::string& name, boost::shared_ptr<dynamic_property_map> pm)
{
property_maps.insert(property_maps_type::value_type(name, pm));
}
template<typename Key, typename Value>
boost::shared_ptr<dynamic_property_map>
generate(const std::string& name, const Key& key, const Value& value)
{
if(!generate_fn) {
BOOST_THROW_EXCEPTION(property_not_found(name));
} else {
return generate_fn(name,key,value);
}
}
private:
property_maps_type property_maps;
generate_fn_type generate_fn;
};
template<typename Key, typename Value>
bool
put(const std::string& name, dynamic_properties& dp, const Key& key,
const Value& value)
{
for (dynamic_properties::iterator i = dp.lower_bound(name);
i != dp.end() && i->first == name; ++i) {
if (i->second->key() == type_id<key>()) {
i->second->put(key, value);
return true;
}
}
boost::shared_ptr<dynamic_property_map> new_map = dp.generate(name, key, value);
if (new_map.get()) {
new_map->put(key, value);
dp.insert(name, new_map);
return true;
} else {
return false;
}
}
#ifndef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
template<typename Value, typename Key>
Value
get(const std::string& name, const dynamic_properties& dp, const Key& key)
{
for (dynamic_properties::const_iterator i = dp.lower_bound(name);
i != dp.end() && i->first == name; ++i) {
if (i->second->key() == type_id<key>())
return any_cast<Value>(i->second->get(key));
}
BOOST_THROW_EXCEPTION(dynamic_get_failure(name));
}
#endif
template<typename Value, typename Key>
Value
get(const std::string& name, const dynamic_properties& dp, const Key& key, type<Value>)
{
for (dynamic_properties::const_iterator i = dp.lower_bound(name);
i != dp.end() && i->first == name; ++i) {
if (i->second->key() == type_id<key>())
return any_cast<Value>(i->second->get(key));
}
BOOST_THROW_EXCEPTION(dynamic_get_failure(name));
}
template<typename Key>
std::string
get(const std::string& name, const dynamic_properties& dp, const Key& key)
{
for (dynamic_properties::const_iterator i = dp.lower_bound(name);
i != dp.end() && i->first == name; ++i) {
if (i->second->key() == type_id<key>())
return i->second->get_string(key);
}
BOOST_THROW_EXCEPTION(dynamic_get_failure(name));
}
// The easy way to ignore properties.
inline
boost::shared_ptr<boost::dynamic_property_map>
ignore_other_properties(const std::string&,
const boost::any&,
const boost::any&) {
return boost::shared_ptr<boost::dynamic_property_map>();
}
} // namespace boost
#endif // DYNAMIC_PROPERTY_MAP_RG09302004_HPP

View File

@ -0,0 +1,80 @@
Index: .
===================================================================
--- . (revision 86520)
+++ . (working copy)
@@ -24,7 +24,7 @@
#include <boost/any.hpp>
#include <boost/function/function3.hpp>
#include <boost/type_traits/is_convertible.hpp>
-#include <typeinfo>
+#include <boost/type_index/type_info.hpp>
#include <boost/mpl/bool.hpp>
#include <stdexcept>
#include <sstream>
@@ -60,8 +60,8 @@
virtual boost::any get(const any& key) = 0;
virtual std::string get_string(const any& key) = 0;
virtual void put(const any& key, const any& value) = 0;
- virtual const std::type_info& key() const = 0;
- virtual const std::type_info& value() const = 0;
+ virtual const boost::type_info& key() const = 0;
+ virtual const boost::type_info& value() const = 0;
};
@@ -147,7 +147,7 @@
using boost::put;
key_type key = any_cast<key_type>(in_key);
- if (in_value.type() == typeid(value_type)) {
+ if (in_value.type() == boost::type_id<value_type>()) {
put(property_map_, key, any_cast<value_type>(in_value));
} else {
// if in_value is an empty string, put a default constructed value_type.
@@ -188,8 +188,8 @@
writable_property_map_tag*>::value)>());
}
- virtual const std::type_info& key() const { return typeid(key_type); }
- virtual const std::type_info& value() const { return typeid(value_type); }
+ virtual const boost::type_info& key() const { return boost::type_id<key_type>(); }
+ virtual const boost::type_info& value() const { return boost::type_id<value_type>(); }
PropertyMap& base() { return property_map_; }
const PropertyMap& base() const { return property_map_; }
@@ -283,7 +283,7 @@
{
for (dynamic_properties::iterator i = dp.lower_bound(name);
i != dp.end() && i->first == name; ++i) {
- if (i->second->key() == typeid(key)) {
+ if (i->second->key() == boost::type_id<Key>()) {
i->second->put(key, value);
return true;
}
@@ -305,7 +305,7 @@
{
for (dynamic_properties::const_iterator i = dp.lower_bound(name);
i != dp.end() && i->first == name; ++i) {
- if (i->second->key() == typeid(key))
+ if (i->second->key() == boost::type_id<Key>())
return any_cast<Value>(i->second->get(key));
}
@@ -318,7 +318,7 @@
{
for (dynamic_properties::const_iterator i = dp.lower_bound(name);
i != dp.end() && i->first == name; ++i) {
- if (i->second->key() == typeid(key))
+ if (i->second->key() == boost::type_id<Key>())
return any_cast<Value>(i->second->get(key));
}
@@ -331,7 +331,7 @@
{
for (dynamic_properties::const_iterator i = dp.lower_bound(name);
i != dp.end() && i->first == name; ++i) {
- if (i->second->key() == typeid(key))
+ if (i->second->key() == boost::type_id<Key>())
return i->second->get_string(key);
}

View File

@ -1,915 +0,0 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
// Copyright (C) 2009 Sebastian Redl
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/assert.hpp>
#include <boost/type_index.hpp>
#include <boost/utility/swap.hpp>
#include <memory>
#if (defined(BOOST_MSVC) && \
(_MSC_FULL_VER >= 160000000 && _MSC_FULL_VER < 170000000)) || \
(defined(BOOST_INTEL_WIN) && \
defined(BOOST_DINKUMWARE_STDLIB))
#define BOOST_PROPERTY_TREE_PAIR_BUG
#endif
namespace boost { namespace property_tree
{
template <class K, class D, class C>
struct basic_ptree<K, D, C>::subs
{
struct by_name {};
// The actual child container.
#if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
// MSVC 10 has moved std::pair's members to a base
// class. Unfortunately this does break the interface.
BOOST_STATIC_CONSTANT(unsigned,
first_offset = offsetof(value_type, first));
#endif
typedef multi_index_container<value_type,
multi_index::indexed_by<
multi_index::sequenced<>,
multi_index::ordered_non_unique<multi_index::tag<by_name>,
#if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
multi_index::member_offset<value_type, const key_type,
first_offset>,
#else
multi_index::member<value_type, const key_type,
&value_type::first>,
#endif
key_compare
>
>
> base_container;
// The by-name lookup index.
typedef typename base_container::template index<by_name>::type
by_name_index;
// Access functions for getting to the children of a tree.
static base_container& ch(self_type *s) {
return *static_cast<base_container*>(s->m_children);
}
static const base_container& ch(const self_type *s) {
return *static_cast<const base_container*>(s->m_children);
}
static by_name_index& assoc(self_type *s) {
return ch(s).BOOST_NESTED_TEMPLATE get<by_name>();
}
static const by_name_index& assoc(const self_type *s) {
return ch(s).BOOST_NESTED_TEMPLATE get<by_name>();
}
};
template <class K, class D, class C>
class basic_ptree<K, D, C>::iterator : public boost::iterator_adaptor<
iterator, typename subs::base_container::iterator, value_type>
{
friend class boost::iterator_core_access;
typedef boost::iterator_adaptor<
iterator, typename subs::base_container::iterator, value_type>
baset;
public:
typedef typename baset::reference reference;
iterator() {}
explicit iterator(typename iterator::base_type b)
: iterator::iterator_adaptor_(b)
{}
reference dereference() const
{
// multi_index doesn't allow modification of its values, because
// indexes could sort by anything, and modification screws that up.
// However, we only sort by the key, and it's protected against
// modification in the value_type, so this const_cast is safe.
return const_cast<reference>(*this->base_reference());
}
};
template <class K, class D, class C>
class basic_ptree<K, D, C>::const_iterator : public boost::iterator_adaptor<
const_iterator, typename subs::base_container::const_iterator>
{
public:
const_iterator() {}
explicit const_iterator(typename const_iterator::base_type b)
: const_iterator::iterator_adaptor_(b)
{}
const_iterator(iterator b)
: const_iterator::iterator_adaptor_(b.base())
{}
};
template <class K, class D, class C>
class basic_ptree<K, D, C>::reverse_iterator
: public boost::reverse_iterator<iterator>
{
public:
reverse_iterator() {}
explicit reverse_iterator(iterator b)
: boost::reverse_iterator<iterator>(b)
{}
};
template <class K, class D, class C>
class basic_ptree<K, D, C>::const_reverse_iterator
: public boost::reverse_iterator<const_iterator>
{
public:
const_reverse_iterator() {}
explicit const_reverse_iterator(const_iterator b)
: boost::reverse_iterator<const_iterator>(b)
{}
const_reverse_iterator(
typename basic_ptree<K, D, C>::reverse_iterator b)
: boost::reverse_iterator<const_iterator>(b)
{}
};
template <class K, class D, class C>
class basic_ptree<K, D, C>::assoc_iterator
: public boost::iterator_adaptor<assoc_iterator,
typename subs::by_name_index::iterator,
value_type>
{
friend class boost::iterator_core_access;
typedef boost::iterator_adaptor<assoc_iterator,
typename subs::by_name_index::iterator,
value_type>
baset;
public:
typedef typename baset::reference reference;
assoc_iterator() {}
explicit assoc_iterator(typename assoc_iterator::base_type b)
: assoc_iterator::iterator_adaptor_(b)
{}
reference dereference() const
{
return const_cast<reference>(*this->base_reference());
}
};
template <class K, class D, class C>
class basic_ptree<K, D, C>::const_assoc_iterator
: public boost::iterator_adaptor<const_assoc_iterator,
typename subs::by_name_index::const_iterator>
{
public:
const_assoc_iterator() {}
explicit const_assoc_iterator(
typename const_assoc_iterator::base_type b)
: const_assoc_iterator::iterator_adaptor_(b)
{}
const_assoc_iterator(assoc_iterator b)
: const_assoc_iterator::iterator_adaptor_(b.base())
{}
};
// Big five
// Perhaps the children collection could be created on-demand only, to
// reduce heap traffic. But that's a lot more work to implement.
template<class K, class D, class C> inline
basic_ptree<K, D, C>::basic_ptree()
: m_children(new typename subs::base_container)
{
}
template<class K, class D, class C> inline
basic_ptree<K, D, C>::basic_ptree(const data_type &d)
: m_data(d), m_children(new typename subs::base_container)
{
}
template<class K, class D, class C> inline
basic_ptree<K, D, C>::basic_ptree(const basic_ptree<K, D, C> &rhs)
: m_data(rhs.m_data),
m_children(new typename subs::base_container(subs::ch(&rhs)))
{
}
template<class K, class D, class C>
basic_ptree<K, D, C> &
basic_ptree<K, D, C>::operator =(const basic_ptree<K, D, C> &rhs)
{
self_type(rhs).swap(*this);
return *this;
}
template<class K, class D, class C>
basic_ptree<K, D, C>::~basic_ptree()
{
delete &subs::ch(this);
}
template<class K, class D, class C> inline
void basic_ptree<K, D, C>::swap(basic_ptree<K, D, C> &rhs)
{
boost::swap(m_data, rhs.m_data);
// Void pointers, no ADL necessary
std::swap(m_children, rhs.m_children);
}
// Container view
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::size_type
basic_ptree<K, D, C>::size() const
{
return subs::ch(this).size();
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::size_type
basic_ptree<K, D, C>::max_size() const
{
return subs::ch(this).max_size();
}
template<class K, class D, class C> inline
bool basic_ptree<K, D, C>::empty() const
{
return subs::ch(this).empty();
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::iterator
basic_ptree<K, D, C>::begin()
{
return iterator(subs::ch(this).begin());
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::const_iterator
basic_ptree<K, D, C>::begin() const
{
return const_iterator(subs::ch(this).begin());
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::iterator
basic_ptree<K, D, C>::end()
{
return iterator(subs::ch(this).end());
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::const_iterator
basic_ptree<K, D, C>::end() const
{
return const_iterator(subs::ch(this).end());
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::reverse_iterator
basic_ptree<K, D, C>::rbegin()
{
return reverse_iterator(this->end());
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::const_reverse_iterator
basic_ptree<K, D, C>::rbegin() const
{
return const_reverse_iterator(this->end());
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::reverse_iterator
basic_ptree<K, D, C>::rend()
{
return reverse_iterator(this->begin());
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::const_reverse_iterator
basic_ptree<K, D, C>::rend() const
{
return const_reverse_iterator(this->begin());
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::value_type &
basic_ptree<K, D, C>::front()
{
return const_cast<value_type&>(subs::ch(this).front());
}
template<class K, class D, class C> inline
const typename basic_ptree<K, D, C>::value_type &
basic_ptree<K, D, C>::front() const
{
return subs::ch(this).front();
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::value_type &
basic_ptree<K, D, C>::back()
{
return const_cast<value_type&>(subs::ch(this).back());
}
template<class K, class D, class C> inline
const typename basic_ptree<K, D, C>::value_type &
basic_ptree<K, D, C>::back() const
{
return subs::ch(this).back();
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::iterator
basic_ptree<K, D, C>::insert(iterator where, const value_type &value)
{
return iterator(subs::ch(this).insert(where.base(), value).first);
}
template<class K, class D, class C>
template<class It> inline
void basic_ptree<K, D, C>::insert(iterator where, It first, It last)
{
subs::ch(this).insert(where.base(), first, last);
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::iterator
basic_ptree<K, D, C>::erase(iterator where)
{
return iterator(subs::ch(this).erase(where.base()));
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::iterator
basic_ptree<K, D, C>::erase(iterator first, iterator last)
{
return iterator(subs::ch(this).erase(first.base(), last.base()));
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::iterator
basic_ptree<K, D, C>::push_front(const value_type &value)
{
return iterator(subs::ch(this).push_front(value).first);
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::iterator
basic_ptree<K, D, C>::push_back(const value_type &value)
{
return iterator(subs::ch(this).push_back(value).first);
}
template<class K, class D, class C> inline
void basic_ptree<K, D, C>::pop_front()
{
subs::ch(this).pop_front();
}
template<class K, class D, class C> inline
void basic_ptree<K, D, C>::pop_back()
{
subs::ch(this).pop_back();
}
template<class K, class D, class C> inline
void basic_ptree<K, D, C>::reverse()
{
subs::ch(this).reverse();
}
namespace impl
{
struct by_first
{
template <typename P>
bool operator ()(const P& lhs, const P& rhs) const {
return lhs.first < rhs.first;
}
};
}
template<class K, class D, class C> inline
void basic_ptree<K, D, C>::sort()
{
sort(impl::by_first());
}
template<class K, class D, class C>
template<class Compare> inline
void basic_ptree<K, D, C>::sort(Compare comp)
{
subs::ch(this).sort(comp);
}
// Equality
template<class K, class D, class C> inline
bool basic_ptree<K, D, C>::operator ==(
const basic_ptree<K, D, C> &rhs) const
{
// The size test is cheap, so add it as an optimization
return size() == rhs.size() && data() == rhs.data() &&
subs::ch(this) == subs::ch(&rhs);
}
template<class K, class D, class C> inline
bool basic_ptree<K, D, C>::operator !=(
const basic_ptree<K, D, C> &rhs) const
{
return !(*this == rhs);
}
// Associative view
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::assoc_iterator
basic_ptree<K, D, C>::ordered_begin()
{
return assoc_iterator(subs::assoc(this).begin());
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::const_assoc_iterator
basic_ptree<K, D, C>::ordered_begin() const
{
return const_assoc_iterator(subs::assoc(this).begin());
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::assoc_iterator
basic_ptree<K, D, C>::not_found()
{
return assoc_iterator(subs::assoc(this).end());
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::const_assoc_iterator
basic_ptree<K, D, C>::not_found() const
{
return const_assoc_iterator(subs::assoc(this).end());
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::assoc_iterator
basic_ptree<K, D, C>::find(const key_type &key)
{
return assoc_iterator(subs::assoc(this).find(key));
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::const_assoc_iterator
basic_ptree<K, D, C>::find(const key_type &key) const
{
return const_assoc_iterator(subs::assoc(this).find(key));
}
template<class K, class D, class C> inline
std::pair<
typename basic_ptree<K, D, C>::assoc_iterator,
typename basic_ptree<K, D, C>::assoc_iterator
> basic_ptree<K, D, C>::equal_range(const key_type &key)
{
std::pair<typename subs::by_name_index::iterator,
typename subs::by_name_index::iterator> r(
subs::assoc(this).equal_range(key));
return std::pair<assoc_iterator, assoc_iterator>(
assoc_iterator(r.first), assoc_iterator(r.second));
}
template<class K, class D, class C> inline
std::pair<
typename basic_ptree<K, D, C>::const_assoc_iterator,
typename basic_ptree<K, D, C>::const_assoc_iterator
> basic_ptree<K, D, C>::equal_range(const key_type &key) const
{
std::pair<typename subs::by_name_index::const_iterator,
typename subs::by_name_index::const_iterator> r(
subs::assoc(this).equal_range(key));
return std::pair<const_assoc_iterator, const_assoc_iterator>(
const_assoc_iterator(r.first), const_assoc_iterator(r.second));
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::size_type
basic_ptree<K, D, C>::count(const key_type &key) const
{
return subs::assoc(this).count(key);
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::size_type
basic_ptree<K, D, C>::erase(const key_type &key)
{
return subs::assoc(this).erase(key);
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::iterator
basic_ptree<K, D, C>::to_iterator(assoc_iterator ai)
{
return iterator(subs::ch(this).
BOOST_NESTED_TEMPLATE project<0>(ai.base()));
}
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::const_iterator
basic_ptree<K, D, C>::to_iterator(const_assoc_iterator ai) const
{
return const_iterator(subs::ch(this).
BOOST_NESTED_TEMPLATE project<0>(ai.base()));
}
// Property tree view
template<class K, class D, class C> inline
typename basic_ptree<K, D, C>::data_type &
basic_ptree<K, D, C>::data()
{
return m_data;
}
template<class K, class D, class C> inline
const typename basic_ptree<K, D, C>::data_type &
basic_ptree<K, D, C>::data() const
{
return m_data;
}
template<class K, class D, class C> inline
void basic_ptree<K, D, C>::clear()
{
m_data = data_type();
subs::ch(this).clear();
}
template<class K, class D, class C>
basic_ptree<K, D, C> &
basic_ptree<K, D, C>::get_child(const path_type &path)
{
path_type p(path);
self_type *n = walk_path(p);
if (!n) {
BOOST_PROPERTY_TREE_THROW(ptree_bad_path("No such node", path));
}
return *n;
}
template<class K, class D, class C> inline
const basic_ptree<K, D, C> &
basic_ptree<K, D, C>::get_child(const path_type &path) const
{
return const_cast<self_type*>(this)->get_child(path);
}
template<class K, class D, class C> inline
basic_ptree<K, D, C> &
basic_ptree<K, D, C>::get_child(const path_type &path,
self_type &default_value)
{
path_type p(path);
self_type *n = walk_path(p);
return n ? *n : default_value;
}
template<class K, class D, class C> inline
const basic_ptree<K, D, C> &
basic_ptree<K, D, C>::get_child(const path_type &path,
const self_type &default_value) const
{
return const_cast<self_type*>(this)->get_child(path,
const_cast<self_type&>(default_value));
}
template<class K, class D, class C>
optional<basic_ptree<K, D, C> &>
basic_ptree<K, D, C>::get_child_optional(const path_type &path)
{
path_type p(path);
self_type *n = walk_path(p);
if (!n) {
return optional<self_type&>();
}
return *n;
}
template<class K, class D, class C>
optional<const basic_ptree<K, D, C> &>
basic_ptree<K, D, C>::get_child_optional(const path_type &path) const
{
path_type p(path);
self_type *n = walk_path(p);
if (!n) {
return optional<const self_type&>();
}
return *n;
}
template<class K, class D, class C>
basic_ptree<K, D, C> &
basic_ptree<K, D, C>::put_child(const path_type &path,
const self_type &value)
{
path_type p(path);
self_type &parent = force_path(p);
// Got the parent. Now get the correct child.
key_type fragment = p.reduce();
assoc_iterator el = parent.find(fragment);
// If the new child exists, replace it.
if(el != parent.not_found()) {
return el->second = value;
} else {
return parent.push_back(value_type(fragment, value))->second;
}
}
template<class K, class D, class C>
basic_ptree<K, D, C> &
basic_ptree<K, D, C>::add_child(const path_type &path,
const self_type &value)
{
path_type p(path);
self_type &parent = force_path(p);
// Got the parent.
key_type fragment = p.reduce();
return parent.push_back(value_type(fragment, value))->second;
}
template<class K, class D, class C>
template<class Type, class Translator>
typename boost::enable_if<detail::is_translator<Translator>, Type>::type
basic_ptree<K, D, C>::get_value(Translator tr) const
{
if(boost::optional<Type> o = get_value_optional<Type>(tr)) {
return *o;
}
BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
std::string("conversion of data to type \"") +
type_id<Type>().name_demangled() + "\" failed", data()));
}
template<class K, class D, class C>
template<class Type> inline
Type basic_ptree<K, D, C>::get_value() const
{
return get_value<Type>(
typename translator_between<data_type, Type>::type());
}
template<class K, class D, class C>
template<class Type, class Translator> inline
Type basic_ptree<K, D, C>::get_value(const Type &default_value,
Translator tr) const
{
return get_value_optional<Type>(tr).get_value_or(default_value);
}
template<class K, class D, class C>
template <class Ch, class Translator>
typename boost::enable_if<
detail::is_character<Ch>,
std::basic_string<Ch>
>::type
basic_ptree<K, D, C>::get_value(const Ch *default_value, Translator tr)const
{
return get_value<std::basic_string<Ch>, Translator>(default_value, tr);
}
template<class K, class D, class C>
template<class Type> inline
typename boost::disable_if<detail::is_translator<Type>, Type>::type
basic_ptree<K, D, C>::get_value(const Type &default_value) const
{
return get_value(default_value,
typename translator_between<data_type, Type>::type());
}
template<class K, class D, class C>
template <class Ch>
typename boost::enable_if<
detail::is_character<Ch>,
std::basic_string<Ch>
>::type
basic_ptree<K, D, C>::get_value(const Ch *default_value) const
{
return get_value< std::basic_string<Ch> >(default_value);
}
template<class K, class D, class C>
template<class Type, class Translator> inline
optional<Type> basic_ptree<K, D, C>::get_value_optional(
Translator tr) const
{
return tr.get_value(data());
}
template<class K, class D, class C>
template<class Type> inline
optional<Type> basic_ptree<K, D, C>::get_value_optional() const
{
return get_value_optional<Type>(
typename translator_between<data_type, Type>::type());
}
template<class K, class D, class C>
template<class Type, class Translator> inline
typename boost::enable_if<detail::is_translator<Translator>, Type>::type
basic_ptree<K, D, C>::get(const path_type &path,
Translator tr) const
{
return get_child(path).BOOST_NESTED_TEMPLATE get_value<Type>(tr);
}
template<class K, class D, class C>
template<class Type> inline
Type basic_ptree<K, D, C>::get(const path_type &path) const
{
return get_child(path).BOOST_NESTED_TEMPLATE get_value<Type>();
}
template<class K, class D, class C>
template<class Type, class Translator> inline
Type basic_ptree<K, D, C>::get(const path_type &path,
const Type &default_value,
Translator tr) const
{
return get_optional<Type>(path, tr).get_value_or(default_value);
}
template<class K, class D, class C>
template <class Ch, class Translator>
typename boost::enable_if<
detail::is_character<Ch>,
std::basic_string<Ch>
>::type
basic_ptree<K, D, C>::get(
const path_type &path, const Ch *default_value, Translator tr) const
{
return get<std::basic_string<Ch>, Translator>(path, default_value, tr);
}
template<class K, class D, class C>
template<class Type> inline
typename boost::disable_if<detail::is_translator<Type>, Type>::type
basic_ptree<K, D, C>::get(const path_type &path,
const Type &default_value) const
{
return get_optional<Type>(path).get_value_or(default_value);
}
template<class K, class D, class C>
template <class Ch>
typename boost::enable_if<
detail::is_character<Ch>,
std::basic_string<Ch>
>::type
basic_ptree<K, D, C>::get(
const path_type &path, const Ch *default_value) const
{
return get< std::basic_string<Ch> >(path, default_value);
}
template<class K, class D, class C>
template<class Type, class Translator>
optional<Type> basic_ptree<K, D, C>::get_optional(const path_type &path,
Translator tr) const
{
if (optional<const self_type&> child = get_child_optional(path))
return child.get().
BOOST_NESTED_TEMPLATE get_value_optional<Type>(tr);
else
return optional<Type>();
}
template<class K, class D, class C>
template<class Type>
optional<Type> basic_ptree<K, D, C>::get_optional(
const path_type &path) const
{
if (optional<const self_type&> child = get_child_optional(path))
return child.get().BOOST_NESTED_TEMPLATE get_value_optional<Type>();
else
return optional<Type>();
}
template<class K, class D, class C>
template<class Type, class Translator>
void basic_ptree<K, D, C>::put_value(const Type &value, Translator tr)
{
if(optional<data_type> o = tr.put_value(value)) {
data() = *o;
} else {
BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
std::string("conversion of type \"") + type_id<Type>().name_demangled() +
"\" to data failed", boost::any()));
}
}
template<class K, class D, class C>
template<class Type> inline
void basic_ptree<K, D, C>::put_value(const Type &value)
{
put_value(value, typename translator_between<data_type, Type>::type());
}
template<class K, class D, class C>
template<class Type, typename Translator>
basic_ptree<K, D, C> & basic_ptree<K, D, C>::put(
const path_type &path, const Type &value, Translator tr)
{
if(optional<self_type &> child = get_child_optional(path)) {
child.get().put_value(value, tr);
return *child;
} else {
self_type &child2 = put_child(path, self_type());
child2.put_value(value, tr);
return child2;
}
}
template<class K, class D, class C>
template<class Type> inline
basic_ptree<K, D, C> & basic_ptree<K, D, C>::put(
const path_type &path, const Type &value)
{
return put(path, value,
typename translator_between<data_type, Type>::type());
}
template<class K, class D, class C>
template<class Type, typename Translator> inline
basic_ptree<K, D, C> & basic_ptree<K, D, C>::add(
const path_type &path, const Type &value, Translator tr)
{
self_type &child = add_child(path, self_type());
child.put_value(value, tr);
return child;
}
template<class K, class D, class C>
template<class Type> inline
basic_ptree<K, D, C> & basic_ptree<K, D, C>::add(
const path_type &path, const Type &value)
{
return add(path, value,
typename translator_between<data_type, Type>::type());
}
template<class K, class D, class C>
basic_ptree<K, D, C> *
basic_ptree<K, D, C>::walk_path(path_type &p) const
{
if(p.empty()) {
// I'm the child we're looking for.
return const_cast<basic_ptree*>(this);
}
// Recurse down the tree to find the path.
key_type fragment = p.reduce();
const_assoc_iterator el = find(fragment);
if(el == not_found()) {
// No such child.
return 0;
}
// Not done yet, recurse.
return el->second.walk_path(p);
}
template<class K, class D, class C>
basic_ptree<K, D, C> & basic_ptree<K, D, C>::force_path(path_type &p)
{
BOOST_ASSERT(!p.empty() && "Empty path not allowed for put_child.");
if(p.single()) {
// I'm the parent we're looking for.
return *this;
}
key_type fragment = p.reduce();
assoc_iterator el = find(fragment);
// If we've found an existing child, go down that path. Else
// create a new one.
self_type& child = el == not_found() ?
push_back(value_type(fragment, self_type()))->second : el->second;
return child.force_path(p);
}
// Free functions
template<class K, class D, class C>
inline void swap(basic_ptree<K, D, C> &pt1, basic_ptree<K, D, C> &pt2)
{
pt1.swap(pt2);
}
} }
#if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
#undef BOOST_PROPERTY_TREE_PAIR_BUG
#endif
#endif

View File

@ -0,0 +1,22 @@
Index: .
===================================================================
--- . (revision 86520)
+++ . (working copy)
@@ -650,7 +650,7 @@
}
BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
std::string("conversion of data to type \"") +
- typeid(Type).name() + "\" failed", data()));
+ boost::type_id<Type>().name_demangled() + "\" failed", data()));
}
template<class K, class D, class C>
@@ -805,7 +805,7 @@
data() = *o;
} else {
BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
- std::string("conversion of type \"") + typeid(Type).name() +
+ std::string("conversion of type \"") + boost::type_id<Type>().name_demangled() +
"\" to data failed", boost::any()));
}
}

View File

@ -0,0 +1,38 @@
Index: .
===================================================================
--- . (revision 86520)
+++ . (working copy)
@@ -19,7 +19,7 @@
#endif
#include <stack>
#include <limits>
-#include <typeinfo>
+#include <boost/type_index/type_info.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/version.hpp>
@@ -144,7 +144,7 @@
explicit xpression_linker(Traits const &tr)
: back_stack_()
, traits_(&tr)
- , traits_type_(&typeid(Traits))
+ , traits_type_(&boost::type_id<Traits>())
, has_backrefs_(false)
{
}
@@ -310,13 +310,13 @@
template<typename Traits>
Traits const &get_traits() const
{
- BOOST_ASSERT(*this->traits_type_ == typeid(Traits));
+ BOOST_ASSERT(*this->traits_type_ == boost::type_id<Traits>());
return *static_cast<Traits const *>(this->traits_);
}
std::stack<void const *> back_stack_;
void const *traits_;
- std::type_info const *traits_type_;
+ boost::type_info const *traits_type_;
bool has_backrefs_;
};

View File

@ -0,0 +1,33 @@
Index: .
===================================================================
--- . (revision 86520)
+++ . (working copy)
@@ -25,9 +25,9 @@
#include <vector>
#include <utility>
#include <iterator>
-#include <typeinfo>
#include <algorithm>
#include <boost/config.hpp>
+#include <boost/type_index/type_info.hpp>
#include <boost/assert.hpp>
#include <boost/integer.hpp>
#include <boost/mpl/if.hpp>
@@ -72,7 +72,7 @@
//
struct type_info_less
{
- bool operator()(std::type_info const *left, std::type_info const *right) const
+ bool operator()(boost::type_info const *left, boost::type_info const *right) const
{
return 0 != left->before(*right);
}
@@ -679,7 +679,7 @@
typedef typename proto::result_of::value<right_type>::type arg_right_type;
BOOST_MPL_ASSERT((proto::matches<Arg, detail::ActionArgBinding>));
BOOST_MPL_ASSERT((is_same<typename arg_left_type::type, arg_right_type>));
- this->args_[&typeid(proto::value(proto::left(arg)))] = &proto::value(proto::right(arg));
+ this->args_[&boost::type_id<arg_left_type>()] = &proto::value(proto::right(arg));
return *this;
}

View File

@ -0,0 +1,43 @@
Index: .
===================================================================
--- . (revision 86520)
+++ . (working copy)
@@ -14,7 +14,7 @@
#endif
#include <string>
-#include <typeinfo>
+#include <boost/type_index/type_info.hpp>
#include <boost/assert.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/assert.hpp>
@@ -250,9 +250,9 @@
if(0 == this->traits_)
{
this->traits_ = &tr;
- this->traits_type_ = &typeid(Traits);
+ this->traits_type_ = &boost::type_id<Traits>();
}
- else if(*this->traits_type_ != typeid(Traits) || this->get_traits_<Traits>() != tr)
+ else if(*this->traits_type_ != boost::type_id<Traits>() || this->get_traits_<Traits>() != tr)
{
this->fail(); // traits mis-match! set all and bail
}
@@ -265,7 +265,7 @@
template<typename Traits>
Traits const &get_traits_() const
{
- BOOST_ASSERT(!!(*this->traits_type_ == typeid(Traits)));
+ BOOST_ASSERT(!!(*this->traits_type_ == boost::type_id<Traits>()));
return *static_cast<Traits const *>(this->traits_);
}
@@ -274,7 +274,7 @@
bool str_icase_;
bool line_start_;
void const *traits_;
- std::type_info const *traits_type_;
+ boost::type_info const *traits_type_;
int leading_simple_repeat_;
bool has_backrefs_;
};