<commit_before>/*
    This file is part of KOrganizer.

    Copyright (c) 2004 Till Adam <adam@kde.org>
    Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net>

    This program 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 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "kotodoviewquicksearch.h"

#include "kotodoviewitem.h"
#include "kotodoview.h"

#include <libkcal/calendar.h>
#include <libkcal/calfilter.h>
#include <libkdepim/categoryhierarchyreader.h>

#include <korganizer/mainwindow.h>

#include "koprefs.h"

#include <kaction.h>
#include <klistviewsearchline.h>
#include <ktoolbar.h>

#include <qlayout.h>
#include <qlabel.h>
#include <qcombobox.h>
#include <qapplication.h>
#include <qregexp.h>
#include <qsizepolicy.h>
#include <qtimer.h>

using namespace KPIM;
using namespace KCal;

KAction *KOTodoListViewQuickSearch::action = 0;

KOTodoListViewQuickSearch::KOTodoListViewQuickSearch( QWidget *parent,
                                            QList<KListView*> listViews,
                                            KActionCollection *actionCollection,
                                            Calendar *calendar,
                                            const char *name )
  : KToolBar( parent, name ), mCategoryCombo( 0 ), mCalendar( calendar ),
    mQuickSearchLine( 0 )
{
  if ( !action ) {
    action = new KAction( i18n( "Reset To-do Quick Search" ),
                          QApplication::isRightToLeft() ? "clear_left" :
                          "locationbar_erase", 0, this, SLOT( reset() ),
                          actionCollection, "reset_quicksearch" );
    action->setWhatsThis( i18n( "Reset Quick Search\n"
                                  "Resets the quick search so that "
                                  "all to-dos are shown again." ) );
  }

  action->plug( this );

  boxLayout()->setSpacing( KDialog::spacingHint() );

  mSearchLabel = new QLabel( i18n("Sea&rch:"), this,
                              "kde toolbar widget" );

  mQuickSearchLine = new KOTodoListViewQuickSearchLine( this, listViews );
  setStretchableWidget( mQuickSearchLine );

  mSearchLabel->setBuddy( mQuickSearchLine );

  mCategoryLabel = new QLabel( i18n("&Category:"), this, "kde toolbar widget" );

  mCategoryCombo = new QComboBox( this, "quick search category combo box" );
  fillCategories();

  mCategoryCombo->setCurrentItem( 0 );
  connect( mCategoryCombo, SIGNAL ( activated( int ) ),
           this, SLOT( slotCategoryChanged( int ) ) );

  mCategoryLabel->setBuddy( mCategoryCombo );
}

KOTodoListViewQuickSearch::~KOTodoListViewQuickSearch()
{
}

bool KOTodoListViewQuickSearchLine::itemMatches(const Q3ListViewItem *item,
                                                const QString &s)
const
{
  while ( item ) {
    const Todo *todo = static_cast<const KOTodoViewItem *>( item )->todo();
    if ( ( mCategory.isNull() ||
           !todo->categories().grep( QRegExp( QString( "^" ) +
           QRegExp::escape( mCategory ) ) ).isEmpty() ) &&
           KListViewSearchLine::itemMatches(item, s) )
      return true;
    else
      item = item->parent(); // children of passed items also pass
  }
  return false;
}

//-----------------------------------------------------------------------------
void KOTodoListViewQuickSearch::reset()
{
  mQuickSearchLine->clear();
  mCategoryCombo->setCurrentItem( 0 );
  slotCategoryChanged( 0 );
}

void KOTodoListViewQuickSearch::slotCategoryChanged( int index )
{
  if ( index == 0 )
    mQuickSearchLine->setCategory( QString() );
  else
    mQuickSearchLine->setCategory( categoryList[index - 1] );
  mQuickSearchLine->updateSearch();
}

void KOTodoListViewQuickSearch::fillCategories()
{
  QString current = mCategoryCombo->currentItem() > 0 ?
    categoryList[mCategoryCombo->currentItem() - 1] : QString();
  QStringList categories;

  CalFilter *filter = mCalendar->filter();
  if ( filter && ( filter->criteria() & CalFilter::ShowCategories ) ) {
    categories = filter->categoryList();
    categories.sort();
  } else {
    categories = KOPrefs::instance()->mCustomCategories;
    QStringList filterCategories = filter->categoryList();
    categories.sort();
    filterCategories.sort();

    QStringList::Iterator it = categories.begin();
    QStringList::Iterator jt = filterCategories.begin();
    while ( it != categories.end() && jt != filterCategories.end() )
      if ( *it == *jt ) {
        QStringList::Iterator next = it;
        next++;
        categories.remove( it );
        jt++;
        it = next;
      } else if ( *it < *jt )
        it++;
      else if ( *it > *jt )
        jt++;
  }

  CategoryHierarchyReaderQComboBox( mCategoryCombo ).read( categories );
  mCategoryCombo->insertItem( i18n( "Any category" ), 0 );

  categoryList.resize( categories.count() );
  qCopy( categories.begin(), categories.end(), categoryList.begin() );

  if ( current.isNull() ) {
    mCategoryCombo->setCurrentItem( 0 );
  } else {
    for ( int i = 0; i < categoryList.count(); ++i )
      if ( categoryList[i] == current ) {
        mCategoryCombo->setCurrentItem( i + 1 );
        break;
      }
  }

}

void KOTodoListViewQuickSearch::setCalendar( Calendar *calendar )
{
  mCalendar = calendar;
  mQuickSearchLine->updateSearch();
}

void KOTodoListViewQuickSearch::resizeEvent( QResizeEvent *e )
{
  int w = width() - mCategoryCombo->sizeHint().width()
                  - mCategoryLabel->sizeHint().width()
                  - mSearchLabel->sizeHint().width();
  int halfw = width() / 2;

  if ( w < halfw ) {
    w += mCategoryLabel->sizeHint().width();
    mCategoryLabel->hide();
  } else
    mCategoryLabel->show();
  if ( w < halfw ) {
    w += mSearchLabel->sizeHint().width();
    mSearchLabel->hide();
  } else
    mSearchLabel->show();
  if ( w < halfw ) {
    slotCategoryChanged( 0 );
    mCategoryCombo->hide();
  } else {
    slotCategoryChanged( mCategoryCombo->currentItem() );
    mCategoryCombo->show();
  }

  KToolBar::resizeEvent( e );
}

void KOTodoListViewQuickSearch::showEvent( QShowEvent *e )
{
  connect( action, SIGNAL( activated() ), this, SLOT( reset() ) );

  KToolBar::showEvent( e );
}

void KOTodoListViewQuickSearch::hideEvent( QHideEvent *e )
{
  disconnect( action, SIGNAL( activated() ), this, SLOT( reset() ) );

  KToolBar::hideEvent( e );
}

KOTodoListViewQuickSearchContainer::KOTodoListViewQuickSearchContainer(
                               QWidget *parent,
                               QList<KListView*> listViews,
                               KActionCollection *actionCollection,
                               Calendar *calendar)
     : QWidget( parent ), mQuickSearch( new KOTodoListViewQuickSearch(
         this, listViews, actionCollection, calendar, "search toolbar" ) )
{
  setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
}

KOTodoListViewQuickSearchContainer::~KOTodoListViewQuickSearchContainer()
{
}

QSize KOTodoListViewQuickSearchContainer::sizeHint() const
{
  int width = KDialog::spacingHint();
  QList<QObject*> list = mQuickSearch->children();
  for ( QList<QObject*>::Iterator it = list.begin(); it != list.end(); ++it ) {
    QWidget *child = dynamic_cast<QWidget *>( *it );
    if ( child ) {
      width += child->sizeHint().width() + KDialog::spacingHint();
    }
  }

  return QSize( width, mQuickSearch->sizeHint().height() );
}

QSize KOTodoListViewQuickSearchContainer::minimumSizeHint() const
{
  return QSize( mQuickSearch->iconSize() +
                mQuickSearch->mQuickSearchLine->minimumSizeHint().width() +
                3 * KDialog::spacingHint(),
                mQuickSearch->minimumSizeHint().height() );
}

KOTodoListViewQuickSearch *KOTodoListViewQuickSearchContainer::quickSearch()
                                                                          const
{
  return mQuickSearch;
}

void KOTodoListViewQuickSearchContainer::resizeEvent ( QResizeEvent */*e*/ )
{
  mQuickSearch->setGeometry( QRect( QPoint( 0, 0 ), size() ) );
}

