<commit_before>/*********************************************************************
 # Copyright (c) 2013-2015, Rethink Robotics
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
 #
 # 1. Redistributions of source code must retain the above copyright notice,
 #    this list of conditions and the following disclaimer.
 # 2. 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.
 # 3. Neither the name of the Rethink Robotics 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 OWNER 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.
 *********************************************************************/

/**
 *  \author Hariharasudan Malaichamee
 *  \desc   Includes the action listener events for the QT controls
 */

#include <QtGui>
#include <QMessageBox>
#include <iostream>
#include <baxter_sim_io/baxter_io.hpp>

namespace baxter_sim_io {

using namespace Qt;

void BaxterIO::setstyle(std::string pressed, std::string released, QPushButton& button)
{

    QPixmap pix(QString::fromUtf8(released.c_str()));
    button.setMask(pix.mask());
    button.setStyleSheet("QPushButton{background-image: url("+QString::fromUtf8(released.c_str())+");\n"
                                           "background-position: center;\n"
                                           "background-color: transparent;\n"
                                           "background-repeat: none;\n"
                                           "border: none;}\n"
                                           "QPushButton:pressed{background-image: url("+QString::fromUtf8(pressed.c_str())+");}");
}

BaxterIO::BaxterIO(int argc, char** argv, QWidget *parent)
    : QMainWindow(parent),
      qnode(argc, argv),
      ui(new Ui::BaxterIO) {
    ui->setupUi(this);  // Calling this incidentally connects all ui's triggers to on_...() callbacks in this class.

    std::string cancel_r=":/new/prefix/nav_cancel_r.png";
    std::string cancel_p=":/new/prefix/nav_cancel_p.png";
    std::string ok_r=":/new/prefix/nav_ok_r.png";
    std::string ok_p=":/new/prefix/nav_ok_p.png";
    std::string show_r=":/new/prefix/nav_show_r.png";
    std::string show_p=":/new/prefix/nav_show_p.png";

    std::string cuff_grasp_r=":/new/prefix/cuff_grasp_r.png";
    std::string cuff_grasp_p=":/new/prefix/cuff_grasp_p.png";
    std::string cuff_ok_r=":/new/prefix/cuff_ok_r.png";
    std::string cuff_ok_p=":/new/prefix/cuff_ok_p.png";
    std::string cuff_squeeze_r=":/new/prefix/cuff_squeeze_r.png";
    std::string cuff_squeeze_p=":/new/prefix/cuff_squeeze_p.png";

    //Configure the stylesheet for all the Qwidgets
    //left arm
    setstyle(cancel_p,cancel_r,*(ui->left_arm_cancel));
    setstyle(ok_p,ok_r,*(ui->left_arm_ok));
    setstyle(show_p,show_r,*(ui->left_arm_show));
    //left shoulder
    setstyle(cancel_p,cancel_r,*(ui->left_shoulder_cancel));
    setstyle(ok_p,ok_r,*(ui->left_shoulder_ok));
    setstyle(show_p,show_r,*(ui->left_shoulder_show));
    //left cuff
    setstyle(cuff_grasp_p,cuff_grasp_r,*(ui->left_cuff_grasp));
    setstyle(cuff_ok_p,cuff_ok_r,*(ui->left_cuff_ok));
    setstyle(cuff_squeeze_p,cuff_squeeze_r,*(ui->left_cuff_squeeze));

    //right arm
    setstyle(cancel_p,cancel_r,*(ui->right_arm_cancel));
    setstyle(ok_p,ok_r,*(ui->right_arm_ok));
    setstyle(show_p,show_r,*(ui->right_arm_show));
    //right shoulder
    setstyle(cancel_p,cancel_r,*(ui->right_shoulder_cancel));
    setstyle(ok_p,ok_r,*(ui->right_shoulder_ok));
    setstyle(show_p,show_r,*(ui->right_shoulder_show));
    //right cuff
    setstyle(cuff_grasp_p,cuff_grasp_r,*(ui->right_cuff_grasp));
    setstyle(cuff_ok_p,cuff_ok_r,*(ui->right_cuff_ok));
    setstyle(cuff_squeeze_p,cuff_squeeze_r,*(ui->right_cuff_squeeze));
}

BaxterIO::~BaxterIO() {
}

void BaxterIO::on_left_arm_ok_pressed() {
  QNode::left_arm_nav.buttons[0] = true;
}

void BaxterIO::on_left_arm_ok_released() {
  QNode::left_arm_nav.buttons[0] = false;
}

void BaxterIO::on_left_arm_cancel_pressed() {
  QNode::left_arm_nav.buttons[1] = true;
}

void BaxterIO::on_left_arm_cancel_released() {
  QNode::left_arm_nav.buttons[1] = false;
}

void BaxterIO::on_left_arm_dial_sliderMoved(int position) {
  QNode::left_arm_nav.wheel = position;
}

void BaxterIO::on_left_arm_show_pressed() {
  QNode::left_arm_nav.buttons[2] = true;
}

void BaxterIO::on_left_arm_show_released() {
  QNode::left_arm_nav.buttons[2] = false;
}

void BaxterIO::on_left_cuff_squeeze_pressed() {
  QNode::left_cuff_squeeze.state = baxter_core_msgs::DigitalIOState::PRESSED;
}

void BaxterIO::on_left_cuff_squeeze_released() {
  QNode::left_cuff_squeeze.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}

void BaxterIO::on_left_cuff_ok_pressed() {
  QNode::left_cuff_ok.state = baxter_core_msgs::DigitalIOState::PRESSED;
}

void BaxterIO::on_left_cuff_ok_released() {
  QNode::left_cuff_ok.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}

void BaxterIO::on_left_cuff_grasp_pressed() {
  QNode::left_cuff_grasp.state = baxter_core_msgs::DigitalIOState::PRESSED;
}

void BaxterIO::on_left_cuff_grasp_released() {
  QNode::left_cuff_grasp.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}

void BaxterIO::on_left_shoulder_ok_pressed() {
  QNode::left_shoulder_nav.buttons[0] = true;
}

void BaxterIO::on_left_shoulder_ok_released() {
  QNode::left_shoulder_nav.buttons[0] = false;
}

void BaxterIO::on_left_shoulder_cancel_pressed() {
  QNode::left_shoulder_nav.buttons[1] = true;
}

void BaxterIO::on_left_shoulder_cancel_released() {
  QNode::left_shoulder_nav.buttons[1] = false;
}

void BaxterIO::on_left_shoulder_show_pressed() {
  QNode::left_shoulder_nav.buttons[2] = true;
}

void BaxterIO::on_left_shoulder_show_released() {
  QNode::left_shoulder_nav.buttons[2] = false;
}

void BaxterIO::on_left_shoulder_dial_sliderMoved(int position) {
  QNode::left_shoulder_nav.wheel = position;
}

void BaxterIO::on_right_shoulder_ok_pressed() {
  QNode::right_shoulder_nav.buttons[0] = true;
}

void BaxterIO::on_right_shoulder_ok_released() {
  QNode::right_shoulder_nav.buttons[0] = false;
}

void BaxterIO::on_right_shoulder_cancel_pressed() {
  QNode::right_shoulder_nav.buttons[1] = true;
}

void BaxterIO::on_right_shoulder_cancel_released() {
  QNode::right_shoulder_nav.buttons[1] = false;
}

void BaxterIO::on_right_shoulder_dial_sliderMoved(int position) {
  QNode::right_shoulder_nav.wheel = position;
}

void BaxterIO::on_right_shoulder_show_pressed() {
  QNode::right_shoulder_nav.buttons[2] = true;
}

void BaxterIO::on_right_shoulder_show_released() {
  QNode::right_shoulder_nav.buttons[2] = false;
}

void BaxterIO::on_right_arm_ok_pressed() {
  QNode::right_arm_nav.buttons[0] = true;
}

void BaxterIO::on_right_arm_ok_released() {
  QNode::right_arm_nav.buttons[0] = false;
}

void BaxterIO::on_right_arm_cancel_pressed() {
  QNode::right_arm_nav.buttons[1] = true;
}

void BaxterIO::on_right_arm_cancel_released() {
  QNode::right_arm_nav.buttons[1] = false;
}

void BaxterIO::on_right_arm_dial_sliderMoved(int position) {
  QNode::right_arm_nav.wheel = position;
}

void BaxterIO::on_right_arm_show_pressed() {
  QNode::right_arm_nav.buttons[2] = true;
}

void BaxterIO::on_right_arm_show_released() {
  QNode::right_arm_nav.buttons[2] = false;
}

void BaxterIO::on_right_cuff_squeeze_pressed() {
  QNode::right_cuff_squeeze.state = baxter_core_msgs::DigitalIOState::PRESSED;
}

void BaxterIO::on_right_cuff_squeeze_released() {
  QNode::right_cuff_squeeze.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}

void BaxterIO::on_right_cuff_ok_pressed() {
  QNode::right_cuff_ok.state = baxter_core_msgs::DigitalIOState::PRESSED;
}

void BaxterIO::on_right_cuff_ok_released() {
  QNode::right_cuff_ok.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}

void BaxterIO::on_right_cuff_grasp_pressed() {
  QNode::right_cuff_grasp.state = baxter_core_msgs::DigitalIOState::PRESSED;
}

void BaxterIO::on_right_cuff_grasp_released() {
  QNode::right_cuff_grasp.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}

void BaxterIO::on_left_shoulder_pressed() {
  QNode::left_shoulder.state = baxter_core_msgs::DigitalIOState::PRESSED;
}
void BaxterIO::on_left_shoulder_released() {
  QNode::left_shoulder.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}
void BaxterIO::on_right_shoulder_pressed() {
  QNode::right_shoulder.state = baxter_core_msgs::DigitalIOState::PRESSED;
}
void BaxterIO::on_right_shoulder_released() {
  QNode::right_shoulder.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}
}  // namespace baxter_sim_io

<commit_msg>Deleted allocated UI object in baxter_sim_io<commit_after>/*********************************************************************
 # Copyright (c) 2013-2015, Rethink Robotics
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
 #
 # 1. Redistributions of source code must retain the above copyright notice,
 #    this list of conditions and the following disclaimer.
 # 2. 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.
 # 3. Neither the name of the Rethink Robotics 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 OWNER 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.
 *********************************************************************/

/**
 *  \author Hariharasudan Malaichamee
 *  \desc   Includes the action listener events for the QT controls
 */

#include <QtGui>
#include <QMessageBox>
#include <iostream>
#include <baxter_sim_io/baxter_io.hpp>

