<commit_before>//
//  poNode.cpp
//  BasicTest
//
//  Created by Stephen Varga on 3/17/14.
//
//

#include "poNode.h"
#include "poNodeContainer.h"
#include "poScene.h"

namespace po {
    static uint OBJECT_UID  = 0;
    static const int ORIGIN_SIZE   = 2;

    NodeRef Node::create()
    {
        return std::shared_ptr<Node>(new Node());
    }

    Node::Node()
    :   uid(OBJECT_UID++)
    ,   position(0.f,0.f)
    ,   positionAnim(ci::Vec2f(0.f,0.f))
    ,   scale(1.f,1.f)
    ,   scaleAnim(ci::Vec2f(1.f,1.f))
    ,   rotation(0)
    ,   rotationAnim(0)
    ,   bUpdatePositionFromAnim(false)
    ,   bUpdateScaleFromAnim(false)
    ,   bUpdateRotationFromAnim(false)
    ,   bDrawBounds(false)
    ,   bVisible(true)
    ,   bInteractionEnabled(true)
    {
        positionAnim.stop();
        scaleAnim.stop();
        rotationAnim.stop();
    }

    Node::~Node() {

    }

    //------------------------------------------------------
    #pragma mark - Update & Draw Trees -

    void Node::updateTree()
    {
        //See if a tween is in progress, if so we want to use that value
        //setting position calls stop() so that will override this
        if(!positionAnim.isComplete())  bUpdatePositionFromAnim = true;
        if(!scaleAnim.isComplete())     bUpdateScaleFromAnim = true;
        if(!rotationAnim.isComplete())  bUpdateRotationFromAnim = true;

        //Update Anims if we care
        if(bUpdatePositionFromAnim)  position    = positionAnim;
        if(bUpdateScaleFromAnim)     scale       = scaleAnim;
        if(bUpdateRotationFromAnim)  rotation    = rotationAnim;

        //Call our update function
        update();
    }

    void Node::drawTree()
    {
        //If we're invisible, nothing to do here
        if(!bVisible) return;

        //Update our draw order
        drawOrder = scene.lock()->getNextDrawOrder();

        //Push our Matrix
        ci::gl::pushMatrices();
        setTransformation();

        //Draw this item
        draw();

        //Draw bounds if necessary
        if(bDrawBounds)
            drawBounds();

        //Pop our Matrix
        ci::gl::popMatrices();
    }

    //------------------------------------------------------
    #pragma mark - Attributes -

    void Node::setPosition(float x, float y)
    {
        positionAnim.stop();
        bUpdatePositionFromAnim = false;
        position.set(x, y);
    }

    void Node::setScale(float x, float y)
    {
        scaleAnim.stop();
        bUpdateScaleFromAnim = false;
        scale.set(x, y);
    }

    void Node::setRotation(float rotation) {
        rotationAnim.stop();
        bUpdateRotationFromAnim = false;
        this->rotation = rotation;
    }

    //------------------------------------------------------
    #pragma mark - Transformation -

    void Node::setTransformation()
    {
        #pragma message "Need to implement matrix order"
        ci::gl::translate(position);
        ci::gl::rotate(rotation);
        ci::gl::scale(scale);

        matrix.set(ci::gl::getModelView(), ci::gl::getProjection(), ci::gl::getViewport());
    }

    ci::Vec2f Node::sceneToLocal(ci::Vec2f scenePoint)
    {
        return ci::Vec2f();
    }

    ci::Vec2f Node::globalToLocal(ci::Vec2f globalPoint)
    {
        return matrix.globalToLocal(globalPoint);
    }

    bool Node::pointInside(ci::Vec2f point)
    {
        return true;
    }

    //------------------------------------------------------
    #pragma mark - Parent & Scene -

    void Node::setScene(SceneRef sceneRef) {
        scene = sceneRef;
        if(hasScene()) scene.lock()->trackChildNode(shared_from_this());
    }

    SceneRef Node::getScene()
    {
        return scene.lock();
    }

    bool Node::hasScene()
    {
        return (scene.lock() ? true : false);
    }

    void Node::removeScene()
    {
        if(hasScene()) scene.lock()->untrackChildNode(shared_from_this());
        scene.reset();
    }

    void Node::setParent(NodeContainerRef containerNode)
    {
        parent = containerNode;
    }

    NodeContainerRef Node::getParent() const {
        return parent.lock();
    }

    bool Node::hasParent()
    {
        return (parent.lock() ? true : false);
    }

    void Node::removeParent() {
        parent.reset();
    }

    //------------------------------------------------------
    #pragma mark  - Dimensions -

    ci::Rectf Node::getBounds()
    {
        //Reset Bounds
        ci::Rectf bounds = ci::Rectf(0,0,0,0);
        return bounds;
    }

    void Node::drawBounds()
    {
        ci::gl::color(255,0,0);

        //Draw bounding box
        ci::gl::drawStrokedRect(getBounds());

        //Draw origin
        ci::gl::pushMatrices();
        ci::gl::scale(ci::Vec2f(1.f,1.f)/ scale);
        ci::gl::drawSolidRect(ci::Rectf(-ORIGIN_SIZE/2, -ORIGIN_SIZE/2, ORIGIN_SIZE, ORIGIN_SIZE));
        ci::gl::popMatrices();
    }

    ci::Rectf Node::getFrame()
    {
        ci::Rectf frame = getBounds();
        frame.scale(scale);
        frame.offset(position);
        return frame;
    }

    //------------------------------------------------------
    #pragma mark  - Events -

    #pragma mark General
    void Node::removeAllEvents() {}

    //Check any list of event callbacks to see if there is already a callback for a given listener
    bool Node::callbackAlreadyExistsForListener(NodeRef listener, std::vector<EventCallback> &callbackList)
    {
        for(EventCallback callback : callbackList) {
            if(callback.listener.lock() == listener) {
                return true;
            }
        }

        return false;
    }

    #pragma mark Mouse Events

    //Global Events
    void Node::notifyGlobal(po::MouseEvent &event) {
        #pragma message "If we just have one mouse event handler this gets infinitely cleaner...i.e. just node->mouseEvent(event)"
        switch (event.getType()) {
            case po::MouseEvent::Type::DOWN:
                mouseDown(event);
                break;

            case po::MouseEvent::Type::MOVE:
                mouseMove(event);
                break;

            case po::MouseEvent::Type::DRAG:
                mouseDrag(event);
                break;

            case po::MouseEvent::Type::UP:
                mouseUp(event);
                break;

            case po::MouseEvent::Type::WHEEL:
                mouseWheel(event);
                break;
        }
    }

    //Callbacks
    void Node::addEvent(po::MouseEvent::Type type, NodeRef source)
    {
        //Subscribe to the source
        source->registerEventCallback(type, shared_from_this());
        #pragma message "Now we need to track our subscriptions on this end for removing events"
        //Track this Subscription
    }

    void Node::removeEvent(po::MouseEvent::Type type, NodeRef source) {}

    //Sets this event
    void Node::registerEventCallback(po::MouseEvent::Type type, NodeRef listener)
    {
        //Check to see if we already have the callback
        if(callbackAlreadyExistsForListener(listener, mouseEventCallbacks[type]))
            return;

        //Otherwise Insert this callback
        EventCallback callback;
        callback.listener = listener;
        mouseEventCallbacks[type].push_back(callback);
    }

    //See if we care about an event
    bool Node::hasCallbacks(po::MouseEvent::Type type)
    {
        if(type == po::MouseEvent::Type::DOWN_INSIDE) {
            "Yea!";
        }
        return mouseEventCallbacks[type].size();
    }

    //For the given event, notify everyone that we have as a subscriber
    void Node::notifyCallbacks(po::MouseEvent &event)
    {
        event.source = shared_from_this();

        //Iterate through all callbacks
        for(EventCallback callback : mouseEventCallbacks[event.getType()])
        {
            //Notify the callback
            NodeRef listener = callback.listener.lock();

            #pragma message "Can we do this any better, maybe using templates?"
            if(listener && !callback.markedForRemoval) {
                switch (event.getType()) {
                    case po::MouseEvent::Type::DOWN_INSIDE:
                        listener->mouseDownInside(event);
                        break;

                    case po::MouseEvent::Type::MOVE_INSIDE:
                        listener->mouseMoveInside(event);
                        break;

                    case po::MouseEvent::Type::DRAG_INSIDE:
                        listener->mouseDragInside(event);
                        break;

                    case po::MouseEvent::Type::UP_INSIDE:
                        listener->mouseUpInside(event);
                        break;
                }
            }
        }

        //Cleanup our callbacks, checking for deleted node refs or callbacks that have been markedForRemoval
        std::vector<EventCallback>::iterator iter = mouseEventCallbacks[event.getType()].begin();
        for(; iter != mouseEventCallbacks[event.getType()].end(); ++iter)
        {
            if(!(*iter).listener.lock() || (*iter).markedForRemoval) {
                iter = mouseEventCallbacks[event.getType()].erase(iter);
            }
        }
    }
}
<commit_msg>Spacing<commit_after>//
//  poNode.cpp
//  BasicTest
//
//  Created by Stephen Varga on 3/17/14.
//
//

