<commit_before>/* This file is part of Zanshin Todo.

   Copyright 2008-2011 Mario Bensi <nef@ipsquad.net>

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

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

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

#include "todometadatamodel.h"

#include <KDE/KCalCore/Todo>

#include <KDebug>
#include <KIcon>
#include <KLocale>

#include "globaldefs.h"

TodoMetadataModel::TodoMetadataModel(QObject *parent)
    : QSortFilterProxyModel(parent)
{
    connect(this, SIGNAL(rowsInserted(const QModelIndex&, int, int)),
            this, SLOT(onSourceInsertRows(const QModelIndex&, int, int)));
    connect(this, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)),
            this, SLOT(onSourceRemoveRows(const QModelIndex&, int, int)));
    connect(this, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
            this, SLOT(onSourceDataChanged(const QModelIndex&, const QModelIndex&)));

    onSourceInsertRows(QModelIndex(), 0, rowCount()-1);
}

TodoMetadataModel::~TodoMetadataModel()
{
}

Qt::ItemFlags TodoMetadataModel::flags(const QModelIndex &index) const
{
    if (!sourceModel()) {
        return Qt::NoItemFlags;
    }

    Qt::ItemFlags flags = sourceModel()->flags(mapToSource(index));

    if (index.isValid()) {
        if (index.column()==0) {
            Akonadi::Item item = sourceModel()->data(mapToSource(index), Akonadi::EntityTreeModel::ItemRole).value<Akonadi::Item>();
            if (item.isValid() && itemTypeFromItem(item)==Zanshin::StandardTodo) {
                flags|= Qt::ItemIsUserCheckable;
            }
        } else if (index.column()==4) {
            flags&= ~Qt::ItemIsEditable;
        }
    }

    return flags;
}

QVariant TodoMetadataModel::data(const QModelIndex &index, int role) const
{
    if (!sourceModel()) {
        return QVariant();
    }

    Akonadi::Item item = sourceModel()->data(mapToSource(index), Akonadi::EntityTreeModel::ItemRole).value<Akonadi::Item>();

    if (!item.isValid() || !item.hasPayload<KCalCore::Todo::Ptr>()) {
        return QSortFilterProxyModel::data(index, role);
    }

    switch (role) {
    case Qt::CheckStateRole:
        if (index.column()==0 && itemTypeFromItem(item)==Zanshin::StandardTodo) {
            return todoFromItem(item)->isCompleted() ? Qt::Checked : Qt::Unchecked;
        } else {
            return QVariant();
        }
    case Qt::DecorationRole:
        if (index.column()==0 && itemTypeFromItem(item)==Zanshin::ProjectTodo) {
            return KIcon("view-pim-tasks");
        } else {
            return QSortFilterProxyModel::data(index, role);
        }
    case Zanshin::UidRole:
        return uidFromItem(item);
    case Zanshin::ParentUidRole:
        return relatedUidFromItem(item);
    case Zanshin::AncestorsUidRole:
        return ancestorsUidFromItem(item);
    case Zanshin::ItemTypeRole:
        return itemTypeFromItem(item);
    case Zanshin::CategoriesRole:
        return categoriesFromItem(item);
    case Zanshin::DataTypeRole:
        switch (index.column()) {
            case 1 :
                return Zanshin::ProjectType;
            case 2 :
                return Zanshin::CategoryType;
            default:
                return Zanshin::StandardType;
        }
    case Zanshin::ChildUidsRole:
        return childUidsFromItem(item);
    case Zanshin::ChildIndexesRole:
        return QVariant::fromValue(childIndexesFromIndex(index));
    default:
        return QSortFilterProxyModel::data(index, role);
    }
    return QSortFilterProxyModel::data(index, role);
}

void TodoMetadataModel::onSourceInsertRows(const QModelIndex &parent, int begin, int end)
{
    for (int i = begin; i <= end; i++) {
        QModelIndex child = index(i, 0, parent);
        onSourceInsertRows(child, 0, rowCount(child)-1);

        KCalCore::Todo::Ptr todo = todoFromIndex(child);

        if (!todo) {
            continue;
        }

        QString uid = todo->uid();

        m_indexMap[uid] = child;

        QString relatedUid = todo->relatedTo();

        if (relatedUid.isEmpty()) {
            continue;
        }

        m_parentMap[uid] = relatedUid;
        m_childrenMap[relatedUid] << uid;

        // Emit dataChanged to notify that the todo is a project todo
        QModelIndex parentIndex = m_indexMap[relatedUid];
        if (parentIndex.data(Zanshin::ItemTypeRole).toInt()==Zanshin::ProjectTodo) {
            emit dataChanged(parentIndex, parentIndex);
        }

    }
}

void TodoMetadataModel::onSourceRemoveRows(const QModelIndex &parent, int begin, int end)
{
    for (int i = begin; i <= end; ++i) {
        QModelIndex child = index(i, 0, parent);
        KCalCore::Todo::Ptr todo = todoFromIndex(child);

        if (!todo) {
            continue;
        }

        QString uid = todo->uid();

        QString relatedUid = todo->relatedTo();

        m_parentMap.remove(uid);
        m_childrenMap[relatedUid].removeAll(uid);
        m_indexMap.remove(uid);
    }
}

void TodoMetadataModel::onSourceDataChanged(const QModelIndex &begin, const QModelIndex &end)
{
    for (int row = begin.row(); row <= end.row(); ++row) {
        for (int column = begin.column(); column <= end.column(); ++column) {
            KCalCore::Todo::Ptr todo = todoFromIndex( index(row, column, begin.parent()) );

            if (!todo) {
                continue;
            }

            QString uid = todo->uid();

            QString newRelatedUid = todo->relatedTo();
            QString oldRelatedUid;
            if (m_parentMap.contains(uid)) {
                oldRelatedUid = m_parentMap[uid];
            }

            if (newRelatedUid!=oldRelatedUid) {
                m_parentMap[uid] = newRelatedUid;
                m_childrenMap[newRelatedUid] << uid;
                m_childrenMap[oldRelatedUid].removeAll(uid);
            }
        }
    }
}

KCalCore::Todo::Ptr TodoMetadataModel::todoFromIndex(const QModelIndex &index) const
{
    Akonadi::Item item = sourceModel()->data(mapToSource(index), Akonadi::EntityTreeModel::ItemRole).value<Akonadi::Item>();
    return todoFromItem(item);
}

KCalCore::Todo::Ptr TodoMetadataModel::todoFromItem(const Akonadi::Item &item) const
{
    if (!item.isValid() || !item.hasPayload<KCalCore::Todo::Ptr>()) {
        return KCalCore::Todo::Ptr();
    } else {
        return item.payload<KCalCore::Todo::Ptr>();
    }
}

Zanshin::ItemType TodoMetadataModel::itemTypeFromItem(const Akonadi::Item &item) const
{
    KCalCore::Todo::Ptr todo = todoFromItem(item);

    QStringList comments = todo->comments();
    if (comments.contains("X-Zanshin-Project")
     || m_childrenMap[todo->uid()].count()>0) {
        return Zanshin::ProjectTodo;
    } else {
        return Zanshin::StandardTodo;
    }
}

QString TodoMetadataModel::uidFromItem(const Akonadi::Item &item) const
{
    KCalCore::Todo::Ptr todo = todoFromItem(item);
    if (todo) {
        return todo->uid();
    } else {
        return QString();
    }
}

QString TodoMetadataModel::relatedUidFromItem(const Akonadi::Item &item) const
{
    KCalCore::Todo::Ptr todo = todoFromItem(item);
    if (todo) {
        return todo->relatedTo();
    } else {
        return QString();
    }
}

QStringList TodoMetadataModel::ancestorsUidFromItem(const Akonadi::Item &item) const
{
    QStringList result;
    KCalCore::Todo::Ptr todo = todoFromItem(item);

    if (todo) {
        QString id = todo->uid();
        while (m_parentMap.contains(id)) {
            const QString parentId = m_parentMap[id];
            Q_ASSERT(!parentId.isEmpty());
            result << parentId;
            id = parentId;
        }
    }

    return result;
}

QStringList TodoMetadataModel::categoriesFromItem(const Akonadi::Item &item) const
{
    KCalCore::Todo::Ptr todo = todoFromItem(item);
    if (todo) {
        return todo->categories();
    } else {
        return QStringList();
    }
}

QStringList TodoMetadataModel::childUidsFromItem(const Akonadi::Item &item) const
{
    KCalCore::Todo::Ptr todo = todoFromItem(item);
    if (todo) {
        return m_childrenMap[todo->uid()];
    } else {
        return QStringList();
    }
}

QModelIndexList TodoMetadataModel::childIndexesFromIndex(const QModelIndex &idx) const
{
    QModelIndexList indexes;
    KCalCore::Todo::Ptr todo = todoFromIndex(idx);
    if (!todo) {
        return indexes;
    }
    QString parent = todo->uid();
    for (int i = 0; i < rowCount(idx.parent()); ++i) {
        QModelIndex child = index(i, idx.column(), idx.parent());
        todo = todoFromIndex(child);
        if (!todo) {
            continue;
        }
        if (m_parentMap[todo->uid()] == parent) {
            indexes << child;
        }
    }
    return indexes;
}
<commit_msg>Emit dataChange on each todo under a project<commit_after>/* This file is part of Zanshin Todo.

   Copyright 2008-2011 Mario Bensi <nef@ipsquad.net>

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

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

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

#include "todometadatamodel.h"

#include <KDE/KCalCore/Todo>

#include <KDebug>
#include <KIcon>
#include <KLocale>

#include "globaldefs.h"

TodoMetadataModel::TodoMetadataModel(QObject *parent)
    : QSortFilterProxyModel(parent)
{
    connect(this, SIGNAL(rowsInserted(const QModelIndex&, int, int)),
            this, SLOT(onSourceInsertRows(const QModelIndex&, int, int)));
    connect(this, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)),
            this, SLOT(onSourceRemoveRows(const QModelIndex&, int, int)));
    connect(this, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
            this, SLOT(onSourceDataChanged(const QModelIndex&, const QModelIndex&)));

    onSourceInsertRows(QModelIndex(), 0, rowCount()-1);
}

TodoMetadataModel::~TodoMetadataModel()
{
}

Qt::ItemFlags TodoMetadataModel::flags(const QModelIndex &index) const
{
    if (!sourceModel()) {
        return Qt::NoItemFlags;
    }

    Qt::ItemFlags flags = sourceModel()->flags(mapToSource(index));

    if (index.isValid()) {
        if (index.column()==0) {
            Akonadi::Item item = sourceModel()->data(mapToSource(index), Akonadi::EntityTreeModel::ItemRole).value<Akonadi::Item>();
            if (item.isValid() && itemTypeFromItem(item)==Zanshin::StandardTodo) {
                flags|= Qt::ItemIsUserCheckable;
            }
        } else if (index.column()==4) {
            flags&= ~Qt::ItemIsEditable;
        }
    }

    return flags;
}

QVariant TodoMetadataModel::data(const QModelIndex &index, int role) const
{
    if (!sourceModel()) {
        return QVariant();
    }

    Akonadi::Item item = sourceModel()->data(mapToSource(index), Akonadi::EntityTreeModel::ItemRole).value<Akonadi::Item>();

    if (!item.isValid() || !item.hasPayload<KCalCore::Todo::Ptr>()) {
        return QSortFilterProxyModel::data(index, role);
    }

    switch (role) {
    case Qt::CheckStateRole:
        if (index.column()==0 && itemTypeFromItem(item)==Zanshin::StandardTodo) {
            return todoFromItem(item)->isCompleted() ? Qt::Checked : Qt::Unchecked;
        } else {
            return QVariant();
        }
    case Qt::DecorationRole:
        if (index.column()==0 && itemTypeFromItem(item)==Zanshin::ProjectTodo) {
            return KIcon("view-pim-tasks");
        } else {
            return QSortFilterProxyModel::data(index, role);
        }
    case Zanshin::UidRole:
        return uidFromItem(item);
    case Zanshin::ParentUidRole:
        return relatedUidFromItem(item);
    case Zanshin::AncestorsUidRole:
        return ancestorsUidFromItem(item);
    case Zanshin::ItemTypeRole:
        return itemTypeFromItem(item);
    case Zanshin::CategoriesRole:
        return categoriesFromItem(item);
    case Zanshin::DataTypeRole:
        switch (index.column()) {
            case 1 :
                return Zanshin::ProjectType;
            case 2 :
                return Zanshin::CategoryType;
            default:
                return Zanshin::StandardType;
        }
    case Zanshin::ChildUidsRole:
        return childUidsFromItem(item);
    case Zanshin::ChildIndexesRole:
        return QVariant::fromValue(childIndexesFromIndex(index));
    default:
        return QSortFilterProxyModel::data(index, role);
    }
    return QSortFilterProxyModel::data(index, role);
}

void TodoMetadataModel::onSourceInsertRows(const QModelIndex &parent, int begin, int end)
{
    for (int i = begin; i <= end; i++) {
        QModelIndex child = index(i, 0, parent);
        onSourceInsertRows(child, 0, rowCount(child)-1);

        KCalCore::Todo::Ptr todo = todoFromIndex(child);

        if (!todo) {
            continue;
        }

        QString uid = todo->uid();

        m_indexMap[uid] = child;

        QString relatedUid = todo->relatedTo();

        if (relatedUid.isEmpty()) {
            continue;
        }

        m_parentMap[uid] = relatedUid;
        m_childrenMap[relatedUid] << uid;

        // Emit dataChanged to notify that the todo is a project todo
        QModelIndex parentIndex = m_indexMap[relatedUid];
        if (parentIndex.data(Zanshin::ItemTypeRole).toInt()==Zanshin::ProjectTodo) {
            emit dataChanged(parentIndex, parentIndex);
        }

    }
}

void TodoMetadataModel::onSourceRemoveRows(const QModelIndex &parent, int begin, int end)
{
    for (int i = begin; i <= end; ++i) {
        QModelIndex child = index(i, 0, parent);
        KCalCore::Todo::Ptr todo = todoFromIndex(child);

        if (!todo) {
            continue;
        }

        QString uid = todo->uid();

        QString relatedUid = todo->relatedTo();

        m_parentMap.remove(uid);
        m_childrenMap[relatedUid].removeAll(uid);
        m_indexMap.remove(uid);
    }
}

void TodoMetadataModel::onSourceDataChanged(const QModelIndex &begin, const QModelIndex &end)
{
    for (int row = begin.row(); row <= end.row(); ++row) {
        for (int column = begin.column(); column <= end.column(); ++column) {
            QModelIndex child = index(row, column, begin.parent());
            KCalCore::Todo::Ptr todo = todoFromIndex(child);

            if (!todo) {
                continue;
            }

            QString uid = todo->uid();

            QString newRelatedUid = todo->relatedTo();
            QString oldRelatedUid;
            if (m_parentMap.contains(uid)) {
                oldRelatedUid = m_parentMap[uid];
            }

            if (newRelatedUid!=oldRelatedUid) {
                m_parentMap[uid] = newRelatedUid;
                m_childrenMap[newRelatedUid] << uid;
                m_childrenMap[oldRelatedUid].removeAll(uid);
            }

            if (child.data(Zanshin::ItemTypeRole).toInt()==Zanshin::ProjectTodo) {
                foreach (const QModelIndex &index, childIndexesFromIndex(child)) {
                    emit dataChanged(index, index);
                }
            }
        }
    }
}

KCalCore::Todo::Ptr TodoMetadataModel::todoFromIndex(const QModelIndex &index) const
{
    Akonadi::Item item = sourceModel()->data(mapToSource(index), Akonadi::EntityTreeModel::ItemRole).value<Akonadi::Item>();
    return todoFromItem(item);
}

KCalCore::Todo::Ptr TodoMetadataModel::todoFromItem(const Akonadi::Item &item) const
{
    if (!item.isValid() || !item.hasPayload<KCalCore::Todo::Ptr>()) {
        return KCalCore::Todo::Ptr();
    } else {
        return item.payload<KCalCore::Todo::Ptr>();
    }
}

Zanshin::ItemType TodoMetadataModel::itemTypeFromItem(const Akonadi::Item &item) const
{
    KCalCore::Todo::Ptr todo = todoFromItem(item);

    QStringList comments = todo->comments();
    if (comments.contains("X-Zanshin-Project")
     || m_childrenMap[todo->uid()].count()>0) {
        return Zanshin::ProjectTodo;
    } else {
        return Zanshin::StandardTodo;
    }
}

QString TodoMetadataModel::uidFromItem(const Akonadi::Item &item) const
{
    KCalCore::Todo::Ptr todo = todoFromItem(item);
    if (todo) {
        return todo->uid();
    } else {
        return QString();
    }
}

QString TodoMetadataModel::relatedUidFromItem(const Akonadi::Item &item) const
{
    KCalCore::Todo::Ptr todo = todoFromItem(item);
    if (todo) {
        return todo->relatedTo();
    } else {
        return QString();
    }
}

QStringList TodoMetadataModel::ancestorsUidFromItem(const Akonadi::Item &item) const
{
    QStringList result;
    KCalCore::Todo::Ptr todo = todoFromItem(item);

    if (todo) {
        QString id = todo->uid();
        while (m_parentMap.contains(id)) {
            const QString parentId = m_parentMap[id];
            Q_ASSERT(!parentId.isEmpty());
            result << parentId;
            id = parentId;
        }
    }

    return result;
}

QStringList TodoMetadataModel::categoriesFromItem(const Akonadi::Item &item) const
{
    KCalCore::Todo::Ptr todo = todoFromItem(item);
    if (todo) {
        return todo->categories();
    } else {
        return QStringList();
    }
}

QStringList TodoMetadataModel::childUidsFromItem(const Akonadi::Item &item) const
{
    KCalCore::Todo::Ptr todo = todoFromItem(item);
    if (todo) {
        return m_childrenMap[todo->uid()];
    } else {
        return QStringList();
    }
}

QModelIndexList TodoMetadataModel::childIndexesFromIndex(const QModelIndex &idx) const
{
    QModelIndexList indexes;
    KCalCore::Todo::Ptr todo = todoFromIndex(idx);
    if (!todo) {
        return indexes;
    }
    QString parent = todo->uid();
    for (int i = 0; i < rowCount(idx.parent()); ++i) {
        QModelIndex child = index(i, idx.column(), idx.parent());
        todo = todoFromIndex(child);
        if (!todo) {
            continue;
        }
        if (m_parentMap[todo->uid()] == parent) {
            indexes << child;
        }
    }
    return indexes;
}
<|endoftext|>


<commit_before>#pragma once

#include <map>
#include <string>

#include <boost/any.hpp>

#include "blackhole/dynamic.hpp"
#include "blackhole/error.hpp"

namespace blackhole {

namespace aux {

template<class T>
class extractor {
    dynamic_t source;
    std::string name;

public:
    extractor(dynamic_t source, std::string name = T::name()) :
        source(std::move(source)),
        name(std::move(name))
    {}

    extractor<T> operator[](const std::string& name) const {
        dynamic_t::object_t map;
        try {
            to(map);
        } catch (const std::exception&) {
            //!@todo: Throw specialized exceptions.
            throw error_t("can't extract '%s': '%s' is not map", name, this->name);
        }

        auto it = map.find(name);
        if (it == map.end()) {
            throw error_t("can't extract '%s' field from '%s': member is absent", name, T::name());
        }

        return extractor<T>(it->second, name);
    }

    template<typename R>
    void to(R& value) const {
        try {
            value = source.to<R>();
        } catch (const dynamic::bad_cast& err) {
            throw error_t("unable to extract '%s' field from '%s': %s", name, T::name(), err.what());
        }
    }

    template<typename R>
    R get() const {
        R value;
        to(value);
        return value;
    }

private:
};

} // namespace aux

}  // namespace blackhole
<commit_msg>[Code Clean] Removed unnecessary access identifier.<commit_after>#pragma once

#include <map>
#include <string>

#include <boost/any.hpp>

#include "blackhole/dynamic.hpp"
#include "blackhole/error.hpp"

namespace blackhole {

namespace aux {

template<class T>
class extractor {
    dynamic_t source;
    std::string name;

public:
    extractor(dynamic_t source, std::string name = T::name()) :
        source(std::move(source)),
        name(std::move(name))
    {}

    extractor<T> operator[](const std::string& name) const {
        dynamic_t::object_t map;
        try {
            to(map);
        } catch (const std::exception&) {
            throw error_t("can't extract '%s': '%s' is not map", name, this->name);
        }

        auto it = map.find(name);
        if (it == map.end()) {
            throw error_t("can't extract '%s' field from '%s': member is absent", name, T::name());
        }

        return extractor<T>(it->second, name);
    }

    template<typename R>
    void to(R& value) const {
        try {
            value = source.to<R>();
        } catch (const dynamic::bad_cast& err) {
            throw error_t("unable to extract '%s' field from '%s': %s", name, T::name(), err.what());
        }
    }

    template<typename R>
    R get() const {
        R value;
        to(value);
        return value;
    }
};

} // namespace aux

}  // namespace blackhole
<|endoftext|>


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

#ifndef ICDAR_READER_HPP
#define ICDAR_READER_HPP

#include <fstream>
#include <iostream>
#include <vector>
#include <cstdint>
#include <memory>
#include <string>

#include "jpeglib.h"

namespace icdar {

struct ICDAR_Rectangle {
    std::size_t left;
    std::size_t top;
    std::size_t right;
    std::size_t bottom;
    std::string text;
};

struct ICDAR_pixel {
    uint8_t r;
    uint8_t g;
    uint8_t b;
};

template<template<typename...> class Container>
struct ICDAR_label {
    Container<ICDAR_Rectangle> rectangles;
};

template<template<typename...> class Container>
struct ICDAR_image {
    std::size_t width;
    std::size_t height;
    Container<ICDAR_pixel> pixels;

    ICDAR_image(std::size_t width, std::size_t height) : width(width), height(height), pixels(width * height) {}
};

template<template<typename...> class Container = std::vector, template<typename...> class Sub = std::vector>
struct ICDAR_dataset {
    Container<ICDAR_image<Sub>> training_images;
    Container<ICDAR_image<Sub>> test_images;
    Container<ICDAR_label<Sub>> training_labels;
    Container<ICDAR_label<Sub>> test_labels;

    void resize_training(std::size_t new_size){
        if(training_images.size() > new_size){
            training_images.resize(new_size);
            training_labels.resize(new_size);
        }
    }

    void resize_test(std::size_t new_size){
        if(test_images.size() > new_size){
            test_images.resize(new_size);
            test_labels.resize(new_size);
        }
    }
};

template<template<typename...> class Container = std::vector, template<typename...> class Sub = std::vector>
Container<ICDAR_image<Sub>> read_images(const std::string& directory, const std::string& prefix, std::size_t first, std::size_t total, std::size_t limit = 0){
    auto max = limit == 0 ? total : std::min(total, limit);

    Container<ICDAR_image<Sub>> images;//(max);
    images.reserve(max);

    std::size_t cnt = 0;

    for(std::size_t image = first; image <= first + max; ++image){
        std::string name = prefix + std::to_string(image) + ".jpg";
        std::string path = directory + "/" + name;

        std::cout << path << std::endl;

        auto in_file = fopen(path.c_str(), "rb");

        if(!in_file){
            std::cout << "Error" << std::endl;
            break;
        }

        struct jpeg_decompress_struct cinfo;

        jpeg_error_mgr jerr;
        cinfo.err = jpeg_std_error(&jerr);

        jpeg_create_decompress(&cinfo);
        jpeg_stdio_src(&cinfo, in_file);
        jpeg_read_header(&cinfo, true);
        jpeg_start_decompress(&cinfo);

        auto row_stride = cinfo.output_width * cinfo.output_components;

        images.emplace_back(cinfo.output_width, cinfo.output_height);

        JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

        while (cinfo.output_scanline < cinfo.output_height) {
            jpeg_read_scanlines(&cinfo, buffer, 1);

            for(std::size_t i = 0; i < cinfo.output_width; ++i){
                images.back().pixels[(cinfo.output_scanline - 1) * cinfo.output_width + i].r = buffer[0][i*cinfo.output_components];
                images.back().pixels[(cinfo.output_scanline - 1) * cinfo.output_width + i].g = buffer[0][i*cinfo.output_components+1];
                images.back().pixels[(cinfo.output_scanline - 1) * cinfo.output_width + i].b = buffer[0][i*cinfo.output_components+2];
            }
        }

        jpeg_finish_decompress(&cinfo);
        jpeg_destroy_decompress(&cinfo);
        fclose(in_file);
        ++cnt;
    }

    std::cout << "image cnt:" << cnt << std::endl;

    return images;
}

template<template<typename...> class Container = std::vector, template<typename...> class Sub = std::vector>
Container<ICDAR_label<Sub>> read_labels(const std::string& directory, const std::string& prefix, std::size_t first, std::size_t total, bool csv, std::size_t limit = 0){
    auto max = limit == 0 ? total : std::min(total, limit);

    Container<ICDAR_label<Sub>> labels(max);

    std::size_t cnt = 0;

    for(std::size_t label = first; label < first + max; ++label){
        std::string name = prefix + std::to_string(label) + ".txt";
        std::string path = directory + "/" + name;

        std::cout << path << std::endl;

        std::ifstream file(path);
        std::string line;
        while (std::getline(file, line)){
            ICDAR_Rectangle rect;

            char sep = ',';

            if(!csv){
                sep = ' ';
            }

            auto start = 0;
            auto pos = line.find(sep, start);

            rect.left = std::stoll(std::string(line.begin() + start, line.begin() + pos));

            start = pos+1;
            pos = line.find(sep, start);
            rect.top = std::stoll(std::string(line.begin() + start, line.begin() + pos));

            start = pos+1;
            pos = line.find(sep, start);
            rect.right = std::stoll(std::string(line.begin() + start, line.begin() + pos));

            start = pos+1;
            pos = line.find(sep, start);
            rect.bottom = std::stoll(std::string(line.begin() + start, line.begin() + pos));

            rect.text = std::string(line.begin() + pos + 2, line.end());

            labels[label - first].rectangles.emplace_back(std::move(rect));
        }
        ++cnt;
    }

    std::cout << "label cnt:" << cnt << std::endl;

    return labels;
}

template<template<typename...> class Container = std::vector, template<typename...> class Sub = std::vector>
ICDAR_dataset<Container, Sub> read_2013_dataset(const std::string& train_directory, const std::string& test_directory, std::size_t training_limit = 0, std::size_t test_limit = 0){
    ICDAR_dataset<Container, Sub> dataset;

    dataset.training_labels = read_labels<Container, Sub>(train_directory, "gt_", 100, 229, false, training_limit);
    dataset.training_images = read_images<Container, Sub>(train_directory, "", 100, 229, training_limit);

    dataset.test_labels = read_labels<Container, Sub>(test_directory, "gt_img_", 1, 233, true, test_limit);
    dataset.test_images = read_images<Container, Sub>(test_directory, "img_", 1, 233, test_limit);

    std::cout << dataset.training_images.size() << std::endl;
    std::cout << dataset.training_labels.size() << std::endl;
    std::cout << dataset.test_images.size() << std::endl;
    std::cout << dataset.test_images.size() << std::endl;

    return std::move(dataset);
}

} //end of icdar namespace

#endif //ICDAR_READER_HPP<commit_msg>Cleanup<commit_after>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef ICDAR_READER_HPP
#define ICDAR_READER_HPP

#include <fstream>
#include <iostream>
#include <vector>
#include <cstdint>
#include <memory>
#include <string>

#include "jpeglib.h"

namespace icdar {

struct ICDAR_Rectangle {
    std::size_t left;
    std::size_t top;
    std::size_t right;
    std::size_t bottom;
    std::string text;
};

struct ICDAR_pixel {
    uint8_t r;
    uint8_t g;
    uint8_t b;
};

template<template<typename...> class Container>
struct ICDAR_label {
    Container<ICDAR_Rectangle> rectangles;
};

template<template<typename...> class Container>
struct ICDAR_image {
    std::size_t width;
    std::size_t height;
    Container<ICDAR_pixel> pixels;

    ICDAR_image(std::size_t width, std::size_t height) : width(width), height(height), pixels(width * height) {}
};

template<template<typename...> class Container = std::vector, template<typename...> class Sub = std::vector>
struct ICDAR_dataset {
    Container<ICDAR_image<Sub>> training_images;
    Container<ICDAR_image<Sub>> test_images;
    Container<ICDAR_label<Sub>> training_labels;
    Container<ICDAR_label<Sub>> test_labels;

    void resize_training(std::size_t new_size){
        if(training_images.size() > new_size){
            training_images.resize(new_size);
            training_labels.resize(new_size);
        }
    }

    void resize_test(std::size_t new_size){
        if(test_images.size() > new_size){
            test_images.resize(new_size);
            test_labels.resize(new_size);
        }
    }
};

template<template<typename...> class Container = std::vector, template<typename...> class Sub = std::vector>
Container<ICDAR_image<Sub>> read_images(const std::string& directory, const std::string& prefix, std::size_t first, std::size_t total, std::size_t limit = 0){
    auto max = limit == 0 ? total : std::min(total, limit);

    Container<ICDAR_image<Sub>> images;
    images.reserve(max);

    for(std::size_t image = first; image <= first + max; ++image){
        std::string name = prefix + std::to_string(image) + ".jpg";
        std::string path = directory + "/" + name;

        std::cout << path << std::endl;

        auto in_file = fopen(path.c_str(), "rb");

        if(!in_file){
            std::cout << "Error" << std::endl;
            break;
        }

        struct jpeg_decompress_struct cinfo;

        jpeg_error_mgr jerr;
        cinfo.err = jpeg_std_error(&jerr);

        jpeg_create_decompress(&cinfo);
        jpeg_stdio_src(&cinfo, in_file);
        jpeg_read_header(&cinfo, true);
        jpeg_start_decompress(&cinfo);

        auto row_stride = cinfo.output_width * cinfo.output_components;

        images.emplace_back(cinfo.output_width, cinfo.output_height);

        JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

        while (cinfo.output_scanline < cinfo.output_height) {
            jpeg_read_scanlines(&cinfo, buffer, 1);

            for(std::size_t i = 0; i < cinfo.output_width; ++i){
                auto& pixel = images.back().pixels[(cinfo.output_scanline - 1) * cinfo.output_width + i];

                pixel.r = buffer[0][i*cinfo.output_components];
                pixel.g = buffer[0][i*cinfo.output_components+1];
                pixel.b = buffer[0][i*cinfo.output_components+2];
            }
        }

        jpeg_finish_decompress(&cinfo);
        jpeg_destroy_decompress(&cinfo);
        fclose(in_file);
    }

    return images;
}

template<template<typename...> class Container = std::vector, template<typename...> class Sub = std::vector>
Container<ICDAR_label<Sub>> read_labels(const std::string& directory, const std::string& prefix, std::size_t first, std::size_t total, bool csv, std::size_t limit = 0){
    auto max = limit == 0 ? total : std::min(total, limit);

    Container<ICDAR_label<Sub>> labels(max);

    std::size_t cnt = 0;

    for(std::size_t label = first; label < first + max; ++label){
        std::string name = prefix + std::to_string(label) + ".txt";
        std::string path = directory + "/" + name;

        std::cout << path << std::endl;

        std::ifstream file(path);
        std::string line;
        while (std::getline(file, line)){
            ICDAR_Rectangle rect;

            char sep = ',';

            if(!csv){
                sep = ' ';
            }

            auto start = 0;
            auto pos = line.find(sep, start);

            rect.left = std::stoll(std::string(line.begin() + start, line.begin() + pos));

            start = pos+1;
            pos = line.find(sep, start);
            rect.top = std::stoll(std::string(line.begin() + start, line.begin() + pos));

            start = pos+1;
            pos = line.find(sep, start);
            rect.right = std::stoll(std::string(line.begin() + start, line.begin() + pos));

            start = pos+1;
            pos = line.find(sep, start);
            rect.bottom = std::stoll(std::string(line.begin() + start, line.begin() + pos));

            rect.text = std::string(line.begin() + pos + 2, line.end());

            labels[label - first].rectangles.emplace_back(std::move(rect));
        }
        ++cnt;
    }

    std::cout << "label cnt:" << cnt << std::endl;

    return labels;
}

template<template<typename...> class Container = std::vector, template<typename...> class Sub = std::vector>
ICDAR_dataset<Container, Sub> read_2013_dataset(const std::string& train_directory, const std::string& test_directory, std::size_t training_limit = 0, std::size_t test_limit = 0){
    ICDAR_dataset<Container, Sub> dataset;

    dataset.training_labels = read_labels<Container, Sub>(train_directory, "gt_", 100, 229, false, training_limit);
    dataset.training_images = read_images<Container, Sub>(train_directory, "", 100, 229, training_limit);

    dataset.test_labels = read_labels<Container, Sub>(test_directory, "gt_img_", 1, 233, true, test_limit);
    dataset.test_images = read_images<Container, Sub>(test_directory, "img_", 1, 233, test_limit);

    std::cout << dataset.training_images.size() << std::endl;
    std::cout << dataset.training_labels.size() << std::endl;
    std::cout << dataset.test_images.size() << std::endl;
    std::cout << dataset.test_images.size() << std::endl;

    return std::move(dataset);
}

} //end of icdar namespace

#endif //ICDAR_READER_HPP<|endoftext|>


<commit_before>// WGLGrabber.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#pragma comment(lib, "opengl32.lib")

HGLRC hglrc;

struct GLFunc
{
	GLFunc(){}
	GLFunc(const GLFunc& r) {
		*this = r;
	}
	const GLFunc& operator=(const GLFunc& r) {
		name = r.name;
		decl = r.decl;
		caster = r.caster;
		return *this;
	}
	std::string name;
	std::string decl;
	std::string caster;
};
std::vector<GLFunc> glFuncs;

static void err(char *msg)
{
	puts(msg);
}

void Create()
{
	HWND hWnd = GetDesktopWindow();
	HDC hdc = GetDC(hWnd);

	PIXELFORMATDESCRIPTOR pfd;
	memset(&pfd, 0, sizeof(pfd));
	pfd.nSize = sizeof(pfd);
	pfd.nVersion = 1;
	pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
	pfd.iPixelType = PFD_TYPE_RGBA;
	pfd.cColorBits = 24;
	pfd.cDepthBits = 32;
	pfd.iLayerType = PFD_MAIN_PLANE;
	int pixelFormat;
	if (!(pixelFormat = ChoosePixelFormat(hdc, &pfd))){
		err("ChoosePixelFormat failed.");
		goto END;
	}
	if (!SetPixelFormat(hdc, pixelFormat, &pfd)){
		err("SetPixelFormat failed.");
		goto END;
	}
	if (!(hglrc = wglCreateContext(hdc))){
		err("wglCreateContext failed.");
		goto END;
	}
	if (!wglMakeCurrent(hdc, hglrc)){
		err("wglMakeCurrent failed.");
		goto END;
	}
	void* glpu = wglGetProcAddress("glProgramUniform1f");
	void* gldei = wglGetProcAddress("glDrawElementsIndirect");
	void* glen1 = glEnable;
	void* glen2 = wglGetProcAddress("glEnable");
	GLuint (*glCreateProgram)(void);
	glCreateProgram = (GLuint (*)(void))wglGetProcAddress("glCreateProgram");
	GLuint (*glCreateShader)(GLenum type);
	glCreateShader = (GLuint(*)(GLenum type))wglGetProcAddress("glCreateShader");
	PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
	static const int attribList[] = {
		WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
		WGL_CONTEXT_MINOR_VERSION_ARB, 0,
		WGL_CONTEXT_FLAGS_ARB, 0,
		WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_ES2_PROFILE_BIT_EXT,
		0,
	};
	HGLRC hglrcNew = wglCreateContextAttribsARB(hdc, 0, attribList);
	if (hglrcNew) {
		wglDeleteContext(hglrc);
		hglrc = hglrcNew;
	}
END:
	ReleaseDC(hWnd, hdc);
}

void Destroy()
{
	wglMakeCurrent(nullptr, nullptr);
	if (hglrc) {
		wglDeleteContext(hglrc);
		hglrc = nullptr;
	}
}

void Grab()
{
	//	char* h = (char*)LoadFile("glheaders/wglext.h");
	char* h = (char*)LoadFile("glheaders/glext.h");
	//	std::regex pattern("wglCreateContextAttribsARB");
	std::regex pattern("^GLAPI\\s+(\\w+)\\s+APIENTRY\\s+(\\w+)\\s*(\\(.*\\))");
	//	std::regex pattern("PFN[A-Za-Z0-9_]+PROC");
	std::cmatch match;
	std::string str = h;
	auto funcBegin = std::sregex_iterator(str.begin(), str.end(), pattern);
	auto End = std::sregex_iterator();
	int dist = std::distance(funcBegin, End);
	printf("%d functions found\n", dist);
	for (auto it = funcBegin; it != End; it++) {
		std::smatch m = *it;
		if (m.size() < 4) {
			continue;
		}
		GLFunc func;
		func.name = m[2].str();
		func.decl = m[1].str() + " " + m[2].str() + m[3].str();
		func.caster = m[1].str() + " (*)" + m[3].str();
		glFuncs.push_back(func);
	}
	free(h);
}

int _tmain(int argc, _TCHAR* argv[])
{
	GoMyDir();
	Create();
	Grab();
	Destroy();
	return 0;
}

<commit_msg>source code generation<commit_after>// WGLGrabber.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#pragma comment(lib, "opengl32.lib")

HGLRC hglrc;

struct GLFunc
{
	GLFunc(){}
	GLFunc(const GLFunc& r) {
		*this = r;
	}
	const GLFunc& operator=(const GLFunc& r) {
		name = r.name;
		decl = r.decl;
		caster = r.caster;
		return *this;
	}
	std::string name;
	std::string decl;
	std::string caster;
};
std::vector<GLFunc> glFuncs;

static void err(char *msg)
{
	puts(msg);
}

void Create()
{
	HWND hWnd = GetDesktopWindow();
	HDC hdc = GetDC(hWnd);

	PIXELFORMATDESCRIPTOR pfd;
	memset(&pfd, 0, sizeof(pfd));
	pfd.nSize = sizeof(pfd);
	pfd.nVersion = 1;
	pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
	pfd.iPixelType = PFD_TYPE_RGBA;
	pfd.cColorBits = 24;
	pfd.cDepthBits = 32;
	pfd.iLayerType = PFD_MAIN_PLANE;
	int pixelFormat;
	if (!(pixelFormat = ChoosePixelFormat(hdc, &pfd))){
		err("ChoosePixelFormat failed.");
		goto END;
	}
	if (!SetPixelFormat(hdc, pixelFormat, &pfd)){
		err("SetPixelFormat failed.");
		goto END;
	}
	if (!(hglrc = wglCreateContext(hdc))){
		err("wglCreateContext failed.");
		goto END;
	}
	if (!wglMakeCurrent(hdc, hglrc)){
		err("wglMakeCurrent failed.");
		goto END;
	}
	void* glpu = wglGetProcAddress("glProgramUniform1f");
	void* gldei = wglGetProcAddress("glDrawElementsIndirect");
	void* glen1 = glEnable;
	void* glen2 = wglGetProcAddress("glEnable");
	GLuint (*glCreateProgram)(void);
	glCreateProgram = (GLuint (*)(void))wglGetProcAddress("glCreateProgram");
	GLuint (*glCreateShader)(GLenum type);
	glCreateShader = (GLuint(*)(GLenum type))wglGetProcAddress("glCreateShader");
	PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
	static const int attribList[] = {
		WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
		WGL_CONTEXT_MINOR_VERSION_ARB, 0,
		WGL_CONTEXT_FLAGS_ARB, 0,
		WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_ES2_PROFILE_BIT_EXT,
		0,
	};
	HGLRC hglrcNew = wglCreateContextAttribsARB(hdc, 0, attribList);
	if (hglrcNew) {
		wglDeleteContext(hglrc);
		hglrc = hglrcNew;
	}
END:
	ReleaseDC(hWnd, hdc);
}

void Destroy()
{
	wglMakeCurrent(nullptr, nullptr);
	if (hglrc) {
		wglDeleteContext(hglrc);
		hglrc = nullptr;
	}
}

void Grab()
{
	//	char* h = (char*)LoadFile("glheaders/wglext.h");
	char* h = (char*)LoadFile("glheaders/glext.h");
	//	std::regex pattern("wglCreateContextAttribsARB");
	std::regex pattern("^GLAPI\\s+(\\w+)\\s+APIENTRY\\s+(\\w+)\\s*(\\(.*\\))");
	//	std::regex pattern("PFN[A-Za-Z0-9_]+PROC");
	std::cmatch match;
	std::string str = h;
	auto funcBegin = std::sregex_iterator(str.begin(), str.end(), pattern);
	auto End = std::sregex_iterator();
	int dist = std::distance(funcBegin, End);
	printf("%d functions found\n", dist);
	int i = 0;
	for (auto it = funcBegin; it != End; it++) {
		std::smatch m = *it;
		if (m.size() < 4) {
			continue;
		}
		GLFunc func;
		func.name = m[2].str();
		func.decl = m[1].str() + " (*" + m[2].str() + ")" + m[3].str();
		func.caster = m[1].str() + " (*)" + m[3].str();
		glFuncs.push_back(func);
		printf("\r%d/%d", i++, dist);
	}
	printf("\n");
	free(h);
}

void CodeGen()
{
	std::string hdr, cpp;
	hdr = "#include <GL/gl.h>\r\n";
	for (auto it : glFuncs) {
		hdr += std::string("extern ") + it.decl + ";\r\n";
	}
	puts(hdr.c_str());

	cpp = "#include \"WGLGrabberGen.h\"\r\n";
	cpp += "void WGLGrabberInit()\r\n";
	cpp += "{\r\n";
	for (auto it : glFuncs) {
		cpp += std::string("\t") + it.name + " = (" + it.caster + ")wglGetProcAddress(\"" + it.name + "\");\r\n";
	}
	cpp += "}\r\n";

	puts(cpp.c_str());
}

int _tmain(int argc, _TCHAR* argv[])
{
	GoMyDir();
	Create();
	Grab();
	CodeGen();
	Destroy();
	return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015-2016, Technische Universität Dresden, Germany
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions
 *    and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other materials provided
 *    with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to
 *    endorse or promote products derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef INCLUDE_NITRO_LANG_REVERSE_HPP
#define INCLUDE_NITRO_LANG_REVERSE_HPP

#include <vector>

namespace nitro
{
namespace lang
{

    namespace detail
    {
        template <typename T, typename Iterator>
        class reverse_proxy
        {
        public:
            using iterator = Iterator;

            reverse_proxy(iterator begin, iterator end) : begin_(begin), end_(end)
            {
            }

            iterator begin() const
            {
                return begin_;
            }

            iterator end() const
            {
                return end_;
            }

        private:
            iterator begin_;
            iterator end_;
        };

        template <typename T>
        class reverse
        {
        public:
            reverse(T container) : container_(std::move(container))
            {
            }

            auto begin() const
            {
                using std::crbegin;
                return crbegin(container_);
            }

            auto end() const
            {
                using std::crend;
                return crend(container_);
            }

        private:
            T container_;
        };
    }

    template <typename T>
    inline auto reverse(const T& container)
    {
        using std::rbegin;
        using std::rend;

        return detail::reverse_proxy<T, decltype(rbegin(container))>(rbegin(container),
                                                                     rend(container));
    }

    template <typename T>
    inline auto reverse(T& container)
    {
        using std::rbegin;
        using std::rend;

        return detail::reverse_proxy<T, decltype(rbegin(container))>(rbegin(container),
                                                                     rend(container));
    }

    template <typename T>
    inline auto reverse(T&& container)
    {
        return detail::reverse<T>(std::move(container));
    }

    template <typename T>
    inline auto reverse(std::initializer_list<T> l)
    {
        return reverse(std::vector<T>(l));
    }
}
} // namespace nitr::lang

#endif // INCLUDE_NITRO_LANG_REVERSE_HPP
<commit_msg>Fixes remaining crbegin<commit_after>/*
 * Copyright (c) 2015-2016, Technische Universität Dresden, Germany
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions
 *    and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other materials provided
 *    with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to
 *    endorse or promote products derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef INCLUDE_NITRO_LANG_REVERSE_HPP
#define INCLUDE_NITRO_LANG_REVERSE_HPP

#include <vector>

namespace nitro
{
namespace lang
{

    namespace detail
    {
        template <typename T, typename Iterator>
        class reverse_proxy
        {
        public:
            using iterator = Iterator;

            reverse_proxy(iterator begin, iterator end) : begin_(begin), end_(end)
            {
            }

            iterator begin() const
            {
                return begin_;
            }

            iterator end() const
            {
                return end_;
            }

        private:
            iterator begin_;
            iterator end_;
        };

        template <typename T>
        class reverse
        {
        public:
            reverse(T container) : container_(std::move(container))
            {
            }

            auto begin() const
            {
                using std::rbegin;
                return rbegin(container_);
            }

            auto end() const
            {
                using std::rend;
                return rend(container_);
            }

        private:
            T container_;
        };
    }

    template <typename T>
    inline auto reverse(const T& container)
    {
        using std::rbegin;
        using std::rend;

        return detail::reverse_proxy<T, decltype(rbegin(container))>(rbegin(container),
                                                                     rend(container));
    }

    template <typename T>
    inline auto reverse(T& container)
    {
        using std::rbegin;
        using std::rend;

        return detail::reverse_proxy<T, decltype(rbegin(container))>(rbegin(container),
                                                                     rend(container));
    }

    template <typename T>
    inline auto reverse(T&& container)
    {
        return detail::reverse<T>(std::move(container));
    }

    template <typename T>
    inline auto reverse(std::initializer_list<T> l)
    {
        return reverse(std::vector<T>(l));
    }
}
} // namespace nitr::lang

#endif // INCLUDE_NITRO_LANG_REVERSE_HPP
<|endoftext|>


<commit_before>#ifndef PROTOZERO_BYTESWAP_HPP
#define PROTOZERO_BYTESWAP_HPP

/*****************************************************************************

protozero - Minimalistic protocol buffer decoder and encoder in C++.

This file is from https://github.com/mapbox/protozero where you can find more
documentation.

*****************************************************************************/

