<commit_before>// ImageControl.hh for FbTk - Fluxbox Toolkit
// Copyright (c) 2001 - 2003 Henrik Kinnunen (fluxbox at users.sourceforge.net)
//
// from Image.hh for Blackbox - an X11 Window manager
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
//
// 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.

// $Id: ImageControl.hh,v 1.9 2004/01/11 12:40:47 fluxgen Exp $

#ifndef	 FBTK_IMAGECONTROL_HH
#define	 FBTK_IMAGECONTROL_HH

#include "Texture.hh"
#include "Timer.hh"
#include "NotCopyable.hh"

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <list>
#include <set>

namespace FbTk {

/// Holds screen info, color tables and caches textures
class ImageControl: private NotCopyable {
public:
    ImageControl(int screen_num, bool dither = false, int colors_per_channel = 4,
                  unsigned long cache_timeout = 300000l, unsigned long cache_max = 200l);
    virtual ~ImageControl();

    inline bool doDither() const { return m_dither; }
    inline int bitsPerPixel() const { return bits_per_pixel; }
    inline int depth() const { return m_screen_depth; }
    inline int colorsPerChannel() const	{ return m_colors_per_channel; }
    int screenNum() const { return m_screen_num; }
    Visual *visual() const { return m_visual; }
    unsigned long getSqrt(unsigned int val) const;

    /**
       Render to pixmap
       @param width width of pixmap
       @param height height of pixmap
       @param src_texture texture type to render
       @return pixmap of the rendered image, on failure None
    */
    Pixmap renderImage(unsigned int width, unsigned int height,
                       const FbTk::Texture &src_texture);

    void installRootColormap();
    void removeImage(Pixmap thepix);
    void colorTables(const unsigned char **, const unsigned char **, const unsigned char **,
                     int *, int *, int *, int *, int *, int *) const;
    void getXColorTable(XColor **, int *);
    void getGradientBuffers(unsigned int, unsigned int,
                            unsigned int **, unsigned int **);
    void setDither(bool d) { m_dither = d; }
    void setColorsPerChannel(int cpc);

    void cleanCache();
private:
    /**
        Search cache for a specific pixmap
        @return None if no cache was found
    */
    Pixmap searchCache(unsigned int width, unsigned int height, const Texture &text) const;

    void createColorTable();
    bool m_dither;
    Timer m_timer;

    Colormap m_colormap;

    Window m_root_window;

    XColor *m_colors; ///< color table
    unsigned int m_num_colors; ///< number of colors in color table

    Visual *m_visual;

    int bits_per_pixel, red_offset, green_offset, blue_offset,
        red_bits, green_bits, blue_bits;
    int m_colors_per_channel; ///< number of colors per channel
    int m_screen_depth; ///< bit depth of screen
    int m_screen_num;  ///< screen number
    unsigned char red_color_table[256], green_color_table[256],
        blue_color_table[256];
    unsigned int *grad_xbuffer, *grad_ybuffer, grad_buffer_width,
        grad_buffer_height;

    static unsigned long *sqrt_table; /// sqrt lookup table

    typedef struct Cache {
        Pixmap pixmap;
        Pixmap texture_pixmap;
        unsigned int count, width, height;
        unsigned long pixel1, pixel2, texture;
    } Cache;

    struct ltCacheEntry {
        bool operator()(const Cache* s1, const Cache* s2) const {
            return (s1->width  < s2->width  || s1->width == s2->width &&
                    (s1->height < s2->height || s1->height == s2->height &&
                     (s1->texture < s2->texture || s1->texture == s2->texture &&
                      s1->pixel1 < s2->pixel1 || s1->pixel1 == s2->pixel1 &&
                      (s1->texture & FbTk::Texture::GRADIENT) &&
                       s1->pixel2 < s2->pixel2)
                        ));
        }
    };

    unsigned long cache_max;
    typedef std::list<Cache *> CacheList;

    mutable CacheList cache;
    static bool s_timed_cache;
};

} // end namespace FbTk

#endif // FBTK_IMAGECONTROL_HH

<commit_msg>inline<commit_after>// ImageControl.hh for FbTk - Fluxbox Toolkit
// Copyright (c) 2001 - 2003 Henrik Kinnunen (fluxbox at users.sourceforge.net)
//
// from Image.hh for Blackbox - an X11 Window manager
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
//
// 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.

// $Id: ImageControl.hh,v 1.10 2004/01/21 14:16:02 fluxgen Exp $

#ifndef	 FBTK_IMAGECONTROL_HH
#define	 FBTK_IMAGECONTROL_HH

#include "Texture.hh"
#include "Timer.hh"
#include "NotCopyable.hh"

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <list>
#include <set>

namespace FbTk {

/// Holds screen info, color tables and caches textures
class ImageControl: private NotCopyable {
public:
    ImageControl(int screen_num, bool dither = false, int colors_per_channel = 4,
                  unsigned long cache_timeout = 300000l, unsigned long cache_max = 200l);
    virtual ~ImageControl();

    inline bool doDither() const { return m_dither; }
    inline int bitsPerPixel() const { return bits_per_pixel; }
    inline int depth() const { return m_screen_depth; }
    inline int colorsPerChannel() const	{ return m_colors_per_channel; }
    inline int screenNumber() const { return m_screen_num; }
    inline Visual *visual() const { return m_visual; }
    unsigned long getSqrt(unsigned int val) const;

    /**
       Render to pixmap
       @param width width of pixmap
       @param height height of pixmap
       @param src_texture texture type to render
       @return pixmap of the rendered image, on failure None
    */
    Pixmap renderImage(unsigned int width, unsigned int height,
                       const FbTk::Texture &src_texture);

    void installRootColormap();
    void removeImage(Pixmap thepix);
    void colorTables(const unsigned char **, const unsigned char **, const unsigned char **,
                     int *, int *, int *, int *, int *, int *) const;
    void getXColorTable(XColor **, int *);
    void getGradientBuffers(unsigned int, unsigned int,
                            unsigned int **, unsigned int **);
    void setDither(bool d) { m_dither = d; }
    void setColorsPerChannel(int cpc);

    void cleanCache();
private:
    /**
        Search cache for a specific pixmap
        @return None if no cache was found
    */
    Pixmap searchCache(unsigned int width, unsigned int height, const Texture &text) const;

    void createColorTable();
    bool m_dither;
    Timer m_timer;

    Colormap m_colormap;

    Window m_root_window;

    XColor *m_colors; ///< color table
    unsigned int m_num_colors; ///< number of colors in color table

    Visual *m_visual;

    int bits_per_pixel, red_offset, green_offset, blue_offset,
        red_bits, green_bits, blue_bits;
    int m_colors_per_channel; ///< number of colors per channel
    int m_screen_depth; ///< bit depth of screen
    int m_screen_num;  ///< screen number
    unsigned char red_color_table[256], green_color_table[256],
        blue_color_table[256];
    unsigned int *grad_xbuffer, *grad_ybuffer, grad_buffer_width,
        grad_buffer_height;

    static unsigned long *sqrt_table; /// sqrt lookup table

    typedef struct Cache {
        Pixmap pixmap;
        Pixmap texture_pixmap;
        unsigned int count, width, height;
        unsigned long pixel1, pixel2, texture;
    } Cache;

    struct ltCacheEntry {
        bool operator()(const Cache* s1, const Cache* s2) const {
            return (s1->width  < s2->width  || s1->width == s2->width &&
                    (s1->height < s2->height || s1->height == s2->height &&
                     (s1->texture < s2->texture || s1->texture == s2->texture &&
                      s1->pixel1 < s2->pixel1 || s1->pixel1 == s2->pixel1 &&
                      (s1->texture & FbTk::Texture::GRADIENT) &&
                       s1->pixel2 < s2->pixel2)
                        ));
        }
    };

    unsigned long cache_max;
    typedef std::list<Cache *> CacheList;

    mutable CacheList cache;
    static bool s_timed_cache;
};

} // end namespace FbTk

#endif // FBTK_IMAGECONTROL_HH

<|endoftext|>


<commit_before><commit_msg>GSvar: fixed IGV timeout when IGV is starting up (sending 'genome' command before 'new' command)<commit_after><|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (ivan.frade@nokia.com)
**
** This file is part of the test suite of the QtSparql module (not yet part of the Qt Toolkit).
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used 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.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at ivan.frade@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>
#include <QtSparql/QtSparql>

//const QString qtest(qTableName( "qtest", __FILE__ )); // FIXME: what's this

//TESTED_FILES=

class tst_QSparqlTrackerDirectCrashes : public QObject
{
    Q_OBJECT

public:
    tst_QSparqlTrackerDirectCrashes();
    virtual ~tst_QSparqlTrackerDirectCrashes();

public slots:
    void initTestCase();
    void cleanupTestCase();
    void init();
    void cleanup();

private slots:
    void waitForFinished_crashes_when_connection_opening_fails();
    void syncExec_crashes_when_connection_opening_fails();
    void syncExec_update_crashes_when_connection_opening_fails();

    void two_failing_connections();
};

tst_QSparqlTrackerDirectCrashes::tst_QSparqlTrackerDirectCrashes()
{
}

tst_QSparqlTrackerDirectCrashes::~tst_QSparqlTrackerDirectCrashes()
{
}

void tst_QSparqlTrackerDirectCrashes::initTestCase()
{
    // For running the test without installing the plugins. Should work in
    // normal and vpath builds.
    QCoreApplication::addLibraryPath("../../../plugins");
}

void tst_QSparqlTrackerDirectCrashes::cleanupTestCase()
{
}

void tst_QSparqlTrackerDirectCrashes::init()
{
}

void tst_QSparqlTrackerDirectCrashes::cleanup()
{
}

void tst_QSparqlTrackerDirectCrashes::waitForFinished_crashes_when_connection_opening_fails()
{
    // This is a regression test. Run this in a setup where the
    // libtracker-sparql connection opening fails to reproduce the problem.
    QSparqlConnection conn ("QTRACKER_DIRECT");
    QSparqlQuery query("SELECT ?u {?u a rdfs:Resource .}");

    QSparqlResult* r = conn.exec(query);
    r->waitForFinished();
    delete r;
}

void tst_QSparqlTrackerDirectCrashes::syncExec_crashes_when_connection_opening_fails()
{
    // This is a regression test. Run this in a setup where the
    // libtracker-sparql connection opening fails to reproduce the problem.
    QSparqlConnection conn ("QTRACKER_DIRECT");
    QSparqlQuery query("SELECT ?u {?u a rdfs:Resource .}");

    QSparqlResult* r = conn.syncExec(query);
    delete r;
}