#include "kotodoviewquicksearch.moc"
<commit_msg>for now, it's unbearable with such a long stringfor now, it's unbearable with such a long stringfor now, it's unbearable with such a long stringfor now, it's unbearable with such a long stringfor now, it's unbearable with such a long stringfor now, it's unbearable with such a long stringfor now, it's unbearable with such a long stringfor now, it's unbearable with such a long string<commit_after>/*
    This file is part of KOrganizer.

    Copyright (c) 2004 Till Adam <adam@kde.org>
    Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net>

    This program 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 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "kotodoviewquicksearch.h"

#include "kotodoviewitem.h"
#include "kotodoview.h"

#include <libkcal/calendar.h>
#include <libkcal/calfilter.h>
#include <libkdepim/categoryhierarchyreader.h>

#include <korganizer/mainwindow.h>

#include "koprefs.h"

#include <kaction.h>
#include <klistviewsearchline.h>
#include <ktoolbar.h>

#include <qlayout.h>
#include <qlabel.h>
#include <qcombobox.h>
#include <qapplication.h>
#include <qregexp.h>
#include <qsizepolicy.h>
#include <qtimer.h>

using namespace KPIM;
using namespace KCal;

KAction *KOTodoListViewQuickSearch::action = 0;

KOTodoListViewQuickSearch::KOTodoListViewQuickSearch( QWidget *parent,
                                            QList<KListView*> listViews,
                                            KActionCollection *actionCollection,
                                            Calendar *calendar,
                                            const char *name )
  : KToolBar( parent, name ), mCategoryCombo( 0 ), mCalendar( calendar ),
    mQuickSearchLine( 0 )
{
  if ( !action ) {
    action = new KAction( i18n( "Reset" ),
                          QApplication::isRightToLeft() ? "clear_left" :
                          "locationbar_erase", 0, this, SLOT( reset() ),
                          actionCollection, "reset_quicksearch" );
    action->setWhatsThis( i18n( "Reset Quick Search\n"
                                  "Resets the quick search so that "
                                  "all to-dos are shown again." ) );
  }

  action->plug( this );

  boxLayout()->setSpacing( KDialog::spacingHint() );

  mSearchLabel = new QLabel( i18n("Sea&rch:"), this,
                              "kde toolbar widget" );

  mQuickSearchLine = new KOTodoListViewQuickSearchLine( this, listViews );
  setStretchableWidget( mQuickSearchLine );

  mSearchLabel->setBuddy( mQuickSearchLine );

  mCategoryLabel = new QLabel( i18n("&Category:"), this, "kde toolbar widget" );

  mCategoryCombo = new QComboBox( this, "quick search category combo box" );
  fillCategories();

  mCategoryCombo->setCurrentItem( 0 );
  connect( mCategoryCombo, SIGNAL ( activated( int ) ),
           this, SLOT( slotCategoryChanged( int ) ) );

  mCategoryLabel->setBuddy( mCategoryCombo );
}

KOTodoListViewQuickSearch::~KOTodoListViewQuickSearch()
{
}

bool KOTodoListViewQuickSearchLine::itemMatches(const Q3ListViewItem *item,
                                                const QString &s)
const
{
  while ( item ) {
    const Todo *todo = static_cast<const KOTodoViewItem *>( item )->todo();
    if ( ( mCategory.isNull() ||
           !todo->categories().grep( QRegExp( QString( "^" ) +
           QRegExp::escape( mCategory ) ) ).isEmpty() ) &&
           KListViewSearchLine::itemMatches(item, s) )
      return true;
    else
      item = item->parent(); // children of passed items also pass
  }
  return false;
}

//-----------------------------------------------------------------------------
void KOTodoListViewQuickSearch::reset()
{
  mQuickSearchLine->clear();
  mCategoryCombo->setCurrentItem( 0 );
  slotCategoryChanged( 0 );
}

void KOTodoListViewQuickSearch::slotCategoryChanged( int index )
{
  if ( index == 0 )
    mQuickSearchLine->setCategory( QString() );
  else
    mQuickSearchLine->setCategory( categoryList[index - 1] );
  mQuickSearchLine->updateSearch();
}

void KOTodoListViewQuickSearch::fillCategories()
{
  QString current = mCategoryCombo->currentItem() > 0 ?
    categoryList[mCategoryCombo->currentItem() - 1] : QString();
  QStringList categories;

  CalFilter *filter = mCalendar->filter();
  if ( filter && ( filter->criteria() & CalFilter::ShowCategories ) ) {
    categories = filter->categoryList();
    categories.sort();
  } else {
    categories = KOPrefs::instance()->mCustomCategories;
    QStringList filterCategories = filter->categoryList();
    categories.sort();
    filterCategories.sort();

    QStringList::Iterator it = categories.begin();
    QStringList::Iterator jt = filterCategories.begin();
    while ( it != categories.end() && jt != filterCategories.end() )
      if ( *it == *jt ) {
        QStringList::Iterator next = it;
        next++;
        categories.remove( it );
        jt++;
        it = next;
      } else if ( *it < *jt )
        it++;
      else if ( *it > *jt )
        jt++;
  }

  CategoryHierarchyReaderQComboBox( mCategoryCombo ).read( categories );
  mCategoryCombo->insertItem( i18n( "Any category" ), 0 );

  categoryList.resize( categories.count() );
  qCopy( categories.begin(), categories.end(), categoryList.begin() );

  if ( current.isNull() ) {
    mCategoryCombo->setCurrentItem( 0 );
  } else {
    for ( int i = 0; i < categoryList.count(); ++i )
      if ( categoryList[i] == current ) {
        mCategoryCombo->setCurrentItem( i + 1 );
        break;
      }
  }

}

void KOTodoListViewQuickSearch::setCalendar( Calendar *calendar )
{
  mCalendar = calendar;
  mQuickSearchLine->updateSearch();
}

void KOTodoListViewQuickSearch::resizeEvent( QResizeEvent *e )
{
  int w = width() - mCategoryCombo->sizeHint().width()
                  - mCategoryLabel->sizeHint().width()
                  - mSearchLabel->sizeHint().width();
  int halfw = width() / 2;

  if ( w < halfw ) {
    w += mCategoryLabel->sizeHint().width();
    mCategoryLabel->hide();
  } else
    mCategoryLabel->show();
  if ( w < halfw ) {
    w += mSearchLabel->sizeHint().width();
    mSearchLabel->hide();
  } else
    mSearchLabel->show();
  if ( w < halfw ) {
    slotCategoryChanged( 0 );
    mCategoryCombo->hide();
  } else {
    slotCategoryChanged( mCategoryCombo->currentItem() );
    mCategoryCombo->show();
  }

  KToolBar::resizeEvent( e );
}

void KOTodoListViewQuickSearch::showEvent( QShowEvent *e )
{
  connect( action, SIGNAL( activated() ), this, SLOT( reset() ) );

  KToolBar::showEvent( e );
}

void KOTodoListViewQuickSearch::hideEvent( QHideEvent *e )
{
  disconnect( action, SIGNAL( activated() ), this, SLOT( reset() ) );

  KToolBar::hideEvent( e );
}

KOTodoListViewQuickSearchContainer::KOTodoListViewQuickSearchContainer(
                               QWidget *parent,
                               QList<KListView*> listViews,
                               KActionCollection *actionCollection,
                               Calendar *calendar)
     : QWidget( parent ), mQuickSearch( new KOTodoListViewQuickSearch(
         this, listViews, actionCollection, calendar, "search toolbar" ) )
{
  setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
}

KOTodoListViewQuickSearchContainer::~KOTodoListViewQuickSearchContainer()
{
}

QSize KOTodoListViewQuickSearchContainer::sizeHint() const
{
  int width = KDialog::spacingHint();
  QList<QObject*> list = mQuickSearch->children();
  for ( QList<QObject*>::Iterator it = list.begin(); it != list.end(); ++it ) {
    QWidget *child = dynamic_cast<QWidget *>( *it );
    if ( child ) {
      width += child->sizeHint().width() + KDialog::spacingHint();
    }
  }

  return QSize( width, mQuickSearch->sizeHint().height() );
}

QSize KOTodoListViewQuickSearchContainer::minimumSizeHint() const
{
  return QSize( mQuickSearch->iconSize() +
                mQuickSearch->mQuickSearchLine->minimumSizeHint().width() +
                3 * KDialog::spacingHint(),
                mQuickSearch->minimumSizeHint().height() );
}

KOTodoListViewQuickSearch *KOTodoListViewQuickSearchContainer::quickSearch()
                                                                          const
{
  return mQuickSearch;
}

void KOTodoListViewQuickSearchContainer::resizeEvent ( QResizeEvent */*e*/ )
{
  mQuickSearch->setGeometry( QRect( QPoint( 0, 0 ), size() ) );
}

#include "kotodoviewquicksearch.moc"
<|endoftext|>


<commit_before>#pragma once

#include <cstdint>

namespace cu
{

template <typename T>
struct IntTraits;

namespace detail
{
    template <std::size_t nBits_,
              bool isSigned_>
    struct IntTraitsImpl
    {
        static constexpr std::size_t nBits = nBits_;
        static constexpr bool isSigned = isSigned_;
    };
}

template <> struct IntTraits<std::  int8_t> : detail::IntTraitsImpl< 8, true> {};
template <> struct IntTraits<std:: int16_t> : detail::IntTraitsImpl<16, true> {};
template <> struct IntTraits<std:: int32_t> : detail::IntTraitsImpl<32, true> {};
template <> struct IntTraits<std:: int64_t> : detail::IntTraitsImpl<64, true> {};
template <> struct IntTraits<std:: uint8_t> : detail::IntTraitsImpl< 8,false> {};
template <> struct IntTraits<std::uint16_t> : detail::IntTraitsImpl<16,false> {};
template <> struct IntTraits<std::uint32_t> : detail::IntTraitsImpl<32,false> {};
template <> struct IntTraits<std::uint64_t> : detail::IntTraitsImpl<64,false> {};

namespace detail
{
    template <std::size_t nBits,
              bool isSigned>
    struct BuildInIntImpl;

    template <typename T>
    struct TypeTrait { using type = T; };

    template <> struct BuildInIntImpl< 8, true> : TypeTrait<std::  int8_t> {};
    template <> struct BuildInIntImpl<16, true> : TypeTrait<std:: int16_t> {};
    template <> struct BuildInIntImpl<32, true> : TypeTrait<std:: int32_t> {};
    template <> struct BuildInIntImpl<64, true> : TypeTrait<std:: int64_t> {};
    template <> struct BuildInIntImpl< 8,false> : TypeTrait<std:: uint8_t> {};
    template <> struct BuildInIntImpl<16,false> : TypeTrait<std::uint16_t> {};
    template <> struct BuildInIntImpl<32,false> : TypeTrait<std::uint32_t> {};
    template <> struct BuildInIntImpl<64,false> : TypeTrait<std::uint64_t> {};
}

template <std::size_t nBits,
          bool isSigned = true>
using BuildInInt = typename detail::BuildInIntImpl<nBits,isSigned>::type;

template <typename IntT>
using DoubleSizeInt = BuildInInt<IntTraits<IntT>::nBits*2,IntTraits<IntT>::isSigned>;

} // namespace cu
<commit_msg>Fix: Included missing header.<commit_after>#pragma once

#include <cstddef>
#include <cstdint>

namespace cu
{

template <typename T>
struct IntTraits;

namespace detail
{
    template <std::size_t nBits_,
              bool isSigned_>
    struct IntTraitsImpl
    {
        static constexpr std::size_t nBits = nBits_;
        static constexpr bool isSigned = isSigned_;
    };
}

template <> struct IntTraits<std::  int8_t> : detail::IntTraitsImpl< 8, true> {};
template <> struct IntTraits<std:: int16_t> : detail::IntTraitsImpl<16, true> {};
template <> struct IntTraits<std:: int32_t> : detail::IntTraitsImpl<32, true> {};
template <> struct IntTraits<std:: int64_t> : detail::IntTraitsImpl<64, true> {};
template <> struct IntTraits<std:: uint8_t> : detail::IntTraitsImpl< 8,false> {};
template <> struct IntTraits<std::uint16_t> : detail::IntTraitsImpl<16,false> {};
template <> struct IntTraits<std::uint32_t> : detail::IntTraitsImpl<32,false> {};
template <> struct IntTraits<std::uint64_t> : detail::IntTraitsImpl<64,false> {};

namespace detail
{
    template <std::size_t nBits,
              bool isSigned>
    struct BuildInIntImpl;

    template <typename T>
    struct TypeTrait { using type = T; };