/**
 * @file byteswap.hpp
 *
 * @brief Contains functions to swap bytes in values (for different endianness).
 */

#include <cstdint>
#include <cassert>

#include <protozero/config.hpp>

namespace protozero {

/**
 * Swap N byte value between endianness formats. This template function must
 * be specialized to actually work.
 */
template <int N>
inline void byteswap(const char* /*data*/, char* /*result*/) {
    static_assert(N == 1, "Can only swap 4 or 8 byte values");
}

/**
 * Swap 4 byte value (int32_t, uint32_t, float) between endianness formats.
 */
template <>
inline void byteswap<4>(const char* data, char* result) {
#ifdef PROTOZERO_USE_BUILTIN_BSWAP
    *reinterpret_cast<uint32_t*>(result) = __builtin_bswap32(*reinterpret_cast<const uint32_t*>(data));
#else
    result[3] = data[0];
    result[2] = data[1];
    result[1] = data[2];
    result[0] = data[3];
#endif
}

/**
 * Swap 8 byte value (int64_t, uint64_t, double) between endianness formats.
 */
template <>
inline void byteswap<8>(const char* data, char* result) {
#ifdef PROTOZERO_USE_BUILTIN_BSWAP
    *reinterpret_cast<uint64_t*>(result) = __builtin_bswap64(*reinterpret_cast<const uint64_t*>(data));
#else
    result[7] = data[0];
    result[6] = data[1];
    result[5] = data[2];
    result[4] = data[3];
    result[3] = data[4];
    result[2] = data[5];
    result[1] = data[6];
    result[0] = data[7];
#endif
}

} // end namespace protozero

