<commit_before>//
// Copyright 2016 Giovanni Mels
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "Utf8.hh"

namespace turtle {

	namespace utf8 {

		// This table maps bytes to character classes
		// to reduce the size of the transition table and create bitmasks.
		alignas(256) const std::uint8_t Decoder::m_type[] = {
			 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x00 - 0x1F
			 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x20 - 0x3F
			 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x40 - 0x5F
			 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x60 - 0x7F
			 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 0x80 - 0x9F
			 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // 0xA0 - 0xBF
			 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xC0 - 0xDF
			10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8  // 0xE0 - 0xFF
		};

		// This table is a transition table that maps a combination
		// of a state of the automaton and a character class to a state.
		alignas(256) const std::uint8_t Decoder::m_transition[] = {
			 0,12,24,36,60,96,84,12,12,12,48,72, // state  0 (ACCEPT)
			12,12,12,12,12,12,12,12,12,12,12,12, // state 12 (REJECT)
			12, 0,12,12,12,12,12, 0,12, 0,12,12, // state 24
			12,24,12,12,12,12,12,24,12,24,12,12, // state 36
			12,12,12,12,12,12,12,24,12,12,12,12, // state 48
			12,24,12,12,12,12,12,12,12,24,12,12, // state 60
			12,12,12,12,12,12,12,36,12,36,12,12, // state 72
			12,36,12,12,12,12,12,36,12,36,12,12, // state 84
			12,36,12,12,12,12,12,12,12,12,12,12  // state 96
		};
	}

}
<commit_msg>Removing alignas for issue #10.<commit_after>//
// Copyright 2016 Giovanni Mels
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "Utf8.hh"

namespace turtle {

	namespace utf8 {

		// This table maps bytes to character classes
		// to reduce the size of the transition table and create bitmasks.
		const std::uint8_t Decoder::m_type[] = {
			 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x00 - 0x1F
			 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x20 - 0x3F
			 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x40 - 0x5F
			 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x60 - 0x7F
			 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 0x80 - 0x9F
			 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // 0xA0 - 0xBF
			 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xC0 - 0xDF
			10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8  // 0xE0 - 0xFF
		};

		// This table is a transition table that maps a combination
		// of a state of the automaton and a character class to a state.
		const std::uint8_t Decoder::m_transition[] = {
			 0,12,24,36,60,96,84,12,12,12,48,72, // state  0 (ACCEPT)
			12,12,12,12,12,12,12,12,12,12,12,12, // state 12 (REJECT)
			12, 0,12,12,12,12,12, 0,12, 0,12,12, // state 24
			12,24,12,12,12,12,12,24,12,24,12,12, // state 36
			12,12,12,12,12,12,12,24,12,12,12,12, // state 48
			12,24,12,12,12,12,12,12,12,24,12,12, // state 60
			12,12,12,12,12,12,12,36,12,36,12,12, // state 72
			12,36,12,12,12,12,12,36,12,36,12,12, // state 84
			12,36,12,12,12,12,12,12,12,12,12,12  // state 96
		};
	}

}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2013 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_EVALUATE_GLOBAL_ATTRIBUTES_HPP
#define MAPNIK_EVALUATE_GLOBAL_ATTRIBUTES_HPP

#include <mapnik/map.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/symbolizer_hash.hpp>
#include <mapnik/attribute.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/expression_node.hpp>
#include <mapnik/color_factory.hpp>

// boost
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/regex.hpp>
#if defined(BOOST_REGEX_HAS_ICU)
#include <boost/regex/icu.hpp>
#endif

namespace mapnik {

namespace {

template <typename T, typename Attributes>
struct evaluate_expression : boost::static_visitor<T>
{
    typedef T value_type;

    explicit evaluate_expression(Attributes const& attributes)
        : attributes_(attributes) {}

    value_type operator() (attribute const& attr) const
    {
        throw std::runtime_error("can't evaluate feature attributes in this context");
    }

    value_type operator() (global_attribute const& attr) const
    {
        auto itr = attributes_.find(attr.name);
        if (itr != attributes_.end())
        {
            return itr->second;
        }
        return value_type();// throw?
    }

    value_type operator() (geometry_type_attribute const& geom) const
    {
        throw std::runtime_error("can't evaluate geometry_type attributes in this context");
    }

    value_type operator() (binary_node<tags::logical_and> const & x) const
    {
        return (boost::apply_visitor(*this, x.left).to_bool())
            && (boost::apply_visitor(*this, x.right).to_bool());
    }

    value_type operator() (binary_node<tags::logical_or> const & x) const
    {
        return (boost::apply_visitor(*this,x.left).to_bool())
            || (boost::apply_visitor(*this,x.right).to_bool());
    }

    template <typename Tag>
    value_type operator() (binary_node<Tag> const& x) const
    {
        typename make_op<Tag>::type operation;
        return operation(boost::apply_visitor(*this, x.left),
                         boost::apply_visitor(*this, x.right));
    }

    template <typename Tag>
    value_type operator() (unary_node<Tag> const& x) const
    {
        typename make_op<Tag>::type func;
        return func(boost::apply_visitor(*this, x.expr));
    }

    value_type operator() (unary_node<tags::logical_not> const& x) const
    {
        return ! (boost::apply_visitor(*this,x.expr).to_bool());
    }

    value_type operator() (regex_match_node const& x) const
    {
        value_type v = boost::apply_visitor(*this, x.expr);
#if defined(BOOST_REGEX_HAS_ICU)
        return boost::u32regex_match(v.to_unicode(),x.pattern);
#else
        return boost::regex_match(v.to_string(),x.pattern);
#endif

    }

    value_type operator() (regex_replace_node const& x) const
    {
        value_type v = boost::apply_visitor(*this, x.expr);
#if defined(BOOST_REGEX_HAS_ICU)
        return boost::u32regex_replace(v.to_unicode(),x.pattern,x.format);
#else
        std::string repl = boost::regex_replace(v.to_string(),x.pattern,x.format);
        mapnik::transcoder tr_("utf8");
        return tr_.transcode(repl.c_str());
#endif
    }

    template <typename ValueType>
    value_type operator() (ValueType const& val) const
    {
        return value_type(val);
    }

    Attributes const& attributes_;
};

template <typename T, typename Attributes>
struct assign_value : boost::static_visitor<> {};

template <typename Attributes>
struct assign_value<expression_ptr,Attributes> : boost::static_visitor<>
{
    assign_value(symbolizer_base::value_type & val, expression_ptr const& expr, Attributes const& attributes)
        : val_(val),
          expr_(expr),
          attributes_(attributes) {}

    void operator() (color const& default_val) const
    {
        // evaluate expression as a string then parse as css color
        std::string str = boost::apply_visitor(mapnik::evaluate_expression<mapnik::value,
                                               Attributes>(attributes_),*expr_).to_string();
        try { val_ = parse_color(str); }
        catch (...) { val_ = default_val;}
    }

    void operator() (value_double default_val) const
    {
        val_ = boost::apply_visitor(mapnik::evaluate_expression<mapnik::value, Attributes>(attributes_),*expr_).to_double();
    }

    void operator() (value_integer default_val) const
    {
        val_ = boost::apply_visitor(mapnik::evaluate_expression<mapnik::value, Attributes>(attributes_),*expr_).to_int();
    }

    void operator() (value_bool default_val) const
    {
        val_ = boost::apply_visitor(mapnik::evaluate_expression<mapnik::value, Attributes>(attributes_),*expr_).to_bool();
    }

    template <typename T>
    void operator() (T const& default_val) const
    {
        // no-op
    }
    symbolizer_base::value_type & val_;
    expression_ptr const& expr_;
    Attributes const& attributes_;
};

}
struct evaluate_global_attributes
{
    template <typename Attributes>
    struct evaluator : boost::static_visitor<>
    {
        evaluator(symbolizer_base::cont_type::value_type & prop, Attributes const& attributes)
            : prop_(prop),
              attributes_(attributes) {}

        void operator() (expression_ptr const& expr) const
        {
            auto const& meta = get_meta(prop_.first);
            boost::apply_visitor(assign_value<expression_ptr,Attributes>(prop_.second, expr, attributes_), std::get<1>(meta));
        }

        template <typename T>
        void operator() (T const& val) const
        {
            // no-op
        }
        symbolizer_base::cont_type::value_type & prop_;
        Attributes const& attributes_;
    };

    template <typename Attributes>
    struct extract_symbolizer : boost::static_visitor<>
    {
        extract_symbolizer(Attributes const& attributes)
            : attributes_(attributes) {}

        template <typename Symbolizer>
        void operator() (Symbolizer & sym) const
        {
            for (auto & prop : sym.properties)
            {
                boost::apply_visitor(evaluator<Attributes>(prop, attributes_), prop.second);
            }
        }
        Attributes const& attributes_;
    };

    template <typename Attributes>
    void apply(Map & m, Attributes const& attributes)
    {
        for ( auto & val :  m.styles() )
        {
            for (auto & rule : val.second.get_rules_nonconst())
            {
                for (auto & sym : rule)
                {
                    boost::apply_visitor(extract_symbolizer<Attributes>(attributes), sym);
                }
            }
        }
    }
};

}

#endif // MAPNIK_EVALUATE_GLOBAL_ATTRIBUTES_HPP
<commit_msg>make apply() static and disable copy ctor/assignment<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2013 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_EVALUATE_GLOBAL_ATTRIBUTES_HPP
#define MAPNIK_EVALUATE_GLOBAL_ATTRIBUTES_HPP

#include <mapnik/map.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/symbolizer_hash.hpp>
#include <mapnik/attribute.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/expression_node.hpp>
#include <mapnik/color_factory.hpp>

// boost
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/regex.hpp>
#if defined(BOOST_REGEX_HAS_ICU)
#include <boost/regex/icu.hpp>
#endif

namespace mapnik {

namespace {

template <typename T, typename Attributes>
struct evaluate_expression : boost::static_visitor<T>
{
    typedef T value_type;

    explicit evaluate_expression(Attributes const& attributes)
        : attributes_(attributes) {}

    value_type operator() (attribute const& attr) const
    {
        throw std::runtime_error("can't evaluate feature attributes in this context");
    }

    value_type operator() (global_attribute const& attr) const
    {
        auto itr = attributes_.find(attr.name);
        if (itr != attributes_.end())
        {
            return itr->second;
        }
        return value_type();// throw?
    }

    value_type operator() (geometry_type_attribute const& geom) const
    {
        throw std::runtime_error("can't evaluate geometry_type attributes in this context");
    }