#include "poNode.h"
#include "poNodeContainer.h"
#include "poScene.h"

namespace po {
    static uint OBJECT_UID  = 0;
    static const int ORIGIN_SIZE   = 2;

    NodeRef Node::create()
    {
        return std::shared_ptr<Node>(new Node());
    }

    Node::Node()
    :   uid(OBJECT_UID++)
    ,   position(0.f,0.f)
    ,   positionAnim(ci::Vec2f(0.f,0.f))
    ,   scale(1.f,1.f)
    ,   scaleAnim(ci::Vec2f(1.f,1.f))
    ,   rotation(0)
    ,   rotationAnim(0)
    ,   bUpdatePositionFromAnim(false)
    ,   bUpdateScaleFromAnim(false)
    ,   bUpdateRotationFromAnim(false)
    ,   bDrawBounds(false)
    ,   bVisible(true)
    ,   bInteractionEnabled(true)
    {
        positionAnim.stop();
        scaleAnim.stop();
        rotationAnim.stop();
    }

    Node::~Node() {

    }

    //------------------------------------------------------
    #pragma mark - Update & Draw Trees -

    void Node::updateTree()
    {
        //See if a tween is in progress, if so we want to use that value
        //setting position calls stop() so that will override this
        if(!positionAnim.isComplete())  bUpdatePositionFromAnim = true;
        if(!scaleAnim.isComplete())     bUpdateScaleFromAnim    = true;
        if(!rotationAnim.isComplete())  bUpdateRotationFromAnim = true;

        //Update Anims if we care
        if(bUpdatePositionFromAnim)  position    = positionAnim;
        if(bUpdateScaleFromAnim)     scale       = scaleAnim;
        if(bUpdateRotationFromAnim)  rotation    = rotationAnim;

        //Call our update function
        update();
    }

    void Node::drawTree()
    {
        //If we're invisible, nothing to do here
        if(!bVisible) return;

        //Update our draw order
        drawOrder = scene.lock()->getNextDrawOrder();

        //Push our Matrix
        ci::gl::pushMatrices();
        setTransformation();

        //Draw this item
        draw();

        //Draw bounds if necessary
        if(bDrawBounds)
            drawBounds();

        //Pop our Matrix
        ci::gl::popMatrices();
    }

    //------------------------------------------------------
    #pragma mark - Attributes -

    void Node::setPosition(float x, float y)
    {
        positionAnim.stop();
        bUpdatePositionFromAnim = false;
        position.set(x, y);
    }

    void Node::setScale(float x, float y)
    {
        scaleAnim.stop();
        bUpdateScaleFromAnim = false;
        scale.set(x, y);
    }

    void Node::setRotation(float rotation) {
        rotationAnim.stop();
        bUpdateRotationFromAnim = false;
        this->rotation = rotation;
    }

    //------------------------------------------------------
    #pragma mark - Transformation -

    void Node::setTransformation()
    {
        #pragma message "Need to implement matrix order"
        ci::gl::translate(position);
        ci::gl::rotate(rotation);
        ci::gl::scale(scale);

        matrix.set(ci::gl::getModelView(), ci::gl::getProjection(), ci::gl::getViewport());
    }

    ci::Vec2f Node::sceneToLocal(ci::Vec2f scenePoint)
    {
        return ci::Vec2f();
    }

    ci::Vec2f Node::globalToLocal(ci::Vec2f globalPoint)
    {
        return matrix.globalToLocal(globalPoint);
    }

    bool Node::pointInside(ci::Vec2f point)
    {
        return true;
    }

    //------------------------------------------------------
    #pragma mark - Parent & Scene -

    void Node::setScene(SceneRef sceneRef) {
        scene = sceneRef;
        if(hasScene()) scene.lock()->trackChildNode(shared_from_this());
    }

    SceneRef Node::getScene()
    {
        return scene.lock();
    }

    bool Node::hasScene()
    {
        return (scene.lock() ? true : false);
    }

    void Node::removeScene()
    {
        if(hasScene()) scene.lock()->untrackChildNode(shared_from_this());
        scene.reset();
    }

    void Node::setParent(NodeContainerRef containerNode)
    {
        parent = containerNode;
    }

    NodeContainerRef Node::getParent() const {
        return parent.lock();
    }

    bool Node::hasParent()
    {
        return (parent.lock() ? true : false);
    }

    void Node::removeParent() {
        parent.reset();
    }

    //------------------------------------------------------
    #pragma mark  - Dimensions -

    ci::Rectf Node::getBounds()
    {
        //Reset Bounds
        ci::Rectf bounds = ci::Rectf(0,0,0,0);
        return bounds;
    }

    void Node::drawBounds()
    {
        ci::gl::color(255,0,0);

        //Draw bounding box
        ci::gl::drawStrokedRect(getBounds());

        //Draw origin
        ci::gl::pushMatrices();
        ci::gl::scale(ci::Vec2f(1.f,1.f)/ scale);
        ci::gl::drawSolidRect(ci::Rectf(-ORIGIN_SIZE/2, -ORIGIN_SIZE/2, ORIGIN_SIZE, ORIGIN_SIZE));
        ci::gl::popMatrices();
    }

    ci::Rectf Node::getFrame()
    {
        ci::Rectf frame = getBounds();
        frame.scale(scale);
        frame.offset(position);
        return frame;
    }

    //------------------------------------------------------
    #pragma mark  - Events -

    #pragma mark General
    void Node::removeAllEvents() {}

    //Check any list of event callbacks to see if there is already a callback for a given listener
    bool Node::callbackAlreadyExistsForListener(NodeRef listener, std::vector<EventCallback> &callbackList)
    {
        for(EventCallback callback : callbackList) {
            if(callback.listener.lock() == listener) {
                return true;
            }
        }

        return false;
    }

    #pragma mark Mouse Events

    //Global Events
    void Node::notifyGlobal(po::MouseEvent &event) {
        #pragma message "If we just have one mouse event handler this gets infinitely cleaner...i.e. just node->mouseEvent(event)"
        switch (event.getType()) {
            case po::MouseEvent::Type::DOWN:
                mouseDown(event);
                break;

            case po::MouseEvent::Type::MOVE:
                mouseMove(event);
                break;

            case po::MouseEvent::Type::DRAG:
                mouseDrag(event);
                break;

            case po::MouseEvent::Type::UP:
                mouseUp(event);
                break;

            case po::MouseEvent::Type::WHEEL:
                mouseWheel(event);
                break;
        }
    }

    //Callbacks
    void Node::addEvent(po::MouseEvent::Type type, NodeRef source)
    {
        //Subscribe to the source
        source->registerEventCallback(type, shared_from_this());
        #pragma message "Now we need to track our subscriptions on this end for removing events"
        //Track this Subscription
    }

    void Node::removeEvent(po::MouseEvent::Type type, NodeRef source) {}

    //Sets this event
    void Node::registerEventCallback(po::MouseEvent::Type type, NodeRef listener)
    {
        //Check to see if we already have the callback
        if(callbackAlreadyExistsForListener(listener, mouseEventCallbacks[type]))
            return;

        //Otherwise Insert this callback
        EventCallback callback;
        callback.listener = listener;
        mouseEventCallbacks[type].push_back(callback);
    }

    //See if we care about an event
    bool Node::hasCallbacks(po::MouseEvent::Type type)
    {
        if(type == po::MouseEvent::Type::DOWN_INSIDE) {
            "Yea!";
        }
        return mouseEventCallbacks[type].size();
    }

