<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <MScalableImage>
#include <MImageWidget>
#include <MLabel>
#include <MWidgetController>
#include <MWidgetView>
#include <MSeparator>

#include <QGraphicsGridLayout>
#include <QGraphicsLinearLayout>
#include <QGraphicsSceneEvent>

#include "mbubbleitem.h"
#include "mbubbleitemview.h"
#include "mbubbleitemview_p.h"
#include "mbubbleitembackground_p.h"

MBubbleItemViewPrivate::MBubbleItemViewPrivate()
        : avatar(0),
        speechBubble(0),
        timeStampLabel(0),
        messageComposition(0),
        separator(0),
        currentCentralWidget(0)
{
    layout = new QGraphicsGridLayout;
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);

    informationWidgetsLayout = new QGraphicsLinearLayout(Qt::Horizontal);
    informationWidgetsLayout->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
    informationWidgetsLayout->setContentsMargins(0, 0, 0, 0);
    informationWidgetsLayout->setSpacing(0);

    informationWidgetsSpacer = new QGraphicsWidget;
    informationWidgetsSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

    innerLayout = new QGraphicsLinearLayout(Qt::Vertical);
    innerLayout->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
    innerLayout->setContentsMargins(0, 0, 0, 0);
    innerLayout->setSpacing(0);

    timeStampLabel = new MLabel();
    timeStampLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

    messageComposition = new MLabel();
    messageComposition->setWordWrap(true);
    messageComposition->setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
    messageComposition->setAlignment(Qt::AlignLeft);
}

MBubbleItemViewPrivate::~MBubbleItemViewPrivate()
{
    clearLayout();
}

void MBubbleItemViewPrivate::initLayout()
{
    clearLayout();

    replaceAvatar();

    if (controller->messageType() == MBubbleItem::Incoming) {
        if (controller->avatar()) {
            layout->addItem(controller->avatar(), 0, 0);
            layout->addItem(speechBubble, 0, 1);
        } else {
            layout->addItem(speechBubble, 0, 0);
        }
    } else if(controller->messageType() == MBubbleItem::Outgoing) {
        layout->addItem(speechBubble, 0, 0);
        if (controller->avatar())
            layout->addItem(controller->avatar(), 0, 1);
    }

    updateInformationWidgetsLayout();

    innerLayout->addItem(messageComposition);
    innerLayout->addItem(informationWidgetsLayout);

    setupCentralWidget();

    controller->connect(speechBubble, SIGNAL(clicked()), controller, SIGNAL(bubbleClicked()));
}

void MBubbleItemViewPrivate::clearLayout()
{
    while (layout->count())
        layout->removeAt(0);
    while (innerLayout->count())
        innerLayout->removeAt(0);
}

void MBubbleItemViewPrivate::replaceAvatar()
{
    Q_Q(MBubbleItemView);

    if (avatar) {
        for (int i = 0; i < layout->count(); i ++) {
            if (layout->itemAt(i) == avatar)
                layout->removeAt(i);
        }
        avatar = 0;
    }

    if (controller->avatar()) {
        if (controller->avatar()->objectName().isEmpty())
            controller->avatar()->setObjectName(q->style()->avatarObjectName());
        if (controller->messageType() == MBubbleItem::Incoming) {
            layout->addItem(controller->avatar(), 0, 0);
            layout->addItem(speechBubble, 0, 1);
        }
        else
            layout->addItem(controller->avatar(), 0, 1);
        avatar = controller->avatar();
    }
}

void MBubbleItemViewPrivate::setupCentralWidget()
{
    Q_Q(MBubbleItemView);

    if (q->model()->centralWidget() &&
        q->model()->centralWidget() != currentCentralWidget) {
        separator = new MSeparator;
        separator->setOrientation(Qt::Horizontal);
        innerLayout->addItem(separator);

        currentCentralWidget = q->model()->centralWidget();
        innerLayout->addItem(currentCentralWidget);
    } else {
        if (separator) {
            innerLayout->removeItem(separator);
            delete separator;
            separator = 0;
        }

        if (currentCentralWidget) {
            innerLayout->removeItem(currentCentralWidget);
            currentCentralWidget = 0;
        }
    }
}

void MBubbleItemViewPrivate::clearInformationWidgetsLayout()
{
    for (int i = 0; i < informationWidgetsLayout->count(); i++)
        informationWidgetsLayout->removeAt(0);
}

void MBubbleItemViewPrivate::updateInformationWidgetsLayout()
{
    Q_Q(MBubbleItemView);

    clearInformationWidgetsLayout();

    foreach (QGraphicsWidget *widget, q->model()->informationWidgets()) {
        informationWidgetsLayout->addItem(widget);
        informationWidgetsLayout->setAlignment(widget, Qt::AlignVCenter | Qt::AlignRight);
    }

    informationWidgetsLayout->addItem(informationWidgetsSpacer);
    informationWidgetsLayout->addItem(timeStampLabel);
}

void MBubbleItemViewPrivate::applyStyle()
{
    refreshStyleMode();
}

void MBubbleItemView::setGeometry(const QRectF &rect)
{
    MWidgetView::setGeometry(rect);

    Q_D(MBubbleItemView);
    d->updateMessageComposition();
    d->layout->invalidate();
    d->informationWidgetsLayout->invalidate();
    d->innerLayout->invalidate();
}

void MBubbleItemViewPrivate::refreshStyleMode()
{
    Q_Q(MBubbleItemView);
    if (controller->messageType() == MBubbleItem::Incoming)
        q->style().setModeDefault();
    else
        q->style().setModeOutgoing();

    if (speechBubble)
        speechBubble->setObjectName(q->style()->bubbleObjectName());

    if (timeStampLabel) {
        timeStampLabel->setFont(q->style()->timestampFont());
        timeStampLabel->setColor(q->style()->timestampTextColor());
    }

    if (messageComposition) {
        messageComposition->setFont(q->style()->font());
        messageComposition->setColor(q->style()->textColor());
    }

    controller->setContentsMargins(q->style()->marginLeft(),
                                   q->style()->marginTop(),
                                   q->style()->marginRight(),
                                   q->style()->marginBottom());
}

void MBubbleItemViewPrivate::updateMessageComposition()
{
    Q_Q(MBubbleItemView);

    QString senderName = q->model()->senderName();
    QFont boldFontForSendername( messageComposition->font() );
    boldFontForSendername.setBold(true);
    QFontMetrics fontMetrics(boldFontForSendername);

    if (fontMetrics.width(senderName) > messageComposition->size().width())
        senderName = fontMetrics.elidedText(senderName, Qt::ElideRight,
                                            messageComposition->size().width()
                                            - fontMetrics.size( Qt::TextSingleLine, "...:" ).width()
                                            );

    if (controller->messageType() == MBubbleItem::Incoming)
        messageComposition->setText( "" + senderName + ": " + q->model()->message());
    else if (controller->messageType() == MBubbleItem::Outgoing)
        messageComposition->setText(q->model()->message() + "");

}
MBubbleItemView::MBubbleItemView(MBubbleItem *controller)
    : MWidgetView(* new MBubbleItemViewPrivate, controller)
{
    Q_D(MBubbleItemView);
    d->controller = controller;
    controller->setLayout(d->layout);
}

MBubbleItemView::MBubbleItemView(MBubbleItemViewPrivate &dd, MBubbleItem *controller)
    : MWidgetView(dd, controller)
{
    Q_D(MBubbleItemView);
    d->controller = controller;
    controller->setLayout(d->layout);
}

MBubbleItemView::~MBubbleItemView()
{
}

void MBubbleItemView::applyStyle()
{
    MWidgetView::applyStyle();

    Q_D(MBubbleItemView);
    d->applyStyle();
}

void MBubbleItemView::updateData(const QList<const char *> &modifications)
{
    Q_D(MBubbleItemView);

    MWidgetView::updateData(modifications);

    const char *member;
    for (int i = 0; i < modifications.count(); i++) {
        member = modifications[i];
        if (member == MBubbleItemModel::Avatar) {
            d->replaceAvatar();
        } else if (member == MBubbleItemModel::SenderName) {
            d->updateMessageComposition();
        } else if (member == MBubbleItemModel::TimeStamp) {
            d->timeStampLabel->setText(model()->timeStamp());
        } else if (member == MBubbleItemModel::Message) {
            d->updateMessageComposition();
        } else if (member == MBubbleItemModel::CentralWidget) {
            d->setupCentralWidget();
        } else if (member == MBubbleItemModel::MessageType) {
            d->speechBubble->setMessageType(static_cast<MBubbleItem::MessageType>(model()->messageType()));
            d->updateMessageComposition();
            d->initLayout();
            d->refreshStyleMode();
        } else if (member == MBubbleItemModel::InformationWidgets) {
            d->updateInformationWidgetsLayout();
        }
    }
}

void MBubbleItemView::setupModel()
{
    Q_D(MBubbleItemView);

    MWidgetView::setupModel();

    d->timeStampLabel->setText(model()->timeStamp());

    connect(d->messageComposition, SIGNAL(linkActivated(QString)), d->controller, SIGNAL(linkActivated(QString)));

    d->speechBubble = new MBubbleItemBackground(d->controller);
    d->speechBubble->setMessageType(static_cast<MBubbleItem::MessageType>(model()->messageType()));
    d->speechBubble->setObjectName(style()->bubbleObjectName());
    d->speechBubble->setLayout(d->innerLayout);
    d->speechBubble->setMinimumSize(0,0); //The background must always be smaller than our current geometry

    d->initLayout();
    d->refreshStyleMode();
}

void MBubbleItemView::setSelected(bool selected)
{
    Q_UNUSED(selected);
}

void MBubbleItemView::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    Q_UNUSED(event);
}

void MBubbleItemView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    Q_UNUSED(event);
}

M_REGISTER_VIEW_NEW(MBubbleItemView, MBubbleItem)

<commit_msg>Changes: MBubbleItemView - we no longer need to invalidate geometry manually on setGeometry<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <MScalableImage>
#include <MImageWidget>
#include <MLabel>
#include <MWidgetController>
#include <MWidgetView>
#include <MSeparator>

#include <QGraphicsGridLayout>
#include <QGraphicsLinearLayout>
#include <QGraphicsSceneEvent>

#include "mbubbleitem.h"
#include "mbubbleitemview.h"
#include "mbubbleitemview_p.h"
#include "mbubbleitembackground_p.h"

MBubbleItemViewPrivate::MBubbleItemViewPrivate()
        : avatar(0),
        speechBubble(0),
        timeStampLabel(0),
        messageComposition(0),
        separator(0),
        currentCentralWidget(0)
{
    layout = new QGraphicsGridLayout;
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);

    informationWidgetsLayout = new QGraphicsLinearLayout(Qt::Horizontal);
    informationWidgetsLayout->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
    informationWidgetsLayout->setContentsMargins(0, 0, 0, 0);
    informationWidgetsLayout->setSpacing(0);

    informationWidgetsSpacer = new QGraphicsWidget;
    informationWidgetsSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

    innerLayout = new QGraphicsLinearLayout(Qt::Vertical);
    innerLayout->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
    innerLayout->setContentsMargins(0, 0, 0, 0);
    innerLayout->setSpacing(0);

    timeStampLabel = new MLabel();
    timeStampLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

    messageComposition = new MLabel();
    messageComposition->setWordWrap(true);
    messageComposition->setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
    messageComposition->setAlignment(Qt::AlignLeft);
}

MBubbleItemViewPrivate::~MBubbleItemViewPrivate()
{
    clearLayout();
}