    value_type operator() (binary_node<tags::logical_and> const & x) const
    {
        return (boost::apply_visitor(*this, x.left).to_bool())
            && (boost::apply_visitor(*this, x.right).to_bool());
    }

    value_type operator() (binary_node<tags::logical_or> const & x) const
    {
        return (boost::apply_visitor(*this,x.left).to_bool())
            || (boost::apply_visitor(*this,x.right).to_bool());
    }

    template <typename Tag>
    value_type operator() (binary_node<Tag> const& x) const
    {
        typename make_op<Tag>::type operation;
        return operation(boost::apply_visitor(*this, x.left),
                         boost::apply_visitor(*this, x.right));
    }

    template <typename Tag>
    value_type operator() (unary_node<Tag> const& x) const
    {
        typename make_op<Tag>::type func;
        return func(boost::apply_visitor(*this, x.expr));
    }

    value_type operator() (unary_node<tags::logical_not> const& x) const
    {
        return ! (boost::apply_visitor(*this,x.expr).to_bool());
    }

    value_type operator() (regex_match_node const& x) const
    {
        value_type v = boost::apply_visitor(*this, x.expr);
#if defined(BOOST_REGEX_HAS_ICU)
        return boost::u32regex_match(v.to_unicode(),x.pattern);
#else
        return boost::regex_match(v.to_string(),x.pattern);
#endif

    }

    value_type operator() (regex_replace_node const& x) const
    {
        value_type v = boost::apply_visitor(*this, x.expr);
#if defined(BOOST_REGEX_HAS_ICU)
        return boost::u32regex_replace(v.to_unicode(),x.pattern,x.format);
#else
        std::string repl = boost::regex_replace(v.to_string(),x.pattern,x.format);
        mapnik::transcoder tr_("utf8");
        return tr_.transcode(repl.c_str());
#endif
    }

    template <typename ValueType>
    value_type operator() (ValueType const& val) const
    {
        return value_type(val);
    }

    Attributes const& attributes_;
};

template <typename T, typename Attributes>
struct assign_value : boost::static_visitor<> {};

template <typename Attributes>
struct assign_value<expression_ptr,Attributes> : boost::static_visitor<>
{
    assign_value(symbolizer_base::value_type & val, expression_ptr const& expr, Attributes const& attributes)
        : val_(val),
          expr_(expr),
          attributes_(attributes) {}

    void operator() (color const& default_val) const
    {
        // evaluate expression as a string then parse as css color
        std::string str = boost::apply_visitor(mapnik::evaluate_expression<mapnik::value,
                                               Attributes>(attributes_),*expr_).to_string();
        try { val_ = parse_color(str); }
        catch (...) { val_ = default_val;}
    }

    void operator() (value_double default_val) const
    {
        val_ = boost::apply_visitor(mapnik::evaluate_expression<mapnik::value, Attributes>(attributes_),*expr_).to_double();
    }

    void operator() (value_integer default_val) const
    {
        val_ = boost::apply_visitor(mapnik::evaluate_expression<mapnik::value, Attributes>(attributes_),*expr_).to_int();
    }

    void operator() (value_bool default_val) const
    {
        val_ = boost::apply_visitor(mapnik::evaluate_expression<mapnik::value, Attributes>(attributes_),*expr_).to_bool();
    }

    template <typename T>
    void operator() (T const& default_val) const
    {
        // no-op
    }
    symbolizer_base::value_type & val_;
    expression_ptr const& expr_;
    Attributes const& attributes_;
};

}
struct evaluate_global_attributes : mapnik::noncopyable
{
    template <typename Attributes>
    struct evaluator : boost::static_visitor<>
    {
        evaluator(symbolizer_base::cont_type::value_type & prop, Attributes const& attributes)
            : prop_(prop),
              attributes_(attributes) {}

        void operator() (expression_ptr const& expr) const
        {
            auto const& meta = get_meta(prop_.first);
            boost::apply_visitor(assign_value<expression_ptr,Attributes>(prop_.second, expr, attributes_), std::get<1>(meta));
        }

        template <typename T>
        void operator() (T const& val) const
        {
            // no-op
        }
        symbolizer_base::cont_type::value_type & prop_;
        Attributes const& attributes_;
    };

    template <typename Attributes>
    struct extract_symbolizer : boost::static_visitor<>
    {
        extract_symbolizer(Attributes const& attributes)
            : attributes_(attributes) {}

        template <typename Symbolizer>
        void operator() (Symbolizer & sym) const
        {
            for (auto & prop : sym.properties)
            {
                boost::apply_visitor(evaluator<Attributes>(prop, attributes_), prop.second);
            }
        }
        Attributes const& attributes_;
    };

    template <typename Attributes>
    static void apply(Map & m, Attributes const& attributes)
    {
        for ( auto & val :  m.styles() )
        {
            for (auto & rule : val.second.get_rules_nonconst())
            {
                for (auto & sym : rule)
                {
                    boost::apply_visitor(extract_symbolizer<Attributes>(attributes), sym);
                }
            }
        }
    }
};

}

#endif // MAPNIK_EVALUATE_GLOBAL_ATTRIBUTES_HPP
<|endoftext|>


<commit_before>#pragma once
#ifndef NIFTY_GRAPH_SIMPLE_GRAPH_HXX
#define NIFTY_GRAPH_SIMPLE_GRAPH_HXX

#include <vector>
#include <boost/version.hpp>

// for strange reason travis does not find the boost flat set
#ifdef WITHIN_TRAVIS
#include <set>
#define __setimpl std::set
#else
#include <boost/container/flat_set.hpp>
#define __setimpl boost::container::flat_set
#endif

#include <boost/iterator/counting_iterator.hpp>

#include "nifty/container/flat_set.hxx"
#include "nifty/tools/runtime_check.hxx"
#include "nifty/graph/undirected_graph_base.hxx"
#include "nifty/graph/detail/adjacency.hxx"
#include "nifty/graph/graph_tags.hxx"

namespace nifty{
namespace graph{

namespace detail_graph{
    template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
    struct UndirectedGraphTypeHelper{
        typedef EDGE_INTERANL_TYPE EdgeInternalType;
        typedef NODE_INTERNAL_TYPE NodeInteralType;
        typedef detail_graph::UndirectedAdjacency<int64_t,int64_t,NodeInteralType,EdgeInternalType> NodeAdjacency;
        //typedef std::set<NodeAdjacency > NodeStorage;
        typedef nifty::container::FlatSet <NodeAdjacency> NodeStorage;

        typedef std::pair<NodeInteralType,NodeInteralType> EdgeStorage;
        typedef boost::counting_iterator<int64_t> NodeIter;
        typedef boost::counting_iterator<int64_t> EdgeIter;
        typedef typename NodeStorage::const_iterator AdjacencyIter;
    };

    class SimpleGraphNodeIter : public boost::counting_iterator<int64_t>{
        using boost::counting_iterator<int64_t>::counting_iterator;
        using boost::counting_iterator<int64_t>::operator=;
    };