namespace baxter_sim_io {

using namespace Qt;

void BaxterIO::setstyle(std::string pressed, std::string released, QPushButton& button)
{

    QPixmap pix(QString::fromUtf8(released.c_str()));
    button.setMask(pix.mask());
    button.setStyleSheet("QPushButton{background-image: url("+QString::fromUtf8(released.c_str())+");\n"
                                           "background-position: center;\n"
                                           "background-color: transparent;\n"
                                           "background-repeat: none;\n"
                                           "border: none;}\n"
                                           "QPushButton:pressed{background-image: url("+QString::fromUtf8(pressed.c_str())+");}");
}

BaxterIO::BaxterIO(int argc, char** argv, QWidget *parent)
    : QMainWindow(parent),
      qnode(argc, argv),
      ui(new Ui::BaxterIO) {
    ui->setupUi(this);  // Calling this incidentally connects all ui's triggers to on_...() callbacks in this class.

    std::string cancel_r=":/new/prefix/nav_cancel_r.png";
    std::string cancel_p=":/new/prefix/nav_cancel_p.png";
    std::string ok_r=":/new/prefix/nav_ok_r.png";
    std::string ok_p=":/new/prefix/nav_ok_p.png";
    std::string show_r=":/new/prefix/nav_show_r.png";
    std::string show_p=":/new/prefix/nav_show_p.png";

    std::string cuff_grasp_r=":/new/prefix/cuff_grasp_r.png";
    std::string cuff_grasp_p=":/new/prefix/cuff_grasp_p.png";
    std::string cuff_ok_r=":/new/prefix/cuff_ok_r.png";
    std::string cuff_ok_p=":/new/prefix/cuff_ok_p.png";
    std::string cuff_squeeze_r=":/new/prefix/cuff_squeeze_r.png";
    std::string cuff_squeeze_p=":/new/prefix/cuff_squeeze_p.png";

    //Configure the stylesheet for all the Qwidgets
    //left arm
    setstyle(cancel_p,cancel_r,*(ui->left_arm_cancel));
    setstyle(ok_p,ok_r,*(ui->left_arm_ok));
    setstyle(show_p,show_r,*(ui->left_arm_show));
    //left shoulder
    setstyle(cancel_p,cancel_r,*(ui->left_shoulder_cancel));
    setstyle(ok_p,ok_r,*(ui->left_shoulder_ok));
    setstyle(show_p,show_r,*(ui->left_shoulder_show));
    //left cuff
    setstyle(cuff_grasp_p,cuff_grasp_r,*(ui->left_cuff_grasp));
    setstyle(cuff_ok_p,cuff_ok_r,*(ui->left_cuff_ok));
    setstyle(cuff_squeeze_p,cuff_squeeze_r,*(ui->left_cuff_squeeze));

    //right arm
    setstyle(cancel_p,cancel_r,*(ui->right_arm_cancel));
    setstyle(ok_p,ok_r,*(ui->right_arm_ok));
    setstyle(show_p,show_r,*(ui->right_arm_show));
    //right shoulder
    setstyle(cancel_p,cancel_r,*(ui->right_shoulder_cancel));
    setstyle(ok_p,ok_r,*(ui->right_shoulder_ok));
    setstyle(show_p,show_r,*(ui->right_shoulder_show));
    //right cuff
    setstyle(cuff_grasp_p,cuff_grasp_r,*(ui->right_cuff_grasp));
    setstyle(cuff_ok_p,cuff_ok_r,*(ui->right_cuff_ok));
    setstyle(cuff_squeeze_p,cuff_squeeze_r,*(ui->right_cuff_squeeze));
}

BaxterIO::~BaxterIO() {
  delete ui;
}

void BaxterIO::on_left_arm_ok_pressed() {
  QNode::left_arm_nav.buttons[0] = true;
}

void BaxterIO::on_left_arm_ok_released() {
  QNode::left_arm_nav.buttons[0] = false;
}

void BaxterIO::on_left_arm_cancel_pressed() {
  QNode::left_arm_nav.buttons[1] = true;
}

void BaxterIO::on_left_arm_cancel_released() {
  QNode::left_arm_nav.buttons[1] = false;
}

void BaxterIO::on_left_arm_dial_sliderMoved(int position) {
  QNode::left_arm_nav.wheel = position;
}

void BaxterIO::on_left_arm_show_pressed() {
  QNode::left_arm_nav.buttons[2] = true;
}

void BaxterIO::on_left_arm_show_released() {
  QNode::left_arm_nav.buttons[2] = false;
}

void BaxterIO::on_left_cuff_squeeze_pressed() {
  QNode::left_cuff_squeeze.state = baxter_core_msgs::DigitalIOState::PRESSED;
}

void BaxterIO::on_left_cuff_squeeze_released() {
  QNode::left_cuff_squeeze.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}

void BaxterIO::on_left_cuff_ok_pressed() {
  QNode::left_cuff_ok.state = baxter_core_msgs::DigitalIOState::PRESSED;
}

void BaxterIO::on_left_cuff_ok_released() {
  QNode::left_cuff_ok.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}

void BaxterIO::on_left_cuff_grasp_pressed() {
  QNode::left_cuff_grasp.state = baxter_core_msgs::DigitalIOState::PRESSED;
}

void BaxterIO::on_left_cuff_grasp_released() {
  QNode::left_cuff_grasp.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}

void BaxterIO::on_left_shoulder_ok_pressed() {
  QNode::left_shoulder_nav.buttons[0] = true;
}

void BaxterIO::on_left_shoulder_ok_released() {
  QNode::left_shoulder_nav.buttons[0] = false;
}

void BaxterIO::on_left_shoulder_cancel_pressed() {
  QNode::left_shoulder_nav.buttons[1] = true;
}

void BaxterIO::on_left_shoulder_cancel_released() {
  QNode::left_shoulder_nav.buttons[1] = false;
}

void BaxterIO::on_left_shoulder_show_pressed() {
  QNode::left_shoulder_nav.buttons[2] = true;
}

void BaxterIO::on_left_shoulder_show_released() {
  QNode::left_shoulder_nav.buttons[2] = false;
}

void BaxterIO::on_left_shoulder_dial_sliderMoved(int position) {
  QNode::left_shoulder_nav.wheel = position;
}

void BaxterIO::on_right_shoulder_ok_pressed() {
  QNode::right_shoulder_nav.buttons[0] = true;
}

void BaxterIO::on_right_shoulder_ok_released() {
  QNode::right_shoulder_nav.buttons[0] = false;
}

void BaxterIO::on_right_shoulder_cancel_pressed() {
  QNode::right_shoulder_nav.buttons[1] = true;
}

void BaxterIO::on_right_shoulder_cancel_released() {
  QNode::right_shoulder_nav.buttons[1] = false;
}

void BaxterIO::on_right_shoulder_dial_sliderMoved(int position) {
  QNode::right_shoulder_nav.wheel = position;
}

void BaxterIO::on_right_shoulder_show_pressed() {
  QNode::right_shoulder_nav.buttons[2] = true;
}

void BaxterIO::on_right_shoulder_show_released() {
  QNode::right_shoulder_nav.buttons[2] = false;
}

void BaxterIO::on_right_arm_ok_pressed() {
  QNode::right_arm_nav.buttons[0] = true;
}

void BaxterIO::on_right_arm_ok_released() {
  QNode::right_arm_nav.buttons[0] = false;
}

void BaxterIO::on_right_arm_cancel_pressed() {
  QNode::right_arm_nav.buttons[1] = true;
}

void BaxterIO::on_right_arm_cancel_released() {
  QNode::right_arm_nav.buttons[1] = false;
}

void BaxterIO::on_right_arm_dial_sliderMoved(int position) {
  QNode::right_arm_nav.wheel = position;
}

void BaxterIO::on_right_arm_show_pressed() {
  QNode::right_arm_nav.buttons[2] = true;
}

void BaxterIO::on_right_arm_show_released() {
  QNode::right_arm_nav.buttons[2] = false;
}

void BaxterIO::on_right_cuff_squeeze_pressed() {
  QNode::right_cuff_squeeze.state = baxter_core_msgs::DigitalIOState::PRESSED;
}

void BaxterIO::on_right_cuff_squeeze_released() {
  QNode::right_cuff_squeeze.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}

void BaxterIO::on_right_cuff_ok_pressed() {
  QNode::right_cuff_ok.state = baxter_core_msgs::DigitalIOState::PRESSED;
}

void BaxterIO::on_right_cuff_ok_released() {
  QNode::right_cuff_ok.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}

void BaxterIO::on_right_cuff_grasp_pressed() {
  QNode::right_cuff_grasp.state = baxter_core_msgs::DigitalIOState::PRESSED;
}

void BaxterIO::on_right_cuff_grasp_released() {
  QNode::right_cuff_grasp.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}

void BaxterIO::on_left_shoulder_pressed() {
  QNode::left_shoulder.state = baxter_core_msgs::DigitalIOState::PRESSED;
}
void BaxterIO::on_left_shoulder_released() {
  QNode::left_shoulder.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}
void BaxterIO::on_right_shoulder_pressed() {
  QNode::right_shoulder.state = baxter_core_msgs::DigitalIOState::PRESSED;
}
void BaxterIO::on_right_shoulder_released() {
  QNode::right_shoulder.state = baxter_core_msgs::DigitalIOState::UNPRESSED;
}
}  // namespace baxter_sim_io
<|endoftext|>