    //For the given event, notify everyone that we have as a subscriber
    void Node::notifyCallbacks(po::MouseEvent &event)
    {
        event.source = shared_from_this();

        //Iterate through all callbacks
        for(EventCallback callback : mouseEventCallbacks[event.getType()])
        {
            //Notify the callback
            NodeRef listener = callback.listener.lock();

            #pragma message "Can we do this any better, maybe using templates?"
            if(listener && !callback.markedForRemoval) {
                switch (event.getType()) {
                    case po::MouseEvent::Type::DOWN_INSIDE:
                        listener->mouseDownInside(event);
                        break;

                    case po::MouseEvent::Type::MOVE_INSIDE:
                        listener->mouseMoveInside(event);
                        break;

                    case po::MouseEvent::Type::DRAG_INSIDE:
                        listener->mouseDragInside(event);
                        break;

                    case po::MouseEvent::Type::UP_INSIDE:
                        listener->mouseUpInside(event);
                        break;
                }
            }
        }

        //Cleanup our callbacks, checking for deleted node refs or callbacks that have been markedForRemoval
        std::vector<EventCallback>::iterator iter = mouseEventCallbacks[event.getType()].begin();
        for(; iter != mouseEventCallbacks[event.getType()].end(); ++iter)
        {
            if(!(*iter).listener.lock() || (*iter).markedForRemoval) {
                iter = mouseEventCallbacks[event.getType()].erase(iter);
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <policy/feerate.h>

#include <tinyformat.h>

CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nBytes_)
{
    assert(nBytes_ <= uint64_t(std::numeric_limits<int64_t>::max()));
    int64_t nSize = int64_t(nBytes_);

    if (nSize > 0)
        nSatoshisPerK = nFeePaid * 1000 / nSize;
    else
        nSatoshisPerK = 0;
}

CAmount CFeeRate::GetFee(size_t nBytes_) const
{
    if((nBytes_*1000) > uint64_t(std::numeric_limits<int64_t>::max()))
        return 0;
    if((nSatoshisPerK*1000) > std::numeric_limits<int64_t>::max())
        return 0;
    assert(nBytes_ <= uint64_t(std::numeric_limits<int64_t>::max()));
    int64_t nSize = int64_t(nBytes_);

    CAmount nFee = nSatoshisPerK * nSize / 1000;

    if (nFee == 0 && nSize != 0) {
        if (nSatoshisPerK > 0)
            nFee = CAmount(1);
        if (nSatoshisPerK < 0)
            nFee = CAmount(-1);
    }

    return nFee;
}

std::string CFeeRate::ToString(const FeeEstimateMode& fee_estimate_mode) const
{
    switch (fee_estimate_mode) {
    case FeeEstimateMode::SAT_B:  return strprintf("%d.%03d %s/B", nSatoshisPerK / 1000, nSatoshisPerK % 1000, CURRENCY_ATOM);
    default:                      return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT);
    }
}
<commit_msg>Update feerate.cpp<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <policy/feerate.h>

#include <tinyformat.h>

CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nBytes_)
{
    assert(nBytes_ <= uint64_t(std::numeric_limits<int64_t>::max()));
    int64_t nSize = int64_t(nBytes_);

    if (nSize > 0)
        nSatoshisPerK = nFeePaid * 1000 / nSize;
    else
        nSatoshisPerK = 0;
}

CAmount CFeeRate::GetFee(size_t nBytes_) const
{
    if(nBytes_ > uint64_t(std::numeric_limits<int64_t>::max()/1000))
        return 0;
    if(nSatoshisPerK > std::numeric_limits<int64_t>::max()/1000)
        return 0;
    assert(nBytes_ <= uint64_t(std::numeric_limits<int64_t>::max()));
    int64_t nSize = int64_t(nBytes_);

    CAmount nFee = nSatoshisPerK * nSize / 1000;

    if (nFee == 0 && nSize != 0) {
        if (nSatoshisPerK > 0)
            nFee = CAmount(1);
        if (nSatoshisPerK < 0)
            nFee = CAmount(-1);
    }

    return nFee;
}

std::string CFeeRate::ToString(const FeeEstimateMode& fee_estimate_mode) const
{
    switch (fee_estimate_mode) {
    case FeeEstimateMode::SAT_B:  return strprintf("%d.%03d %s/B", nSatoshisPerK / 1000, nSatoshisPerK % 1000, CURRENCY_ATOM);
    default:                      return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT);
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Vinzenz Feenstra
//
// 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.
#if !(defined(GUARD_PYPA_AST_AST_HH_INCLUDED) && defined(GUARD_PYPA_AST_TYPES_HH_INCLUDED))
#   error "This must be only included by pypa/ast/ast.hh"
#endif
#ifndef GUARD_PYPA_AST_MACROS_HH_INCLUDED
#define GUARD_PYPA_AST_MACROS_HH_INCLUDED

#define DEF_AST_TYPE_BY_ID(ID, TYPE) \
    template<> struct AstIDByType<TYPE> { static constexpr AstType Id = AstType::ID; static char const * name(){ return #ID; }}; \
    template<> struct AstTypeByID<AstType::ID> { typedef TYPE Type; static char const * name(){ return #ID; }}

#define DEF_AST_TYPE_BY_ID1(TYPE) DEF_AST_TYPE_BY_ID(TYPE, Ast##TYPE)

#define PYPA_AST_TYPE_DECL_ALIAS(NAME, ALIASPTR, ALIASLIST) \
    typedef std::shared_ptr<struct NAME> ALIASPTR; \
    typedef std::vector<ALIASPTR> ALIASLIST; \
    struct NAME

#define PYPA_AST_TYPE_DECL(NAME) \
    PYPA_AST_TYPE_DECL_ALIAS(NAME, NAME##Ptr, NAME##List)

#define PYPA_AST_TYPE_DECL_DERIVED_TPL(NAME, TPL) \
    PYPA_AST_TYPE_DECL(Ast##NAME) : TPL<AstType::NAME>

#define PYPA_AST_TYPE_DECL_DERIVED(NAME) \
    PYPA_AST_TYPE_DECL_DERIVED_TPL(NAME, AstT)

#define PYPA_AST_TYPE_DECL_DERIVED_ALIAS(NAME, ALIASPTR, ALIASLIST) \
    PYPA_AST_TYPE_DECL_ALIAS(Ast##NAME, ALIASPTR, ALIASLIST) : AstT<AstType::NAME>

#define PYPA_AST_TYPE_DECL_SLICE_KIND(NAME) \
    PYPA_AST_TYPE_DECL_DERIVED_TPL(NAME, AstSliceT)

#define PYPA_AST_STMT(AST_TYPE) \
    typedef std::shared_ptr<struct Ast##AST_TYPE> Ast##AST_TYPE##Ptr; \
    DEF_AST_TYPE_BY_ID(AST_TYPE, struct Ast##AST_TYPE); \
    struct Ast##AST_TYPE : AstStmtT<AstType::AST_TYPE>

#define PYPA_AST_EXPR(AST_TYPE) \
    typedef std::shared_ptr<struct Ast##AST_TYPE> Ast##AST_TYPE##Ptr; \
    DEF_AST_TYPE_BY_ID(AST_TYPE, struct Ast##AST_TYPE); \
    struct Ast##AST_TYPE : AstExprT<AstType::AST_TYPE>

#define PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPEID)                                     \
    template<>                                                                      \
    struct ast_member_dump<Ast##TYPEID> {                                           \
        typedef Ast##TYPEID Type;                                                   \
        static void print_padding(int depth) { while(depth--) printf(" "); }        \
        static void dump(int depth, std::shared_ptr<Ast##TYPEID> const & p) {       \
            if(p) dump(depth, *p);                                                  \
        }                                                                           \
        static void dump(int depth, Ast##TYPEID const & t) {                        \
            printf("[%s]\n", AstIDByType<Ast##TYPEID>::name());                     \
            print_padding(depth);                                                   \

#define PYPA_AST_MEMBER_DUMP_IMPL_END(TYPEID)                                       \
        }                                                                           \
        template< typename MemberType >                                             \
        static void dump_member(int depth, Ast##TYPEID const & t, char const * name, MemberType const Ast##TYPEID::*m) { \
                printf("  - %s:", name);                                            \
                dump_member_value(depth + 4, t.*m);                                 \
        }                                                                           \
        template< typename T >                                                      \
        static void dump_member_value(int depth, std::shared_ptr<T> const & v) {    \
            if(!v) printf("<NULL>");                                                \
            else { T const & v_ = *v; dump_member_value(int(depth), v_); }          \
        }                                                                           \
        template< typename T >                                                      \
        static void dump_member_value(int depth, std::vector<T> const & v) {        \
            printf("[\n");                                                          \
            for(auto const & e : v) {                                               \
                print_padding(depth+4);                                             \
                dump_member_value(depth+4, e);                                      \
            }                                                                       \
            print_padding(depth);                                                   \
            printf("]\n");                                                          \
        }                                                                           \
        static void dump_member_value(int depth, Ast const & v) {                   \
            printf("\n");                                                           \
            print_padding(depth+4);                                                 \
            pypa::detail::visit_dump_internal(depth, v);                            \
        }                                                                           \
        static void dump_member_value(int depth, String const & v) {                \
            printf("%s", v.c_str());                                                \
        }                                                                           \
        static void dump_member_value(int depth, char const * v) {                  \
            printf("RAW BUFFER: %p", v);                                            \
        }                                                                           \
        static void dump_member_value(int depth, bool v) {                          \
            printf("%s", v ? "True" : "False");                                     \
        }                                                                           \
        static void dump_member_value(int depth, int const & v) {                   \
            printf("%d", int(v));                                                   \
        }                                                                           \
        static void dump_member_value(int depth, AstBoolOpType const & v) {         \
            printf("%d", int(v));                                                   \
        }                                                                           \
        static void dump_member_value(int depth, AstUnaryOpType const & v) {        \
            printf("%d", int(v));                                                   \
        }                                                                           \
        static void dump_member_value(int depth, AstCompareOpType const & v) {      \
            printf("%d", int(v));                                                   \
        }                                                                           \
        static void dump_member_value(int depth, AstBinOpType const & v) {          \
            printf("%d", int(v));                                                   \
        }                                                                           \
        static void dump_member_value(int depth, AstContext const & v) {            \
            printf("%d", int(v));                                                   \
        }                                                                           \
    };

#define PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARGNAME)                               \
            dump_member(depth, t, #ARGNAME, &Type::ARGNAME);

#define PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPEID)                               \
    template<>                                                                  \
    struct ast_member_visit<AstType::TYPEID> {                                  \
        template<typename T, typename V, typename F>                            \
        static void do_apply(T t, V T::*v, F f) {                               \
            detail::apply_member(t, v, f);                                      \
        }                                                                       \
        template<typename T, typename V, typename F>                            \
        static void do_apply(std::shared_ptr<T> t, V T::*v, F f) {              \
            detail::apply_member(t, v, f);                                      \
        }                                                                       \
        template<typename T, typename F>                                        \
        static void apply(T t, F f) {                                           \
            typedef typename AstTypeByID<AstType::TYPEID>::Type Type;           \
            f(t);

#define PYPA_AST_MEMBER_VISIT_IMPL_END }}

#define PYPA_AST_MEMBERS0(TYPE) \
    PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPE)      \
    PYPA_AST_MEMBER_DUMP_IMPL_END(TYPE)        \
    PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPE)     \
    PYPA_AST_MEMBER_VISIT_IMPL_END

#define PYPA_AST_MEMBERS1(TYPE, ARG0)          \
    PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPE)      \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG0)     \
    PYPA_AST_MEMBER_DUMP_IMPL_END(TYPE)        \
    PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPE)     \
    do_apply(t, &Type::ARG0, f);               \
    PYPA_AST_MEMBER_VISIT_IMPL_END

#define PYPA_AST_MEMBERS2(TYPE, ARG0, ARG1)     \
    PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPE)      \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG0)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG1)     \
    PYPA_AST_MEMBER_DUMP_IMPL_END(TYPE)        \
    PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPE)     \
    do_apply(t, &Type::ARG0, f);                \
    do_apply(t, &Type::ARG1, f);                \
    PYPA_AST_MEMBER_VISIT_IMPL_END

#define PYPA_AST_MEMBERS3(TYPE, ARG0, ARG1, ARG2)       \
    PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPE)      \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG0)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG1)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG2)     \
    PYPA_AST_MEMBER_DUMP_IMPL_END(TYPE)        \
    PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPE)             \
    do_apply(t, &Type::ARG0, f);                        \
    do_apply(t, &Type::ARG1, f);                        \
    do_apply(t, &Type::ARG2, f);                        \
    PYPA_AST_MEMBER_VISIT_IMPL_END