    class SimpleGraphEdgeIter : public boost::counting_iterator<int64_t>{
        using boost::counting_iterator<int64_t>::counting_iterator;
        using boost::counting_iterator<int64_t>::operator=;
    };
};

template<class EDGE_INTERANL_TYPE = int64_t,
         class NODE_INTERNAL_TYPE = int64_t>
class UndirectedGraph : public
    UndirectedGraphBase<
        UndirectedGraph<EDGE_INTERANL_TYPE,NODE_INTERNAL_TYPE>,
        detail_graph::SimpleGraphNodeIter,
        detail_graph::SimpleGraphEdgeIter,
        typename detail_graph::UndirectedGraphTypeHelper<EDGE_INTERANL_TYPE,NODE_INTERNAL_TYPE>::AdjacencyIter
    >
{
protected:
    typedef EDGE_INTERANL_TYPE EdgeInternalType;
    typedef NODE_INTERNAL_TYPE NodeInteralType;
    typedef detail_graph::UndirectedAdjacency<int64_t,int64_t,NodeInteralType,EdgeInternalType> NodeAdjacency;
    typedef nifty::container::FlatSet<NodeAdjacency> NodeStorage;
    typedef std::pair<EdgeInternalType,EdgeInternalType> EdgeStorage;
public:
    typedef detail_graph::SimpleGraphNodeIter NodeIter;
    typedef boost::counting_iterator<int64_t> EdgeIter;
    typedef typename NodeStorage::const_iterator AdjacencyIter;

    typedef ContiguousTag EdgeIdTag;
    typedef ContiguousTag NodeIdTag;

    typedef SortedTag EdgeIdOrderTag;
    typedef SortedTag NodeIdOrderTag;

    // constructors
    UndirectedGraph(const uint64_t numberOfNodes = 0, const uint64_t reserveNumberOfEdges = 0);
    void assign(const uint64_t numberOfNodes = 0, const uint64_t reserveNumberOfEdges = 0);
    int64_t insertEdge(const int64_t u, const int64_t v);

    // MUST IMPL INTERFACE
    int64_t u(const int64_t e)const;
    int64_t v(const int64_t e)const;

    int64_t findEdge(const int64_t u, const int64_t v)const;
    int64_t nodeIdUpperBound() const;
    int64_t edgeIdUpperBound() const;
    uint64_t numberOfEdges() const;
    uint64_t numberOfNodes() const;

    NodeIter nodesBegin()const;
    NodeIter nodesEnd()const;
    EdgeIter edgesBegin()const;
    EdgeIter edgesEnd()const;

    AdjacencyIter adjacencyBegin(const int64_t node)const;
    AdjacencyIter adjacencyEnd(const int64_t node)const;
    AdjacencyIter adjacencyOutBegin(const int64_t node)const;

    // optional (with default impl in base)
    std::pair<int64_t,int64_t> uv(const int64_t e)const;
    template<class F>
    void forEachEdge(F && f)const;

    // serialization de-serialization

    void serializationSize() const;

    template<class ITER>
    void serialize(ITER iter) const;

    template<class ITER>
    void deserialize(ITER iter);

protected:
    std::vector<NodeStorage> nodes_;
    std::vector<EdgeStorage> edges_;
};

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
UndirectedGraph(const uint64_t numberOfNodes , const uint64_t reserveNumberOfEdges )
:   nodes_(numberOfNodes),
    edges_()
{
    edges_.reserve(reserveNumberOfEdges);
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
void
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
assign(const uint64_t numberOfNodes , const uint64_t reserveNumberOfEdges ){
    nodes_.clear();
    edges_.clear();
    nodes_.resize(numberOfNodes);
    edges_.reserve(reserveNumberOfEdges);
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
int64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
insertEdge(const int64_t u, const int64_t v){

    const auto fres =  nodes_[u].find(NodeAdjacency(v));
    if(fres != nodes_[u].end())
        return fres->edge();
    else{
        const auto uu = std::min(u,v);
        const auto vv = std::max(u,v);
        auto e = EdgeStorage(uu, vv);
        auto ei = edges_.size();
        edges_.push_back(e);
        nodes_[u].insert(NodeAdjacency(v,ei));
        nodes_[v].insert(NodeAdjacency(u,ei));
        return ei;
    }
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
int64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
u(const int64_t e)const{
    NIFTY_ASSERT_OP(e,<,numberOfEdges());
    return edges_[e].first;
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
int64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
v(const int64_t e)const{
    NIFTY_ASSERT_OP(e,<,numberOfEdges());
    return edges_[e].second;
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
int64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
findEdge(const int64_t u, const int64_t v)const{
    NIFTY_ASSERT_OP(u,<,numberOfNodes());
    NIFTY_ASSERT_OP(v,<,numberOfNodes());
    const auto fres =  nodes_[u].find(NodeAdjacency(v));
    if(fres != nodes_[u].end())
        return fres->edge();
    else
        return -1;
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
int64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
nodeIdUpperBound() const{
    return numberOfNodes() == 0 ? 0 : numberOfNodes()-1;
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
int64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
edgeIdUpperBound() const{
    return numberOfEdges() == 0 ? 0 : numberOfEdges()-1;
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
uint64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
numberOfEdges() const {
    return edges_.size();
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
uint64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
numberOfNodes() const{
    return nodes_.size();
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::NodeIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
nodesBegin()const{
    return NodeIter(0);
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::NodeIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
nodesEnd()const{
    return NodeIter(this->numberOfNodes());
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::EdgeIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
edgesBegin()const{
    return EdgeIter(0);
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::EdgeIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
edgesEnd()const{
    return EdgeIter(this->numberOfEdges());
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::AdjacencyIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
adjacencyBegin(const int64_t node)const{
    NIFTY_ASSERT_OP(node,<,numberOfNodes());
    return nodes_[node].begin();
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::AdjacencyIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
adjacencyEnd(const int64_t node)const{
    NIFTY_ASSERT_OP(node,<,numberOfNodes());
    return nodes_[node].end();
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::AdjacencyIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
adjacencyOutBegin(const int64_t node)const{
    return adjacencyBegin(node);
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
std::pair<int64_t,int64_t>
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
uv(const int64_t e)const{
    const auto _uv = edges_[e];
    return std::pair<int64_t,int64_t>(_uv.first, _uv.second);
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
template<class F>
void
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
forEachEdge(F && f)const{
    for(uint64_t edge=0; edge< numberOfEdges(); ++edge){
        f(edge);
    }
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
void
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
serializationSize() const{
    auto size = 0;
    size += 2; // number of nodes;  number of edges
    size += this->numberOfEdges() * 2;  // u, v;
    return size;
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
template<class ITER>
void
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
serialize(ITER iter) const{

    *iter = this->numberOfNodes();
    ++iter;
    *iter = this->numberOfEdges();
    ++iter;

    for(const edge : this->edges()){
        *iter = this->u(edge);
        ++iter;
        *iter = this->v(edge);
        ++iter;
    }
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
template<class ITER>
void
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
deserialize(ITER iter){
    const auto nNodes = *iter;
    ++iter;
    const auto nEdges = *iter;
    ++iter;

    this->assign(nNodes, nEdges);

    for(auto e=0; e<nEdges; ++e){
        const auto u = *iter;
        ++iter;
        const auto v = *iter;
        ++iter;
        this->insertEdge(u, v);
    }

}

} // namespace nifty::graph
} // namespace nifty

#endif  // NIFTY_GRAPH_SIMPLE_GRAPH_HXX
<commit_msg>UndirectedListGraph: implemented Serialization<commit_after>#pragma once
#ifndef NIFTY_GRAPH_SIMPLE_GRAPH_HXX
#define NIFTY_GRAPH_SIMPLE_GRAPH_HXX

#include <vector>
#include <boost/version.hpp>

// for strange reason travis does not find the boost flat set
#ifdef WITHIN_TRAVIS
#include <set>
#define __setimpl std::set
#else
#include <boost/container/flat_set.hpp>
#define __setimpl boost::container::flat_set
#endif

#include <boost/iterator/counting_iterator.hpp>

#include "nifty/container/flat_set.hxx"
#include "nifty/tools/runtime_check.hxx"
#include "nifty/graph/undirected_graph_base.hxx"
#include "nifty/graph/detail/adjacency.hxx"
#include "nifty/graph/graph_tags.hxx"

namespace nifty{
namespace graph{

namespace detail_graph{
    template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
    struct UndirectedGraphTypeHelper{
        typedef EDGE_INTERANL_TYPE EdgeInternalType;
        typedef NODE_INTERNAL_TYPE NodeInteralType;
        typedef detail_graph::UndirectedAdjacency<int64_t,int64_t,NodeInteralType,EdgeInternalType> NodeAdjacency;
        //typedef std::set<NodeAdjacency > NodeStorage;
        typedef nifty::container::FlatSet <NodeAdjacency> NodeStorage;

        typedef std::pair<NodeInteralType,NodeInteralType> EdgeStorage;
        typedef boost::counting_iterator<int64_t> NodeIter;
        typedef boost::counting_iterator<int64_t> EdgeIter;
        typedef typename NodeStorage::const_iterator AdjacencyIter;
    };

    class SimpleGraphNodeIter : public boost::counting_iterator<int64_t>{
        using boost::counting_iterator<int64_t>::counting_iterator;
        using boost::counting_iterator<int64_t>::operator=;
    };

    class SimpleGraphEdgeIter : public boost::counting_iterator<int64_t>{
        using boost::counting_iterator<int64_t>::counting_iterator;
        using boost::counting_iterator<int64_t>::operator=;
    };
};

template<class EDGE_INTERANL_TYPE = int64_t,
         class NODE_INTERNAL_TYPE = int64_t>
class UndirectedGraph : public
    UndirectedGraphBase<
        UndirectedGraph<EDGE_INTERANL_TYPE,NODE_INTERNAL_TYPE>,
        detail_graph::SimpleGraphNodeIter,
        detail_graph::SimpleGraphEdgeIter,
        typename detail_graph::UndirectedGraphTypeHelper<EDGE_INTERANL_TYPE,NODE_INTERNAL_TYPE>::AdjacencyIter
    >
{
protected:
    typedef EDGE_INTERANL_TYPE EdgeInternalType;
    typedef NODE_INTERNAL_TYPE NodeInteralType;
    typedef detail_graph::UndirectedAdjacency<int64_t,int64_t,NodeInteralType,EdgeInternalType> NodeAdjacency;
    typedef nifty::container::FlatSet<NodeAdjacency> NodeStorage;
    typedef std::pair<EdgeInternalType,EdgeInternalType> EdgeStorage;
public:
    typedef detail_graph::SimpleGraphNodeIter NodeIter;
    typedef boost::counting_iterator<int64_t> EdgeIter;
    typedef typename NodeStorage::const_iterator AdjacencyIter;

    typedef ContiguousTag EdgeIdTag;
    typedef ContiguousTag NodeIdTag;

    typedef SortedTag EdgeIdOrderTag;
    typedef SortedTag NodeIdOrderTag;

    // constructors
    UndirectedGraph(const uint64_t numberOfNodes = 0, const uint64_t reserveNumberOfEdges = 0);
    void assign(const uint64_t numberOfNodes = 0, const uint64_t reserveNumberOfEdges = 0);
    int64_t insertEdge(const int64_t u, const int64_t v);

    // MUST IMPL INTERFACE
    int64_t u(const int64_t e)const;
    int64_t v(const int64_t e)const;

    int64_t findEdge(const int64_t u, const int64_t v)const;
    int64_t nodeIdUpperBound() const;
    int64_t edgeIdUpperBound() const;
    uint64_t numberOfEdges() const;
    uint64_t numberOfNodes() const;

    NodeIter nodesBegin()const;
    NodeIter nodesEnd()const;
    EdgeIter edgesBegin()const;
    EdgeIter edgesEnd()const;

    AdjacencyIter adjacencyBegin(const int64_t node)const;
    AdjacencyIter adjacencyEnd(const int64_t node)const;
    AdjacencyIter adjacencyOutBegin(const int64_t node)const;

    // optional (with default impl in base)
    std::pair<int64_t,int64_t> uv(const int64_t e)const;
    template<class F>
    void forEachEdge(F && f)const;

    // serialization de-serialization

    void serializationSize() const;

    template<class ITER>
    void serialize(ITER iter) const;

    template<class ITER>
    void deserialize(ITER iter);

protected:
    std::vector<NodeStorage> nodes_;
    std::vector<EdgeStorage> edges_;
};

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
UndirectedGraph(const uint64_t numberOfNodes , const uint64_t reserveNumberOfEdges )
:   nodes_(numberOfNodes),
    edges_()
{
    edges_.reserve(reserveNumberOfEdges);
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
void
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
assign(const uint64_t numberOfNodes , const uint64_t reserveNumberOfEdges ){
    nodes_.clear();
    edges_.clear();
    nodes_.resize(numberOfNodes);
    edges_.reserve(reserveNumberOfEdges);
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
int64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
insertEdge(const int64_t u, const int64_t v){

    const auto fres =  nodes_[u].find(NodeAdjacency(v));
    if(fres != nodes_[u].end())
        return fres->edge();
    else{
        const auto uu = std::min(u,v);
        const auto vv = std::max(u,v);
        auto e = EdgeStorage(uu, vv);
        auto ei = edges_.size();
        edges_.push_back(e);
        nodes_[u].insert(NodeAdjacency(v,ei));
        nodes_[v].insert(NodeAdjacency(u,ei));
        return ei;
    }
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
int64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
u(const int64_t e)const{
    NIFTY_ASSERT_OP(e,<,numberOfEdges());
    return edges_[e].first;
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
int64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
v(const int64_t e)const{
    NIFTY_ASSERT_OP(e,<,numberOfEdges());
    return edges_[e].second;
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
int64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
findEdge(const int64_t u, const int64_t v)const{
    NIFTY_ASSERT_OP(u,<,numberOfNodes());
    NIFTY_ASSERT_OP(v,<,numberOfNodes());
    const auto fres =  nodes_[u].find(NodeAdjacency(v));
    if(fres != nodes_[u].end())
        return fres->edge();
    else
        return -1;
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
int64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
nodeIdUpperBound() const{
    return numberOfNodes() == 0 ? 0 : numberOfNodes()-1;
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
int64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
edgeIdUpperBound() const{
    return numberOfEdges() == 0 ? 0 : numberOfEdges()-1;
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
uint64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
numberOfEdges() const {
    return edges_.size();
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
uint64_t
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
numberOfNodes() const{
    return nodes_.size();
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::NodeIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
nodesBegin()const{
    return NodeIter(0);
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::NodeIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
nodesEnd()const{
    return NodeIter(this->numberOfNodes());
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::EdgeIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
edgesBegin()const{
    return EdgeIter(0);
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::EdgeIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
edgesEnd()const{
    return EdgeIter(this->numberOfEdges());
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::AdjacencyIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
adjacencyBegin(const int64_t node)const{
    NIFTY_ASSERT_OP(node,<,numberOfNodes());
    return nodes_[node].begin();
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::AdjacencyIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
adjacencyEnd(const int64_t node)const{
    NIFTY_ASSERT_OP(node,<,numberOfNodes());
    return nodes_[node].end();
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
typename UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::AdjacencyIter
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
adjacencyOutBegin(const int64_t node)const{
    return adjacencyBegin(node);
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
std::pair<int64_t,int64_t>
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
uv(const int64_t e)const{
    const auto _uv = edges_[e];
    return std::pair<int64_t,int64_t>(_uv.first, _uv.second);
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
template<class F>
void
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
forEachEdge(F && f)const{
    for(uint64_t edge=0; edge< numberOfEdges(); ++edge){
        f(edge);
    }
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
void
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
serializationSize() const{
    auto size = 0;
    size += 2; // number of nodes;  number of edges
    size += this->numberOfEdges() * 2;  // u, v;
    return size;
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
template<class ITER>
void
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
serialize(ITER iter) const{

    *iter = this->numberOfNodes();
    ++iter;
    *iter = this->numberOfEdges();
    ++iter;

    for(const auto edge : this->edges()){
        *iter = this->u(edge);
        ++iter;
        *iter = this->v(edge);
        ++iter;
    }
}

template<class EDGE_INTERANL_TYPE, class NODE_INTERNAL_TYPE >
template<class ITER>
void
UndirectedGraph<EDGE_INTERANL_TYPE, NODE_INTERNAL_TYPE>::
deserialize(ITER iter){
    const auto nNodes = *iter;
    ++iter;
    const auto nEdges = *iter;
    ++iter;

    this->assign(nNodes, nEdges);

    for(auto e=0; e<nEdges; ++e){
        const auto u = *iter;
        ++iter;
        const auto v = *iter;
        ++iter;
        this->insertEdge(u, v);
    }

}

} // namespace nifty::graph
} // namespace nifty

#endif  // NIFTY_GRAPH_SIMPLE_GRAPH_HXX
<|endoftext|>


<commit_before>#pragma once
#ifndef OPENGM_LEARNING_STRUCT_MAX_MARGIN_HXX
#define OPENGM_LEARNING_STRUCT_MAX_MARGIN_HXX

#include "bundle-optimizer.hxx"
#include "gradient-accumulator.hxx"

namespace opengm {

namespace learning {

template <
		typename DS,
		typename O = BundleOptimizer<typename DS::ValueType> >
class StructMaxMargin {

public:

	typedef DS DatasetType;
	typedef O  OptimizerType;

    typedef typename DatasetType::GMType GMType;
	typedef typename DatasetType::ValueType       ValueType;
    typedef typename DatasetType::Weights         Weights;

	struct Parameter {
        typedef typename OptimizerType::Parameter OptimizerParameter;
        OptimizerParameter optimizerParameter_;
	};

	StructMaxMargin(DatasetType& dataset, const Parameter& parameter = Parameter()) :
		_dataset(dataset),
        _parameter(parameter),
        _optimizer(parameter.optimizerParameter_)
    {}

	Parameter& parameter() { return _parameter; }

    template <typename InferenceType>
    void learn(const typename InferenceType::Parameter& parameter);

    const Weights& getWeights() { return _weights; }

private:

	template <typename InferenceType>
	class Oracle {

		public:

            Oracle(DatasetType& dataset, const typename InferenceType::Parameter& infParam) :
                _dataset(dataset),
                _infParam(infParam)
            {}

			/**
			 * Evaluate the loss-augmented energy value of the dataset and its
			 * gradient at w.
			 */
            void operator()(const Weights& w, double& value, Weights& gradient) {

				typedef std::vector<typename InferenceType::LabelType> ConfigurationType;

				// initialize gradient and value with zero
				for (int i = 0; i < gradient.numberOfWeights(); i++)
					gradient[i] = 0;
				value = 0;

				// For each model E(y,w), we have to compute the value and
				// gradient of
				//
				//   max_y E(y',w) - E(y,w) + Δ(y',y)            (1)
				//   =
				//   max_y L(y,w)
				//
				// where y' is the best-effort solution (also known as
				// groundtruth) and w are the current weights. The loss
				// augmented model given by the dataset is
				//
				//   F(y,w) = E(y,w) - Δ(y',y).
				//
				// Let c = E(y',w) be the constant contribution of the
				// best-effort solution. (1) is equal to
				//
				//  -min_y -c + F(y,w).
				//
				// The gradient of the maximand in (1) at y* is
				//
				//   ∂L(y,w)/∂w = ∂E(y',w)/∂w -
				//                ∂E(y,w)/∂w
				//
				//              = Σ_θ ∂θ(y'_θ,w)/∂w -
				//                Σ_θ ∂θ(y_θ,w)/∂w,
				//
				// which is a positive gradient contribution for the
				// best-effort, and a negative contribution for the maximizer
				// y*.

				for (int i = 0; i < _dataset.getNumberOfModels(); i++) {

					// get E(x,y) and F(x,y)
					_dataset.lockModel(i);
					const typename DatasetType::GMType&     gm  = _dataset.getModel(i);
					const typename DatasetType::GMWITHLOSS& gml = _dataset.getModelWithLoss(i);

					// set the weights w in E(x,y) and F(x,y)
					_dataset.getWeights() = w;

					// get the best-effort solution y'
					const ConfigurationType& bestEffort = _dataset.getGT(i);

					// compute constant c for current w
					ValueType c = gm.evaluate(bestEffort);

					// find the minimizer y* of F(y,w)
					ConfigurationType mostViolated;
                    InferenceType inference(gml, _infParam);
					inference.infer();
					inference.arg(mostViolated);

					// the optimal value of (1) is now c - F(y*,w)
					value += c - gml.evaluate(mostViolated);

					// the gradients are
					typedef GradientAccumulator<Weights, ConfigurationType> GA;
					GA gaBestEffort(gradient, bestEffort, GA::Add);
					GA gaMostViolated(gradient, mostViolated, GA::Subtract);
					for (size_t j = 0; j < gm.numberOfFactors(); j++) {

						gm[j].callViFunctor(gaBestEffort);
						gm[j].callViFunctor(gaMostViolated);
					}

					_dataset.unlockModel(i);
				}
			}

		private:

			DatasetType& _dataset;
            const typename InferenceType::Parameter& _infParam;
	};

	DatasetType& _dataset;

	Parameter _parameter;

	OptimizerType _optimizer;

    Weights _weights;
};

template <typename DS, typename O>
template <typename InferenceType>
void
StructMaxMargin<DS, O>::learn(const typename InferenceType::Parameter& infParams) {

    Oracle<InferenceType> oracle(_dataset, infParams);

	_weights = _dataset.getWeights();

	// minimize structured loss
    OptimizerResult result = _optimizer.optimize(oracle, _weights);

	if (result == Error)
		throw opengm::RuntimeError("optimizer did not succeed");

	if (result == ReachedMinGap)
		std::cout << "optimization converged to requested precision" << std::endl;

	if (result == ReachedSteps)
        std::cout << "optimization stopped after " << parameter().optimizerParameter_.steps << " iterations" << std::endl;
}

} // namespace learning

} // namespace opengm

#endif // OPENGM_LEARNING_STRUCT_MAX_MARGIN_HXX

<commit_msg>struct-max-margin: set data-weights only once for all models<commit_after>#pragma once
#ifndef OPENGM_LEARNING_STRUCT_MAX_MARGIN_HXX
#define OPENGM_LEARNING_STRUCT_MAX_MARGIN_HXX

#include "bundle-optimizer.hxx"
#include "gradient-accumulator.hxx"

namespace opengm {

namespace learning {

template <
		typename DS,
		typename O = BundleOptimizer<typename DS::ValueType> >
class StructMaxMargin {

public:

	typedef DS DatasetType;
	typedef O  OptimizerType;

    typedef typename DatasetType::GMType GMType;
	typedef typename DatasetType::ValueType       ValueType;
    typedef typename DatasetType::Weights         Weights;

	struct Parameter {
        typedef typename OptimizerType::Parameter OptimizerParameter;
        OptimizerParameter optimizerParameter_;
	};

	StructMaxMargin(DatasetType& dataset, const Parameter& parameter = Parameter()) :
		_dataset(dataset),
        _parameter(parameter),
        _optimizer(parameter.optimizerParameter_)
    {}

	Parameter& parameter() { return _parameter; }

    template <typename InferenceType>
    void learn(const typename InferenceType::Parameter& parameter);

    const Weights& getWeights() { return _weights; }

private:

	template <typename InferenceType>
	class Oracle {

		public:

            Oracle(DatasetType& dataset, const typename InferenceType::Parameter& infParam) :
                _dataset(dataset),
                _infParam(infParam)
            {}

			/**
			 * Evaluate the loss-augmented energy value of the dataset and its
			 * gradient at w.
			 */
            void operator()(const Weights& w, double& value, Weights& gradient) {

				typedef std::vector<typename InferenceType::LabelType> ConfigurationType;

				// initialize gradient and value with zero
				for (int i = 0; i < gradient.numberOfWeights(); i++)
					gradient[i] = 0;
				value = 0;

				// For each model E(y,w), we have to compute the value and
				// gradient of
				//
				//   max_y E(y',w) - E(y,w) + Δ(y',y)            (1)
				//   =
				//   max_y L(y,w)
				//
				// where y' is the best-effort solution (also known as
				// groundtruth) and w are the current weights. The loss
				// augmented model given by the dataset is
				//
				//   F(y,w) = E(y,w) - Δ(y',y).
				//
				// Let c = E(y',w) be the constant contribution of the
				// best-effort solution. (1) is equal to
				//
				//  -min_y -c + F(y,w).
				//
				// The gradient of the maximand in (1) at y* is
				//
				//   ∂L(y,w)/∂w = ∂E(y',w)/∂w -
				//                ∂E(y,w)/∂w
				//
				//              = Σ_θ ∂θ(y'_θ,w)/∂w -
				//                Σ_θ ∂θ(y_θ,w)/∂w,
				//
				// which is a positive gradient contribution for the
				// best-effort, and a negative contribution for the maximizer
				// y*.

				// set the weights w in E(x,y) and F(x,y)
				_dataset.getWeights() = w;

				for (int i = 0; i < _dataset.getNumberOfModels(); i++) {

					// get E(x,y) and F(x,y)
					_dataset.lockModel(i);
					const typename DatasetType::GMType&     gm  = _dataset.getModel(i);
					const typename DatasetType::GMWITHLOSS& gml = _dataset.getModelWithLoss(i);

					// get the best-effort solution y'
					const ConfigurationType& bestEffort = _dataset.getGT(i);

					// compute constant c for current w
					ValueType c = gm.evaluate(bestEffort);

					// find the minimizer y* of F(y,w)
					ConfigurationType mostViolated;
                    InferenceType inference(gml, _infParam);
					inference.infer();
					inference.arg(mostViolated);

					// the optimal value of (1) is now c - F(y*,w)
					value += c - gml.evaluate(mostViolated);

					// the gradients are
					typedef GradientAccumulator<Weights, ConfigurationType> GA;
					GA gaBestEffort(gradient, bestEffort, GA::Add);
					GA gaMostViolated(gradient, mostViolated, GA::Subtract);
					for (size_t j = 0; j < gm.numberOfFactors(); j++) {

						gm[j].callViFunctor(gaBestEffort);
						gm[j].callViFunctor(gaMostViolated);
					}

					_dataset.unlockModel(i);
				}
			}

		private:

			DatasetType& _dataset;
            const typename InferenceType::Parameter& _infParam;
	};

	DatasetType& _dataset;

	Parameter _parameter;

	OptimizerType _optimizer;

    Weights _weights;
};

template <typename DS, typename O>
template <typename InferenceType>
void
StructMaxMargin<DS, O>::learn(const typename InferenceType::Parameter& infParams) {

    Oracle<InferenceType> oracle(_dataset, infParams);

	_weights = _dataset.getWeights();

	// minimize structured loss
    OptimizerResult result = _optimizer.optimize(oracle, _weights);

	if (result == Error)
		throw opengm::RuntimeError("optimizer did not succeed");

	if (result == ReachedMinGap)
		std::cout << "optimization converged to requested precision" << std::endl;

	if (result == ReachedSteps)
        std::cout << "optimization stopped after " << parameter().optimizerParameter_.steps << " iterations" << std::endl;
}

} // namespace learning

} // namespace opengm

#endif // OPENGM_LEARNING_STRUCT_MAX_MARGIN_HXX

<|endoftext|>


<commit_before>//===- seec/Trace/GetCurrentRuntimeValue.hpp ------------------------ C++ -===//
//
//
//
//===----------------------------------------------------------------------===//
//
//
//
//===----------------------------------------------------------------------===//

#ifndef SEEC_TRACE_GETCURRENTRUNTIMEVALUE_HPP
#define SEEC_TRACE_GETCURRENTRUNTIMEVALUE_HPP

#include "seec/Trace/RuntimeValue.hpp"
#include "seec/Util/Maybe.hpp"

#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

#include <cstdint>

namespace seec {

namespace trace {

/// \brief Implementation class for getCurrentRuntimeValueAs.
///
/// This class is specialized for various types of T. If no specialization
/// exists then getCurrentRuntimeValueAs will always return an unassigned Maybe.
/// \tparam SrcTy Type of object to get raw GenericValue values from.
/// \tparam T Type to try and extract the value as.
template<typename SrcTy, typename T, typename Enable = void>
struct GetCurrentRuntimeValueAsImpl;

/// \brief Specialization of getCurrentRuntimeValueAs to extract uintptr_t.
///
/// Because we store all pointers as uintptr_t, this specialization also
/// requires the additional requirements of pointer types, namely that the
/// following member functions are present in the source type SrcTy:
///
///   uintptr_t getRuntimeAddress(Function const *);
///   uintptr_t getRuntimeAddress(GlobalVariable const *);
///
/// Which return the run-time addresses of the objects passed to them, or 0 if
/// the run-time addresses cannot be found.
///
/// \tparam SrcTy The type of object to get raw GenericValue values from.
template<typename SrcTy>
struct GetCurrentRuntimeValueAsImpl<SrcTy, uintptr_t, void> {
  static seec::util::Maybe<uintptr_t>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    auto Ty = V->getType();

    if (Ty->isIntegerTy()) {
      if (auto Instruction = llvm::dyn_cast<llvm::Instruction>(V)) {
        if (auto RTValue = Source.getCurrentRuntimeValue(Instruction)) {
          return RTValue->getUIntPtr();
        }
      }
      else if (auto ConstantInt = llvm::dyn_cast<llvm::ConstantInt>(V)) {
        return static_cast<uintptr_t>(ConstantInt->getZExtValue());
      }
    }
    else if (Ty->isPointerTy()) {
      // If the Value is an Instruction, get its recorded runtime value
      if (auto I = llvm::dyn_cast<llvm::Instruction>(V)) {
        if (auto RTValue = Source.getCurrentRuntimeValue(I)) {
          return RTValue->getUIntPtr();
        }

        return seec::util::Maybe<uintptr_t>();
      }

      // Get constant pointer values
      auto StrippedValue = V->stripPointerCasts();

      if (auto Global = llvm::dyn_cast<llvm::GlobalValue>(StrippedValue)) {
        if (auto Function = llvm::dyn_cast<llvm::Function>(Global)) {
          auto Addr = Source.getRuntimeAddress(Function);
          return Addr ? seec::util::Maybe<uintptr_t>(Addr)
                      : seec::util::Maybe<uintptr_t>();
        }
        else if (auto GV = llvm::dyn_cast<llvm::GlobalVariable>(StrippedValue)){
          auto Addr = Source.getRuntimeAddress(GV);
          return Addr ? seec::util::Maybe<uintptr_t>(Addr)
                      : seec::util::Maybe<uintptr_t>();
        }

        llvm::errs() << "Value = " << *V << "\n";
        llvm_unreachable("Don't know how to get pointer from global value.");
      }
      else if (llvm::isa<llvm::ConstantPointerNull>(StrippedValue)) {
        return seec::util::Maybe<uintptr_t>(static_cast<uintptr_t>(0));
      }

      llvm::errs() << "Value = " << *V << "\n";
      llvm_unreachable("Don't know how to get runtime value of pointer.");
    }

    return seec::util::Maybe<uintptr_t>();
  }
};

/// \brief Specialization of getCurrentRuntimeValueAs to extract pointer types.
///
/// Pointer types additionally require that the following member functions are
/// present in the source type SrcTy:
///
///   uintptr_t getRuntimeAddress(Function const *);
///   uintptr_t getRuntimeAddress(GlobalVariable const *);
///
/// Which return the run-time addresses of the objects passed to them, or 0 if
/// the run-time addresses cannot be found.
///
/// \tparam SrcTy The type of object to get raw GenericValue values from.
/// \tparam T The base type to try and extract the value as a pointer to.
template<typename SrcTy, typename T>
struct GetCurrentRuntimeValueAsImpl<SrcTy, T *, void> {
  static seec::util::Maybe<T *>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    auto Addr = GetCurrentRuntimeValueAsImpl<SrcTy, uintptr_t>::
                  getCurrentRuntimeValueAs(Source, V);

    if (Addr.assigned())
      return reinterpret_cast<T *>(Addr.template get<0>());

    return seec::util::Maybe<T *>();
  }
};

/// \brief Specialization of getCurrentRuntimeValueAs to extract signed
///        integral types.
template<typename SrcTy, typename T>
struct GetCurrentRuntimeValueAsImpl
  <SrcTy,
   T,
   typename std::enable_if<std::is_integral<T>::value
                           && std::is_signed<T>::value
                          >::type>
{
  static seec::util::Maybe<T>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    assert(V->getType()->isIntegerTy()
           && "Extracting integral type from non-integer value.");

    if (auto Instruction = llvm::dyn_cast<llvm::Instruction>(V)) {
      if (auto RTValue = Source.getCurrentRuntimeValue(Instruction)) {
        return getAs<T>(*RTValue, Instruction->getType());
      }
    }
    else if (auto ConstantInt = llvm::dyn_cast<llvm::ConstantInt>(V)) {
      // TODO: Assert that the constant isn't too large.
      return static_cast<T>(ConstantInt->getSExtValue());
    }

    return seec::util::Maybe<T>();
  }
};

/// \brief Specialization of getCurrentRuntimeValueAs to extract unsigned
///        integral types.
template<typename SrcTy, typename T>
struct GetCurrentRuntimeValueAsImpl
  <SrcTy,
   T,
   typename std::enable_if<std::is_integral<T>::value
                           && std::is_unsigned<T>::value
                          >::type>
{
  static seec::util::Maybe<T>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    assert(V->getType()->isIntegerTy()
           && "Extracting integral type from non-integer value.");

    if (auto Instruction = llvm::dyn_cast<llvm::Instruction>(V)) {
      if (auto RTValue = Source.getCurrentRuntimeValue(Instruction)) {
        return getAs<T>(*RTValue, Instruction->getType());
      }
    }
    else if (auto ConstantInt = llvm::dyn_cast<llvm::ConstantInt>(V)) {
      // TODO: Assert that the constant isn't too large.
      return static_cast<T>(ConstantInt->getZExtValue());
    }

    return seec::util::Maybe<T>();
  }
};

// Overload for float types.
template<typename SrcTy>
struct GetCurrentRuntimeValueAsImpl<SrcTy, float, void> {
  static seec::util::Maybe<float>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    assert(V->getType()->isFloatTy());

    if (auto Instruction = llvm::dyn_cast<llvm::Instruction>(V)) {
      if (auto RTValue = Source.getCurrentRuntimeValue(Instruction)) {
        return RTValue->getFloat();
      }
    }
    else if (auto ConstantFloat = llvm::dyn_cast<llvm::ConstantFP>(V)) {
      return ConstantFloat->getValueAPF().convertToFloat();
    }

    return seec::util::Maybe<float>();
  }
};

// Overload for double types.
template<typename SrcTy>
struct GetCurrentRuntimeValueAsImpl<SrcTy, double, void> {
  static seec::util::Maybe<double>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    assert(V->getType()->isFloatTy());

    if (auto Instruction = llvm::dyn_cast<llvm::Instruction>(V)) {
      if (auto RTValue = Source.getCurrentRuntimeValue(Instruction)) {
        return RTValue->getDouble();
      }
    }
    else if (auto ConstantFloat = llvm::dyn_cast<llvm::ConstantFP>(V)) {
      return ConstantFloat->getValueAPF().convertToDouble();
    }

    return seec::util::Maybe<double>();
  }
};

// Overload to extract the raw RuntimeValue
template<typename SrcTy>
struct GetCurrentRuntimeValueAsImpl<SrcTy, RuntimeValue const *, void> {
  static seec::util::Maybe<RuntimeValue const *>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    if (auto Instruction = llvm::dyn_cast<llvm::Instruction>(V)) {
      if (auto RTValue = Source.getCurrentRuntimeValue(Instruction)) {
        return RTValue;
      }
    }
    return seec::util::Maybe<RuntimeValue const *>();
  }
};

/// \brief Find the current value of a Value.
///
/// This requires the source object to implement the function:
///
///   RuntimeValue const *getCurrentRuntimeValue(llvm::Instruction const *I)
///
/// \tparam T The type to extract the value as.
/// \tparam SrcTy The type of source object to get raw RuntimeValues from.
/// \param Source The source object to get raw RuntimeValues from.
/// \param V The Value that we will try to find the run-time value for.
template<typename T, typename SrcTy>
seec::util::Maybe<T>
getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *Value) {
  return GetCurrentRuntimeValueAsImpl<SrcTy, T>
          ::getCurrentRuntimeValueAs(Source, Value);
}

/// Find the values of arguments of a CallInst using getCurrentRuntimeValueAs.
// This is the base case for the variadic template below.
template<typename SrcTy>
bool getArgumentValues(SrcTy &Source,
                       llvm::CallInst const *Call,
                       size_t Offset) {
  return true;
}

/// Find the values of arguments of a CallInst using getCurrentRuntimeValueAs.
/// \tparam SrcTy The type of source object to extract run-time values from.
/// \tparam T The type to get the first argument as.
/// \tparam TS The types to get the remaining arguments as.
/// \param Source The source object to get raw RuntimeValues from.
/// \param Call The CallInst to extract the arguments of.
/// \param Offset The index into the CallInst's argument list to start
///               extracting arguments from.
/// \param Arg A reference to the object that will hold the first extracted
///            argument.
/// \param Args References to the objects that will hold the remaining extracted
///             arguments.
/// \return true if all arguments were extracted successfully.
template<typename SrcTy, typename T, typename... TS>
bool getArgumentValues(SrcTy &Source,
                       llvm::CallInst const *Call,
                       size_t Offset,
                       T& Arg,
                       TS&... Args) {
  auto Value = getCurrentRuntimeValueAs<T>(Source, Call->getArgOperand(Offset));
  if (!Value.assigned())
    return false;

  Arg = Value.template get<0>();

  return getArgumentValues(Source, Call, Offset + 1, Args...);
}

}

}

#endif // SEEC_TRACE_GETCURRENTRUNTIMEVALUE_HPP
<commit_msg>Remove now-unused getArgumentValues().<commit_after>//===- seec/Trace/GetCurrentRuntimeValue.hpp ------------------------ C++ -===//
//
//
//
//===----------------------------------------------------------------------===//
//
//
//
//===----------------------------------------------------------------------===//

#ifndef SEEC_TRACE_GETCURRENTRUNTIMEVALUE_HPP
#define SEEC_TRACE_GETCURRENTRUNTIMEVALUE_HPP

#include "seec/Trace/RuntimeValue.hpp"
#include "seec/Util/Maybe.hpp"

#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

#include <cstdint>

namespace seec {

namespace trace {

/// \brief Implementation class for getCurrentRuntimeValueAs.
///
/// This class is specialized for various types of T. If no specialization
/// exists then getCurrentRuntimeValueAs will always return an unassigned Maybe.
/// \tparam SrcTy Type of object to get raw GenericValue values from.
/// \tparam T Type to try and extract the value as.
template<typename SrcTy, typename T, typename Enable = void>
struct GetCurrentRuntimeValueAsImpl;

/// \brief Specialization of getCurrentRuntimeValueAs to extract uintptr_t.
///
/// Because we store all pointers as uintptr_t, this specialization also
/// requires the additional requirements of pointer types, namely that the
/// following member functions are present in the source type SrcTy:
///
///   uintptr_t getRuntimeAddress(Function const *);
///   uintptr_t getRuntimeAddress(GlobalVariable const *);
///
/// Which return the run-time addresses of the objects passed to them, or 0 if
/// the run-time addresses cannot be found.
///
/// \tparam SrcTy The type of object to get raw GenericValue values from.
template<typename SrcTy>
struct GetCurrentRuntimeValueAsImpl<SrcTy, uintptr_t, void> {
  static seec::util::Maybe<uintptr_t>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    auto Ty = V->getType();

    if (Ty->isIntegerTy()) {
      if (auto Instruction = llvm::dyn_cast<llvm::Instruction>(V)) {
        if (auto RTValue = Source.getCurrentRuntimeValue(Instruction)) {
          return RTValue->getUIntPtr();
        }
      }
      else if (auto ConstantInt = llvm::dyn_cast<llvm::ConstantInt>(V)) {
        return static_cast<uintptr_t>(ConstantInt->getZExtValue());
      }
    }
    else if (Ty->isPointerTy()) {
      // If the Value is an Instruction, get its recorded runtime value
      if (auto I = llvm::dyn_cast<llvm::Instruction>(V)) {
        if (auto RTValue = Source.getCurrentRuntimeValue(I)) {
          return RTValue->getUIntPtr();
        }

        return seec::util::Maybe<uintptr_t>();
      }

      // Get constant pointer values
      auto StrippedValue = V->stripPointerCasts();

      if (auto Global = llvm::dyn_cast<llvm::GlobalValue>(StrippedValue)) {
        if (auto Function = llvm::dyn_cast<llvm::Function>(Global)) {
          auto Addr = Source.getRuntimeAddress(Function);
          return Addr ? seec::util::Maybe<uintptr_t>(Addr)
                      : seec::util::Maybe<uintptr_t>();
        }
        else if (auto GV = llvm::dyn_cast<llvm::GlobalVariable>(StrippedValue)){
          auto Addr = Source.getRuntimeAddress(GV);
          return Addr ? seec::util::Maybe<uintptr_t>(Addr)
                      : seec::util::Maybe<uintptr_t>();
        }

        llvm::errs() << "Value = " << *V << "\n";
        llvm_unreachable("Don't know how to get pointer from global value.");
      }
      else if (llvm::isa<llvm::ConstantPointerNull>(StrippedValue)) {
        return seec::util::Maybe<uintptr_t>(static_cast<uintptr_t>(0));
      }

      llvm::errs() << "Value = " << *V << "\n";
      llvm_unreachable("Don't know how to get runtime value of pointer.");
    }

    return seec::util::Maybe<uintptr_t>();
  }
};

/// \brief Specialization of getCurrentRuntimeValueAs to extract pointer types.
///
/// Pointer types additionally require that the following member functions are
/// present in the source type SrcTy:
///
///   uintptr_t getRuntimeAddress(Function const *);
///   uintptr_t getRuntimeAddress(GlobalVariable const *);
///
/// Which return the run-time addresses of the objects passed to them, or 0 if
/// the run-time addresses cannot be found.
///
/// \tparam SrcTy The type of object to get raw GenericValue values from.
/// \tparam T The base type to try and extract the value as a pointer to.
template<typename SrcTy, typename T>
struct GetCurrentRuntimeValueAsImpl<SrcTy, T *, void> {
  static seec::util::Maybe<T *>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    auto Addr = GetCurrentRuntimeValueAsImpl<SrcTy, uintptr_t>::
                  getCurrentRuntimeValueAs(Source, V);

    if (Addr.assigned())
      return reinterpret_cast<T *>(Addr.template get<0>());

    return seec::util::Maybe<T *>();
  }
};

/// \brief Specialization of getCurrentRuntimeValueAs to extract signed
///        integral types.
template<typename SrcTy, typename T>
struct GetCurrentRuntimeValueAsImpl
  <SrcTy,
   T,
   typename std::enable_if<std::is_integral<T>::value
                           && std::is_signed<T>::value
                          >::type>
{
  static seec::util::Maybe<T>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    assert(V->getType()->isIntegerTy()
           && "Extracting integral type from non-integer value.");

    if (auto Instruction = llvm::dyn_cast<llvm::Instruction>(V)) {
      if (auto RTValue = Source.getCurrentRuntimeValue(Instruction)) {
        return getAs<T>(*RTValue, Instruction->getType());
      }
    }
    else if (auto ConstantInt = llvm::dyn_cast<llvm::ConstantInt>(V)) {
      // TODO: Assert that the constant isn't too large.
      return static_cast<T>(ConstantInt->getSExtValue());
    }

    return seec::util::Maybe<T>();
  }
};

/// \brief Specialization of getCurrentRuntimeValueAs to extract unsigned
///        integral types.
template<typename SrcTy, typename T>
struct GetCurrentRuntimeValueAsImpl
  <SrcTy,
   T,
   typename std::enable_if<std::is_integral<T>::value
                           && std::is_unsigned<T>::value
                          >::type>
{
  static seec::util::Maybe<T>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    assert(V->getType()->isIntegerTy()
           && "Extracting integral type from non-integer value.");

    if (auto Instruction = llvm::dyn_cast<llvm::Instruction>(V)) {
      if (auto RTValue = Source.getCurrentRuntimeValue(Instruction)) {
        return getAs<T>(*RTValue, Instruction->getType());
      }
    }
    else if (auto ConstantInt = llvm::dyn_cast<llvm::ConstantInt>(V)) {
      // TODO: Assert that the constant isn't too large.
      return static_cast<T>(ConstantInt->getZExtValue());
    }

    return seec::util::Maybe<T>();
  }
};

// Overload for float types.
template<typename SrcTy>
struct GetCurrentRuntimeValueAsImpl<SrcTy, float, void> {
  static seec::util::Maybe<float>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    assert(V->getType()->isFloatTy());

    if (auto Instruction = llvm::dyn_cast<llvm::Instruction>(V)) {
      if (auto RTValue = Source.getCurrentRuntimeValue(Instruction)) {
        return RTValue->getFloat();
      }
    }
    else if (auto ConstantFloat = llvm::dyn_cast<llvm::ConstantFP>(V)) {
      return ConstantFloat->getValueAPF().convertToFloat();
    }

    return seec::util::Maybe<float>();
  }
};

// Overload for double types.
template<typename SrcTy>
struct GetCurrentRuntimeValueAsImpl<SrcTy, double, void> {
  static seec::util::Maybe<double>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    assert(V->getType()->isFloatTy());

    if (auto Instruction = llvm::dyn_cast<llvm::Instruction>(V)) {
      if (auto RTValue = Source.getCurrentRuntimeValue(Instruction)) {
        return RTValue->getDouble();
      }
    }
    else if (auto ConstantFloat = llvm::dyn_cast<llvm::ConstantFP>(V)) {
      return ConstantFloat->getValueAPF().convertToDouble();
    }

    return seec::util::Maybe<double>();
  }
};

// Overload to extract the raw RuntimeValue
template<typename SrcTy>
struct GetCurrentRuntimeValueAsImpl<SrcTy, RuntimeValue const *, void> {
  static seec::util::Maybe<RuntimeValue const *>
  getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *V) {
    if (auto Instruction = llvm::dyn_cast<llvm::Instruction>(V)) {
      if (auto RTValue = Source.getCurrentRuntimeValue(Instruction)) {
        return RTValue;
      }
    }
    return seec::util::Maybe<RuntimeValue const *>();
  }
};

/// \brief Find the current value of a Value.
///
/// This requires the source object to implement the function:
///
///   RuntimeValue const *getCurrentRuntimeValue(llvm::Instruction const *I)
///
/// \tparam T The type to extract the value as.
/// \tparam SrcTy The type of source object to get raw RuntimeValues from.
/// \param Source The source object to get raw RuntimeValues from.
/// \param V The Value that we will try to find the run-time value for.
template<typename T, typename SrcTy>
seec::util::Maybe<T>
getCurrentRuntimeValueAs(SrcTy &Source, llvm::Value const *Value) {
  return GetCurrentRuntimeValueAsImpl<SrcTy, T>
          ::getCurrentRuntimeValueAs(Source, Value);
}

}

}

#endif // SEEC_TRACE_GETCURRENTRUNTIMEVALUE_HPP
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: XMLCalculationSettingsContext.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: vg $ $Date: 2005-03-23 12:45:34 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PCH
#include "filt_pch.hxx"
#endif

#pragma hdrstop

// INCLUDE ---------------------------------------------------------------

#ifndef _SC_XMLCALCULATIONSETTINGSCONTEXT_HXX
#include "XMLCalculationSettingsContext.hxx"
#endif
#ifndef SC_XMLIMPRT_HXX
#include "xmlimprt.hxx"
#endif
#ifndef SC_UNONAMES_HXX
#include "unonames.hxx"
#endif
#ifndef SC_DOCOPTIO_HXX
#include "docoptio.hxx"
#endif
#ifndef SC_DOCUMENT_HXX
#include "document.hxx"
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include <xmloff/xmltoken.hxx>
#endif
#ifndef _XMLOFF_XMLNMSPE_HXX
#include <xmloff/xmlnmspe.hxx>
#endif
#ifndef _XMLOFF_XMLUCONV_HXX
#include <xmloff/xmluconv.hxx>
#endif
#ifndef _XMLOFF_NMSPMAP_HXX
#include <xmloff/nmspmap.hxx>
#endif

#ifndef _COM_SUN_STAR_SHEET_XSPREADSHEETDOCUMENT_HPP_
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif

using namespace com::sun::star;
using namespace xmloff::token;

//------------------------------------------------------------------

ScXMLCalculationSettingsContext::ScXMLCalculationSettingsContext( ScXMLImport& rImport,
                                      USHORT nPrfx,
                                      const ::rtl::OUString& rLName,
                                      const ::com::sun::star::uno::Reference<
                                      ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
    SvXMLImportContext( rImport, nPrfx, rLName ),
    fIterationEpsilon(0.001),
    nIterationCount(100),
    nYear2000(1930),
    bIsIterationEnabled(sal_False),
    bCalcAsShown(sal_False),
    bIgnoreCase(sal_False),
    bLookUpLabels(sal_True),
    bMatchWholeCell(sal_True),
    bUseRegularExpressions(sal_True)
{
    aNullDate.Day = 30;
    aNullDate.Month = 12;
    aNullDate.Year = 1899;
    sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; ++i )
    {
        const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
        rtl::OUString aLocalName;
        sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
                                            sAttrName, &aLocalName );
        const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));

        if (nPrefix == XML_NAMESPACE_TABLE)
        {
            if (IsXMLToken(aLocalName, XML_CASE_SENSITIVE))
            {
                if (IsXMLToken(sValue, XML_FALSE))
                    bIgnoreCase = sal_True;
            }
            else if (IsXMLToken(aLocalName, XML_PRECISION_AS_SHOWN))
            {
                if (IsXMLToken(sValue, XML_TRUE))
                    bCalcAsShown = sal_True;
            }
            else if (IsXMLToken(aLocalName, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL))
            {
                if (IsXMLToken(sValue, XML_FALSE))
                    bMatchWholeCell = sal_False;
            }
            else if (IsXMLToken(aLocalName, XML_AUTOMATIC_FIND_LABELS))
            {
                if (IsXMLToken(sValue, XML_FALSE))
                    bLookUpLabels = sal_False;
            }
            else if (IsXMLToken(aLocalName, XML_NULL_YEAR))
            {
                sal_Int32 nTemp;
                GetScImport().GetMM100UnitConverter().convertNumber(nTemp, sValue);
                nYear2000 = static_cast<sal_uInt16>(nTemp);
            }
            else if (IsXMLToken(aLocalName, XML_USE_REGULAR_EXPRESSIONS))
            {
                if (IsXMLToken(sValue, XML_FALSE))
                    bUseRegularExpressions = sal_False;
            }
        }
    }
}

ScXMLCalculationSettingsContext::~ScXMLCalculationSettingsContext()
{
}

SvXMLImportContext *ScXMLCalculationSettingsContext::CreateChildContext( USHORT nPrefix,
                                            const ::rtl::OUString& rLName,
                                            const ::com::sun::star::uno::Reference<
                                          ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
{
    SvXMLImportContext *pContext = 0;

    if (nPrefix == XML_NAMESPACE_TABLE)
    {
        if (IsXMLToken(rLName, XML_NULL_DATE))
            pContext = new ScXMLNullDateContext(GetScImport(), nPrefix, rLName, xAttrList, this);
        else if (IsXMLToken(rLName, XML_ITERATION))
            pContext = new ScXMLIterationContext(GetScImport(), nPrefix, rLName, xAttrList, this);
    }

    if( !pContext )
        pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );

    return pContext;
}

void ScXMLCalculationSettingsContext::EndElement()
{
    if (GetScImport().GetModel().is())
    {
        uno::Reference <beans::XPropertySet> xPropertySet (GetScImport().GetModel(), uno::UNO_QUERY);
        if (xPropertySet.is())
        {
            xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_CALCASSHOWN)), uno::makeAny(bCalcAsShown) );
            xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_IGNORECASE)), uno::makeAny(bIgnoreCase) );
            xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_LOOKUPLABELS)), uno::makeAny(bLookUpLabels) );
            xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_MATCHWHOLE)), uno::makeAny(bMatchWholeCell) );
            xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_REGEXENABLED)), uno::makeAny(bUseRegularExpressions) );
            xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERENABLED)), uno::makeAny(bIsIterationEnabled) );
            xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERCOUNT)), uno::makeAny(nIterationCount) );
            xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITEREPSILON)), uno::makeAny(fIterationEpsilon) );
            xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NULLDATE)), uno::makeAny(aNullDate) );
            if (GetScImport().GetDocument())
            {
                GetScImport().LockSolarMutex();
                ScDocOptions aDocOptions (GetScImport().GetDocument()->GetDocOptions());
                aDocOptions.SetYear2000(nYear2000);
                GetScImport().GetDocument()->SetDocOptions(aDocOptions);
                GetScImport().UnlockSolarMutex();
            }
        }
    }
}