#endif // PROTOZERO_BYTESWAP_HPP
<commit_msg>Make a few helper functions noexcept.<commit_after>#ifndef PROTOZERO_BYTESWAP_HPP
#define PROTOZERO_BYTESWAP_HPP

/*****************************************************************************

protozero - Minimalistic protocol buffer decoder and encoder in C++.

This file is from https://github.com/mapbox/protozero where you can find more
documentation.

*****************************************************************************/

/**
 * @file byteswap.hpp
 *
 * @brief Contains functions to swap bytes in values (for different endianness).
 */

#include <cstdint>
#include <cassert>

#include <protozero/config.hpp>

namespace protozero {

/**
 * Swap N byte value between endianness formats. This template function must
 * be specialized to actually work.
 */
template <int N>
inline void byteswap(const char* /*data*/, char* /*result*/) noexcept {
    static_assert(N == 1, "Can only swap 4 or 8 byte values");
}

/**
 * Swap 4 byte value (int32_t, uint32_t, float) between endianness formats.
 */
template <>
inline void byteswap<4>(const char* data, char* result) noexcept {
#ifdef PROTOZERO_USE_BUILTIN_BSWAP
    *reinterpret_cast<uint32_t*>(result) = __builtin_bswap32(*reinterpret_cast<const uint32_t*>(data));
#else
    result[3] = data[0];
    result[2] = data[1];
    result[1] = data[2];
    result[0] = data[3];
#endif
}

/**
 * Swap 8 byte value (int64_t, uint64_t, double) between endianness formats.
 */
template <>
inline void byteswap<8>(const char* data, char* result) noexcept {
#ifdef PROTOZERO_USE_BUILTIN_BSWAP
    *reinterpret_cast<uint64_t*>(result) = __builtin_bswap64(*reinterpret_cast<const uint64_t*>(data));
#else
    result[7] = data[0];
    result[6] = data[1];
    result[5] = data[2];
    result[4] = data[3];
    result[3] = data[4];
    result[2] = data[5];
    result[1] = data[6];
    result[0] = data[7];
#endif
}

} // end namespace protozero