#define PYPA_AST_MEMBERS4(TYPE, ARG0, ARG1, ARG2, ARG3)     \
    PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPE)      \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG0)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG1)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG2)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG3)     \
    PYPA_AST_MEMBER_DUMP_IMPL_END(TYPE)        \
    PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPE)                 \
    do_apply(t, &Type::ARG0, f);                            \
    do_apply(t, &Type::ARG1, f);                            \
    do_apply(t, &Type::ARG2, f);                            \
    do_apply(t, &Type::ARG3, f);                            \
    PYPA_AST_MEMBER_VISIT_IMPL_END

#define PYPA_AST_MEMBERS5(TYPE, ARG0, ARG1, ARG2, ARG3, ARG4)       \
    PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPE)      \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG0)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG1)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG2)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG3)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG4)     \
    PYPA_AST_MEMBER_DUMP_IMPL_END(TYPE)        \
    PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPE)                         \
    do_apply(t, &Type::ARG0, f);                                    \
    do_apply(t, &Type::ARG1, f);                                    \
    do_apply(t, &Type::ARG2, f);                                    \
    do_apply(t, &Type::ARG3, f);                                    \
    do_apply(t, &Type::ARG4, f);                                    \
    PYPA_AST_MEMBER_VISIT_IMPL_END

#endif //GUARD_PYPA_AST_MACROS_HH_INCLUDED
<commit_msg>Improved the dump<commit_after>// Copyright 2014 Vinzenz Feenstra
//
// 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.
#if !(defined(GUARD_PYPA_AST_AST_HH_INCLUDED) && defined(GUARD_PYPA_AST_TYPES_HH_INCLUDED))
#   error "This must be only included by pypa/ast/ast.hh"
#endif
#ifndef GUARD_PYPA_AST_MACROS_HH_INCLUDED
#define GUARD_PYPA_AST_MACROS_HH_INCLUDED