    template <> struct BuildInIntImpl< 8, true> : TypeTrait<std::  int8_t> {};
    template <> struct BuildInIntImpl<16, true> : TypeTrait<std:: int16_t> {};
    template <> struct BuildInIntImpl<32, true> : TypeTrait<std:: int32_t> {};
    template <> struct BuildInIntImpl<64, true> : TypeTrait<std:: int64_t> {};
    template <> struct BuildInIntImpl< 8,false> : TypeTrait<std:: uint8_t> {};
    template <> struct BuildInIntImpl<16,false> : TypeTrait<std::uint16_t> {};
    template <> struct BuildInIntImpl<32,false> : TypeTrait<std::uint32_t> {};
    template <> struct BuildInIntImpl<64,false> : TypeTrait<std::uint64_t> {};
}

template <std::size_t nBits,
          bool isSigned = true>
using BuildInInt = typename detail::BuildInIntImpl<nBits,isSigned>::type;

template <typename IntT>
using DoubleSizeInt = BuildInInt<IntTraits<IntT>::nBits*2,IntTraits<IntT>::isSigned>;

} // namespace cu
<|endoftext|>


<commit_before>//===-- Metadata.cpp - Implement Metadata classes -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Metadata classes.
//
//===----------------------------------------------------------------------===//

#include "LLVMContextImpl.h"
#include "llvm/Metadata.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "SymbolTableListTraitsImpl.h"
using namespace llvm;

//===----------------------------------------------------------------------===//
//MetadataBase implementation
//

/// resizeOperands - Metadata keeps track of other metadata uses using
/// OperandList. Resize this list to hold anticipated number of metadata
/// operands.
void MetadataBase::resizeOperands(unsigned NumOps) {
  unsigned e = getNumOperands();
  if (NumOps == 0) {
    NumOps = e*2;
    if (NumOps < 2) NumOps = 2;
  } else if (NumOps > NumOperands) {
    // No resize needed.
    if (ReservedSpace >= NumOps) return;
  } else if (NumOps == NumOperands) {
    if (ReservedSpace == NumOps) return;
  } else {
    return;
  }

  ReservedSpace = NumOps;
  Use *OldOps = OperandList;
  Use *NewOps = allocHungoffUses(NumOps);
  std::copy(OldOps, OldOps + e, NewOps);
  OperandList = NewOps;
  if (OldOps) Use::zap(OldOps, OldOps + e, true);
}
//===----------------------------------------------------------------------===//
//MDString implementation
//
MDString *MDString::get(LLVMContext &Context, const StringRef &Str) {
  LLVMContextImpl *pImpl = Context.pImpl;
  sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
  StringMapEntry<MDString *> &Entry =
    pImpl->MDStringCache.GetOrCreateValue(Str);
  MDString *&S = Entry.getValue();
  if (!S) S = new MDString(Context, Entry.getKeyData(),
                           Entry.getKeyLength());

  return S;
}

//===----------------------------------------------------------------------===//
//MDNode implementation
//
MDNode::MDNode(LLVMContext &C, Value*const* Vals, unsigned NumVals)
  : MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) {
  NumOperands = 0;
  resizeOperands(NumVals);
  for (unsigned i = 0; i != NumVals; ++i) {
    // Only record metadata uses.
    if (MetadataBase *MB = dyn_cast_or_null<MetadataBase>(Vals[i]))
      OperandList[NumOperands++] = MB;
    else if(Vals[i] &&
            Vals[i]->getType()->getTypeID() == Type::MetadataTyID)
      OperandList[NumOperands++] = Vals[i];
    Node.push_back(ElementVH(Vals[i], this));
  }
}

void MDNode::Profile(FoldingSetNodeID &ID) const {
  for (const_elem_iterator I = elem_begin(), E = elem_end(); I != E; ++I)
    ID.AddPointer(*I);
}

MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) {
  LLVMContextImpl *pImpl = Context.pImpl;
  FoldingSetNodeID ID;
  for (unsigned i = 0; i != NumVals; ++i)
    ID.AddPointer(Vals[i]);

  // FIXME: MDNode uniquing disabled temporarily.
#ifndef ENABLE_MDNODE_UNIQUING
  return new MDNode(Context, Vals, NumVals);
#endif

  pImpl->ConstantsLock.reader_acquire();
  void *InsertPoint;
  MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
  pImpl->ConstantsLock.reader_release();

  if (!N) {
    sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
    N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
    if (!N) {
      // InsertPoint will have been set by the FindNodeOrInsertPos call.
      N = new MDNode(Context, Vals, NumVals);
      pImpl->MDNodeSet.InsertNode(N, InsertPoint);
    }
  }

  return N;
}

/// dropAllReferences - Remove all uses and clear node vector.
void MDNode::dropAllReferences() {
  User::dropAllReferences();
  Node.clear();
}

MDNode::~MDNode() {
  // FIXME: MDNode uniquing disabled temporarily.
#ifdef ENABLE_MDNODE_UNIQUING
  getType()->getContext().pImpl->MDNodeSet.RemoveNode(this);
#endif
  dropAllReferences();
}

// Replace value from this node's element list.
void MDNode::replaceElement(Value *From, Value *To) {
  // FIXME: MDNode uniquing disabled temporarily.
#ifndef ENABLE_MDNODE_UNIQUING
  if (From == To || !getType())
    return;

  for (SmallVector<ElementVH, 4>::iterator I = Node.begin(),
         E = Node.end(); I != E; ++I)
    if (*I && *I == From)
      *I = ElementVH(To, this);
  return;
#endif

  if (From == To || !getType())
    return;
  LLVMContext &Context = getType()->getContext();
  LLVMContextImpl *pImpl = Context.pImpl;

  // Find value. This is a linear search, do something if it consumes
  // lot of time. It is possible that to have multiple instances of
  // From in this MDNode's element list.
  SmallVector<unsigned, 4> Indexes;
  unsigned Index = 0;
  for (SmallVector<ElementVH, 4>::iterator I = Node.begin(),
         E = Node.end(); I != E; ++I, ++Index) {
    Value *V = *I;
    if (V && V == From)
      Indexes.push_back(Index);
  }

  if (Indexes.empty())
    return;

  // Remove "this" from the context map.
  {
    sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
    pImpl->MDNodeSet.RemoveNode(this);
  }

  // MDNode only lists metadata elements in operand list, because MDNode
  // used by MDNode is considered a valid use. However on the side, MDNode
  // using a non-metadata value is not considered a "use" of non-metadata
  // value.
  SmallVector<unsigned, 4> OpIndexes;
  unsigned OpIndex = 0;
  for (User::op_iterator OI = op_begin(), OE = op_end();
       OI != OE; ++OI, OpIndex++) {
    if (*OI == From)
      OpIndexes.push_back(OpIndex);
  }
  if (MetadataBase *MDTo = dyn_cast_or_null<MetadataBase>(To)) {
    for (SmallVector<unsigned, 4>::iterator OI = OpIndexes.begin(),
           OE = OpIndexes.end(); OI != OE; ++OI)
      setOperand(*OI, MDTo);
  } else {
    for (SmallVector<unsigned, 4>::iterator OI = OpIndexes.begin(),
           OE = OpIndexes.end(); OI != OE; ++OI)
      setOperand(*OI, 0);
  }

  // Replace From element(s) in place.
  for (SmallVector<unsigned, 4>::iterator I = Indexes.begin(), E = Indexes.end();
       I != E; ++I) {
    unsigned Index = *I;
    Node[Index] = ElementVH(To, this);
  }

  // Insert updated "this" into the context's folding node set.
  // If a node with same element list already exist then before inserting
  // updated "this" into the folding node set, replace all uses of existing
  // node with updated "this" node.
  FoldingSetNodeID ID;
  Profile(ID);
  pImpl->ConstantsLock.reader_acquire();
  void *InsertPoint;
  MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
  pImpl->ConstantsLock.reader_release();

  if (N) {
    N->replaceAllUsesWith(this);
    delete N;
    N = 0;
  }

  {
    sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
    N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
    if (!N) {
      // InsertPoint will have been set by the FindNodeOrInsertPos call.
      N = this;
      pImpl->MDNodeSet.InsertNode(N, InsertPoint);
    }
  }
}

//===----------------------------------------------------------------------===//
//NamedMDNode implementation
//
NamedMDNode::NamedMDNode(LLVMContext &C, const Twine &N,
                         MetadataBase*const* MDs,
                         unsigned NumMDs, Module *ParentModule)
  : MetadataBase(Type::getMetadataTy(C), Value::NamedMDNodeVal), Parent(0) {
  setName(N);
  NumOperands = 0;
  resizeOperands(NumMDs);

  for (unsigned i = 0; i != NumMDs; ++i) {
    if (MDs[i])
      OperandList[NumOperands++] = MDs[i];
    Node.push_back(WeakMetadataVH(MDs[i]));
  }
  if (ParentModule)
    ParentModule->getNamedMDList().push_back(this);
}

NamedMDNode *NamedMDNode::Create(const NamedMDNode *NMD, Module *M) {
  assert (NMD && "Invalid source NamedMDNode!");
  SmallVector<MetadataBase *, 4> Elems;
  for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i)
    Elems.push_back(NMD->getElement(i));
  return new NamedMDNode(NMD->getContext(), NMD->getName().data(),
                         Elems.data(), Elems.size(), M);
}

/// eraseFromParent - Drop all references and remove the node from parent
/// module.
void NamedMDNode::eraseFromParent() {
  getParent()->getNamedMDList().erase(this);
}

/// dropAllReferences - Remove all uses and clear node vector.
void NamedMDNode::dropAllReferences() {
  User::dropAllReferences();
  Node.clear();
}

NamedMDNode::~NamedMDNode() {
  dropAllReferences();
}
<commit_msg>Enable MDNode uniquing.<commit_after>//===-- Metadata.cpp - Implement Metadata classes -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Metadata classes.
//
//===----------------------------------------------------------------------===//

#include "LLVMContextImpl.h"
#include "llvm/Metadata.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "SymbolTableListTraitsImpl.h"
using namespace llvm;

//===----------------------------------------------------------------------===//
//MetadataBase implementation
//

/// resizeOperands - Metadata keeps track of other metadata uses using
/// OperandList. Resize this list to hold anticipated number of metadata
/// operands.
void MetadataBase::resizeOperands(unsigned NumOps) {
  unsigned e = getNumOperands();
  if (NumOps == 0) {
    NumOps = e*2;
    if (NumOps < 2) NumOps = 2;
  } else if (NumOps > NumOperands) {
    // No resize needed.
    if (ReservedSpace >= NumOps) return;
  } else if (NumOps == NumOperands) {
    if (ReservedSpace == NumOps) return;
  } else {
    return;
  }

  ReservedSpace = NumOps;
  Use *OldOps = OperandList;
  Use *NewOps = allocHungoffUses(NumOps);
  std::copy(OldOps, OldOps + e, NewOps);
  OperandList = NewOps;
  if (OldOps) Use::zap(OldOps, OldOps + e, true);
}
//===----------------------------------------------------------------------===//
//MDString implementation
//
MDString *MDString::get(LLVMContext &Context, const StringRef &Str) {
  LLVMContextImpl *pImpl = Context.pImpl;
  sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
  StringMapEntry<MDString *> &Entry =
    pImpl->MDStringCache.GetOrCreateValue(Str);
  MDString *&S = Entry.getValue();
  if (!S) S = new MDString(Context, Entry.getKeyData(),
                           Entry.getKeyLength());

  return S;
}