void MBubbleItemViewPrivate::initLayout()
{
    clearLayout();

    replaceAvatar();

    if (controller->messageType() == MBubbleItem::Incoming) {
        if (controller->avatar()) {
            layout->addItem(controller->avatar(), 0, 0);
            layout->addItem(speechBubble, 0, 1);
        } else {
            layout->addItem(speechBubble, 0, 0);
        }
    } else if(controller->messageType() == MBubbleItem::Outgoing) {
        layout->addItem(speechBubble, 0, 0);
        if (controller->avatar())
            layout->addItem(controller->avatar(), 0, 1);
    }

    updateInformationWidgetsLayout();

    innerLayout->addItem(messageComposition);
    innerLayout->addItem(informationWidgetsLayout);

    setupCentralWidget();

    controller->connect(speechBubble, SIGNAL(clicked()), controller, SIGNAL(bubbleClicked()));
}

void MBubbleItemViewPrivate::clearLayout()
{
    while (layout->count())
        layout->removeAt(0);
    while (innerLayout->count())
        innerLayout->removeAt(0);
}

void MBubbleItemViewPrivate::replaceAvatar()
{
    Q_Q(MBubbleItemView);

    if (avatar) {
        for (int i = 0; i < layout->count(); i ++) {
            if (layout->itemAt(i) == avatar)
                layout->removeAt(i);
        }
        avatar = 0;
    }

    if (controller->avatar()) {
        if (controller->avatar()->objectName().isEmpty())
            controller->avatar()->setObjectName(q->style()->avatarObjectName());
        if (controller->messageType() == MBubbleItem::Incoming) {
            layout->addItem(controller->avatar(), 0, 0);
            layout->addItem(speechBubble, 0, 1);
        }
        else
            layout->addItem(controller->avatar(), 0, 1);
        avatar = controller->avatar();
    }
}

void MBubbleItemViewPrivate::setupCentralWidget()
{
    Q_Q(MBubbleItemView);

    if (q->model()->centralWidget() &&
        q->model()->centralWidget() != currentCentralWidget) {
        separator = new MSeparator;
        separator->setOrientation(Qt::Horizontal);
        innerLayout->addItem(separator);

        currentCentralWidget = q->model()->centralWidget();
        innerLayout->addItem(currentCentralWidget);
    } else {
        if (separator) {
            innerLayout->removeItem(separator);
            delete separator;
            separator = 0;
        }

        if (currentCentralWidget) {
            innerLayout->removeItem(currentCentralWidget);
            currentCentralWidget = 0;
        }
    }
}

void MBubbleItemViewPrivate::clearInformationWidgetsLayout()
{
    for (int i = 0; i < informationWidgetsLayout->count(); i++)
        informationWidgetsLayout->removeAt(0);
}

void MBubbleItemViewPrivate::updateInformationWidgetsLayout()
{
    Q_Q(MBubbleItemView);

    clearInformationWidgetsLayout();

    foreach (QGraphicsWidget *widget, q->model()->informationWidgets()) {
        informationWidgetsLayout->addItem(widget);
        informationWidgetsLayout->setAlignment(widget, Qt::AlignVCenter | Qt::AlignRight);
    }

    informationWidgetsLayout->addItem(informationWidgetsSpacer);
    informationWidgetsLayout->addItem(timeStampLabel);
}

void MBubbleItemViewPrivate::applyStyle()
{
    refreshStyleMode();
}

void MBubbleItemView::setGeometry(const QRectF &rect)
{
    MWidgetView::setGeometry(rect);

    Q_D(MBubbleItemView);
    d->updateMessageComposition();
}

void MBubbleItemViewPrivate::refreshStyleMode()
{
    Q_Q(MBubbleItemView);
    if (controller->messageType() == MBubbleItem::Incoming)
        q->style().setModeDefault();
    else
        q->style().setModeOutgoing();

    if (speechBubble)
        speechBubble->setObjectName(q->style()->bubbleObjectName());

    if (timeStampLabel) {
        timeStampLabel->setFont(q->style()->timestampFont());
        timeStampLabel->setColor(q->style()->timestampTextColor());
    }

    if (messageComposition) {
        messageComposition->setFont(q->style()->font());
        messageComposition->setColor(q->style()->textColor());
    }

    controller->setContentsMargins(q->style()->marginLeft(),
                                   q->style()->marginTop(),
                                   q->style()->marginRight(),
                                   q->style()->marginBottom());
}

void MBubbleItemViewPrivate::updateMessageComposition()
{
    Q_Q(MBubbleItemView);

    QString senderName = q->model()->senderName();
    QFont boldFontForSendername( messageComposition->font() );
    boldFontForSendername.setBold(true);
    QFontMetrics fontMetrics(boldFontForSendername);

    if (fontMetrics.width(senderName) > messageComposition->size().width())
        senderName = fontMetrics.elidedText(senderName, Qt::ElideRight,
                                            messageComposition->size().width()
                                            - fontMetrics.size( Qt::TextSingleLine, "...:" ).width()
                                            );

    if (controller->messageType() == MBubbleItem::Incoming)
        messageComposition->setText( "" + senderName + ": " + q->model()->message());
    else if (controller->messageType() == MBubbleItem::Outgoing)
        messageComposition->setText(q->model()->message() + "");

}
MBubbleItemView::MBubbleItemView(MBubbleItem *controller)
    : MWidgetView(* new MBubbleItemViewPrivate, controller)
{
    Q_D(MBubbleItemView);
    d->controller = controller;
    controller->setLayout(d->layout);
}

MBubbleItemView::MBubbleItemView(MBubbleItemViewPrivate &dd, MBubbleItem *controller)
    : MWidgetView(dd, controller)
{
    Q_D(MBubbleItemView);
    d->controller = controller;
    controller->setLayout(d->layout);
}

MBubbleItemView::~MBubbleItemView()
{
}

void MBubbleItemView::applyStyle()
{
    MWidgetView::applyStyle();

    Q_D(MBubbleItemView);
    d->applyStyle();
}

void MBubbleItemView::updateData(const QList<const char *> &modifications)
{
    Q_D(MBubbleItemView);

    MWidgetView::updateData(modifications);

    const char *member;
    for (int i = 0; i < modifications.count(); i++) {
        member = modifications[i];
        if (member == MBubbleItemModel::Avatar) {
            d->replaceAvatar();
        } else if (member == MBubbleItemModel::SenderName) {
            d->updateMessageComposition();
        } else if (member == MBubbleItemModel::TimeStamp) {
            d->timeStampLabel->setText(model()->timeStamp());
        } else if (member == MBubbleItemModel::Message) {
            d->updateMessageComposition();
        } else if (member == MBubbleItemModel::CentralWidget) {
            d->setupCentralWidget();
        } else if (member == MBubbleItemModel::MessageType) {
            d->speechBubble->setMessageType(static_cast<MBubbleItem::MessageType>(model()->messageType()));
            d->updateMessageComposition();
            d->initLayout();
            d->refreshStyleMode();
        } else if (member == MBubbleItemModel::InformationWidgets) {
            d->updateInformationWidgetsLayout();
        }
    }
}

void MBubbleItemView::setupModel()
{
    Q_D(MBubbleItemView);

    MWidgetView::setupModel();

    d->timeStampLabel->setText(model()->timeStamp());

    connect(d->messageComposition, SIGNAL(linkActivated(QString)), d->controller, SIGNAL(linkActivated(QString)));

    d->speechBubble = new MBubbleItemBackground(d->controller);
    d->speechBubble->setMessageType(static_cast<MBubbleItem::MessageType>(model()->messageType()));
    d->speechBubble->setObjectName(style()->bubbleObjectName());
    d->speechBubble->setLayout(d->innerLayout);
    d->speechBubble->setMinimumSize(0,0); //The background must always be smaller than our current geometry

    d->initLayout();
    d->refreshStyleMode();
}

void MBubbleItemView::setSelected(bool selected)
{
    Q_UNUSED(selected);
}

void MBubbleItemView::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    Q_UNUSED(event);
}

void MBubbleItemView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    Q_UNUSED(event);
}

M_REGISTER_VIEW_NEW(MBubbleItemView, MBubbleItem)

<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include "../make_random_data/make_random_data.hpp"
#include "../sort/merge.hpp"
#include "../sort/quick.hpp"
#include "../sort/selection.hpp"
#include "../sort/insertion.hpp"
#include "../sort/bubble.hpp"

#define SORT    quick
#define SIZE    10

int main(void)
{
    int *data = make_random_data(SIZE);

    for(int i = 0; i < SIZE; ++i) printf("%d\n", data[i]);
    putchar('\n');

    SORT(data, SIZE);

    for(int i = 0; i < SIZE; ++i) printf("%d\n", data[i]);

    free_random_data(data);

    return 0;
}
<commit_msg>Remove main_for_testing.cpp<commit_after><|endoftext|>


<commit_before>//===-- Module.cpp - Implement the Module class ------------------*- C++ -*--=//
//
// This file implements the Module class for the VMCore library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
#include "llvm/InstrTypes.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "Support/STLExtras.h"
#include "SymbolTableListTraitsImpl.h"
#include <algorithm>
#include <map>

Function *ilist_traits<Function>::createNode() {
  return new Function(FunctionType::get(Type::VoidTy,std::vector<const Type*>(),
                                        false), false);
}
GlobalVariable *ilist_traits<GlobalVariable>::createNode() {
  return new GlobalVariable(Type::IntTy, false, false);
}

iplist<Function> &ilist_traits<Function>::getList(Module *M) {
  return M->getFunctionList();
}
iplist<GlobalVariable> &ilist_traits<GlobalVariable>::getList(Module *M) {
  return M->getGlobalList();
}

// Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file...
template SymbolTableListTraits<GlobalVariable, Module, Module>;
template SymbolTableListTraits<Function, Module, Module>;

// Define the GlobalValueRefMap as a struct that wraps a map so that we don't
// have Module.h depend on <map>
//
struct GlobalValueRefMap : public std::map<GlobalValue*, ConstantPointerRef*>{
};

Module::Module() {
  FunctionList.setItemParent(this);
  FunctionList.setParent(this);
  GlobalList.setItemParent(this);
  GlobalList.setParent(this);
  GVRefMap = 0;
  SymTab = 0;
}

Module::~Module() {
  dropAllReferences();
  GlobalList.clear();
  GlobalList.setParent(0);
  FunctionList.clear();
  FunctionList.setParent(0);
  delete SymTab;
}

SymbolTable *Module::getSymbolTableSure() {
  if (!SymTab) SymTab = new SymbolTable(0);
  return SymTab;
}

// hasSymbolTable() - Returns true if there is a symbol table allocated to
// this object AND if there is at least one name in it!
//
bool Module::hasSymbolTable() const {
  if (!SymTab) return false;

  for (SymbolTable::const_iterator I = SymTab->begin(), E = SymTab->end();
       I != E; ++I)
    if (I->second.begin() != I->second.end())
      return true;                                // Found nonempty type plane!

  return false;
}

// getOrInsertFunction - Look up the specified function in the module symbol
// table.  If it does not exist, add a prototype for the function and return
// it.  This is nice because it allows most passes to get away with not handling
// the symbol table directly for this common task.
//
Function *Module::getOrInsertFunction(const std::string &Name,
                                      const FunctionType *Ty) {
  SymbolTable *SymTab = getSymbolTableSure();

  // See if we have a definitions for the specified function already...
  if (Value *V = SymTab->lookup(PointerType::get(Ty), Name)) {
    return cast<Function>(V);      // Yup, got it
  } else {                         // Nope, add one
    Function *New = new Function(Ty, false, Name);
    FunctionList.push_back(New);
    return New;                    // Return the new prototype...
  }
}

// getFunction - Look up the specified function in the module symbol table.
// If it does not exist, return null.
//
Function *Module::getFunction(const std::string &Name, const FunctionType *Ty) {
  SymbolTable *SymTab = getSymbolTable();
  if (SymTab == 0) return 0;  // No symtab, no symbols...

  return cast_or_null<Function>(SymTab->lookup(PointerType::get(Ty), Name));
}

// addTypeName - Insert an entry in the symbol table mapping Str to Type.  If
// there is already an entry for this name, true is returned and the symbol
// table is not modified.
//
bool Module::addTypeName(const std::string &Name, const Type *Ty) {
  SymbolTable *ST = getSymbolTableSure();

  if (ST->lookup(Type::TypeTy, Name)) return true;  // Already in symtab...

  // Not in symbol table?  Set the name with the Symtab as an argument so the
  // type knows what to update...
  ((Value*)Ty)->setName(Name, ST);

  return false;
}