#define DEF_AST_TYPE_BY_ID(ID, TYPE) \
    template<> struct AstIDByType<TYPE> { static constexpr AstType Id = AstType::ID; static char const * name(){ return #ID; }}; \
    template<> struct AstTypeByID<AstType::ID> { typedef TYPE Type; static char const * name(){ return #ID; }}

#define DEF_AST_TYPE_BY_ID1(TYPE) DEF_AST_TYPE_BY_ID(TYPE, Ast##TYPE)

#define PYPA_AST_TYPE_DECL_ALIAS(NAME, ALIASPTR, ALIASLIST) \
    typedef std::shared_ptr<struct NAME> ALIASPTR; \
    typedef std::vector<ALIASPTR> ALIASLIST; \
    struct NAME

#define PYPA_AST_TYPE_DECL(NAME) \
    PYPA_AST_TYPE_DECL_ALIAS(NAME, NAME##Ptr, NAME##List)

#define PYPA_AST_TYPE_DECL_DERIVED_TPL(NAME, TPL) \
    PYPA_AST_TYPE_DECL(Ast##NAME) : TPL<AstType::NAME>

#define PYPA_AST_TYPE_DECL_DERIVED(NAME) \
    PYPA_AST_TYPE_DECL_DERIVED_TPL(NAME, AstT)

#define PYPA_AST_TYPE_DECL_DERIVED_ALIAS(NAME, ALIASPTR, ALIASLIST) \
    PYPA_AST_TYPE_DECL_ALIAS(Ast##NAME, ALIASPTR, ALIASLIST) : AstT<AstType::NAME>

#define PYPA_AST_TYPE_DECL_SLICE_KIND(NAME) \
    PYPA_AST_TYPE_DECL_DERIVED_TPL(NAME, AstSliceT)

#define PYPA_AST_STMT(AST_TYPE) \
    typedef std::shared_ptr<struct Ast##AST_TYPE> Ast##AST_TYPE##Ptr; \
    DEF_AST_TYPE_BY_ID(AST_TYPE, struct Ast##AST_TYPE); \
    struct Ast##AST_TYPE : AstStmtT<AstType::AST_TYPE>

#define PYPA_AST_EXPR(AST_TYPE) \
    typedef std::shared_ptr<struct Ast##AST_TYPE> Ast##AST_TYPE##Ptr; \
    DEF_AST_TYPE_BY_ID(AST_TYPE, struct Ast##AST_TYPE); \
    struct Ast##AST_TYPE : AstExprT<AstType::AST_TYPE>

#define PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPEID)                                     \
    template<>                                                                      \
    struct ast_member_dump<Ast##TYPEID> {                                           \
        typedef Ast##TYPEID Type;                                                   \
        static void print_padding(int depth) { while(depth--) printf(" "); }        \
        static void dump(int depth, std::shared_ptr<Ast##TYPEID> const & p) {       \
            if(p) dump(depth, *p);                                                  \
        }                                                                           \
        static void dump(int depth, Ast##TYPEID const & t) {                        \
            printf("[%s]\n", AstIDByType<Ast##TYPEID>::name());                     \

#define PYPA_AST_MEMBER_DUMP_IMPL_END(TYPEID)                                       \
        }                                                                           \
        template< typename MemberType >                                             \
        static void dump_member(int depth, Ast##TYPEID const & t, char const * name, MemberType const Ast##TYPEID::*m) { \
                print_padding(depth+4);                                             \
                printf("  - %s: ", name);                                           \
                dump_member_value(depth + 4, t.*m);                                 \
        }                                                                           \
        template< typename T >                                                      \
        static void dump_member_value(int depth, std::shared_ptr<T> const & v) {    \
            if(!v) printf("<NULL>");                                                \
            else { T const & v_ = *v; dump_member_value(int(depth), v_); }          \
        }                                                                           \
        template< typename T >                                                      \
        static void dump_member_value(int depth, std::vector<T> const & v) {        \
            if(v.empty()) {                                                         \
                printf("[]\n");                                                     \
            }                                                                       \
            else {                                                                  \
                printf("[");                                                        \
                for(auto const & e : v) {                                           \
                    print_padding(depth+4);                                         \
                    dump_member_value(depth+4, e);                                  \
                }                                                                   \
                print_padding(depth);                                               \
                printf("]\n");                                                      \
            }                                                                       \
        }                                                                           \
        static void dump_member_value(int depth, Ast const & v) {                   \
            printf("\n");                                                           \
            print_padding(depth+4);                                                 \
            pypa::detail::visit_dump_internal(depth, v);                            \
        }                                                                           \
        static void dump_member_value(int depth, String const & v) {                \
            printf("%s\n", v.c_str());                                              \
        }                                                                           \
        static void dump_member_value(int depth, char const * v) {                  \
            printf("RAW BUFFER: %p\n", v);                                          \
        }                                                                           \
        static void dump_member_value(int depth, bool v) {                          \
            printf("%s\n", v ? "True" : "False");                                   \
        }                                                                           \
        static void dump_member_value(int depth, int const & v) {                   \
            printf("%d\n", int(v));                                                 \
        }                                                                           \
        static void dump_member_value(int depth, AstBoolOpType const & v) {         \
            printf("%d\n", int(v));                                                 \
        }                                                                           \
        static void dump_member_value(int depth, AstUnaryOpType const & v) {        \
            printf("%d\n", int(v));                                                 \
        }                                                                           \
        static void dump_member_value(int depth, AstCompareOpType const & v) {      \
            printf("%d\n", int(v));                                                 \
        }                                                                           \
        static void dump_member_value(int depth, AstBinOpType const & v) {          \
            printf("%d\n", int(v));                                                 \
        }                                                                           \
        static void dump_member_value(int depth, AstContext const & v) {            \
            printf("%d\n", int(v));                                                 \
        }                                                                           \
    };

#define PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARGNAME)                               \
            dump_member(depth, t, #ARGNAME, &Type::ARGNAME);

#define PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPEID)                               \
    template<>                                                                  \
    struct ast_member_visit<AstType::TYPEID> {                                  \
        template<typename T, typename V, typename F>                            \
        static void do_apply(T t, V T::*v, F f) {                               \
            detail::apply_member(t, v, f);                                      \
        }                                                                       \
        template<typename T, typename V, typename F>                            \
        static void do_apply(std::shared_ptr<T> t, V T::*v, F f) {              \
            detail::apply_member(t, v, f);                                      \
        }                                                                       \
        template<typename T, typename F>                                        \
        static void apply(T t, F f) {                                           \
            typedef typename AstTypeByID<AstType::TYPEID>::Type Type;           \
            f(t);

#define PYPA_AST_MEMBER_VISIT_IMPL_END }}

#define PYPA_AST_MEMBERS0(TYPE) \
    PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPE)      \
    PYPA_AST_MEMBER_DUMP_IMPL_END(TYPE)        \
    PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPE)     \
    PYPA_AST_MEMBER_VISIT_IMPL_END

#define PYPA_AST_MEMBERS1(TYPE, ARG0)          \
    PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPE)      \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG0)     \
    PYPA_AST_MEMBER_DUMP_IMPL_END(TYPE)        \
    PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPE)     \
    do_apply(t, &Type::ARG0, f);               \
    PYPA_AST_MEMBER_VISIT_IMPL_END

#define PYPA_AST_MEMBERS2(TYPE, ARG0, ARG1)     \
    PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPE)      \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG0)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG1)     \
    PYPA_AST_MEMBER_DUMP_IMPL_END(TYPE)        \
    PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPE)     \
    do_apply(t, &Type::ARG0, f);                \
    do_apply(t, &Type::ARG1, f);                \
    PYPA_AST_MEMBER_VISIT_IMPL_END

#define PYPA_AST_MEMBERS3(TYPE, ARG0, ARG1, ARG2)       \
    PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPE)      \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG0)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG1)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG2)     \
    PYPA_AST_MEMBER_DUMP_IMPL_END(TYPE)        \
    PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPE)             \
    do_apply(t, &Type::ARG0, f);                        \
    do_apply(t, &Type::ARG1, f);                        \
    do_apply(t, &Type::ARG2, f);                        \
    PYPA_AST_MEMBER_VISIT_IMPL_END
#define PYPA_AST_MEMBERS4(TYPE, ARG0, ARG1, ARG2, ARG3)     \
    PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPE)      \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG0)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG1)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG2)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG3)     \
    PYPA_AST_MEMBER_DUMP_IMPL_END(TYPE)        \
    PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPE)                 \
    do_apply(t, &Type::ARG0, f);                            \
    do_apply(t, &Type::ARG1, f);                            \
    do_apply(t, &Type::ARG2, f);                            \
    do_apply(t, &Type::ARG3, f);                            \
    PYPA_AST_MEMBER_VISIT_IMPL_END

#define PYPA_AST_MEMBERS5(TYPE, ARG0, ARG1, ARG2, ARG3, ARG4)       \
    PYPA_AST_MEMBER_DUMP_IMPL_BEGIN(TYPE)      \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG0)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG1)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG2)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG3)     \
    PYPA_AST_MEMBER_DUMP_MEMBER_ITEM(ARG4)     \
    PYPA_AST_MEMBER_DUMP_IMPL_END(TYPE)        \
    PYPA_AST_MEMBER_VISIT_IMPL_BEGIN(TYPE)                         \
    do_apply(t, &Type::ARG0, f);                                    \
    do_apply(t, &Type::ARG1, f);                                    \
    do_apply(t, &Type::ARG2, f);                                    \
    do_apply(t, &Type::ARG3, f);                                    \
    do_apply(t, &Type::ARG4, f);                                    \
    PYPA_AST_MEMBER_VISIT_IMPL_END

#endif //GUARD_PYPA_AST_MACROS_HH_INCLUDED
<|endoftext|>


<commit_before>#include <Eigen/Geometry>
#include <ros/ros.h>
#include <tf/transform_datatypes.h>
#include <tf/transform_broadcaster.h>
#include <tf/transform_listener.h>
#include <tf/transform_broadcaster.h>
#include <tf_conversions/tf_eigen.h>
#include <geometry_msgs/QuaternionStamped.h>
#include <nav_msgs/Odometry.h>
#include <sensor_msgs/Imu.h>
#include <robot_kf/robot_kf.h>

// TODO: Deal with TF frames.

static double const big = 99999.0;

static boost::shared_ptr<tf::TransformListener> sub_tf;
static boost::shared_ptr<tf::TransformBroadcaster> pub_tf;
static ros::Subscriber sub_compass;
static ros::Subscriber sub_encoders;
static ros::Subscriber sub_gps;
static ros::Publisher  pub_fused;
static robot_kf::KalmanFilter kf;

static bool watch_compass, watch_encoders, watch_gps;
static std::string global_frame_id, odom_frame_id, base_frame_id;