#endif // PROTOZERO_BYTESWAP_HPP
<|endoftext|>


<commit_before>#ifndef PROTOZERO_BYTESWAP_HPP
#define PROTOZERO_BYTESWAP_HPP

/*****************************************************************************

protozero - Minimalistic protocol buffer decoder and encoder in C++.

This file is from https://github.com/mapbox/protozero where you can find more
documentation.

*****************************************************************************/

#include <cassert>

namespace protozero {

template <int N>
inline void byteswap(const char* /*data*/, char* /*result*/) {
    assert(false);
}

template <>
inline void byteswap<1>(const char* data, char* result) {
    result[0] = data[0];
}

template <>
inline void byteswap<4>(const char* data, char* result) {
    result[3] = data[0];
    result[2] = data[1];
    result[1] = data[2];
    result[0] = data[3];
}

template <>
inline void byteswap<8>(const char* data, char* result) {
    result[7] = data[0];
    result[6] = data[1];
    result[5] = data[2];
    result[4] = data[3];
    result[3] = data[4];
    result[2] = data[5];
    result[1] = data[6];
    result[0] = data[7];
}

} // end namespace protozero

#endif // PROTOZERO_BYTESWAP_HPP
<commit_msg>Use static_assert instead of runtime assert for missing implementation.<commit_after>#ifndef PROTOZERO_BYTESWAP_HPP
#define PROTOZERO_BYTESWAP_HPP