void tst_QSparqlTrackerDirectCrashes::syncExec_update_crashes_when_connection_opening_fails()
{
    // This is a regression test. Run this in a setup where the
    // libtracker-sparql connection opening fails to reproduce the problem.
    QSparqlConnection conn ("QTRACKER_DIRECT");
    QSparqlQuery insertQuery("insert { "
                             "<testcontact> a nco:PersonContact ; "
                             "nie:isLogicalPartOf <qsparql-tracker-direct-tests> . }",
                             QSparqlQuery::InsertStatement);

    QSparqlResult* r = conn.syncExec(insertQuery);
    delete r;

    QSparqlQuery deleteQuery("delete { "
                             "<testcontact> a rdfs:Resource . }",
                             QSparqlQuery::DeleteStatement);

    r = conn.syncExec(deleteQuery);
    delete r;
}

void tst_QSparqlTrackerDirectCrashes::two_failing_connections()
{
    QSKIP("Waiting for a tracker bugfix", SkipAll);
    // This is a regression test. Run this in a setup where the
    // libtracker-sparql connection opening fails to reproduce the problem.
    {
        QSparqlConnection conn ("QTRACKER_DIRECT");
        QSparqlQuery query("SELECT ?u {?u a rdfs:Resource .}");

        QSparqlResult* r = conn.exec(query);
        r->waitForFinished();
        delete r;
    }
    {
        QSparqlConnection conn ("QTRACKER_DIRECT");
        QSparqlQuery query("SELECT ?u {?u a rdfs:Resource .}");
        QSparqlResult* r = conn.syncExec(query);
        delete r;
    }
}

QTEST_MAIN( tst_QSparqlTrackerDirectCrashes )
#include "tst_qsparql_tracker_direct_crashes.moc"
<commit_msg>Test additions: verifying error codes in the sparql_tracker_direct_crashes case.<commit_after>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (ivan.frade@nokia.com)
**
** This file is part of the test suite of the QtSparql module (not yet part of the Qt Toolkit).
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used 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.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at ivan.frade@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>
#include <QtSparql/QtSparql>

//const QString qtest(qTableName( "qtest", __FILE__ )); // FIXME: what's this

//TESTED_FILES=

class tst_QSparqlTrackerDirectCrashes : public QObject
{
    Q_OBJECT

public:
    tst_QSparqlTrackerDirectCrashes();
    virtual ~tst_QSparqlTrackerDirectCrashes();

public slots:
    void initTestCase();
    void cleanupTestCase();
    void init();
    void cleanup();

private slots:
    void waitForFinished_crashes_when_connection_opening_fails();
    void syncExec_crashes_when_connection_opening_fails();
    void syncExec_update_crashes_when_connection_opening_fails();

    void two_failing_connections();
};

tst_QSparqlTrackerDirectCrashes::tst_QSparqlTrackerDirectCrashes()
{
}

tst_QSparqlTrackerDirectCrashes::~tst_QSparqlTrackerDirectCrashes()
{
}

void tst_QSparqlTrackerDirectCrashes::initTestCase()
{
    // For running the test without installing the plugins. Should work in
    // normal and vpath builds.
    QCoreApplication::addLibraryPath("../../../plugins");
}

void tst_QSparqlTrackerDirectCrashes::cleanupTestCase()
{
}

void tst_QSparqlTrackerDirectCrashes::init()
{
}

void tst_QSparqlTrackerDirectCrashes::cleanup()
{
}

void tst_QSparqlTrackerDirectCrashes::waitForFinished_crashes_when_connection_opening_fails()
{
    // This is a regression test. Run this in a setup where the
    // libtracker-sparql connection opening fails to reproduce the problem.
    QSparqlConnection conn ("QTRACKER_DIRECT");
    QSparqlQuery query("SELECT ?u {?u a rdfs:Resource .}");

    QSparqlResult* r = conn.exec(query);
    r->waitForFinished();
    QVERIFY2(r->hasError(), "This test needs to run in a setup where connection opening fails");
    QVERIFY(r->lastError().type() == QSparqlError::ConnectionError);
    delete r;
}

void tst_QSparqlTrackerDirectCrashes::syncExec_crashes_when_connection_opening_fails()
{
    // This is a regression test. Run this in a setup where the
    // libtracker-sparql connection opening fails to reproduce the problem.
    QSparqlConnection conn ("QTRACKER_DIRECT");
    QSparqlQuery query("SELECT ?u {?u a rdfs:Resource .}");

    QSparqlResult* r = conn.syncExec(query);
    QVERIFY2(r->hasError(), "This test needs to run in a setup where connection opening fails");
    QVERIFY(r->lastError().type() == QSparqlError::ConnectionError);
    delete r;
}

void tst_QSparqlTrackerDirectCrashes::syncExec_update_crashes_when_connection_opening_fails()
{
    // This is a regression test. Run this in a setup where the
    // libtracker-sparql connection opening fails to reproduce the problem.
    QSparqlConnection conn ("QTRACKER_DIRECT");
    QSparqlQuery insertQuery("insert { "
                             "<testcontact> a nco:PersonContact ; "
                             "nie:isLogicalPartOf <qsparql-tracker-direct-tests> . }",
                             QSparqlQuery::InsertStatement);

    QSparqlResult* r = conn.syncExec(insertQuery);
    delete r;

    QSparqlQuery deleteQuery("delete { "
                             "<testcontact> a rdfs:Resource . }",
                             QSparqlQuery::DeleteStatement);

    r = conn.syncExec(deleteQuery);
    QVERIFY2(r->hasError(), "This test needs to run in a setup where connection opening fails");
    QVERIFY(r->lastError().type() == QSparqlError::ConnectionError);
    delete r;
}

void tst_QSparqlTrackerDirectCrashes::two_failing_connections()
{
    QSKIP("Waiting for a tracker bugfix", SkipAll);
    // This is a regression test. Run this in a setup where the
    // libtracker-sparql connection opening fails to reproduce the problem.
    {
        QSparqlConnection conn ("QTRACKER_DIRECT");
        QSparqlQuery query("SELECT ?u {?u a rdfs:Resource .}");

        QSparqlResult* r = conn.exec(query);
        r->waitForFinished();
        QVERIFY2(r->hasError(), "This test needs to run in a setup where connection opening fails");
        QVERIFY(r->lastError().type() == QSparqlError::ConnectionError);
        delete r;
    }
    {
        QSparqlConnection conn ("QTRACKER_DIRECT");
        QSparqlQuery query("SELECT ?u {?u a rdfs:Resource .}");
        QSparqlResult* r = conn.syncExec(query);
        QVERIFY2(r->hasError(), "This test needs to run in a setup where connection opening fails");
        QVERIFY(r->lastError().type() == QSparqlError::ConnectionError);
        delete r;
    }
}

QTEST_MAIN( tst_QSparqlTrackerDirectCrashes )
#include "tst_qsparql_tracker_direct_crashes.moc"
<|endoftext|>


<commit_before><commit_msg>[common.configtree] fix old name<commit_after><|endoftext|>


<commit_before><commit_msg>[common] fix underlying type workaround >_><commit_after><|endoftext|>


<commit_before><commit_msg>Update String<commit_after><|endoftext|>


<commit_before><commit_msg>Remove it, it breaks double click to select freebusy url<commit_after><|endoftext|>


<commit_before>//===-- ValueSymbolTable.cpp - Implement the ValueSymbolTable class -------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group.  It is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the ValueSymbolTable class for the VMCore library.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "valuesymtab"
#include "llvm/GlobalValue.h"
#include "llvm/Type.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include <algorithm>
using namespace llvm;

// Class destructor
ValueSymbolTable::~ValueSymbolTable() {
#ifndef NDEBUG   // Only do this in -g mode...
  bool LeftoverValues = true;
  for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ++VI)
    if (!isa<Constant>(VI->second) ) {
      DEBUG(DOUT << "Value still in symbol table! Type = '"
           << VI->second->getType()->getDescription() << "' Name = '"
           << VI->first << "'\n");
      LeftoverValues = false;
    }
  assert(LeftoverValues && "Values remain in symbol table!");
#endif
}

// getUniqueName - Given a base name, return a string that is either equal to
// it (or derived from it) that does not already occur in the symbol table for
// the specified type.
//
std::string ValueSymbolTable::getUniqueName(const std::string &BaseName) const {
  std::string TryName = BaseName;
  const_iterator End = vmap.end();

  // See if the name exists
  while (vmap.find(TryName) != End)            // Loop until we find a free
    TryName = BaseName + utostr(++LastUnique); // name in the symbol table
  return TryName;
}

// lookup a value - Returns null on failure...
//
Value *ValueSymbolTable::lookup(const std::string &Name) const {
  const_iterator VI = vmap.find(Name);
  if (VI != vmap.end())                   // We found the symbol
    return const_cast<Value*>(VI->second);
  return 0;
}

// Strip the symbol table of its names.
//
bool ValueSymbolTable::strip() {
  bool RemovedSymbol = false;
  for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ) {
    Value *V = VI->second;
    ++VI;
    if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) {
      // Set name to "", removing from symbol table!
      V->setName("");
      RemovedSymbol = true;
    }
  }
  return RemovedSymbol;
}

// Insert a value into the symbol table with the specified name...
//
void ValueSymbolTable::insert(Value* V) {
  assert(V && "Can't insert null Value into symbol table!");
  assert(V->hasName() && "Can't insert nameless Value into symbol table");

  // Try inserting the name, assuming it won't conflict.
  if (vmap.insert(make_pair(V->Name, V)).second) {
    DOUT << " Inserted value: " << V->Name << ": " << *V << "\n";
    return;
  }

  // Otherwise, there is a naming conflict.  Rename this value.
  std::string UniqueName = getUniqueName(V->getName());

  DEBUG(DOUT << " Inserting value: " << UniqueName << ": " << *V << "\n");

  // Insert the vmap entry
  V->Name = UniqueName;
  vmap.insert(make_pair(V->Name, V));
}

// Remove a value
bool ValueSymbolTable::remove(Value *V) {
  assert(V->hasName() && "Value doesn't have name!");
  iterator Entry = vmap.find(V->getName());
  if (Entry == vmap.end())
    return false;

  DEBUG(DOUT << " Removing Value: " << Entry->second->getName() << "\n");

  // Remove the value from the plane...
  vmap.erase(Entry);
  return true;
}

// rename - Given a value with a non-empty name, remove its existing entry
// from the symbol table and insert a new one for Name.  This is equivalent to
// doing "remove(V), V->Name = Name, insert(V)",
//
bool ValueSymbolTable::rename(Value *V, const std::string &name) {
  assert(V && "Can't rename a null Value");
  assert(V->hasName() && "Can't rename a nameless Value");
  assert(!V->getName().empty() && "Can't rename an Value with null name");
  assert(V->getName() != name && "Can't rename a Value with same name");
  assert(!name.empty() && "Can't rename a named Value with a null name");

  // Find the name
  iterator VI = vmap.find(V->getName());

  // If we didn't find it, we're done
  if (VI == vmap.end())
    return false;

  // Remove the old entry.
  vmap.erase(VI);

  // See if we can insert the new name.
  VI = vmap.lower_bound(name);

  // Is there a naming conflict?
  if (VI != vmap.end() && VI->first == name) {
    V->Name = getUniqueName( name);
    vmap.insert(make_pair(V->Name, V));
  } else {
    V->Name = name;
    vmap.insert(VI, make_pair(V->Name, V));
  }

  return true;
}