static void publish(ros::Time stamp)
{
    Eigen::Vector3d const state = kf.getState();
    Eigen::Matrix3d const cov = kf.getCovariance();

    // Publish the odometry message.
    nav_msgs::Odometry msg;
    msg.header.stamp = msg.header.stamp;
    msg.header.frame_id = msg.header.frame_id;
    msg.child_frame_id = base_frame_id;
    msg.pose.pose.position.x = state[0];
    msg.pose.pose.position.y = state[1];
    tf::quaternionTFToMsg(tf::createQuaternionFromYaw(state[2]),
                          msg.pose.pose.orientation);

    Eigen::Map<Eigen::Matrix<double, 6, 6> > cov_raw(&msg.pose.covariance[0]);
    cov_raw << cov(0,0), cov(0,1), 0.0, 0.0, 0.0, cov(0,2),
               cov(1,0), cov(1,1), 0.0, 0.0, 0.0, cov(1,2),
               0.0,      0.0,      big, 0.0, 0.0, 0.0,
               0.0,      0.0,      0.0, big, 0.0, 0.0,
               0.0,      0.0,      0.0, 0.0, big, 0.0,
               cov(2,0), cov(2,1), 0.0, 0.0, 0.0, cov(2,2);
    msg.twist.covariance[0] = -1;
    pub_fused.publish(msg);

    // Transformation.
    // TODO: Follow the localization REP and publish the /map to /odom
    // transform instead of the /map to /base_link transform.
#if 0
    geometry_msgs::TransformStamped transform;
    transform.header.stamp = stamp;
    transform.header.frame_id = frame_id;
    transform.child_frame_id = child_frame_id;
    transform.transform.translation.x = state[0];
    transform.transform.translation.y = state[1];
    tf::quaternionTFToMsg(tf::createQuaternionFromYaw(state[2]),
                          transform.transform.rotation);
    pub_tf->sendTransform(transform);
#endif
}

static void updateCompass(sensor_msgs::Imu const &msg)
{
    ros::Time const stamp = msg.header.stamp;
    std::string const frame_id = msg.header.frame_id;

    // Transform the orientation into the base coordinate frame.
    geometry_msgs::QuaternionStamped stamped_in, stamped_out;
    stamped_in.header.frame_id = frame_id;
    stamped_in.header.stamp    = stamp;
    stamped_in.quaternion = msg.orientation;
    sub_tf->transformQuaternion(base_frame_id, stamped_in, stamped_out);

    // Rotate the covariance matrix according to the transformation.
    tf::StampedTransform transform;
    Eigen::Affine3d eigen_transform;
    sub_tf->lookupTransform(base_frame_id, frame_id, stamp, transform);
    tf::TransformTFToEigen(transform, eigen_transform);

    Eigen::Matrix3d const rotation = eigen_transform.rotation();
    Eigen::Map<Eigen::Matrix3d const> cov_raw(&msg.orientation_covariance.front());
    Eigen::Matrix3d const cov = rotation.transpose() * cov_raw * rotation;

    kf.update_compass(tf::getYaw(stamped_out.quaternion), cov(2, 2));
    if (watch_compass) publish(stamp);
}

static void updateEncoders(nav_msgs::Odometry const &msg)
{
    //

    Eigen::Vector3d const z = (Eigen::Vector3d() <<
        msg.pose.pose.position.x,
        msg.pose.pose.position.y,
        tf::getYaw(msg.pose.pose.orientation)
    ).finished();

    Eigen::Map<Eigen::Matrix<double, 6, 6> const> cov_raw(
        &msg.pose.covariance.front()
    );

    Eigen::Matrix3d cov_z = Eigen::Matrix3d::Zero();
    cov_z.topLeftCorner<2, 2>() = cov_raw.topLeftCorner<2, 2>();
    cov_z(2, 2) = cov_raw(5, 5);

    kf.update_encoders(z, cov_z);
    if (watch_encoders) publish(msg.header.stamp);
}

static void updateGps(nav_msgs::Odometry const &msg)
{
    Eigen::Vector2d const z = (Eigen::Vector2d() <<
        msg.pose.pose.position.x,
        msg.pose.pose.position.y
    ).finished();

    Eigen::Map<Eigen::Matrix<double, 6, 6> const> cov_raw(
        &msg.pose.covariance.front()
    );
    Eigen::Matrix2d const cov_z = cov_raw.topLeftCorner<2, 2>();

    kf.update_gps(z, cov_z);
    if (watch_gps) publish(msg.header.stamp);
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "robot_kf_node");

    ros::NodeHandle nh, nh_node("~");
    nh_node.param<bool>("watch_compass",  watch_compass,  true);
    nh_node.param<bool>("watch_encoders", watch_encoders, true);
    nh_node.param<bool>("watch_gps",      watch_gps,      true);
    nh_node.param<std::string>("global_frame_id", global_frame_id, "/map");
    nh_node.param<std::string>("odom_frame_id", odom_frame_id, "/odom");
    nh_node.param<std::string>("base_frame_id", base_frame_id, "/base_footprint");

    sub_tf = boost::make_shared<tf::TransformListener>();
    pub_tf = boost::make_shared<tf::TransformBroadcaster>();
    sub_compass  = nh.subscribe("compass", 1, &updateCompass);
    sub_encoders = nh.subscribe("odom", 1, &updateEncoders);
    sub_gps      = nh.subscribe("gps", 1, &updateGps);
    pub_fused    = nh.advertise<nav_msgs::Odometry>("odom_fused", 100);

    ros::spin();
    return 0;
}
<commit_msg>warn if the odometry frames are wrong<commit_after>#include <Eigen/Geometry>
#include <ros/ros.h>
#include <tf/transform_datatypes.h>
#include <tf/transform_broadcaster.h>
#include <tf/transform_listener.h>
#include <tf/transform_broadcaster.h>
#include <tf_conversions/tf_eigen.h>
#include <geometry_msgs/QuaternionStamped.h>
#include <nav_msgs/Odometry.h>
#include <sensor_msgs/Imu.h>
#include <robot_kf/robot_kf.h>

// TODO: Deal with TF frames.

static double const big = 99999.0;

static boost::shared_ptr<tf::TransformListener> sub_tf;
static boost::shared_ptr<tf::TransformBroadcaster> pub_tf;
static ros::Subscriber sub_compass;
static ros::Subscriber sub_encoders;
static ros::Subscriber sub_gps;
static ros::Publisher  pub_fused;
static robot_kf::KalmanFilter kf;

static bool watch_compass, watch_encoders, watch_gps;
static std::string global_frame_id, odom_frame_id, base_frame_id;

static void publish(ros::Time stamp)
{
    Eigen::Vector3d const state = kf.getState();
    Eigen::Matrix3d const cov = kf.getCovariance();

    // Publish the odometry message.
    nav_msgs::Odometry msg;
    msg.header.stamp = msg.header.stamp;
    msg.header.frame_id = msg.header.frame_id;
    msg.child_frame_id = base_frame_id;
    msg.pose.pose.position.x = state[0];
    msg.pose.pose.position.y = state[1];
    tf::quaternionTFToMsg(tf::createQuaternionFromYaw(state[2]),
                          msg.pose.pose.orientation);

    Eigen::Map<Eigen::Matrix<double, 6, 6> > cov_raw(&msg.pose.covariance[0]);
    cov_raw << cov(0,0), cov(0,1), 0.0, 0.0, 0.0, cov(0,2),
               cov(1,0), cov(1,1), 0.0, 0.0, 0.0, cov(1,2),
               0.0,      0.0,      big, 0.0, 0.0, 0.0,
               0.0,      0.0,      0.0, big, 0.0, 0.0,
               0.0,      0.0,      0.0, 0.0, big, 0.0,
               cov(2,0), cov(2,1), 0.0, 0.0, 0.0, cov(2,2);
    msg.twist.covariance[0] = -1;
    pub_fused.publish(msg);

    // Transformation.
    // TODO: Follow the localization REP and publish the /map to /odom
    // transform instead of the /map to /base_link transform.
#if 0
    geometry_msgs::TransformStamped transform;
    transform.header.stamp = stamp;
    transform.header.frame_id = frame_id;
    transform.child_frame_id = child_frame_id;
    transform.transform.translation.x = state[0];
    transform.transform.translation.y = state[1];
    tf::quaternionTFToMsg(tf::createQuaternionFromYaw(state[2]),
                          transform.transform.rotation);
    pub_tf->sendTransform(transform);
#endif
}