/*****************************************************************************

protozero - Minimalistic protocol buffer decoder and encoder in C++.

This file is from https://github.com/mapbox/protozero where you can find more
documentation.

*****************************************************************************/

#include <cassert>

namespace protozero {

template <int N>
inline void byteswap(const char* /*data*/, char* /*result*/) {
    static_assert(N == 1, "Can only swap 1, 4, or 8 byte values");
}

template <>
inline void byteswap<1>(const char* data, char* result) {
    result[0] = data[0];
}

template <>
inline void byteswap<4>(const char* data, char* result) {
    result[3] = data[0];
    result[2] = data[1];
    result[1] = data[2];
    result[0] = data[3];
}

template <>
inline void byteswap<8>(const char* data, char* result) {
    result[7] = data[0];
    result[6] = data[1];
    result[5] = data[2];
    result[4] = data[3];
    result[3] = data[4];
    result[2] = data[5];
    result[1] = data[6];
    result[0] = data[7];
}

} // end namespace protozero

#endif // PROTOZERO_BYTESWAP_HPP
<|endoftext|>


<commit_before>#pragma once

#include <utility>
#include <vector>
#include <algorithm>

#include "reflection_info.hpp"

namespace shadow
{
////////////////////////////////////////////////////////////////////////////////
// user facing API types carrying information and functionality for the
// reflection system

class reflection_manager;

// holds one value with type/reflection information
class variable
{
private:
    // holds type erased value
    any value_;
    // these identify the type erased value
    const reflection_manager* manager_;
    std::size_t type_index_;
};

template <class InfoType, template <class> class... Policies>
class api_type_aggregator
    : public Policies<api_type_aggregator<InfoType, Policies...>>...
{
public:
    api_type_aggregator() : info_(nullptr), manager_(nullptr)
    {
    }

    api_type_aggregator(const InfoType* info, const reflection_manager* manager)
        : info_(info), manager_(manager)
    {
    }

    api_type_aggregator* operator->()
    {
        return this;
    }

    const api_type_aggregator* operator->() const
    {
        return this;
    }

public:
    const InfoType* info_;
    const reflection_manager* manager_;
};

template <class Derived>
class get_name_policy
{
public:
    std::string
    name() const
    {
        return (static_cast<const Derived*>(this))->info_->name;
    }
};

template <class Derived>
class get_size_policy
{
public:
    std::size_t
    size() const
    {
        return static_cast<const Derived*>(this)->info_->size;
    }
};

typedef api_type_aggregator<type_info, get_name_policy, get_size_policy> type_;

template <class Derived>
class get_type_policy
{
public:
    type_
    get_type() const
    {
        // retrieve type index
        const auto type_index =
            static_cast<const Derived*>(this)->info_->type_index;

        return static_cast<const Derived*>(this)->manager_->type_by_index(
            type_index);
    }
};

typedef api_type_aggregator<constructor_info, get_type_policy> constructor_;

template <class InfoType, class ProxyType>
class info_iterator_
{
public:
    typedef ProxyType value_type;
    typedef typename std::iterator_traits<const InfoType*>::difference_type
        difference_type;
    typedef ProxyType reference;
    typedef ProxyType pointer;
    typedef typename std::iterator_traits<const InfoType*>::iterator_category
        iterator_category;

public:
    info_iterator_() = default;