<commit_before>/*
    This file is part of the Cagibi daemon, part of the KDE project.

    Copyright 2010 Friedrich W. H. Kossebau <kossebau@kde.org>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of
    the License or (at your option) version 3 or any later version
    accepted by the membership of KDE e.V. (or its successor approved
    by the membership of KDE e.V.), which shall act as a proxy
    defined in Section 14 of version 3 of the license.

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

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "upnpproxy.h"

// program
#include "upnpproxydbusadaptor.h"
#include "ssdpwatcher.h"
#include "rootdevice.h"
#include "device.h"

namespace Cagibi
{

static void fillMap( DeviceTypeMap& map, const Device& device )
{
    map.insert( device.udn(), device.type() );
    foreach( const Cagibi::Device& subDevice, device.devices() )
        fillMap( map, subDevice );
}

static void fillMapByType( DeviceTypeMap& map, const Device& device,
                           const QString& type = QString() )
{
    const QString deviceType = device.type();
    if( deviceType == type )
        map.insert( device.udn(), deviceType );

    foreach( const Cagibi::Device& subDevice, device.devices() )
        fillMapByType( map, subDevice, type );
}

static const Device* find( const Device& device, const QString& udn )
{
    const Device* result = 0;

    if( device.udn() == udn )
        result = &device;
    else
    {
        foreach( const Cagibi::Device& subDevice, device.devices() )
        {
            result = find( subDevice, udn );
            if( result )
                break;
        }
    }

    return result;
}

UPnPProxy::UPnPProxy( QObject* parent )
  : QObject( parent ),
    mSsdpWatcher( new SSDPWatcher(this) )
{
    new UPnPProxyDBusAdaptor( this );

    QDBusConnection sessionBus = QDBusConnection::sessionBus();
    sessionBus.registerService( QString::fromLatin1("org.kde.Cagibi") );
    sessionBus.registerObject( QString::fromLatin1("/"), this );

    connect( mSsdpWatcher, SIGNAL(deviceDiscovered( Cagibi::RootDevice* )),
             SLOT(onDeviceDiscovered( Cagibi::RootDevice* )) );
    connect( mSsdpWatcher, SIGNAL(deviceRemoved( Cagibi::RootDevice* )),
             SLOT(onDeviceRemoved( Cagibi::RootDevice* )) );

    mSsdpWatcher->discover();
}

DeviceTypeMap UPnPProxy::allDevices() const
{
    DeviceTypeMap result;

    const QList<RootDevice*> rootDevices = mSsdpWatcher->devices();

    foreach( RootDevice* rootDevice, rootDevices )
    {
        const Device device = rootDevice->device();
        fillMap( result, device );
    }

    return result;
}

DeviceTypeMap UPnPProxy::devicesByParent( const QString& udn ) const
{
    DeviceTypeMap result;

    const QList<RootDevice*> rootDevices = mSsdpWatcher->devices();

    foreach( RootDevice* rootDevice, rootDevices )
    {
        const Device device = rootDevice->device();

        const Device* match = find( device, udn );
        if( match )
        {
            foreach( const Cagibi::Device& subDevice, device.devices() )
                result.insert( subDevice.udn(), subDevice.type() );
            break;
        }
    }

    return result;
}

DeviceTypeMap UPnPProxy::devicesByType( const QString& type ) const
{
    DeviceTypeMap result;

    const QList<RootDevice*> rootDevices = mSsdpWatcher->devices();

    foreach( RootDevice* rootDevice, rootDevices )
    {
        const Device device = rootDevice->device();
        fillMapByType( result, device, type );
    }

    return result;
}

Device UPnPProxy::deviceDetails( const QString& udn ) const
{
    Device result;

    const QList<RootDevice*> rootDevices = mSsdpWatcher->devices();

    foreach( RootDevice* rootDevice, rootDevices )
    {
        const Device device = rootDevice->device();

        const Device* match = find( device, udn );
        if( match )
        {
            result = *match;
            break;
        }
    }

    return result;
}

void UPnPProxy::onDeviceDiscovered( RootDevice* rootDevice )
{
    DeviceTypeMap devices;

    const Device device = rootDevice->device();
    fillMap( devices, device );

    emit devicesAdded( devices );
}

void UPnPProxy::onDeviceRemoved( RootDevice* rootDevice )
{
    DeviceTypeMap devices;

    const Device device = rootDevice->device();
    fillMap( devices, device );

    emit devicesRemoved( devices );
}

UPnPProxy::~UPnPProxy()
{
}

}
<commit_msg>removed: unneeded default empty type parameter for fillMapByType()<commit_after>/*
    This file is part of the Cagibi daemon, part of the KDE project.

    Copyright 2010 Friedrich W. H. Kossebau <kossebau@kde.org>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of
    the License or (at your option) version 3 or any later version
    accepted by the membership of KDE e.V. (or its successor approved
    by the membership of KDE e.V.), which shall act as a proxy
    defined in Section 14 of version 3 of the license.

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

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "upnpproxy.h"

// program
#include "upnpproxydbusadaptor.h"
#include "ssdpwatcher.h"
#include "rootdevice.h"
#include "device.h"

#include <QtCore/QDebug>

namespace Cagibi
{

static void fillMap( DeviceTypeMap& map, const Device& device )
{
    map.insert( device.udn(), device.type() );
    foreach( const Cagibi::Device& subDevice, device.devices() )
        fillMap( map, subDevice );
}

static void fillMapByType( DeviceTypeMap& map, const Device& device,
                           const QString& type )
{
    const QString deviceType = device.type();

    if( deviceType == type )
        map.insert( device.udn(), deviceType );

    foreach( const Cagibi::Device& subDevice, device.devices() )
        fillMapByType( map, subDevice, type );
}

static const Device* find( const Device& device, const QString& udn )
{
    const Device* result = 0;

    if( device.udn() == udn )
        result = &device;
    else
    {
        foreach( const Cagibi::Device& subDevice, device.devices() )
        {
            result = find( subDevice, udn );
            if( result )
                break;
        }
    }

    return result;
}

UPnPProxy::UPnPProxy( QObject* parent )
  : QObject( parent ),
    mSsdpWatcher( new SSDPWatcher(this) )
{
    new UPnPProxyDBusAdaptor( this );

    QDBusConnection sessionBus = QDBusConnection::sessionBus();
    sessionBus.registerService( QString::fromLatin1("org.kde.Cagibi") );
    sessionBus.registerObject( QString::fromLatin1("/"), this );

    connect( mSsdpWatcher, SIGNAL(deviceDiscovered( Cagibi::RootDevice* )),
             SLOT(onDeviceDiscovered( Cagibi::RootDevice* )) );
    connect( mSsdpWatcher, SIGNAL(deviceRemoved( Cagibi::RootDevice* )),
             SLOT(onDeviceRemoved( Cagibi::RootDevice* )) );

    mSsdpWatcher->discover();
}

DeviceTypeMap UPnPProxy::allDevices() const
{
    DeviceTypeMap result;

    const QList<RootDevice*> rootDevices = mSsdpWatcher->devices();

    foreach( RootDevice* rootDevice, rootDevices )
    {
        const Device device = rootDevice->device();
        fillMap( result, device );
    }

    return result;
}

DeviceTypeMap UPnPProxy::devicesByParent( const QString& udn ) const
{
    DeviceTypeMap result;

    const QList<RootDevice*> rootDevices = mSsdpWatcher->devices();

    foreach( RootDevice* rootDevice, rootDevices )
    {
        const Device device = rootDevice->device();

        const Device* match = find( device, udn );
        if( match )
        {
            foreach( const Cagibi::Device& subDevice, device.devices() )
                result.insert( subDevice.udn(), subDevice.type() );
            break;
        }
    }

    return result;
}

DeviceTypeMap UPnPProxy::devicesByType( const QString& type ) const
{
    DeviceTypeMap result;

    const QList<RootDevice*> rootDevices = mSsdpWatcher->devices();

    foreach( RootDevice* rootDevice, rootDevices )
    {
        const Device device = rootDevice->device();
        fillMapByType( result, device, type );
    }

    return result;
}

Device UPnPProxy::deviceDetails( const QString& udn ) const
{
    Device result;

    const QList<RootDevice*> rootDevices = mSsdpWatcher->devices();

    foreach( RootDevice* rootDevice, rootDevices )
    {
        const Device device = rootDevice->device();

        const Device* match = find( device, udn );
        if( match )
        {
            result = *match;
            break;
        }
    }

    return result;
}

void UPnPProxy::onDeviceDiscovered( RootDevice* rootDevice )
{
    DeviceTypeMap devices;

    const Device device = rootDevice->device();
    fillMap( devices, device );

    emit devicesAdded( devices );
}

void UPnPProxy::onDeviceRemoved( RootDevice* rootDevice )
{
    DeviceTypeMap devices;

    const Device device = rootDevice->device();
    fillMap( devices, device );

    emit devicesRemoved( devices );
}

UPnPProxy::~UPnPProxy()
{
}

}
<|endoftext|>


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

#pragma once

#include <iostream>
#include <chrono>
#include <random>

#include "etl/etl.hpp"

#define CPM_NO_RANDOMIZATION            //Randomly initialize only once
#define CPM_AUTO_STEPS                  //Enable steps estimation system
#define CPM_STEP_ESTIMATION_MIN 0.05    //Run during 0.05 seconds for estimating steps
#define CPM_RUNTIME_TARGET 1.0          //Run each test during 1.0 seconds

#include "cpm/cpm.hpp"

#ifdef ETL_VECTORIZE_IMPL
#ifdef __SSE3__
#define TEST_SSE
#endif
#ifdef __AVX__
#define TEST_AVX
#endif
#endif

#ifdef ETL_MKL_MODE
#define TEST_MKL
#endif

#ifdef ETL_CUBLAS_MODE
#define TEST_CUBLAS
#endif

#ifdef ETL_CUFFT_MODE
#define TEST_CUFFT
#endif

#ifdef ETL_BLAS_MODE
#define TEST_BLAS
#endif

#ifdef ETL_BENCH_STRASSEN
#define TEST_STRASSEN
#endif

#ifdef ETL_BENCH_MMUL_CONV
#define TEST_MMUL_CONV
#endif

using smat_cm = etl::dyn_matrix_cm<float>;
using dmat_cm = etl::dyn_matrix_cm<double>;
using cmat_cm = etl::dyn_matrix_cm<std::complex<float>>;
using zmat_cm = etl::dyn_matrix_cm<std::complex<double>>;

using dvec = etl::dyn_vector<double>;
using dmat = etl::dyn_matrix<double>;
using dmat2 = etl::dyn_matrix<double, 2>;
using dmat3 = etl::dyn_matrix<double, 3>;
using dmat4 = etl::dyn_matrix<double, 4>;

using svec = etl::dyn_vector<float>;
using smat = etl::dyn_matrix<float>;

using cvec = etl::dyn_vector<std::complex<float>>;
using cmat = etl::dyn_matrix<std::complex<float>>;

using zvec = etl::dyn_vector<std::complex<double>>;
using zmat = etl::dyn_matrix<std::complex<double>>;

using mat_policy = VALUES_POLICY(10, 25, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 2000,3000,4000);
using mat_policy_2d = NARY_POLICY(mat_policy, mat_policy);

using conv_1d_large_policy = NARY_POLICY(VALUES_POLICY(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000), VALUES_POLICY(500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000));
using conv_2d_large_policy = NARY_POLICY(VALUES_POLICY(100, 105, 110, 115, 120, 125, 130, 135, 140), VALUES_POLICY(50, 50, 55, 55, 60, 60, 65, 65, 70));

using fft_1d_policy = VALUES_POLICY(10, 100, 1000, 10000, 100000, 500000);
using fft_1d_policy_2 = VALUES_POLICY(16, 64, 256, 1024, 16384, 131072, 1048576, 2097152);
using fft_1d_many_policy = VALUES_POLICY(10, 50, 100, 500, 1000, 5000, 10000);

using fft_2d_policy = NARY_POLICY(
    VALUES_POLICY(8, 16, 32, 64, 128, 256, 512, 1024, 2048),
    VALUES_POLICY(8, 16, 32, 64, 128, 256, 512, 1024, 2048));

using sigmoid_policy = VALUES_POLICY(250, 500, 750, 1000, 1250, 1500, 1750, 2000);

using small_square_policy = NARY_POLICY(VALUES_POLICY(50, 100, 150, 200, 250, 300, 350, 400, 450, 500), VALUES_POLICY(50, 100, 150, 200, 250, 300, 350, 400, 450, 500));
using square_policy = NARY_POLICY(VALUES_POLICY(50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000), VALUES_POLICY(50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000));

using gemv_policy = NARY_POLICY(
    VALUES_POLICY(250, 500, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000),
    VALUES_POLICY(250, 500, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000));

using trans_sub_policy = VALUES_POLICY(100, 200, 300, 400, 500, 600, 700, 800, 900, 1000);
using trans_policy = NARY_POLICY(
    VALUES_POLICY(100, 100, 200, 200, 300, 300, 400, 400, 500, 500, 600, 600, 700, 700, 800, 800, 900, 900, 1000, 1000),
    VALUES_POLICY(100, 200, 200, 300, 300, 400, 400, 500, 500, 600, 600, 700, 700, 800, 800, 900, 900, 1000, 1000, 1100));

#ifdef TEST_SSE
#define SSE_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define SSE_SECTION_FUNCTOR(name, ...)
#endif

#ifdef TEST_AVX
#define AVX_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define AVX_SECTION_FUNCTOR(name, ...)
#endif

#ifdef TEST_MKL
#define MKL_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define MKL_SECTION_FUNCTOR(name, ...)
#endif

#ifdef TEST_BLAS
#define BLAS_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define BLAS_SECTION_FUNCTOR(name, ...)
#endif

#ifdef TEST_CUBLAS
#define CUBLAS_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define CUBLAS_SECTION_FUNCTOR(name, ...)
#endif

#ifdef TEST_CUFFT
#define CUFFT_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define CUFFT_SECTION_FUNCTOR(name, ...)
#endif

#ifdef TEST_MMUL_CONV
#define MC_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define MC_SECTION_FUNCTOR(name, ...)
#endif
<commit_msg>Save some time<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include <iostream>
#include <chrono>
#include <random>

#include "etl/etl.hpp"

#define CPM_NO_RANDOMIZATION            //Randomly initialize only once
#define CPM_AUTO_STEPS                  //Enable steps estimation system
#define CPM_STEP_ESTIMATION_MIN 0.05    //Run during 0.05 seconds for estimating steps
#define CPM_RUNTIME_TARGET 0.9          //Run each test during 0.9 seconds

#include "cpm/cpm.hpp"

#ifdef ETL_VECTORIZE_IMPL
#ifdef __SSE3__
#define TEST_SSE
#endif
#ifdef __AVX__
#define TEST_AVX
#endif
#endif

#ifdef ETL_MKL_MODE
#define TEST_MKL
#endif

#ifdef ETL_CUBLAS_MODE
#define TEST_CUBLAS
#endif

#ifdef ETL_CUFFT_MODE
#define TEST_CUFFT
#endif

#ifdef ETL_BLAS_MODE
#define TEST_BLAS
#endif

#ifdef ETL_BENCH_STRASSEN
#define TEST_STRASSEN
#endif

#ifdef ETL_BENCH_MMUL_CONV
#define TEST_MMUL_CONV
#endif

using smat_cm = etl::dyn_matrix_cm<float>;
using dmat_cm = etl::dyn_matrix_cm<double>;
using cmat_cm = etl::dyn_matrix_cm<std::complex<float>>;
using zmat_cm = etl::dyn_matrix_cm<std::complex<double>>;

using dvec = etl::dyn_vector<double>;
using dmat = etl::dyn_matrix<double>;
using dmat2 = etl::dyn_matrix<double, 2>;
using dmat3 = etl::dyn_matrix<double, 3>;
using dmat4 = etl::dyn_matrix<double, 4>;

using svec = etl::dyn_vector<float>;
using smat = etl::dyn_matrix<float>;

using cvec = etl::dyn_vector<std::complex<float>>;
using cmat = etl::dyn_matrix<std::complex<float>>;

using zvec = etl::dyn_vector<std::complex<double>>;
using zmat = etl::dyn_matrix<std::complex<double>>;

using mat_policy = VALUES_POLICY(10, 25, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 2000,3000,4000);
using mat_policy_2d = NARY_POLICY(mat_policy, mat_policy);

using conv_1d_large_policy = NARY_POLICY(VALUES_POLICY(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000), VALUES_POLICY(500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000));
using conv_2d_large_policy = NARY_POLICY(VALUES_POLICY(100, 105, 110, 115, 120, 125, 130, 135, 140), VALUES_POLICY(50, 50, 55, 55, 60, 60, 65, 65, 70));

using fft_1d_policy = VALUES_POLICY(10, 100, 1000, 10000, 100000, 500000);
using fft_1d_policy_2 = VALUES_POLICY(16, 64, 256, 1024, 16384, 131072, 1048576, 2097152);
using fft_1d_many_policy = VALUES_POLICY(10, 50, 100, 500, 1000, 5000, 10000);

using fft_2d_policy = NARY_POLICY(
    VALUES_POLICY(8, 16, 32, 64, 128, 256, 512, 1024, 2048),
    VALUES_POLICY(8, 16, 32, 64, 128, 256, 512, 1024, 2048));

using sigmoid_policy = VALUES_POLICY(250, 500, 750, 1000, 1250, 1500, 1750, 2000);

using small_square_policy = NARY_POLICY(VALUES_POLICY(50, 100, 150, 200, 250, 300, 350, 400, 450, 500), VALUES_POLICY(50, 100, 150, 200, 250, 300, 350, 400, 450, 500));
using square_policy = NARY_POLICY(VALUES_POLICY(50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000), VALUES_POLICY(50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000));

using gemv_policy = NARY_POLICY(
    VALUES_POLICY(250, 500, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000),
    VALUES_POLICY(250, 500, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000));

using trans_sub_policy = VALUES_POLICY(100, 200, 300, 400, 500, 600, 700, 800, 900, 1000);
using trans_policy = NARY_POLICY(
    VALUES_POLICY(100, 100, 200, 200, 300, 300, 400, 400, 500, 500, 600, 600, 700, 700, 800, 800, 900, 900, 1000, 1000),
    VALUES_POLICY(100, 200, 200, 300, 300, 400, 400, 500, 500, 600, 600, 700, 700, 800, 800, 900, 900, 1000, 1000, 1100));

#ifdef TEST_SSE
#define SSE_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define SSE_SECTION_FUNCTOR(name, ...)
#endif

#ifdef TEST_AVX
#define AVX_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define AVX_SECTION_FUNCTOR(name, ...)
#endif

#ifdef TEST_MKL
#define MKL_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define MKL_SECTION_FUNCTOR(name, ...)
#endif

#ifdef TEST_BLAS
#define BLAS_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define BLAS_SECTION_FUNCTOR(name, ...)
#endif

#ifdef TEST_CUBLAS
#define CUBLAS_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define CUBLAS_SECTION_FUNCTOR(name, ...)
#endif

#ifdef TEST_CUFFT
#define CUFFT_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define CUFFT_SECTION_FUNCTOR(name, ...)
#endif

#ifdef TEST_MMUL_CONV
#define MC_SECTION_FUNCTOR(name, ...) , CPM_SECTION_FUNCTOR(name, __VA_ARGS__)
#else
#define MC_SECTION_FUNCTOR(name, ...)
#endif
<|endoftext|>


<commit_before>/* -*- mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

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

#include "fflas-ffpack/fflas-ffpack-config.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;

#include "fflas-ffpack/utils/timer.h"
#include "fflas-ffpack/fflas/fflas.h"
#include "fflas-ffpack/utils/args-parser.h"
#include "givaro/modular-integer.h"
#include "fflas-ffpack/paladin/parallel.h"

#ifdef	BENCH_FLINT
#define __GMP_BITS_PER_MP_LIMB 64
extern "C" {
#include "flint/longlong.h"
#include "flint/long_extras.h"
#include "flint/fmpz_mat.h"
#include "flint/fmpz.h"
#include "flint/flint.h"
}

template<typename T>
void write_matrix(Givaro::Integer p, size_t m, size_t n, T* C, size_t ldc){

	size_t www=(p.bitsize()*log(2.))/log(10.);
	for (size_t i=0;i<m;++i){
		cout<<"[ ";
		cout.width(www+1);
		cout<<std::right<<C[i*ldc];
		for (size_t j=1;j<n;++j){
			cout<<" ";
			cout.width(www);
			cout<<std::right<<C[i*ldc+j];
		}
		cout<<"]"<<endl;
	}
	cout<<endl;

}
#endif

int main(int argc, char** argv){
	srand((int)time(NULL));
	srand48(time(NULL));
	static size_t iters = 3 ;
	static Givaro::Integer q = -1 ;
	static unsigned long b = 512 ;
	static size_t m = 512 ;
	static size_t k = 512 ;
	static size_t n = 512 ;
	static int nbw = -1 ;
	static Argument as[] = {
		{ 'q', "-q Q", "Set the field characteristic (-1 for random).",         TYPE_INTEGER , &q },
		{ 'b', "-b B", "Set the bitsize of the random characteristic.",         TYPE_INT , &b },
		{ 'm', "-m M", "Set the dimension m of the matrix.",                    TYPE_INT , &m },
		{ 'k', "-k K", "Set the dimension k of the matrix.",                    TYPE_INT , &k },
		{ 'n', "-n N", "Set the dimension n of the matrix.",                    TYPE_INT , &n },
		{ 'w', "-w N", "Set the number of winograd levels (-1 for random).",    TYPE_INT , &nbw },
		{ 'i', "-i R", "Set number of repetitions.",                            TYPE_INT , &iters },
		END_OF_ARGUMENTS
	};
	FFLAS::parseArguments(argc,argv,as);

	size_t seed= time(NULL);
	typedef Givaro::Modular<Givaro::Integer> Field;
	Givaro::Integer p;
	FFLAS::Timer chrono, TimFreivalds;
	double time=0.,timev=0.;
#ifdef BENCH_FLINT
	double timeFlint=0.;
#endif
	for (size_t loop=0;loop<iters;loop++){
		Givaro::Integer::random_exact_2exp(p, b);
		Givaro::IntPrimeDom IPD;
		IPD.nextprimein(p);

		Field F(p);
		size_t lda,ldb,ldc;
		lda=k;
		ldb=n;
		ldc=n;

		typename Field::RandIter Rand(F,seed);
		Field::Element_ptr A,B,C;
		A= FFLAS::fflas_new(F,m,lda);
		B= FFLAS::fflas_new(F,k,ldb);
		C= FFLAS::fflas_new(F,m,ldc);

// 		for (size_t i=0;i<m;++i)
// 			for (size_t j=0;j<k;++j)
// 				Rand.random(A[i*lda+j]);
// 		for (size_t i=0;i<k;++i)
// 			for (size_t j=0;j<n;++j)
// 				Rand.random(B[i*ldb+j]);
// 		for (size_t i=0;i<m;++i)
// 			for (size_t j=0;j<n;++j)
// 				Rand.random(C[i*ldc+j]);

		PAR_BLOCK { FFLAS::pfrand(F,Rand, m,k,A,m/size_t(MAX_THREADS)); }
		PAR_BLOCK { FFLAS::pfrand(F,Rand, k,n,B,k/MAX_THREADS); }
		PAR_BLOCK { FFLAS::pfzero(F, m,n,C,m/MAX_THREADS); }

		Givaro::Integer alpha,beta;
		alpha=1;
		beta=0;

#ifdef	BENCH_FLINT
		// FLINT MUL //
		fmpz_t modp,tmp;
		fmpz_init(modp);
		fmpz_init(tmp);
		fmpz_set_mpz(modp, *(reinterpret_cast<const mpz_t*>(&p)));
		fmpz_mat_t AA,BB,CC,DD;
		fmpz_mat_init (AA, m, k);
		fmpz_mat_init (BB, k, n);
		fmpz_mat_init (CC, m, n);
		fmpz_mat_init (DD, m, n);
		fmpz_t aalpha, bbeta;
		fmpz_set_mpz(aalpha,*(reinterpret_cast<const mpz_t*>(&alpha)));
		fmpz_set_mpz(bbeta,*(reinterpret_cast<const mpz_t*>(&beta)));

		for (size_t i=0;i<m;++i)
			for (size_t j=0;j<k;++j)
				fmpz_set_mpz(fmpz_mat_entry(AA,i,j),*(reinterpret_cast<const mpz_t*>(A+i*lda+j)));
		for (size_t i=0;i<k;++i)
			for (size_t j=0;j<n;++j)
				fmpz_set_mpz(fmpz_mat_entry(BB,i,j),*(reinterpret_cast<const mpz_t*>(B+i*ldb+j)));
		for (size_t i=0;i<m;++i)
			for (size_t j=0;j<n;++j)
				fmpz_set_mpz(fmpz_mat_entry(CC,i,j),*(reinterpret_cast<const mpz_t*>(C+i*ldc+j)));
		chrono.clear();chrono.start();
		// DD= A.B
		fmpz_mat_mul(DD,AA,BB);
		// CC = beta.C
		fmpz_mat_scalar_mul_fmpz(CC,CC,bbeta);
		// CC = CC + DD.alpha
		fmpz_mat_scalar_addmul_fmpz(CC,DD,aalpha);
		// CC = CC mod p
		for (size_t i=0;i<m;++i)
			for (size_t j=0;j<n;++j)
				fmpz_mod(fmpz_mat_entry(CC,i,j),fmpz_mat_entry(CC,i,j),modp);

		chrono.stop();
		timeFlint+=chrono.usertime();
		fmpz_mat_clear(AA);
		fmpz_mat_clear(BB);
#endif
		//END FLINT CODE //
		using  FFLAS::CuttingStrategy::Recursive;
		using  FFLAS::StrategyParameter::TwoDAdaptive;
		// RNS MUL_LA
		chrono.clear();chrono.start();
		PAR_BLOCK{ FFLAS::fgemm(F,FFLAS::FflasNoTrans,FFLAS::FflasNoTrans,m,n,k,alpha,A,lda,B,ldb,beta,C,ldc, SPLITTER(MAX_THREADS,Recursive,TwoDAdaptive) );
		}

		chrono.stop();
		time+=chrono.usertime();

// 		TimFreivalds.start();
// 		bool pass = FFLAS::freivalds(F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, m,n,k, F.one, A, k, B, n, C,n);
// 		TimFreivalds.stop();
// 		timev+=TimFreivalds.usertime();
// 		if (!pass) std::cout<<"FAILED"<<std::endl;

		FFLAS::fflas_delete(A);
		FFLAS::fflas_delete(B);
		FFLAS::fflas_delete(C);

	}

	double Gflops=(2.*double(m)/1000.*double(n)/1000.*double(k)/1000.0) / chrono.realtime() * double(iters);
// 	Gflops*=p.bitsize()/16.;
	cout<<"Time: "<<time<<"  Gflops: "<<Gflops<<"  | perword: "<< (Gflops*p.bitsize())/64. ;
	FFLAS::writeCommandString(std::cout << '|' << p << " (" << p.bitsize()<<")|", as) << std::endl;

#ifdef BENCH_FLINT
	cout<<"Time FLINT: "<<timeFlint<<endl;
#endif
		return 0;
	}

<commit_msg>remove unused variable warning<commit_after>/* -*- mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

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

#include "fflas-ffpack/fflas-ffpack-config.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;

#include "fflas-ffpack/utils/timer.h"
#include "fflas-ffpack/fflas/fflas.h"
#include "fflas-ffpack/utils/args-parser.h"
#include "givaro/modular-integer.h"
#include "fflas-ffpack/paladin/parallel.h"

#ifdef	BENCH_FLINT
#define __GMP_BITS_PER_MP_LIMB 64
extern "C" {
#include "flint/longlong.h"
#include "flint/long_extras.h"
#include "flint/fmpz_mat.h"
#include "flint/fmpz.h"
#include "flint/flint.h"
}

template<typename T>
void write_matrix(Givaro::Integer p, size_t m, size_t n, T* C, size_t ldc){

	size_t www=(p.bitsize()*log(2.))/log(10.);
	for (size_t i=0;i<m;++i){
		cout<<"[ ";
		cout.width(www+1);
		cout<<std::right<<C[i*ldc];
		for (size_t j=1;j<n;++j){
			cout<<" ";
			cout.width(www);
			cout<<std::right<<C[i*ldc+j];
		}
		cout<<"]"<<endl;
	}
	cout<<endl;

}
#endif

int main(int argc, char** argv){
	srand((int)time(NULL));
	srand48(time(NULL));
	static size_t iters = 3 ;
	static Givaro::Integer q = -1 ;
	static unsigned long b = 512 ;
	static size_t m = 512 ;
	static size_t k = 512 ;
	static size_t n = 512 ;
	static int nbw = -1 ;
	static Argument as[] = {
		{ 'q', "-q Q", "Set the field characteristic (-1 for random).",         TYPE_INTEGER , &q },
		{ 'b', "-b B", "Set the bitsize of the random characteristic.",         TYPE_INT , &b },
		{ 'm', "-m M", "Set the dimension m of the matrix.",                    TYPE_INT , &m },
		{ 'k', "-k K", "Set the dimension k of the matrix.",                    TYPE_INT , &k },
		{ 'n', "-n N", "Set the dimension n of the matrix.",                    TYPE_INT , &n },
		{ 'w', "-w N", "Set the number of winograd levels (-1 for random).",    TYPE_INT , &nbw },
		{ 'i', "-i R", "Set number of repetitions.",                            TYPE_INT , &iters },
		END_OF_ARGUMENTS
	};
	FFLAS::parseArguments(argc,argv,as);

	size_t seed= time(NULL);
	typedef Givaro::Modular<Givaro::Integer> Field;
	Givaro::Integer p;
	FFLAS::Timer chrono, TimFreivalds;
	double time=0.;
#ifdef BENCH_FLINT
	double timeFlint=0.;
#endif
	for (size_t loop=0;loop<iters;loop++){
		Givaro::Integer::random_exact_2exp(p, b);
		Givaro::IntPrimeDom IPD;
		IPD.nextprimein(p);

		Field F(p);
		size_t lda,ldb,ldc;
		lda=k;
		ldb=n;
		ldc=n;

		typename Field::RandIter Rand(F,seed);
		Field::Element_ptr A,B,C;
		A= FFLAS::fflas_new(F,m,lda);
		B= FFLAS::fflas_new(F,k,ldb);
		C= FFLAS::fflas_new(F,m,ldc);

// 		for (size_t i=0;i<m;++i)
// 			for (size_t j=0;j<k;++j)
// 				Rand.random(A[i*lda+j]);
// 		for (size_t i=0;i<k;++i)
// 			for (size_t j=0;j<n;++j)
// 				Rand.random(B[i*ldb+j]);
// 		for (size_t i=0;i<m;++i)
// 			for (size_t j=0;j<n;++j)
// 				Rand.random(C[i*ldc+j]);

		PAR_BLOCK { FFLAS::pfrand(F,Rand, m,k,A,m/size_t(MAX_THREADS)); }
		PAR_BLOCK { FFLAS::pfrand(F,Rand, k,n,B,k/MAX_THREADS); }
		PAR_BLOCK { FFLAS::pfzero(F, m,n,C,m/MAX_THREADS); }

		Givaro::Integer alpha,beta;
		alpha=1;
		beta=0;

#ifdef	BENCH_FLINT
		// FLINT MUL //
		fmpz_t modp,tmp;
		fmpz_init(modp);
		fmpz_init(tmp);
		fmpz_set_mpz(modp, *(reinterpret_cast<const mpz_t*>(&p)));
		fmpz_mat_t AA,BB,CC,DD;
		fmpz_mat_init (AA, m, k);
		fmpz_mat_init (BB, k, n);
		fmpz_mat_init (CC, m, n);
		fmpz_mat_init (DD, m, n);
		fmpz_t aalpha, bbeta;
		fmpz_set_mpz(aalpha,*(reinterpret_cast<const mpz_t*>(&alpha)));
		fmpz_set_mpz(bbeta,*(reinterpret_cast<const mpz_t*>(&beta)));

		for (size_t i=0;i<m;++i)
			for (size_t j=0;j<k;++j)
				fmpz_set_mpz(fmpz_mat_entry(AA,i,j),*(reinterpret_cast<const mpz_t*>(A+i*lda+j)));
		for (size_t i=0;i<k;++i)
			for (size_t j=0;j<n;++j)
				fmpz_set_mpz(fmpz_mat_entry(BB,i,j),*(reinterpret_cast<const mpz_t*>(B+i*ldb+j)));
		for (size_t i=0;i<m;++i)
			for (size_t j=0;j<n;++j)
				fmpz_set_mpz(fmpz_mat_entry(CC,i,j),*(reinterpret_cast<const mpz_t*>(C+i*ldc+j)));
		chrono.clear();chrono.start();
		// DD= A.B
		fmpz_mat_mul(DD,AA,BB);
		// CC = beta.C
		fmpz_mat_scalar_mul_fmpz(CC,CC,bbeta);
		// CC = CC + DD.alpha
		fmpz_mat_scalar_addmul_fmpz(CC,DD,aalpha);
		// CC = CC mod p
		for (size_t i=0;i<m;++i)
			for (size_t j=0;j<n;++j)
				fmpz_mod(fmpz_mat_entry(CC,i,j),fmpz_mat_entry(CC,i,j),modp);

		chrono.stop();
		timeFlint+=chrono.usertime();
		fmpz_mat_clear(AA);
		fmpz_mat_clear(BB);
#endif
		//END FLINT CODE //
		using  FFLAS::CuttingStrategy::Recursive;
		using  FFLAS::StrategyParameter::TwoDAdaptive;
		// RNS MUL_LA
		chrono.clear();chrono.start();
		PAR_BLOCK{ FFLAS::fgemm(F,FFLAS::FflasNoTrans,FFLAS::FflasNoTrans,m,n,k,alpha,A,lda,B,ldb,beta,C,ldc, SPLITTER(MAX_THREADS,Recursive,TwoDAdaptive) );
		}

		chrono.stop();
		time+=chrono.usertime();

// 		TimFreivalds.start();
// 		bool pass = FFLAS::freivalds(F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, m,n,k, F.one, A, k, B, n, C,n);
// 		TimFreivalds.stop();
// 		timev+=TimFreivalds.usertime();
// 		if (!pass) std::cout<<"FAILED"<<std::endl;

		FFLAS::fflas_delete(A);
		FFLAS::fflas_delete(B);
		FFLAS::fflas_delete(C);

	}

	double Gflops=(2.*double(m)/1000.*double(n)/1000.*double(k)/1000.0) / chrono.realtime() * double(iters);
// 	Gflops*=p.bitsize()/16.;
	cout<<"Time: "<<time<<"  Gflops: "<<Gflops<<"  | perword: "<< (Gflops*p.bitsize())/64. ;
	FFLAS::writeCommandString(std::cout << '|' << p << " (" << p.bitsize()<<")|", as) << std::endl;

#ifdef BENCH_FLINT
	cout<<"Time FLINT: "<<timeFlint<<endl;
#endif
		return 0;
	}

<|endoftext|>


<commit_before>/**
 * @file
 */
