<commit_before>#include <mos/gfx/text.hpp>
#include <mos/util.hpp>
#include <glm/glm.hpp>
#include <iostream>
#include <glm/gtc/matrix_transform.hpp>
namespace mos {
namespace gfx {
Text::Text(const std::string &txt, const Font &font, const glm::mat4 &transform,
           const float spacing)
    : model_("Text", std::make_shared<Mesh>(Mesh()),
             transform),
      font_(font), spacing(spacing) {
  model_.material.albedo = glm::vec3(1.0f);
  model_.material.opacity = 0.0f;
  model_.material.emission = glm::vec3(1.0f);
  model_.material.albedo_map = font.texture;
  text(txt);
}

Text::~Text() {}

std::string Text::text() const { return text_; }

void Text::text(const std::string &text) {
  if (text_.compare(text) != 0) {
    text_ = text;
    std::vector<std::string> lines = mos::split(text_, '\n');
    model_.mesh->clear();

    float line_index = 0.0f;
    const float line_height = -font_.height();
    for (auto & line : lines) {
      float index = 0.0f;
      for (auto & c : line) {
        auto character = font_.characters.at(c);
        float u1 = character.rect_x / ((float)model_.material.albedo_map->width());
        float u2 = (character.rect_x + character.rect_w) /
                   (float)model_.material.albedo_map->width();
        float v1 = character.rect_y / ((float)model_.material.albedo_map->height());
        float v2 = ((character.rect_y + character.rect_h) /
                    ((float)model_.material.albedo_map->height()));

        float offset_y = character.offset_y;
        float offset_x = character.offset_x;
        float rect_h = -character.rect_h;
        float rect_w = character.rect_w;

        float z = index / 2000.0f;
        model_.mesh->vertices.push_back(
            Vertex(glm::vec3(index + offset_x, rect_h + offset_y + line_index, z),
                   glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f), glm::vec2(u1, v2)));

        model_.mesh->vertices.push_back(Vertex(
            glm::vec3(index + rect_w + offset_x, offset_y + line_index, z),
            glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f), glm::vec2(u2, v1)));

        model_.mesh->vertices.push_back(Vertex(glm::vec3(index + offset_x, offset_y + line_index, z),
                                glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f), glm::vec2(u1, v1)));
        model_.mesh->vertices.push_back(
            Vertex(glm::vec3(index + offset_x, rect_h + offset_y + line_index, z),
                   glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f), glm::vec2(u1, v2)));

        model_.mesh->vertices.push_back(Vertex(glm::vec3(index + rect_w + offset_x,
                                          rect_h + offset_y + line_index, z),
                                glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f), glm::vec2(u2, v2)));
        model_.mesh->vertices.push_back(Vertex(
            glm::vec3(index + rect_w + offset_x, offset_y + line_index, z),
            glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f), glm::vec2(u2, v1)));

        index += character.advance + spacing;
      }
      line_index += line_height;
    }
  }
}

float Text::width() const {
  if (model_.mesh->vertices.size() > 2){
    glm::vec2 p1 = glm::vec2(model_.mesh->vertices.begin()->position);
    glm::vec2 p2 = glm::vec2((model_.mesh->vertices.end() - 2)->position);
    return glm::distance(p1, p2);
  }
  else {
    return 0.0f;
  }
}

float Text::height() const { return font_.height(); }

void Text::position(const glm::vec2 &position) {
  model_.transform =
      glm::translate(glm::mat4(1.0f), glm::vec3(position.x, position.y, 0.0f));
}

void Text::position(const glm::vec3 & position) {
  model_.transform = glm::translate(glm::mat4(1.0f), position);
}

glm::vec2 Text::position() const { return glm::vec2(model_.position()); }

void Text::scale(const float scale) {
  model_.transform =
      glm::scale(model_.transform, glm::vec3(scale, scale, scale));
}

void Text::material(const Material &material) {
  model_.material = material;
}

void Text::transform(const glm::mat4 & transform) {
  model_.transform = transform;
}

glm::mat4 Text::transform() const {
  return model_.transform;
}

Model Text::model() const { return model_; }

Text &Text::operator=(const std::string &input) {
  text(input);
  return *this;
}

Text &Text::operator+=(const std::string &input) {
  text(text() + input);
  return *this;
}
}
}
<commit_msg>Text rendering<commit_after>#include <mos/gfx/text.hpp>
#include <mos/util.hpp>
#include <glm/glm.hpp>
#include <iostream>
#include <glm/gtc/matrix_transform.hpp>
namespace mos {
namespace gfx {
Text::Text(const std::string &txt, const Font &font, const glm::mat4 &transform,
           const float spacing)
    : model_("Text", std::make_shared<Mesh>(Mesh()),
             transform),
      font_(font), spacing(spacing) {
  model_.material.albedo = glm::vec3(1.0f);
  model_.material.opacity = 0.0f;
  model_.material.emission = glm::vec3(1.0f);
  model_.material.albedo_map = font.texture;
  text(txt);
}

Text::~Text() {}

std::string Text::text() const { return text_; }

void Text::text(const std::string &text) {
  if (text_.compare(text) != 0) {
    text_ = text;
    std::vector<std::string> lines = mos::split(text_, '\n');
    model_.mesh->clear();

    float line_index = 0.0f;
    const float line_height = -font_.height();
    for (auto & line : lines) {
      float index = 0.0f;
      for (auto & c : line) {
        auto character = font_.characters.at(c);
        float u1 = character.rect_x / ((float)model_.material.albedo_map->width());
        float u2 = (character.rect_x + character.rect_w) /
                   (float)model_.material.albedo_map->width();
        float v1 = character.rect_y / ((float)model_.material.albedo_map->height());
        float v2 = ((character.rect_y + character.rect_h) /
                    ((float)model_.material.albedo_map->height()));

        float offset_y = character.offset_y;
        float offset_x = character.offset_x;
        float rect_h = -character.rect_h;
        float rect_w = character.rect_w;
        float advance = character.advance;

        float z = index / 2000.0f;
        model_.mesh->vertices.push_back(
            Vertex(glm::vec3(index + offset_x, rect_h + offset_y + line_index, z),
                   glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f), glm::vec2(u1, v2)));

        model_.mesh->vertices.push_back(Vertex(
            glm::vec3(index + rect_w + offset_x, offset_y + line_index, z),
            glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f), glm::vec2(u2, v1)));

        model_.mesh->vertices.push_back(Vertex(glm::vec3(index + offset_x, offset_y + line_index, z),
                                glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f), glm::vec2(u1, v1)));
        model_.mesh->vertices.push_back(
            Vertex(glm::vec3(index + offset_x, rect_h + offset_y + line_index, z),
                   glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f), glm::vec2(u1, v2)));

        model_.mesh->vertices.push_back(Vertex(glm::vec3(index + rect_w + offset_x,
                                          rect_h + offset_y + line_index, z),
                                glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f), glm::vec2(u2, v2)));
        model_.mesh->vertices.push_back(Vertex(
            glm::vec3(index + rect_w + offset_x, offset_y + line_index, z),
            glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f), glm::vec2(u2, v1)));

        index += advance + spacing;
      }
      line_index += line_height;
    }
  }
}

float Text::width() const {
  if (model_.mesh->vertices.size() > 2){
    glm::vec2 p1 = glm::vec2(model_.mesh->vertices.begin()->position);
    glm::vec2 p2 = glm::vec2((model_.mesh->vertices.end() - 2)->position);
    return glm::distance(p1, p2);
  }
  else {
    return 0.0f;
  }
}

float Text::height() const { return font_.height(); }

void Text::position(const glm::vec2 &position) {
  model_.transform =
      glm::translate(glm::mat4(1.0f), glm::vec3(position.x, position.y, 0.0f));
}

void Text::position(const glm::vec3 & position) {
  model_.transform = glm::translate(glm::mat4(1.0f), position);
}

glm::vec2 Text::position() const { return glm::vec2(model_.position()); }

void Text::scale(const float scale) {
  model_.transform =
      glm::scale(model_.transform, glm::vec3(scale, scale, scale));
}

void Text::material(const Material &material) {
  model_.material = material;
}

void Text::transform(const glm::mat4 & transform) {
  model_.transform = transform;
}

glm::mat4 Text::transform() const {
  return model_.transform;
}

Model Text::model() const { return model_; }

Text &Text::operator=(const std::string &input) {
  text(input);
  return *this;
}

Text &Text::operator+=(const std::string &input) {
  text(text() + input);
  return *this;
}
}
}
<|endoftext|>


<commit_before>#include <boost/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/log/trivial.hpp>
#include <boost/program_options.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <hadouken/application.hpp>
#include <hadouken/logging.hpp>
#include <hadouken/platform.hpp>
#include <hadouken/hosting/host.hpp>
#include <hadouken/hosting/console_host.hpp>

#ifdef WIN32
#include <hadouken/hosting/service_host.hpp>
#endif

namespace fs = boost::filesystem;
namespace po = boost::program_options;
namespace pt = boost::property_tree;

po::variables_map load_options(int argc,char *argv[])
{
    po::options_description desc("Allowed options");
    desc.add_options()
        ("config", po::value<std::string>(), "Set path to a JSON configuration file. The default is %appdir%/hadouken.json")
        ("daemon", "Start Hadouken in daemon/service mode.")
#ifdef WIN32
        ("install-service", "Install Hadouken in the SCM.")
        ("uninstall-service", "Uninstall Hadouken from the SCM.")
#endif
        ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    return vm;
}

fs::path get_config_path(const po::variables_map& options)
{
    if (options.count("config"))
    {
        return options["config"].as<std::string>();
    }
    else if (options.count("daemon"))
    {
        return (hadouken::platform::data_path() / "hadouken.json");
    }
    else
    {
        return (hadouken::platform::get_current_directory() / "hadouken.json");
    }
}

std::unique_ptr<hadouken::hosting::host> get_host(const po::variables_map& options)
{
    if (options.count("daemon"))
    {
#ifdef WIN32
        return std::unique_ptr<hadouken::hosting::host>(new hadouken::hosting::service_host());
#endif
    }

    return std::unique_ptr<hadouken::hosting::host>(new hadouken::hosting::console_host());
}

int main(int argc, char *argv[])
{
    po::variables_map vm = load_options(argc, argv);
    hadouken::logging::setup(vm);

    // Do platform-specific initialization as early as possible.
    hadouken::platform::init();

#ifdef WIN32
    if (vm.count("install-service"))
    {
        hadouken::platform::install_service();
        return 0;
    }
    else if (vm.count("uninstall-service"))
    {
        hadouken::platform::uninstall_service();
        return 0;
    }
#endif

    fs::path config_file = get_config_path(vm);
    pt::ptree config;

    if (!fs::exists(config_file))
    {
        BOOST_LOG_TRIVIAL(warning) << "Could not find config file at " << config_file;
    }
    else
    {
        try
        {
            pt::read_json(config_file.string(), config);
            BOOST_LOG_TRIVIAL(info) << "Loaded config file " << config_file;
        }
        catch (const std::exception& ex)
        {
            // To meet expectations, fail if the configuration file cannot be parsed. Otherwise,
            // we will revert to the default config which might be totally wrong.
            BOOST_LOG_TRIVIAL(fatal) << "Error when loading config file " << config_file << ": " << ex.what();
            return EXIT_FAILURE;
        }
    }

    boost::shared_ptr<boost::asio::io_service> io(new boost::asio::io_service());

    hadouken::application app(io, config);
    app.script_host().define_global("__CONFIG__", config_file.string());
    app.script_host().define_global("__CONFIG_PATH__", config_file.parent_path().string());

    app.start();
    int result = get_host(vm)->wait_for_exit(io);
    app.stop();

    return result;
}
<commit_msg>Print friendly error when given invalid parameter<commit_after>#include <boost/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/log/trivial.hpp>
#include <boost/program_options.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <hadouken/application.hpp>
#include <hadouken/logging.hpp>
#include <hadouken/platform.hpp>
#include <hadouken/hosting/host.hpp>
#include <hadouken/hosting/console_host.hpp>

#ifdef WIN32
#include <hadouken/hosting/service_host.hpp>
#endif

namespace fs = boost::filesystem;
namespace po = boost::program_options;
namespace pt = boost::property_tree;