//===----------------------------------------------------------------------===//
//MDNode implementation
//
MDNode::MDNode(LLVMContext &C, Value*const* Vals, unsigned NumVals)
  : MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) {
  NumOperands = 0;
  resizeOperands(NumVals);
  for (unsigned i = 0; i != NumVals; ++i) {
    // Only record metadata uses.
    if (MetadataBase *MB = dyn_cast_or_null<MetadataBase>(Vals[i]))
      OperandList[NumOperands++] = MB;
    else if(Vals[i] &&
            Vals[i]->getType()->getTypeID() == Type::MetadataTyID)
      OperandList[NumOperands++] = Vals[i];
    Node.push_back(ElementVH(Vals[i], this));
  }
}

void MDNode::Profile(FoldingSetNodeID &ID) const {
  for (const_elem_iterator I = elem_begin(), E = elem_end(); I != E; ++I)
    ID.AddPointer(*I);
}

MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) {
  LLVMContextImpl *pImpl = Context.pImpl;
  FoldingSetNodeID ID;
  for (unsigned i = 0; i != NumVals; ++i)
    ID.AddPointer(Vals[i]);

  pImpl->ConstantsLock.reader_acquire();
  void *InsertPoint;
  MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
  pImpl->ConstantsLock.reader_release();

  if (!N) {
    sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
    N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
    if (!N) {
      // InsertPoint will have been set by the FindNodeOrInsertPos call.
      N = new MDNode(Context, Vals, NumVals);
      pImpl->MDNodeSet.InsertNode(N, InsertPoint);
    }
  }

  return N;
}

/// dropAllReferences - Remove all uses and clear node vector.
void MDNode::dropAllReferences() {
  User::dropAllReferences();
  Node.clear();
}

MDNode::~MDNode() {
  getType()->getContext().pImpl->MDNodeSet.RemoveNode(this);
  dropAllReferences();
}

// Replace value from this node's element list.
void MDNode::replaceElement(Value *From, Value *To) {
  if (From == To || !getType())
    return;
  LLVMContext &Context = getType()->getContext();
  LLVMContextImpl *pImpl = Context.pImpl;

  // Find value. This is a linear search, do something if it consumes
  // lot of time. It is possible that to have multiple instances of
  // From in this MDNode's element list.
  SmallVector<unsigned, 4> Indexes;
  unsigned Index = 0;
  for (SmallVector<ElementVH, 4>::iterator I = Node.begin(),
         E = Node.end(); I != E; ++I, ++Index) {
    Value *V = *I;
    if (V && V == From)
      Indexes.push_back(Index);
  }

  if (Indexes.empty())
    return;

  // Remove "this" from the context map.
  {
    sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
    pImpl->MDNodeSet.RemoveNode(this);
  }

  // MDNode only lists metadata elements in operand list, because MDNode
  // used by MDNode is considered a valid use. However on the side, MDNode
  // using a non-metadata value is not considered a "use" of non-metadata
  // value.
  SmallVector<unsigned, 4> OpIndexes;
  unsigned OpIndex = 0;
  for (User::op_iterator OI = op_begin(), OE = op_end();
       OI != OE; ++OI, OpIndex++) {
    if (*OI == From)
      OpIndexes.push_back(OpIndex);
  }
  if (MetadataBase *MDTo = dyn_cast_or_null<MetadataBase>(To)) {
    for (SmallVector<unsigned, 4>::iterator OI = OpIndexes.begin(),
           OE = OpIndexes.end(); OI != OE; ++OI)
      setOperand(*OI, MDTo);
  } else {
    for (SmallVector<unsigned, 4>::iterator OI = OpIndexes.begin(),
           OE = OpIndexes.end(); OI != OE; ++OI)
      setOperand(*OI, 0);
  }

  // Replace From element(s) in place.
  for (SmallVector<unsigned, 4>::iterator I = Indexes.begin(), E = Indexes.end();
       I != E; ++I) {
    unsigned Index = *I;
    Node[Index] = ElementVH(To, this);
  }

  // Insert updated "this" into the context's folding node set.
  // If a node with same element list already exist then before inserting
  // updated "this" into the folding node set, replace all uses of existing
  // node with updated "this" node.
  FoldingSetNodeID ID;
  Profile(ID);
  pImpl->ConstantsLock.reader_acquire();
  void *InsertPoint;
  MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
  pImpl->ConstantsLock.reader_release();

  if (N) {
    N->replaceAllUsesWith(this);
    delete N;
    N = 0;
  }

  {
    sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
    N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
    if (!N) {
      // InsertPoint will have been set by the FindNodeOrInsertPos call.
      N = this;
      pImpl->MDNodeSet.InsertNode(N, InsertPoint);
    }
  }
}

//===----------------------------------------------------------------------===//
//NamedMDNode implementation
//
NamedMDNode::NamedMDNode(LLVMContext &C, const Twine &N,
                         MetadataBase*const* MDs,
                         unsigned NumMDs, Module *ParentModule)
  : MetadataBase(Type::getMetadataTy(C), Value::NamedMDNodeVal), Parent(0) {
  setName(N);
  NumOperands = 0;
  resizeOperands(NumMDs);

  for (unsigned i = 0; i != NumMDs; ++i) {
    if (MDs[i])
      OperandList[NumOperands++] = MDs[i];
    Node.push_back(WeakMetadataVH(MDs[i]));
  }
  if (ParentModule)
    ParentModule->getNamedMDList().push_back(this);
}

NamedMDNode *NamedMDNode::Create(const NamedMDNode *NMD, Module *M) {
  assert (NMD && "Invalid source NamedMDNode!");
  SmallVector<MetadataBase *, 4> Elems;
  for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i)
    Elems.push_back(NMD->getElement(i));
  return new NamedMDNode(NMD->getContext(), NMD->getName().data(),
                         Elems.data(), Elems.size(), M);
}

/// eraseFromParent - Drop all references and remove the node from parent
/// module.
void NamedMDNode::eraseFromParent() {
  getParent()->getNamedMDList().erase(this);
}

/// dropAllReferences - Remove all uses and clear node vector.
void NamedMDNode::dropAllReferences() {
  User::dropAllReferences();
  Node.clear();
}