ScXMLNullDateContext::ScXMLNullDateContext( ScXMLImport& rImport,
                                      USHORT nPrfx,
                                      const ::rtl::OUString& rLName,
                                      const ::com::sun::star::uno::Reference<
                                      ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
                                      ScXMLCalculationSettingsContext* pCalcSet) :
    SvXMLImportContext( rImport, nPrfx, rLName )
{
    sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; ++i )
    {
        const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
        rtl::OUString aLocalName;
        sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
                                            sAttrName, &aLocalName );
        const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));

        if (nPrefix == XML_NAMESPACE_TABLE && IsXMLToken(aLocalName, XML_DATE_VALUE))
        {
            util::DateTime aDateTime;
            GetScImport().GetMM100UnitConverter().convertDateTime(aDateTime, sValue);
            util::Date aDate;
            aDate.Day = aDateTime.Day;
            aDate.Month = aDateTime.Month;
            aDate.Year = aDateTime.Year;
            pCalcSet->SetNullDate(aDate);
        }
    }
}

ScXMLNullDateContext::~ScXMLNullDateContext()
{
}

SvXMLImportContext *ScXMLNullDateContext::CreateChildContext( USHORT nPrefix,
                                            const ::rtl::OUString& rLName,
                                            const ::com::sun::star::uno::Reference<
                                          ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
{
    SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );

    return pContext;
}