#include "bi/io/cpp/CppClassGenerator.hpp"

#include "bi/io/cpp/CppResumeGenerator.hpp"
#include "bi/visitor/Gatherer.hpp"
#include "bi/primitive/encode.hpp"

bi::CppClassGenerator::CppClassGenerator(std::ostream& base, const int level,
    const bool header, const bool generic, const Class* currentClass) :
    CppBaseGenerator(base, level, header, generic),
    currentClass(currentClass) {
  //
}

void bi::CppClassGenerator::visit(const Class* o) {
  if (!o->isAlias() && !o->braces->isEmpty()) {
    currentClass = o;
    auto base = dynamic_cast<const NamedType*>(o->base);

    Gatherer<MemberFunction> memberFunctions;
    Gatherer<MemberFiber> memberFibers;
    Gatherer<MemberVariable> memberVariables;
    o->accept(&memberFunctions);
    o->accept(&memberFibers);
    o->accept(&memberVariables);

    if (header) {
      genTemplateParams(o);
      genSourceLine(o->loc);
      start("class " << o->name);
      if (o->has(FINAL)) {
        middle(" final");
      }
      middle(" : public ");
      if (base) {
        middle(base->name);
        if (!base->typeArgs->isEmpty()) {
          middle('<' << base->typeArgs << '>');
        }
      } else {
        middle("libbirch::Any");
      }
      finish(" {");
      line("public:");
      in();
      genSourceLine(o->loc);
      start("using class_type_ = " << o->name);
      genTemplateArgs(o);
      finish(';');
      genSourceLine(o->loc);
      line("using this_type_ = class_type_;");
      genSourceLine(o->loc);
      start("using super_type_ = ");
      if (base) {
        middle(base->name);
        if (!base->typeArgs->isEmpty()) {
          middle('<' << base->typeArgs << '>');
        }
      } else {
        middle("libbirch::Any");
      }
      finish(";\n");

      /* using declarations for member functions and fibers in base classes
       * that are overridden */
      std::set<std::string> names;
      for (auto f : memberFunctions) {
        auto name = f->name->str();
        if (o->scope->overrides(name)) {
          names.insert(name);
        }
      }
      for (auto f : memberFibers) {
        auto name = f->name->str();
        if (o->scope->overrides(name)) {
          names.insert(name);
        }
      }

      genSourceLine(o->loc);
      line("using super_type_::operator=;");
      for (auto name : names) {
        genSourceLine(o->loc);
        line("using super_type_::" << internalise(name) << ';');
      }
      line("");
    }

    /* boilerplate */
    if (header) {
    	if (o->has(ABSTRACT)) {
    	  start("LIBBIRCH_ABSTRACT_CLASS");
    	} else {
    	  start("LIBBIRCH_CLASS");
    	}
      middle('(' << o->name << ", ");
      if (base) {
        middle(base->name);
        if (!base->typeArgs->isEmpty()) {
          middle('<' << base->typeArgs << '>');
        }
      } else {
        middle("libbirch::Any");
      }
      finish(')');
      start("LIBBIRCH_MEMBERS(");
      for (auto iter = memberVariables.begin(); iter != memberVariables.end();
          ++iter) {
        if (iter != memberVariables.begin()) {
          middle(", ");
        }
        middle((*iter)->name);
      }
      finish(")\n");
    }

    /* constructor */
    if (!header) {
      genTemplateParams(o);
      genSourceLine(o->loc);
      start("bi::type::" << o->name);
      genTemplateArgs(o);
      middle("::");
    } else {
      genSourceLine(o->loc);
      start("");
    }
    middle(o->name << '(' << o->params << ')');
    if (header) {
      finish(";\n");
    } else {
      finish(" :");
      in();
      in();
      genSourceLine(o->loc);
      start("super_type_(" << o->args << ')');
      ++inConstructor;
      for (auto o : memberVariables) {
	      finish(',');
        genSourceLine(o->loc);
        start(o->name << '(');
        if (!o->value->isEmpty()) {
          middle(o->value);
        } else if (!o->brackets->isEmpty()) {
          middle("libbirch::make_shape(" << o->brackets << ')');
          if (!o->args->isEmpty()) {
            middle(", " << o->args);
          }
        } else if (!o->args->isEmpty()) {
          middle(o->args);
				}
        middle(')');
      }
      --inConstructor;
      out();
      out();
      finish(" {");
      in();
      line("//");
      out();
      line("}\n");
    }

    /* member variables and functions */
    *this << o->braces->strip();

    /* end class */
    if (header) {
      out();
      line("};\n");
    }

    /* C linkage function */
    if (!o->has(ABSTRACT) && !o->isGeneric() && o->params->isEmpty()) {
      genSourceLine(o->loc);
      if (header) {
        start("extern \"C\" bi::type::" << o->name << "* ");
        finish("make_" << o->name << "_();");
      } else {
        start("bi::type::" << o->name << "* ");
        finish("bi::type::make_" << o->name << "_() {");
        in();
        genSourceLine(o->loc);
        line("return new bi::type::" << o->name << "();");
        genSourceLine(o->loc);
        out();
        line("}");
      }
      line("");
    }
  }
}