// getTypeName - If there is at least one entry in the symbol table for the
// specified type, return it.
//
std::string Module::getTypeName(const Type *Ty) {
  const SymbolTable *ST = getSymbolTable();
  if (ST == 0) return "";  // No symbol table, must not have an entry...
  if (ST->find(Type::TypeTy) == ST->end())
    return ""; // No names for types...

  SymbolTable::type_const_iterator TI = ST->type_begin(Type::TypeTy);
  SymbolTable::type_const_iterator TE = ST->type_end(Type::TypeTy);

  while (TI != TE && TI->second != (const Value*)Ty)
    ++TI;

  if (TI != TE)  // Must have found an entry!
    return TI->first;
  return "";     // Must not have found anything...
}

// dropAllReferences() - This function causes all the subinstructions to "let
// go" of all references that they are maintaining.  This allows one to
// 'delete' a whole class at a time, even though there may be circular
// references... first all references are dropped, and all use counts go to
// zero.  Then everything is delete'd for real.  Note that no operations are
// valid on an object that has "dropped all references", except operator
// delete.
//
void Module::dropAllReferences() {
  for(Module::iterator I = begin(), E = end(); I != E; ++I)
    I->dropAllReferences();

  for(Module::giterator I = gbegin(), E = gend(); I != E; ++I)
    I->dropAllReferences();

  // If there are any GlobalVariable references still out there, nuke them now.
  // Since all references are hereby dropped, nothing could possibly reference
  // them still.
  if (GVRefMap) {
    for (GlobalValueRefMap::iterator I = GVRefMap->begin(), E = GVRefMap->end();
	 I != E; ++I) {
      // Delete the ConstantPointerRef node...
      I->second->destroyConstant();
    }

    // Since the table is empty, we can now delete it...
    delete GVRefMap;
  }
}

// Accessor for the underlying GlobalValRefMap...
ConstantPointerRef *Module::getConstantPointerRef(GlobalValue *V){
  // Create ref map lazily on demand...
  if (GVRefMap == 0) GVRefMap = new GlobalValueRefMap();

  GlobalValueRefMap::iterator I = GVRefMap->find(V);
  if (I != GVRefMap->end()) return I->second;

  ConstantPointerRef *Ref = new ConstantPointerRef(V);
  GVRefMap->insert(std::make_pair(V, Ref));

  return Ref;
}

void Module::mutateConstantPointerRef(GlobalValue *OldGV, GlobalValue *NewGV) {
  GlobalValueRefMap::iterator I = GVRefMap->find(OldGV);
  assert(I != GVRefMap->end() &&
	 "mutateConstantPointerRef; OldGV not in table!");
  ConstantPointerRef *Ref = I->second;

  // Remove the old entry...
  GVRefMap->erase(I);

  // Insert the new entry...
  GVRefMap->insert(std::make_pair(NewGV, Ref));
}
<commit_msg>Changes to make GlobalValueRefMap not derive from std::map.<commit_after>//===-- Module.cpp - Implement the Module class ------------------*- C++ -*--=//
//
// This file implements the Module class for the VMCore library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
#include "llvm/InstrTypes.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "Support/STLExtras.h"
#include "SymbolTableListTraitsImpl.h"
#include <algorithm>
#include <map>

Function *ilist_traits<Function>::createNode() {
  return new Function(FunctionType::get(Type::VoidTy,std::vector<const Type*>(),
                                        false), false);
}
GlobalVariable *ilist_traits<GlobalVariable>::createNode() {
  return new GlobalVariable(Type::IntTy, false, false);
}

iplist<Function> &ilist_traits<Function>::getList(Module *M) {
  return M->getFunctionList();
}
iplist<GlobalVariable> &ilist_traits<GlobalVariable>::getList(Module *M) {
  return M->getGlobalList();
}

// Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file...
template SymbolTableListTraits<GlobalVariable, Module, Module>;
template SymbolTableListTraits<Function, Module, Module>;

// Define the GlobalValueRefMap as a struct that wraps a map so that we don't
// have Module.h depend on <map>
//
struct GlobalValueRefMap {
  typedef std::map<GlobalValue*, ConstantPointerRef*> MapTy;
  typedef MapTy::iterator iterator;
  std::map<GlobalValue*, ConstantPointerRef*> Map;
};

Module::Module() {
  FunctionList.setItemParent(this);
  FunctionList.setParent(this);
  GlobalList.setItemParent(this);
  GlobalList.setParent(this);
  GVRefMap = 0;
  SymTab = 0;
}

Module::~Module() {
  dropAllReferences();
  GlobalList.clear();
  GlobalList.setParent(0);
  FunctionList.clear();
  FunctionList.setParent(0);
  delete SymTab;
}

SymbolTable *Module::getSymbolTableSure() {
  if (!SymTab) SymTab = new SymbolTable(0);
  return SymTab;
}

// hasSymbolTable() - Returns true if there is a symbol table allocated to
// this object AND if there is at least one name in it!
//
bool Module::hasSymbolTable() const {
  if (!SymTab) return false;

  for (SymbolTable::const_iterator I = SymTab->begin(), E = SymTab->end();
       I != E; ++I)
    if (I->second.begin() != I->second.end())
      return true;                                // Found nonempty type plane!

  return false;
}

// getOrInsertFunction - Look up the specified function in the module symbol
// table.  If it does not exist, add a prototype for the function and return
// it.  This is nice because it allows most passes to get away with not handling
// the symbol table directly for this common task.
//
Function *Module::getOrInsertFunction(const std::string &Name,
                                      const FunctionType *Ty) {
  SymbolTable *SymTab = getSymbolTableSure();

  // See if we have a definitions for the specified function already...
  if (Value *V = SymTab->lookup(PointerType::get(Ty), Name)) {
    return cast<Function>(V);      // Yup, got it
  } else {                         // Nope, add one
    Function *New = new Function(Ty, false, Name);
    FunctionList.push_back(New);
    return New;                    // Return the new prototype...
  }
}

// getFunction - Look up the specified function in the module symbol table.
// If it does not exist, return null.
//
Function *Module::getFunction(const std::string &Name, const FunctionType *Ty) {
  SymbolTable *SymTab = getSymbolTable();
  if (SymTab == 0) return 0;  // No symtab, no symbols...

  return cast_or_null<Function>(SymTab->lookup(PointerType::get(Ty), Name));
}

// addTypeName - Insert an entry in the symbol table mapping Str to Type.  If
// there is already an entry for this name, true is returned and the symbol
// table is not modified.
//
bool Module::addTypeName(const std::string &Name, const Type *Ty) {
  SymbolTable *ST = getSymbolTableSure();

  if (ST->lookup(Type::TypeTy, Name)) return true;  // Already in symtab...

  // Not in symbol table?  Set the name with the Symtab as an argument so the
  // type knows what to update...
  ((Value*)Ty)->setName(Name, ST);

  return false;
}

// getTypeName - If there is at least one entry in the symbol table for the
// specified type, return it.
//
std::string Module::getTypeName(const Type *Ty) {
  const SymbolTable *ST = getSymbolTable();
  if (ST == 0) return "";  // No symbol table, must not have an entry...
  if (ST->find(Type::TypeTy) == ST->end())
    return ""; // No names for types...

  SymbolTable::type_const_iterator TI = ST->type_begin(Type::TypeTy);
  SymbolTable::type_const_iterator TE = ST->type_end(Type::TypeTy);

  while (TI != TE && TI->second != (const Value*)Ty)
    ++TI;

  if (TI != TE)  // Must have found an entry!
    return TI->first;
  return "";     // Must not have found anything...
}

// dropAllReferences() - This function causes all the subinstructions to "let
// go" of all references that they are maintaining.  This allows one to
// 'delete' a whole class at a time, even though there may be circular
// references... first all references are dropped, and all use counts go to
// zero.  Then everything is delete'd for real.  Note that no operations are
// valid on an object that has "dropped all references", except operator
// delete.
//
void Module::dropAllReferences() {
  for(Module::iterator I = begin(), E = end(); I != E; ++I)
    I->dropAllReferences();

  for(Module::giterator I = gbegin(), E = gend(); I != E; ++I)
    I->dropAllReferences();

  // If there are any GlobalVariable references still out there, nuke them now.
  // Since all references are hereby dropped, nothing could possibly reference
  // them still.
  if (GVRefMap) {
    for (GlobalValueRefMap::iterator I = GVRefMap->Map.begin(),
           E = GVRefMap->Map.end(); I != E; ++I) {
      // Delete the ConstantPointerRef node...
      I->second->destroyConstant();
    }

    // Since the table is empty, we can now delete it...
    delete GVRefMap;
  }
}

// Accessor for the underlying GlobalValRefMap...
ConstantPointerRef *Module::getConstantPointerRef(GlobalValue *V){
  // Create ref map lazily on demand...
  if (GVRefMap == 0) GVRefMap = new GlobalValueRefMap();

  GlobalValueRefMap::iterator I = GVRefMap->Map.find(V);
  if (I != GVRefMap->Map.end()) return I->second;

  ConstantPointerRef *Ref = new ConstantPointerRef(V);
  GVRefMap->Map.insert(std::make_pair(V, Ref));

  return Ref;
}

void Module::mutateConstantPointerRef(GlobalValue *OldGV, GlobalValue *NewGV) {
  GlobalValueRefMap::iterator I = GVRefMap->Map.find(OldGV);
  assert(I != GVRefMap->Map.end() &&
	 "mutateConstantPointerRef; OldGV not in table!");
  ConstantPointerRef *Ref = I->second;

  // Remove the old entry...
  GVRefMap->Map.erase(I);

  // Insert the new entry...
  GVRefMap->Map.insert(std::make_pair(NewGV, Ref));
}
<|endoftext|>


<commit_before>//===-- Module.cpp - Implement the Module class ------------------*- C++ -*--=//
//
// This file implements the Module class for the VMCore library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/InstrTypes.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "Support/STLExtras.h"
#include "SymbolTableListTraitsImpl.h"
#include <algorithm>
#include <map>

Function *ilist_traits<Function>::createNode() {
  return new Function(FunctionType::get(Type::VoidTy,std::vector<const Type*>(),
                                        false), false);
}
GlobalVariable *ilist_traits<GlobalVariable>::createNode() {
  return new GlobalVariable(Type::IntTy, false, false);
}

iplist<Function> &ilist_traits<Function>::getList(Module *M) {
  return M->getFunctionList();
}
iplist<GlobalVariable> &ilist_traits<GlobalVariable>::getList(Module *M) {
  return M->getGlobalList();
}

// Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file...
template SymbolTableListTraits<GlobalVariable, Module, Module>;
template SymbolTableListTraits<Function, Module, Module>;

// Define the GlobalValueRefMap as a struct that wraps a map so that we don't
// have Module.h depend on <map>
//
struct GlobalValueRefMap {
  typedef std::map<GlobalValue*, ConstantPointerRef*> MapTy;
  typedef MapTy::iterator iterator;
  std::map<GlobalValue*, ConstantPointerRef*> Map;
};

Module::Module() {
  FunctionList.setItemParent(this);
  FunctionList.setParent(this);
  GlobalList.setItemParent(this);
  GlobalList.setParent(this);
  GVRefMap = 0;
  SymTab = 0;
}

Module::~Module() {
  dropAllReferences();
  GlobalList.clear();
  GlobalList.setParent(0);
  FunctionList.clear();
  FunctionList.setParent(0);
  delete SymTab;
}

SymbolTable *Module::getSymbolTableSure() {
  if (!SymTab) SymTab = new SymbolTable(0);
  return SymTab;
}