void ScXMLNullDateContext::EndElement()
{
}

ScXMLIterationContext::ScXMLIterationContext( ScXMLImport& rImport,
                                      USHORT nPrfx,
                                      const ::rtl::OUString& rLName,
                                      const ::com::sun::star::uno::Reference<
                                      ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
                                      ScXMLCalculationSettingsContext* pCalcSet) :
    SvXMLImportContext( rImport, nPrfx, rLName )
{
    sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; ++i )
    {
        const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
        rtl::OUString aLocalName;
        sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
                                            sAttrName, &aLocalName );
        const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));

        if (nPrefix == XML_NAMESPACE_TABLE)
        {
            if (IsXMLToken(aLocalName, XML_STATUS))
            {
                if (IsXMLToken(sValue, XML_ENABLE))
                    pCalcSet->SetIterationStatus(sal_True);
            }
            else if (IsXMLToken(aLocalName, XML_STEPS))
            {
                sal_Int32 nSteps;
                GetScImport().GetMM100UnitConverter().convertNumber(nSteps, sValue);
                pCalcSet->SetIterationCount(nSteps);
            }
            else if (IsXMLToken(aLocalName, XML_MAXIMUM_DIFFERENCE))
            {
                double fDif;
                GetScImport().GetMM100UnitConverter().convertDouble(fDif, sValue);
                pCalcSet->SetIterationEpsilon(fDif);
            }
        }
    }
}