static void updateCompass(sensor_msgs::Imu const &msg)
{
    ros::Time const stamp = msg.header.stamp;
    std::string const frame_id = msg.header.frame_id;

    // Transform the orientation into the base coordinate frame.
    geometry_msgs::QuaternionStamped stamped_in, stamped_out;
    stamped_in.header.frame_id = frame_id;
    stamped_in.header.stamp    = stamp;
    stamped_in.quaternion = msg.orientation;
    sub_tf->transformQuaternion(base_frame_id, stamped_in, stamped_out);

    // Rotate the covariance matrix according to the transformation.
    tf::StampedTransform transform;
    Eigen::Affine3d eigen_transform;
    sub_tf->lookupTransform(base_frame_id, frame_id, stamp, transform);
    tf::TransformTFToEigen(transform, eigen_transform);

    Eigen::Matrix3d const rotation = eigen_transform.rotation();
    Eigen::Map<Eigen::Matrix3d const> cov_raw(&msg.orientation_covariance.front());
    Eigen::Matrix3d const cov = rotation.transpose() * cov_raw * rotation;

    kf.update_compass(tf::getYaw(stamped_out.quaternion), cov(2, 2));
    if (watch_compass) publish(stamp);
}

static void updateEncoders(nav_msgs::Odometry const &msg)
{
    if (msg.header.frame_id != odom_frame_id
     || msg.child_frame_id != base_frame_id) {
        ROS_ERROR_THROTTLE(10,
            "Odometry message must have a frame_id '%s' and child_frame_id '%s'",
            odom_frame_id.c_str(), base_frame_id.c_str()
        );
        return;
    }

    Eigen::Vector3d const z = (Eigen::Vector3d() <<
        msg.pose.pose.position.x,
        msg.pose.pose.position.y,
        tf::getYaw(msg.pose.pose.orientation)
    ).finished();
    Eigen::Map<Eigen::Matrix<double, 6, 6> const> cov_raw(
        &msg.pose.covariance.front()
    );

    Eigen::Matrix3d cov_z = Eigen::Matrix3d::Zero();
    cov_z.topLeftCorner<2, 2>() = cov_raw.topLeftCorner<2, 2>();
    cov_z(2, 2) = cov_raw(5, 5);

    kf.update_encoders(z, cov_z);
    if (watch_encoders) publish(msg.header.stamp);
}

static void updateGps(nav_msgs::Odometry const &msg)
{
    Eigen::Vector2d const z = (Eigen::Vector2d() <<
        msg.pose.pose.position.x,
        msg.pose.pose.position.y
    ).finished();

    Eigen::Map<Eigen::Matrix<double, 6, 6> const> cov_raw(
        &msg.pose.covariance.front()
    );
    Eigen::Matrix2d const cov_z = cov_raw.topLeftCorner<2, 2>();

    kf.update_gps(z, cov_z);
    if (watch_gps) publish(msg.header.stamp);
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "robot_kf_node");

    ros::NodeHandle nh, nh_node("~");
    nh_node.param<bool>("watch_compass",  watch_compass,  true);
    nh_node.param<bool>("watch_encoders", watch_encoders, true);
    nh_node.param<bool>("watch_gps",      watch_gps,      true);
    nh_node.param<std::string>("global_frame_id", global_frame_id, "/map");
    nh_node.param<std::string>("odom_frame_id", odom_frame_id, "/odom");
    nh_node.param<std::string>("base_frame_id", base_frame_id, "/base_footprint");

    sub_tf = boost::make_shared<tf::TransformListener>();
    pub_tf = boost::make_shared<tf::TransformBroadcaster>();
    sub_compass  = nh.subscribe("compass", 1, &updateCompass);
    sub_encoders = nh.subscribe("odom", 1, &updateEncoders);
    sub_gps      = nh.subscribe("gps", 1, &updateGps);
    pub_fused    = nh.advertise<nav_msgs::Odometry>("odom_fused", 100);

    ros::spin();
    return 0;
}
<|endoftext|>


<commit_before>#include "DebugHandler.h"

#include <QByteArray>
#include <QCoreApplication>
#include <QDebug>

#include <syslog.h>

namespace FastCgiQt
{
	DebugHandler::DebugHandler()
		:
			m_name(QCoreApplication::applicationName().toUtf8())
	{
		::openlog(m_name.constData(), /*LOG_PERROR |*/ LOG_PID, LOG_USER);
		qInstallMsgHandler(syslogHandler);
	}

	void DebugHandler::syslogHandler(QtMsgType type, const char* message)
	{
		switch(type)
		{
			case QtDebugMsg:
				::syslog(LOG_DEBUG, "DEBUG: %s", message);
				break;
			case QtWarningMsg:
				::syslog(LOG_WARNING, "WARNING: %s", message);
				break;
			case QtCriticalMsg:
				::syslog(LOG_CRIT, "CRITICAL: %s", message);
				break;
			case QtFatalMsg:
				::syslog(LOG_EMERG, "FATAL: %s", message);
				abort();
			default:
				::syslog(LOG_EMERG, "UNKNOWN: %s", message);
				abort();
		}
	}

	DebugHandler::~DebugHandler()
	{
		::closelog();
		qInstallMsgHandler(m_oldHandler);
	}
}
<commit_msg>output debug messages to stderr again<commit_after>#include "DebugHandler.h"

#include <QByteArray>
#include <QCoreApplication>
#include <QDebug>

#include <syslog.h>

namespace FastCgiQt
{
	DebugHandler::DebugHandler()
		:
			m_name(QCoreApplication::applicationName().toUtf8())
	{
		::openlog(m_name.constData(), LOG_PERROR | LOG_PID, LOG_USER);
		qInstallMsgHandler(syslogHandler);
	}

	void DebugHandler::syslogHandler(QtMsgType type, const char* message)
	{
		switch(type)
		{
			case QtDebugMsg:
				::syslog(LOG_DEBUG, "DEBUG: %s", message);
				break;
			case QtWarningMsg:
				::syslog(LOG_WARNING, "WARNING: %s", message);
				break;
			case QtCriticalMsg:
				::syslog(LOG_CRIT, "CRITICAL: %s", message);
				break;
			case QtFatalMsg:
				::syslog(LOG_EMERG, "FATAL: %s", message);
				abort();
			default:
				::syslog(LOG_EMERG, "UNKNOWN: %s", message);
				abort();
		}
	}

	DebugHandler::~DebugHandler()
	{
		::closelog();
		qInstallMsgHandler(m_oldHandler);
	}
}
<|endoftext|>


<commit_before>//===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCLabel.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
using namespace llvm;

typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
typedef StringMap<const MCSectionELF*> ELFUniqueMapTy;
typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;

MCContext::MCContext(const MCAsmInfo &mai) : MAI(mai), NextUniqueID(0) {
  MachOUniquingMap = 0;
  ELFUniquingMap = 0;
  COFFUniquingMap = 0;
}

MCContext::~MCContext() {
  // NOTE: The symbols are all allocated out of a bump pointer allocator,
  // we don't need to free them here.

  // If we have the MachO uniquing map, free it.
  delete (MachOUniqueMapTy*)MachOUniquingMap;
  delete (ELFUniqueMapTy*)ELFUniquingMap;
  delete (COFFUniqueMapTy*)COFFUniquingMap;
}

//===----------------------------------------------------------------------===//
// Symbol Manipulation
//===----------------------------------------------------------------------===//

MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
  assert(!Name.empty() && "Normal symbols cannot be unnamed!");

  // Determine whether this is an assembler temporary or normal label.
  bool isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix());

  // Do the lookup and get the entire StringMapEntry.  We want access to the
  // key if we are creating the entry.
  StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name);
  if (Entry.getValue()) return Entry.getValue();

  // Ok, the entry doesn't already exist.  Have the MCSymbol object itself refer
  // to the copy of the string that is embedded in the StringMapEntry.
  MCSymbol *Result = new (*this) MCSymbol(Entry.getKey(), isTemporary);
  Entry.setValue(Result);
  return Result;
}

MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
  SmallString<128> NameSV;
  Name.toVector(NameSV);
  return GetOrCreateSymbol(NameSV.str());
}

MCSymbol *MCContext::CreateTempSymbol() {
  return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
                           "tmp" + Twine(NextUniqueID++));
}

unsigned MCContext::NextInstance(int64_t LocalLabelVal) {
  unsigned Instance;
  MCLabel *Label;
  Label = Instances[LocalLabelVal];
  if (Label) {
    Instance = Label->incInstance();
  }
  else {
    Instance = 1;
    Label = new MCLabel(Instance);
    Instances[LocalLabelVal] = Label;
  }
  return Instance;
}