// DumpVal - a std::for_each function for dumping a value
//
static void DumpVal(const std::pair<const std::string, Value *> &V) {
  DOUT << "  '" << V.first << "' = ";
  V.second->dump();
  DOUT << "\n";
}

// dump - print out the symbol table
//
void ValueSymbolTable::dump() const {
  DOUT << "ValueSymbolTable:\n";
  for_each(vmap.begin(), vmap.end(), DumpVal);
}
<commit_msg>speed up conflict handling.<commit_after>//===-- ValueSymbolTable.cpp - Implement the ValueSymbolTable class -------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group.  It is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the ValueSymbolTable class for the VMCore library.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "valuesymtab"
#include "llvm/GlobalValue.h"
#include "llvm/Type.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include <algorithm>
using namespace llvm;

// Class destructor
ValueSymbolTable::~ValueSymbolTable() {
#ifndef NDEBUG   // Only do this in -g mode...
  bool LeftoverValues = true;
  for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ++VI)
    if (!isa<Constant>(VI->second) ) {
      DEBUG(DOUT << "Value still in symbol table! Type = '"
           << VI->second->getType()->getDescription() << "' Name = '"
           << VI->first << "'\n");
      LeftoverValues = false;
    }
  assert(LeftoverValues && "Values remain in symbol table!");
#endif
}

// getUniqueName - Given a base name, return a string that is either equal to
// it (or derived from it) that does not already occur in the symbol table for
// the specified type.
//
std::string ValueSymbolTable::getUniqueName(const std::string &BaseName) const {
  std::string TryName = BaseName;
  const_iterator End = vmap.end();

  // See if the name exists
  while (vmap.find(TryName) != End)            // Loop until we find a free
    TryName = BaseName + utostr(++LastUnique); // name in the symbol table
  return TryName;
}

// lookup a value - Returns null on failure...
//
Value *ValueSymbolTable::lookup(const std::string &Name) const {
  const_iterator VI = vmap.find(Name);
  if (VI != vmap.end())                   // We found the symbol
    return const_cast<Value*>(VI->second);
  return 0;
}

// Strip the symbol table of its names.
//
bool ValueSymbolTable::strip() {
  bool RemovedSymbol = false;
  for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ) {
    Value *V = VI->second;
    ++VI;
    if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) {
      // Set name to "", removing from symbol table!
      V->setName("");
      RemovedSymbol = true;
    }
  }
  return RemovedSymbol;
}

// Insert a value into the symbol table with the specified name...
//
void ValueSymbolTable::insert(Value* V) {
  assert(V && "Can't insert null Value into symbol table!");
  assert(V->hasName() && "Can't insert nameless Value into symbol table");

  // Try inserting the name, assuming it won't conflict.
  if (vmap.insert(make_pair(V->Name, V)).second) {
    DOUT << " Inserted value: " << V->Name << ": " << *V << "\n";
    return;
  }

  // Otherwise, there is a naming conflict.  Rename this value.
  std::string UniqueName = V->getName();
  unsigned BaseSize = UniqueName.size();
  do {
    // Trim any suffix off.
    UniqueName.resize(BaseSize);
    UniqueName += utostr(++LastUnique);
  } while (!vmap.insert(make_pair(UniqueName, V)).second);

  DEBUG(DOUT << " Inserting value: " << UniqueName << ": " << *V << "\n");

  // Insert the vmap entry
  V->Name = UniqueName;
}

// Remove a value
bool ValueSymbolTable::remove(Value *V) {
  assert(V->hasName() && "Value doesn't have name!");
  iterator Entry = vmap.find(V->getName());
  if (Entry == vmap.end())
    return false;

  DEBUG(DOUT << " Removing Value: " << Entry->second->getName() << "\n");

  // Remove the value from the plane...
  vmap.erase(Entry);
  return true;
}

// rename - Given a value with a non-empty name, remove its existing entry
// from the symbol table and insert a new one for Name.  This is equivalent to
// doing "remove(V), V->Name = Name, insert(V)",
//
bool ValueSymbolTable::rename(Value *V, const std::string &name) {
  assert(V && "Can't rename a null Value");
  assert(V->hasName() && "Can't rename a nameless Value");
  assert(!V->getName().empty() && "Can't rename an Value with null name");
  assert(V->getName() != name && "Can't rename a Value with same name");
  assert(!name.empty() && "Can't rename a named Value with a null name");

  // Find the name
  iterator VI = vmap.find(V->getName());

  // If we didn't find it, we're done
  if (VI == vmap.end())
    return false;

  // Remove the old entry.
  vmap.erase(VI);

  // See if we can insert the new name.
  VI = vmap.lower_bound(name);

  // Is there a naming conflict?
  if (VI != vmap.end() && VI->first == name) {
    V->Name = getUniqueName( name);
    vmap.insert(make_pair(V->Name, V));
  } else {
    V->Name = name;
    vmap.insert(VI, make_pair(V->Name, V));
  }

  return true;
}

// DumpVal - a std::for_each function for dumping a value
//
static void DumpVal(const std::pair<const std::string, Value *> &V) {
  DOUT << "  '" << V.first << "' = ";
  V.second->dump();
  DOUT << "\n";
}

// dump - print out the symbol table
//
void ValueSymbolTable::dump() const {
  DOUT << "ValueSymbolTable:\n";
  for_each(vmap.begin(), vmap.end(), DumpVal);
}
<|endoftext|>


<commit_before>#ifndef INCLUDE_AL_AUDIODATA_IO_HPP
#define INCLUDE_AL_AUDIODATA_IO_HPP

/*	Allocore --
	Multimedia / virtual environment application class library

	Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
	Copyright (C) 2012. The Regents of the University of California.
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

		Redistributions of source code must retain the above copyright notice,
		this list of conditions and the following disclaimer.

		Redistributions in binary form must reproduce the above copyright
		notice, this list of conditions and the following disclaimer in the
		documentation and/or other materials provided with the distribution.

		Neither the name of the University of California nor the names of its
		contributors may be used to endorse or promote products derived from
		this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
	POSSIBILITY OF SUCH DAMAGE.

	File description:
	An interface to low-level audio device streams

	File author(s):
	Lance Putnam, 2010, putnam.lance@gmail.com
*/

#include <cstdio>

namespace al{

static int min(int x, int y){ return x<y?x:y; }

/*
static void err(const char * msg, const char * src, bool exits){
	fprintf(stderr, "%s%serror: %s\n", src, src[0]?" ":"", msg);
	if(exits) exit(EXIT_FAILURE);
}
*/

static void warn(const char * msg, const char * src){
	fprintf(stderr, "%s%swarning: %s\n", src, src[0]?" ":"", msg);
}

template <class T>
static void deleteBuf(T *& buf){ delete[] buf; buf=0; }

template <class T>
static int resize(T *& buf, int n){
	deleteBuf(buf);
	buf = new T[n];
	return n;
}

// Utility function to efficiently clear buffer (set all to 0)
template <class T>
static void zero(T * buf, int n){ memset(buf, 0, n*sizeof(T)); }

// Utility function to deinterleave samples
template <class T>
static void deinterleave(T * dst, const T * src, int numFrames, int numChannels){
	int numSamples = numFrames * numChannels;
	for(int c=0; c < numChannels; c++){
		for(int i=c; i < numSamples; i+=numChannels){
			*dst++ = src[i];
		}
	}
}

/// Utility function to interleave samples
template <class T>
static void interleave(T * dst, const T * src, int numFrames, int numChannels){
	int numSamples = numFrames * numChannels;
	for(int c=0; c < numChannels; c++){
		for(int i=c; i < numSamples; i+=numChannels){
			dst[i] = *src++;
		}
	}
}

/// Audio device information
///
/// @ingroup allocore
class AudioDeviceInfo{
public:

	/// Stream mode
	enum StreamMode{
		INPUT	= 1,	/**< Input stream */
		OUTPUT	= 2		/**< Output stream */
	};

	/// @param[in] deviceNum	Device enumeration number
	AudioDeviceInfo(int deviceNum);

//	/// @param[in] nameKeyword	Keyword to search for in device name
//	/// @param[in] stream		Whether to search for input and/or output devices
//	AudioDeviceInfo(const std::string& nameKeyword, StreamMode stream = StreamMode(INPUT | OUTPUT)) : mID(-1) {}

	virtual ~AudioDeviceInfo(){}

	virtual bool valid() const;						///< Returns whether device is valid
	virtual int id() const;							///< Get device unique ID
	virtual const char * name() const;				///< Get device name
	virtual int channelsInMax() const;				///< Get maximum number of input channels supported
	virtual int channelsOutMax() const;				///< Get maximum number of output channels supported
	virtual double defaultSampleRate() const;		///< Get default sample rate

	virtual void setID(int iD);						///< Sets unique ID
	virtual void setName(char *name);				///< Sets device name
	virtual void setChannelsInMax(int num);			///< Sets maximum number of Input channels supported
	virtual void setChannelsOutMax(int num);		///< Sets maximum number of Output channels supported
	virtual void setDefaultSampleRate(double rate);	///< Sets default sample rate

	virtual bool hasInput() const = 0;				///< Returns whether device has input
	virtual bool hasOutput() const = 0;				///< Returns whether device has output

	virtual void print() const = 0;					///< Prints info about specific i/o device to stdout

protected:
	int mID;
	char mName[128];
	int mChannelsInMax;
	int mChannelsOutMax;
	double mDefaultSampleRate;
};

inline AudioDeviceInfo::StreamMode operator| (const AudioDeviceInfo::StreamMode& a, const AudioDeviceInfo::StreamMode& b){
	return static_cast<AudioDeviceInfo::StreamMode>(+a|+b);
}

/// Abstract audio backend
///
/// @ingroup allocore
class AudioBackend{
public:
	AudioBackend();

	virtual ~AudioBackend(){}

	virtual bool isOpen() const = 0;
	virtual bool isRunning() const = 0;
	virtual bool error() const = 0;

	virtual void printError(const char * text = "") const = 0;
	virtual void printInfo() const = 0;

	virtual bool supportsFPS(double fps) const = 0;

	virtual void inDevice(int index) = 0;
	virtual void outDevice(int index) = 0;

	virtual void channels(int num, bool forOutput) = 0;

	virtual int inDeviceChans() = 0;
	virtual int outDeviceChans() = 0;
	virtual void setInDeviceChans(int num) = 0;
	virtual void setOutDeviceChans(int num) = 0;

	virtual double time() = 0;