static po::options_description desc("Allowed options");

po::variables_map load_options(int argc,char *argv[])
{
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    return vm;
}

fs::path get_config_path(const po::variables_map& options)
{
    if (options.count("config"))
    {
        return options["config"].as<std::string>();
    }
    else if (options.count("daemon"))
    {
        return (hadouken::platform::data_path() / "hadouken.json");
    }
    else
    {
        return (hadouken::platform::get_current_directory() / "hadouken.json");
    }
}

std::unique_ptr<hadouken::hosting::host> get_host(const po::variables_map& options)
{
    if (options.count("daemon"))
    {
#ifdef WIN32
        return std::unique_ptr<hadouken::hosting::host>(new hadouken::hosting::service_host());
#endif
    }

    return std::unique_ptr<hadouken::hosting::host>(new hadouken::hosting::console_host());
}

int main(int argc, char *argv[])
{
    desc.add_options()
        ("config", po::value<std::string>(), "Set path to a JSON configuration file. The default is %appdir%/hadouken.json")
        ("daemon", "Start Hadouken in daemon/service mode.")
#ifdef WIN32
        ("install-service", "Install Hadouken in the SCM.")
        ("uninstall-service", "Uninstall Hadouken from the SCM.")
#endif
        ;

    po::variables_map vm;
    try
    {
        vm = load_options(argc, argv);
    }
    catch (po::unknown_option& ex)
    {
        BOOST_LOG_TRIVIAL(error) << ex.what();
        std::cerr << std::endl << desc << std::endl;

        return EXIT_FAILURE;
    }

    hadouken::logging::setup(vm);

    // Do platform-specific initialization as early as possible.
    hadouken::platform::init();

#ifdef WIN32
    if (vm.count("install-service"))
    {
        hadouken::platform::install_service();
        return 0;
    }
    else if (vm.count("uninstall-service"))
    {
        hadouken::platform::uninstall_service();
        return 0;
    }
#endif

    fs::path config_file = get_config_path(vm);
    pt::ptree config;

    if (!fs::exists(config_file))
    {
        BOOST_LOG_TRIVIAL(warning) << "Could not find config file at " << config_file;
    }
    else
    {
        try
        {
            pt::read_json(config_file.string(), config);
            BOOST_LOG_TRIVIAL(info) << "Loaded config file " << config_file;
        }
        catch (const std::exception& ex)
        {
            // To meet expectations, fail if the configuration file cannot be parsed. Otherwise,
            // we will revert to the default config which might be totally wrong.
            BOOST_LOG_TRIVIAL(fatal) << "Error when loading config file " << config_file << ": " << ex.what();
            return EXIT_FAILURE;
        }
    }

    boost::shared_ptr<boost::asio::io_service> io(new boost::asio::io_service());

    hadouken::application app(io, config);
    app.script_host().define_global("__CONFIG__", config_file.string());
    app.script_host().define_global("__CONFIG_PATH__", config_file.parent_path().string());

    app.start();
    int result = get_host(vm)->wait_for_exit(io);
    app.stop();

    return result;
}
<|endoftext|>


<commit_before>/* * This file is part of meego-im-framework *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "mplainwindow.h"

#include <MSceneManager>
#include <MGConfItem>
#include <QDebug>

namespace
{
    // This GConf item defines whether multitouch is enabled or disabled
    const char * const MultitouchSettings = "/meegotouch/inputmethods/multitouch/enabled";
}

MPlainWindow *MPlainWindow::m_instance = 0;

MPlainWindow *MPlainWindow::instance()
{
    return m_instance;
}

MPlainWindow::MPlainWindow(QWidget *parent) :
    MWindow(new MSceneManager, parent)
{
    if (m_instance)
        qFatal("There can be only one instance of MPlainWindow");

    m_instance = this;

    if (MGConfItem(MultitouchSettings).value().toBool()) {
        setAttribute(Qt::WA_AcceptTouchEvents);
    }
}

MPlainWindow::~MPlainWindow()
{
    m_instance = 0;
}

#if defined(M_IM_DISABLE_TRANSLUCENCY) && !defined(M_IM_USE_SHAPE_WINDOW)
void MPlainWindow::updatePosition(const QRegion &region)
{
    //update view's parameters to compensate movement of MPasstroughWindow
    //this update allows plugin to use screen coordinates
    const QRect rect = region.boundingRect();
    const QSize sceneSize = visibleSceneSize();
    const int size = region.rects().size();

    if (!size) {
        setSceneRect(0, 0, sceneSize.width(), sceneSize.height());
        resize(sceneSize);
        move(0, 0);
        return;
    }

    switch (orientationAngle())
    {
    case M::Angle0:
        setSceneRect(0, sceneSize.height() - rect.height(),
                     sceneSize.width(), rect.height());
        resize(rect.width(), rect.height());
        move(0, 0);
        break;
    case M::Angle90:
        setSceneRect(0, 0, rect.width(), rect.height());
        resize(rect.width(), rect.height());
        move(sceneSize.height() - rect.width(), 0);
        break;
    case M::Angle180:
        setSceneRect(0, 0, rect.width(), sceneSize.height());
        resize(rect.width(), rect.height());
        move(0, sceneSize.height() - rect.height());
        break;
    case M::Angle270:
        setSceneRect(sceneSize.height() - rect.width(), rect.top(),
                     rect.width(), sceneSize.width());
        resize(rect.width(), rect.height());
        move(0, 0);
        break;
    }
}
#endif

<commit_msg>Changes: More detailed comment for a WA attribute<commit_after>/* * This file is part of meego-im-framework *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "mplainwindow.h"

#include <MSceneManager>
#include <MGConfItem>
#include <QDebug>

namespace
{
    // This GConf item defines whether multitouch is enabled or disabled
    const char * const MultitouchSettings = "/meegotouch/inputmethods/multitouch/enabled";
}

MPlainWindow *MPlainWindow::m_instance = 0;

MPlainWindow *MPlainWindow::instance()
{
    return m_instance;
}

MPlainWindow::MPlainWindow(QWidget *parent) :
    MWindow(new MSceneManager, parent)
{
    if (m_instance)
        qFatal("There can be only one instance of MPlainWindow");

    m_instance = this;

    // This *does not* prevent plugins from activating multitouch through
    // QGraphicsItem::setAcceptTouchEvents, as the first (enabling) call to
    // that method *will* set the WA_AcceptTouchEvents attribute on all
    // attached viewports (this was probably done in Qt to add some
    // convenience for sloppy programmers).
    //
    // Setting this attribute explicitely here is supposed to guard against
    // changes in above mentioned (undocumented!) "convenience", as this is
    // what the documentation suggests [1].
    //
    // [1] http://doc.trolltech.com/4.6/qtouchevent.html#enabling-touch-events
    if (MGConfItem(MultitouchSettings).value().toBool()) {
        setAttribute(Qt::WA_AcceptTouchEvents);
    }
}

MPlainWindow::~MPlainWindow()
{
    m_instance = 0;
}

#if defined(M_IM_DISABLE_TRANSLUCENCY) && !defined(M_IM_USE_SHAPE_WINDOW)
void MPlainWindow::updatePosition(const QRegion &region)
{
    //update view's parameters to compensate movement of MPasstroughWindow
    //this update allows plugin to use screen coordinates
    const QRect rect = region.boundingRect();
    const QSize sceneSize = visibleSceneSize();
    const int size = region.rects().size();

    if (!size) {
        setSceneRect(0, 0, sceneSize.width(), sceneSize.height());
        resize(sceneSize);
        move(0, 0);
        return;
    }

    switch (orientationAngle())
    {
    case M::Angle0:
        setSceneRect(0, sceneSize.height() - rect.height(),
                     sceneSize.width(), rect.height());
        resize(rect.width(), rect.height());
        move(0, 0);
        break;
    case M::Angle90:
        setSceneRect(0, 0, rect.width(), rect.height());
        resize(rect.width(), rect.height());
        move(sceneSize.height() - rect.width(), 0);
        break;
    case M::Angle180:
        setSceneRect(0, 0, rect.width(), sceneSize.height());
        resize(rect.width(), rect.height());
        move(0, sceneSize.height() - rect.height());
        break;
    case M::Angle270:
        setSceneRect(sceneSize.height() - rect.width(), rect.top(),
                     rect.width(), sceneSize.width());
        resize(rect.width(), rect.height());
        move(0, 0);
        break;
    }
}
#endif

<|endoftext|>


<commit_before>/*
 * File:   main.cpp
 * Author: vlad
 *
 * Created on December 12, 2013, 10:38 PM
 */

#include <iostream>

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

// TODO: expandout function
// TODO: dyad function
// TODO: proj (dya) function
// TODO: ip (inner product function) function, make it general to return matrices
// TODO: Error class
// TODO: change all for(s) to column major order
// TODO: use .data() raw pointer instead of looping

using namespace std;

using namespace qpp;
using namespace qpp::types;

//int main(int argc, char **argv)
int main()
{
	_init();

	// Display formatting
	std::cout << std::fixed; // use fixed format for nice formatting
//	std::cout << std::scientific;
	std::cout << std::setprecision(4); // only for fixed or scientific modes

	cout << "Starting qpp..." << endl;

	size_t N = 7000;
	cmat testmat = cmat::Random(N, N);

	// TIMING
	Timer t;  // start the timer
	cout << "The norm of a " << N << " x " << N << " random complex matrix is: "
			<< norm(testmat) << endl;
	t.toc(); // read the time
	cout << "It took me " << t.ticks() << " ticks (" << t.secs()
			<< " seconds) to compute the norm." << endl;
	// END TIMING

	cout << endl << "Exiting qpp..." << endl;
}
<commit_msg>commit<commit_after>/*
 * File:   main.cpp
 * Author: vlad
 *
 * Created on December 12, 2013, 10:38 PM
 */

#include <iostream>

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

// TODO: expandout function
// TODO: dyad function
// TODO: proj (dya) function
// TODO: ip (inner product function) function, make it general to return matrices
// TODO: Error class
// TODO: change all for(s) to column major order
// TODO: use .data() raw pointer instead of looping

using namespace std;

using namespace qpp;
using namespace qpp::types;

//int main(int argc, char **argv)
int main()
{
	_init();

	// Display formatting
	std::cout << std::fixed; // use fixed format for nice formatting
//	std::cout << std::scientific;
	std::cout << std::setprecision(4); // only for fixed or scientific modes

	cout << "Starting qpp..." << endl;

	size_t N = 7000;
	cmat testmat = cmat::Random(N, N);

	// TIMING
	Timer t;  // start the timer
	cout << "The norm of a " << N << " x " << N
			<< " random complex matrix is: "<<endl;
	cout << norm(testmat) << endl;
	t.toc(); // read the time
	cout << "It took me " << t.ticks() << " ticks (" << t.secs()
			<< " seconds) to compute the norm." << endl;
	// END TIMING

	cout << endl << "Exiting qpp..." << endl;
}
<|endoftext|>


<commit_before>/**
 ** \file object/object.cc
 ** \brief Implementation of object::Object.
 */

#include <algorithm>
#include <climits>

#include <boost/format.hpp>
#include <boost/lambda/lambda.hpp>

#include <libport/containers.hh>
#include <libport/contract.hh>
#include <libport/foreach.hh>
#include <libport/lexical-cast.hh>

#include <kernel/userver.hh>

#include <object/cxx-conversions.hh>
#include <object/dictionary.hh>
#include <object/float.hh>
#include <object/global.hh>
#include <object/list.hh>
#include <object/object.hh>
#include <object/root-classes.hh>
#include <object/symbols.hh>
#include <object/urbi-exception.hh>

#include <runner/raise.hh>
#include <runner/runner.hh>

namespace object
{

  namespace
  {
    /// Use xalloc/iword to store our current depth within the stream object.
    static
    inline
    long&
    current_depth(std::ostream& o)
    {
      static const long idx = std::ios::xalloc();
      return o.iword(idx);
    }
  }

  Object::Object()
    : protos_(new protos_type)
    , slots_()
    , lookup_id_(INT_MAX)
  {
    root_classes_initialize();
  }

  Object::~Object ()
  {
    slots_.finalize(this);
    if (!protos_cache_)
      delete protos_;
  }