// hasSymbolTable() - Returns true if there is a symbol table allocated to
// this object AND if there is at least one name in it!
//
bool Module::hasSymbolTable() const {
  if (!SymTab) return false;

  for (SymbolTable::const_iterator I = SymTab->begin(), E = SymTab->end();
       I != E; ++I)
    if (I->second.begin() != I->second.end())
      return true;                                // Found nonempty type plane!

  return false;
}

// getOrInsertFunction - Look up the specified function in the module symbol
// table.  If it does not exist, add a prototype for the function and return
// it.  This is nice because it allows most passes to get away with not handling
// the symbol table directly for this common task.
//
Function *Module::getOrInsertFunction(const std::string &Name,
                                      const FunctionType *Ty) {
  SymbolTable *SymTab = getSymbolTableSure();

  // See if we have a definitions for the specified function already...
  if (Value *V = SymTab->lookup(PointerType::get(Ty), Name)) {
    return cast<Function>(V);      // Yup, got it
  } else {                         // Nope, add one
    Function *New = new Function(Ty, false, Name);
    FunctionList.push_back(New);
    return New;                    // Return the new prototype...
  }
}

// getFunction - Look up the specified function in the module symbol table.
// If it does not exist, return null.
//
Function *Module::getFunction(const std::string &Name, const FunctionType *Ty) {
  SymbolTable *SymTab = getSymbolTable();
  if (SymTab == 0) return 0;  // No symtab, no symbols...

  return cast_or_null<Function>(SymTab->lookup(PointerType::get(Ty), Name));
}

// addTypeName - Insert an entry in the symbol table mapping Str to Type.  If
// there is already an entry for this name, true is returned and the symbol
// table is not modified.
//
bool Module::addTypeName(const std::string &Name, const Type *Ty) {
  SymbolTable *ST = getSymbolTableSure();

  if (ST->lookup(Type::TypeTy, Name)) return true;  // Already in symtab...

  // Not in symbol table?  Set the name with the Symtab as an argument so the
  // type knows what to update...
  ((Value*)Ty)->setName(Name, ST);

  return false;
}

// getTypeName - If there is at least one entry in the symbol table for the
// specified type, return it.
//
std::string Module::getTypeName(const Type *Ty) {
  const SymbolTable *ST = getSymbolTable();
  if (ST == 0) return "";  // No symbol table, must not have an entry...
  if (ST->find(Type::TypeTy) == ST->end())
    return ""; // No names for types...

  SymbolTable::type_const_iterator TI = ST->type_begin(Type::TypeTy);
  SymbolTable::type_const_iterator TE = ST->type_end(Type::TypeTy);

  while (TI != TE && TI->second != (const Value*)Ty)
    ++TI;

  if (TI != TE)  // Must have found an entry!
    return TI->first;
  return "";     // Must not have found anything...
}

// dropAllReferences() - This function causes all the subinstructions to "let
// go" of all references that they are maintaining.  This allows one to
// 'delete' a whole class at a time, even though there may be circular
// references... first all references are dropped, and all use counts go to
// zero.  Then everything is delete'd for real.  Note that no operations are
// valid on an object that has "dropped all references", except operator
// delete.
//
void Module::dropAllReferences() {
  for(Module::iterator I = begin(), E = end(); I != E; ++I)
    I->dropAllReferences();

  for(Module::giterator I = gbegin(), E = gend(); I != E; ++I)
    I->dropAllReferences();

  // If there are any GlobalVariable references still out there, nuke them now.
  // Since all references are hereby dropped, nothing could possibly reference
  // them still.
  if (GVRefMap) {
    for (GlobalValueRefMap::iterator I = GVRefMap->Map.begin(),
           E = GVRefMap->Map.end(); I != E; ++I) {
      // Delete the ConstantPointerRef node...
      I->second->destroyConstant();
    }

    // Since the table is empty, we can now delete it...
    delete GVRefMap;
  }
}

// Accessor for the underlying GlobalValRefMap...
ConstantPointerRef *Module::getConstantPointerRef(GlobalValue *V){
  // Create ref map lazily on demand...
  if (GVRefMap == 0) GVRefMap = new GlobalValueRefMap();

  GlobalValueRefMap::iterator I = GVRefMap->Map.find(V);
  if (I != GVRefMap->Map.end()) return I->second;

  ConstantPointerRef *Ref = new ConstantPointerRef(V);
  GVRefMap->Map.insert(std::make_pair(V, Ref));

  return Ref;
}

void Module::mutateConstantPointerRef(GlobalValue *OldGV, GlobalValue *NewGV) {
  GlobalValueRefMap::iterator I = GVRefMap->Map.find(OldGV);
  assert(I != GVRefMap->Map.end() &&
	 "mutateConstantPointerRef; OldGV not in table!");
  ConstantPointerRef *Ref = I->second;

  // Remove the old entry...
  GVRefMap->Map.erase(I);

  // Insert the new entry...
  GVRefMap->Map.insert(std::make_pair(NewGV, Ref));
}
<commit_msg><commit_after>//===-- Module.cpp - Implement the Module class ------------------*- C++ -*--=//
//
// This file implements the Module class for the VMCore library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/InstrTypes.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "Support/STLExtras.h"
#include "SymbolTableListTraitsImpl.h"
#include <algorithm>
#include <map>

Function *ilist_traits<Function>::createNode() {
  return new Function(FunctionType::get(Type::VoidTy,std::vector<const Type*>(),
                                        false), false);
}
GlobalVariable *ilist_traits<GlobalVariable>::createNode() {
  return new GlobalVariable(Type::IntTy, false, false);
}

iplist<Function> &ilist_traits<Function>::getList(Module *M) {
  return M->getFunctionList();
}
iplist<GlobalVariable> &ilist_traits<GlobalVariable>::getList(Module *M) {
  return M->getGlobalList();
}

// Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file...
template SymbolTableListTraits<GlobalVariable, Module, Module>;
template SymbolTableListTraits<Function, Module, Module>;

// Define the GlobalValueRefMap as a struct that wraps a map so that we don't
// have Module.h depend on <map>
//
struct GlobalValueRefMap {
  typedef std::map<GlobalValue*, ConstantPointerRef*> MapTy;
  typedef MapTy::iterator iterator;
  std::map<GlobalValue*, ConstantPointerRef*> Map;
};

Module::Module() {
  FunctionList.setItemParent(this);
  FunctionList.setParent(this);
  GlobalList.setItemParent(this);
  GlobalList.setParent(this);
  GVRefMap = 0;
  SymTab = 0;
}

Module::~Module() {
  dropAllReferences();
  GlobalList.clear();
  GlobalList.setParent(0);
  FunctionList.clear();
  FunctionList.setParent(0);
  delete SymTab;
}

// Module::dump() - Allow printing from debugger
void Module::dump() const {
  print(std::cerr);
}

SymbolTable *Module::getSymbolTableSure() {
  if (!SymTab) SymTab = new SymbolTable(0);
  return SymTab;
}

// hasSymbolTable() - Returns true if there is a symbol table allocated to
// this object AND if there is at least one name in it!
//
bool Module::hasSymbolTable() const {
  if (!SymTab) return false;

  for (SymbolTable::const_iterator I = SymTab->begin(), E = SymTab->end();
       I != E; ++I)
    if (I->second.begin() != I->second.end())
      return true;                                // Found nonempty type plane!

  return false;
}

// getOrInsertFunction - Look up the specified function in the module symbol
// table.  If it does not exist, add a prototype for the function and return
// it.  This is nice because it allows most passes to get away with not handling
// the symbol table directly for this common task.
//
Function *Module::getOrInsertFunction(const std::string &Name,
                                      const FunctionType *Ty) {
  SymbolTable *SymTab = getSymbolTableSure();

  // See if we have a definitions for the specified function already...
  if (Value *V = SymTab->lookup(PointerType::get(Ty), Name)) {
    return cast<Function>(V);      // Yup, got it
  } else {                         // Nope, add one
    Function *New = new Function(Ty, false, Name);
    FunctionList.push_back(New);
    return New;                    // Return the new prototype...
  }
}

// getFunction - Look up the specified function in the module symbol table.
// If it does not exist, return null.
//
Function *Module::getFunction(const std::string &Name, const FunctionType *Ty) {
  SymbolTable *SymTab = getSymbolTable();
  if (SymTab == 0) return 0;  // No symtab, no symbols...

  return cast_or_null<Function>(SymTab->lookup(PointerType::get(Ty), Name));
}

// addTypeName - Insert an entry in the symbol table mapping Str to Type.  If
// there is already an entry for this name, true is returned and the symbol
// table is not modified.
//
bool Module::addTypeName(const std::string &Name, const Type *Ty) {
  SymbolTable *ST = getSymbolTableSure();

  if (ST->lookup(Type::TypeTy, Name)) return true;  // Already in symtab...

  // Not in symbol table?  Set the name with the Symtab as an argument so the
  // type knows what to update...
  ((Value*)Ty)->setName(Name, ST);

  return false;
}

// getTypeName - If there is at least one entry in the symbol table for the
// specified type, return it.
//
std::string Module::getTypeName(const Type *Ty) {
  const SymbolTable *ST = getSymbolTable();
  if (ST == 0) return "";  // No symbol table, must not have an entry...
  if (ST->find(Type::TypeTy) == ST->end())
    return ""; // No names for types...

  SymbolTable::type_const_iterator TI = ST->type_begin(Type::TypeTy);
  SymbolTable::type_const_iterator TE = ST->type_end(Type::TypeTy);

  while (TI != TE && TI->second != (const Value*)Ty)
    ++TI;

  if (TI != TE)  // Must have found an entry!
    return TI->first;
  return "";     // Must not have found anything...
}

// dropAllReferences() - This function causes all the subelementss to "let go"
// of all references that they are maintaining.  This allows one to 'delete' a
// whole module at a time, even though there may be circular references... first
// all references are dropped, and all use counts go to zero.  Then everything
// is delete'd for real.  Note that no operations are valid on an object that
// has "dropped all references", except operator delete.
//
void Module::dropAllReferences() {
  for(Module::iterator I = begin(), E = end(); I != E; ++I)
    I->dropAllReferences();

  for(Module::giterator I = gbegin(), E = gend(); I != E; ++I)
    I->dropAllReferences();

  // If there are any GlobalVariable references still out there, nuke them now.
  // Since all references are hereby dropped, nothing could possibly reference
  // them still.
  if (GVRefMap) {
    for (GlobalValueRefMap::iterator I = GVRefMap->Map.begin(),
           E = GVRefMap->Map.end(); I != E; ++I) {
      // Delete the ConstantPointerRef node...
      I->second->destroyConstant();
    }

    // Since the table is empty, we can now delete it...
    delete GVRefMap;
  }
}

// Accessor for the underlying GlobalValRefMap...
ConstantPointerRef *Module::getConstantPointerRef(GlobalValue *V){
  // Create ref map lazily on demand...
  if (GVRefMap == 0) GVRefMap = new GlobalValueRefMap();

  GlobalValueRefMap::iterator I = GVRefMap->Map.find(V);
  if (I != GVRefMap->Map.end()) return I->second;

  ConstantPointerRef *Ref = new ConstantPointerRef(V);
  GVRefMap->Map.insert(std::make_pair(V, Ref));

  return Ref;
}

void Module::mutateConstantPointerRef(GlobalValue *OldGV, GlobalValue *NewGV) {
  GlobalValueRefMap::iterator I = GVRefMap->Map.find(OldGV);
  assert(I != GVRefMap->Map.end() &&
	 "mutateConstantPointerRef; OldGV not in table!");
  ConstantPointerRef *Ref = I->second;

  // Remove the old entry...
  GVRefMap->Map.erase(I);

  // Insert the new entry...
  GVRefMap->Map.insert(std::make_pair(NewGV, Ref));
}
<|endoftext|>