	virtual bool open(int framesPerSecond, int framesPerBuffer, void *userdata) = 0;
	virtual bool close() = 0;

	virtual bool start(int framesPerSecond, int framesPerBuffer, void *userdata) = 0;
	virtual bool stop() = 0;
	virtual double cpu() = 0;

protected:
	bool mIsOpen;						// An audio device is open
	bool mIsRunning;					// An audio stream is running
};

/// Audio data to be sent to callback
/// Audio buffers are guaranteed to be stored in a contiguous non-interleaved
/// format, i.e., frames are tightly packed per channel.
///
/// @ingroup allocore
class AudioIOData {
public:
	/// Constructor
	AudioIOData(void * user);

	virtual ~AudioIOData();

	typedef enum {
		PORTAUDIO,
		DUMMY
	} Backend;

	/// Iterate frame counter, returning true while more frames
	bool operator()() const { return (++mFrame)<framesPerBuffer(); }

	/// Get current frame number
	int frame() const { return mFrame; }

	/// Get bus sample at current frame iteration on specified channel
	float& bus(int chan) const { return bus(chan, frame()); }

	/// Get bus sample at specified channel and frame
	float& bus(int chan, int frame) const;

	/// Get non-interleaved bus buffer on specified channel
	float * busBuffer(int chan=0) const { return &bus(chan,0); }

	/// Get input sample at current frame iteration on specified channel
	const float& in(int chan) const { return in (chan, frame()); }

	/// Get input sample at specified channel and frame
	const float& in (int chan, int frame) const;

	/// Get non-interleaved input buffer on specified channel
	const float * inBuffer(int chan=0) const { return &in(chan,0); }

	/// Get output sample at current frame iteration on specified channel
	float& out(int chan) const { return out(chan, frame()); }

	/// Get output sample at specified channel and frame
	float& out(int chan, int frame) const;

	/// Get non-interleaved output buffer on specified channel
	float * outBuffer(int chan=0) const { return &out(chan,0); }

	/// Add value to current output sample on specified channel
	void sum(float v, int chan) const { out(chan)+=v; }

	/// Add value to current output sample on specified channels
	void sum(float v, int ch1, int ch2) const { sum(v, ch1); sum(v,ch2); }

	/// Get sample from temporary buffer at specified frame
	float& temp(int frame) const;

	/// Get non-interleaved temporary buffer on specified channel
	float * tempBuffer() const { return &temp(0); }

	void * user() const{ return mUser; } ///< Get pointer to user data

	template<class UserDataType>
	UserDataType& user() const { return *(static_cast<UserDataType *>(mUser)); }

	int channelsIn () const;			///< Get effective number of input channels
	int channelsOut() const;			///< Get effective number of output channels
	int channelsBus() const;			///< Get number of allocated bus channels
	int framesPerBuffer() const;		///< Get frames/buffer of audio I/O stream
	double framesPerSecond() const;		///< Get frames/second of audio I/O streams
	double fps() const { return framesPerSecond(); }
	double secondsPerBuffer() const;	///< Get seconds/buffer of audio I/O stream
	double time() const;				///< Get current stream time in seconds
	double time(int frame) const;		///< Get current stream time in seconds of frame

	void user(void * v){ mUser=v; }		///< Set user data
	void frame(int v){ mFrame=v-1; }	///< Set frame count for next iteration
	void zeroBus();						///< Zeros all the bus buffers
	void zeroOut();						///< Zeros all the internal output buffers

	AudioIOData& gain(float v){ mGain=v; return *this; }
	bool usingGain() const { return mGain != 1.f || mGainPrev != 1.f; }

protected:
	AudioBackend * mImpl;
	void * mUser;					// User specified data
	mutable int mFrame;
	int mFramesPerBuffer;
	double mFramesPerSecond;
	float *mBufI, *mBufO, *mBufB;	// input, output, and aux buffers
	float * mBufT;					// temporary one channel buffer
	int mNumI, mNumO, mNumB;		// input, output, and aux channels
public:
	float mGain, mGainPrev;
};

/// Interface for objects which can be registered with an audio IO stream
///
/// @ingroup allocore
class AudioCallback {
public:
	virtual ~AudioCallback() {}
	virtual void onAudioCB(AudioIOData& io) = 0;	///< Callback
};

//==============================================================================
inline float&       AudioIOData::bus(int c, int f) const { return mBufB[c*framesPerBuffer() + f]; }
inline const float& AudioIOData::in (int c, int f) const { return mBufI[c*framesPerBuffer() + f]; }
inline float&       AudioIOData::out(int c, int f) const { return mBufO[c*framesPerBuffer() + f]; }
inline float&       AudioIOData::temp(int f) const { return mBufT[f]; }

} // al::

#endif
<commit_msg>Added asserts to AudioIO buffer to prevent misuse<commit_after>#ifndef INCLUDE_AL_AUDIODATA_IO_HPP
#define INCLUDE_AL_AUDIODATA_IO_HPP

/*	Allocore --
	Multimedia / virtual environment application class library

	Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
	Copyright (C) 2012. The Regents of the University of California.
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

		Redistributions of source code must retain the above copyright notice,
		this list of conditions and the following disclaimer.

		Redistributions in binary form must reproduce the above copyright
		notice, this list of conditions and the following disclaimer in the
		documentation and/or other materials provided with the distribution.

		Neither the name of the University of California nor the names of its
		contributors may be used to endorse or promote products derived from
		this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
	POSSIBILITY OF SUCH DAMAGE.

	File description:
	An interface to low-level audio device streams

	File author(s):
	Lance Putnam, 2010, putnam.lance@gmail.com
*/

#include <cstdio>
#include <cassert>

namespace al{

static int min(int x, int y){ return x<y?x:y; }

/*
static void err(const char * msg, const char * src, bool exits){
	fprintf(stderr, "%s%serror: %s\n", src, src[0]?" ":"", msg);
	if(exits) exit(EXIT_FAILURE);
}
*/

static void warn(const char * msg, const char * src){
	fprintf(stderr, "%s%swarning: %s\n", src, src[0]?" ":"", msg);
}

template <class T>
static void deleteBuf(T *& buf){ delete[] buf; buf=0; }

template <class T>
static int resize(T *& buf, int n){
	deleteBuf(buf);
	buf = new T[n];
	return n;
}

// Utility function to efficiently clear buffer (set all to 0)
template <class T>
static void zero(T * buf, int n){ memset(buf, 0, n*sizeof(T)); }

// Utility function to deinterleave samples
template <class T>
static void deinterleave(T * dst, const T * src, int numFrames, int numChannels){
	int numSamples = numFrames * numChannels;
	for(int c=0; c < numChannels; c++){
		for(int i=c; i < numSamples; i+=numChannels){
			*dst++ = src[i];
		}
	}
}

/// Utility function to interleave samples
template <class T>
static void interleave(T * dst, const T * src, int numFrames, int numChannels){
	int numSamples = numFrames * numChannels;
	for(int c=0; c < numChannels; c++){
		for(int i=c; i < numSamples; i+=numChannels){
			dst[i] = *src++;
		}
	}
}

/// Audio device information
///
/// @ingroup allocore
class AudioDeviceInfo{
public:

	/// Stream mode
	enum StreamMode{
		INPUT	= 1,	/**< Input stream */
		OUTPUT	= 2		/**< Output stream */
	};

	/// @param[in] deviceNum	Device enumeration number
	AudioDeviceInfo(int deviceNum);

//	/// @param[in] nameKeyword	Keyword to search for in device name
//	/// @param[in] stream		Whether to search for input and/or output devices
//	AudioDeviceInfo(const std::string& nameKeyword, StreamMode stream = StreamMode(INPUT | OUTPUT)) : mID(-1) {}

	virtual ~AudioDeviceInfo(){}

	virtual bool valid() const;						///< Returns whether device is valid
	virtual int id() const;							///< Get device unique ID
	virtual const char * name() const;				///< Get device name
	virtual int channelsInMax() const;				///< Get maximum number of input channels supported
	virtual int channelsOutMax() const;				///< Get maximum number of output channels supported
	virtual double defaultSampleRate() const;		///< Get default sample rate

	virtual void setID(int iD);						///< Sets unique ID
	virtual void setName(char *name);				///< Sets device name
	virtual void setChannelsInMax(int num);			///< Sets maximum number of Input channels supported
	virtual void setChannelsOutMax(int num);		///< Sets maximum number of Output channels supported
	virtual void setDefaultSampleRate(double rate);	///< Sets default sample rate

	virtual bool hasInput() const = 0;				///< Returns whether device has input
	virtual bool hasOutput() const = 0;				///< Returns whether device has output

	virtual void print() const = 0;					///< Prints info about specific i/o device to stdout

protected:
	int mID;
	char mName[128];
	int mChannelsInMax;
	int mChannelsOutMax;
	double mDefaultSampleRate;
};

inline AudioDeviceInfo::StreamMode operator| (const AudioDeviceInfo::StreamMode& a, const AudioDeviceInfo::StreamMode& b){
	return static_cast<AudioDeviceInfo::StreamMode>(+a|+b);
}

/// Abstract audio backend
///
/// @ingroup allocore
class AudioBackend{
public:
	AudioBackend();

	virtual ~AudioBackend(){}

	virtual bool isOpen() const = 0;
	virtual bool isRunning() const = 0;
	virtual bool error() const = 0;

	virtual void printError(const char * text = "") const = 0;
	virtual void printInfo() const = 0;

	virtual bool supportsFPS(double fps) const = 0;

	virtual void inDevice(int index) = 0;
	virtual void outDevice(int index) = 0;

	virtual void channels(int num, bool forOutput) = 0;

	virtual int inDeviceChans() = 0;
	virtual int outDeviceChans() = 0;
	virtual void setInDeviceChans(int num) = 0;
	virtual void setOutDeviceChans(int num) = 0;

	virtual double time() = 0;

	virtual bool open(int framesPerSecond, int framesPerBuffer, void *userdata) = 0;
	virtual bool close() = 0;

	virtual bool start(int framesPerSecond, int framesPerBuffer, void *userdata) = 0;
	virtual bool stop() = 0;
	virtual double cpu() = 0;

protected:
	bool mIsOpen;						// An audio device is open
	bool mIsRunning;					// An audio stream is running
};

/// Audio data to be sent to callback
/// Audio buffers are guaranteed to be stored in a contiguous non-interleaved
/// format, i.e., frames are tightly packed per channel.
///
/// @ingroup allocore
class AudioIOData {
public:
	/// Constructor
	AudioIOData(void * user);

	virtual ~AudioIOData();

	typedef enum {
		PORTAUDIO,
		DUMMY
	} Backend;

	/// Iterate frame counter, returning true while more frames
	bool operator()() const { return (++mFrame)<framesPerBuffer(); }

	/// Get current frame number
	int frame() const { return mFrame; }