  /*--------.
  | Slots.  |
  `--------*/

  rList
  Object::urbi_protos_get()
  {
    if (protos_cache_)
      return protos_cache_->as<List>();

    rList protos = new List(*protos_);
    protos_cache_ = protos;
    delete protos_;
    protos_ = &protos->value_get();
    return protos;
  }

  void
  Object::protos_set(const rList& l)
  {
    if (!protos_cache_)
      delete protos_;
    protos_cache_ = l;
    protos_ = &l->value_get();
  }

  static int lookup_id = 0;

  inline Object::location_type
  Object::slot_locate_(const key_type& k, bool fallback) const
  {
    if (lookup_id_ == lookup_id)
      return location_type(0, 0);
    lookup_id_ = lookup_id;
    if (rSlot slot = local_slot_get(k))
      return location_type(const_cast<Object*>(this), slot);
    foreach (const rObject& proto, protos_get())
    {
      location_type rec = proto->slot_locate_(k, fallback);
      if (rec.first)
        return rec;
    }
    if (fallback)
      if (rSlot slot = local_slot_get(SYMBOL(fallback)))
        return location_type(const_cast<Object*>(this), slot);
    return location_type(0, 0);
  }

  Object::location_type
  Object::slot_locate(const key_type& k,
                      bool fallback) const
  {
    ++lookup_id;
    return slot_locate_(k, fallback);
  }

  Object::location_type
  Object::safe_slot_locate(const key_type& k) const
  {
    location_type r = slot_locate(k, true);
    if (!r.first)
      runner::raise_lookup_error(k, const_cast<Object*>(this));
    return r;
  }

  rObject
  Object::slot_get(const key_type& k) const
  {
    return const_cast<Object*>(this)->slot_get(k);
  }

  Slot&
  Object::slot_get(const key_type& k)
  {
    return *safe_slot_locate(k).second;
  }

  Object&
  Object::slot_set(const key_type& k, rObject o, bool constant)
  {
    Slot* slot = new Slot(o);
    slot->constant_set(constant);
    return slot_set(k, slot);
  }

  Object&
  Object::slot_set(const key_type& k, Slot* o)
  {
    if (!slots_.set(this, k, o))
      runner::raise_urbi_skip(SYMBOL(RedefinitionError), to_urbi(k));
    return *this;
  }

  Object&
  Object::slot_copy(const key_type& name, const rObject& from)
  {
    this->slot_set(name, from->slot_get(name));
    return *this;
  }

  bool
  Object::slot_has(const key_type& k) const
  {
    return slot_locate(k).first;
  }

  rObject
  Object::slot_update(const key_type& k, const rObject& o,
                      bool hook)
  {
    runner::Runner& r = ::kernel::urbiserver->getCurrentRunner();

    // The updated slot
    Slot& s = slot_get(k);
    // Its owner
    rObject owner = slot_locate(k).first;
    // Value to write to the slot
    rObject v = o;

    // If the current value in the slot to be written in has a slot
    // named 'updateHook', call it, passing the object owning the
    // slot, the slot name and the target.
    if (hook)
      if (rObject hook = s.property_get(SYMBOL(updateHook)))
      {
        objects_type args;
        args.push_back(rObject(this));
        args.push_back(new String(k));
        args.push_back(o);
        v = r.apply(hook, SYMBOL(updateHook), args);
        // If the updateHook returned void, do nothing. Otherwise let
        // the slot be overwritten.
        if (v == object::void_class)
          return o;
      }
    // If return-value of hook is not void, write it to slot.
    if (owner == this)
      s = v;
    else
    {
      // Here comes the cow
      Slot* slot = new Slot(s);
      *slot = v;
      slot_set(k, slot);
    }
    return v;
  };

  /*-------------.
  | Properties.  |
  `-------------*/

  rDictionary
  Object::properties_get()
  {
    Dictionary::value_type res;
    for (slots_implem::const_iterator slot = slots_.begin(this);
         slot != slots_.end(this);
         ++slot)
      res[slot->first.second] = properties_get(slot->first.second);
    return new Dictionary(res);
  }

  rDictionary
  Object::properties_get(const key_type& k)
  {
    if (Slot::properties_type* props = slot_get(k).properties_get())
      return new Dictionary(*props);
    else
      return new Dictionary();
  }

  rObject
  Object::property_get(const key_type& k, const key_type& p)
  {
    return slot_get(k).property_get(p);
  }

  bool
  Object::property_has(const key_type& k, const key_type& p)
  {
    return slot_get(k).property_has(p);
  }

  rObject
  Object::property_set(const key_type& k,
		       const key_type& p,
		       const rObject& value)
  {
    // CoW
    if (safe_slot_locate(k).first != this)
      slot_set(k, slot_get(k));
    Slot& slot = slot_get(k);
    if (slot.property_set(p, value))
      if (slot->slot_has(SYMBOL(newPropertyHook)))
        slot->call(SYMBOL(newPropertyHook),
                   this, new String(k), new String(p), value);
    return value;
  }

  rObject
  Object::property_remove(const key_type& k, const key_type& p)
  {
    Slot& slot = slot_get(k);
    rObject res = slot.property_get(p);
    slot.property_remove(p);
    return res;
  }

  /*-----------.
  | Printing.  |
  `-----------*/

  std::ostream&
  Object::special_slots_dump(std::ostream& o) const
  {
    return o;
  }

  std::ostream&
  Object::slot_dump(std::ostream& o,
                    const CentralizedSlots::q_slot_type& slot,
                    int depth_max) const
  {
    o << slot.first.second << " = ";
    slot.second->value()->dump(o, depth_max) << libport::iendl;
    if (Slot::properties_type* props = slot.second->properties_get())
    {
      o << "  /* Properties */" << libport::incendl;
      foreach (const Slot::properties_type::value_type& p, *props)
      {
        o << p.first << " = ";
        p.second->dump(o, depth_max);
      }
      o << libport::decendl;
    }
    return o;
  }

  bool
  Object::operator< (const Object& rhs) const
  {
    return this < &rhs;
  }

  std::ostream&
  Object::id_dump(std::ostream& o) const
  {
    rObject data = const_cast<Object*>(this)->call(SYMBOL(id));
    type_check<String>(data);
    return o << data->as<String>()->value_get();
  }

  std::ostream&
  Object::protos_dump(std::ostream& o) const
  {
    if (!protos_->empty())
    {
      o << "protos = ";
      bool tail = false;
      foreach (const rObject& p, *protos_)
      {
	if (tail++)
	  o << ", ";
	p->id_dump (o);
      }
      o << libport::iendl;
    }
    return o;
  }

  std::ostream&
  Object::dump(std::ostream& o, int depth_max) const
  {
    id_dump(o);

    // Stop recursion at depth_max.
    if (depth_max < current_depth(o))
      return o << " <...>";
    ++current_depth(o);

    o << " {" << libport::incendl
      << "/* Special slots */" << libport::iendl;
    protos_dump(o);
    special_slots_dump (o);

    o << "/* Slots */" << libport::iendl;
    for (slots_implem::const_iterator i = slots_.begin(this);
         i != slots_.end(this);
         ++i)
      slot_dump(o, *i, depth_max);

    o << libport::decindent << '}';
    --current_depth(o);
    return o;
  }

  std::ostream&
  Object::print(std::ostream& o) const
  {
    try
    {
      rObject s = const_cast<Object*>(this)->call(SYMBOL(asString));
      type_check<String>(s);
      o << s->as<String>()->value_get();
      return o;
    }
    // Check if asString was found, especially for bootstrap: asString
    // is implemented in urbi/urbi.u, but print is called to show
    // result in the toplevel before its definition.
    catch (UrbiException&)
    {
      // If no asString method is supplied, print the unique id
      return o << std::hex << this;
    }
  }

  bool
  is_a(const rObject& c, const rObject& p)
  {
    return for_all_protos(c, boost::lambda::_1 == p);
  }

  bool
  Object::as_bool() const
  {
    if (this == nil_class.get()
        || this == false_class.get())
      return false;

    if (this == void_class.get())
      runner::raise_unexpected_void_error();

    return true;
  }

  bool Object::valid_proto(const Object&) const
  {
    return true;
  }

  Object&
  Object::proto_add(const rObject& p)
  {
    assert(p);
    // Inheriting from atoms is a problem: we cannot morph in place
    // the C++ object to give him the right primitive type. For now,
    // we forbid inheriting from atoms.
    if (!p->valid_proto(*this))
    {
      boost::format fmt("cannot inherit from a %1% without being a %1% too");
      runner::raise_primitive_error((fmt % p->type_name_get()).str());
    }

    if (!libport::has(*protos_, p))
      push_front (*protos_, p);
    return *this;
  }

  std::string
  Object::type_name_get() const
  {
    return "Object";
  }

  /*---------------.
  | Urbi methods.  |
  `---------------*/

  void
  Object::urbi_createSlot(key_type name)
  {
    slot_set(name, void_class);
  }

  rObject
  Object::urbi_getSlot(key_type name)
  {
    return slot_get(name);
  }

  rObject
  Object::urbi_locateSlot(key_type name)
  {
    rObject o = slot_locate(name).first;
    return o ? o : nil_class;
  }

  rDictionary
  Object::urbi_properties(key_type name)
  {
    return properties_get(name);
  }

  rObject
  Object::urbi_removeSlot(key_type name)
  {
    slot_remove(name);
    return this;
  }

  rObject
  Object::urbi_setSlot(key_type name, const rObject& value)
  {
    slot_set(name, value);
    return value;
  }

  rObject
  Object::urbi_setConstSlot(key_type name, const rObject& value)
  {
    slot_set(name, value, true);
    return value;
  }