ScXMLIterationContext::~ScXMLIterationContext()
{
}

SvXMLImportContext *ScXMLIterationContext::CreateChildContext( USHORT nPrefix,
                                            const ::rtl::OUString& rLName,
                                            const ::com::sun::star::uno::Reference<
                                          ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
{
    SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );

    return pContext;
}

void ScXMLIterationContext::EndElement()
{
}
<commit_msg>INTEGRATION: CWS ooo19126 (1.12.116); FILE MERGED 2005/09/05 15:03:17 rt 1.12.116.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLCalculationSettingsContext.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 19:48:19 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifdef PCH
#include "filt_pch.hxx"
#endif

#pragma hdrstop

// INCLUDE ---------------------------------------------------------------

#ifndef _SC_XMLCALCULATIONSETTINGSCONTEXT_HXX
#include "XMLCalculationSettingsContext.hxx"
#endif
#ifndef SC_XMLIMPRT_HXX
#include "xmlimprt.hxx"
#endif
#ifndef SC_UNONAMES_HXX
#include "unonames.hxx"
#endif
#ifndef SC_DOCOPTIO_HXX
#include "docoptio.hxx"
#endif
#ifndef SC_DOCUMENT_HXX
#include "document.hxx"
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include <xmloff/xmltoken.hxx>
#endif
#ifndef _XMLOFF_XMLNMSPE_HXX
#include <xmloff/xmlnmspe.hxx>
#endif
#ifndef _XMLOFF_XMLUCONV_HXX
#include <xmloff/xmluconv.hxx>
#endif
#ifndef _XMLOFF_NMSPMAP_HXX
#include <xmloff/nmspmap.hxx>
#endif