	/// Get bus sample at current frame iteration on specified channel
	float& bus(int chan) const { return bus(chan, frame()); }

	/// Get bus sample at specified channel and frame
	float& bus(int chan, int frame) const;

	/// Get non-interleaved bus buffer on specified channel
	float * busBuffer(int chan=0) const { return &bus(chan,0); }

	/// Get input sample at current frame iteration on specified channel
	const float& in(int chan) const { return in (chan, frame()); }

	/// Get input sample at specified channel and frame
	const float& in (int chan, int frame) const;

	/// Get non-interleaved input buffer on specified channel
	const float * inBuffer(int chan=0) const { return &in(chan,0); }

	/// Get output sample at current frame iteration on specified channel
	float& out(int chan) const { return out(chan, frame()); }

	/// Get output sample at specified channel and frame
	float& out(int chan, int frame) const;

	/// Get non-interleaved output buffer on specified channel
	float * outBuffer(int chan=0) const { return &out(chan,0); }

	/// Add value to current output sample on specified channel
	void sum(float v, int chan) const { out(chan)+=v; }

	/// Add value to current output sample on specified channels
	void sum(float v, int ch1, int ch2) const { sum(v, ch1); sum(v,ch2); }

	/// Get sample from temporary buffer at specified frame
	float& temp(int frame) const;

	/// Get non-interleaved temporary buffer on specified channel
	float * tempBuffer() const { return &temp(0); }

	void * user() const{ return mUser; } ///< Get pointer to user data

	template<class UserDataType>
	UserDataType& user() const { return *(static_cast<UserDataType *>(mUser)); }

	int channelsIn () const;			///< Get effective number of input channels
	int channelsOut() const;			///< Get effective number of output channels
	int channelsBus() const;			///< Get number of allocated bus channels
	int framesPerBuffer() const;		///< Get frames/buffer of audio I/O stream
	double framesPerSecond() const;		///< Get frames/second of audio I/O streams
	double fps() const { return framesPerSecond(); }
	double secondsPerBuffer() const;	///< Get seconds/buffer of audio I/O stream
	double time() const;				///< Get current stream time in seconds
	double time(int frame) const;		///< Get current stream time in seconds of frame

	void user(void * v){ mUser=v; }		///< Set user data
	void frame(int v){ mFrame=v-1; }	///< Set frame count for next iteration
	void zeroBus();						///< Zeros all the bus buffers
	void zeroOut();						///< Zeros all the internal output buffers

	AudioIOData& gain(float v){ mGain=v; return *this; }
	bool usingGain() const { return mGain != 1.f || mGainPrev != 1.f; }

protected:
	AudioBackend * mImpl;
	void * mUser;					// User specified data
	mutable int mFrame;
	int mFramesPerBuffer;
	double mFramesPerSecond;
	float *mBufI, *mBufO, *mBufB;	// input, output, and aux buffers
	float * mBufT;					// temporary one channel buffer
	int mNumI, mNumO, mNumB;		// input, output, and aux channels
public:
	float mGain, mGainPrev;
};

/// Interface for objects which can be registered with an audio IO stream
///
/// @ingroup allocore
class AudioCallback {
public:
	virtual ~AudioCallback() {}
	virtual void onAudioCB(AudioIOData& io) = 0;	///< Callback
};

//==============================================================================
inline float&       AudioIOData::bus(int c, int f) const
{
	assert(c < mNumB);
	assert(f < framesPerBuffer());
	return mBufB[c*framesPerBuffer() + f];
}

inline const float& AudioIOData::in (int c, int f) const
{
	assert(c < mNumI);
	assert(f < framesPerBuffer());
	return mBufI[c*framesPerBuffer() + f];
}

inline float&       AudioIOData::out(int c, int f) const
{
	assert(c < mNumO);
	assert(f < framesPerBuffer());
	return mBufO[c*framesPerBuffer() + f];
}
inline float&       AudioIOData::temp(int f) const { return mBufT[f]; }

} // al::

#endif
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_COMMON_CRTP_HH
#define DUNE_STUFF_COMMON_CRTP_HH

#include <atomic>

#include "exceptions.hh"

#ifdef CHECK_CRTP
# undef CHECK_CRTP
#endif
#ifdef CHECK_AND_CALL_CRTP
# undef CHECK_AND_CALL_CRTP
#endif

#ifdef NDEBUG
# define CHECK_CRTP(dummy)
#else
/**
  * This macro is essentially a thread safe variant of the CHECK_INTERFACE_IMPLEMENTATION macro from dune-common.
  */
# define CHECK_CRTP(__interface_method_to_call__) \
  { \
    static std::atomic< bool > call(false); \
    if (call) \
      DUNE_THROW(Dune::Stuff::Exceptions::CRTP_check_failed, \
                 "The derived class does not implement the required method!"); \
    call = true; \
    try { \
      (__interface_method_to_call__); \
      call = false; \
    } catch (...) { \
      call = false; \
      throw; \
    } \
  }
// CHECK_CRTP
#endif

#ifdef NDEBUG
# define CHECK_AND_CALL_CRTP(__interface_method_to_call__) \
  (__interface_method_to_call__)
#else
/**
  * This macro is essentially a slightly modified copy of the CHECK_AND_CALL_INTERFACE_IMPLEMENTATION macro.
  */
# define CHECK_AND_CALL_CRTP(__interface_method_to_call__) \
  CHECK_CRTP(__interface_method_to_call__)
#endif

namespace Dune {
namespace Stuff {

template< class InterfaceType, class Traits >
class CRTPInterface
{
public:
  typedef typename Traits::derived_type derived_type;

  static inline derived_type& as_imp(InterfaceType& that)
  {
    return static_cast< derived_type& >(that);
  }

  static inline const derived_type& as_imp(const InterfaceType& that)
  {
    return static_cast< const derived_type& >(that);
  }

  inline derived_type& as_imp()
  {
    return static_cast< derived_type& >(*this);
  }

  inline const derived_type& as_imp() const
  {
    return static_cast< const derived_type& >(*this);
  }

protected:
  // nicely avoid warning about non-virtual dtor when derived classes have vfunc
  ~CRTPInterface() = default;
}; // CRTPInterface

} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_COMMON_CRTP_HH
<commit_msg>[common] actually thread safe crpt check macro<commit_after>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_COMMON_CRTP_HH
#define DUNE_STUFF_COMMON_CRTP_HH

#include <atomic>
#include <mutex>

#include "exceptions.hh"

#ifdef CHECK_CRTP
# undef CHECK_CRTP
#endif
#ifdef CHECK_AND_CALL_CRTP
# undef CHECK_AND_CALL_CRTP
#endif

#ifdef NDEBUG
# define CHECK_CRTP(dummy)
#else

/**
  * This macro is essentially a thread safe variant of the CHECK_INTERFACE_IMPLEMENTATION macro from dune-common.
  */
# define CHECK_CRTP(__interface_method_to_call__) \
  { \
    std::lock_guard<std::recursive_mutex> crtp_mutex_guard(this->crtp_mutex_); \
    static std::atomic< bool > call(false); \
    if (call) \
      DUNE_THROW(Dune::Stuff::Exceptions::CRTP_check_failed, \
                 "The derived class does not implement the required method!"); \
    call = true; \
    try { \
      (__interface_method_to_call__); \
      call = false; \
    } catch (...) { \
      call = false; \
      throw; \
    } \
  }
// CHECK_CRTP
#endif

#ifdef NDEBUG
# define CHECK_AND_CALL_CRTP(__interface_method_to_call__) \
  (__interface_method_to_call__)
#else
/**
  * This macro is essentially a slightly modified copy of the CHECK_AND_CALL_INTERFACE_IMPLEMENTATION macro.
  */
# define CHECK_AND_CALL_CRTP(__interface_method_to_call__) \
  CHECK_CRTP(__interface_method_to_call__)
#endif

namespace Dune {
namespace Stuff {

template< class InterfaceType, class Traits >
class CRTPInterface
{
public:
  typedef typename Traits::derived_type derived_type;

  static inline derived_type& as_imp(InterfaceType& that)
  {
    return static_cast< derived_type& >(that);
  }

  static inline const derived_type& as_imp(const InterfaceType& that)
  {
    return static_cast< const derived_type& >(that);
  }

  inline derived_type& as_imp()
  {
    return static_cast< derived_type& >(*this);
  }