    info_iterator_(const InfoType* current, const reflection_manager* manager)
        : current_(current), manager_(manager)
    {
    }

public:
    ProxyType operator*() const
    {
        return ProxyType(current_, manager_);
    }

    ProxyType operator->() const
    {
        return ProxyType(current_, manager_);
    }

    ProxyType operator[](difference_type n) const
    {
        return ProxyType(current_ + n, manager_);
    }

    info_iterator_& operator++()
    {
        ++current_;
        return *this;
    }

    info_iterator_ operator++(int)
    {
        auto temp = *this;
        ++(*this);
        return temp;
    }

    info_iterator_& operator--()
    {
        --current_;
        return *this;
    }

    info_iterator_ operator--(int)
    {
        auto temp = *this;
        --(*this);
        return temp;
    }

    info_iterator_&
    operator+=(difference_type n)
    {
        current_ += n;
        return *this;
    }

    info_iterator_&
    operator-=(difference_type n)
    {
        current_ -= n;
        return *this;
    }

    info_iterator_
    operator+(difference_type n) const
    {
        return info_iterator_(current_ + n, manager_);
    }

    info_iterator_
    operator-(difference_type n) const
    {
        return info_iterator_(current_ - n, manager_);
    }

    difference_type
    operator-(const info_iterator_& other)
    {
        return current_ - other.current_;
    }

    friend info_iterator_
    operator+(difference_type lhs, const info_iterator_& rhs)
    {
        return rhs + lhs;
    }

    bool
    operator==(const info_iterator_& other) const
    {
        return current_ == other.current_;
    }

    bool
    operator!=(const info_iterator_& other) const
    {
        return current_ != other.current_;
    }

    bool
    operator<(const info_iterator_& other) const
    {
        return current_ < other.current_;
    }

    bool
    operator>(const info_iterator_& other) const
    {
        return current_ > other.current_;
    }

    bool
    operator<=(const info_iterator_& other) const
    {
        return current_ <= other.current_;
    }

    bool
    operator>=(const info_iterator_& other) const
    {
        return current_ >= other.current_;
    }

private:
    InfoType* current_;
    const reflection_manager* manager_;
};

class reflection_manager
{
public:
    template <class Derived>
    friend class get_type_policy;

    typedef type_ type;
    typedef info_iterator_<const type_info, const type> const_type_iterator;

    typedef constructor_ constructor;
    typedef info_iterator_<const constructor_info, const constructor>
        const_constructor_iterator;

public:
    reflection_manager() = default;

    template <class TypeInfoArrayHolder,
              class ConstructorInfoArrayHolder,
              class ConversionInfoArrayHolder,
              class StringSerializationInfoArrayHolder,
              class FreeFunctionInfoArrayHolder,
              class MemberFunctionInfoArrayHolder,
              class MemberVariableInfoArrayHolder>
    reflection_manager(TypeInfoArrayHolder,
                       ConstructorInfoArrayHolder,
                       ConversionInfoArrayHolder,
                       StringSerializationInfoArrayHolder,
                       FreeFunctionInfoArrayHolder,
                       MemberFunctionInfoArrayHolder,
                       MemberVariableInfoArrayHolder)
        : type_info_range_(initialize_range(TypeInfoArrayHolder())),
          constructor_info_range_(
              initialize_range(ConstructorInfoArrayHolder())),
          conversion_info_range_(initialize_range(ConversionInfoArrayHolder())),
          string_serialization_info_range_(
              initialize_range(StringSerializationInfoArrayHolder())),
          free_function_info_range_(
              initialize_range(FreeFunctionInfoArrayHolder())),
          member_function_info_range_(
              initialize_range(MemberFunctionInfoArrayHolder())),
          member_variable_info_range_(
              initialize_range(MemberVariableInfoArrayHolder())),
          constructor_info_by_index_(buckets_by_index(
              constructor_info_range_,
              TypeInfoArrayHolder(),
              [](const auto& info) { return info.type_index; })),
          conversion_info_by_index_(buckets_by_index(
              conversion_info_range_,
              TypeInfoArrayHolder(),
              [](const auto& info) { return info.from_type_index; })),
          member_function_info_by_index_(buckets_by_index(
              member_function_info_range_,
              TypeInfoArrayHolder(),
              [](const auto& info) { return info.object_type_index; }))
    {
    }

private:
// clang complains here due to the comparison of decayed array and
// nullptr, since in the case ArrayHolderType::value was an array, this
// would always evaluate to true. The fact is that
// ArrayHolderType::value may be a pointer to nullptr for some cases of
// ArrayHolderType.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
    template <class ArrayHolderType>
    std::pair<const typename ArrayHolderType::type*,
              const typename ArrayHolderType::type*>
        initialize_range(ArrayHolderType)
    {
        if(ArrayHolderType::value != nullptr)
        {
            return std::make_pair(std::begin(ArrayHolderType::value),
                                  std::end(ArrayHolderType::value));
        }
        else
        {
            std::pair<const typename ArrayHolderType::type*,
                      const typename ArrayHolderType::type*>
                out(nullptr, nullptr);

            return out;
        }
    }