#ifndef _COM_SUN_STAR_SHEET_XSPREADSHEETDOCUMENT_HPP_
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif

using namespace com::sun::star;
using namespace xmloff::token;

//------------------------------------------------------------------

ScXMLCalculationSettingsContext::ScXMLCalculationSettingsContext( ScXMLImport& rImport,
                                      USHORT nPrfx,
                                      const ::rtl::OUString& rLName,
                                      const ::com::sun::star::uno::Reference<
                                      ::com::sun::star::xml::sax::XAttributeList>& xAttrList) :
    SvXMLImportContext( rImport, nPrfx, rLName ),
    fIterationEpsilon(0.001),
    nIterationCount(100),
    nYear2000(1930),
    bIsIterationEnabled(sal_False),
    bCalcAsShown(sal_False),
    bIgnoreCase(sal_False),
    bLookUpLabels(sal_True),
    bMatchWholeCell(sal_True),
    bUseRegularExpressions(sal_True)
{
    aNullDate.Day = 30;
    aNullDate.Month = 12;
    aNullDate.Year = 1899;
    sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; ++i )
    {
        const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
        rtl::OUString aLocalName;
        sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
                                            sAttrName, &aLocalName );
        const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));

        if (nPrefix == XML_NAMESPACE_TABLE)
        {
            if (IsXMLToken(aLocalName, XML_CASE_SENSITIVE))
            {
                if (IsXMLToken(sValue, XML_FALSE))
                    bIgnoreCase = sal_True;
            }
            else if (IsXMLToken(aLocalName, XML_PRECISION_AS_SHOWN))
            {
                if (IsXMLToken(sValue, XML_TRUE))
                    bCalcAsShown = sal_True;
            }
            else if (IsXMLToken(aLocalName, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL))
            {
                if (IsXMLToken(sValue, XML_FALSE))
                    bMatchWholeCell = sal_False;
            }
            else if (IsXMLToken(aLocalName, XML_AUTOMATIC_FIND_LABELS))
            {
                if (IsXMLToken(sValue, XML_FALSE))
                    bLookUpLabels = sal_False;
            }
            else if (IsXMLToken(aLocalName, XML_NULL_YEAR))
            {
                sal_Int32 nTemp;
                GetScImport().GetMM100UnitConverter().convertNumber(nTemp, sValue);
                nYear2000 = static_cast<sal_uInt16>(nTemp);
            }
            else if (IsXMLToken(aLocalName, XML_USE_REGULAR_EXPRESSIONS))
            {
                if (IsXMLToken(sValue, XML_FALSE))
                    bUseRegularExpressions = sal_False;
            }
        }
    }
}