void bi::CppClassGenerator::visit(const MemberVariable* o) {
  if (header) {
    line(o->type << ' ' << o->name << ';');
  }
}

void bi::CppClassGenerator::visit(const MemberFunction* o) {
  if ((generic || !o->isGeneric()) && (!o->braces->isEmpty() ||
      (header && o->has(ABSTRACT)))) {
    start("");
    if (header) {
      genTemplateParams(o);
      genSourceLine(o->loc);
      if (o->typeParams->isEmpty()) {
        middle("virtual ");
      }
    } else {
      genTemplateParams(currentClass);
      genTemplateParams(o);
      genSourceLine(o->loc);
    }
    middle(o->returnType << ' ');
    if (!header) {
      middle("bi::type::" << currentClass->name);
      genTemplateArgs(currentClass);
      middle("::");
    }
    middle(o->name << '(' << o->params << ')');
    if (header) {
      if (o->has(FINAL)) {
        middle(" final");
      } else if (o->has(OVERRIDE)) {
        middle(" override");
      } else if (o->has(ABSTRACT)) {
        middle(" = 0");
      }
      finish(';');
    } else {
      finish(" {");
      in();
      genTraceFunction(o->name->str(), o->loc);
      CppBaseGenerator auxBase(base, level, header);
      auxBase << o->braces->strip();
      out();
      finish("}\n");
    }
  }
}