<commit_before>/*
 * Quantum++
 *
 * Copyright (c) 2013 - 2014 Vlad Gheorghiu (vgheorgh@gmail.com)
 *
 * This file is part of Quantum++.
 *
 * Quantum++ is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Quantum++ is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Quantum++.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qpp.h"

// #include "MATLAB/matlab.h" // support for MATLAB

using namespace qpp;

int main()
{
//	/*   comment this line with "//" to uncomment the whole example

	// Qudit Teleportation
	{
		std::size_t D = 3; // size of the system
		std::cout << std::endl << "**** Qudit Teleportation, D = " << D
				<< " ****" << std::endl;
		ket mes_AB = ket::Zero(D * D); // maximally entangled state resource
		for (std::size_t i = 0; i < D; i++)
			mes_AB += mket( { i, i }, { D, D });
		mes_AB /= std::sqrt((double) D);
		cmat Bell_aA = adjoint( // circuit that measures in the qudit Bell basis
				gt.CTRL(gt.Xd(D), { 0 }, { 1 }, 2, D)
						* kron(gt.Fd(D), gt.Id(D)));
		ket psi_a = randket(D); // random state as input on a
		std::cout << "** Initial state:" << std::endl;
		displn(psi_a);
		ket input_aAB = kron(psi_a, mes_AB); // joint input state aAB
		// output before measurement
		ket output_aAB = apply(input_aAB, Bell_aA, { 0, 1 }, 3, D);
		auto measured_aA = measure(ptrace2(prj(output_aAB), { D * D, D }),
				gt.Id(D * D)); // measure on aA
		std::discrete_distribution<std::size_t> dd(measured_aA.first.begin(),
				measured_aA.first.end());
		std::cout << "** Measurement probabilities: ";
		displn(measured_aA.first, ", ");
		std::size_t m = dd(rdevs._rng); // sample
		auto midx = n2multiidx(m, { D, D });
		std::cout << "** Measurement result: ";
		displn(midx, " ");
		// conditional result on B before correction
		ket output_m_aAB = apply(output_aAB, prj(mket(midx, { D, D })),
				{ 0, 1 }, 3, D) / std::sqrt(measured_aA.first[m]);
		cmat correction_B = powm(gt.Zd(D), midx[0])
				* powm(adjoint(gt.Xd(D)), midx[1]); // correction operator
				// apply correction on B
		output_aAB = apply(output_m_aAB, correction_B, { 2 }, 3, D);
		cmat rho_B = ptrace1(prj(output_aAB), { D * D, D });
		std::cout << "** Bob's density operator: " << std::endl;
		displn(rho_B);
		std::cout << "** Norm difference: " << norm(rho_B - prj(psi_a))
				<< std::endl; // verification
	}

	// Qudit Dense Coding
	{
		std::size_t D = 4; // size of the system
		std::cout << std::endl << "**** Qudit Dense Coding , D = " << D
				<< " ****" << std::endl;
		ket mes_AB = ket::Zero(D * D); // maximally entangled state resource
		for (std::size_t i = 0; i < D; i++)
			mes_AB += mket( { i, i }, { D, D });
		mes_AB /= std::sqrt((double) D);
		cmat Bell_AB = adjoint( // circuit that measures in the qudit Bell basis
				gt.CTRL(gt.Xd(D), { 0 }, { 1 }, 2, D)
						* kron(gt.Fd(D), gt.Id(D)));
		// equal probabilities of choosing a message
		std::uniform_int_distribution<std::size_t> udd(0, D * D - 1);
		std::size_t m_A = udd(rdevs._rng); // sample, obtain the message index
		auto midx = n2multiidx(m_A, { D, D });
		std::cout << "** Alice sent: ";
		displn(midx, " ");
		// Alice's operation
		cmat U_A = powm(gt.Zd(D), midx[0]) * powm(adjoint(gt.Xd(D)), midx[1]);
		// Alice encodes the message
		ket psi_AB = apply(mes_AB, U_A, { 0 }, 2, D);
		// Bob measures the joint system in the qudit Bell basis
		psi_AB = apply(psi_AB, Bell_AB, { 0, 1 }, 2, D);
		auto measured = measure(psi_AB, gt.Id(D * D));
		std::cout << "** Bob measurement probabilities: ";
		displn(measured.first, ", ");
		// Bob samples according to the measurement probabilities
		std::discrete_distribution<std::size_t> dd(measured.first.begin(),
				measured.first.end());
		std::size_t m_B = dd(rdevs._rng);
		std::cout << "** Bob received: ";
		displn(n2multiidx(m_B, { D, D }), " ") << std::endl;
	}

	// */
}
<commit_msg>Library is now fully functional<commit_after>/*
 * Quantum++
 *
 * Copyright (c) 2013 - 2014 Vlad Gheorghiu (vgheorgh@gmail.com)
 *
 * This file is part of Quantum++.
 *
 * Quantum++ is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Quantum++ is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Quantum++.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qpp.h"

// #include "MATLAB/matlab.h" // support for MATLAB

using namespace qpp;

int main()
{
//	/*   comment this line with "//" to uncomment the whole example

	// Qudit Teleportation
	{
		std::size_t D = 3; // size of the system
		std::cout << std::endl << "**** Qudit Teleportation, D = " << D
				<< " ****" << std::endl;
		ket mes_AB = ket::Zero(D * D); // maximally entangled state resource
		for (std::size_t i = 0; i < D; i++)
			mes_AB += mket( { i, i }, { D, D });
		mes_AB /= std::sqrt((double) D);
		cmat Bell_aA = adjoint( // circuit that measures in the qudit Bell basis
				gt.CTRL(gt.Xd(D), { 0 }, { 1 }, 2, D)
						* kron(gt.Fd(D), gt.Id(D)));
		ket psi_a = randket(D); // random state as input on a
		std::cout << "** Initial state:" << std::endl;
		displn(psi_a);
		ket input_aAB = kron(psi_a, mes_AB); // joint input state aAB
		// output before measurement
		ket output_aAB = apply(input_aAB, Bell_aA, { 0, 1 }, 3, D);
		auto measured_aA = measure(ptrace2(prj(output_aAB), { D * D, D }),
				gt.Id(D * D)); // measure on aA
		std::discrete_distribution<std::size_t> dd(measured_aA.first.begin(),
				measured_aA.first.end());
		std::cout << "** Measurement probabilities: ";
		displn(measured_aA.first, ", ");
		std::size_t m = dd(rdevs._rng); // sample
		auto midx = n2multiidx(m, { D, D });
		std::cout << "** Measurement result: ";
		displn(midx, " ");
		// conditional result on B before correction
		ket output_m_aAB = apply(output_aAB, prj(mket(midx, { D, D })),
				{ 0, 1 }, 3, D) / std::sqrt(measured_aA.first[m]);
		cmat correction_B = powm(gt.Zd(D), midx[0])
				* powm(adjoint(gt.Xd(D)), midx[1]); // correction operator
				// apply correction on B
		output_aAB = apply(output_m_aAB, correction_B, { 2 }, 3, D);
		cmat rho_B = ptrace1(prj(output_aAB), { D * D, D });
		std::cout << "** Bob's density operator: " << std::endl;
		displn(rho_B);
		std::cout << "** Norm difference: " << norm(rho_B - prj(psi_a))
				<< std::endl; // verification
	}

	// Qudit Dense Coding
	{
		std::size_t D = 3; // size of the system
		std::cout << std::endl << "**** Qudit Dense Coding , D = " << D
				<< " ****" << std::endl;
		ket mes_AB = ket::Zero(D * D); // maximally entangled state resource
		for (std::size_t i = 0; i < D; i++)
			mes_AB += mket( { i, i }, { D, D });
		mes_AB /= std::sqrt((double) D);
		cmat Bell_AB = adjoint( // circuit that measures in the qudit Bell basis
				gt.CTRL(gt.Xd(D), { 0 }, { 1 }, 2, D)
						* kron(gt.Fd(D), gt.Id(D)));
		// equal probabilities of choosing a message
		std::uniform_int_distribution<std::size_t> udd(0, D * D - 1);
		std::size_t m_A = udd(rdevs._rng); // sample, obtain the message index
		auto midx = n2multiidx(m_A, { D, D });
		std::cout << "** Alice sent: ";
		displn(midx, " ");
		// Alice's operation
		cmat U_A = powm(gt.Zd(D), midx[0]) * powm(adjoint(gt.Xd(D)), midx[1]);
		// Alice encodes the message
		ket psi_AB = apply(mes_AB, U_A, { 0 }, 2, D);
		// Bob measures the joint system in the qudit Bell basis
		psi_AB = apply(psi_AB, Bell_AB, { 0, 1 }, 2, D);
		auto measured = measure(psi_AB, gt.Id(D * D));
		std::cout << "** Bob measurement probabilities: ";
		displn(measured.first, ", ");
		// Bob samples according to the measurement probabilities
		std::discrete_distribution<std::size_t> dd(measured.first.begin(),
				measured.first.end());
		std::size_t m_B = dd(rdevs._rng);
		std::cout << "** Bob received: ";
		displn(n2multiidx(m_B, { D, D }), " ") << std::endl;
	}

	// */
}
<|endoftext|>


<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2014 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/ui/gl/gl_context.h"

#include <gflags/gflags.h>

#include <mutex>
#include <string>

#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/profiling.h"
#include "xenia/ui/gl/gl_immediate_drawer.h"
#include "xenia/ui/window.h"

DEFINE_bool(thread_safe_gl, false,
            "Only allow one GL context to be active at a time.");

DEFINE_bool(disable_gl_context_reset, false,
            "Do not aggressively reset the GL context (helps with capture "
            "programs such as OBS or FRAPS).");

DEFINE_bool(random_clear_color, false, "Randomizes GL clear color.");

DEFINE_bool(gl_debug, false, "Enable OpenGL debug validation layer.");
DEFINE_bool(gl_debug_output, false, "Dump ARB_debug_output to stderr.");
DEFINE_bool(gl_debug_output_synchronous, true,
            "ARB_debug_output will synchronize to be thread safe.");