    template <class ArrayHolderType>
    std::size_t array_size(ArrayHolderType)
    {
        if(ArrayHolderType::value == nullptr)
        {
            return 0;
        }
        else
        {
            return std::extent<decltype(ArrayHolderType::value)>::value;
        }
    }

    template <class ValueType, class TypeInfoArrayHolder, class Fun>
    std::vector<std::vector<ValueType>>
    buckets_by_index(const std::pair<const ValueType*, const ValueType*>& range,
                     TypeInfoArrayHolder,
                     Fun index_extractor)
    {
        if(range.first != nullptr && range.second != nullptr)
        {
            std::vector<std::vector<ValueType>> out(
                array_size(TypeInfoArrayHolder()));

            std::for_each(range.first,
                          range.second,
                          [&out, index_extractor](const auto& info) {
                              out[index_extractor(info)].push_back(info);
                          });

            return out;
        }
        else
        {
            return std::vector<std::vector<ValueType>>();
        }
    }

#pragma clang diagnostic pop

    type
    type_by_index(std::size_t index) const
    {
        return type(type_info_range_.first + index, this);
    }

public:
    ////////////////////////////////////////////////////////////////////////////
    // main api interface for interacting with the reflection system
    std::pair<const_type_iterator, const_type_iterator>
    types() const
    {
        return std::make_pair(
            const_type_iterator(type_info_range_.first, this),
            const_type_iterator(type_info_range_.second, this));
    }

    std::pair<const_constructor_iterator, const_constructor_iterator>
    constructors() const
    {
        return std::make_pair(
            const_constructor_iterator(constructor_info_range_.first, this),
            const_constructor_iterator(constructor_info_range_.second, this));
    }

private:
    // pairs hold iterators to beginning and end of arrays of information
    // generated at compile time
    std::pair<const type_info*, const type_info*> type_info_range_;
    std::pair<const constructor_info*, const constructor_info*>
        constructor_info_range_;
    std::pair<const conversion_info*, const conversion_info*>
        conversion_info_range_;
    std::pair<const string_serialization_info*,
              const string_serialization_info*>
        string_serialization_info_range_;
    std::pair<const free_function_info*, const free_function_info*>
        free_function_info_range_;
    std::pair<const member_function_info*, const member_function_info*>
        member_function_info_range_;
    std::pair<const member_variable_info*, const member_variable_info*>
        member_variable_info_range_;

    // sorted information
    std::vector<std::vector<constructor_info>> constructor_info_by_index_;
    std::vector<std::vector<conversion_info>> conversion_info_by_index_;
    std::vector<std::vector<member_function_info>>
        member_function_info_by_index_;
};
}

namespace std
{
// specialize std::iterator_traits for info_iterator_

template <class InfoType, class ProxyType>
struct std::iterator_traits<shadow::info_iterator_<InfoType, ProxyType>>
{
    typedef typename shadow::info_iterator_<InfoType, ProxyType>::value_type
        value_type;
    typedef
        typename shadow::info_iterator_<InfoType, ProxyType>::difference_type
            difference_type;
    typedef typename shadow::info_iterator_<InfoType, ProxyType>::reference
        reference;
    typedef
        typename shadow::info_iterator_<InfoType, ProxyType>::pointer pointer;
    typedef
        typename shadow::info_iterator_<InfoType, ProxyType>::iterator_category
            iterator_category;
};
}
<commit_msg>Add member_variable_info_by_index_ member variable. 	modified:   include/reflection_manager.hpp<commit_after>#pragma once

#include <utility>
#include <vector>
#include <algorithm>

#include "reflection_info.hpp"

namespace shadow
{
////////////////////////////////////////////////////////////////////////////////
// user facing API types carrying information and functionality for the
// reflection system

class reflection_manager;

// holds one value with type/reflection information
class variable
{
private:
    // holds type erased value
    any value_;
    // these identify the type erased value
    const reflection_manager* manager_;
    std::size_t type_index_;
};

template <class InfoType, template <class> class... Policies>
class api_type_aggregator
    : public Policies<api_type_aggregator<InfoType, Policies...>>...
{
public:
    api_type_aggregator() : info_(nullptr), manager_(nullptr)
    {
    }

    api_type_aggregator(const InfoType* info, const reflection_manager* manager)
        : info_(info), manager_(manager)
    {
    }

    api_type_aggregator* operator->()
    {
        return this;
    }

    const api_type_aggregator* operator->() const
    {
        return this;
    }

public:
    const InfoType* info_;
    const reflection_manager* manager_;
};

template <class Derived>
class get_name_policy
{
public:
    std::string
    name() const
    {
        return (static_cast<const Derived*>(this))->info_->name;
    }
};

template <class Derived>
class get_size_policy
{
public:
    std::size_t
    size() const
    {
        return static_cast<const Derived*>(this)->info_->size;
    }
};

typedef api_type_aggregator<type_info, get_name_policy, get_size_policy> type_;

template <class Derived>
class get_type_policy
{
public:
    type_
    get_type() const
    {
        // retrieve type index
        const auto type_index =
            static_cast<const Derived*>(this)->info_->type_index;

        return static_cast<const Derived*>(this)->manager_->type_by_index(
            type_index);
    }
};

typedef api_type_aggregator<constructor_info, get_type_policy> constructor_;

template <class InfoType, class ProxyType>
class info_iterator_
{
public:
    typedef ProxyType value_type;
    typedef typename std::iterator_traits<const InfoType*>::difference_type
        difference_type;
    typedef ProxyType reference;
    typedef ProxyType pointer;
    typedef typename std::iterator_traits<const InfoType*>::iterator_category
        iterator_category;

public:
    info_iterator_() = default;

    info_iterator_(const InfoType* current, const reflection_manager* manager)
        : current_(current), manager_(manager)
    {
    }

public:
    ProxyType operator*() const
    {
        return ProxyType(current_, manager_);
    }

    ProxyType operator->() const
    {
        return ProxyType(current_, manager_);
    }

    ProxyType operator[](difference_type n) const
    {
        return ProxyType(current_ + n, manager_);
    }

    info_iterator_& operator++()
    {
        ++current_;
        return *this;
    }

    info_iterator_ operator++(int)
    {
        auto temp = *this;
        ++(*this);
        return temp;
    }

    info_iterator_& operator--()
    {
        --current_;
        return *this;
    }

    info_iterator_ operator--(int)
    {
        auto temp = *this;
        --(*this);
        return temp;
    }

    info_iterator_&
    operator+=(difference_type n)
    {
        current_ += n;
        return *this;
    }

    info_iterator_&
    operator-=(difference_type n)
    {
        current_ -= n;
        return *this;
    }

    info_iterator_
    operator+(difference_type n) const
    {
        return info_iterator_(current_ + n, manager_);
    }

    info_iterator_
    operator-(difference_type n) const
    {
        return info_iterator_(current_ - n, manager_);
    }

    difference_type
    operator-(const info_iterator_& other)
    {
        return current_ - other.current_;
    }

    friend info_iterator_
    operator+(difference_type lhs, const info_iterator_& rhs)
    {
        return rhs + lhs;
    }

    bool
    operator==(const info_iterator_& other) const
    {
        return current_ == other.current_;
    }

    bool
    operator!=(const info_iterator_& other) const
    {
        return current_ != other.current_;
    }

    bool
    operator<(const info_iterator_& other) const
    {
        return current_ < other.current_;
    }

    bool
    operator>(const info_iterator_& other) const
    {
        return current_ > other.current_;
    }

    bool
    operator<=(const info_iterator_& other) const
    {
        return current_ <= other.current_;
    }

    bool
    operator>=(const info_iterator_& other) const
    {
        return current_ >= other.current_;
    }

private:
    InfoType* current_;
    const reflection_manager* manager_;
};

class reflection_manager
{
public:
    template <class Derived>
    friend class get_type_policy;

    typedef type_ type;
    typedef info_iterator_<const type_info, const type> const_type_iterator;

    typedef constructor_ constructor;
    typedef info_iterator_<const constructor_info, const constructor>
        const_constructor_iterator;

public:
    reflection_manager() = default;