void bi::CppClassGenerator::visit(const MemberFiber* o) {
  if ((generic || !o->isGeneric()) && (!o->braces->isEmpty() ||
      (header && o->has(ABSTRACT)))) {
    /* initialization function */
    if (header) {
      genSourceLine(o->loc);
      start("virtual ");
    } else {
      genTemplateParams(currentClass);
      genSourceLine(o->loc);
      start("");
    }
    middle(o->returnType << ' ');
    if (!header) {
      middle("bi::type::" << currentClass->name);
      genTemplateArgs(currentClass);
      middle("::");
    }
    middle(o->name << '(' << o->params << ')');
    if (header) {
      if (o->has(FINAL)) {
        middle(" final");
      } else if (o->has(OVERRIDE)) {
        middle(" override");
      } else if (o->has(ABSTRACT)) {
        middle(" = 0");
      }
      finish(';');
    } else {
      finish(" {");
      in();
      genTraceFunction(o->name->str(), o->loc);
      genTraceLine(o->loc);
      line("yield_" << currentClass->name << '_' << o->name << '_' << o->number << "_0_();");
      out();
      line("}\n");
    }

    /* start function */
    CppResumeGenerator auxResume(currentClass, o, base, level, header);
    auxResume << o->start;

    /* resume functions */
    Gatherer<Yield> yields;
    o->accept(&yields);
    for (auto yield : yields) {
      if (yield->resume) {
        CppResumeGenerator auxResume(currentClass, o, base, level, header);
        auxResume << yield->resume;
      }
    }
  }
}

void bi::CppClassGenerator::visit(const AssignmentOperator* o) {
  if (!o->braces->isEmpty()) {
    if (header) {
      genSourceLine(o->loc);
      start("virtual ");
    } else {
      genTemplateParams(currentClass);
      genSourceLine(o->loc);
      start("bi::type::");
    }
    middle(currentClass->name);
    genTemplateArgs(currentClass);
    middle("& ");
    if (!header) {
      middle("bi::type::" << currentClass->name);
      genTemplateArgs(currentClass);
      middle("::");
    }
    middle("operator=(" << o->single << ')');
    if (header) {
      finish(';');
    } else {
      finish(" {");
      in();
      genTraceFunction("<assignment>", o->loc);
      CppBaseGenerator auxBase(base, level, header);
      auxBase << o->braces->strip();
      genSourceLine(o->loc);
      line("return *this;");
      out();
      finish("}\n");
    }
  }
}

void bi::CppClassGenerator::visit(const ConversionOperator* o) {
  if (!o->braces->isEmpty()) {
    if (header) {
      genSourceLine(o->loc);
      start("virtual ");
    } else {
      genTemplateParams(currentClass);
      genSourceLine(o->loc);
      start("bi::type::" << currentClass->name);
      genTemplateArgs(currentClass);
      middle("::");
    }
    middle("operator " << o->returnType << "()");
    if (header) {
      finish(';');
    } else {
      finish(" {");
      in();
      genTraceFunction("<conversion>", o->loc);
      CppBaseGenerator auxBase(base, level, header);
      auxBase << o->braces->strip();
      out();
      finish("}\n");
    }
  }
}
<commit_msg>Fixed C++ code generation for generic member functions declared final.<commit_after>/**
 * @file
 */
#include "bi/io/cpp/CppClassGenerator.hpp"

#include "bi/io/cpp/CppResumeGenerator.hpp"
#include "bi/visitor/Gatherer.hpp"
#include "bi/primitive/encode.hpp"

bi::CppClassGenerator::CppClassGenerator(std::ostream& base, const int level,
    const bool header, const bool generic, const Class* currentClass) :
    CppBaseGenerator(base, level, header, generic),
    currentClass(currentClass) {
  //
}

void bi::CppClassGenerator::visit(const Class* o) {
  if (!o->isAlias() && !o->braces->isEmpty()) {
    currentClass = o;
    auto base = dynamic_cast<const NamedType*>(o->base);

    Gatherer<MemberFunction> memberFunctions;
    Gatherer<MemberFiber> memberFibers;
    Gatherer<MemberVariable> memberVariables;
    o->accept(&memberFunctions);
    o->accept(&memberFibers);
    o->accept(&memberVariables);

    if (header) {
      genTemplateParams(o);
      genSourceLine(o->loc);
      start("class " << o->name);
      if (o->has(FINAL)) {
        middle(" final");
      }
      middle(" : public ");
      if (base) {
        middle(base->name);
        if (!base->typeArgs->isEmpty()) {
          middle('<' << base->typeArgs << '>');
        }
      } else {
        middle("libbirch::Any");
      }
      finish(" {");
      line("public:");
      in();
      genSourceLine(o->loc);
      start("using class_type_ = " << o->name);
      genTemplateArgs(o);
      finish(';');
      genSourceLine(o->loc);
      line("using this_type_ = class_type_;");
      genSourceLine(o->loc);
      start("using super_type_ = ");
      if (base) {
        middle(base->name);
        if (!base->typeArgs->isEmpty()) {
          middle('<' << base->typeArgs << '>');
        }
      } else {
        middle("libbirch::Any");
      }
      finish(";\n");

      /* using declarations for member functions and fibers in base classes
       * that are overridden */
      std::set<std::string> names;
      for (auto f : memberFunctions) {
        auto name = f->name->str();
        if (o->scope->overrides(name)) {
          names.insert(name);
        }
      }
      for (auto f : memberFibers) {
        auto name = f->name->str();
        if (o->scope->overrides(name)) {
          names.insert(name);
        }
      }

      genSourceLine(o->loc);
      line("using super_type_::operator=;");
      for (auto name : names) {
        genSourceLine(o->loc);
        line("using super_type_::" << internalise(name) << ';');
      }
      line("");
    }

    /* boilerplate */
    if (header) {
    	if (o->has(ABSTRACT)) {
    	  start("LIBBIRCH_ABSTRACT_CLASS");
    	} else {
    	  start("LIBBIRCH_CLASS");
    	}
      middle('(' << o->name << ", ");
      if (base) {
        middle(base->name);
        if (!base->typeArgs->isEmpty()) {
          middle('<' << base->typeArgs << '>');
        }
      } else {
        middle("libbirch::Any");
      }
      finish(')');
      start("LIBBIRCH_MEMBERS(");
      for (auto iter = memberVariables.begin(); iter != memberVariables.end();
          ++iter) {
        if (iter != memberVariables.begin()) {
          middle(", ");
        }
        middle((*iter)->name);
      }
      finish(")\n");
    }

    /* constructor */
    if (!header) {
      genTemplateParams(o);
      genSourceLine(o->loc);
      start("bi::type::" << o->name);
      genTemplateArgs(o);
      middle("::");
    } else {
      genSourceLine(o->loc);
      start("");
    }
    middle(o->name << '(' << o->params << ')');
    if (header) {
      finish(";\n");
    } else {
      finish(" :");
      in();
      in();
      genSourceLine(o->loc);
      start("super_type_(" << o->args << ')');
      ++inConstructor;
      for (auto o : memberVariables) {
	      finish(',');
        genSourceLine(o->loc);
        start(o->name << '(');
        if (!o->value->isEmpty()) {
          middle(o->value);
        } else if (!o->brackets->isEmpty()) {
          middle("libbirch::make_shape(" << o->brackets << ')');
          if (!o->args->isEmpty()) {
            middle(", " << o->args);
          }
        } else if (!o->args->isEmpty()) {
          middle(o->args);
				}
        middle(')');
      }
      --inConstructor;
      out();
      out();
      finish(" {");
      in();
      line("//");
      out();
      line("}\n");
    }

    /* member variables and functions */
    *this << o->braces->strip();

    /* end class */
    if (header) {
      out();
      line("};\n");
    }

    /* C linkage function */
    if (!o->has(ABSTRACT) && !o->isGeneric() && o->params->isEmpty()) {
      genSourceLine(o->loc);
      if (header) {
        start("extern \"C\" bi::type::" << o->name << "* ");
        finish("make_" << o->name << "_();");
      } else {
        start("bi::type::" << o->name << "* ");
        finish("bi::type::make_" << o->name << "_() {");
        in();
        genSourceLine(o->loc);
        line("return new bi::type::" << o->name << "();");
        genSourceLine(o->loc);
        out();
        line("}");
      }
      line("");
    }
  }
}

void bi::CppClassGenerator::visit(const MemberVariable* o) {
  if (header) {
    line(o->type << ' ' << o->name << ';');
  }
}

void bi::CppClassGenerator::visit(const MemberFunction* o) {
  if ((generic || !o->isGeneric()) && (!o->braces->isEmpty() ||
      (header && o->has(ABSTRACT)))) {
    start("");
    if (header) {
      genTemplateParams(o);
      genSourceLine(o->loc);
      if (o->typeParams->isEmpty()) {
        middle("virtual ");
      }
    } else {
      genTemplateParams(currentClass);
      genTemplateParams(o);
      genSourceLine(o->loc);
    }
    middle(o->returnType << ' ');
    if (!header) {
      middle("bi::type::" << currentClass->name);
      genTemplateArgs(currentClass);
      middle("::");
    }
    middle(o->name << '(' << o->params << ')');
    if (header) {
      if (o->has(FINAL) && !o->isGeneric()) {
        middle(" final");
      } else if (o->has(OVERRIDE)) {
        middle(" override");
      } else if (o->has(ABSTRACT)) {
        middle(" = 0");
      }
      finish(';');
    } else {
      finish(" {");
      in();
      genTraceFunction(o->name->str(), o->loc);
      CppBaseGenerator auxBase(base, level, header);
      auxBase << o->braces->strip();
      out();
      finish("}\n");
    }
  }
}

void bi::CppClassGenerator::visit(const MemberFiber* o) {
  if ((generic || !o->isGeneric()) && (!o->braces->isEmpty() ||
      (header && o->has(ABSTRACT)))) {
    /* initialization function */
    if (header) {
      genSourceLine(o->loc);
      start("virtual ");
    } else {
      genTemplateParams(currentClass);
      genSourceLine(o->loc);
      start("");
    }
    middle(o->returnType << ' ');
    if (!header) {
      middle("bi::type::" << currentClass->name);
      genTemplateArgs(currentClass);
      middle("::");
    }
    middle(o->name << '(' << o->params << ')');
    if (header) {
      if (o->has(FINAL) && !o->isGeneric()) {
        middle(" final");
      } else if (o->has(OVERRIDE)) {
        middle(" override");
      } else if (o->has(ABSTRACT)) {
        middle(" = 0");
      }
      finish(';');
    } else {
      finish(" {");
      in();
      genTraceFunction(o->name->str(), o->loc);
      genTraceLine(o->loc);
      line("yield_" << currentClass->name << '_' << o->name << '_' << o->number << "_0_();");
      out();
      line("}\n");
    }

    /* start function */
    CppResumeGenerator auxResume(currentClass, o, base, level, header);
    auxResume << o->start;

    /* resume functions */
    Gatherer<Yield> yields;
    o->accept(&yields);
    for (auto yield : yields) {
      if (yield->resume) {
        CppResumeGenerator auxResume(currentClass, o, base, level, header);
        auxResume << yield->resume;
      }
    }
  }
}

void bi::CppClassGenerator::visit(const AssignmentOperator* o) {
  if (!o->braces->isEmpty()) {
    if (header) {
      genSourceLine(o->loc);
      start("virtual ");
    } else {
      genTemplateParams(currentClass);
      genSourceLine(o->loc);
      start("bi::type::");
    }
    middle(currentClass->name);
    genTemplateArgs(currentClass);
    middle("& ");
    if (!header) {
      middle("bi::type::" << currentClass->name);
      genTemplateArgs(currentClass);
      middle("::");
    }
    middle("operator=(" << o->single << ')');
    if (header) {
      finish(';');
    } else {
      finish(" {");
      in();
      genTraceFunction("<assignment>", o->loc);
      CppBaseGenerator auxBase(base, level, header);
      auxBase << o->braces->strip();
      genSourceLine(o->loc);
      line("return *this;");
      out();
      finish("}\n");
    }
  }
}