namespace xe {
namespace ui {
namespace gl {

std::recursive_mutex GLContext::global_gl_mutex_;

void GLContext::FatalGLError(std::string error) {
  xe::FatalError(
      error +
      "\nEnsure you have the latest drivers for your GPU and that it supports "
      "OpenGL 4.5. See http://xenia.jp/faq/ for more information and a list"
      "of supported GPUs.");
}

GLContext::GLContext(GraphicsProvider* provider, Window* target_window)
    : GraphicsContext(provider, target_window) {}

GLContext::~GLContext() {}

void GLContext::AssertExtensionsPresent() {
  if (!MakeCurrent()) {
    FatalGLError("Unable to make GL context current.");
    return;
  }

  // Check shader version at least 4.5 (matching GL 4.5).
  auto glsl_version_raw =
      reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
  std::string glsl_version(glsl_version_raw);
  if (glsl_version.find("4.5") == std::string::npos && glsl_version.find("4.6") == std::string::npos) {
    FatalGLError("OpenGL GLSL version 4.50 or higher is required.");
    return;
  }

  if (!GLEW_ARB_bindless_texture || !glMakeTextureHandleResidentARB) {
    FatalGLError("OpenGL extension ARB_bindless_texture is required.");
    return;
  }

  if (!GLEW_ARB_fragment_coord_conventions) {
    FatalGLError(
        "OpenGL extension ARB_fragment_coord_conventions is required.");
    return;
  }

  ClearCurrent();
}

void GLContext::DebugMessage(GLenum source, GLenum type, GLuint id,
                             GLenum severity, GLsizei length,
                             const GLchar* message) {
  const char* source_name = nullptr;
  switch (source) {
    case GL_DEBUG_SOURCE_API_ARB:
      source_name = "OpenGL";
      break;
    case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
      source_name = "Windows";
      break;
    case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
      source_name = "Shader Compiler";
      break;
    case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
      source_name = "Third Party";
      break;
    case GL_DEBUG_SOURCE_APPLICATION_ARB:
      source_name = "Application";
      break;
    case GL_DEBUG_SOURCE_OTHER_ARB:
      source_name = "Other";
      break;
    default:
      source_name = "(unknown source)";
      break;
  }

  const char* type_name = nullptr;
  switch (type) {
    case GL_DEBUG_TYPE_ERROR:
      type_name = "error";
      break;
    case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
      type_name = "deprecated behavior";
      break;
    case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
      type_name = "undefined behavior";
      break;
    case GL_DEBUG_TYPE_PORTABILITY:
      type_name = "portability";
      break;
    case GL_DEBUG_TYPE_PERFORMANCE:
      type_name = "performance";
      break;
    case GL_DEBUG_TYPE_OTHER:
      type_name = "message";
      break;
    case GL_DEBUG_TYPE_MARKER:
      type_name = "marker";
      break;
    case GL_DEBUG_TYPE_PUSH_GROUP:
      type_name = "push group";
      break;
    case GL_DEBUG_TYPE_POP_GROUP:
      type_name = "pop group";
      break;
    default:
      type_name = "(unknown type)";
      break;
  }

  const char* severity_name = nullptr;
  switch (severity) {
    case GL_DEBUG_SEVERITY_HIGH_ARB:
      severity_name = "high";
      break;
    case GL_DEBUG_SEVERITY_MEDIUM_ARB:
      severity_name = "medium";
      break;
    case GL_DEBUG_SEVERITY_LOW_ARB:
      severity_name = "low";
      break;
    case GL_DEBUG_SEVERITY_NOTIFICATION:
      severity_name = "notification";
      break;
    default:
      severity_name = "(unknown severity)";
      break;
  }

  XELOGE("GL4 %s: %s(%s) %d: %s", source_name, type_name, severity_name, id,
         message);
}

void GLAPIENTRY GLContext::DebugMessageThunk(GLenum source, GLenum type,
                                             GLuint id, GLenum severity,
                                             GLsizei length,
                                             const GLchar* message,
                                             GLvoid* user_param) {
  reinterpret_cast<GLContext*>(user_param)
      ->DebugMessage(source, type, id, severity, length, message);
}

void GLContext::SetupDebugging() {
  if (!FLAGS_gl_debug || !FLAGS_gl_debug_output) {
    return;
  }

  glEnable(GL_DEBUG_OUTPUT);

  // Synchronous output hurts, but is required if we want to line up the logs.
  if (FLAGS_gl_debug_output_synchronous) {
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  } else {
    glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  }

  // Enable everything by default.
  glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL,
                        GL_TRUE);

  // Disable annoying messages.
  GLuint disable_message_ids[] = {
      0x00020004,  // Usage warning: Generic vertex attribute array 0 uses a
                   // pointer with a small value (0x0000000000000000). Is this
                   // intended to be used as an offset into a buffer object?
  };
  glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE,
                        GLsizei(xe::countof(disable_message_ids)),
                        disable_message_ids, GL_FALSE);

  // Callback will be made from driver threads.
  glDebugMessageCallback(reinterpret_cast<GLDEBUGPROC>(&DebugMessageThunk),
                         this);
}

ImmediateDrawer* GLContext::immediate_drawer() {
  return immediate_drawer_.get();
}

bool GLContext::WasLost() {
  if (!robust_access_supported_) {
    // Can't determine if we lost the context.
    return false;
  }

  if (context_lost_) {
    return true;
  }

  auto status = glGetGraphicsResetStatusARB();
  if (status != GL_NO_ERROR) {
    // Graphics card reset.
    XELOGE("============= TDR detected on context %p! Context %s =============",
           handle(), status == GL_GUILTY_CONTEXT_RESET ? "guilty" : "innocent");
    context_lost_ = true;
    return true;
  }

  return false;
}

std::unique_ptr<RawImage> GLContext::Capture() {
  GraphicsContextLock lock(this);

  std::unique_ptr<RawImage> raw_image(new RawImage());
  raw_image->width = target_window_->width();
  raw_image->stride = raw_image->width * 4;
  raw_image->height = target_window_->height();
  raw_image->data.resize(raw_image->stride * raw_image->height);

  glReadPixels(0, 0, target_window_->width(), target_window_->height(), GL_RGBA,
               GL_UNSIGNED_BYTE, raw_image->data.data());

  // Flip vertically in-place.
  size_t yt = 0;
  size_t yb = (raw_image->height - 1) * raw_image->stride;
  while (yt < yb) {
    for (size_t i = 0; i < raw_image->stride; ++i) {
      std::swap(raw_image->data[yt + i], raw_image->data[yb + i]);
    }
    yt += raw_image->stride;
    yb -= raw_image->stride;
  }

  return raw_image;
}

}  // namespace gl
}  // namespace ui
}  // namespace xe
<commit_msg>Formatting.<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2014 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/ui/gl/gl_context.h"

#include <gflags/gflags.h>

#include <mutex>
#include <string>

#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/profiling.h"
#include "xenia/ui/gl/gl_immediate_drawer.h"
#include "xenia/ui/window.h"

DEFINE_bool(thread_safe_gl, false,
            "Only allow one GL context to be active at a time.");

DEFINE_bool(disable_gl_context_reset, false,
            "Do not aggressively reset the GL context (helps with capture "
            "programs such as OBS or FRAPS).");

DEFINE_bool(random_clear_color, false, "Randomizes GL clear color.");

DEFINE_bool(gl_debug, false, "Enable OpenGL debug validation layer.");
DEFINE_bool(gl_debug_output, false, "Dump ARB_debug_output to stderr.");
DEFINE_bool(gl_debug_output_synchronous, true,
            "ARB_debug_output will synchronize to be thread safe.");

namespace xe {
namespace ui {
namespace gl {

std::recursive_mutex GLContext::global_gl_mutex_;

void GLContext::FatalGLError(std::string error) {
  xe::FatalError(
      error +
      "\nEnsure you have the latest drivers for your GPU and that it supports "
      "OpenGL 4.5. See http://xenia.jp/faq/ for more information and a list"
      "of supported GPUs.");
}

GLContext::GLContext(GraphicsProvider* provider, Window* target_window)
    : GraphicsContext(provider, target_window) {}

GLContext::~GLContext() {}

void GLContext::AssertExtensionsPresent() {
  if (!MakeCurrent()) {
    FatalGLError("Unable to make GL context current.");
    return;
  }

  // Check shader version at least 4.5 (matching GL 4.5).
  auto glsl_version_raw =
      reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
  std::string glsl_version(glsl_version_raw);
  if (glsl_version.find("4.5") == std::string::npos &&
      glsl_version.find("4.6") == std::string::npos) {
    FatalGLError("OpenGL GLSL version 4.50 or higher is required.");
    return;
  }

  if (!GLEW_ARB_bindless_texture || !glMakeTextureHandleResidentARB) {
    FatalGLError("OpenGL extension ARB_bindless_texture is required.");
    return;
  }

  if (!GLEW_ARB_fragment_coord_conventions) {
    FatalGLError(
        "OpenGL extension ARB_fragment_coord_conventions is required.");
    return;
  }

  ClearCurrent();
}

void GLContext::DebugMessage(GLenum source, GLenum type, GLuint id,
                             GLenum severity, GLsizei length,
                             const GLchar* message) {
  const char* source_name = nullptr;
  switch (source) {
    case GL_DEBUG_SOURCE_API_ARB:
      source_name = "OpenGL";
      break;
    case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
      source_name = "Windows";
      break;
    case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
      source_name = "Shader Compiler";
      break;
    case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
      source_name = "Third Party";
      break;
    case GL_DEBUG_SOURCE_APPLICATION_ARB:
      source_name = "Application";
      break;
    case GL_DEBUG_SOURCE_OTHER_ARB:
      source_name = "Other";
      break;
    default:
      source_name = "(unknown source)";
      break;
  }

  const char* type_name = nullptr;
  switch (type) {
    case GL_DEBUG_TYPE_ERROR:
      type_name = "error";
      break;
    case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
      type_name = "deprecated behavior";
      break;
    case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
      type_name = "undefined behavior";
      break;
    case GL_DEBUG_TYPE_PORTABILITY:
      type_name = "portability";
      break;
    case GL_DEBUG_TYPE_PERFORMANCE:
      type_name = "performance";
      break;
    case GL_DEBUG_TYPE_OTHER:
      type_name = "message";
      break;
    case GL_DEBUG_TYPE_MARKER:
      type_name = "marker";
      break;
    case GL_DEBUG_TYPE_PUSH_GROUP:
      type_name = "push group";
      break;
    case GL_DEBUG_TYPE_POP_GROUP:
      type_name = "pop group";
      break;
    default:
      type_name = "(unknown type)";
      break;
  }

  const char* severity_name = nullptr;
  switch (severity) {
    case GL_DEBUG_SEVERITY_HIGH_ARB:
      severity_name = "high";
      break;
    case GL_DEBUG_SEVERITY_MEDIUM_ARB:
      severity_name = "medium";
      break;
    case GL_DEBUG_SEVERITY_LOW_ARB:
      severity_name = "low";
      break;
    case GL_DEBUG_SEVERITY_NOTIFICATION:
      severity_name = "notification";
      break;
    default:
      severity_name = "(unknown severity)";
      break;
  }

  XELOGE("GL4 %s: %s(%s) %d: %s", source_name, type_name, severity_name, id,
         message);
}

void GLAPIENTRY GLContext::DebugMessageThunk(GLenum source, GLenum type,
                                             GLuint id, GLenum severity,
                                             GLsizei length,
                                             const GLchar* message,
                                             GLvoid* user_param) {
  reinterpret_cast<GLContext*>(user_param)
      ->DebugMessage(source, type, id, severity, length, message);
}

void GLContext::SetupDebugging() {
  if (!FLAGS_gl_debug || !FLAGS_gl_debug_output) {
    return;
  }

  glEnable(GL_DEBUG_OUTPUT);

  // Synchronous output hurts, but is required if we want to line up the logs.
  if (FLAGS_gl_debug_output_synchronous) {
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  } else {
    glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  }

  // Enable everything by default.
  glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL,
                        GL_TRUE);

  // Disable annoying messages.
  GLuint disable_message_ids[] = {
      0x00020004,  // Usage warning: Generic vertex attribute array 0 uses a
                   // pointer with a small value (0x0000000000000000). Is this
                   // intended to be used as an offset into a buffer object?
  };
  glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE,
                        GLsizei(xe::countof(disable_message_ids)),
                        disable_message_ids, GL_FALSE);

  // Callback will be made from driver threads.
  glDebugMessageCallback(reinterpret_cast<GLDEBUGPROC>(&DebugMessageThunk),
                         this);
}

ImmediateDrawer* GLContext::immediate_drawer() {
  return immediate_drawer_.get();
}

bool GLContext::WasLost() {
  if (!robust_access_supported_) {
    // Can't determine if we lost the context.
    return false;
  }

  if (context_lost_) {
    return true;
  }

  auto status = glGetGraphicsResetStatusARB();
  if (status != GL_NO_ERROR) {
    // Graphics card reset.
    XELOGE("============= TDR detected on context %p! Context %s =============",
           handle(), status == GL_GUILTY_CONTEXT_RESET ? "guilty" : "innocent");
    context_lost_ = true;
    return true;
  }

  return false;
}

std::unique_ptr<RawImage> GLContext::Capture() {
  GraphicsContextLock lock(this);

  std::unique_ptr<RawImage> raw_image(new RawImage());
  raw_image->width = target_window_->width();
  raw_image->stride = raw_image->width * 4;
  raw_image->height = target_window_->height();
  raw_image->data.resize(raw_image->stride * raw_image->height);

  glReadPixels(0, 0, target_window_->width(), target_window_->height(), GL_RGBA,
               GL_UNSIGNED_BYTE, raw_image->data.data());

  // Flip vertically in-place.
  size_t yt = 0;
  size_t yb = (raw_image->height - 1) * raw_image->stride;
  while (yt < yb) {
    for (size_t i = 0; i < raw_image->stride; ++i) {
      std::swap(raw_image->data[yt + i], raw_image->data[yb + i]);
    }
    yt += raw_image->stride;
    yb -= raw_image->stride;
  }

  return raw_image;
}

}  // namespace gl
}  // namespace ui
}  // namespace xe
<|endoftext|>