  inline const derived_type& as_imp() const
  {
    return static_cast< const derived_type& >(*this);
  }

protected:
  // nicely avoid warning about non-virtual dtor when derived classes have vfunc
  ~CRTPInterface() = default;
#ifndef NDEBUG
  mutable std::recursive_mutex crtp_mutex_;
#endif
}; // CRTPInterface

} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_COMMON_CRTP_HH
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//
// Contributors: Sven Kaulmann

#ifndef DUNE_STUFF_COMMON_MATH_HH
#define DUNE_STUFF_COMMON_MATH_HH

#include <vector>
#include <limits>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <type_traits>

#include <dune/common/deprecated.hh>

#include <boost/static_assert.hpp>
#include <boost/fusion/include/void.hpp>
#include <boost/format.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/max.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/math/special_functions/fpclassify.hpp>

#if HAVE_DUNE_FEM
#include <dune/stuff/common/disable_warnings.hh>
  #include <dune/fem/function/blockvectorfunction/blockvectorfunction.hh>
#include <dune/stuff/common/reenable_warnings.hh>

#include <dune/stuff/fem/namespace.hh>
#include <dune/stuff/common/type_utils.hh>

namespace boost {
namespace math {

// use the limited scope here to no longer care about which effing fem version we compile against
using namespace Dune;
using namespace Dune::Fem;

//! isinf specialization for Dune::StraightenBlockVector
template< class BlockVectorImp, class DofImp >
inline bool isinf(const StraightenBlockVector< BlockVectorImp, DofImp >& x)
{
  for (size_t i = 0; i < x.size(); ++i)
  {
    if ( std::isinf(x[i]) )
      return true;
  }
  return false;
} // isinf
}
}
#endif // if HAVE_DUNE_FEM

namespace Dune {
namespace Stuff {
namespace Common {

/** \todo DOCME **/
template< class SomeRangeType, class OtherRangeType >
static double colonProduct(const SomeRangeType& arg1,
                           const OtherRangeType& arg2) {
  static_assert(SomeRangeType::cols == SomeRangeType::rows
                     && OtherRangeType::cols == OtherRangeType::rows
                     && int(OtherRangeType::cols) == int(SomeRangeType::rows), "RangeTypes_dont_fit");

  double ret = 0.0;
  // iterators
  typedef typename SomeRangeType::ConstRowIterator
  ConstRowIteratorType;
  typedef typename SomeRangeType::row_type::ConstIterator
  ConstIteratorType;
  ConstRowIteratorType arg1RowItEnd = arg1.end();
  ConstRowIteratorType arg2RowItEnd = arg2.end();
  ConstRowIteratorType arg2RowIt = arg2.begin();
  for (ConstRowIteratorType arg1RowIt = arg1.begin();
       arg1RowIt != arg1RowItEnd && arg2RowIt != arg2RowItEnd;
       ++arg1RowIt, ++arg2RowIt)
  {
    ConstIteratorType row1ItEnd = arg1RowIt->end();
    ConstIteratorType row2ItEnd = arg2RowIt->end();
    ConstIteratorType row2It = arg2RowIt->begin();
    for (ConstIteratorType row1It = arg1RowIt->begin();
         row1It != row1ItEnd && row2It != row2ItEnd;
         ++row1It, ++row2It)
    {
      ret += *row1It * *row2It;
    }
  }
  return ret;
} // colonProduct

/**
 * since std::numeric_limits<T>::epsilon() is 0 for integral types
 * use this to get the minimum increment/difference for all basic types
 * (or add specializations as necessary ofc)
 **/
template< class T, bool is_integral = std::is_integral< T >::value >
struct Epsilon {
};

template< class T >
struct Epsilon< T,true > {
  static const T value ;
};

template< class T >
struct Epsilon< T, false > {
  static const T value ;
};

template< >
struct Epsilon< std::string, false > {
  static const std::string value;
};

template< class T >
const T Epsilon< T, true >::value = 1;
template< class T >
const T Epsilon< T, false >::value = std::numeric_limits< T >::epsilon();

/**
 *  Helper struct to compute absolute values of signed and unsigned values,
 *  std::abs is only defined for signed types.
 **/
template<class T, bool isUnsigned = std::is_unsigned<T>::value>
struct absoluteValue {
  static T result(const T& val) {
    return std::abs(val);
  }
};
template<class T>
struct absoluteValue<T, true> {
  static T result(const T& val) {
    return val;
  }
};

template <class T, bool is_enum = std::is_enum<T>::value>
struct absretval {
  typedef T type;
};

template <class T>
struct absretval<T, true> {
  typedef typename underlying_type<T>::type type;
};

template<class T>
typename absretval<T>::type abs(const T& val) {
  typedef typename absretval<T>::type R;
  return absoluteValue<R>::result(static_cast<R>(val));
}

/**
   *  \brief  dyadic product
   *
   *          Implements \f$\left(arg_{1} \otimes arg_{2}\right)_{i,j}:={arg_{1}}_{i} {arg_{2}}_{j}\f$
   *			RangeType1 should be fieldmatrix, RangeType2 fieldvector
   **/
template< class RangeType1, class RangeType2 >
static RangeType1 dyadicProduct(const RangeType2& arg1,
                                const RangeType2& arg2) {
  RangeType1 ret(0.0);

  typedef typename RangeType1::RowIterator
    MatrixRowIteratorType;
  typedef typename RangeType2::ConstIterator
    ConstVectorIteratorType;
  typedef typename RangeType2::Iterator
    VectorIteratorType;
  const MatrixRowIteratorType rItEnd = ret.end();
  ConstVectorIteratorType arg1It = arg1.begin();
  for (MatrixRowIteratorType rIt = ret.begin(); rIt != rItEnd; ++rIt)
  {
    ConstVectorIteratorType arg2It = arg2.begin();
    const VectorIteratorType vItEnd = rIt->end();
    for (VectorIteratorType vIt = rIt->begin();
         vIt != vItEnd;
         ++vIt, ++arg2It)
    {
      *vIt = *arg1It * *arg2It;
    }
    ++arg1It;
  }
  return ret;
} // dyadicProduct

//! a vector wrapper for continiously updating min,max,avg of some element type vector
template< class ElementType >
class MinMaxAvg
{
protected:
  typedef MinMaxAvg< ElementType >
    ThisType;

public:
  MinMaxAvg()
  {}

  template< class stl_container_type > MinMaxAvg(const stl_container_type& elements) {
    static_assert( (boost::is_same< ElementType, typename stl_container_type::value_type >::value),
                        "cannot assign mismatching types" );
    acc_ = std::for_each(elements.begin(), elements.end(), acc_);
  }

  std::size_t count() const { return boost::accumulators::count(acc_); }
  ElementType sum() const { return boost::accumulators::sum(acc_); }
  ElementType min() const { return boost::accumulators::min(acc_); }
  ElementType max() const { return boost::accumulators::max(acc_); }
  ElementType average() const {
    // for integer ElementType this just truncates from floating-point
    return ElementType(boost::accumulators::mean(acc_));
  }

  void operator()(const ElementType& el) {
    acc_(el);
  }

  void output(std::ostream& stream) {
    stream << boost::format("min: %e\tmax: %e\tavg: %e\n") % min() % max() % average();
  }

protected:
  typedef boost::accumulators::stats<
    boost::accumulators::tag::max,
    boost::accumulators::tag::min,
    boost::accumulators::tag::mean,
    boost::accumulators::tag::count,
    boost::accumulators::tag::sum>
  StatsType;
  boost::accumulators::accumulator_set< ElementType, StatsType > acc_;

};

//! \return var bounded in [min, max]
template< typename T >
T clamp(const T var, const T min, const T max) {
  return (var < min) ? min : (var > max) ? max : var;
}

//! no-branch sign function
inline long sign(long x) { return long(x != 0) | (long(x >= 0) - 1);  }

template <class T, typename = void>
class numeric_limits
    : public std::numeric_limits<double> {};

template <class T>
class numeric_limits<T, typename std::enable_if<std::numeric_limits<T>::is_specialized >::type>
    : public std::numeric_limits<T> {};

} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_COMMON_MATH_HH
<commit_msg>[common] make underlying type workaround available with dune-fem missing<commit_after>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//
// Contributors: Sven Kaulmann

#ifndef DUNE_STUFF_COMMON_MATH_HH
#define DUNE_STUFF_COMMON_MATH_HH

#include <vector>
#include <limits>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <type_traits>

#include <dune/common/deprecated.hh>

#include <boost/static_assert.hpp>
#include <boost/fusion/include/void.hpp>
#include <boost/format.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/max.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/math/special_functions/fpclassify.hpp>

#include <dune/stuff/common/type_utils.hh>

#if HAVE_DUNE_FEM
#include <dune/stuff/common/disable_warnings.hh>
  #include <dune/fem/function/blockvectorfunction/blockvectorfunction.hh>
#include <dune/stuff/common/reenable_warnings.hh>

#include <dune/stuff/fem/namespace.hh>

namespace boost {
namespace math {

// use the limited scope here to no longer care about which effing fem version we compile against
using namespace Dune;
using namespace Dune::Fem;

//! isinf specialization for Dune::StraightenBlockVector
template< class BlockVectorImp, class DofImp >
inline bool isinf(const StraightenBlockVector< BlockVectorImp, DofImp >& x)
{
  for (size_t i = 0; i < x.size(); ++i)
  {
    if ( std::isinf(x[i]) )
      return true;
  }
  return false;
} // isinf
}
}
#endif // if HAVE_DUNE_FEM

namespace Dune {
namespace Stuff {
namespace Common {

/** \todo DOCME **/
template< class SomeRangeType, class OtherRangeType >
static double colonProduct(const SomeRangeType& arg1,
                           const OtherRangeType& arg2) {
  static_assert(SomeRangeType::cols == SomeRangeType::rows
                     && OtherRangeType::cols == OtherRangeType::rows
                     && int(OtherRangeType::cols) == int(SomeRangeType::rows), "RangeTypes_dont_fit");

  double ret = 0.0;
  // iterators
  typedef typename SomeRangeType::ConstRowIterator
  ConstRowIteratorType;
  typedef typename SomeRangeType::row_type::ConstIterator
  ConstIteratorType;
  ConstRowIteratorType arg1RowItEnd = arg1.end();
  ConstRowIteratorType arg2RowItEnd = arg2.end();
  ConstRowIteratorType arg2RowIt = arg2.begin();
  for (ConstRowIteratorType arg1RowIt = arg1.begin();
       arg1RowIt != arg1RowItEnd && arg2RowIt != arg2RowItEnd;
       ++arg1RowIt, ++arg2RowIt)
  {
    ConstIteratorType row1ItEnd = arg1RowIt->end();
    ConstIteratorType row2ItEnd = arg2RowIt->end();
    ConstIteratorType row2It = arg2RowIt->begin();
    for (ConstIteratorType row1It = arg1RowIt->begin();
         row1It != row1ItEnd && row2It != row2ItEnd;
         ++row1It, ++row2It)
    {
      ret += *row1It * *row2It;
    }
  }
  return ret;
} // colonProduct

/**
 * since std::numeric_limits<T>::epsilon() is 0 for integral types
 * use this to get the minimum increment/difference for all basic types
 * (or add specializations as necessary ofc)
 **/
template< class T, bool is_integral = std::is_integral< T >::value >
struct Epsilon {
};

template< class T >
struct Epsilon< T,true > {
  static const T value ;
};

template< class T >
struct Epsilon< T, false > {
  static const T value ;
};

template< >
struct Epsilon< std::string, false > {
  static const std::string value;
};

template< class T >
const T Epsilon< T, true >::value = 1;
template< class T >
const T Epsilon< T, false >::value = std::numeric_limits< T >::epsilon();

/**
 *  Helper struct to compute absolute values of signed and unsigned values,
 *  std::abs is only defined for signed types.
 **/
template<class T, bool isUnsigned = std::is_unsigned<T>::value>
struct absoluteValue {
  static T result(const T& val) {
    return std::abs(val);
  }
};
template<class T>
struct absoluteValue<T, true> {
  static T result(const T& val) {
    return val;
  }
};

template <class T, bool is_enum = std::is_enum<T>::value>
struct absretval {
  typedef T type;
};

template <class T>
struct absretval<T, true> {
  typedef typename underlying_type<T>::type type;
};

template<class T>
typename absretval<T>::type abs(const T& val) {
  typedef typename absretval<T>::type R;
  return absoluteValue<R>::result(static_cast<R>(val));
}

/**
   *  \brief  dyadic product
   *
   *          Implements \f$\left(arg_{1} \otimes arg_{2}\right)_{i,j}:={arg_{1}}_{i} {arg_{2}}_{j}\f$
   *			RangeType1 should be fieldmatrix, RangeType2 fieldvector
   **/
template< class RangeType1, class RangeType2 >
static RangeType1 dyadicProduct(const RangeType2& arg1,
                                const RangeType2& arg2) {
  RangeType1 ret(0.0);

  typedef typename RangeType1::RowIterator
    MatrixRowIteratorType;
  typedef typename RangeType2::ConstIterator
    ConstVectorIteratorType;
  typedef typename RangeType2::Iterator
    VectorIteratorType;
  const MatrixRowIteratorType rItEnd = ret.end();
  ConstVectorIteratorType arg1It = arg1.begin();
  for (MatrixRowIteratorType rIt = ret.begin(); rIt != rItEnd; ++rIt)
  {
    ConstVectorIteratorType arg2It = arg2.begin();
    const VectorIteratorType vItEnd = rIt->end();
    for (VectorIteratorType vIt = rIt->begin();
         vIt != vItEnd;
         ++vIt, ++arg2It)
    {
      *vIt = *arg1It * *arg2It;
    }
    ++arg1It;
  }
  return ret;
} // dyadicProduct

//! a vector wrapper for continiously updating min,max,avg of some element type vector
template< class ElementType >
class MinMaxAvg
{
protected:
  typedef MinMaxAvg< ElementType >
    ThisType;

public:
  MinMaxAvg()
  {}