NamedMDNode::~NamedMDNode() {
  dropAllReferences();
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2013-2017 Baptiste Wicht.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "cpp_utils/assert.hpp"
#include "cpp_utils/string.hpp"

#include "writer.hpp"
#include "console.hpp"

budget::console_writer::console_writer(std::ostream& os) : os(os) {}

budget::writer& budget::console_writer::operator<<(const std::string& value){
    os << format(value);

    return *this;
}

budget::writer& budget::console_writer::operator<<(const double& value){
    os << value;

    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::money& m) {
    os << m;

    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::month& m) {
    os << m.as_short_string();

    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::year& y) {
    os << y.value;

    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::end_of_line_t&) {
    os << std::endl;

    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::p_begin_t&) {
    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::p_end_t&) {
    os << std::endl;

    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::title_begin_t&) {
    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::title_end_t&) {
    os << std::endl << std::endl;

    return *this;
}

void budget::console_writer::display_table(std::vector<std::string>& columns, std::vector<std::vector<std::string>>& contents, size_t groups, std::vector<size_t> lines, size_t left){
    cpp_assert(groups > 0, "There must be at least 1 group");

    for(auto& row : contents){
        for(auto& cell : row){
            cpp::trim(cell);
        }
    }

    std::vector<size_t> widths;
    std::vector<size_t> header_widths;

    if(!contents.size()){
        for(auto& column : columns){
            widths.push_back(rsize(column));
        }
    } else {
        auto& first = contents[0];

        widths.assign(first.size(), 0);

        for(auto& row : contents){
            for(size_t i = 0; i < row.size(); ++i){
                widths[i] = std::max(widths[i], rsize(row[i]) + 1);
            }
        }
    }

    cpp_assert(widths.size() == groups * columns.size(), "Widths incorrectly computed");

    // Display the header

    if (left) {
        os << std::string(left, ' ');
    }

    for(size_t i = 0; i < columns.size(); ++i){
        auto& column = columns[i];

        size_t width = 0;
        for(size_t j = i * groups; j < (i + 1) * groups; ++j){
            width += widths[j];
        }

        width = std::max(width, rsize(column));
        header_widths.push_back(width + (i < columns.size() - 1 && rsize(column) >= width ? 1 : 0));

        //The last space is not underlined
        --width;

        os << format_code(4, 0, 7) << column << (width > rsize(column) ? std::string(width - rsize(column), ' ') : "") << format_code(0, 0, 7);

        //The very last column has no trailing space

        if(i < columns.size() - 1){
            os << " ";
        }
    }

    os << std::endl;

    // Display the contents

    for(size_t i = 0; i < contents.size(); ++i){
        if(left){
            os << std::string(left, ' ');
        }

        auto& row = contents[i];

        bool underline = std::find(lines.begin(), lines.end(), i) != lines.end();

        for(size_t j = 0; j < row.size(); j += groups){
            size_t acc_width = 0;

            //First columns of the group
            for(size_t k = 0; k < groups - 1; ++k){
                auto column = j + k;

                std::string value = format(row[column]);

                acc_width += widths[column];

                if (underline) {
                    os << format_code(4, 0, 7);
                    os << value;
                    os << std::string(widths[column] - rsize(value) - 1, ' ');
                    os << format_code(0, 0, 7);
                } else {
                    os << value;
                    os << std::string(widths[column] - rsize(value) - 1, ' ');
                }

                os << ' ';
            }

            //The last column of the group

            auto last_column = j + (groups - 1);
            auto width = widths[last_column];
            acc_width += width;

            //Pad with spaces to fit the header column width

            if(header_widths[j / groups] > acc_width){
                width += header_widths[j / groups] - acc_width;
            } else if(last_column == row.size() - 1){
                --width;
            }

            auto value = format(row[last_column]);

            auto missing = width - rsize(row[last_column]);

            std::string fill_string;
            if (missing > 1){
                fill_string = std::string(missing - 1, ' ');
            }

            if (underline) {
                os << format_code(4, 0, 7);
                os << value;
                os << fill_string;
                os << format_code(0, 0, 7);
            } else {
                os << value;
                os << fill_string;
            }

            if (missing > 0) {
                if (j == row.size() - 1 && underline) {
                    os << format_code(4, 0, 7);
                    os << ' ';
                    os << format_code(0, 0, 7);
                } else {
                    os << ' ';
                }
            }
        }

        os << format_code(0, 0, 7) << std::endl;
    }
}
<commit_msg>Fix support for vertical table<commit_after>//=======================================================================
// Copyright (c) 2013-2017 Baptiste Wicht.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "cpp_utils/assert.hpp"
#include "cpp_utils/string.hpp"

#include "writer.hpp"
#include "console.hpp"

budget::console_writer::console_writer(std::ostream& os) : os(os) {}

budget::writer& budget::console_writer::operator<<(const std::string& value){
    os << format(value);

    return *this;
}

budget::writer& budget::console_writer::operator<<(const double& value){
    os << value;

    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::money& m) {
    os << m;

    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::month& m) {
    os << m.as_short_string();

    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::year& y) {
    os << y.value;

    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::end_of_line_t&) {
    os << std::endl;

    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::p_begin_t&) {
    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::p_end_t&) {
    os << std::endl;

    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::title_begin_t&) {
    return *this;
}

budget::writer& budget::console_writer::operator<<(const budget::title_end_t&) {
    os << std::endl << std::endl;

    return *this;
}

void budget::console_writer::display_table(std::vector<std::string>& columns, std::vector<std::vector<std::string>>& contents, size_t groups, std::vector<size_t> lines, size_t left){
    cpp_assert(groups > 0, "There must be at least 1 group");
    cpp_assert(contents.size() || columns.size(), "There must be at least some columns or contents");

    for(auto& row : contents){
        for(auto& cell : row){
            cpp::trim(cell);
        }
    }

    std::vector<size_t> widths;
    std::vector<size_t> header_widths;

    if(!contents.size()){
        for(auto& column : columns){
            widths.push_back(rsize(column));
        }
    } else {
        auto& first = contents[0];

        widths.assign(first.size(), 0);

        for(auto& row : contents){
            for(size_t i = 0; i < row.size(); ++i){
                widths[i] = std::max(widths[i], rsize(row[i]) + 1);
            }
        }
    }

    cpp_assert(widths.size() == groups * columns.size(), "Widths incorrectly computed");

    // Display the header

    if (left) {
        os << std::string(left, ' ');
    }

    if (columns.empty()) {
        const size_t C = contents.front().size();
        for (size_t i = 0; i < C; ++i) {
            size_t width = 0;
            for (size_t j = i * groups; j < (i + 1) * groups; ++j) {
                width += widths[j];
            }

            header_widths.push_back(width + (i < C - 1 ? 1 : 0));
        }
    } else {
        for (size_t i = 0; i < columns.size(); ++i) {
            auto& column = columns[i];

            size_t width = 0;
            for (size_t j = i * groups; j < (i + 1) * groups; ++j) {
                width += widths[j];
            }

            width = std::max(width, rsize(column));
            header_widths.push_back(width + (i < columns.size() - 1 && rsize(column) >= width ? 1 : 0));

            //The last space is not underlined
            --width;

            os << format_code(4, 0, 7) << column << (width > rsize(column) ? std::string(width - rsize(column), ' ') : "") << format_code(0, 0, 7);

            //The very last column has no trailing space

            if (i < columns.size() - 1) {
                os << " ";
            }
        }
    }

    os << std::endl;

    // Display the contents

    for(size_t i = 0; i < contents.size(); ++i){
        if(left){
            os << std::string(left, ' ');
        }

        auto& row = contents[i];

        bool underline = std::find(lines.begin(), lines.end(), i) != lines.end();

        for(size_t j = 0; j < row.size(); j += groups){
            size_t acc_width = 0;

            //First columns of the group
            for(size_t k = 0; k < groups - 1; ++k){
                auto column = j + k;

                std::string value = format(row[column]);

                acc_width += widths[column];

                if (underline) {
                    os << format_code(4, 0, 7);
                    os << value;
                    os << std::string(widths[column] - rsize(value) - 1, ' ');
                    os << format_code(0, 0, 7);
                } else {
                    os << value;
                    os << std::string(widths[column] - rsize(value) - 1, ' ');
                }

                os << ' ';
            }

            //The last column of the group

            auto last_column = j + (groups - 1);
            auto width = widths[last_column];
            acc_width += width;

            //Pad with spaces to fit the header column width

            if(header_widths[j / groups] > acc_width){
                width += header_widths[j / groups] - acc_width;
            } else if(last_column == row.size() - 1){
                --width;
            }

            auto value = format(row[last_column]);

            auto missing = width - rsize(row[last_column]);

            std::string fill_string;
            if (missing > 1){
                fill_string = std::string(missing - 1, ' ');
            }

            if (underline) {
                os << format_code(4, 0, 7);
                os << value;
                os << fill_string;
                os << format_code(0, 0, 7);
            } else {
                os << value;
                os << fill_string;
            }

            if (missing > 0) {
                if (j == row.size() - 1 && underline) {
                    os << format_code(4, 0, 7);
                    os << ' ';
                    os << format_code(0, 0, 7);
                } else {
                    os << ' ';
                }
            }
        }

        os << format_code(0, 0, 7) << std::endl;
    }
}
<|endoftext|>


<commit_before>/*
***************************************
*   Asylum3D @ 2014-12-17
***************************************
*/

#ifndef __ASYLUM3D_HPP__
#define __ASYLUM3D_HPP__

/* Asylum Namespace */
namespace asy {

/***********/
/* VertexN */
/***********/
struct vertex_n
{
    vec3d_t pos;
    vec3d_t nrm;
};

/************/
/* VertexT2 */
/************/
struct vertex_t2
{
    vec3d_t pos;
    vec2d_t tex;
};

/************/
/* VertexT3 */
/************/
struct vertex_t3
{
    vec3d_t pos;
    vec3d_t tex;
};

/*************/
/* VertexNT2 */
/*************/
struct vertex_nt2
{
    vec3d_t pos;
    vec3d_t nrm;
    vec2d_t tex;
};

/*************/
/* VertexNT3 */
/*************/
struct vertex_nt3
{
    vec3d_t pos;
    vec3d_t nrm;
    vec3d_t tex;
};

}   /* namespace */

#endif  /* __ASYLUM3D_HPP__ */
<commit_msg>Asylum: 增加效果和材质接口<commit_after>/*
***************************************
*   Asylum3D @ 2014-12-17
***************************************
*/

#ifndef __ASYLUM3D_HPP__
#define __ASYLUM3D_HPP__

/* Asylum Namespace */
namespace asy {

/***********/
/* VertexN */
/***********/
struct vertex_n
{
    vec3d_t pos;
    vec3d_t nrm;
};

/************/
/* VertexT2 */
/************/
struct vertex_t2
{
    vec3d_t pos;
    vec2d_t tex;
};

/************/
/* VertexT3 */
/************/
struct vertex_t3
{
    vec3d_t pos;
    vec3d_t tex;
};

/*************/
/* VertexNT2 */
/*************/
struct vertex_nt2
{
    vec3d_t pos;
    vec3d_t nrm;
    vec2d_t tex;
};

/*************/
/* VertexNT3 */
/*************/
struct vertex_nt3
{
    vec3d_t pos;
    vec3d_t nrm;
    vec3d_t tex;
};

/***************/
/* Effect Port */
/***************/
class effect_i : public asylum
{
public:
    /* ================= */
    virtual ~effect_i () {}

public:
    /* ==================== */
    virtual void enter () = 0;

    /* ==================== */
    virtual void leave () = 0;
};

/*****************/
/* Material Port */
/*****************/
class material_i : public asylum
{
public:
    /* =================== */
    virtual ~material_i () {}

public:
    /* ===================== */
    virtual void commit () = 0;
};

}   /* namespace */

#endif  /* __ASYLUM3D_HPP__ */
<|endoftext|>


<commit_before>#include <chrono>
#include <gflags/gflags.h>
#include <iostream>
#include <stdio.h>

#include "lang/interpreter/language_evaluation.h"
#include "lang/interpreter/source_util.h"
#include "lang/interpreter/steinlang_parser.h"
#include "util/file_io.h"
#include "util/optional.h"

DEFINE_bool(debug_print_parse_trees, false, "");
DEFINE_bool(debug_print_syntax_tree, false, "");
DEFINE_bool(debug_print_steps, false,
            "If true, print verbose evaluation state after each step. This "
            "slows down execution significantly.");
DEFINE_bool(debug_print_timing, false, "");

namespace {

std::string ReadStdIn() {
  std::stringstream ss;
  ss << std::cin.rdbuf();
  return ss.str();
}

template <typename Lexer, typename Parser>
util::Optional<typename Parser::ParseTreeNode> LexAndParse(
    const std::string& text, const Lexer& lexer, const Parser& parser) {
  const std::vector<typename Lexer::Token> tokens = lexer(text);
  auto parse_result = parser.Parse(tokens.begin(), tokens.end());

  if (FLAGS_debug_print_parse_trees) {
    std::cout << parse_result.DebugString(tokens.end()) << "\n";
  }

  const std::vector<typename Lexer::Token> unparsed_tokens(parse_result.pos,
                                                           tokens.end());
  if (!unparsed_tokens.empty()) {
    std::cout << "unparsed tokens:";
    for (const auto& token : unparsed_tokens) {
      std::cout << " " << token.value;
    }
    std::cout << "\n";
  }

  if (!parse_result.success) {
    std::cout << "parse failed.\n";
    return util::EmptyOptional();
  }
  return std::move(parse_result.node);
}

}  // namespace

namespace steinlang {

void DebugPrint(const EvalContext& ctx) {
  printf("================\n");
  printf("results: .");
  for (const Result& r : ctx.cur_ctx().result()) {
    printf(" <~ %s", r.ShortDebugString().c_str());
  }
  printf("\n--------\n");
  printf("env:\n");
  for (const auto& kv : ctx.cur_ctx().env()) {
    printf("  env[%s] = %s\n", kv.first.c_str(),
           ctx.store(kv.second).ShortDebugString().c_str());
  }
  printf("\n--------\n");
  printf("comps: .");
  for (const Computation c : ctx.cur_ctx().comp()) {
    printf(" <~ %s", c.ShortDebugString().c_str());
  }
  printf("\n--------\n");
}

int evaluate(std::unique_ptr<Evaluator> evaluator) {
  int steps = 0;
  int num_output_printed = 0;
  while (evaluator->HasComputation()) {
    evaluator->Step();
    for (const std::string& output : evaluator->consume_output()) {
      printf("output: %s\n", output.c_str());
    }
    ++steps;
    if (FLAGS_debug_print_steps) {
      DebugPrint(evaluator->ctx());
    }
  }
  return steps;
}

void InitCtx(const Program& pgm, EvalContext* ctx) {
  *ctx->mutable_pgm() = pgm;
  AnnotateSource(ctx->mutable_pgm());
  for (int i = pgm.stmt_size(); i-- > 0;) {
    *ctx->mutable_cur_ctx()->add_comp()->mutable_stmt() = pgm.stmt(i);
  }
}

bool Evaluate(const std::string& input, EvalContext* ctx, PoolingArenaAllocator* allocator) {
  const util::Optional<steinlang::Parser::ParseTreeNode> parse_result =
      LexAndParse(input, steinlang::Tokenizer(), steinlang::Parser());
  if (!parse_result.is_present()) {
    std::cout << "failed to parse input.\n";
    return false;
  }

  steinlang::Program pgm = steinlang::ToProgram(parse_result.value());
  if (FLAGS_debug_print_syntax_tree) {
    std::cout << pgm.DebugString() << "\n";
  }

  steinlang::InitCtx(pgm, ctx);
  auto evaluator = std::make_unique<steinlang::Evaluator>(ctx, allocator);
  auto start = std::chrono::high_resolution_clock::now();
  int num_steps = evaluate(std::move(evaluator));
  auto elapsed = std::chrono::high_resolution_clock::now() - start;
  long long microseconds =
      std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
  if (FLAGS_debug_print_timing) {
    printf("total num steps evaluated: %d\n", num_steps);
    printf("total time: %lld us\n", microseconds);
    printf("avg: %f us / step\n", static_cast<float>(microseconds) / num_steps);
  }
  return true;
}

}  // namespace steinlang

int main(int argc, char** argv) {
  google::ParseCommandLineFlags(&argc, &argv, true);

  steinlang::PoolingArenaAllocator allocator;
  steinlang::EvalContext* ctx = allocator.AllocateEvalContext();
  for (std::string line; std::getline(std::cin, line) && Evaluate(line, ctx, &allocator);) {}

  return 0;
}
<commit_msg>undo make interpreter_main interpret line-by-line, now that there are multistatement blocks<commit_after>#include <chrono>
#include <gflags/gflags.h>
#include <iostream>
#include <stdio.h>

#include "lang/interpreter/language_evaluation.h"
#include "lang/interpreter/source_util.h"
#include "lang/interpreter/steinlang_parser.h"
#include "util/file_io.h"
#include "util/optional.h"

DEFINE_bool(debug_print_parse_trees, false, "");
DEFINE_bool(debug_print_syntax_tree, false, "");
DEFINE_bool(debug_print_steps, false,
            "If true, print verbose evaluation state after each step. This "
            "slows down execution significantly.");
DEFINE_bool(debug_print_timing, false, "");

namespace {

std::string ReadStdIn() {
  std::stringstream ss;
  ss << std::cin.rdbuf();
  return ss.str();
}

template <typename Lexer, typename Parser>
util::Optional<typename Parser::ParseTreeNode> LexAndParse(
    const std::string& text, const Lexer& lexer, const Parser& parser) {
  const std::vector<typename Lexer::Token> tokens = lexer(text);
  auto parse_result = parser.Parse(tokens.begin(), tokens.end());

  if (FLAGS_debug_print_parse_trees) {
    std::cout << parse_result.DebugString(tokens.end()) << "\n";
  }

  const std::vector<typename Lexer::Token> unparsed_tokens(parse_result.pos,
                                                           tokens.end());
  if (!unparsed_tokens.empty()) {
    std::cout << "unparsed tokens:";
    for (const auto& token : unparsed_tokens) {
      std::cout << " " << token.value;
    }
    std::cout << "\n";
  }

  if (!parse_result.success) {
    std::cout << "parse failed.\n";
    return util::EmptyOptional();
  }
  return std::move(parse_result.node);
}

}  // namespace

namespace steinlang {

void DebugPrint(const EvalContext& ctx) {
  printf("================\n");
  printf("results: .");
  for (const Result& r : ctx.cur_ctx().result()) {
    printf(" <~ %s", r.ShortDebugString().c_str());
  }
  printf("\n--------\n");
  printf("env:\n");
  for (const auto& kv : ctx.cur_ctx().env()) {
    printf("  env[%s] = %s\n", kv.first.c_str(),
           ctx.store(kv.second).ShortDebugString().c_str());
  }
  printf("\n--------\n");
  printf("comps: .");
  for (const Computation c : ctx.cur_ctx().comp()) {
    printf(" <~ %s", c.ShortDebugString().c_str());
  }
  printf("\n--------\n");
}

int evaluate(std::unique_ptr<Evaluator> evaluator) {
  int steps = 0;
  int num_output_printed = 0;
  while (evaluator->HasComputation()) {
    evaluator->Step();
    for (const std::string& output : evaluator->consume_output()) {
      printf("output: %s\n", output.c_str());
    }
    ++steps;
    if (FLAGS_debug_print_steps) {
      DebugPrint(evaluator->ctx());
    }
  }
  return steps;
}

void InitCtx(const Program& pgm, EvalContext* ctx) {
  *ctx->mutable_pgm() = pgm;
  AnnotateSource(ctx->mutable_pgm());
  for (int i = pgm.stmt_size(); i-- > 0;) {
    *ctx->mutable_cur_ctx()->add_comp()->mutable_stmt() = pgm.stmt(i);
  }
}

bool Evaluate(const std::string& input, EvalContext* ctx, PoolingArenaAllocator* allocator) {
  const util::Optional<steinlang::Parser::ParseTreeNode> parse_result =
      LexAndParse(input, steinlang::Tokenizer(), steinlang::Parser());
  if (!parse_result.is_present()) {
    std::cout << "failed to parse input.\n";
    return false;
  }

  steinlang::Program pgm = steinlang::ToProgram(parse_result.value());
  if (FLAGS_debug_print_syntax_tree) {
    std::cout << pgm.DebugString() << "\n";
  }

  steinlang::InitCtx(pgm, ctx);
  auto evaluator = std::make_unique<steinlang::Evaluator>(ctx, allocator);
  auto start = std::chrono::high_resolution_clock::now();
  int num_steps = evaluate(std::move(evaluator));
  auto elapsed = std::chrono::high_resolution_clock::now() - start;
  long long microseconds =
      std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
  if (FLAGS_debug_print_timing) {
    printf("total num steps evaluated: %d\n", num_steps);
    printf("total time: %lld us\n", microseconds);
    printf("avg: %f us / step\n", static_cast<float>(microseconds) / num_steps);
  }
  return true;
}

}  // namespace steinlang

int main(int argc, char** argv) {
  google::ParseCommandLineFlags(&argc, &argv, true);

  steinlang::PoolingArenaAllocator allocator;
  steinlang::EvalContext* ctx = allocator.AllocateEvalContext();
  Evaluate(ReadStdIn(), ctx, &allocator);
  return 0;
}
<|endoftext|>


<commit_before>/** File: OGRE3DRenderable.cpp
    Created on: 13-Feb-09
    Author: Robin Southern "betajaen"

    Copyright (c) 2008-2009 Robin Southern

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.

*/

#include "OGRE3DRenderable.h"
#include "OGRE3DRenderSystem.h"
#include "Ogre.h"

// operation, normals, colour, indexes, texture-coords, 16bit indexes.
OGRE3DRenderable::RenderProfile OGRE3DRenderable::NXOGRE_VISUALDEBUGGER =
                  OGRE3DRenderable::RenderProfile (Ogre::RenderOperation::OT_LINE_LIST, false, true, false, false, false);

OGRE3DRenderable::RenderProfile OGRE3DRenderable::NXOGRE_PHYSXMESH =
                  OGRE3DRenderable::RenderProfile (Ogre::RenderOperation::OT_TRIANGLE_LIST, true, false, true, true, false);

OGRE3DRenderable::RenderProfile OGRE3DRenderable::NXOGRE_PARTICLEPOINTS =
                  OGRE3DRenderable::RenderProfile (Ogre::RenderOperation::OT_POINT_LIST, false, false, false, false, false);

OGRE3DRenderable::RenderProfile OGRE3DRenderable::NXOGRE_SOFTBODY =
                  OGRE3DRenderable::RenderProfile (Ogre::RenderOperation::OT_TRIANGLE_LIST, false, false, true, false, false);

OGRE3DRenderable::RenderProfile::RenderProfile()
: mRenderOperation(Ogre::RenderOperation::OT_POINT_LIST),
  usesNormals(false),
  usesColourVertices(false),
  usesIndexes(false),
  uses16BitIndexes(false),
  usesTextureCoordinates(false)
{
}

OGRE3DRenderable::RenderProfile::RenderProfile(Ogre::RenderOperation::OperationType op, bool n, bool c, bool i, bool t, bool _16)
: mRenderOperation(op),
  usesNormals(n),
  usesColourVertices(c),
  usesIndexes(i),
  uses16BitIndexes(_16),
  usesTextureCoordinates(t)
{
}

OGRE3DRenderable::OGRE3DRenderable(NxOgre::Enums::RenderableType type)
: NxOgre::Renderable(type)
{
 _createProfile(mType);
 _initialise();
}

OGRE3DRenderable::~OGRE3DRenderable()
{
 NxOgre_Delete(mRenderOp.vertexData);
 NxOgre_Delete(mRenderOp.indexData);
}

void OGRE3DRenderable::drawSoftBodySimple(NxOgre::PhysXMeshData* data, const NxOgre::Bounds3& bounds)
{
 // Early escape.
 if (data->getNbVertices() < 3)
 {
  mBox.setExtents(Ogre::Vector3::ZERO, Ogre::Vector3::ZERO);
  return;
 }

 // Resize buffers if necessary.
 _resize(data->getNbVertices(), data->getNbIndices());

 // Write the vertices.
 mVertexBuffer->writeData(0, 3 * data->getNbVertices() * sizeof(Ogre::Real), data->getVertices() );

 // Write the indices.
 mRenderOp.indexData->indexBuffer->writeData(0, data->getNbIndices() * sizeof(unsigned int), data->getIndices() );

 // Set the extents.
 mBox.setExtents(bounds.min.as<Ogre::Vector3>(), bounds.max.as<Ogre::Vector3>());

 // Done.
}

void OGRE3DRenderable::drawCloth(NxOgre::PhysXMeshData* data, NxOgre::Buffer<float>& textureCoords, const NxOgre::Bounds3& bounds)
{
 // Early escape.
 if (data->getNbVertices() < 3)
 {
  mBox.setExtents(Ogre::Vector3::ZERO, Ogre::Vector3::ZERO);
  return;
 }

 // Resize buffers if necessary.
 _resize(data->getNbVertices(), data->getNbIndices());

 // Write the vertices.
 mVertexBuffer->writeData(0, 3 * data->getNbVertices() * sizeof(Ogre::Real), data->getVertices() );

 // Write the normals.
 mNormalBuffer->writeData(0, 3 * data->getNbVertices() * sizeof(Ogre::Real), data->getNormals() );

 // Write the texture coords.
 mTextureCoordsBuffer->writeData(0, textureCoords.size() * sizeof(float), textureCoords.first() );

 // Write the indices.
 mRenderOp.indexData->indexBuffer->writeData(0, data->getNbIndices() * sizeof(unsigned int), data->getIndices() );

 // Set the extents.
 mBox.setExtents(bounds.min.as<Ogre::Vector3>(), bounds.max.as<Ogre::Vector3>());

 // Done.
}

void OGRE3DRenderable::drawClothFast(NxOgre::PhysXMeshData* data, const NxOgre::Bounds3& bounds)
{

 // Resize buffers if necessary.
 _resize(data->getNbVertices(), data->getNbIndices());

 // Write the vertices.
 mVertexBuffer->writeData(0, 3 * data->getNbVertices() * sizeof(Ogre::Real), data->getVertices() );

 // Write the normals.
 mNormalBuffer->writeData(0, 3 * data->getNbVertices() * sizeof(Ogre::Real), data->getNormals() );

 // Set the extents.
 mBox.setExtents(bounds.min.as<Ogre::Vector3>(), bounds.max.as<Ogre::Vector3>());

 // Done.
}
void OGRE3DRenderable::drawVisualDebugger(NxOgre::VisualDebuggerMeshData* data)
{
 _resize(data->getNbLines(), 0);

 // Write the vertices.
 mVertexBuffer->writeData(0, 3 * data->getNbLines() * sizeof(Ogre::Real), data->getLines() );

 mVertexColourBuffer->writeData(0, data->getNbLines() * sizeof(unsigned int), data->getColours() );

 mBox.setInfinite();

}

void OGRE3DRenderable::_createProfile(NxOgre::Enums::RenderableType type)
{
 switch(type)
 {
  case NxOgre::Enums::RenderableType_VisualDebugger:
   mProfile = OGRE3DRenderable::NXOGRE_VISUALDEBUGGER;
  break;

  case NxOgre::Enums::RenderableType_PhysXMesh:
   mProfile = OGRE3DRenderable::NXOGRE_PHYSXMESH;
  break;

  case NxOgre::Enums::RenderableType_ParticlePoints:
   mProfile = OGRE3DRenderable::NXOGRE_PARTICLEPOINTS;
  break;

  case NxOgre::Enums::RenderableType_SoftBody:
   mProfile = OGRE3DRenderable::NXOGRE_SOFTBODY;
  break;

 }
}

void OGRE3DRenderable::_initialise()
{
 // Op.
 mRenderOp.operationType = mProfile.mRenderOperation;

 // Vertices and other vertex bits.
 mRenderOp.vertexData  = new Ogre::VertexData;

 // Main vertex declartion. It is assumed that a Renderable has vertices.
 Ogre::VertexDeclaration* vDecl = mRenderOp.vertexData->vertexDeclaration;
 vDecl->addElement(VertexDeclaration_Position, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);

 // Normals.
 if (mProfile.usesNormals)
  vDecl->addElement(VertexDeclaration_Normal, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);

 // Vertex Colours.
 if (mProfile.usesColourVertices)
  vDecl->addElement(VertexDeclaration_Colour, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);

 if (mProfile.usesTextureCoordinates)
  vDecl->addElement(VertexDeclaration_TextureCoordinates, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);

 // Vertex buffer capacity is zero.
 mVertexBufferCapacity = 0;

 // Do the indexes. If it has one.
 if (mRenderOp.useIndexes = mProfile.usesIndexes)
  mRenderOp.indexData = new Ogre::IndexData;

 mIndexBufferCapacity = 0;
}

void OGRE3DRenderable::_resize(size_t vertexCount, size_t indexCount)
{
  // Prepare vertex buffer
  size_t newVertCapacity = mVertexBufferCapacity;
  if ((vertexCount > mVertexBufferCapacity) ||
      (!mVertexBufferCapacity))
  {
    // vertexCount exceeds current capacity!
    // It is necessary to reallocate the buffer.

    // Check if this is the first call
    if (!newVertCapacity)
      newVertCapacity = 1;

    // Make capacity the next power of two
    while (newVertCapacity < vertexCount)
      newVertCapacity <<= 1;
  }
  else if (vertexCount < mVertexBufferCapacity>>1) {
    // Make capacity the previous power of two
    while (vertexCount < newVertCapacity>>1)
      newVertCapacity >>= 1;
  }

  if (newVertCapacity != mVertexBufferCapacity)
  {
    mVertexBufferCapacity = newVertCapacity;

    // Create new vertex buffer
    mVertexBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        mRenderOp.vertexData->vertexDeclaration->getVertexSize(VertexDeclaration_Position),
        mVertexBufferCapacity,
        Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?

    // Bind buffer
    mRenderOp.vertexData->vertexBufferBinding->setBinding(VertexDeclaration_Position, mVertexBuffer);

    // Colour vertices.
    if (this->mProfile.usesColourVertices)
    {
     // Create new vertexColour buffer
     mVertexColourBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
         mRenderOp.vertexData->vertexDeclaration->getVertexSize(VertexDeclaration_Colour),
         mVertexBufferCapacity,
         Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?

     // Bind buffer
     mRenderOp.vertexData->vertexBufferBinding->setBinding(VertexDeclaration_Colour, mVertexColourBuffer);
    }

    // Normals.
    if (this->mProfile.usesNormals)
    {
     // Create new vertexColour buffer
     mNormalBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
         mRenderOp.vertexData->vertexDeclaration->getVertexSize(VertexDeclaration_Normal),
         mVertexBufferCapacity,
         Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?

     // Bind buffer
     mRenderOp.vertexData->vertexBufferBinding->setBinding(VertexDeclaration_Normal, mNormalBuffer);
    }

    // Texture coords.
    if (this->mProfile.usesTextureCoordinates)
    {
     // Create new vertexColour buffer
     mTextureCoordsBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
         mRenderOp.vertexData->vertexDeclaration->getVertexSize(VertexDeclaration_TextureCoordinates),
         mVertexBufferCapacity,
         Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?

     // Bind buffer
     mRenderOp.vertexData->vertexBufferBinding->setBinding(VertexDeclaration_TextureCoordinates, mTextureCoordsBuffer);
    }

  }
  // Update vertex count in the render operation
  mRenderOp.vertexData->vertexCount = vertexCount;

  if (mProfile.usesIndexes)
  {
    OgreAssert(indexCount <= std::numeric_limits<unsigned short>::max(), "indexCount exceeds 16 bit");

    size_t newIndexCapacity = mIndexBufferCapacity;
    // Prepare index buffer
    if ((indexCount > newIndexCapacity) || (!newIndexCapacity))
    {
      // indexCount exceeds current capacity!
      // It is necessary to reallocate the buffer.
      // Check if this is the first call
      if (!newIndexCapacity)
        newIndexCapacity = 1;
      // Make capacity the next power of two
      while (newIndexCapacity < indexCount)
        newIndexCapacity <<= 1;
    }
    else if (indexCount < newIndexCapacity>>1)
    {
      // Make capacity the previous power of two
      while (indexCount < newIndexCapacity>>1)
        newIndexCapacity >>= 1;
    }

    if (newIndexCapacity != mIndexBufferCapacity)
    {
      mIndexBufferCapacity = newIndexCapacity;
      // Create new index buffer
      mIndexBuffer = mRenderOp.indexData->indexBuffer =
        Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
          Ogre::HardwareIndexBuffer::IndexType(!mProfile.uses16BitIndexes),
          mIndexBufferCapacity,
          Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?
    }

    // Update index count in the render operation
    mRenderOp.indexData->indexCount = indexCount;
  }
}

Ogre::Real OGRE3DRenderable::getBoundingRadius(void) const
{
 return Ogre::Math::Sqrt(std::max(mBox.getMaximum().squaredLength(), mBox.getMinimum().squaredLength()));
}

Ogre::Real OGRE3DRenderable::getSquaredViewDepth(const Ogre::Camera* cam) const
{
 Ogre::Vector3 vMin, vMax, vMid, vDist;
 vMin = mBox.getMinimum();
 vMax = mBox.getMaximum();
 vMid = ((vMax - vMin) * 0.5) + vMin;
 vDist = cam->getDerivedPosition() - vMid;
 return vDist.squaredLength();
}
<commit_msg>Ogre::Real to float Fix<commit_after>/** File: OGRE3DRenderable.cpp
    Created on: 13-Feb-09
    Author: Robin Southern "betajaen"

    Copyright (c) 2008-2009 Robin Southern

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.

*/

#include "OGRE3DRenderable.h"
#include "OGRE3DRenderSystem.h"
#include "Ogre.h"

// operation, normals, colour, indexes, texture-coords, 16bit indexes.
OGRE3DRenderable::RenderProfile OGRE3DRenderable::NXOGRE_VISUALDEBUGGER =
                  OGRE3DRenderable::RenderProfile (Ogre::RenderOperation::OT_LINE_LIST, false, true, false, false, false);

OGRE3DRenderable::RenderProfile OGRE3DRenderable::NXOGRE_PHYSXMESH =
                  OGRE3DRenderable::RenderProfile (Ogre::RenderOperation::OT_TRIANGLE_LIST, true, false, true, true, false);

OGRE3DRenderable::RenderProfile OGRE3DRenderable::NXOGRE_PARTICLEPOINTS =
                  OGRE3DRenderable::RenderProfile (Ogre::RenderOperation::OT_POINT_LIST, false, false, false, false, false);

OGRE3DRenderable::RenderProfile OGRE3DRenderable::NXOGRE_SOFTBODY =
                  OGRE3DRenderable::RenderProfile (Ogre::RenderOperation::OT_TRIANGLE_LIST, false, false, true, false, false);

OGRE3DRenderable::RenderProfile::RenderProfile()
: mRenderOperation(Ogre::RenderOperation::OT_POINT_LIST),
  usesNormals(false),
  usesColourVertices(false),
  usesIndexes(false),
  uses16BitIndexes(false),
  usesTextureCoordinates(false)
{
}

OGRE3DRenderable::RenderProfile::RenderProfile(Ogre::RenderOperation::OperationType op, bool n, bool c, bool i, bool t, bool _16)
: mRenderOperation(op),
  usesNormals(n),
  usesColourVertices(c),
  usesIndexes(i),
  uses16BitIndexes(_16),
  usesTextureCoordinates(t)
{
}

OGRE3DRenderable::OGRE3DRenderable(NxOgre::Enums::RenderableType type)
: NxOgre::Renderable(type)
{
 _createProfile(mType);
 _initialise();
}

OGRE3DRenderable::~OGRE3DRenderable()
{
 NxOgre_Delete(mRenderOp.vertexData);
 NxOgre_Delete(mRenderOp.indexData);
}

void OGRE3DRenderable::drawSoftBodySimple(NxOgre::PhysXMeshData* data, const NxOgre::Bounds3& bounds)
{
 // Early escape.
 if (data->getNbVertices() < 3)
 {
  mBox.setExtents(Ogre::Vector3::ZERO, Ogre::Vector3::ZERO);
  return;
 }

 // Resize buffers if necessary.
 _resize(data->getNbVertices(), data->getNbIndices());

 // Write the vertices.
 mVertexBuffer->writeData(0, 3 * data->getNbVertices() * sizeof(float), data->getVertices() );

 // Write the indices.
 mRenderOp.indexData->indexBuffer->writeData(0, data->getNbIndices() * sizeof(unsigned int), data->getIndices() );

 // Set the extents.
 mBox.setExtents(bounds.min.as<Ogre::Vector3>(), bounds.max.as<Ogre::Vector3>());

 // Done.
}

void OGRE3DRenderable::drawCloth(NxOgre::PhysXMeshData* data, NxOgre::Buffer<float>& textureCoords, const NxOgre::Bounds3& bounds)
{
 // Early escape.
 if (data->getNbVertices() < 3)
 {
  mBox.setExtents(Ogre::Vector3::ZERO, Ogre::Vector3::ZERO);
  return;
 }

 // Resize buffers if necessary.
 _resize(data->getNbVertices(), data->getNbIndices());

 // Write the vertices.
 mVertexBuffer->writeData(0, 3 * data->getNbVertices() * sizeof(float), data->getVertices() );

 // Write the normals.
 mNormalBuffer->writeData(0, 3 * data->getNbVertices() * sizeof(float), data->getNormals() );

 // Write the texture coords.
 mTextureCoordsBuffer->writeData(0, textureCoords.size() * sizeof(float), textureCoords.first() );

 // Write the indices.
 mRenderOp.indexData->indexBuffer->writeData(0, data->getNbIndices() * sizeof(unsigned int), data->getIndices() );

 // Set the extents.
 mBox.setExtents(bounds.min.as<Ogre::Vector3>(), bounds.max.as<Ogre::Vector3>());

 // Done.
}

void OGRE3DRenderable::drawClothFast(NxOgre::PhysXMeshData* data, const NxOgre::Bounds3& bounds)
{

 // Resize buffers if necessary.
 _resize(data->getNbVertices(), data->getNbIndices());

 // Write the vertices.
 mVertexBuffer->writeData(0, 3 * data->getNbVertices() * sizeof(float), data->getVertices() );

 // Write the normals.
 mNormalBuffer->writeData(0, 3 * data->getNbVertices() * sizeof(float), data->getNormals() );

 // Set the extents.
 mBox.setExtents(bounds.min.as<Ogre::Vector3>(), bounds.max.as<Ogre::Vector3>());

 // Done.
}
void OGRE3DRenderable::drawVisualDebugger(NxOgre::VisualDebuggerMeshData* data)
{
 _resize(data->getNbLines(), 0);

 // Write the vertices.
 mVertexBuffer->writeData(0, 3 * data->getNbLines() * sizeof(float), data->getLines() );

 mVertexColourBuffer->writeData(0, data->getNbLines() * sizeof(unsigned int), data->getColours() );

 mBox.setInfinite();

}

void OGRE3DRenderable::_createProfile(NxOgre::Enums::RenderableType type)
{
 switch(type)
 {
  case NxOgre::Enums::RenderableType_VisualDebugger:
   mProfile = OGRE3DRenderable::NXOGRE_VISUALDEBUGGER;
  break;

  case NxOgre::Enums::RenderableType_PhysXMesh:
   mProfile = OGRE3DRenderable::NXOGRE_PHYSXMESH;
  break;

  case NxOgre::Enums::RenderableType_ParticlePoints:
   mProfile = OGRE3DRenderable::NXOGRE_PARTICLEPOINTS;
  break;

  case NxOgre::Enums::RenderableType_SoftBody:
   mProfile = OGRE3DRenderable::NXOGRE_SOFTBODY;
  break;

 }
}

void OGRE3DRenderable::_initialise()
{
 // Op.
 mRenderOp.operationType = mProfile.mRenderOperation;

 // Vertices and other vertex bits.
 mRenderOp.vertexData  = new Ogre::VertexData;

 // Main vertex declartion. It is assumed that a Renderable has vertices.
 Ogre::VertexDeclaration* vDecl = mRenderOp.vertexData->vertexDeclaration;
 vDecl->addElement(VertexDeclaration_Position, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);

 // Normals.
 if (mProfile.usesNormals)
  vDecl->addElement(VertexDeclaration_Normal, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);

 // Vertex Colours.
 if (mProfile.usesColourVertices)
  vDecl->addElement(VertexDeclaration_Colour, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);

 if (mProfile.usesTextureCoordinates)
  vDecl->addElement(VertexDeclaration_TextureCoordinates, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);

 // Vertex buffer capacity is zero.
 mVertexBufferCapacity = 0;

 // Do the indexes. If it has one.
 if (mRenderOp.useIndexes = mProfile.usesIndexes)
  mRenderOp.indexData = new Ogre::IndexData;

 mIndexBufferCapacity = 0;
}

void OGRE3DRenderable::_resize(size_t vertexCount, size_t indexCount)
{
  // Prepare vertex buffer
  size_t newVertCapacity = mVertexBufferCapacity;
  if ((vertexCount > mVertexBufferCapacity) ||
      (!mVertexBufferCapacity))
  {
    // vertexCount exceeds current capacity!
    // It is necessary to reallocate the buffer.

    // Check if this is the first call
    if (!newVertCapacity)
      newVertCapacity = 1;

    // Make capacity the next power of two
    while (newVertCapacity < vertexCount)
      newVertCapacity <<= 1;
  }
  else if (vertexCount < mVertexBufferCapacity>>1) {
    // Make capacity the previous power of two
    while (vertexCount < newVertCapacity>>1)
      newVertCapacity >>= 1;
  }

  if (newVertCapacity != mVertexBufferCapacity)
  {
    mVertexBufferCapacity = newVertCapacity;

    // Create new vertex buffer
    mVertexBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        mRenderOp.vertexData->vertexDeclaration->getVertexSize(VertexDeclaration_Position),
        mVertexBufferCapacity,
        Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?

    // Bind buffer
    mRenderOp.vertexData->vertexBufferBinding->setBinding(VertexDeclaration_Position, mVertexBuffer);

    // Colour vertices.
    if (this->mProfile.usesColourVertices)
    {
     // Create new vertexColour buffer
     mVertexColourBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
         mRenderOp.vertexData->vertexDeclaration->getVertexSize(VertexDeclaration_Colour),
         mVertexBufferCapacity,
         Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?

     // Bind buffer
     mRenderOp.vertexData->vertexBufferBinding->setBinding(VertexDeclaration_Colour, mVertexColourBuffer);
    }

    // Normals.
    if (this->mProfile.usesNormals)
    {
     // Create new vertexColour buffer
     mNormalBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
         mRenderOp.vertexData->vertexDeclaration->getVertexSize(VertexDeclaration_Normal),
         mVertexBufferCapacity,
         Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?

     // Bind buffer
     mRenderOp.vertexData->vertexBufferBinding->setBinding(VertexDeclaration_Normal, mNormalBuffer);
    }

    // Texture coords.
    if (this->mProfile.usesTextureCoordinates)
    {
     // Create new vertexColour buffer
     mTextureCoordsBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
         mRenderOp.vertexData->vertexDeclaration->getVertexSize(VertexDeclaration_TextureCoordinates),
         mVertexBufferCapacity,
         Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?

     // Bind buffer
     mRenderOp.vertexData->vertexBufferBinding->setBinding(VertexDeclaration_TextureCoordinates, mTextureCoordsBuffer);
    }

  }
  // Update vertex count in the render operation
  mRenderOp.vertexData->vertexCount = vertexCount;

  if (mProfile.usesIndexes)
  {
    OgreAssert(indexCount <= std::numeric_limits<unsigned short>::max(), "indexCount exceeds 16 bit");

    size_t newIndexCapacity = mIndexBufferCapacity;
    // Prepare index buffer
    if ((indexCount > newIndexCapacity) || (!newIndexCapacity))
    {
      // indexCount exceeds current capacity!
      // It is necessary to reallocate the buffer.
      // Check if this is the first call
      if (!newIndexCapacity)
        newIndexCapacity = 1;
      // Make capacity the next power of two
      while (newIndexCapacity < indexCount)
        newIndexCapacity <<= 1;
    }
    else if (indexCount < newIndexCapacity>>1)
    {
      // Make capacity the previous power of two
      while (indexCount < newIndexCapacity>>1)
        newIndexCapacity >>= 1;
    }

    if (newIndexCapacity != mIndexBufferCapacity)
    {
      mIndexBufferCapacity = newIndexCapacity;
      // Create new index buffer
      mIndexBuffer = mRenderOp.indexData->indexBuffer =
        Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
          Ogre::HardwareIndexBuffer::IndexType(!mProfile.uses16BitIndexes),
          mIndexBufferCapacity,
          Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?
    }

    // Update index count in the render operation
    mRenderOp.indexData->indexCount = indexCount;
  }
}

float OGRE3DRenderable::getBoundingRadius(void) const
{
 return Ogre::Math::Sqrt(std::max(mBox.getMaximum().squaredLength(), mBox.getMinimum().squaredLength()));
}

float OGRE3DRenderable::getSquaredViewDepth(const Ogre::Camera* cam) const
{
 Ogre::Vector3 vMin, vMax, vMid, vDist;
 vMin = mBox.getMinimum();
 vMax = mBox.getMaximum();
 vMid = ((vMax - vMin) * 0.5) + vMin;
 vDist = cam->getDerivedPosition() - vMid;
 return vDist.squaredLength();
}
<|endoftext|>