<commit_before>#include "swift/Basic/LangOptions.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Parse/Lexer.h"
#include "swift/Parse/Parser.h"
#include "swift/Subsystems.h"
#include "llvm/Support/MemoryBuffer.h"
#include "gtest/gtest.h"

using namespace swift;
using namespace llvm;

// The test fixture.
class TokenizerTest : public ::testing::Test {
public:
  LangOptions LangOpts;
  SourceManager SM;

  unsigned makeBuffer(StringRef Source) {
    return SM.addMemBufferCopy(Source);
  }

  static void replaceNewLines(std::string &S) {
    size_t Index = 0;
    while (true) {
      Index = S.find("\n", Index);
      if (Index == std::string::npos) break;
      S.erase(Index, 1);
      S.insert(Index, "\\n");
      Index += 3;
    }
  }

  static StringRef tokToString(swift::tok T) {
    switch (T) {
  #define KEYWORD(X) \
    case swift::tok::kw_##X: return "kw_" #X; break;
  #define PUNCTUATOR(X, Y) \
    case swift::tok::X: return #X; break;
  #include "swift/Parse/Tokens.def"

  #define OTHER(X) \
  case swift::tok::X: return #X; break;
        OTHER(unknown)
        OTHER(eof)
        OTHER(code_complete)
        OTHER(identifier)
        OTHER(oper_binary_unspaced)
        OTHER(oper_binary_spaced)
        OTHER(oper_postfix)
        OTHER(oper_prefix)
        OTHER(dollarident)
        OTHER(integer_literal)
        OTHER(floating_literal)
        OTHER(string_literal)
        OTHER(sil_local_name)
        OTHER(pound_if)
        OTHER(pound_else)
        OTHER(pound_elseif)
        OTHER(pound_endif)
        OTHER(pound_line)
        OTHER(pound_available)
        OTHER(comment)

      default:
        return "??? (" + std::to_string(static_cast<int>(tok())) + ")";
        break;
    }
  }

  void assertTokens(std::vector<Token> Ts, StringRef Expected) {
    std::string Actual;
    for (auto C = Ts.begin(), E = Ts.end(); C != E; ++C) {
      Actual += tokToString(C->getKind());
      Actual += ": ";

      std::string Txt(C->getRawText());
      replaceNewLines(Txt);
      Actual += Txt;

      Actual += "\n";
    }
    EXPECT_EQ(Expected, Actual)
      << "---- Expected: \n" << Expected << "\n"
      << "---- Actual: \n" << Actual << "\n";
  }

  std::vector<Token> parseAndGetSplitTOkens(unsigned BufID) {
    swift::ParserUnit PU(SM, BufID, LangOpts, "unknown");

    bool Done = false;
    while (!Done) {
      PU.getParser().parseTopLevel();
      Done = PU.getParser().Tok.is(tok::eof);
    }

    return PU.getParser().getSplitTokens();
  }

  std::vector<Token> tokenize(unsigned BufID, const std::vector<Token> &SplitTokens = {}) {
    return swift::tokenize(LangOpts,
                           SM,
                           BufID,
                           /* Offset = */ 0,
                           /* EndOffset = */ 0,
                           /* KeepComments = */ true,
                           /* TokenizeInterpolatedString = */ true,
                           SplitTokens);
  }
};

TEST_F(TokenizerTest, ProperlySplitTokens) {
  auto BufID = makeBuffer(
    "infix operator ⊕ { associativity left precedence 100 }\n"
    "func ⊕<T>(t1: T, t2: T) {}\n"
  );

  // Tokenize w/o fixing split tokens
  auto Tokens = tokenize(BufID);
  assertTokens(Tokens,
    "identifier: infix\n"
    "kw_operator: operator\n"
    "oper_binary_spaced: ⊕\n"
    "l_brace: {\n"
    "identifier: associativity\n"
    "identifier: left\n"
    "identifier: precedence\n"
    "integer_literal: 100\n"
    "r_brace: }\n"
    "kw_func: func\n"
    "oper_prefix: ⊕<\n"
    "identifier: T\n"
    "oper_binary_unspaced: >\n"
    "l_paren: (\n"
    "identifier: t1\n"
    "colon: :\n"
    "identifier: T\n"
    "comma: ,\n"
    "identifier: t2\n"
    "colon: :\n"
    "identifier: T\n"
    "r_paren: )\n"
    "l_brace: {\n"
    "r_brace: }\n"
  );

  // Parse the input and get split tokens info
  auto SplitTokens = parseAndGetSplitTOkens(BufID);

  // Tokenize with fixing split tokens
  Tokens = tokenize(BufID, SplitTokens);
  assertTokens(Tokens,
     "identifier: infix\n"
     "kw_operator: operator\n"
     "oper_binary_spaced: ⊕\n"
     "l_brace: {\n"
     "identifier: associativity\n"
     "identifier: left\n"
     "identifier: precedence\n"
     "integer_literal: 100\n"
     "r_brace: }\n"
     "kw_func: func\n"
     "identifier: ⊕\n"
     "oper_binary_unspaced: <\n"
     "identifier: T\n"
     "oper_binary_unspaced: >\n"
     "l_paren: (\n"
     "identifier: t1\n"
     "colon: :\n"
     "identifier: T\n"
     "comma: ,\n"
     "identifier: t2\n"
     "colon: :\n"
     "identifier: T\n"
     "r_paren: )\n"
     "l_brace: {\n"
     "r_brace: }\n"
  );
}

<commit_msg>[gardening] Fix recently introduced typo: "TOkens" → "Tokens"<commit_after>#include "swift/Basic/LangOptions.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Parse/Lexer.h"
#include "swift/Parse/Parser.h"
#include "swift/Subsystems.h"
#include "llvm/Support/MemoryBuffer.h"
#include "gtest/gtest.h"

using namespace swift;
using namespace llvm;

// The test fixture.
class TokenizerTest : public ::testing::Test {
public:
  LangOptions LangOpts;
  SourceManager SM;

  unsigned makeBuffer(StringRef Source) {
    return SM.addMemBufferCopy(Source);
  }

  static void replaceNewLines(std::string &S) {
    size_t Index = 0;
    while (true) {
      Index = S.find("\n", Index);
      if (Index == std::string::npos) break;
      S.erase(Index, 1);
      S.insert(Index, "\\n");
      Index += 3;
    }
  }

  static StringRef tokToString(swift::tok T) {
    switch (T) {
  #define KEYWORD(X) \
    case swift::tok::kw_##X: return "kw_" #X; break;
  #define PUNCTUATOR(X, Y) \
    case swift::tok::X: return #X; break;
  #include "swift/Parse/Tokens.def"

  #define OTHER(X) \
  case swift::tok::X: return #X; break;
        OTHER(unknown)
        OTHER(eof)
        OTHER(code_complete)
        OTHER(identifier)
        OTHER(oper_binary_unspaced)
        OTHER(oper_binary_spaced)
        OTHER(oper_postfix)
        OTHER(oper_prefix)
        OTHER(dollarident)
        OTHER(integer_literal)
        OTHER(floating_literal)
        OTHER(string_literal)
        OTHER(sil_local_name)
        OTHER(pound_if)
        OTHER(pound_else)
        OTHER(pound_elseif)
        OTHER(pound_endif)
        OTHER(pound_line)
        OTHER(pound_available)
        OTHER(comment)

      default:
        return "??? (" + std::to_string(static_cast<int>(tok())) + ")";
        break;
    }
  }

  void assertTokens(std::vector<Token> Ts, StringRef Expected) {
    std::string Actual;
    for (auto C = Ts.begin(), E = Ts.end(); C != E; ++C) {
      Actual += tokToString(C->getKind());
      Actual += ": ";

      std::string Txt(C->getRawText());
      replaceNewLines(Txt);
      Actual += Txt;

      Actual += "\n";
    }
    EXPECT_EQ(Expected, Actual)
      << "---- Expected: \n" << Expected << "\n"
      << "---- Actual: \n" << Actual << "\n";
  }

  std::vector<Token> parseAndGetSplitTokens(unsigned BufID) {
    swift::ParserUnit PU(SM, BufID, LangOpts, "unknown");

    bool Done = false;
    while (!Done) {
      PU.getParser().parseTopLevel();
      Done = PU.getParser().Tok.is(tok::eof);
    }

    return PU.getParser().getSplitTokens();
  }

  std::vector<Token> tokenize(unsigned BufID, const std::vector<Token> &SplitTokens = {}) {
    return swift::tokenize(LangOpts,
                           SM,
                           BufID,
                           /* Offset = */ 0,
                           /* EndOffset = */ 0,
                           /* KeepComments = */ true,
                           /* TokenizeInterpolatedString = */ true,
                           SplitTokens);
  }
};

TEST_F(TokenizerTest, ProperlySplitTokens) {
  auto BufID = makeBuffer(
    "infix operator ⊕ { associativity left precedence 100 }\n"
    "func ⊕<T>(t1: T, t2: T) {}\n"
  );

  // Tokenize w/o fixing split tokens
  auto Tokens = tokenize(BufID);
  assertTokens(Tokens,
    "identifier: infix\n"
    "kw_operator: operator\n"
    "oper_binary_spaced: ⊕\n"
    "l_brace: {\n"
    "identifier: associativity\n"
    "identifier: left\n"
    "identifier: precedence\n"
    "integer_literal: 100\n"
    "r_brace: }\n"
    "kw_func: func\n"
    "oper_prefix: ⊕<\n"
    "identifier: T\n"
    "oper_binary_unspaced: >\n"
    "l_paren: (\n"
    "identifier: t1\n"
    "colon: :\n"
    "identifier: T\n"
    "comma: ,\n"
    "identifier: t2\n"
    "colon: :\n"
    "identifier: T\n"
    "r_paren: )\n"
    "l_brace: {\n"
    "r_brace: }\n"
  );

  // Parse the input and get split tokens info
  auto SplitTokens = parseAndGetSplitTokens(BufID);

  // Tokenize with fixing split tokens
  Tokens = tokenize(BufID, SplitTokens);
  assertTokens(Tokens,
     "identifier: infix\n"
     "kw_operator: operator\n"
     "oper_binary_spaced: ⊕\n"
     "l_brace: {\n"
     "identifier: associativity\n"
     "identifier: left\n"
     "identifier: precedence\n"
     "integer_literal: 100\n"
     "r_brace: }\n"
     "kw_func: func\n"
     "identifier: ⊕\n"
     "oper_binary_unspaced: <\n"
     "identifier: T\n"
     "oper_binary_unspaced: >\n"
     "l_paren: (\n"
     "identifier: t1\n"
     "colon: :\n"
     "identifier: T\n"
     "comma: ,\n"
     "identifier: t2\n"
     "colon: :\n"
     "identifier: T\n"
     "r_paren: )\n"
     "l_brace: {\n"
     "r_brace: }\n"
  );
}

<|endoftext|>


<commit_before>//===-- Timer.cpp -----------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/Core/Timer.h"

#include <map>
#include <vector>
#include <algorithm>

#include "lldb/Core/Stream.h"
#include "lldb/Host/Mutex.h"

#include <stdio.h>

using namespace lldb_private;

#define TIMER_INDENT_AMOUNT 2
static bool g_quiet = true;
uint32_t Timer::g_depth = 0;
uint32_t Timer::g_display_depth = 0;
FILE * Timer::g_file = NULL;
typedef std::vector<Timer *> TimerStack;
typedef std::map<const char *, uint64_t> CategoryMap;
static pthread_key_t g_key;

static Mutex &
GetCategoryMutex()
{
    static Mutex g_category_mutex(Mutex::eMutexTypeNormal);
    return g_category_mutex;
}

static CategoryMap &
GetCategoryMap()
{
    static CategoryMap g_category_map;
    return g_category_map;
}