    template <class TypeInfoArrayHolder,
              class ConstructorInfoArrayHolder,
              class ConversionInfoArrayHolder,
              class StringSerializationInfoArrayHolder,
              class FreeFunctionInfoArrayHolder,
              class MemberFunctionInfoArrayHolder,
              class MemberVariableInfoArrayHolder>
    reflection_manager(TypeInfoArrayHolder,
                       ConstructorInfoArrayHolder,
                       ConversionInfoArrayHolder,
                       StringSerializationInfoArrayHolder,
                       FreeFunctionInfoArrayHolder,
                       MemberFunctionInfoArrayHolder,
                       MemberVariableInfoArrayHolder)
        : type_info_range_(initialize_range(TypeInfoArrayHolder())),
          constructor_info_range_(
              initialize_range(ConstructorInfoArrayHolder())),
          conversion_info_range_(initialize_range(ConversionInfoArrayHolder())),
          string_serialization_info_range_(
              initialize_range(StringSerializationInfoArrayHolder())),
          free_function_info_range_(
              initialize_range(FreeFunctionInfoArrayHolder())),
          member_function_info_range_(
              initialize_range(MemberFunctionInfoArrayHolder())),
          member_variable_info_range_(
              initialize_range(MemberVariableInfoArrayHolder())),
          constructor_info_by_index_(buckets_by_index(
              constructor_info_range_,
              TypeInfoArrayHolder(),
              [](const auto& info) { return info.type_index; })),
          conversion_info_by_index_(buckets_by_index(
              conversion_info_range_,
              TypeInfoArrayHolder(),
              [](const auto& info) { return info.from_type_index; })),
          member_function_info_by_index_(buckets_by_index(
              member_function_info_range_,
              TypeInfoArrayHolder(),
              [](const auto& info) { return info.object_type_index; })),
          member_variable_info_by_index_(buckets_by_index(
              member_variable_info_range_,
              TypeInfoArrayHolder(),
              [](const auto& info) { return info.object_type_index; }))
    {
    }

private:
// clang complains here due to the comparison of decayed array and
// nullptr, since in the case ArrayHolderType::value was an array, this
// would always evaluate to true. The fact is that
// ArrayHolderType::value may be a pointer to nullptr for some cases of
// ArrayHolderType.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
    template <class ArrayHolderType>
    std::pair<const typename ArrayHolderType::type*,
              const typename ArrayHolderType::type*>
        initialize_range(ArrayHolderType)
    {
        if(ArrayHolderType::value != nullptr)
        {
            return std::make_pair(std::begin(ArrayHolderType::value),
                                  std::end(ArrayHolderType::value));
        }
        else
        {
            std::pair<const typename ArrayHolderType::type*,
                      const typename ArrayHolderType::type*>
                out(nullptr, nullptr);

            return out;
        }
    }

    template <class ArrayHolderType>
    std::size_t array_size(ArrayHolderType)
    {
        if(ArrayHolderType::value == nullptr)
        {
            return 0;
        }
        else
        {
            return std::extent<decltype(ArrayHolderType::value)>::value;
        }
    }

    template <class ValueType, class TypeInfoArrayHolder, class Fun>
    std::vector<std::vector<ValueType>>
    buckets_by_index(const std::pair<const ValueType*, const ValueType*>& range,
                     TypeInfoArrayHolder,
                     Fun index_extractor)
    {
        if(range.first != nullptr && range.second != nullptr)
        {
            std::vector<std::vector<ValueType>> out(
                array_size(TypeInfoArrayHolder()));

            std::for_each(range.first,
                          range.second,
                          [&out, index_extractor](const auto& info) {
                              out[index_extractor(info)].push_back(info);
                          });

            return out;
        }
        else
        {
            return std::vector<std::vector<ValueType>>();
        }
    }

#pragma clang diagnostic pop

    type
    type_by_index(std::size_t index) const
    {
        return type(type_info_range_.first + index, this);
    }

public:
    ////////////////////////////////////////////////////////////////////////////
    // main api interface for interacting with the reflection system
    std::pair<const_type_iterator, const_type_iterator>
    types() const
    {
        return std::make_pair(
            const_type_iterator(type_info_range_.first, this),
            const_type_iterator(type_info_range_.second, this));
    }

    std::pair<const_constructor_iterator, const_constructor_iterator>
    constructors() const
    {
        return std::make_pair(
            const_constructor_iterator(constructor_info_range_.first, this),
            const_constructor_iterator(constructor_info_range_.second, this));
    }

private:
    // pairs hold iterators to beginning and end of arrays of information
    // generated at compile time
    std::pair<const type_info*, const type_info*> type_info_range_;
    std::pair<const constructor_info*, const constructor_info*>
        constructor_info_range_;
    std::pair<const conversion_info*, const conversion_info*>
        conversion_info_range_;
    std::pair<const string_serialization_info*,
              const string_serialization_info*>
        string_serialization_info_range_;
    std::pair<const free_function_info*, const free_function_info*>
        free_function_info_range_;
    std::pair<const member_function_info*, const member_function_info*>
        member_function_info_range_;
    std::pair<const member_variable_info*, const member_variable_info*>
        member_variable_info_range_;

    // sorted information
    std::vector<std::vector<constructor_info>> constructor_info_by_index_;
    std::vector<std::vector<conversion_info>> conversion_info_by_index_;
    std::vector<std::vector<member_function_info>>
        member_function_info_by_index_;
    std::vector<std::vector<member_variable_info>>
        member_variable_info_by_index_;
};
}

namespace std
{
// specialize std::iterator_traits for info_iterator_

template <class InfoType, class ProxyType>
struct std::iterator_traits<shadow::info_iterator_<InfoType, ProxyType>>
{
    typedef typename shadow::info_iterator_<InfoType, ProxyType>::value_type
        value_type;
    typedef
        typename shadow::info_iterator_<InfoType, ProxyType>::difference_type
            difference_type;
    typedef typename shadow::info_iterator_<InfoType, ProxyType>::reference
        reference;
    typedef
        typename shadow::info_iterator_<InfoType, ProxyType>::pointer pointer;
    typedef
        typename shadow::info_iterator_<InfoType, ProxyType>::iterator_category
            iterator_category;
};
}
<|endoftext|>


<commit_before>// The Art of C++ / Utility
// Copyright (c) 2016-2018 Daniel Frey

#ifndef TAOCPP_INCLUDE_UTILITY_PRINTF_HPP
#define TAOCPP_INCLUDE_UTILITY_PRINTF_HPP

#include <string>

namespace tao
{
   namespace utility
   {
#ifdef WIN32
      std::string printf( const char* format, ... );
      std::string vprintf( const char* format, va_list ap );
#else
      std::string printf( const char* format, ... ) __attribute__( ( format( printf, 1, 2 ) ) );
      std::string vprintf( const char* format, va_list ap ) __attribute__( ( format( printf, 1, 0 ) ) );
#endif
   }
}

#endif  // TAOCPP_INCLUDE_UTILITY_PRINTF_HPP
<commit_msg>Add missing include<commit_after>// The Art of C++ / Utility
// Copyright (c) 2016-2018 Daniel Frey

#ifndef TAOCPP_INCLUDE_UTILITY_PRINTF_HPP
#define TAOCPP_INCLUDE_UTILITY_PRINTF_HPP

#include <cstdarg>
#include <string>

namespace tao
{
   namespace utility
   {
#ifdef WIN32
      std::string printf( const char* format, ... );
      std::string vprintf( const char* format, va_list ap );
#else
      std::string printf( const char* format, ... ) __attribute__( ( format( printf, 1, 2 ) ) );
      std::string vprintf( const char* format, va_list ap ) __attribute__( ( format( printf, 1, 0 ) ) );
#endif
   }
}

#endif  // TAOCPP_INCLUDE_UTILITY_PRINTF_HPP
<|endoftext|>


<commit_before>#ifndef TELNETPP_GENERATOR_HPP_
#define TELNETPP_GENERATOR_HPP_

#include "telnetpp/detail/generate_helper.hpp"
#include <algorithm>
#include <iterator>
#include <type_traits>
#include <utility>

namespace telnetpp {

//* =========================================================================
/// \brief Parse a series of Telnet tokens into a stream of bytes.
/// \param begin an iterator to the start of the series.
/// \param end an iterator to one past the end of the series.
//* =========================================================================
template <class InputIterator1, class InputIterator2>
auto generate(InputIterator1 begin, InputIterator2 end)
{
    static_assert(std::is_same<
        typename std::iterator_traits<InputIterator1>::value_type,
        telnetpp::token
    >::value, "Must pass a range of tokens into telnetpp::generate");
    static_assert(std::is_same<
        typename std::iterator_traits<InputIterator2>::value_type,
        telnetpp::token
    >::value, "Must pass a range of tokens into telnetpp::generate");

    typedef boost::variant<std::vector<u8>, boost::any> result;
    std::vector<result> results;

    std::vector<u8> stream;

    std::for_each(begin, end, [&results, &stream](auto &&token)
    {
        printf("\nerror token type is %s", token.type().name());
        if (token.type() == typeid(element))
        {
            detail::generate_helper(
                stream,
                boost::get<element>(token));
        }
        else
        {
            if (!stream.empty())
            {
                results.push_back(result(stream));
                stream.clear();
            }

            results.push_back(result(boost::get<boost::any>(token)));
        }
    });

    if (!stream.empty())
    {
        results.push_back(result(stream));
    }

    return results;
}

//* =========================================================================
/// \brief Parse a collection of Telnet tokens into a stream of bytes.
/// \param collection the collection containing the tokens.
//* =========================================================================
template <class Collection>
auto generate(Collection &&collection)
{
    using std::begin;
    using std::end;

    return generate(begin(collection), end(collection));
}

}

#endif
<commit_msg>Removed debug code.<commit_after>#ifndef TELNETPP_GENERATOR_HPP_
#define TELNETPP_GENERATOR_HPP_

#include "telnetpp/detail/generate_helper.hpp"
#include <algorithm>
#include <iterator>
#include <utility>

namespace telnetpp {

//* =========================================================================
/// \brief Parse a series of Telnet tokens into a stream of bytes.
/// \param begin an iterator to the start of the series.
/// \param end an iterator to one past the end of the series.
//* =========================================================================
template <class InputIterator1, class InputIterator2>
auto generate(InputIterator1 begin, InputIterator2 end)
{
    typedef boost::variant<std::vector<u8>, boost::any> result;
    std::vector<result> results;
    std::vector<u8> stream;

    std::for_each(begin, end, [&results, &stream](auto &&token)
    {
        if (token.type() == typeid(element))
        {
            detail::generate_helper(
                stream,
                boost::get<element>(token));
        }
        else
        {
            if (!stream.empty())
            {
                results.push_back(result(stream));
                stream.clear();
            }

            results.push_back(result(boost::get<boost::any>(token)));
        }
    });

    if (!stream.empty())
    {
        results.push_back(result(stream));
    }

    return results;
}

//* =========================================================================
/// \brief Parse a collection of Telnet tokens into a stream of bytes.
/// \param collection the collection containing the tokens.
//* =========================================================================
template <class Collection>
auto generate(Collection &&collection)
{
    using std::begin;
    using std::end;

    return generate(begin(collection), end(collection));
}

}

#endif
<|endoftext|>