void bi::CppClassGenerator::visit(const ConversionOperator* o) {
  if (!o->braces->isEmpty()) {
    if (header) {
      genSourceLine(o->loc);
      start("virtual ");
    } else {
      genTemplateParams(currentClass);
      genSourceLine(o->loc);
      start("bi::type::" << currentClass->name);
      genTemplateArgs(currentClass);
      middle("::");
    }
    middle("operator " << o->returnType << "()");
    if (header) {
      finish(';');
    } else {
      finish(" {");
      in();
      genTraceFunction("<conversion>", o->loc);
      CppBaseGenerator auxBase(base, level, header);
      auxBase << o->braces->strip();
      out();
      finish("}\n");
    }
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011-2013 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#pragma warning(push)
// choorucode.com/2010/08/30/visual-c-c4996-warning-on-copy-with-array-parameters
#pragma warning(disable: 4996)
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
#pragma warning(pop)
#include <bitcoin/bitcoin.hpp>
#include "script_json/vectors.hpp"

using namespace bc;

bool is_number(const std::string& token)
{
    if (boost::all(token, boost::is_digit()))
        return true;
    // Now check for negative numbers
    if (!boost::starts_with(token, "-"))
        return false;
    std::string numeric_part(token.begin() + 1, token.end());
    return boost::all(numeric_part, boost::is_digit());
}

bool is_hex_data(const std::string& token)
{
    if (!boost::starts_with(token, "0x"))
        return false;
    std::string hex_part(token.begin() + 2, token.end());
    return boost::all(hex_part, [](char c) { return std::isxdigit(c); });
}

bool is_quoted_string(const std::string& token)
{
    if (token.size() < 2)
        return false;
    return boost::starts_with(token, "'") && boost::ends_with(token, "'");
}

opcode token_to_opcode(const std::string& token)
{
    std::string lower_token = token;
    boost::algorithm::to_lower(lower_token);
    return string_to_opcode(lower_token);
}

bool is_opcode(const std::string& token)
{
    return token_to_opcode(token) != opcode::bad_operation;
}

bool is_opx(int64_t value)
{
    return value == -1 || (1 <= value && value <= 16);
}

void push_literal(data_chunk& raw_script, int64_t value)
{
    BITCOIN_ASSERT(is_opx(value));
    switch (value)
    {
        case -1:
            raw_script.push_back(static_cast<uint8_t>(opcode::negative_1));
            return;

#define PUSH_X(n) \
        case n: \
            raw_script.push_back(static_cast<uint8_t>(opcode::op_##n)); \
            return;

        PUSH_X(1);
        PUSH_X(2);
        PUSH_X(3);
        PUSH_X(4);
        PUSH_X(5);
        PUSH_X(6);
        PUSH_X(7);
        PUSH_X(8);
        PUSH_X(9);
        PUSH_X(10);
        PUSH_X(11);
        PUSH_X(12);
        PUSH_X(13);
        PUSH_X(14);
        PUSH_X(15);
        PUSH_X(16);
    }
}

void push_data(data_chunk& raw_script, const data_chunk& data)
{
    operation op;
    // pushdata1 = 76
    if (data.empty())
        op.code = opcode::zero;
    else if (data.size() < 76)
        op.code = opcode::special;
    else if (data.size() <= 0xff)
        op.code = opcode::pushdata1;
    else if (data.size() <= 0xffff)
        op.code = opcode::pushdata2;
    else
    {
        BITCOIN_ASSERT(data.size() <= 0xffffffff);
        op.code = opcode::pushdata4;
    }
    op.data = data;
    script_type tmp_script;
    tmp_script.push_operation(op);
    extend_data(raw_script, save_script(tmp_script));
}

bool parse_token(data_chunk& raw_script, std::string token)
{
    boost::algorithm::trim(token);
    // skip this
    if (token.empty())
        return true;
    static data_chunk hex_raw;
    if (token == "ENDING" || !is_hex_data(token))
    {
        if (!hex_raw.empty())
        {
            extend_data(raw_script, hex_raw);
            hex_raw.resize(0);
        }
    }
    if (token == "ENDING")
    {
        // Do nothing...
    }
    else if (is_number(token))
    {
        int64_t value = boost::lexical_cast<int64_t>(token);
        if (is_opx(value))
            push_literal(raw_script, value);
        else
        {
            script_number bignum(value);
            push_data(raw_script, bignum.data());
        }
    }
    else if (is_hex_data(token))
    {
        std::string hex_part(token.begin() + 2, token.end());
        data_chunk raw_data = decode_hex(hex_part);
        extend_data(hex_raw, raw_data);
    }
    else if (is_quoted_string(token))
    {
        data_chunk inner_value(token.begin() + 1, token.end() - 1);
        push_data(raw_script, inner_value);
    }
    else if (is_opcode(token))
    {
        opcode tokenized_opcode = token_to_opcode(token);
        raw_script.push_back(static_cast<uint8_t>(tokenized_opcode));
    }
    else
    {
        log_error() << "Token parsing failed with: " << token;
        return false;
    }
    return true;
}

bool parse(script_type& result_script, std::string format)
{
    boost::algorithm::trim(format);
    if (format.empty())
        return true;
    std::vector<std::string> tokens;
    boost::split(tokens, format, boost::is_any_of(" "));
    data_chunk raw_script;
    for (const auto& token: tokens)
        if (!parse_token(raw_script, token))
            return false;
    parse_token(raw_script, "ENDING");
    try
    {
        result_script = parse_script(raw_script);
    }
    catch (end_of_stream)
    {
        return false;
    }
    if (result_script.operations().empty())
        return false;
    return true;
}

bool run_script(const script_test& test)
{
    script_type input, output;
    if (!parse(input, test.input))
        return false;
    if (!parse(output, test.output))
        return false;
    transaction_type tx;
    //log_debug() << test.input << " -> " << input;
    //log_debug() << test.output << " -> " << output;
    return output.run(input, tx, 0);
}

void ignore_output(log_level,
    const std::string&, const std::string&)
{
}

BOOST_AUTO_TEST_SUITE(script_tests)

BOOST_AUTO_TEST_CASE(script_json_valid)
{
    for (const script_test& test: valid_scripts)
    {
        BOOST_REQUIRE(run_script(test));
    }
}

BOOST_AUTO_TEST_CASE(script_json_invalid)
{
    // Shut up!
    log_fatal().set_output_function(ignore_output);
    for (const script_test& test: invalid_scripts)
    {
        BOOST_REQUIRE(!run_script(test));
    }
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Conditionally include warning suppression pragmas (VC builds only).<commit_after>/*
 * Copyright (c) 2011-2013 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifdef _MSC_VER
#pragma warning(push)
// choorucode.com/2010/08/30/visual-c-c4996-warning-on-copy-with-array-parameters
#pragma warning(disable: 4996)
#endif
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#include <bitcoin/bitcoin.hpp>
#include "script_json/vectors.hpp"

using namespace bc;

bool is_number(const std::string& token)
{
    if (boost::all(token, boost::is_digit()))
        return true;
    // Now check for negative numbers
    if (!boost::starts_with(token, "-"))
        return false;
    std::string numeric_part(token.begin() + 1, token.end());
    return boost::all(numeric_part, boost::is_digit());
}

bool is_hex_data(const std::string& token)
{
    if (!boost::starts_with(token, "0x"))
        return false;
    std::string hex_part(token.begin() + 2, token.end());
    return boost::all(hex_part, [](char c) { return std::isxdigit(c); });
}

bool is_quoted_string(const std::string& token)
{
    if (token.size() < 2)
        return false;
    return boost::starts_with(token, "'") && boost::ends_with(token, "'");
}

opcode token_to_opcode(const std::string& token)
{
    std::string lower_token = token;
    boost::algorithm::to_lower(lower_token);
    return string_to_opcode(lower_token);
}

bool is_opcode(const std::string& token)
{
    return token_to_opcode(token) != opcode::bad_operation;
}

bool is_opx(int64_t value)
{
    return value == -1 || (1 <= value && value <= 16);
}

void push_literal(data_chunk& raw_script, int64_t value)
{
    BITCOIN_ASSERT(is_opx(value));
    switch (value)
    {
        case -1:
            raw_script.push_back(static_cast<uint8_t>(opcode::negative_1));
            return;

#define PUSH_X(n) \
        case n: \
            raw_script.push_back(static_cast<uint8_t>(opcode::op_##n)); \
            return;

        PUSH_X(1);
        PUSH_X(2);
        PUSH_X(3);
        PUSH_X(4);
        PUSH_X(5);
        PUSH_X(6);
        PUSH_X(7);
        PUSH_X(8);
        PUSH_X(9);
        PUSH_X(10);
        PUSH_X(11);
        PUSH_X(12);
        PUSH_X(13);
        PUSH_X(14);
        PUSH_X(15);
        PUSH_X(16);
    }
}

void push_data(data_chunk& raw_script, const data_chunk& data)
{
    operation op;
    // pushdata1 = 76
    if (data.empty())
        op.code = opcode::zero;
    else if (data.size() < 76)
        op.code = opcode::special;
    else if (data.size() <= 0xff)
        op.code = opcode::pushdata1;
    else if (data.size() <= 0xffff)
        op.code = opcode::pushdata2;
    else
    {
        BITCOIN_ASSERT(data.size() <= 0xffffffff);
        op.code = opcode::pushdata4;
    }
    op.data = data;
    script_type tmp_script;
    tmp_script.push_operation(op);
    extend_data(raw_script, save_script(tmp_script));
}

bool parse_token(data_chunk& raw_script, std::string token)
{
    boost::algorithm::trim(token);
    // skip this
    if (token.empty())
        return true;
    static data_chunk hex_raw;
    if (token == "ENDING" || !is_hex_data(token))
    {
        if (!hex_raw.empty())
        {
            extend_data(raw_script, hex_raw);
            hex_raw.resize(0);
        }
    }
    if (token == "ENDING")
    {
        // Do nothing...
    }
    else if (is_number(token))
    {
        int64_t value = boost::lexical_cast<int64_t>(token);
        if (is_opx(value))
            push_literal(raw_script, value);
        else
        {
            script_number bignum(value);
            push_data(raw_script, bignum.data());
        }
    }
    else if (is_hex_data(token))
    {
        std::string hex_part(token.begin() + 2, token.end());
        data_chunk raw_data = decode_hex(hex_part);
        extend_data(hex_raw, raw_data);
    }
    else if (is_quoted_string(token))
    {
        data_chunk inner_value(token.begin() + 1, token.end() - 1);
        push_data(raw_script, inner_value);
    }
    else if (is_opcode(token))
    {
        opcode tokenized_opcode = token_to_opcode(token);
        raw_script.push_back(static_cast<uint8_t>(tokenized_opcode));
    }
    else
    {
        log_error() << "Token parsing failed with: " << token;
        return false;
    }
    return true;
}

bool parse(script_type& result_script, std::string format)
{
    boost::algorithm::trim(format);
    if (format.empty())
        return true;
    std::vector<std::string> tokens;
    boost::split(tokens, format, boost::is_any_of(" "));
    data_chunk raw_script;
    for (const auto& token: tokens)
        if (!parse_token(raw_script, token))
            return false;
    parse_token(raw_script, "ENDING");
    try
    {
        result_script = parse_script(raw_script);
    }
    catch (end_of_stream)
    {
        return false;
    }
    if (result_script.operations().empty())
        return false;
    return true;
}

bool run_script(const script_test& test)
{
    script_type input, output;
    if (!parse(input, test.input))
        return false;
    if (!parse(output, test.output))
        return false;
    transaction_type tx;
    //log_debug() << test.input << " -> " << input;
    //log_debug() << test.output << " -> " << output;
    return output.run(input, tx, 0);
}

void ignore_output(log_level,
    const std::string&, const std::string&)
{
}

BOOST_AUTO_TEST_SUITE(script_tests)

BOOST_AUTO_TEST_CASE(script_json_valid)
{
    for (const script_test& test: valid_scripts)
    {
        BOOST_REQUIRE(run_script(test));
    }
}

BOOST_AUTO_TEST_CASE(script_json_invalid)
{
    // Shut up!
    log_fatal().set_output_function(ignore_output);
    for (const script_test& test: invalid_scripts)
    {
        BOOST_REQUIRE(!run_script(test));
    }
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>/***********************************************************************
 test/string.cpp - Tests the behavior of mysqlpp::String, particularly
	its data conversion methods.

 Copyright (c) 2007-2008 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the
 CREDITS file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

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

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include <mysql++.h>

#include <iostream>

// Does an equality comparison on the value, forcing the string to
// convert itself to T on the way.  Note that we do this test in terms
// of greater and less than to avoid pedantic GCC warnings for the
// floating point type tests.
template <typename T>
static bool
test_equality(const mysqlpp::String& s, T value)
{
	T converted = s.conv(value);
	if ((value < converted) || (value > converted)) {
		std::cerr << "Type conversion to " << typeid(T).name() <<
				" failed: \"" << s << "\" != \"" << value << "\"." <<
				std::endl;
		return false;
	}
	else {
		return true;
	}
}

// Check that we can convert strings with decimals in them to native
// floating-point values, regardless of locale.
static bool
test_float_conversion()
{
	// This stuff should just work
	if (!test_equality(mysqlpp::String("123.00"), 123)) return false;
	if (!test_equality(mysqlpp::String("123."), 123)) return false;

	// This is trickier: MySQL ignores the system locale when it comes
	// to decimal separators, always using '.', so ensure the conversion
	// stuff in MySQL++ does the right thing regardless.  Test against
	// this system's current locale, an arbitrary European one where ','
	// is the decimal separator, and the "C" locale where it's '.'.
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale old_locale = std::locale::global(std::locale::classic());
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale::global(std::locale("de_DE"));
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale::global(old_locale);

	// Check that we choke on silly float-like values
	try {
		if (test_equality(mysqlpp::String("621.20.0"), 621.2)) {
			std::cerr << "Quasi-FP with two decimal points "
					"converting without error!" << std::endl;
		}
		return false;
	}
	catch (const mysqlpp::BadConversion&) {
		return true;
	}
}

// Tries to convert the given string to an int.  Returns false if we got
// a BadConversion exception and didn't expect it, or didn't get one we
// expected.  Returns false on all other exceptions regardless.
static bool
test_int_conversion(const mysqlpp::String& s, bool throw_expected)
{
	// Try the conversion
	bool conv_threw = false;
	try {
		int converted = s;
		(void)converted;	// pedantic warning squisher
	}
	catch (const mysqlpp::BadConversion&) {
		conv_threw = true;
	}
	catch (const std::exception& e) {
		std::cerr << "Unexpected " << typeid(e).name() <<
				" exception in test_int_conv: " << e.what() << std::endl;
		return false;
	}
	catch (...) {
		std::cerr << "Like, totally bogus exception in test_int_conv, "
				"man!" << std::endl;
		return false;
	}

	// Did it do what we expected?
	if (throw_expected == conv_threw) {
		return true;
	}
	else {
		std::cerr << "Conversion of \"" << s << "\" to int " <<
				(conv_threw ? "did not " : "") << "throw; did " <<
				(throw_expected ? "not " : "") << "expect it to." <<
				std::endl;
		return false;
	}
}

// Ensures that the program's locale doesn't affect our floating-point
// conversions.  ('.' vs. ',' stuff.)
static bool
test_locale()
{

	return true;
}

// Ensures numeric conversions of many different types get handled
// correctly.
static bool
test_numeric(const mysqlpp::String& s, int value)
{
	return	test_equality(s, static_cast<signed char>(value)) &&
			test_equality(s, static_cast<unsigned char>(value)) &&
			test_equality(s, static_cast<signed short>(value)) &&
			test_equality(s, static_cast<unsigned short>(value)) &&
			test_equality(s, static_cast<signed int>(value)) &&
			test_equality(s, static_cast<unsigned int>(value)) &&
			test_equality(s, static_cast<signed long>(value)) &&
			test_equality(s, static_cast<unsigned long>(value)) &&
#if !defined(NO_LONG_LONGS)
			test_equality(s, static_cast<mysqlpp::longlong>(value)) &&
			test_equality(s, static_cast<mysqlpp::ulonglong>(value)) &&
#endif
			test_equality(s, static_cast<float>(value)) &&
			test_equality(s, static_cast<double>(value));
}

static bool
test_quote_q(const mysqlpp::String& s, bool expected)
{
	if (s.quote_q() == expected) {
		return true;
	}
	else {
		std::cerr << s.type().name() << " should" <<
				(expected ? "" : " NOT") << " be quoted." << std::endl;
		return false;
	}
}

int
main(int, char* argv[])
{
	try {
		int failures = 0;
		mysqlpp::String empty;
		mysqlpp::String zero("0");
		mysqlpp::String nonzero("42");

		failures += test_equality(empty, mysqlpp::Date()) == false;
		failures += test_equality(empty,
				mysqlpp::DateTime(0, 0, 0, 0, 0, 0)) == false;
		failures += test_equality(empty, mysqlpp::Time()) == false;
		failures += test_equality(empty, false) == false;
		failures += test_equality(nonzero, true) == false;
		failures += test_numeric(empty, 0) == false;
		failures += test_numeric(zero, 0) == false;
		failures += test_numeric(nonzero, 42) == false;
		failures += test_quote_q(empty, true) == false;
		failures += test_quote_q(mysqlpp::String("1", typeid(int)),
				false) == false;
		failures += test_locale() == false;
		failures += test_float_conversion() == false;
		failures += test_float_conversion() == false;

		return failures;
	}
	catch (mysqlpp::Exception& e) {
		std::cerr << "Unexpected MySQL++ exception caught in " <<
				argv[0] << ": " << e.what() << std::endl;
		return 1;
	}
	catch (std::exception& e) {
		std::cerr << "Unexpected C++ exception caught in " <<
				argv[0] << ": " << e.what() << std::endl;
		return 1;
	}

}

<commit_msg>Wrote a test case for test/string.cpp that wasn't getting called. (Ooopsie.)  Made up several ways to call it, so now we know string to int conversions are working.<commit_after>/***********************************************************************
 test/string.cpp - Tests the behavior of mysqlpp::String, particularly
	its data conversion methods.

 Copyright (c) 2007-2008 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the
 CREDITS file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

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

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include <mysql++.h>

#include <iostream>

// Does an equality comparison on the value, forcing the string to
// convert itself to T on the way.  Note that we do this test in terms
// of greater and less than to avoid pedantic GCC warnings for the
// floating point type tests.
template <typename T>
static bool
test_equality(const mysqlpp::String& s, T value)
{
	T converted = s.conv(value);
	if ((value < converted) || (value > converted)) {
		std::cerr << "Type conversion to " << typeid(T).name() <<
				" failed: \"" << s << "\" != \"" << value << "\"." <<
				std::endl;
		return false;
	}
	else {
		return true;
	}
}

// Check that we can convert strings with decimals in them to native
// floating-point values, regardless of locale.
static bool
test_float_conversion()
{
	// This stuff should just work
	if (!test_equality(mysqlpp::String("123.00"), 123)) return false;
	if (!test_equality(mysqlpp::String("123."), 123)) return false;

	// This is trickier: MySQL ignores the system locale when it comes
	// to decimal separators, always using '.', so ensure the conversion
	// stuff in MySQL++ does the right thing regardless.  Test against
	// this system's current locale, an arbitrary European one where ','
	// is the decimal separator, and the "C" locale where it's '.'.
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale old_locale = std::locale::global(std::locale::classic());
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale::global(std::locale("de_DE"));
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale::global(old_locale);

	// Check that we choke on silly float-like values
	try {
		if (test_equality(mysqlpp::String("621.20.0"), 621.2)) {
			std::cerr << "Quasi-FP with two decimal points "
					"converting without error!" << std::endl;
		}
		return false;
	}
	catch (const mysqlpp::BadConversion&) {
		return true;
	}
}

// Tries to convert the given string to an int.  Returns false if we got
// a BadConversion exception and didn't expect it, or didn't get one we
// expected.  Returns false on all other exceptions regardless.
static bool
test_int_conversion(const mysqlpp::String& s, bool throw_expected)
{
	// Try the conversion
	bool conv_threw = false;
	try {
		int converted = s;
		(void)converted;	// pedantic warning squisher
	}
	catch (const mysqlpp::BadConversion&) {
		conv_threw = true;
	}
	catch (const std::exception& e) {
		std::cerr << "Unexpected " << typeid(e).name() <<
				" exception in test_int_conv: " << e.what() << std::endl;
		return false;
	}
	catch (...) {
		std::cerr << "Like, totally bogus exception in test_int_conv, "
				"man!" << std::endl;
		return false;
	}

	// Did it do what we expected?
	if (throw_expected == conv_threw) {
		return true;
	}
	else {
		std::cerr << "Conversion of \"" << s << "\" to int " <<
				(conv_threw ? "did not throw" : "threw") << "; " <<
				(throw_expected ? "did not expect" : "expected") <<
				" it to." << std::endl;
		return false;
	}
}

// Ensures that the program's locale doesn't affect our floating-point
// conversions.  ('.' vs. ',' stuff.)
static bool
test_locale()
{

	return true;
}

// Ensures numeric conversions of many different types get handled
// correctly.
static bool
test_numeric(const mysqlpp::String& s, int value)
{
	return	test_equality(s, static_cast<signed char>(value)) &&
			test_equality(s, static_cast<unsigned char>(value)) &&
			test_equality(s, static_cast<signed short>(value)) &&
			test_equality(s, static_cast<unsigned short>(value)) &&
			test_equality(s, static_cast<signed int>(value)) &&
			test_equality(s, static_cast<unsigned int>(value)) &&
			test_equality(s, static_cast<signed long>(value)) &&
			test_equality(s, static_cast<unsigned long>(value)) &&
#if !defined(NO_LONG_LONGS)
			test_equality(s, static_cast<mysqlpp::longlong>(value)) &&
			test_equality(s, static_cast<mysqlpp::ulonglong>(value)) &&
#endif
			test_equality(s, static_cast<float>(value)) &&
			test_equality(s, static_cast<double>(value));
}

static bool
test_quote_q(const mysqlpp::String& s, bool expected)
{
	if (s.quote_q() == expected) {
		return true;
	}
	else {
		std::cerr << s.type().name() << " should" <<
				(expected ? "" : " NOT") << " be quoted." << std::endl;
		return false;
	}
}

int
main(int, char* argv[])
{
	try {
		int failures = 0;
		mysqlpp::String empty;
		mysqlpp::String zero("0");
		mysqlpp::String nonzero("42");
		mysqlpp::String intable1("42.");
		mysqlpp::String intable2("42.0");
		mysqlpp::String nonint("42.1");

		failures += test_equality(empty, mysqlpp::Date()) == false;
		failures += test_equality(empty,
				mysqlpp::DateTime(0, 0, 0, 0, 0, 0)) == false;
		failures += test_equality(empty, mysqlpp::Time()) == false;
		failures += test_equality(empty, false) == false;
		failures += test_equality(nonzero, true) == false;
		failures += test_numeric(empty, 0) == false;
		failures += test_numeric(zero, 0) == false;
		failures += test_numeric(nonzero, 42) == false;
		failures += test_quote_q(empty, true) == false;
		failures += test_quote_q(mysqlpp::String("1", typeid(int)),
				false) == false;
		failures += test_locale() == false;
		failures += test_float_conversion() == false;
		failures += test_float_conversion() == false;
		failures += test_int_conversion(empty, false) == false;
		failures += test_int_conversion(zero, false) == false;
		failures += test_int_conversion(nonzero, false) == false;
		failures += test_int_conversion(intable1, false) == false;
		failures += test_int_conversion(intable2, false) == false;
		failures += test_int_conversion(nonint, true) == false;

		return failures;
	}
	catch (mysqlpp::Exception& e) {
		std::cerr << "Unexpected MySQL++ exception caught in " <<
				argv[0] << ": " << e.what() << std::endl;
		return 1;
	}
	catch (std::exception& e) {
		std::cerr << "Unexpected C++ exception caught in " <<
				argv[0] << ": " << e.what() << std::endl;
		return 1;
	}

}

<|endoftext|>