  template< class stl_container_type > MinMaxAvg(const stl_container_type& elements) {
    static_assert( (boost::is_same< ElementType, typename stl_container_type::value_type >::value),
                        "cannot assign mismatching types" );
    acc_ = std::for_each(elements.begin(), elements.end(), acc_);
  }

  std::size_t count() const { return boost::accumulators::count(acc_); }
  ElementType sum() const { return boost::accumulators::sum(acc_); }
  ElementType min() const { return boost::accumulators::min(acc_); }
  ElementType max() const { return boost::accumulators::max(acc_); }
  ElementType average() const {
    // for integer ElementType this just truncates from floating-point
    return ElementType(boost::accumulators::mean(acc_));
  }

  void operator()(const ElementType& el) {
    acc_(el);
  }

  void output(std::ostream& stream) {
    stream << boost::format("min: %e\tmax: %e\tavg: %e\n") % min() % max() % average();
  }

protected:
  typedef boost::accumulators::stats<
    boost::accumulators::tag::max,
    boost::accumulators::tag::min,
    boost::accumulators::tag::mean,
    boost::accumulators::tag::count,
    boost::accumulators::tag::sum>
  StatsType;
  boost::accumulators::accumulator_set< ElementType, StatsType > acc_;

};

//! \return var bounded in [min, max]
template< typename T >
T clamp(const T var, const T min, const T max) {
  return (var < min) ? min : (var > max) ? max : var;
}

//! no-branch sign function
inline long sign(long x) { return long(x != 0) | (long(x >= 0) - 1);  }

template <class T, typename = void>
class numeric_limits
    : public std::numeric_limits<double> {};

template <class T>
class numeric_limits<T, typename std::enable_if<std::numeric_limits<T>::is_specialized >::type>
    : public std::numeric_limits<T> {};

} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_COMMON_MATH_HH
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_GRID_WALKER_HH
#define DUNE_STUFF_GRID_WALKER_HH

#include <vector>
#include <memory>
#include <type_traits>
#include <functional>

#if HAVE_TBB
# include <tbb/blocked_range.h>
# include <tbb/parallel_reduce.h>
# include <tbb/tbb_stddef.h>
#endif

#include <dune/stuff/grid/entity.hh>
#include <dune/stuff/grid/intersection.hh>
#include <dune/stuff/common/parallel/threadmanager.hh>

#include "walker/functors.hh"
#include "walker/apply-on.hh"
#include "walker/wrapper.hh"

namespace Dune {
namespace Stuff {
namespace Grid {

template< class GridViewImp >
class Walker
  : public Functor::Codim0And1< GridViewImp >
{
  typedef Walker< GridViewImp > ThisType;
public:
  typedef GridViewImp GridViewType;
  typedef typename Stuff::Grid::Entity< GridViewType >::Type       EntityType;
  typedef typename Stuff::Grid::Intersection< GridViewType >::Type IntersectionType;

  Walker(const GridViewType& grd_vw)
    : grid_view_(grd_vw)
  {}

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  void add(std::function< void(const EntityType&) > lambda,
           const ApplyOn::WhichEntity< GridViewType >* where = new ApplyOn::AllEntities< GridViewType >())
  {
    codim0_functors_.emplace_back(new internal::Codim0LambdaWrapper< GridViewType >(lambda, where));
  }

  void add(Functor::Codim0< GridViewType >& functor,
           const ApplyOn::WhichEntity< GridViewType >* where = new ApplyOn::AllEntities< GridViewType >())
  {
    codim0_functors_.emplace_back(
          new internal::Codim0FunctorWrapper<GridViewType, Functor::Codim0< GridViewType > >(functor, where));
  }

  void add(Functor::Codim1< GridViewType >& functor,
           const ApplyOn::WhichIntersection< GridViewType >* where = new ApplyOn::AllIntersections< GridViewType >())
  {
    codim1_functors_.emplace_back(
          new internal::Codim1FunctorWrapper<GridViewType, Functor::Codim1< GridViewType > >(functor, where));
  }

  void add(Functor::Codim0And1< GridViewType >& functor,
           const ApplyOn::WhichEntity< GridViewType >* which_entities = new ApplyOn::AllEntities< GridViewType >(),
           const ApplyOn::WhichIntersection< GridViewType >* which_intersections
              = new ApplyOn::AllIntersections< GridViewType >())
  {
    codim0_functors_.emplace_back(
          new internal::Codim0FunctorWrapper<GridViewType, Functor::Codim0And1< GridViewType > >(functor,
                                                                                which_entities));
    codim1_functors_.emplace_back(
          new internal::Codim1FunctorWrapper<GridViewType, Functor::Codim0And1< GridViewType > >(functor,
                                                                                which_intersections));
  }

  void add(Functor::Codim0And1< GridViewType >& functor,
           const ApplyOn::WhichIntersection< GridViewType >* which_intersections,
           const ApplyOn::WhichEntity< GridViewType >* which_entities = new ApplyOn::AllEntities< GridViewType >())
  {
    codim0_functors_.emplace_back(
          new internal::Codim0FunctorWrapper<GridViewType, Functor::Codim0And1< GridViewType > >(functor,
                                                                                which_entities));
    codim1_functors_.emplace_back(
          new internal::Codim1FunctorWrapper<GridViewType, Functor::Codim0And1< GridViewType > >(functor,
                                                                                which_intersections));
  }

  void add(ThisType& other,
           const ApplyOn::WhichEntity< GridViewType >* which_entities = new ApplyOn::AllEntities< GridViewType >(),
           const ApplyOn::WhichIntersection< GridViewType >* which_intersections
              = new ApplyOn::AllIntersections< GridViewType >())
  {
    if (&other == this)
      DUNE_THROW(Stuff::Exceptions::you_are_using_this_wrong, "Do not add a Walker to itself!");
    codim0_functors_.emplace_back(new internal::WalkerWrapper< GridViewType, ThisType >(other, which_entities));
    codim1_functors_.emplace_back(new internal::WalkerWrapper< GridViewType, ThisType >(other, which_intersections));
  } // ... add(...)

  void add(ThisType& other,
           const ApplyOn::WhichIntersection< GridViewType >* which_intersections,
           const ApplyOn::WhichEntity< GridViewType >* which_entities = new ApplyOn::AllEntities< GridViewType >())
  {
    if (&other == this)
      DUNE_THROW(Stuff::Exceptions::you_are_using_this_wrong, "Do not add a Walker to itself!");
    codim0_functors_.emplace_back(new internal::WalkerWrapper< GridViewType, ThisType >(other, which_entities));
    codim1_functors_.emplace_back(new internal::WalkerWrapper< GridViewType, ThisType >(other, which_intersections));
  } // ... add(...)

  void clear()
  {
    codim0_functors_.clear();
    codim1_functors_.clear();
  } // ... clear()

  virtual void prepare()
  {
    for (auto& functor : codim0_functors_)
      functor->prepare();
    for (auto& functor : codim1_functors_)
      functor->prepare();
  } // ... prepare()

  bool apply_on(const EntityType& entity) const
  {
    for (const auto& functor : codim0_functors_)
      if (functor->apply_on(grid_view_, entity))
        return true;
    return false;
  } // ... apply_on(...)

  bool apply_on(const IntersectionType& intersection) const
  {
    for (const auto& functor : codim1_functors_)
      if (functor->apply_on(grid_view_, intersection))
        return true;
    return false;
  } // ... apply_on(...)

  virtual void apply_local(const EntityType& entity)
  {
    for (auto& functor : codim0_functors_)
      if (functor->apply_on(grid_view_, entity))
        functor->apply_local(entity);
  } // ... apply_local(...)

  virtual void apply_local(const IntersectionType& intersection,
                           const EntityType& inside_entity,
                           const EntityType& outside_entity)
  {
    for (auto& functor : codim1_functors_)
      if (functor->apply_on(grid_view_, intersection))
        functor->apply_local(intersection, inside_entity, outside_entity);
  } // ... apply_local(...)

  virtual void finalize()
  {
    for (auto& functor : codim0_functors_)
      functor->finalize();
    for (auto& functor : codim1_functors_)
      functor->finalize();
  } // ... finalize()

  void walk(const bool clear_stack = true)
  {
    // prepare functors
    prepare();

    // only do something, if we have to
    if ((codim0_functors_.size() + codim1_functors_.size()) > 0) {
      walk_range(DSC::entityRange(grid_view_));
    } // only do something, if we have to

    // finalize functors
    finalize();

    // clear the stack of functors
    if (clear_stack) clear();
  } // ... walk(...)

#if HAVE_TBB

protected:
  template< class PartioningType, class WalkerType >
  struct Body
  {
    Body(WalkerType& walker, PartioningType& partitioning)
      : walker_(walker)
      , partitioning_(partitioning)
    {}

    Body(Body& other, tbb::split /*split*/)
      : walker_(other.walker_)
      , partitioning_(other.partitioning_)
    {}

    void operator()(const tbb::blocked_range< std::size_t > &range)
    {
      // for all partitions in tbb-range
      for(std::size_t p = range.begin(); p != range.end(); ++p) {
        auto partition = partitioning_.partition(p);
        walker_.walk_range(partition);
      }
    }

    void join(Body& /*other*/)
    {}

    WalkerType& walker_;
    const PartioningType& partitioning_;
  }; // struct Body

public:
  template< class PartioningType >
  void tbb_walk(PartioningType& partitioning, const bool clear_stack = true)
  {
    // prepare functors
    prepare();

    // only do something, if we have to
    if ((codim0_functors_.size() + codim1_functors_.size()) > 0) {
      tbb::blocked_range< std::size_t > range(0, partitioning.partitions());
      Body< PartioningType, ThisType > body(*this, partitioning);
      tbb::parallel_reduce(range, body);
    }

    // finalize functors
    finalize();

    // clear the stack of functors
    if (clear_stack) clear();
  } // ... tbb_walk(...)

#endif // HAVE_TBB

protected:
  template< class EntityRange >
  void walk_range(const EntityRange& entity_range)
  {
#ifdef __INTEL_COMPILER
    const auto it_end = entity_range.end();
    for (auto it = entity_range.begin(); it != it_end; ++it) {
      const EntityType& entity = *it;
#else
    for (const EntityType& entity : entity_range) {
#endif
      // apply codim0 functors
      apply_local(entity);

      // only walk the intersections, if there are codim1 functors present
      if (codim1_functors_.size() > 0) {
        // walk the intersections
        const auto intersection_it_end = grid_view_.iend(entity);
        for (auto intersection_it = grid_view_.ibegin(entity);
             intersection_it != intersection_it_end;
             ++intersection_it) {
          const auto& intersection = *intersection_it;

          // apply codim1 functors
          if (intersection.neighbor()) {
            const auto neighbor_ptr = intersection.outside();
            const auto& neighbor = *neighbor_ptr;
            apply_local(intersection, entity, neighbor);
          } else
            apply_local(intersection, entity, entity);

        } // walk the intersections
      } // only walk the intersections, if there are codim1 functors present
    }
  } // ... walk_range(...)

  const GridViewType& grid_view_;
  std::vector< std::unique_ptr< internal::Codim0Object<GridViewType> > > codim0_functors_;
  std::vector< std::unique_ptr< internal::Codim1Object<GridViewType> > > codim1_functors_;
}; // class Walker

} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRID_WALKER_HH
<commit_msg>[grid.walker] passing gridView by value<commit_after>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_GRID_WALKER_HH
#define DUNE_STUFF_GRID_WALKER_HH

#include <vector>
#include <memory>
#include <type_traits>
#include <functional>

#if HAVE_TBB
# include <tbb/blocked_range.h>
# include <tbb/parallel_reduce.h>
# include <tbb/tbb_stddef.h>
#endif

#include <dune/stuff/grid/entity.hh>
#include <dune/stuff/grid/intersection.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/stuff/common/parallel/threadmanager.hh>

#include "walker/functors.hh"
#include "walker/apply-on.hh"
#include "walker/wrapper.hh"

namespace Dune {
namespace Stuff {
namespace Grid {

template< class GridViewImp >
class Walker
  : public Functor::Codim0And1< GridViewImp >
{
  typedef Walker< GridViewImp > ThisType;
public:
  typedef GridViewImp GridViewType;
  typedef typename Stuff::Grid::Entity< GridViewType >::Type       EntityType;
  typedef typename Stuff::Grid::Intersection< GridViewType >::Type IntersectionType;

  Walker(GridViewType grd_vw)
    : grid_view_(grd_vw)
  {}

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  void add(std::function< void(const EntityType&) > lambda,
           const ApplyOn::WhichEntity< GridViewType >* where = new ApplyOn::AllEntities< GridViewType >())
  {
    codim0_functors_.emplace_back(new internal::Codim0LambdaWrapper< GridViewType >(lambda, where));
  }

  void add(Functor::Codim0< GridViewType >& functor,
           const ApplyOn::WhichEntity< GridViewType >* where = new ApplyOn::AllEntities< GridViewType >())
  {
    codim0_functors_.emplace_back(
          new internal::Codim0FunctorWrapper<GridViewType, Functor::Codim0< GridViewType > >(functor, where));
  }

  void add(Functor::Codim1< GridViewType >& functor,
           const ApplyOn::WhichIntersection< GridViewType >* where = new ApplyOn::AllIntersections< GridViewType >())
  {
    codim1_functors_.emplace_back(
          new internal::Codim1FunctorWrapper<GridViewType, Functor::Codim1< GridViewType > >(functor, where));
  }

  void add(Functor::Codim0And1< GridViewType >& functor,
           const ApplyOn::WhichEntity< GridViewType >* which_entities = new ApplyOn::AllEntities< GridViewType >(),
           const ApplyOn::WhichIntersection< GridViewType >* which_intersections
              = new ApplyOn::AllIntersections< GridViewType >())
  {
    codim0_functors_.emplace_back(
          new internal::Codim0FunctorWrapper<GridViewType, Functor::Codim0And1< GridViewType > >(functor,
                                                                                which_entities));
    codim1_functors_.emplace_back(
          new internal::Codim1FunctorWrapper<GridViewType, Functor::Codim0And1< GridViewType > >(functor,
                                                                                which_intersections));
  }

  void add(Functor::Codim0And1< GridViewType >& functor,
           const ApplyOn::WhichIntersection< GridViewType >* which_intersections,
           const ApplyOn::WhichEntity< GridViewType >* which_entities = new ApplyOn::AllEntities< GridViewType >())
  {
    codim0_functors_.emplace_back(
          new internal::Codim0FunctorWrapper<GridViewType, Functor::Codim0And1< GridViewType > >(functor,
                                                                                which_entities));
    codim1_functors_.emplace_back(
          new internal::Codim1FunctorWrapper<GridViewType, Functor::Codim0And1< GridViewType > >(functor,
                                                                                which_intersections));
  }

  void add(ThisType& other,
           const ApplyOn::WhichEntity< GridViewType >* which_entities = new ApplyOn::AllEntities< GridViewType >(),
           const ApplyOn::WhichIntersection< GridViewType >* which_intersections
              = new ApplyOn::AllIntersections< GridViewType >())
  {
    if (&other == this)
      DUNE_THROW(Stuff::Exceptions::you_are_using_this_wrong, "Do not add a Walker to itself!");
    codim0_functors_.emplace_back(new internal::WalkerWrapper< GridViewType, ThisType >(other, which_entities));
    codim1_functors_.emplace_back(new internal::WalkerWrapper< GridViewType, ThisType >(other, which_intersections));
  } // ... add(...)

  void add(ThisType& other,
           const ApplyOn::WhichIntersection< GridViewType >* which_intersections,
           const ApplyOn::WhichEntity< GridViewType >* which_entities = new ApplyOn::AllEntities< GridViewType >())
  {
    if (&other == this)
      DUNE_THROW(Stuff::Exceptions::you_are_using_this_wrong, "Do not add a Walker to itself!");
    codim0_functors_.emplace_back(new internal::WalkerWrapper< GridViewType, ThisType >(other, which_entities));
    codim1_functors_.emplace_back(new internal::WalkerWrapper< GridViewType, ThisType >(other, which_intersections));
  } // ... add(...)

  void clear()
  {
    codim0_functors_.clear();
    codim1_functors_.clear();
  } // ... clear()

  virtual void prepare()
  {
    for (auto& functor : codim0_functors_)
      functor->prepare();
    for (auto& functor : codim1_functors_)
      functor->prepare();
  } // ... prepare()

  bool apply_on(const EntityType& entity) const
  {
    for (const auto& functor : codim0_functors_)
      if (functor->apply_on(grid_view_, entity))
        return true;
    return false;
  } // ... apply_on(...)

  bool apply_on(const IntersectionType& intersection) const
  {
    for (const auto& functor : codim1_functors_)
      if (functor->apply_on(grid_view_, intersection))
        return true;
    return false;
  } // ... apply_on(...)

  virtual void apply_local(const EntityType& entity)
  {
    for (auto& functor : codim0_functors_)
      if (functor->apply_on(grid_view_, entity))
        functor->apply_local(entity);
  } // ... apply_local(...)

  virtual void apply_local(const IntersectionType& intersection,
                           const EntityType& inside_entity,
                           const EntityType& outside_entity)
  {
    for (auto& functor : codim1_functors_)
      if (functor->apply_on(grid_view_, intersection))
        functor->apply_local(intersection, inside_entity, outside_entity);
  } // ... apply_local(...)

  virtual void finalize()
  {
    for (auto& functor : codim0_functors_)
      functor->finalize();
    for (auto& functor : codim1_functors_)
      functor->finalize();
  } // ... finalize()

  void walk(const bool clear_stack = true)
  {
    // prepare functors
    prepare();

    // only do something, if we have to
    if ((codim0_functors_.size() + codim1_functors_.size()) > 0) {
      walk_range(DSC::entityRange(grid_view_));
    } // only do something, if we have to

    // finalize functors
    finalize();

    // clear the stack of functors
    if (clear_stack) clear();
  } // ... walk(...)

#if HAVE_TBB

protected:
  template< class PartioningType, class WalkerType >
  struct Body
  {
    Body(WalkerType& walker, PartioningType& partitioning)
      : walker_(walker)
      , partitioning_(partitioning)
    {}

    Body(Body& other, tbb::split /*split*/)
      : walker_(other.walker_)
      , partitioning_(other.partitioning_)
    {}

    void operator()(const tbb::blocked_range< std::size_t > &range)
    {
      // for all partitions in tbb-range
      for(std::size_t p = range.begin(); p != range.end(); ++p) {
        auto partition = partitioning_.partition(p);
        walker_.walk_range(partition);
      }
    }

    void join(Body& /*other*/)
    {}

    WalkerType& walker_;
    const PartioningType& partitioning_;
  }; // struct Body

public:
  template< class PartioningType >
  void tbb_walk(PartioningType& partitioning, const bool clear_stack = true)
  {
    // prepare functors
    prepare();

    // only do something, if we have to
    if ((codim0_functors_.size() + codim1_functors_.size()) > 0) {
      tbb::blocked_range< std::size_t > range(0, partitioning.partitions());
      Body< PartioningType, ThisType > body(*this, partitioning);
      tbb::parallel_reduce(range, body);
    }

    // finalize functors
    finalize();

    // clear the stack of functors
    if (clear_stack) clear();
  } // ... tbb_walk(...)

#endif // HAVE_TBB

protected:
  template< class EntityRange >
  void walk_range(const EntityRange& entity_range)
  {
#ifdef __INTEL_COMPILER
    const auto it_end = entity_range.end();
    for (auto it = entity_range.begin(); it != it_end; ++it) {
      const EntityType& entity = *it;
#else
    for (const EntityType& entity : entity_range) {
#endif
      // apply codim0 functors
      apply_local(entity);

      // only walk the intersections, if there are codim1 functors present
      if (codim1_functors_.size() > 0) {
        // walk the intersections
        const auto intersection_it_end = grid_view_.iend(entity);
        for (auto intersection_it = grid_view_.ibegin(entity);
             intersection_it != intersection_it_end;
             ++intersection_it) {
          const auto& intersection = *intersection_it;

          // apply codim1 functors
          if (intersection.neighbor()) {
            const auto neighbor_ptr = intersection.outside();
            const auto& neighbor = *neighbor_ptr;
            apply_local(intersection, entity, neighbor);
          } else
            apply_local(intersection, entity, entity);

        } // walk the intersections
      } // only walk the intersections, if there are codim1 functors present
    }
  } // ... walk_range(...)

  const GridViewType grid_view_;
  std::vector< std::unique_ptr< internal::Codim0Object<GridViewType> > > codim0_functors_;
  std::vector< std::unique_ptr< internal::Codim1Object<GridViewType> > > codim1_functors_;
}; // class Walker

} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRID_WALKER_HH
<|endoftext|>