unsigned MCContext::GetInstance(int64_t LocalLabelVal) {
  int Instance;
  MCLabel *Label;
  Label = Instances[LocalLabelVal];
  if (Label) {
    Instance = Label->getInstance();
  }
  else {
    Instance = 0;
    Label = new MCLabel(Instance);
    Instances[LocalLabelVal] = Label;
  }
  return Instance;
}

MCSymbol *MCContext::CreateDirectionalLocalSymbol(int64_t LocalLabelVal) {
  return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
                           Twine(LocalLabelVal) +
                           "\2" +
			   Twine(NextInstance(LocalLabelVal)));
}
MCSymbol *MCContext::GetDirectionalLocalSymbol(int64_t LocalLabelVal,
                                               int bORf) {
  return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
                           Twine(LocalLabelVal) +
                           "\2" +
			   Twine(GetInstance(LocalLabelVal) + bORf));
}

MCSymbol *MCContext::LookupSymbol(StringRef Name) const {
  return Symbols.lookup(Name);
}

//===----------------------------------------------------------------------===//
// Section Management
//===----------------------------------------------------------------------===//

const MCSectionMachO *MCContext::
getMachOSection(StringRef Segment, StringRef Section,
                unsigned TypeAndAttributes,
                unsigned Reserved2, SectionKind Kind) {

  // We unique sections by their segment/section pair.  The returned section
  // may not have the same flags as the requested section, if so this should be
  // diagnosed by the client as an error.

  // Create the map if it doesn't already exist.
  if (MachOUniquingMap == 0)
    MachOUniquingMap = new MachOUniqueMapTy();
  MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)MachOUniquingMap;

  // Form the name to look up.
  SmallString<64> Name;
  Name += Segment;
  Name.push_back(',');
  Name += Section;

  // Do the lookup, if we have a hit, return it.
  const MCSectionMachO *&Entry = Map[Name.str()];
  if (Entry) return Entry;

  // Otherwise, return a new section.
  return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes,
                                            Reserved2, Kind);
}

const MCSection *MCContext::
getELFSection(StringRef Section, unsigned Type, unsigned Flags,
              SectionKind Kind, bool IsExplicit) {
  if (ELFUniquingMap == 0)
    ELFUniquingMap = new ELFUniqueMapTy();
  ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)ELFUniquingMap;

  // Do the lookup, if we have a hit, return it.
  StringMapEntry<const MCSectionELF*> &Entry = Map.GetOrCreateValue(Section);
  if (Entry.getValue()) return Entry.getValue();

  MCSectionELF *Result = new (*this) MCSectionELF(Entry.getKey(), Type, Flags,
                                                  Kind, IsExplicit);
  Entry.setValue(Result);
  return Result;
}

const MCSection *MCContext::getCOFFSection(StringRef Section,
                                           unsigned Characteristics,
                                           int Selection,
                                           SectionKind Kind) {
  if (COFFUniquingMap == 0)
    COFFUniquingMap = new COFFUniqueMapTy();
  COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;

  // Do the lookup, if we have a hit, return it.
  StringMapEntry<const MCSectionCOFF*> &Entry = Map.GetOrCreateValue(Section);
  if (Entry.getValue()) return Entry.getValue();

  MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(),
                                                    Characteristics,
                                                    Selection, Kind);

  Entry.setValue(Result);
  return Result;
}
<commit_msg>Simplify MCContext::(Next|Get)Instance<commit_after>//===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCLabel.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
using namespace llvm;

typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
typedef StringMap<const MCSectionELF*> ELFUniqueMapTy;
typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;

MCContext::MCContext(const MCAsmInfo &mai) : MAI(mai), NextUniqueID(0) {
  MachOUniquingMap = 0;
  ELFUniquingMap = 0;
  COFFUniquingMap = 0;
}

MCContext::~MCContext() {
  // NOTE: The symbols are all allocated out of a bump pointer allocator,
  // we don't need to free them here.

  // If we have the MachO uniquing map, free it.
  delete (MachOUniqueMapTy*)MachOUniquingMap;
  delete (ELFUniqueMapTy*)ELFUniquingMap;
  delete (COFFUniqueMapTy*)COFFUniquingMap;
}

//===----------------------------------------------------------------------===//
// Symbol Manipulation
//===----------------------------------------------------------------------===//

MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
  assert(!Name.empty() && "Normal symbols cannot be unnamed!");

  // Determine whether this is an assembler temporary or normal label.
  bool isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix());

  // Do the lookup and get the entire StringMapEntry.  We want access to the
  // key if we are creating the entry.
  StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name);
  if (Entry.getValue()) return Entry.getValue();

  // Ok, the entry doesn't already exist.  Have the MCSymbol object itself refer
  // to the copy of the string that is embedded in the StringMapEntry.
  MCSymbol *Result = new (*this) MCSymbol(Entry.getKey(), isTemporary);
  Entry.setValue(Result);
  return Result;
}

MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
  SmallString<128> NameSV;
  Name.toVector(NameSV);
  return GetOrCreateSymbol(NameSV.str());
}

MCSymbol *MCContext::CreateTempSymbol() {
  return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
                           "tmp" + Twine(NextUniqueID++));
}

unsigned MCContext::NextInstance(int64_t LocalLabelVal) {
  MCLabel *&Label = Instances[LocalLabelVal];
  if (!Label)
    Label = new (*this) MCLabel(0);
  return Label->incInstance();
}

unsigned MCContext::GetInstance(int64_t LocalLabelVal) {
  MCLabel *&Label = Instances[LocalLabelVal];
  if (!Label)
    Label = new (*this) MCLabel(0);
  return Label->getInstance();
}

MCSymbol *MCContext::CreateDirectionalLocalSymbol(int64_t LocalLabelVal) {
  return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
                           Twine(LocalLabelVal) +
                           "\2" +
			   Twine(NextInstance(LocalLabelVal)));
}
MCSymbol *MCContext::GetDirectionalLocalSymbol(int64_t LocalLabelVal,
                                               int bORf) {
  return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
                           Twine(LocalLabelVal) +
                           "\2" +
			   Twine(GetInstance(LocalLabelVal) + bORf));
}

MCSymbol *MCContext::LookupSymbol(StringRef Name) const {
  return Symbols.lookup(Name);
}

//===----------------------------------------------------------------------===//
// Section Management
//===----------------------------------------------------------------------===//

const MCSectionMachO *MCContext::
getMachOSection(StringRef Segment, StringRef Section,
                unsigned TypeAndAttributes,
                unsigned Reserved2, SectionKind Kind) {

  // We unique sections by their segment/section pair.  The returned section
  // may not have the same flags as the requested section, if so this should be
  // diagnosed by the client as an error.

  // Create the map if it doesn't already exist.
  if (MachOUniquingMap == 0)
    MachOUniquingMap = new MachOUniqueMapTy();
  MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)MachOUniquingMap;

  // Form the name to look up.
  SmallString<64> Name;
  Name += Segment;
  Name.push_back(',');
  Name += Section;

  // Do the lookup, if we have a hit, return it.
  const MCSectionMachO *&Entry = Map[Name.str()];
  if (Entry) return Entry;

  // Otherwise, return a new section.
  return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes,
                                            Reserved2, Kind);
}

const MCSection *MCContext::
getELFSection(StringRef Section, unsigned Type, unsigned Flags,
              SectionKind Kind, bool IsExplicit) {
  if (ELFUniquingMap == 0)
    ELFUniquingMap = new ELFUniqueMapTy();
  ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)ELFUniquingMap;

  // Do the lookup, if we have a hit, return it.
  StringMapEntry<const MCSectionELF*> &Entry = Map.GetOrCreateValue(Section);
  if (Entry.getValue()) return Entry.getValue();

  MCSectionELF *Result = new (*this) MCSectionELF(Entry.getKey(), Type, Flags,
                                                  Kind, IsExplicit);
  Entry.setValue(Result);
  return Result;
}

const MCSection *MCContext::getCOFFSection(StringRef Section,
                                           unsigned Characteristics,
                                           int Selection,
                                           SectionKind Kind) {
  if (COFFUniquingMap == 0)
    COFFUniquingMap = new COFFUniqueMapTy();
  COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;

  // Do the lookup, if we have a hit, return it.
  StringMapEntry<const MCSectionCOFF*> &Entry = Map.GetOrCreateValue(Section);
  if (Entry.getValue()) return Entry.getValue();

  MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(),
                                                    Characteristics,
                                                    Selection, Kind);

  Entry.setValue(Result);
  return Result;
}
<|endoftext|>