  rObject
  Object::urbi_updateSlot(key_type name, const rObject& value)
  {
    return slot_update(name, value);
  }

#define CHECK_ARG(N)				\
  if (!arg ## N)				\
    goto done;					\
  args.push_back(arg ## N)

  rObject
  Object::call(libport::Symbol name,
               rObject arg1,
               rObject arg2,
               rObject arg3,
               rObject arg4,
               rObject arg5)
  {
    objects_type args;
    args.push_back(this);
    CHECK_ARG(1);
    CHECK_ARG(2);
    CHECK_ARG(3);
    CHECK_ARG(4);
    CHECK_ARG(5);
    done:

    return call(name, args);
  }

#undef CHECK_ARG

  rObject
  Object::call(libport::Symbol name,
               const objects_type& args)
  {
    runner::Runner& r = ::kernel::urbiserver->getCurrentRunner();

    rObject self = slot_get(name);
    return r.apply(self, name, args);
  }

  rObject
  Object::call(const std::string& name,
               rObject arg1,
               rObject arg2,
               rObject arg3,
               rObject arg4,
               rObject arg5)
  {
    return call(libport::Symbol(name), arg1, arg2, arg3, arg4, arg5);
  }

  std::ostream& operator<< (std::ostream& s, Object& o)
  {
    s << o.call(SYMBOL(asString))->as<String>()->value_get();
    return s;
  }

  rObject Object::proto;

} // namespace object
<commit_msg>Style changes.<commit_after>/**
 ** \file object/object.cc
 ** \brief Implementation of object::Object.
 */

#include <algorithm>
#include <climits>

#include <boost/format.hpp>
#include <boost/lambda/lambda.hpp>

#include <libport/containers.hh>
#include <libport/contract.hh>
#include <libport/foreach.hh>
#include <libport/lexical-cast.hh>

#include <kernel/userver.hh>

#include <object/cxx-conversions.hh>
#include <object/dictionary.hh>
#include <object/float.hh>
#include <object/global.hh>
#include <object/list.hh>
#include <object/object.hh>
#include <object/root-classes.hh>
#include <object/symbols.hh>
#include <object/urbi-exception.hh>

#include <runner/raise.hh>
#include <runner/runner.hh>

namespace object
{

  namespace
  {
    /// Use xalloc/iword to store our current depth within the stream object.
    static
    inline
    long&
    current_depth(std::ostream& o)
    {
      static const long idx = std::ios::xalloc();
      return o.iword(idx);
    }
  }

  Object::Object()
    : protos_(new protos_type)
    , slots_()
    , lookup_id_(INT_MAX)
  {
    root_classes_initialize();
  }

  Object::~Object ()
  {
    slots_.finalize(this);
    if (!protos_cache_)
      delete protos_;
  }

  /*--------.
  | Slots.  |
  `--------*/

  rList
  Object::urbi_protos_get()
  {
    if (protos_cache_)
      return protos_cache_->as<List>();

    rList protos = new List(*protos_);
    protos_cache_ = protos;
    delete protos_;
    protos_ = &protos->value_get();
    return protos;
  }

  void
  Object::protos_set(const rList& l)
  {
    if (!protos_cache_)
      delete protos_;
    protos_cache_ = l;
    protos_ = &l->value_get();
  }

  static int lookup_id = 0;

  inline Object::location_type
  Object::slot_locate_(const key_type& k, bool fallback) const
  {
    if (lookup_id_ == lookup_id)
      return location_type(0, 0);
    lookup_id_ = lookup_id;
    if (rSlot slot = local_slot_get(k))
      return location_type(const_cast<Object*>(this), slot);
    foreach (const rObject& proto, protos_get())
    {
      location_type rec = proto->slot_locate_(k, fallback);
      if (rec.first)
        return rec;
    }
    if (fallback)
      if (rSlot slot = local_slot_get(SYMBOL(fallback)))
        return location_type(const_cast<Object*>(this), slot);
    return location_type(0, 0);
  }

  Object::location_type
  Object::slot_locate(const key_type& k,
                      bool fallback) const
  {
    ++lookup_id;
    return slot_locate_(k, fallback);
  }

  Object::location_type
  Object::safe_slot_locate(const key_type& k) const
  {
    location_type r = slot_locate(k, true);
    if (!r.first)
      runner::raise_lookup_error(k, const_cast<Object*>(this));
    return r;
  }

  rObject
  Object::slot_get(const key_type& k) const
  {
    return const_cast<Object*>(this)->slot_get(k);
  }

  Slot&
  Object::slot_get(const key_type& k)
  {
    return *safe_slot_locate(k).second;
  }

  Object&
  Object::slot_set(const key_type& k, rObject o, bool constant)
  {
    Slot* slot = new Slot(o);
    slot->constant_set(constant);
    return slot_set(k, slot);
  }

  Object&
  Object::slot_set(const key_type& k, Slot* o)
  {
    if (!slots_.set(this, k, o))
      runner::raise_urbi_skip(SYMBOL(RedefinitionError), to_urbi(k));
    return *this;
  }

  Object&
  Object::slot_copy(const key_type& name, const rObject& from)
  {
    this->slot_set(name, from->slot_get(name));
    return *this;
  }

  bool
  Object::slot_has(const key_type& k) const
  {
    return slot_locate(k).first;
  }

  rObject
  Object::slot_update(const key_type& k, const rObject& o,
                      bool hook)
  {
    runner::Runner& r = ::kernel::urbiserver->getCurrentRunner();

    // The updated slot
    Slot& s = slot_get(k);
    // Its owner
    rObject owner = slot_locate(k).first;
    // Value to write to the slot
    rObject v = o;

    // If the current value in the slot to be written in has a slot
    // named 'updateHook', call it, passing the object owning the
    // slot, the slot name and the target.
    if (hook)
      if (rObject hook = s.property_get(SYMBOL(updateHook)))
      {
        objects_type args;
        args.push_back(rObject(this));
        args.push_back(new String(k));
        args.push_back(o);
        v = r.apply(hook, SYMBOL(updateHook), args);
        // If the updateHook returned void, do nothing. Otherwise let
        // the slot be overwritten.
        if (v == object::void_class)
          return o;
      }
    // If return-value of hook is not void, write it to slot.
    if (owner == this)
      s = v;
    else
    {
      // Here comes the cow
      Slot* slot = new Slot(s);
      *slot = v;
      slot_set(k, slot);
    }
    return v;
  };

  /*-------------.
  | Properties.  |
  `-------------*/

  rDictionary
  Object::properties_get()
  {
    Dictionary::value_type res;
    for (slots_implem::const_iterator slot = slots_.begin(this);
         slot != slots_.end(this);
         ++slot)
      res[slot->first.second] = properties_get(slot->first.second);
    return new Dictionary(res);
  }

  rDictionary
  Object::properties_get(const key_type& k)
  {
    if (Slot::properties_type* props = slot_get(k).properties_get())
      return new Dictionary(*props);
    else
      return new Dictionary();
  }

  rObject
  Object::property_get(const key_type& k, const key_type& p)
  {
    return slot_get(k).property_get(p);
  }

  bool
  Object::property_has(const key_type& k, const key_type& p)
  {
    return slot_get(k).property_has(p);
  }

  rObject
  Object::property_set(const key_type& k,
		       const key_type& p,
		       const rObject& value)
  {
    // CoW
    if (safe_slot_locate(k).first != this)
      slot_set(k, slot_get(k));
    Slot& slot = slot_get(k);
    if (slot.property_set(p, value))
      if (slot->slot_has(SYMBOL(newPropertyHook)))
        slot->call(SYMBOL(newPropertyHook),
                   this, new String(k), new String(p), value);
    return value;
  }

  rObject
  Object::property_remove(const key_type& k, const key_type& p)
  {
    Slot& slot = slot_get(k);
    rObject res = slot.property_get(p);
    slot.property_remove(p);
    return res;
  }

  /*-----------.
  | Printing.  |
  `-----------*/

  std::ostream&
  Object::special_slots_dump(std::ostream& o) const
  {
    return o;
  }

  std::ostream&
  Object::slot_dump(std::ostream& o,
                    const CentralizedSlots::q_slot_type& slot,
                    int depth_max) const
  {
    o << slot.first.second << " = ";
    slot.second->value()->dump(o, depth_max) << libport::iendl;
    if (Slot::properties_type* props = slot.second->properties_get())
    {
      o << "  /* Properties */" << libport::incendl;
      foreach (const Slot::properties_type::value_type& p, *props)
      {
        o << p.first << " = ";
        p.second->dump(o, depth_max);
      }
      o << libport::decendl;
    }
    return o;
  }

  bool
  Object::operator< (const Object& rhs) const
  {
    return this < &rhs;
  }

  std::ostream&
  Object::id_dump(std::ostream& o) const
  {
    rObject data = const_cast<Object*>(this)->call(SYMBOL(id));
    type_check<String>(data);
    return o << data->as<String>()->value_get();
  }

  std::ostream&
  Object::protos_dump(std::ostream& o) const
  {
    if (!protos_->empty())
    {
      o << "protos = ";
      bool tail = false;
      foreach (const rObject& p, *protos_)
      {
	if (tail++)
	  o << ", ";
	p->id_dump (o);
      }
      o << libport::iendl;
    }
    return o;
  }

  std::ostream&
  Object::dump(std::ostream& o, int depth_max) const
  {
    id_dump(o);

    // Stop recursion at depth_max.
    if (depth_max < current_depth(o))
      return o << " <...>";
    ++current_depth(o);

    o << " {" << libport::incendl
      << "/* Special slots */" << libport::iendl;
    protos_dump(o);
    special_slots_dump (o);

    o << "/* Slots */" << libport::iendl;
    for (slots_implem::const_iterator i = slots_.begin(this);
         i != slots_.end(this);
         ++i)
      slot_dump(o, *i, depth_max);

    o << libport::decindent << '}';
    --current_depth(o);
    return o;
  }

  std::ostream&
  Object::print(std::ostream& o) const
  {
    try
    {
      rObject s = const_cast<Object*>(this)->call(SYMBOL(asString));
      type_check<String>(s);
      o << s->as<String>()->value_get();
      return o;
    }
    // Check if asString was found, especially for bootstrap: asString
    // is implemented in urbi/urbi.u, but print is called to show
    // result in the toplevel before its definition.
    catch (UrbiException&)
    {
      // If no asString method is supplied, print the unique id
      return o << std::hex << this;
    }
  }

  bool
  is_a(const rObject& c, const rObject& p)
  {
    return for_all_protos(c, boost::lambda::_1 == p);
  }

  bool
  Object::as_bool() const
  {
    if (this == nil_class.get()
        || this == false_class.get())
      return false;

    if (this == void_class.get())
      runner::raise_unexpected_void_error();

    return true;
  }

  bool Object::valid_proto(const Object&) const
  {
    return true;
  }

  Object&
  Object::proto_add(const rObject& p)
  {
    assert(p);
    // Inheriting from atoms is a problem: we cannot morph in place
    // the C++ object to give him the right primitive type. For now,
    // we forbid inheriting from atoms.
    if (!p->valid_proto(*this))
    {
      boost::format fmt("cannot inherit from a %1% without being a %1% too");
      runner::raise_primitive_error((fmt % p->type_name_get()).str());
    }

    if (!libport::has(*protos_, p))
      push_front (*protos_, p);
    return *this;
  }

  std::string
  Object::type_name_get() const
  {
    return "Object";
  }

  /*---------------.
  | Urbi methods.  |
  `---------------*/

  void
  Object::urbi_createSlot(key_type name)
  {
    slot_set(name, void_class);
  }

  rObject
  Object::urbi_getSlot(key_type name)
  {
    return slot_get(name);
  }

  rObject
  Object::urbi_locateSlot(key_type name)
  {
    rObject o = slot_locate(name).first;
    return o ? o : nil_class;
  }

  rDictionary
  Object::urbi_properties(key_type name)
  {
    return properties_get(name);
  }

  rObject
  Object::urbi_removeSlot(key_type name)
  {
    slot_remove(name);
    return this;
  }

  rObject
  Object::urbi_setSlot(key_type name, const rObject& value)
  {
    slot_set(name, value);
    return value;
  }

  rObject
  Object::urbi_setConstSlot(key_type name, const rObject& value)
  {
    slot_set(name, value, true);
    return value;
  }

  rObject
  Object::urbi_updateSlot(key_type name, const rObject& value)
  {
    return slot_update(name, value);
  }

#define CHECK_ARG(N)				\
  if (!arg ## N)				\
    goto done;					\
  args.push_back(arg ## N)

  rObject
  Object::call(libport::Symbol name,
               rObject arg1,
               rObject arg2,
               rObject arg3,
               rObject arg4,
               rObject arg5)
  {
    objects_type args;
    args.push_back(this);
    CHECK_ARG(1);
    CHECK_ARG(2);
    CHECK_ARG(3);
    CHECK_ARG(4);
    CHECK_ARG(5);
    done:

    return call(name, args);
  }

#undef CHECK_ARG

  rObject
  Object::call(libport::Symbol name,
               const objects_type& args)
  {
    runner::Runner& r = ::kernel::urbiserver->getCurrentRunner();
    rObject fun = slot_get(name);
    return r.apply(fun, name, args);
  }

  rObject
  Object::call(const std::string& name,
               rObject arg1,
               rObject arg2,
               rObject arg3,
               rObject arg4,
               rObject arg5)
  {
    return call(libport::Symbol(name), arg1, arg2, arg3, arg4, arg5);
  }

  std::ostream& operator<< (std::ostream& s, Object& o)
  {
    s << o.call(SYMBOL(asString))->as<String>()->value_get();
    return s;
  }

  rObject Object::proto;

} // namespace object
<|endoftext|>


<commit_before>// The entry point of yrmcdsd.
// (C) 2013 Cybozu.

#include "config.hpp"
#include "constants.hpp"
#include "server.hpp"

#include <cybozu/filesystem.hpp>
#include <cybozu/siphash.hpp>
#include <cybozu/util.hpp>

#include <algorithm>
#include <grp.h>
#include <iostream>
#include <pwd.h>
#include <random>
#include <string>
#include <sys/prctl.h>
#include <sys/types.h>
#include <typeinfo>
#include <unistd.h>
#include <vector>

#define QUOTE(str) #str
#define EXPAND_AND_QUOTE(str) QUOTE(str)

namespace {

#include "../COPYING.hpp"

void print_help() {
    std::cout << "Usage: yrmcdsd [-v] [-h] [-f FILE]" << std::endl;
}

void print_version() {
    std::cout << yrmcds::VERSION << std::endl << std::endl << COPYING;
}

void seed_siphash() {
    union {
        char key[16];
        std::uint64_t ikey[2];
    } k;

    std::random_device rd;
    std::uniform_int_distribution<std::uint64_t> dis;
    k.ikey[0] = dis(rd);
    k.ikey[1] = dis(rd);
    cybozu::siphash24_seed(k.key);
}

bool load_config(const std::vector<std::string>& args) {
    auto it = std::find(args.begin(), args.end(), "-f");
    using yrmcds::g_config;
    if( it != args.end() ) {
        ++it;
        if( it == args.end() ) {
            std::cerr << "missing filename after -f" << std::endl;
            return false;
        }
        g_config.load(*it);
    } else {
        std::string config_path = EXPAND_AND_QUOTE(DEFAULT_CONFIG);
        struct stat st;
        if( cybozu::get_stat(config_path, st) )
            g_config.load( config_path );
    }
    if( g_config.secure_erase() &&
        (g_config.max_data_size() > g_config.heap_data_limit()) ) {
        std::cerr << "WARNING: " << std::endl
                  << "   \"secure_erase\" is enabled but your data may be written out to disk."
                  << std::endl
                  << "   Consider setting \"max_data_size\" equal to \"heap_data_limit\"."
                  << std::endl;
    }
    return true;
}

} // anonymous namespace

int main(int argc, char** argv) {
    std::vector<std::string> args;
    for( int i = 1; i < argc; ++i )
        args.push_back(argv[i]);

    if( std::find(args.begin(), args.end(), "-h") != args.end() ) {
        print_help();
        return 0;
    }

    if( std::find(args.begin(), args.end(), "-v") != args.end() ) {
        print_version();
        return 0;
    }

    using cybozu::logger;

    seed_siphash();

    try {
        if( ! load_config(args) )
            return 1;

        // first, set group id (as root)
        const std::string& g = yrmcds::g_config.group();
        if( ! g.empty() ) {
            if( getuid() != 0 ) {
                std::cerr << "Ignored group configuration." << std::endl;
            } else {
                struct group* grp = getgrnam(g.c_str());
                if( grp == nullptr ) {
                    std::cerr << "No such group: " << g << std::endl;
                    return 1;
                }
                if( setgid(grp->gr_gid) == -1 ) {
                    std::cerr << "Failed to set group id!" << std::endl;
                    return 1;
                }
            }
        }

        const std::string& u = yrmcds::g_config.user();
        if( ! u.empty() ) {
            if( getuid() != 0 ) {
                std::cerr << "Ignored user configuration." << std::endl;
            } else {
                struct passwd* p = getpwnam(u.c_str());
                if( p == nullptr ) {
                    std::cerr << "No such user: " << u << std::endl;
                    return 1;
                }
                if( setuid(p->pw_uid) == -1 ) {
                    std::cerr << "Failed to set user id!" << std::endl;
                    return 1;
                }
            }
        }

        // make it core dumpable
        if( prctl(PR_SET_DUMPABLE, 1) == -1 ) {
            std::cerr << "WARNING: failed to enable core dump!" << std::endl;
        }

        // setup logger
        logger::set_threshold(yrmcds::g_config.threshold());
        if( ! yrmcds::g_config.logfile().empty() )
            logger::instance().open(yrmcds::g_config.logfile());

        yrmcds::server().serve();

    } catch( const std::system_error& e ) {
        cybozu::demangler t( typeid(e).name() );
        logger::error() << "[" << t.name() << "] (" << e.code() << ") "
                        << e.what();
        std::cerr << "Exception [" << t.name() << "] (" << e.code() << ") "
                  << e.what() << std::endl;
        return 1;

    } catch( const std::exception& e ) {
        cybozu::demangler t( typeid(e).name() );
        logger::error() << "[" << t.name() << "] " << e.what();
        std::cerr << "Exception [" << t.name() << "] " << e.what() << std::endl;
        return 1;
    }

    return 0;
}
<commit_msg>Call mlockall(MCL_CURRENT|MCL_FUTURE) if lock_memory is true.<commit_after>// The entry point of yrmcdsd.
// (C) 2013 Cybozu.

#include "config.hpp"
#include "constants.hpp"
#include "server.hpp"

#include <cybozu/filesystem.hpp>
#include <cybozu/siphash.hpp>
#include <cybozu/util.hpp>

#include <algorithm>
#include <cerrno>
#include <grp.h>
#include <iostream>
#include <pwd.h>
#include <random>
#include <string>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <typeinfo>
#include <unistd.h>
#include <vector>

#define QUOTE(str) #str
#define EXPAND_AND_QUOTE(str) QUOTE(str)

namespace {

#include "../COPYING.hpp"

void print_help() {
    std::cout << "Usage: yrmcdsd [-v] [-h] [-f FILE]" << std::endl;
}

void print_version() {
    std::cout << yrmcds::VERSION << std::endl << std::endl << COPYING;
}

void seed_siphash() {
    union {
        char key[16];
        std::uint64_t ikey[2];
    } k;

    std::random_device rd;
    std::uniform_int_distribution<std::uint64_t> dis;
    k.ikey[0] = dis(rd);
    k.ikey[1] = dis(rd);
    cybozu::siphash24_seed(k.key);
}

bool load_config(const std::vector<std::string>& args) {
    auto it = std::find(args.begin(), args.end(), "-f");
    using yrmcds::g_config;
    if( it != args.end() ) {
        ++it;
        if( it == args.end() ) {
            std::cerr << "missing filename after -f" << std::endl;
            return false;
        }
        g_config.load(*it);
    } else {
        std::string config_path = EXPAND_AND_QUOTE(DEFAULT_CONFIG);
        struct stat st;
        if( cybozu::get_stat(config_path, st) )
            g_config.load( config_path );
    }
    if( g_config.secure_erase() &&
        (g_config.max_data_size() > g_config.heap_data_limit()) ) {
        std::cerr << "WARNING: " << std::endl
                  << "   \"secure_erase\" is enabled but your data may be written out to disk."
                  << std::endl
                  << "   Consider setting \"max_data_size\" equal to \"heap_data_limit\"."
                  << std::endl;
    }
    return true;
}

} // anonymous namespace

int main(int argc, char** argv) {
    std::vector<std::string> args;
    for( int i = 1; i < argc; ++i )
        args.push_back(argv[i]);

    if( std::find(args.begin(), args.end(), "-h") != args.end() ) {
        print_help();
        return 0;
    }

    if( std::find(args.begin(), args.end(), "-v") != args.end() ) {
        print_version();
        return 0;
    }

    using cybozu::logger;

    seed_siphash();

    try {
        if( ! load_config(args) )
            return 1;

        if( yrmcds::g_config.lock_memory() ) {
            if( ::mlockall( MCL_CURRENT | MCL_FUTURE ) == -1 )
                cybozu::throw_unix_error(errno, "mlockall");
        }

        // first, set group id (as root)
        const std::string& g = yrmcds::g_config.group();
        if( ! g.empty() ) {
            if( getuid() != 0 ) {
                std::cerr << "Ignored group configuration." << std::endl;
            } else {
                struct group* grp = getgrnam(g.c_str());
                if( grp == nullptr ) {
                    std::cerr << "No such group: " << g << std::endl;
                    return 1;
                }
                if( setgid(grp->gr_gid) == -1 ) {
                    std::cerr << "Failed to set group id!" << std::endl;
                    return 1;
                }
            }
        }

        const std::string& u = yrmcds::g_config.user();
        if( ! u.empty() ) {
            if( getuid() != 0 ) {
                std::cerr << "Ignored user configuration." << std::endl;
            } else {
                struct passwd* p = getpwnam(u.c_str());
                if( p == nullptr ) {
                    std::cerr << "No such user: " << u << std::endl;
                    return 1;
                }
                if( setuid(p->pw_uid) == -1 ) {
                    std::cerr << "Failed to set user id!" << std::endl;
                    return 1;
                }
            }
        }

        // make it core dumpable
        if( prctl(PR_SET_DUMPABLE, 1) == -1 ) {
            std::cerr << "WARNING: failed to enable core dump!" << std::endl;
        }

        // setup logger
        logger::set_threshold(yrmcds::g_config.threshold());
        if( ! yrmcds::g_config.logfile().empty() )
            logger::instance().open(yrmcds::g_config.logfile());

        yrmcds::server().serve();

    } catch( const std::system_error& e ) {
        cybozu::demangler t( typeid(e).name() );
        logger::error() << "[" << t.name() << "] (" << e.code() << ") "
                        << e.what();
        std::cerr << "Exception [" << t.name() << "] (" << e.code() << ") "
                  << e.what() << std::endl;
        return 1;

    } catch( const std::exception& e ) {
        cybozu::demangler t( typeid(e).name() );
        logger::error() << "[" << t.name() << "] " << e.what();
        std::cerr << "Exception [" << t.name() << "] " << e.what() << std::endl;
        return 1;
    }

    return 0;
}
<|endoftext|>


<commit_before>#include "platform.h"

#include <algorithm>

int GameMain(Platform & platform)
{
    platform.SetCaption("Roguelike Experiments");

    Platform::Color colors[] = {
        {0x00,0x00,0x00}, {0x20,0x20,0xc0}, {0x20,0xc0,0x20}, {0x20,0xc0,0xc0}, {0xc0,0x20,0x20}, {0xc0,0x20,0xc0}, {0xc0,0xc0,0x20}, {0xc0,0xc0,0xc0},
        {0x40,0x40,0x40}, {0x40,0x40,0xff}, {0x40,0xff,0x40}, {0x40,0xff,0xff}, {0xff,0x40,0x40}, {0xff,0x40,0xff}, {0xff,0xff,0x40}, {0xff,0xff,0xff}
    };
    platform.SetPalette(colors);

    int x=5, y=5;
    while(true)
    {
        Platform::Cell cells[Platform::WIDTH * Platform::HEIGHT] = {};
        cells[y*Platform::WIDTH+x] = {'@', 14};
        platform.ShowScreen(cells);

        platform.SetCursor(x, y);

        switch(platform.GetChar())
        {
        case 'Q': return 0;
        case '7': --x; --y; break;
        case '8':      --y; break;
        case '9': ++x; --y; break;
        case '4': --x;      break;
        case '5':           break;
        case '6': ++x;      break;
        case '1': --x; ++y; break;
        case '2':      ++y; break;
        case '3': ++x; ++y; break;
        }
        x = std::max(x, 0);
        y = std::max(y, 0);
        x = std::min(x, Platform::WIDTH-1);
        y = std::min(y, Platform::HEIGHT-1);
    }
}<commit_msg>Add utility coordinate type.<commit_after>#include "platform.h"

#include <algorithm>

struct int2
{
    int x,y;
    int2() : x(),y() {}
    int2(int x, int y) : x(x),y(y) {}
};
bool operator == (const int2 & a, const int2 & b) { return a.x==b.x && a.y==b.y; }
bool operator != (const int2 & a, const int2 & b) { return a.x!=b.x || a.y!=b.y; }
int2 operator + (const int2 & a) { return {+a.x, +a.y}; }
int2 operator - (const int2 & a) { return {-a.x, -a.y}; }
int2 operator + (const int2 & a, const int2 & b) { return {a.x+b.x, a.y+b.y}; }
int2 operator - (const int2 & a, const int2 & b) { return {a.x-b.x, a.y-b.y}; }
int2 & operator += (int2 & a, const int2 & b) { return a=a+b; }
int2 & operator -= (int2 & a, const int2 & b) { return a=a-b; }
int2 max(const int2 & a, const int2 & b) { return {std::max(a.x,b.x), std::max(a.y,b.y)}; }
int2 min(const int2 & a, const int2 & b) { return {std::min(a.x,b.x), std::min(a.y,b.y)}; }

struct Screen
{
    Platform::Cell cells[Platform::WIDTH * Platform::HEIGHT];

    Screen() { Clear(); }
    void Clear() { memset(cells, 0, sizeof(cells)); }
    void PutChar(const int2 & coord, int character, int attribute) { PutChar(coord.x, coord.y, character, attribute); }
    void PutChar(int x, int y, int character, int attribute)
    {
        if(x < 0 || y < 0 || x >= Platform::WIDTH || y >= Platform::HEIGHT) return;
        cells[y * Platform::WIDTH + x] = {character, attribute};
    }
};

int GameMain(Platform & platform)
{
    platform.SetCaption("Roguelike Experiments");

    const Platform::Color colors[] = {
        {0x00,0x00,0x00}, {0x20,0x20,0xc0}, {0x20,0xc0,0x20}, {0x20,0xc0,0xc0}, {0xc0,0x20,0x20}, {0xc0,0x20,0xc0}, {0xc0,0xc0,0x20}, {0xc0,0xc0,0xc0},
        {0x40,0x40,0x40}, {0x40,0x40,0xff}, {0x40,0xff,0x40}, {0x40,0xff,0xff}, {0xff,0x40,0x40}, {0xff,0x40,0xff}, {0xff,0xff,0x40}, {0xff,0xff,0xff}
    };
    platform.SetPalette(colors);

    const int2 directions[] = {{-1,1}, {0,1}, {1,1}, {-1,0}, {0,0}, {1,0}, {-1,-1}, {0,-1}, {1,-1}};
    int2 playerPos = {5,5};
    while(true)
    {
        Screen screen;
        for(int x=2; x<78; ++x)
        {
            screen.PutChar(x, 2, '#', 8);
            screen.PutChar(x, 22, '#', 8);
        }
        for(int y=2; y<23; ++y)
        {
            screen.PutChar(2, y, '#', 8);
            screen.PutChar(77, y, '#', 8);
        }
        screen.PutChar(playerPos, '@', 14);
        platform.ShowScreen(screen.cells);

        platform.SetCursor(playerPos.x, playerPos.y);

        switch(int ch = platform.GetChar())
        {
        case 'Q':
            return 0;
        case '1': case '2': case '3':
        case '4': case '5': case '6':
        case '7': case '8': case '9':
            playerPos += directions[ch-'1'];
            break;
        }
        playerPos = max(playerPos, {0,0});
        playerPos = min(playerPos, {Platform::WIDTH-1,Platform::HEIGHT-1});
    }
}<|endoftext|>


<commit_before>#include <NeuralNetwork/Perceptron/Perceptron.h>
#include <NeuralNetwork/Neuron/Neuron.h>
#include <NeuralNetwork/NeuralLayer/NeuralLayer.h>
#include <NeuralNetwork/Neuron/ActivationFunction/SigmoidFunction.h>
#include <NeuralNetwork/Neuron/ActivationFunction/TanhFunction.h>
#include <NeuralNetwork/Neuron/ActivationFunction/SoftmaxFunction.h>
#include <NeuralNetwork/Neuron/ActivationFunction/BiopolarSigmoidFunction.h>
#include <NeuralNetwork/LearningAlgorithm/BackPropagation/BepAlgorithm.h>
#include <NeuralNetwork/Neuron/ActivationFunction/LogScaleSoftmaxFunction.h>
#include <NeuralNetwork/NeuralLayer/OpenCLNeuralLayer.h>
#include <NeuralNetwork/Config.h>
#include <cmath>

#ifndef BOOST_SYSTEM_NO_DEPRECATED
#define BOOST_SYSTEM_NO_DEPRECATED 1
#include <boost/filesystem.hpp>
#undef BOOST_SYSTEM_NO_DEPRECATED
#endif

#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <fstream>
#include <iomanip>
#include <set>

#define png_infopp_NULL (png_infopp)NULL
#define int_p_NULL (int*)NULL

#if defined(NN_CC_MSVC)
# pragma warning(push)
// This function or variable may be unsafe
# pragma warning(disable:4996)
#endif

#include <boost/gil/gil_all.hpp>
#include <boost/gil/channel_algorithm.hpp>
#include <boost/gil/channel.hpp>
#include <boost/gil/image.hpp>
#include <boost/gil/extension/io/png_dynamic_io.hpp>
#include <boost/gil/extension/io/dynamic_io.hpp>
#include <boost/gil/extension/dynamic_image/any_image.hpp>
#include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
#include "gil/extension/numeric/sampler.hpp"
#include "gil/extension/numeric/resample.hpp"

#if defined(NN_CC_MSVC)
# pragma warning(pop)
#endif

#include "Var.h"

typedef long double VarType;

using namespace boost::gil;
using namespace boost::gil::detail;
static const std::string alphabet("0123456789");
static const unsigned int width = 49;
static const unsigned int height = 67;
static const unsigned int inputsNumber = width * height;

typedef nn::Perceptron< VarType,
			nn::NeuralLayer<nn::Neuron, nn::SigmoidFunction, 10 , inputsNumber, 1000 >,
			nn::NeuralLayer<nn::Neuron, nn::SigmoidFunction, 80, 10, 1000>,
			nn::NeuralLayer<nn::Neuron, nn::SoftmaxFunction, 10, 1000>
		       > Perceptron;

typedef nn::Perceptron< VarType,
			nn::NeuralLayer<nn::Neuron, nn::SigmoidFunction, 20, inputsNumber, 1000>,
			nn::NeuralLayer<nn::Neuron, nn::SoftmaxFunction,  inputsNumber, 80, 1000 >
		      > AutoEncoder;

typedef nn::bp::BepAlgorithm< AutoEncoder, nn::bp::CrossEntropyError> AutoEncAlgo;
typedef nn::bp::BepAlgorithm< Perceptron, nn::bp::CrossEntropyError> Algo;

template <typename Out>
struct halfdiff_cast_channels {
    template <typename T>
    Out operator()(const T& in1, const T& in2) const {
        return Out( (in1-in2)/2 );
    }
};

template <typename SrcView, typename DstView>
void convert_color(const SrcView& src, const DstView& dst) {
    typedef typename channel_type<DstView>::type d_channel_t;
    typedef typename channel_convert_to_unsigned<d_channel_t>::type channel_t;
    typedef pixel<channel_t, gray_layout_t>  gray_pixel_t;

    copy_pixels(color_converted_view<gray_pixel_t>(src), dst);
}

template<typename Iterator>
void readImage(std::string fileName, Iterator out) {
    using namespace boost::gil;
    using namespace nn;
    using namespace nn::bp;

    rgb8_image_t srcImg;
    png_read_image(fileName.c_str(), srcImg);

    gray8_image_t dstImg(srcImg.dimensions());
    gray8_pixel_t white(255);
    fill_pixels(view(dstImg), white);

    gray8_image_t grayImage(srcImg.dimensions());
    convert_color( view(srcImg), view(grayImage) );
    auto grayView = view(grayImage);

    gray8_image_t scaledImage(width, height);
    resize_view(grayView, view(scaledImage), bilinear_sampler() );
    auto srcView = view(scaledImage);

    for (int y=0; y<srcView.height(); ++y) {
        gray8c_view_t::x_iterator src_it( srcView.row_begin(y) );
        for (int x=0; x<srcView.width(); ++x) {
            *out = src_it[x]/255.f;// < 130? 1.f: -1.f;//255.f;
            out++;
        }
    }
}

Perceptron readPerceptron(std::string fileName) {
    Perceptron perceptron;
    if( boost::filesystem::exists(fileName.c_str()) ){
      std::ifstream file(fileName);
      if( file.good() ) {
	  Perceptron::Memento memento;
	  boost::archive::xml_iarchive ia ( file );
	  ia  >> BOOST_SERIALIZATION_NVP ( memento );

	  perceptron.setMemento ( memento );
      } else {
	  throw nn::NNException("Invalid perceptron file name", __FILE__, __LINE__);
      }
    }

    return perceptron;
}

void recognize(std::string perceptron, std::string image) {
    try {
        std::array<VarType, inputsNumber> inputs = {0};
        readImage(image, inputs.begin() );
        std::vector<VarType> result(alphabet.length(), VarType(0.f) );
        readPerceptron(perceptron).calculate(inputs.begin(), inputs.end(), result.begin() );
        for( unsigned int i = 0; i < result.size(); i++ ) {
	  std::cout << "Symbol: " <<
		       alphabet[i] <<
		       " " <<
		       result[i] <<
		       std::endl;
        }

    } catch( const nn::NNException& e) {
        std::cout << e.what() << std::endl;
    } catch( const std::exception& e) {
        std::cout << e.what() << std::endl;
    } catch(...) {
        std::cout << "Unknown error" << std::endl;
    }
}

template<typename Perc>
void save(const Perc& perc, std::string name)
{
    typename Perc::Memento memento = perc.getMemento();
    std::ofstream strm( name );
    boost::archive::xml_oarchive oa ( strm );
    oa << BOOST_SERIALIZATION_NVP ( memento );
    strm.flush();
}

template<typename Files>
AutoEncoder calculateAutoEncoder(Files files){
    std::cout << "AutoEncoder calculation started" << std::endl;
    std::vector<AutoEncAlgo::Prototype> prototypes;
    for( auto image : files) {
        if( !boost::filesystem::is_directory( image ) ) {
            try {
                AutoEncAlgo::Prototype proto;
                readImage( image, std::get<0>(proto).begin() );
		std::copy( std::get<0>(proto).begin(),
			   std::get<0>(proto).end(),
			   std::get<1>(proto).begin());

                prototypes.push_back(proto);
            } catch(const std::exception&) {
                std::cout << "Invalid image found :" << image << std::endl;
            }
        }
    }

    static AutoEncAlgo autoEncAlgo(0.005f, 0.01f);

    static std::size_t counter = 0;
    static AutoEncoder enc = autoEncAlgo.calculate(prototypes.begin(),
							  prototypes.end(),
							  [](VarType error) {
							      counter++;
							      if(counter > 0){
								counter = 0;
								std::cout << error << std::endl;
							      }
							  });

    save(enc, "autoencoder.xml");
}

void calculateWeights(std::string imagesPath) {
    using namespace boost::filesystem;
    path directory(imagesPath);
    directory_iterator end_iter;

    std::vector< std::string > files;
    if ( exists(directory) && is_directory(directory))
    {
        for( directory_iterator dir_iter(directory) ; dir_iter != end_iter ; ++dir_iter)
        {
            if (is_regular_file(dir_iter->status()) )
            {
                files.push_back( dir_iter->path().string() );
            }
        }
    }

    //static AutoEncoder autoEnc = calculateAutoEncoder(files);

    std::cout << "Perceptron calculation started" << std::endl;
    static Perceptron tmp = readPerceptron("perceptron.xml");
    static Algo algorithm (0.003f, 0.001f );
    algorithm.setMemento( tmp.getMemento() );

    std::vector<Algo::Prototype> prototypes;
    for( auto image : files ) {
        if( !boost::filesystem::is_directory( image ) ) {
            try {
                Algo::Prototype proto;
                readImage( image, std::get<0>(proto).begin() );
                std::fill(std::get<1>(proto).begin(), std::get<1>(proto).end(), 0.f);
                char ch = path(image).filename().string()[0];
                size_t pos = alphabet.find(ch);
                std::get<1>(proto)[pos] = 1.0f;
                prototypes.push_back(proto);
            } catch(const std::exception&) {
                std::cout << "Invalid image found :" << image << std::endl;
            }
        }
    }

    static std::size_t counter = 0;
    auto errorFunc = [](VarType error) {counter++;
					if(counter > 1000){
					  counter = 0;
					  std::cout << error << std::endl;
					}};

    static Perceptron perceptron = algorithm.calculate(prototypes.begin(),
						       prototypes.end(),
						       errorFunc);

    save(perceptron, "perceptron.xml");
}

int main(int argc, char** argv)
{
    int result = -1;
    if( argc == 3 ) {
        recognize(argv[1], argv[2]);
        result = 0;
    } else if( argc == 2 ) {
        calculateWeights(argv[1]);
        result = 0;
    } else {
        std::cout << std::endl << "Usage : " << std::endl << std::endl;
        std::cout << "./ocr [folder] where  [folder] is a directory with your samples, this command will generate a perceptron.xml file" << std::endl << std::endl;
        std::cout << "./ocr perceptron.xml [file] where [file] is a png image which has to be recognized" << std::endl << std::endl;
    }

    return result;
}

<commit_msg>Removed OpenCL support from ocr. Due to a problem with the lib in the test servers.<commit_after>#include <NeuralNetwork/Perceptron/Perceptron.h>
#include <NeuralNetwork/Neuron/Neuron.h>
#include <NeuralNetwork/NeuralLayer/NeuralLayer.h>
#include <NeuralNetwork/Neuron/ActivationFunction/SigmoidFunction.h>
#include <NeuralNetwork/Neuron/ActivationFunction/TanhFunction.h>
#include <NeuralNetwork/Neuron/ActivationFunction/SoftmaxFunction.h>
#include <NeuralNetwork/Neuron/ActivationFunction/BiopolarSigmoidFunction.h>
#include <NeuralNetwork/LearningAlgorithm/BackPropagation/BepAlgorithm.h>
#include <NeuralNetwork/Neuron/ActivationFunction/LogScaleSoftmaxFunction.h>
//#include <NeuralNetwork/NeuralLayer/OpenCLNeuralLayer.h>
#include <NeuralNetwork/Config.h>
#include <cmath>

#ifndef BOOST_SYSTEM_NO_DEPRECATED
#define BOOST_SYSTEM_NO_DEPRECATED 1
#include <boost/filesystem.hpp>
#undef BOOST_SYSTEM_NO_DEPRECATED
#endif

#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <fstream>
#include <iomanip>
#include <set>

#define png_infopp_NULL (png_infopp)NULL
#define int_p_NULL (int*)NULL

#if defined(NN_CC_MSVC)
# pragma warning(push)
// This function or variable may be unsafe
# pragma warning(disable:4996)
#endif

#include <boost/gil/gil_all.hpp>
#include <boost/gil/channel_algorithm.hpp>
#include <boost/gil/channel.hpp>
#include <boost/gil/image.hpp>
#include <boost/gil/extension/io/png_dynamic_io.hpp>
#include <boost/gil/extension/io/dynamic_io.hpp>
#include <boost/gil/extension/dynamic_image/any_image.hpp>
#include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
#include "gil/extension/numeric/sampler.hpp"
#include "gil/extension/numeric/resample.hpp"

#if defined(NN_CC_MSVC)
# pragma warning(pop)
#endif

#include "Var.h"

typedef long double VarType;

using namespace boost::gil;
using namespace boost::gil::detail;
static const std::string alphabet("0123456789");
static const unsigned int width = 49;
static const unsigned int height = 67;
static const unsigned int inputsNumber = width * height;

typedef nn::Perceptron< VarType,
			nn::NeuralLayer<nn::Neuron, nn::SigmoidFunction, 10 , inputsNumber, 1000 >,
			nn::NeuralLayer<nn::Neuron, nn::SigmoidFunction, 80, 10, 1000>,
			nn::NeuralLayer<nn::Neuron, nn::SoftmaxFunction, 10, 1000>
		       > Perceptron;

typedef nn::Perceptron< VarType,
			nn::NeuralLayer<nn::Neuron, nn::SigmoidFunction, 20, inputsNumber, 1000>,
			nn::NeuralLayer<nn::Neuron, nn::SoftmaxFunction,  inputsNumber, 80, 1000 >
		      > AutoEncoder;

typedef nn::bp::BepAlgorithm< AutoEncoder, nn::bp::CrossEntropyError> AutoEncAlgo;
typedef nn::bp::BepAlgorithm< Perceptron, nn::bp::CrossEntropyError> Algo;

template <typename Out>
struct halfdiff_cast_channels {
    template <typename T>
    Out operator()(const T& in1, const T& in2) const {
        return Out( (in1-in2)/2 );
    }
};

template <typename SrcView, typename DstView>
void convert_color(const SrcView& src, const DstView& dst) {
    typedef typename channel_type<DstView>::type d_channel_t;
    typedef typename channel_convert_to_unsigned<d_channel_t>::type channel_t;
    typedef pixel<channel_t, gray_layout_t>  gray_pixel_t;

    copy_pixels(color_converted_view<gray_pixel_t>(src), dst);
}

template<typename Iterator>
void readImage(std::string fileName, Iterator out) {
    using namespace boost::gil;
    using namespace nn;
    using namespace nn::bp;

    rgb8_image_t srcImg;
    png_read_image(fileName.c_str(), srcImg);

    gray8_image_t dstImg(srcImg.dimensions());
    gray8_pixel_t white(255);
    fill_pixels(view(dstImg), white);

    gray8_image_t grayImage(srcImg.dimensions());
    convert_color( view(srcImg), view(grayImage) );
    auto grayView = view(grayImage);

    gray8_image_t scaledImage(width, height);
    resize_view(grayView, view(scaledImage), bilinear_sampler() );
    auto srcView = view(scaledImage);

    for (int y=0; y<srcView.height(); ++y) {
        gray8c_view_t::x_iterator src_it( srcView.row_begin(y) );
        for (int x=0; x<srcView.width(); ++x) {
            *out = src_it[x]/255.f;// < 130? 1.f: -1.f;//255.f;
            out++;
        }
    }
}

Perceptron readPerceptron(std::string fileName) {
    Perceptron perceptron;
    if( boost::filesystem::exists(fileName.c_str()) ){
      std::ifstream file(fileName);
      if( file.good() ) {
	  Perceptron::Memento memento;
	  boost::archive::xml_iarchive ia ( file );
	  ia  >> BOOST_SERIALIZATION_NVP ( memento );

	  perceptron.setMemento ( memento );
      } else {
	  throw nn::NNException("Invalid perceptron file name", __FILE__, __LINE__);
      }
    }

    return perceptron;
}

void recognize(std::string perceptron, std::string image) {
    try {
        std::array<VarType, inputsNumber> inputs = {0};
        readImage(image, inputs.begin() );
        std::vector<VarType> result(alphabet.length(), VarType(0.f) );
        readPerceptron(perceptron).calculate(inputs.begin(), inputs.end(), result.begin() );
        for( unsigned int i = 0; i < result.size(); i++ ) {
	  std::cout << "Symbol: " <<
		       alphabet[i] <<
		       " " <<
		       result[i] <<
		       std::endl;
        }

    } catch( const nn::NNException& e) {
        std::cout << e.what() << std::endl;
    } catch( const std::exception& e) {
        std::cout << e.what() << std::endl;
    } catch(...) {
        std::cout << "Unknown error" << std::endl;
    }
}

template<typename Perc>
void save(const Perc& perc, std::string name)
{
    typename Perc::Memento memento = perc.getMemento();
    std::ofstream strm( name );
    boost::archive::xml_oarchive oa ( strm );
    oa << BOOST_SERIALIZATION_NVP ( memento );
    strm.flush();
}

template<typename Files>
AutoEncoder calculateAutoEncoder(Files files){
    std::cout << "AutoEncoder calculation started" << std::endl;
    std::vector<AutoEncAlgo::Prototype> prototypes;
    for( auto image : files) {
        if( !boost::filesystem::is_directory( image ) ) {
            try {
                AutoEncAlgo::Prototype proto;
                readImage( image, std::get<0>(proto).begin() );
		std::copy( std::get<0>(proto).begin(),
			   std::get<0>(proto).end(),
			   std::get<1>(proto).begin());

                prototypes.push_back(proto);
            } catch(const std::exception&) {
                std::cout << "Invalid image found :" << image << std::endl;
            }
        }
    }

    static AutoEncAlgo autoEncAlgo(0.005f, 0.01f);

    static std::size_t counter = 0;
    static AutoEncoder enc = autoEncAlgo.calculate(prototypes.begin(),
							  prototypes.end(),
							  [](VarType error) {
							      counter++;
							      if(counter > 0){
								counter = 0;
								std::cout << error << std::endl;
							      }
							  });

    save(enc, "autoencoder.xml");
}

void calculateWeights(std::string imagesPath) {
    using namespace boost::filesystem;
    path directory(imagesPath);
    directory_iterator end_iter;

    std::vector< std::string > files;
    if ( exists(directory) && is_directory(directory))
    {
        for( directory_iterator dir_iter(directory) ; dir_iter != end_iter ; ++dir_iter)
        {
            if (is_regular_file(dir_iter->status()) )
            {
                files.push_back( dir_iter->path().string() );
            }
        }
    }

    //static AutoEncoder autoEnc = calculateAutoEncoder(files);

    std::cout << "Perceptron calculation started" << std::endl;
    static Perceptron tmp = readPerceptron("perceptron.xml");
    static Algo algorithm (0.003f, 0.001f );
    algorithm.setMemento( tmp.getMemento() );

    std::vector<Algo::Prototype> prototypes;
    for( auto image : files ) {
        if( !boost::filesystem::is_directory( image ) ) {
            try {
                Algo::Prototype proto;
                readImage( image, std::get<0>(proto).begin() );
                std::fill(std::get<1>(proto).begin(), std::get<1>(proto).end(), 0.f);
                char ch = path(image).filename().string()[0];
                size_t pos = alphabet.find(ch);
                std::get<1>(proto)[pos] = 1.0f;
                prototypes.push_back(proto);
            } catch(const std::exception&) {
                std::cout << "Invalid image found :" << image << std::endl;
            }
        }
    }

    static std::size_t counter = 0;
    auto errorFunc = [](VarType error) {counter++;
					if(counter > 1000){
					  counter = 0;
					  std::cout << error << std::endl;
					}};

    static Perceptron perceptron = algorithm.calculate(prototypes.begin(),
						       prototypes.end(),
						       errorFunc);

    save(perceptron, "perceptron.xml");
}

int main(int argc, char** argv)
{
    int result = -1;
    if( argc == 3 ) {
        recognize(argv[1], argv[2]);
        result = 0;
    } else if( argc == 2 ) {
        calculateWeights(argv[1]);
        result = 0;
    } else {
        std::cout << std::endl << "Usage : " << std::endl << std::endl;
        std::cout << "./ocr [folder] where  [folder] is a directory with your samples, this command will generate a perceptron.xml file" << std::endl << std::endl;
        std::cout << "./ocr perceptron.xml [file] where [file] is a png image which has to be recognized" << std::endl << std::endl;
    }

    return result;
}

<|endoftext|>


<commit_before>#include <iostream>
#include <cassert>

#include <QChar>
#include <QTextStream>
#include <QString>

#include "StreamIterator"
#include "TokenRule"
#include "DiscardRule"
#include "MultipleRule"
#include "PredicateRule"
#include "ProxyRule"
#include "AlternativeRule"
#include "ReduceRule"

#include <QRegExp>
#include <QElapsedTimer>

using namespace sprout;

int main(int argc, char* argv[])
{
    auto whitespace = makeDiscard(
        makeMultiple(makeSimplePredicate<QChar, QString>([](const QChar& input) {
            return input.isSpace();
        }))
    );

    auto name = makeSimpleReduce<QString>(
        [](QString& aggregate, const QChar& c) {
            aggregate += c;
        },
        makeMultiple(makeSimplePredicate<QChar>([](const QChar& input) {
            return input.isLetter() || input == '_';
        }))
    );

    auto definition = makeReduce<QString>(
        [](Result<QString>& result, Result<QString>& subresults) {
            QString aggregate;
            for (auto c : subresults) {
                aggregate += c;
            }

            result.insert(aggregate);
        },
        makeProxySequence<QChar, QString>(
            OrderedTokenRule<QChar, QString>("var"),
            whitespace,
            name
        )
    );

    auto parser = makeMultiple(
        makeProxySequence<QChar, QString>(
            whitespace,
            makeProxyAlternate<QChar, QString>(
                OrderedTokenRule<QChar, QString>("Cat", "Heathen"),
                OrderedTokenRule<QChar, QString>("Dog", "Civilized"),
                OrderedTokenRule<QChar, QString>("Calf", "Cow"),
                name
            ),
            whitespace
        )
    );

    QTextStream stream(stdin);
    stream.setCodec("UTF-8");

    QString line;
    while (true) {
        line = stream.readLine();
        if (line.isNull()) {
            break;
        }
        QTextStream lineStream(&line);
        auto cursor = makeCursor<QChar>(&lineStream);
        Result<QString> results;

        if (definition(cursor, results)) {
            std::cout << "I came up with ";
            while (results) {
                std::cout << results->toUtf8().constData() << " ";
                ++results;
            }
            std::cout << std::endl;
        } else {
            std::cout << "I didn't match anything. :(" << std::endl;
        }
    }

    return 0;
}

// vim: set ts=4 sw=4 :
<commit_msg>Make the parser a bit more realistic<commit_after>#include <iostream>
#include <cassert>

#include <QChar>
#include <QTextStream>
#include <QString>

#include "StreamIterator"
#include "TokenRule"
#include "DiscardRule"
#include "MultipleRule"
#include "PredicateRule"
#include "ProxyRule"
#include "AlternativeRule"
#include "ReduceRule"

#include <QRegExp>
#include <QElapsedTimer>

using namespace sprout;

int main(int argc, char* argv[])
{
    auto whitespace = makeDiscard(
        makeMultiple(makeSimplePredicate<QChar, QString>([](const QChar& input) {
            return input.isSpace();
        }))
    );

    auto name = makeSimpleReduce<QString>(
        [](QString& aggregate, const QChar& c) {
            aggregate += c;
        },
        makeMultiple(makeSimplePredicate<QChar>([](const QChar& input) {
            return input.isLetter() || input == '_';
        }))
    );

    auto definition = makeReduce<QString>(
        [](Result<QString>& result, Result<QString>& subresults) {
            QString aggregate;
            for (auto c : subresults) {
                aggregate += c;
            }

            result.insert(aggregate);
        },
        makeProxySequence<QChar, QString>(
            OrderedTokenRule<QChar, QString>("var"),
            whitespace,
            name
        )
    );

    auto quotedString = [](Cursor<QChar>& orig, Result<QString>& result) {
        auto iter = orig;

        if (!iter) {
            return false;
        }
        auto quote = *iter++;

        if (quote != '\'' && quote != '"') {
            return false;
        }

        QString str;
        while (iter) {
            auto c = *iter++;

            if (c == quote) {
                result.insert(str);
                orig = iter;
                return true;
            }

            if (c == '\\') {
                // Escaped string, so parse it accordingly
                if (!iter) {
                    break;
                }

                auto escape = *iter++;
                if (escape == 'n') {
                    c = '\n';
                } else if (escape == 'b') {
                    c = '\b';
                } else if (escape == 'f') {
                    c = '\f';
                } else if (escape == 'r') {
                    c = '\r';
                } else if (escape == 't') {
                    c = '\t';
                } else if (escape == 'u') {
                    // Unicode
                    QString unicodeValue;
                    for (int i = 0; i < 4; ++i) {
                        if (!iter) {
                            return false;
                        }
                        unicodeValue += *iter++;
                    }
                    bool ok;
                    auto realValue = unicodeValue.toInt(&ok, 16);
                    if (!ok) {
                        return false;
                    }
                    c = QChar(realValue);
                }
            }

            str += c;
        }

        // Ran out of data before we could complete the string
        return false;
    };

    auto parser = makeMultiple(
        makeProxySequence<QChar, QString>(
            definition,
            whitespace,
            OrderedTokenRule<QChar, QString>("="),
            whitespace,
            quotedString,
            whitespace
        )
    );

    QTextStream stream(stdin);
    stream.setCodec("UTF-8");

    QString line;
    while (true) {
        line = stream.readLine();
        if (line.isNull()) {
            break;
        }
        QTextStream lineStream(&line);
        auto cursor = makeCursor<QChar>(&lineStream);
        Result<QString> results;

        if (parser(cursor, results) && results) {
            std::cout << "I came up with ";
            while (results) {
                std::cout << results->toUtf8().constData() << " ";
                ++results;
            }
            std::cout << std::endl;
        } else {
            std::cout << "I didn't match anything. :(" << std::endl;
        }
    }

    return 0;
}

// vim: set ts=4 sw=4 :
<|endoftext|>


<commit_before>/*
 * Alexander Puh
 * I shan't cheat.
 * 10/27/2015
 * CS100 - Rshell
 */

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
#include <string>
#include <cstring>
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost;

//V1
//char * NULLVAL;
string input;
//char * cstr;
char ** cmds;

bool promptUser(){
	cout << "$ ";
	getline(cin, input);
	while(input != "quit"){

		if(input.find_first_not_of(' ')!=string::npos && input!="quit" && input.at(0)!='#'){
			vector<string> words;
			split(words, input, is_any_of(" "), token_compress_on);

			//THIS WORKED
			/*
	        	for(auto it=words.begin(); it != words.end(); it++){
				cout << *it << endl;
			}

			*/
			//CODE TO LOOK FOR CONNECTORS like ; || && and also comments like #
			//FIRST REMOVE ALL COMMENTS BUT CHECK TO SEE THAT ONE MAY POTENTIALLY EXIST FIRST
			if(input.find('#') != string::npos){
				unsigned earliestComment = words.size(); //Assuming one after last index
				for(unsigned i = 0; i < words.size(); i++){
					//Ensures if sharp is found, it was at the beginning of the word or alone
					if(words[i].find('#')!=string::npos && words[i].at(0)=='#')
						earliestComment=i;
				}
				//REMOVE ALL TOKENS AFTER AND AT THE FOUND COMMENT
				for(unsigned i = words.size(); i >= earliestComment; i--){
					words.pop_back();
				}
			}

			//CHECKS FOR CONNECTORS
			//BUT FIRST CONFIRM IF THERE ARE CONNECTORS OR NOT
			if(input.find("||")!=string::npos || input.find("&&")!=string::npos || input.find(";")!=string::npos){
				vector<int> conIndices;	//All indices in which a connector was found
				for(unsigned i = 0; i <words.size(); i++){
					if(words[i].size() > 1)
						if(words[i].at(0)=="||" || words[i].at(0)=="&&" || words[i].at(0)==";")
							conIndices.push_back(i);
				}

				//NOW SPLIT UP INTO SEVERAL CMDS
				vector<vector<string>> allCmds;

				unsigned lastStartVal = 0;
				for(unsigned i = 0; i < conIndices.size(); i++){
					vector<string> vec;
					for(unsigned y = lastStartVal; y < conIndices[i]; y++){
						vec.push_back(words.at(y));
						lastStartVal=conIndices[i]+1;
					}
					vec.push_back(NULL);
					allCmds.push_back(vec);
					vec.clear();
				}

				//TRACK WHICH ARE EXECUTED
				bool succeeded = 1;
				//AVAILABLE: begin, ;, &&, ||
				string current_connector = "begin";

				pid_t c_pid, pid;
				int status;

				//CONVERT
				for(unsigned x = 0; x < allCmds.size(); x++){
					//Checking to see if this is the first cmd or if this is a cmd following &&
					//and a previously successful cmd OR if cmd followed by || after a failed cmd
					//previously OR if cmd is followed by ; which allows immediate execution.
					if(current_connector = ";" ||
					   (succeeded && (current_connector = "begin" || current_connector = "&&")) ||
					   (!succeeded && current_connector = "||")){
						cmds = new char * [allCmds[x].size() + 1];
						for(unsigned i = 0; i < allCmds.at(x).size(); i++){
							cmds[i] = new char[(allCmds[x].size() + 1];
							copy(allCmds[x].at(i).begin(), allCmds[x].at(i).end(), cmds[i]);
							cmds[i][allCmds[x].at(i).size()] = '\0';
						}
						//APPENT NULL
						cmds[words.size()] = NULL;

						//Assume success unless set to fail by execvp
						succeeded = 1;

						//EXECUTE
						pid_t c_pid, pid;
						int status;

	        				if( c_pid < 0 ){
							perror("fork failed");
							exit(1);
						}
						else if (c_pid == 0){
							if (execvp(cmds[0], cmds) < 0){
								cout << "EXECVP FAILED\n";
								succeeded = 0;
							}
							perror("Execvp failed");
						}
						else if (c_pid > 0){
							if((pid=wait(&status)) < 0){
								perror("wait");
								exit(1);
							}
						}

						//Set connector
						current_connector = allCmds[x][allCmds[x].size() - 1];

						for(unsigned i = 0; i < words.size(); i++){
							delete[] cmds[i];
						}
						delete[] cmds;
					}
					//In this case, the last cmd failed followed by && or
					//last cmd succeeded followed by a || which means this
					//cmd has failed = not executed.
					else{
						succeeded = 0;
						//LAST INDEX CARRIES A CONNECTOR
						current_connector = allCmds[x][allCmds[x].size()-1];
					}
				}
			}
			//========================================
			//VERSION WHERE THERE ARE NO CONNECTORS...
			//========================================
			else{

				//CODE TO "CONVERT" VECTOR TO POINTER TO A CSTRING ARR
				cmds = new char * [words.size() + 1];

				for(unsigned i = 0; i < words.size(); i++){
					cmds[i] = new char[(words.at(i)).size() + 1];
			        	copy(words.at(i).begin(), words.at(i).end(), cmds[i]);
					cmds[i][words.at(i).size()] = '\0';
				}
		        	//REMEMBER TO APPEND NULL AT END OF VECTOR
		        	cmds[words.size()] = NULL;

				pid_t c_pid, pid;
				int status;
				c_pid = fork();
	        		if( c_pid < 0 ){
					perror("fork failed");
					exit(1);
				}
				else if (c_pid == 0){
					if (execvp(cmds[0], cmds) < 0){
						cout << "EXECVP FAILED\n";
						exit(1);
				}
					perror("Execvp failed");
				}
				else if (c_pid > 0){
					if((pid=wait(&status)) < 0){
						perror("wait");
						exit(1);
					}
				}

				cout << "The status is: " << status << endl;

				for(unsigned i = 0; i < words.size(); i++){
					delete[] cmds[i];
				}
				delete[] cmds;
			}
		}
		//RESET ALL VALUES
		input="quit";
		//delete[] cstr;
		cout << "$ ";
		cin.clear();
		getline(cin, input);
	}
	return false;
}

int main(int argc, char * argv[]){

while(promptUser());

return 0;

}

//OLD VERSION
		//int counter = 0;
		//char * test = cstr;
		//while((test = strchr(cstr, ' ')) != NULL){
		//	count++;
		//	test++;
		//}
		/*
		const int count=counter+1;
		char ** fullInput = new char*[count];

		for(int i = 0; i < counter; i++)
		{
			fullInput[i] = new char[strlen(cstr[i]) + 1];
			strcpy(fullInput[i], cstr[i]);
		}
		*/

			//OLD VERSION
			//cstr = new char[input.length()+1];
			//strcpy(cstr, input.c_str());
			//cstr = strtok(cstr, " ");

<commit_msg>removing main.cpp. Has been replaced with rshell.cpp<commit_after><|endoftext|>


<commit_before>/*
 * PhoneBook application
 * Author: Martin Proks
 * Version 0.1
 *
 * Created on September 3, 2015, 12:26 PM
 */
#include <iostream>
#include "app.h"

using namespace std;

int main(int argc, char** argv) {

    cout << "Welcome to Phonebook application v 0.1" << endl;
    string phoneBookFileName;

    if (argc == 1) {

        phoneBookFileName = "/Users/matq007/Projects/Github/livecoding-phoneBook/phoneBook.xml";

    } else if (argc == 2) {

        string param = argv[1];
        if (param == "--help" || param == "-h") {
            help();
        }

        if (param.substr(param.find_last_of(".") + 1) == "xml") {
            phoneBookFileName = param;
        }

    } else {

        cout << "[ERROR]: Bad number of parameters, see help" << endl;
        help();
        return -1;

    }

    PhoneBook phoneBook(phoneBookFileName);
    phoneBook.load();
    menu(phoneBook); //menu with options

    return 0;
}
<commit_msg>phonebook file name updated<commit_after>/*
 * PhoneBook application
 * Author: Martin Proks
 * Version 0.1
 *
 * Created on September 3, 2015, 12:26 PM
 */
#include <iostream>
#include "app.h"

using namespace std;

int main(int argc, char** argv) {

    cout << "Welcome to Phonebook application v 0.1" << endl;
    string phoneBookFileName;

    if (argc == 1) {

        phoneBookFileName = "phoneBook.xml";

    } else if (argc == 2) {

        string param = argv[1];
        if (param == "--help" || param == "-h") {
            help();
        }

        if (param.substr(param.find_last_of(".") + 1) == "xml") {
            phoneBookFileName = param;
        }

    } else {

        cout << "[ERROR]: Bad number of parameters, see help" << endl;
        help();
        return -1;

    }

    PhoneBook phoneBook(phoneBookFileName);
    phoneBook.load();
    menu(phoneBook); //menu with options

    return 0;
}
<|endoftext|>