static TimerStack *
GetTimerStackForCurrentThread ()
{
    void *timer_stack = ::pthread_getspecific (g_key);
    if (timer_stack == NULL)
    {
        ::pthread_setspecific (g_key, new TimerStack);
        timer_stack = ::pthread_getspecific (g_key);
    }
    return (TimerStack *)timer_stack;
}

void
ThreadSpecificCleanup (void *p)
{
    delete (TimerStack *)p;
}

void
Timer::SetQuiet (bool value)
{
    g_quiet = value;
}

void
Timer::Initialize ()
{
    Timer::g_file = stdout;
    ::pthread_key_create (&g_key, ThreadSpecificCleanup);

}

Timer::Timer (const char *category, const char *format, ...) :
    m_category (category),
    m_total_start (),
    m_timer_start (),
    m_total_ticks (0),
    m_timer_ticks (0)
{
    if (g_depth++ < g_display_depth)
    {
        if (g_quiet == false)
        {
            // Indent
            ::fprintf (g_file, "%*s", g_depth * TIMER_INDENT_AMOUNT, "");
            // Print formatted string
            va_list args;
            va_start (args, format);
            ::vfprintf (g_file, format, args);
            va_end (args);

            // Newline
            ::fprintf (g_file, "\n");
        }
        TimeValue start_time(TimeValue::Now());
        m_total_start = start_time;
        m_timer_start = start_time;
        TimerStack *stack = GetTimerStackForCurrentThread ();
        if (stack)
        {
            if (stack->empty() == false)
                stack->back()->ChildStarted (start_time);
            stack->push_back(this);
        }
    }
}

Timer::~Timer()
{
    if (m_total_start.IsValid())
    {
        TimeValue stop_time = TimeValue::Now();
        bool notify = false;
        if (m_total_start.IsValid())
        {
            m_total_ticks += (stop_time - m_total_start);
            m_total_start.Clear();
            notify = true;
        }
        if (m_timer_start.IsValid())
        {
            m_timer_ticks += (stop_time - m_timer_start);
            m_timer_start.Clear();
        }

        TimerStack *stack = GetTimerStackForCurrentThread ();
        if (stack)
        {
            assert (stack->back() == this);
            stack->pop_back();
            if (stack->empty() == false)
                stack->back()->ChildStopped(stop_time);
        }

        const uint64_t total_nsec_uint = GetTotalElapsedNanoSeconds();
        const uint64_t timer_nsec_uint = GetTimerElapsedNanoSeconds();
        const double total_nsec = total_nsec_uint;
        const double timer_nsec = timer_nsec_uint;

        if (g_quiet == false)
        {

            ::fprintf (g_file,
                       "%*s%.9f sec (%.9f sec)\n",
                       (g_depth - 1) *TIMER_INDENT_AMOUNT, "",
                       total_nsec / 1000000000.0,
                       timer_nsec / 1000000000.0);
        }

        // Keep total results for each category so we can dump results.
        Mutex::Locker locker (GetCategoryMutex());
        CategoryMap &category_map = GetCategoryMap();
        category_map[m_category] += timer_nsec_uint;
    }
    if (g_depth > 0)
        --g_depth;
}

uint64_t
Timer::GetTotalElapsedNanoSeconds()
{
    uint64_t total_ticks = m_total_ticks;

    // If we are currently running, we need to add the current
    // elapsed time of the running timer...
    if (m_total_start.IsValid())
        total_ticks += (TimeValue::Now() - m_total_start);

    return total_ticks;
}

uint64_t
Timer::GetTimerElapsedNanoSeconds()
{
    uint64_t timer_ticks = m_timer_ticks;

    // If we are currently running, we need to add the current
    // elapsed time of the running timer...
    if (m_timer_start.IsValid())
        timer_ticks += (TimeValue::Now() - m_timer_start);

    return timer_ticks;
}

void
Timer::ChildStarted (const TimeValue& start_time)
{
    if (m_timer_start.IsValid())
    {
        m_timer_ticks += (start_time - m_timer_start);
        m_timer_start.Clear();
    }
}

void
Timer::ChildStopped (const TimeValue& stop_time)
{
    if (!m_timer_start.IsValid())
        m_timer_start = stop_time;
}

void
Timer::SetDisplayDepth (uint32_t depth)
{
    g_display_depth = depth;
}

/* binary function predicate:
 * - returns whether a person is less than another person
 */
static bool
CategoryMapIteratorSortCriterion (const CategoryMap::const_iterator& lhs, const CategoryMap::const_iterator& rhs)
{
    return lhs->second > rhs->second;
}

void
Timer::ResetCategoryTimes ()
{
    Mutex::Locker locker (GetCategoryMutex());
    CategoryMap &category_map = GetCategoryMap();
    category_map.clear();
}

void
Timer::DumpCategoryTimes (Stream *s)
{
    Mutex::Locker locker (GetCategoryMutex());
    CategoryMap &category_map = GetCategoryMap();
    std::vector<CategoryMap::const_iterator> sorted_iterators;
    CategoryMap::const_iterator pos, end = category_map.end();
    for (pos = category_map.begin(); pos != end; ++pos)
    {
        sorted_iterators.push_back (pos);
    }
    std::sort (sorted_iterators.begin(), sorted_iterators.end(), CategoryMapIteratorSortCriterion);

    const size_t count = sorted_iterators.size();
    for (size_t i=0; i<count; ++i)
    {
        const double timer_nsec = sorted_iterators[i]->second;
        s->Printf("%.9f sec for %s\n", timer_nsec / 1000000000.0, sorted_iterators[i]->first);
    }
}
<commit_msg>Patch from Filipe Cabecinhas.<commit_after>//===-- Timer.cpp -----------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/Core/Timer.h"

#include <map>
#include <vector>
#include <algorithm>

#include "lldb/Core/Stream.h"
#include "lldb/Host/Mutex.h"

#include <stdio.h>

using namespace lldb_private;

#define TIMER_INDENT_AMOUNT 2
static bool g_quiet = true;
uint32_t Timer::g_depth = 0;
uint32_t Timer::g_display_depth = 0;
FILE * Timer::g_file = NULL;
typedef std::vector<Timer *> TimerStack;
typedef std::map<const char *, uint64_t> CategoryMap;
static pthread_key_t g_key;

static Mutex &
GetCategoryMutex()
{
    static Mutex g_category_mutex(Mutex::eMutexTypeNormal);
    return g_category_mutex;
}

static CategoryMap &
GetCategoryMap()
{
    static CategoryMap g_category_map;
    return g_category_map;
}

static TimerStack *
GetTimerStackForCurrentThread ()
{
    void *timer_stack = ::pthread_getspecific (g_key);
    if (timer_stack == NULL)
    {
        ::pthread_setspecific (g_key, new TimerStack);
        timer_stack = ::pthread_getspecific (g_key);
    }
    return (TimerStack *)timer_stack;
}

void
ThreadSpecificCleanup (void *p)
{
    delete (TimerStack *)p;
}

void
Timer::SetQuiet (bool value)
{
    g_quiet = value;
}

void
Timer::Initialize ()
{
    Timer::g_file = stdout;
    ::pthread_key_create (&g_key, ThreadSpecificCleanup);

}

Timer::Timer (const char *category, const char *format, ...) :
    m_category (category),
    m_total_start (),
    m_timer_start (),
    m_total_ticks (0),
    m_timer_ticks (0)
{
    if (g_depth++ < g_display_depth)
    {
        if (g_quiet == false)
        {
            // Indent
            ::fprintf (g_file, "%*s", g_depth * TIMER_INDENT_AMOUNT, "");
            // Print formatted string
            va_list args;
            va_start (args, format);
            ::vfprintf (g_file, format, args);
            va_end (args);

            // Newline
            ::fprintf (g_file, "\n");
        }
        TimeValue start_time(TimeValue::Now());
        m_total_start = start_time;
        m_timer_start = start_time;
        TimerStack *stack = GetTimerStackForCurrentThread ();
        if (stack)
        {
            if (stack->empty() == false)
                stack->back()->ChildStarted (start_time);
            stack->push_back(this);
        }
    }
}

Timer::~Timer()
{
    if (m_total_start.IsValid())
    {
        TimeValue stop_time = TimeValue::Now();
        if (m_total_start.IsValid())
        {
            m_total_ticks += (stop_time - m_total_start);
            m_total_start.Clear();
        }
        if (m_timer_start.IsValid())
        {
            m_timer_ticks += (stop_time - m_timer_start);
            m_timer_start.Clear();
        }

        TimerStack *stack = GetTimerStackForCurrentThread ();
        if (stack)
        {
            assert (stack->back() == this);
            stack->pop_back();
            if (stack->empty() == false)
                stack->back()->ChildStopped(stop_time);
        }

        const uint64_t total_nsec_uint = GetTotalElapsedNanoSeconds();
        const uint64_t timer_nsec_uint = GetTimerElapsedNanoSeconds();
        const double total_nsec = total_nsec_uint;
        const double timer_nsec = timer_nsec_uint;

        if (g_quiet == false)
        {

            ::fprintf (g_file,
                       "%*s%.9f sec (%.9f sec)\n",
                       (g_depth - 1) *TIMER_INDENT_AMOUNT, "",
                       total_nsec / 1000000000.0,
                       timer_nsec / 1000000000.0);
        }

        // Keep total results for each category so we can dump results.
        Mutex::Locker locker (GetCategoryMutex());
        CategoryMap &category_map = GetCategoryMap();
        category_map[m_category] += timer_nsec_uint;
    }
    if (g_depth > 0)
        --g_depth;
}

uint64_t
Timer::GetTotalElapsedNanoSeconds()
{
    uint64_t total_ticks = m_total_ticks;

    // If we are currently running, we need to add the current
    // elapsed time of the running timer...
    if (m_total_start.IsValid())
        total_ticks += (TimeValue::Now() - m_total_start);

    return total_ticks;
}

uint64_t
Timer::GetTimerElapsedNanoSeconds()
{
    uint64_t timer_ticks = m_timer_ticks;

    // If we are currently running, we need to add the current
    // elapsed time of the running timer...
    if (m_timer_start.IsValid())
        timer_ticks += (TimeValue::Now() - m_timer_start);

    return timer_ticks;
}

void
Timer::ChildStarted (const TimeValue& start_time)
{
    if (m_timer_start.IsValid())
    {
        m_timer_ticks += (start_time - m_timer_start);
        m_timer_start.Clear();
    }
}

void
Timer::ChildStopped (const TimeValue& stop_time)
{
    if (!m_timer_start.IsValid())
        m_timer_start = stop_time;
}

void
Timer::SetDisplayDepth (uint32_t depth)
{
    g_display_depth = depth;
}

/* binary function predicate:
 * - returns whether a person is less than another person
 */
static bool
CategoryMapIteratorSortCriterion (const CategoryMap::const_iterator& lhs, const CategoryMap::const_iterator& rhs)
{
    return lhs->second > rhs->second;
}

void
Timer::ResetCategoryTimes ()
{
    Mutex::Locker locker (GetCategoryMutex());
    CategoryMap &category_map = GetCategoryMap();
    category_map.clear();
}

void
Timer::DumpCategoryTimes (Stream *s)
{
    Mutex::Locker locker (GetCategoryMutex());
    CategoryMap &category_map = GetCategoryMap();
    std::vector<CategoryMap::const_iterator> sorted_iterators;
    CategoryMap::const_iterator pos, end = category_map.end();
    for (pos = category_map.begin(); pos != end; ++pos)
    {
        sorted_iterators.push_back (pos);
    }
    std::sort (sorted_iterators.begin(), sorted_iterators.end(), CategoryMapIteratorSortCriterion);

    const size_t count = sorted_iterators.size();
    for (size_t i=0; i<count; ++i)
    {
        const double timer_nsec = sorted_iterators[i]->second;
        s->Printf("%.9f sec for %s\n", timer_nsec / 1000000000.0, sorted_iterators[i]->first);
    }
}
<|endoftext|>