ScXMLCalculationSettingsContext::~ScXMLCalculationSettingsContext()
{
}

SvXMLImportContext *ScXMLCalculationSettingsContext::CreateChildContext( USHORT nPrefix,
                                            const ::rtl::OUString& rLName,
                                            const ::com::sun::star::uno::Reference<
                                          ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
{
    SvXMLImportContext *pContext = 0;

    if (nPrefix == XML_NAMESPACE_TABLE)
    {
        if (IsXMLToken(rLName, XML_NULL_DATE))
            pContext = new ScXMLNullDateContext(GetScImport(), nPrefix, rLName, xAttrList, this);
        else if (IsXMLToken(rLName, XML_ITERATION))
            pContext = new ScXMLIterationContext(GetScImport(), nPrefix, rLName, xAttrList, this);
    }

    if( !pContext )
        pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );

    return pContext;
}

void ScXMLCalculationSettingsContext::EndElement()
{
    if (GetScImport().GetModel().is())
    {
        uno::Reference <beans::XPropertySet> xPropertySet (GetScImport().GetModel(), uno::UNO_QUERY);
        if (xPropertySet.is())
        {
            xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_CALCASSHOWN)), uno::makeAny(bCalcAsShown) );
            xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_IGNORECASE)), uno::makeAny(bIgnoreCase) );
            xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_LOOKUPLABELS)), uno::makeAny(bLookUpLabels) );
            xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_MATCHWHOLE)), uno::makeAny(bMatchWholeCell) );
            xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_REGEXENABLED)), uno::makeAny(bUseRegularExpressions) );
            xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERENABLED)), uno::makeAny(bIsIterationEnabled) );
            xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERCOUNT)), uno::makeAny(nIterationCount) );
            xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITEREPSILON)), uno::makeAny(fIterationEpsilon) );
            xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NULLDATE)), uno::makeAny(aNullDate) );
            if (GetScImport().GetDocument())
            {
                GetScImport().LockSolarMutex();
                ScDocOptions aDocOptions (GetScImport().GetDocument()->GetDocOptions());
                aDocOptions.SetYear2000(nYear2000);
                GetScImport().GetDocument()->SetDocOptions(aDocOptions);
                GetScImport().UnlockSolarMutex();
            }
        }
    }
}

ScXMLNullDateContext::ScXMLNullDateContext( ScXMLImport& rImport,
                                      USHORT nPrfx,
                                      const ::rtl::OUString& rLName,
                                      const ::com::sun::star::uno::Reference<
                                      ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
                                      ScXMLCalculationSettingsContext* pCalcSet) :
    SvXMLImportContext( rImport, nPrfx, rLName )
{
    sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; ++i )
    {
        const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
        rtl::OUString aLocalName;
        sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
                                            sAttrName, &aLocalName );
        const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));

        if (nPrefix == XML_NAMESPACE_TABLE && IsXMLToken(aLocalName, XML_DATE_VALUE))
        {
            util::DateTime aDateTime;
            GetScImport().GetMM100UnitConverter().convertDateTime(aDateTime, sValue);
            util::Date aDate;
            aDate.Day = aDateTime.Day;
            aDate.Month = aDateTime.Month;
            aDate.Year = aDateTime.Year;
            pCalcSet->SetNullDate(aDate);
        }
    }
}

ScXMLNullDateContext::~ScXMLNullDateContext()
{
}

SvXMLImportContext *ScXMLNullDateContext::CreateChildContext( USHORT nPrefix,
                                            const ::rtl::OUString& rLName,
                                            const ::com::sun::star::uno::Reference<
                                          ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
{
    SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );

    return pContext;
}

void ScXMLNullDateContext::EndElement()
{
}

ScXMLIterationContext::ScXMLIterationContext( ScXMLImport& rImport,
                                      USHORT nPrfx,
                                      const ::rtl::OUString& rLName,
                                      const ::com::sun::star::uno::Reference<
                                      ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
                                      ScXMLCalculationSettingsContext* pCalcSet) :
    SvXMLImportContext( rImport, nPrfx, rLName )
{
    sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; ++i )
    {
        const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
        rtl::OUString aLocalName;
        sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
                                            sAttrName, &aLocalName );
        const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));

        if (nPrefix == XML_NAMESPACE_TABLE)
        {
            if (IsXMLToken(aLocalName, XML_STATUS))
            {
                if (IsXMLToken(sValue, XML_ENABLE))
                    pCalcSet->SetIterationStatus(sal_True);
            }
            else if (IsXMLToken(aLocalName, XML_STEPS))
            {
                sal_Int32 nSteps;
                GetScImport().GetMM100UnitConverter().convertNumber(nSteps, sValue);
                pCalcSet->SetIterationCount(nSteps);
            }
            else if (IsXMLToken(aLocalName, XML_MAXIMUM_DIFFERENCE))
            {
                double fDif;
                GetScImport().GetMM100UnitConverter().convertDouble(fDif, sValue);
                pCalcSet->SetIterationEpsilon(fDif);
            }
        }
    }
}

ScXMLIterationContext::~ScXMLIterationContext()
{
}

SvXMLImportContext *ScXMLIterationContext::CreateChildContext( USHORT nPrefix,
                                            const ::rtl::OUString& rLName,
                                            const ::com::sun::star::uno::Reference<
                                          ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
{
    SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );

    return pContext;
}

void ScXMLIterationContext::EndElement()
{
}
<|endoftext|>