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

#ifndef MAPNIK_JSON_GEOJSON_GRAMMAR_X3_DEF_HPP
#define MAPNIK_JSON_GEOJSON_GRAMMAR_X3_DEF_HPP

#include <mapnik/json/geojson_grammar_x3.hpp>
#include <mapnik/json/unicode_string_grammar_x3.hpp>
#include <mapnik/json/positions_grammar_x3.hpp>
#include <boost/fusion/include/std_pair.hpp>

namespace mapnik { namespace json { namespace grammar {

namespace x3 = boost::spirit::x3;

auto make_null = [] (auto const& ctx)
{
    _val(ctx) = mapnik::value_null{};
};

auto make_true = [] (auto const& ctx)
{
    _val(ctx) = true;
};

auto make_false = [] (auto const& ctx)
{
    _val(ctx) = false;
};

auto assign = [](auto const& ctx)
{
    _val(ctx) = std::move(_attr(ctx));
};

auto assign_key = [](auto const& ctx)
{
    std::string const& name = _attr(ctx);
    keys_map & keys = x3::get<keys_tag>(ctx);
    auto result = keys.insert(std::make_pair(name, keys.size()));
    std::get<0>(_val(ctx)) = result.first->second;
};

auto assign_value = [](auto const& ctx)
{
    std::get<1>(_val(ctx)) = std::move(_attr(ctx));
};

using x3::lit;
using x3::string;
using x3::omit;

struct geometry_type_ : x3::symbols<mapnik::geometry::geometry_types>
{
    geometry_type_()
    {
        add
            ("\"Feature\"",mapnik::geometry::geometry_types(0xff)) // this is a temp hack FIXME
            ("\"Point\"", mapnik::geometry::geometry_types::Point)
            ("\"LineString\"", mapnik::geometry::geometry_types::LineString)
            ("\"Polygon\"", mapnik::geometry::geometry_types::Polygon)
            ("\"MultiPoint\"", mapnik::geometry::geometry_types::MultiPoint)
            ("\"MultiLineString\"", mapnik::geometry::geometry_types::MultiLineString )
            ("\"MultiPolygon\"",mapnik::geometry::geometry_types::MultiPolygon)
            ("\"GeometryCollection\"",mapnik::geometry::geometry_types::GeometryCollection)
            ;
    }
} geometry_type_sym;

// exported rules
// start
geojson_grammar_type const value("JSON Value");
key_value_type const key_value("JSON key/value");
// rules
x3::rule<class json_object_tag, geojson_object> object("JSON Object");
x3::rule<class json_array_tag, geojson_array> array("JSON Array");
x3::rule<class json_number_tag, geojson_value> number("JSON Number");
//x3::rule<class key_value_tag, geojson_object_element> key_value("JSON key/value");
// GeoJSON
x3::rule<class geojson_coordinates_tag, geojson_object_element> coordinates("GeoJSON Coordinates");
x3::rule<class geojson_geometry_type_tag, geojson_object_element> geometry_type("GeoJSON Geometry Type");
x3::rule<class geojson_key_value_type_tag, geojson_object_element> geojson_key_value("GeoJSON Key/Value Type");
auto const geojson_double = x3::real_parser<value_double, x3::strict_real_policies<value_double>>();
auto const geojson_integer = x3::int_parser<value_integer, 10, 1, -1>();

// import unicode string rule
namespace { auto const& geojson_string = mapnik::json::unicode_string_grammar(); }
// import positions rule
namespace { auto const& positions_rule = mapnik::json::positions_grammar(); }

// GeoJSON types
auto const value_def =  object | array | geojson_string | number
    ;

auto const coordinates_def = string("\"coordinates\"")[assign_key] > lit(':') > (positions_rule[assign_value] | value[assign_value])
    ;

auto const geometry_type_def = string("\"type\"")[assign_key] > lit(':') > (geometry_type_sym[assign_value] | value[assign_value])
    ;

auto const key_value_def = geojson_string[assign_key] > lit(':') > value[assign_value]
    ;

auto const geojson_key_value_def =
    geometry_type
    |
    coordinates
    |
    key_value
    ;

auto const object_def = lit('{')
    > -(geojson_key_value % lit(','))
    > lit('}')
    ;

auto const array_def = lit('[')
    > -(value % lit(','))
    > lit(']')
    ;

auto const number_def = geojson_double[assign]
    | geojson_integer[assign]
    | lit("true") [make_true]
    | lit ("false") [make_false]
    | lit("null")[make_null]
    ;

#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>

BOOST_SPIRIT_DEFINE(
    value,
    geometry_type,
    coordinates,
    object,
    key_value,
    geojson_key_value,
    array,
    number
    );

#pragma GCC diagnostic pop

}}}

namespace mapnik { namespace json {

grammar::geojson_grammar_type const& geojson_grammar()
{
    return grammar::value;
}

grammar::key_value_type const& key_value_grammar()
{
    return grammar::key_value;
}

}}

#endif // MAPNIK_JSON_GEOJSON_GRAMMAR_X3_DEF_HPP
<commit_msg>parse well-known-names as un-quoted strings<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2016 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_JSON_GEOJSON_GRAMMAR_X3_DEF_HPP
#define MAPNIK_JSON_GEOJSON_GRAMMAR_X3_DEF_HPP

#include <mapnik/json/geojson_grammar_x3.hpp>
#include <mapnik/json/unicode_string_grammar_x3.hpp>
#include <mapnik/json/positions_grammar_x3.hpp>
#include <boost/fusion/include/std_pair.hpp>

namespace mapnik { namespace json { namespace grammar {

namespace x3 = boost::spirit::x3;

auto make_null = [] (auto const& ctx)
{
    _val(ctx) = mapnik::value_null{};
};

auto make_true = [] (auto const& ctx)
{
    _val(ctx) = true;
};

auto make_false = [] (auto const& ctx)
{
    _val(ctx) = false;
};

auto assign = [](auto const& ctx)
{
    _val(ctx) = std::move(_attr(ctx));
};

auto assign_key = [](auto const& ctx)
{
    std::string const& name = _attr(ctx);
    keys_map & keys = x3::get<keys_tag>(ctx);
    auto result = keys.insert(std::make_pair(name, keys.size()));
    std::get<0>(_val(ctx)) = result.first->second;
};

auto assign_value = [](auto const& ctx)
{
    std::get<1>(_val(ctx)) = std::move(_attr(ctx));
};

using x3::lit;
using x3::string;
using x3::lexeme;

struct geometry_type_ : x3::symbols<mapnik::geometry::geometry_types>
{
    geometry_type_()
    {
        add
            ("\"Feature\"",mapnik::geometry::geometry_types(0xff)) // this is a temp hack FIXME
            ("\"Point\"", mapnik::geometry::geometry_types::Point)
            ("\"LineString\"", mapnik::geometry::geometry_types::LineString)
            ("\"Polygon\"", mapnik::geometry::geometry_types::Polygon)
            ("\"MultiPoint\"", mapnik::geometry::geometry_types::MultiPoint)
            ("\"MultiLineString\"", mapnik::geometry::geometry_types::MultiLineString )
            ("\"MultiPolygon\"",mapnik::geometry::geometry_types::MultiPolygon)
            ("\"GeometryCollection\"",mapnik::geometry::geometry_types::GeometryCollection)
            ;
    }
} geometry_type_sym;

// exported rules
// start
geojson_grammar_type const value("JSON Value");
key_value_type const key_value("JSON key/value");
// rules
x3::rule<class json_object_tag, geojson_object> object("JSON Object");
x3::rule<class json_array_tag, geojson_array> array("JSON Array");
x3::rule<class json_number_tag, geojson_value> number("JSON Number");
//x3::rule<class key_value_tag, geojson_object_element> key_value("JSON key/value");
// GeoJSON
x3::rule<class geojson_coordinates_tag, geojson_object_element> coordinates("GeoJSON Coordinates");
x3::rule<class geojson_geometry_type_tag, geojson_object_element> geometry_type("GeoJSON Geometry Type");
x3::rule<class geojson_key_value_type_tag, geojson_object_element> geojson_key_value("GeoJSON Key/Value Type");
auto const geojson_double = x3::real_parser<value_double, x3::strict_real_policies<value_double>>();
auto const geojson_integer = x3::int_parser<value_integer, 10, 1, -1>();

// import unicode string rule
namespace { auto const& geojson_string = mapnik::json::unicode_string_grammar(); }
// import positions rule
namespace { auto const& positions_rule = mapnik::json::positions_grammar(); }

// GeoJSON types
auto const value_def =  object | array | geojson_string | number
    ;

auto const coordinates_def = lexeme[lit('"') >> (string("coordinates") > lit('"'))][assign_key]
    > lit(':') > (positions_rule[assign_value] | value[assign_value])
    ;

auto const geometry_type_def = lexeme[lit('"') >> (string("type") > lit('"'))][assign_key]
    > lit(':') > (geometry_type_sym[assign_value] | value[assign_value])
    ;

auto const key_value_def = geojson_string[assign_key] > lit(':') > value[assign_value]
    ;

auto const geojson_key_value_def =
    geometry_type
    |
    coordinates
    |
    key_value
    ;

auto const object_def = lit('{')
    > -(geojson_key_value % lit(','))
    > lit('}')
    ;

auto const array_def = lit('[')
    > -(value % lit(','))
    > lit(']')
    ;

auto const number_def = geojson_double[assign]
    | geojson_integer[assign]
    | lit("true") [make_true]
    | lit ("false") [make_false]
    | lit("null")[make_null]
    ;

#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>

BOOST_SPIRIT_DEFINE(
    value,
    geometry_type,
    coordinates,
    object,
    key_value,
    geojson_key_value,
    array,
    number
    );

#pragma GCC diagnostic pop

}}}

namespace mapnik { namespace json {

grammar::geojson_grammar_type const& geojson_grammar()
{
    return grammar::value;
}

grammar::key_value_type const& key_value_grammar()
{
    return grammar::key_value;
}

}}

#endif // MAPNIK_JSON_GEOJSON_GRAMMAR_X3_DEF_HPP
<|endoftext|>


<commit_before>/**
 \file
 Implementation file for RawParticleIterator class
 \author Troy Porter
 \version $Id$
 \date 22 May 2003
 */

#include <corsika/RawParticleIterator.h>
#include <corsika/RawStream.h>
#include <corsika/CorsikaIOException.h>
#include <sstream>

namespace corsika
{

    template <class Thinning>
    RawParticleIterator<Thinning>::
    RawParticleIterator() :
    fStartPosition(0),
    fCurrentBlockIndex(0),
    fParticleInBlock(0),
    fCurrentBlock(),
    fIteratorValid(false),
    fBlockBufferValid(false)
    { }

    template <class Thinning>
    RawParticleIterator<Thinning>::
    RawParticleIterator(boost::shared_ptr<VRawStream> rawStream, size_t startPosition) :
    fRawStream(rawStream),
    fStartPosition(startPosition),
    fCurrentBlockIndex(0),
    fParticleInBlock(0),
    fCurrentBlock(),
    fIteratorValid(false),
    fBlockBufferValid(false)
    {
        Rewind();
    }

    template <class Thinning> bool RawParticleIterator<Thinning>::operator==(const RawParticleIterator& other) const
    {
        if (!fRawStream || !other.fRawStream || !fIteratorValid || !other.fIteratorValid) {
            return fIteratorValid == other.fIteratorValid;
        }

        bool ret =
        fStartPosition    == other.fStartPosition &&
        fCurrentBlockIndex  == other.fCurrentBlockIndex &&
        fParticleInBlock  == other.fParticleInBlock &&
        fBlockBufferValid == other.fBlockBufferValid;

        return ret;
    }

    template <class Thinning> void RawParticleIterator<Thinning>::Rewind()
    {
        fCurrentBlockIndex = fStartPosition;
        fParticleInBlock = 0;
        fBlockBufferValid = false;
        fIteratorValid = true;
        if (!fRawStream->IsSeekable())
            throw CorsikaIOException("Can not rewind RawParticleIterator because stream is not seekable");
        fRawStream->SeekTo(fCurrentBlockIndex);
    }

    template <class Thinning> const typename Block<Thinning>::ParticleData* RawParticleIterator<Thinning>::GetOneParticle()
    {
        if (!fIteratorValid)
            throw CorsikaIOException("RawParticleIterator not valid.");

        if (!fBlockBufferValid)
        {
            if (!fRawStream->GetNextBlock(fCurrentBlock))
            {
                std::ostringstream msg;
                msg << "Error reading block " << fCurrentBlockIndex << " in CORSIKA file.";
                throw CorsikaIOException(msg.str());
            }
            if (fCurrentBlock.IsControl() || fCurrentBlock.IsLongitudinal()) { // end of particle records
                fIteratorValid = false;
                return 0;
            }
            fBlockBufferValid = true;
        }

        const typename Block<Thinning>::ParticleData * currentRecord =
        fCurrentBlock.AsParticleBlock().fParticle + fParticleInBlock;
        ++fParticleInBlock;

        if (fParticleInBlock >= Block<Thinning>::kParticlesInBlock)
        {
            ++fCurrentBlockIndex;
            fParticleInBlock = 0;
            fBlockBufferValid = false;
        }
        return currentRecord;
    }

    template class RawParticleIterator<Thinned>;
    template class RawParticleIterator<NotThinned>;

    boost::shared_ptr<VRawParticleIterator> VRawParticleIterator::Create(RawStreamPtr stream, size_t start)
    {
        if (stream->IsThinned()) return boost::shared_ptr<VRawParticleIterator>(new RawParticleIterator<Thinned>(stream, start));
        return boost::shared_ptr<VRawParticleIterator>(new RawParticleIterator<NotThinned>(stream, start));
    }
}
<commit_msg>Skip first block<commit_after>/**
 \file
 Implementation file for RawParticleIterator class
 \author Troy Porter
 \version $Id$
 \date 22 May 2003
 */

#include <corsika/RawParticleIterator.h>
#include <corsika/RawStream.h>
#include <corsika/CorsikaIOException.h>
#include <sstream>

namespace corsika
{

    template <class Thinning>
    RawParticleIterator<Thinning>::
    RawParticleIterator() :
    fStartPosition(0),
    fCurrentBlockIndex(0),
    fParticleInBlock(0),
    fCurrentBlock(),
    fIteratorValid(false),
    fBlockBufferValid(false)
    { }

    template <class Thinning>
    RawParticleIterator<Thinning>::
    RawParticleIterator(boost::shared_ptr<VRawStream> rawStream, size_t startPosition) :
    fRawStream(rawStream),
    fStartPosition(startPosition),
    fCurrentBlockIndex(0),
    fParticleInBlock(0),
    fCurrentBlock(),
    fIteratorValid(false),
    fBlockBufferValid(false)
    {
        // if there is something we KNOW, it is that particles are not in block zero.
        if (fStartPosition == 0) fStartPosition = rawStream->GetNextPosition();
        Rewind();
    }

    template <class Thinning> bool RawParticleIterator<Thinning>::operator==(const RawParticleIterator& other) const
    {
        if (!fRawStream || !other.fRawStream || !fIteratorValid || !other.fIteratorValid) {
            return fIteratorValid == other.fIteratorValid;
        }

        bool ret =
        fStartPosition    == other.fStartPosition &&
        fCurrentBlockIndex  == other.fCurrentBlockIndex &&
        fParticleInBlock  == other.fParticleInBlock &&
        fBlockBufferValid == other.fBlockBufferValid;

        return ret;
    }

    template <class Thinning> void RawParticleIterator<Thinning>::Rewind()
    {
        fCurrentBlockIndex = fStartPosition;
        fParticleInBlock = 0;
        fBlockBufferValid = false;
        fIteratorValid = true;
        if (!fRawStream->IsSeekable())
            throw CorsikaIOException("Can not rewind RawParticleIterator because stream is not seekable");
        fRawStream->SeekTo(fCurrentBlockIndex);
    }

    template <class Thinning> const typename Block<Thinning>::ParticleData* RawParticleIterator<Thinning>::GetOneParticle()
    {
        if (!fIteratorValid)
            throw CorsikaIOException("RawParticleIterator not valid.");

        if (!fBlockBufferValid)
        {
            if (!fRawStream->GetNextBlock(fCurrentBlock))
            {
                std::ostringstream msg;
                msg << "Error reading block " << fCurrentBlockIndex << " in CORSIKA file.";
                throw CorsikaIOException(msg.str());
            }
            if (fCurrentBlock.IsControl() || fCurrentBlock.IsLongitudinal()) { // end of particle records
                fIteratorValid = false;
                return 0;
            }
            fBlockBufferValid = true;
        }

        const typename Block<Thinning>::ParticleData * currentRecord =
        fCurrentBlock.AsParticleBlock().fParticle + fParticleInBlock;
        ++fParticleInBlock;

        if (fParticleInBlock >= Block<Thinning>::kParticlesInBlock)
        {
            ++fCurrentBlockIndex;
            fParticleInBlock = 0;
            fBlockBufferValid = false;
        }
        return currentRecord;
    }

    template class RawParticleIterator<Thinned>;
    template class RawParticleIterator<NotThinned>;

    boost::shared_ptr<VRawParticleIterator> VRawParticleIterator::Create(RawStreamPtr stream, size_t start)
    {
        if (stream->IsThinned()) return boost::shared_ptr<VRawParticleIterator>(new RawParticleIterator<Thinned>(stream, start));
        return boost::shared_ptr<VRawParticleIterator>(new RawParticleIterator<NotThinned>(stream, start));
    }
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) Yorik van Havre (yorik@uncreated.net) 2014              *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_

#endif
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <Base/Vector3D.h>
#include <Base/Rotation.h>
#include <Base/Writer.h>
#include <Base/Reader.h>
#include <Base/Exception.h>
#include "Command.h"

using namespace Base;
using namespace Path;

TYPESYSTEM_SOURCE(Path::Command , Base::Persistence);

// Constructors & destructors

Command::Command(const char* name,
                 const std::map<std::string, double>& parameters)
:Name(name),Parameters(parameters)
{
}

Command::Command()
{
}

Command::~Command()
{
}

// New methods

Placement Command::getPlacement (void)
{
    std::string x = "X";
    std::string y = "Y";
    std::string z = "Z";
    std::string a = "A";
    std::string b = "B";
    std::string c = "C";
    double xval = 0.0;
    double yval = 0.0;
    double zval = 0.0;
    double aval = 0.0;
    double bval = 0.0;
    double cval = 0.0;
    if (Parameters.count(x))
        xval = Parameters[x];
    if (Parameters.count(y))
        yval = Parameters[y];
    if (Parameters.count(z))
        zval = Parameters[z];
    if (Parameters.count(a))
        aval = Parameters[a];
    if (Parameters.count(b))
        bval = Parameters[b];
    if (Parameters.count(c))
        cval = Parameters[c];
    Vector3d vec(xval,yval,zval);
    Rotation rot;
    rot.setYawPitchRoll(aval,bval,cval);
    Placement plac(vec,rot);
    return plac;
}

Vector3d Command::getCenter (void)
{
    std::string i = "I";
    std::string j = "J";
    std::string k = "K";
    double ival = 0.0;
    double jval = 0.0;
    double kval = 0.0;
    if (Parameters.count(i))
        ival = Parameters[i];
    if (Parameters.count(j))
        jval = Parameters[j];
    if (Parameters.count(k))
        kval = Parameters[k];
    Vector3d vec(ival,jval,kval);
    return vec;
}

double Command::getValue(const std::string& attr)
{
    std::string a(attr);
    boost::to_upper(a);
    double val = 0.0;
    if (Parameters.count(a))
        val = Parameters[a];
    return val;
}

bool Command::has(const std::string& attr)
{
    std::string a(attr);
    boost::to_upper(a);
    return Parameters.count(a) > 0;
}

std::string Command::toGCode (void) const
{
    std::stringstream str;
    str.precision(5);
    str << Name;
    char v[60];
    for(std::map<std::string,double>::const_iterator i = Parameters.begin(); i != Parameters.end(); ++i) {
        std::string k = i->first;
        //std::string v = std::to_string(i->second);  // only 6 digits
        snprintf(v, sizeof(v), "%.9f", i->second);
        v[sizeof(v)-1] = '\0';
        str << " " << k << v;
    }
    return str.str();
}

void Command::setFromGCode (const std::string& str)
{
    Parameters.clear();
    std::string mode = "none";
    std::string key;
    std::string value;
    for (unsigned int i=0; i < str.size(); i++) {
        if ( (isdigit(str[i])) || (str[i] == '-') || (str[i] == '.') ) {
            value += str[i];
        } else if (isalpha(str[i])) {
            if (mode == "command") {
                if (!key.empty() && !value.empty()) {
                    std::string cmd = key + value;
                    boost::to_upper(cmd);
                    Name = cmd;
                    key = "";
                    value = "";
                    mode = "argument";
                } else {
                    throw Base::Exception("Badly formatted GCode command");
                }
                mode = "argument";
            } else if (mode == "none") {
                mode = "command";
            } else if (mode == "argument") {
                if (!key.empty() && !value.empty()) {
                    double val = std::atof(value.c_str());
                    boost::to_upper(key);
                    Parameters[key] = val;
                    key = "";
                    value = "";
                } else {
                    throw Base::Exception("Badly formatted GCode argument");
                }
            } else if (mode == "comment") {
                value += str[i];
            }
            key = str[i];
        } else if (str[i] == '(') {
            mode = "comment";
        } else if (str[i] == ')') {
            key = "(";
            value += ")";
        } else {
            // add non-ascii characters only if this is a comment
            if (mode == "comment") {
                value += str[i];
            }
        }
    }
    if (!key.empty() && !value.empty()) {
        if ( (mode == "command") || (mode == "comment") ) {
            std::string cmd = key + value;
            if (mode == "command")
                boost::to_upper(cmd);
            Name = cmd;
        } else {
            double val = std::atof(value.c_str());
            boost::to_upper(key);
            Parameters[key] = val;
        }
    } else {
        throw Base::Exception("Badly formatted GCode argument");
    }
}

void Command::setFromPlacement (const Base::Placement &plac)
{
    Name = "G1";
    Parameters.clear();
    std::string x = "X";
    std::string y = "Y";
    std::string z = "Z";
    std::string a = "A";
    std::string b = "B";
    std::string c = "C";
    double xval, yval, zval, aval, bval, cval;
    xval = plac.getPosition().x;
    yval = plac.getPosition().y;
    zval = plac.getPosition().z;
    plac.getRotation().getYawPitchRoll(aval,bval,cval);
    if (xval != 0.0)
        Parameters[x] = xval;
    if (yval != 0.0)
        Parameters[y] = yval;
    if (zval != 0.0)
        Parameters[z] = zval;
    if (aval != 0.0)
        Parameters[a] = aval;
    if (bval != 0.0)
        Parameters[b] = bval;
    if (cval != 0.0)
        Parameters[c] = cval;
}

void Command::setCenter(const Base::Vector3d &pos, bool clockwise)
{
    if (clockwise) {
        Name = "G2";
    } else {
        Name = "G3";
    }
    std::string i = "I";
    std::string j = "J";
    std::string k = "K";
    double ival, jval, kval;
    ival = pos.x;
    jval = pos.y;
    kval = pos.z;
    Parameters[i] = ival;
    Parameters[j] = jval;
    Parameters[k] = kval;
}

Command Command::transform(const Base::Placement other)
{
    Base::Placement plac = getPlacement();
    plac *= other;
    double xval, yval, zval, aval, bval, cval;
    xval = plac.getPosition().x;
    yval = plac.getPosition().y;
    zval = plac.getPosition().z;
    plac.getRotation().getYawPitchRoll(aval,bval,cval);
    Command c = Command();
    c.Name = Name;
    for(std::map<std::string,double>::const_iterator i = Parameters.begin(); i != Parameters.end(); ++i) {
        std::string k = i->first;
        double v = i->second;
        if (k == "X")
            v = xval;
        if (k == "Y")
            v = yval;
        if (k == "Z")
            v = zval;
        if (k == "A")
            v = aval;
        if (k == "B")
            v = bval;
        if (k == "C")
            v = cval;
        c.Parameters[k] = v;
    }
    return c;
}

// Reimplemented from base class

unsigned int Command::getMemSize (void) const
{
    return toGCode().size();
}

void Command::Save (Writer &writer) const
{
    // this will only get used if saved as XML (probably never)
    writer.Stream() << writer.ind() << "<Command "
                    << "gcode=\"" << toGCode() << "\" />";
    writer.Stream()<< std::endl;
}

void Command::Restore(XMLReader &reader)
{
    reader.readElement("Command");
    std::string gcode = reader.getAttribute("gcode");
    setFromGCode(gcode);
}

<commit_msg>Added missing include directive.<commit_after>/***************************************************************************
 *   Copyright (c) Yorik van Havre (yorik@uncreated.net) 2014              *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_

#endif
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <Base/Vector3D.h>
#include <Base/Rotation.h>
#include <Base/Writer.h>
#include <Base/Reader.h>
#include <Base/Exception.h>
#include "Command.h"
#include <stdio.h>

using namespace Base;
using namespace Path;

TYPESYSTEM_SOURCE(Path::Command , Base::Persistence);

// Constructors & destructors

Command::Command(const char* name,
                 const std::map<std::string, double>& parameters)
:Name(name),Parameters(parameters)
{
}

Command::Command()
{
}

Command::~Command()
{
}

// New methods

Placement Command::getPlacement (void)
{
    std::string x = "X";
    std::string y = "Y";
    std::string z = "Z";
    std::string a = "A";
    std::string b = "B";
    std::string c = "C";
    double xval = 0.0;
    double yval = 0.0;
    double zval = 0.0;
    double aval = 0.0;
    double bval = 0.0;
    double cval = 0.0;
    if (Parameters.count(x))
        xval = Parameters[x];
    if (Parameters.count(y))
        yval = Parameters[y];
    if (Parameters.count(z))
        zval = Parameters[z];
    if (Parameters.count(a))
        aval = Parameters[a];
    if (Parameters.count(b))
        bval = Parameters[b];
    if (Parameters.count(c))
        cval = Parameters[c];
    Vector3d vec(xval,yval,zval);
    Rotation rot;
    rot.setYawPitchRoll(aval,bval,cval);
    Placement plac(vec,rot);
    return plac;
}

Vector3d Command::getCenter (void)
{
    std::string i = "I";
    std::string j = "J";
    std::string k = "K";
    double ival = 0.0;
    double jval = 0.0;
    double kval = 0.0;
    if (Parameters.count(i))
        ival = Parameters[i];
    if (Parameters.count(j))
        jval = Parameters[j];
    if (Parameters.count(k))
        kval = Parameters[k];
    Vector3d vec(ival,jval,kval);
    return vec;
}

double Command::getValue(const std::string& attr)
{
    std::string a(attr);
    boost::to_upper(a);
    double val = 0.0;
    if (Parameters.count(a))
        val = Parameters[a];
    return val;
}

bool Command::has(const std::string& attr)
{
    std::string a(attr);
    boost::to_upper(a);
    return Parameters.count(a) > 0;
}

std::string Command::toGCode (void) const
{
    std::stringstream str;
    str.precision(5);
    str << Name;
    char v[60];
    for(std::map<std::string,double>::const_iterator i = Parameters.begin(); i != Parameters.end(); ++i) {
        std::string k = i->first;
        //std::string v = std::to_string(i->second);  // only 6 digits
        snprintf(v, sizeof(v), "%.9f", i->second);
        v[sizeof(v)-1] = '\0';
        str << " " << k << v;
    }
    return str.str();
}

void Command::setFromGCode (const std::string& str)
{
    Parameters.clear();
    std::string mode = "none";
    std::string key;
    std::string value;
    for (unsigned int i=0; i < str.size(); i++) {
        if ( (isdigit(str[i])) || (str[i] == '-') || (str[i] == '.') ) {
            value += str[i];
        } else if (isalpha(str[i])) {
            if (mode == "command") {
                if (!key.empty() && !value.empty()) {
                    std::string cmd = key + value;
                    boost::to_upper(cmd);
                    Name = cmd;
                    key = "";
                    value = "";
                    mode = "argument";
                } else {
                    throw Base::Exception("Badly formatted GCode command");
                }
                mode = "argument";
            } else if (mode == "none") {
                mode = "command";
            } else if (mode == "argument") {
                if (!key.empty() && !value.empty()) {
                    double val = std::atof(value.c_str());
                    boost::to_upper(key);
                    Parameters[key] = val;
                    key = "";
                    value = "";
                } else {
                    throw Base::Exception("Badly formatted GCode argument");
                }
            } else if (mode == "comment") {
                value += str[i];
            }
            key = str[i];
        } else if (str[i] == '(') {
            mode = "comment";
        } else if (str[i] == ')') {
            key = "(";
            value += ")";
        } else {
            // add non-ascii characters only if this is a comment
            if (mode == "comment") {
                value += str[i];
            }
        }
    }
    if (!key.empty() && !value.empty()) {
        if ( (mode == "command") || (mode == "comment") ) {
            std::string cmd = key + value;
            if (mode == "command")
                boost::to_upper(cmd);
            Name = cmd;
        } else {
            double val = std::atof(value.c_str());
            boost::to_upper(key);
            Parameters[key] = val;
        }
    } else {
        throw Base::Exception("Badly formatted GCode argument");
    }
}

void Command::setFromPlacement (const Base::Placement &plac)
{
    Name = "G1";
    Parameters.clear();
    std::string x = "X";
    std::string y = "Y";
    std::string z = "Z";
    std::string a = "A";
    std::string b = "B";
    std::string c = "C";
    double xval, yval, zval, aval, bval, cval;
    xval = plac.getPosition().x;
    yval = plac.getPosition().y;
    zval = plac.getPosition().z;
    plac.getRotation().getYawPitchRoll(aval,bval,cval);
    if (xval != 0.0)
        Parameters[x] = xval;
    if (yval != 0.0)
        Parameters[y] = yval;
    if (zval != 0.0)
        Parameters[z] = zval;
    if (aval != 0.0)
        Parameters[a] = aval;
    if (bval != 0.0)
        Parameters[b] = bval;
    if (cval != 0.0)
        Parameters[c] = cval;
}

void Command::setCenter(const Base::Vector3d &pos, bool clockwise)
{
    if (clockwise) {
        Name = "G2";
    } else {
        Name = "G3";
    }
    std::string i = "I";
    std::string j = "J";
    std::string k = "K";
    double ival, jval, kval;
    ival = pos.x;
    jval = pos.y;
    kval = pos.z;
    Parameters[i] = ival;
    Parameters[j] = jval;
    Parameters[k] = kval;
}

Command Command::transform(const Base::Placement other)
{
    Base::Placement plac = getPlacement();
    plac *= other;
    double xval, yval, zval, aval, bval, cval;
    xval = plac.getPosition().x;
    yval = plac.getPosition().y;
    zval = plac.getPosition().z;
    plac.getRotation().getYawPitchRoll(aval,bval,cval);
    Command c = Command();
    c.Name = Name;
    for(std::map<std::string,double>::const_iterator i = Parameters.begin(); i != Parameters.end(); ++i) {
        std::string k = i->first;
        double v = i->second;
        if (k == "X")
            v = xval;
        if (k == "Y")
            v = yval;
        if (k == "Z")
            v = zval;
        if (k == "A")
            v = aval;
        if (k == "B")
            v = bval;
        if (k == "C")
            v = cval;
        c.Parameters[k] = v;
    }
    return c;
}

// Reimplemented from base class

unsigned int Command::getMemSize (void) const
{
    return toGCode().size();
}

void Command::Save (Writer &writer) const
{
    // this will only get used if saved as XML (probably never)
    writer.Stream() << writer.ind() << "<Command "
                    << "gcode=\"" << toGCode() << "\" />";
    writer.Stream()<< std::endl;
}

void Command::Restore(XMLReader &reader)
{
    reader.readElement("Command");
    std::string gcode = reader.getAttribute("gcode");
    setFromGCode(gcode);
}

<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include "PDBSetup.h"
#include "MolSetup.h"
#include "BondAdjacencyList.h"
#include "ConfigSetup.h"
#include "FFSetup.h"        //For geometry kinds
#include "FFConst.h"
#include "Reader.h"
#include "InputFileReader.h"
#include "Simulation.h"
#include<unistd.h>
/* There are 4 cases for restarting from checkpoint

1) Base Case:
    The first run.
    Checkpoint Setup  - RestartFromCheckpoint = false
    Checkpoint Output - RestartFromCheckpoint = false

2) The first restart from checkpoint
    Checkpoint Setup  - RestartFromCheckpoint = true
    Checkpoint Output - RestartFromCheckpoint = true

3) The Nth restart from checkpoint from a prev checkpoint
    Checkpoint Setup  - RestartFromCheckpoint = true
    Checkpoint Output - RestartFromCheckpoint = true

*/
TEST(ConsistentTrajectoryTest, CheckPDBTrajCoordinates) {
    chdir("./test/input/ConsistentTrajectory/Base/");
    Simulation base("in.conf");
    base.RunSimulation();
    chdir("../K_1");
    Simulation K_1("in.conf");
    K_1.RunSimulation();
    chdir("../K_N");
    Simulation K_N("in.conf");
    K_N.RunSimulation();
    chdir("../../../..");

    config_setup::RestartSettings rsStart;
    config_setup::RestartSettings rsBase;
    config_setup::RestartSettings rs1;
    config_setup::RestartSettings rsN;

    std::string pdbnamesSTART[2], pdbnamesBase[2], pdbnames1[2], pdbnamesN[2];
    std::string pdbnamesBaseRestart[2], pdbnames1Restart[2], pdbnamesNRestart[2];

    pdbnamesSTART[0] = "./test/input/ConsistentTrajectory/Base/START_BOX_0.pdb";
    pdbnamesSTART[1] = "./test/input/ConsistentTrajectory/Base/START_BOX_1.pdb";

    pdbnamesBase[0] = "./test/input/ConsistentTrajectory/Base/base_BOX_0.pdb";
    pdbnamesBase[1] = "./test/input/ConsistentTrajectory/Base/base_BOX_1.pdb";

    pdbnames1[0] = "./test/input/ConsistentTrajectory/K_1/K_1_BOX_0.pdb";
    pdbnames1[1] = "./test/input/ConsistentTrajectory/K_1/K_1_BOX_1.pdb";

    pdbnamesN[0] = "./test/input/ConsistentTrajectory/K_N/K_N_BOX_0.pdb";
    pdbnamesN[1] = "./test/input/ConsistentTrajectory/K_N/K_N_BOX_1.pdb";

    pdbnamesBaseRestart[0] = "./test/input/ConsistentTrajectory/Base/base_BOX_0_restart.pdb";
    pdbnamesBaseRestart[1] = "./test/input/ConsistentTrajectory/Base/base_BOX_1_restart.pdb";

    pdbnames1Restart[0] = "./test/input/ConsistentTrajectory/K_1/K_1_BOX_0_restart.pdb";
    pdbnames1Restart[1] = "./test/input/ConsistentTrajectory/K_1/K_1_BOX_1_restart.pdb";

    pdbnamesNRestart[0] = "./test/input/ConsistentTrajectory/K_N/K_N_BOX_0_restart.pdb";
    pdbnamesNRestart[1] = "./test/input/ConsistentTrajectory/K_N/K_N_BOX_1_restart.pdb";

    PDBSetup pdbStart, pdbBase, pdb1, pdbN;
    PDBSetup pdbBaseRestart, pdb1Restart, pdbNRestart;

    rsStart.recalcTrajectory = false;
    rsBase.recalcTrajectory = true;
    rs1.recalcTrajectory = true;
    rsN.recalcTrajectory = true;

    // This is needed to get passed Remark
    uint frameNum = 1;
    pdbStart.Init(rsStart, pdbnamesSTART);
    pdbBase.Init(rsBase, pdbnamesBase, frameNum);
    pdb1.Init(rs1, pdbnames1, frameNum);
    pdbN.Init(rsN, pdbnamesN, frameNum);

    frameNum = 11;
    pdbBase.Init(rsBase, pdbnamesBase, frameNum);
    pdb1.Init(rs1, pdbnames1, frameNum);
    pdbN.Init(rsN, pdbnamesN, frameNum);

    config_setup::RestartSettings rsBaseRestart;
    config_setup::RestartSettings rs1Restart;
    config_setup::RestartSettings rsNRestart;

    rsBaseRestart.restartFromCheckpoint = true;
    rs1Restart.restartFromCheckpoint = true;
    rsNRestart.restartFromCheckpoint = true;

    pdbBaseRestart.Init(rsBaseRestart, pdbnamesBaseRestart);
    pdb1Restart.Init(rs1Restart, pdbnames1Restart);
    pdbNRestart.Init(rsNRestart, pdbnamesNRestart);

    for (uint i = 0; i < pdbBase.atoms.count; ++i){
        /* Find mol i's chain index in restart output files */
        ptrdiff_t pos = find(pdbBaseRestart.atoms.chainLetter.begin(),
            pdbBaseRestart.atoms.chainLetter.end(), pdbBase.atoms.chainLetter[i])
            - pdbBaseRestart.atoms.chainLetter.begin();
        if(pdbBase.atoms.x[i] != pdbBaseRestart.atoms.x[pos])
            std::cout << pdbBase.atoms.x[i] << " " << i << " " << pdbBaseRestart.atoms.x[pos] << " " << pos <<  std::endl;
        EXPECT_EQ(pdbBase.atoms.x[i] == pdbBaseRestart.atoms.x[pos], true);
    }

    for (uint i = 0; i < pdb1.atoms.count; ++i){
        /* Find mol i's chain index in restart output files */
        ptrdiff_t pos = find(pdb1Restart.atoms.chainLetter.begin(),
            pdb1Restart.atoms.chainLetter.end(), pdb1.atoms.chainLetter[i])
            - pdb1Restart.atoms.chainLetter.begin();
        if(pdb1.atoms.x[i] != pdb1Restart.atoms.x[pos])
            std::cout << pdbBase.atoms.x[i] << " " << i << " " << pdb1Restart.atoms.x[pos] << " " << pos <<  std::endl;
        EXPECT_EQ(pdb1.atoms.x[i] == pdb1Restart.atoms.x[pos], true);
    }

    for (uint i = 0; i < pdbN.atoms.count; ++i){
        /* Find mol i's chain index in restart output files */
        ptrdiff_t pos = find(pdbNRestart.atoms.chainLetter.begin(),
            pdbNRestart.atoms.chainLetter.end(), pdbN.atoms.chainLetter[i])
            - pdbNRestart.atoms.chainLetter.begin();
        if(pdbN.atoms.x[i] != pdbNRestart.atoms.x[pos])
            std::cout << pdbN.atoms.x[i] << " " << i << " " << pdbNRestart.atoms.x[pos] << " " << pos <<  std::endl;
        EXPECT_EQ(pdbN.atoms.x[i] == pdbNRestart.atoms.x[pos], true);
    }
}<commit_msg>Check last frame equals first frame of next cycle<commit_after>#include <gtest/gtest.h>
#include "PDBSetup.h"
#include "MolSetup.h"
#include "BondAdjacencyList.h"
#include "ConfigSetup.h"
#include "FFSetup.h"        //For geometry kinds
#include "FFConst.h"
#include "Reader.h"
#include "InputFileReader.h"
#include "Simulation.h"
#include<unistd.h>
/* There are 4 cases for restarting from checkpoint

1) Base Case:
    The first run.
    Checkpoint Setup  - RestartFromCheckpoint = false
    Checkpoint Output - RestartFromCheckpoint = false

2) The first restart from checkpoint
    Checkpoint Setup  - RestartFromCheckpoint = true
    Checkpoint Output - RestartFromCheckpoint = true

3) The Nth restart from checkpoint from a prev checkpoint
    Checkpoint Setup  - RestartFromCheckpoint = true
    Checkpoint Output - RestartFromCheckpoint = true

*/
TEST(ConsistentTrajectoryTest, CheckPDBTrajCoordinates) {
    chdir("./test/input/ConsistentTrajectory/Base/");
    Simulation base("in.conf");
    base.RunSimulation();
    chdir("../K_1");
    Simulation K_1("in.conf");
    K_1.RunSimulation();
    chdir("../K_N");
    Simulation K_N("in.conf");
    K_N.RunSimulation();
    chdir("../../../..");

    config_setup::RestartSettings rsStart;
    config_setup::RestartSettings rsBase;
    config_setup::RestartSettings rs1;
    config_setup::RestartSettings rsN;

    std::string pdbnamesSTART[2], pdbnamesBase[2], pdbnames1[2], pdbnamesN[2];
    std::string pdbnamesBaseRestart[2], pdbnames1Restart[2], pdbnamesNRestart[2];

    pdbnamesSTART[0] = "./test/input/ConsistentTrajectory/Base/START_BOX_0.pdb";
    pdbnamesSTART[1] = "./test/input/ConsistentTrajectory/Base/START_BOX_1.pdb";

    pdbnamesBase[0] = "./test/input/ConsistentTrajectory/Base/base_BOX_0.pdb";
    pdbnamesBase[1] = "./test/input/ConsistentTrajectory/Base/base_BOX_1.pdb";

    pdbnames1[0] = "./test/input/ConsistentTrajectory/K_1/K_1_BOX_0.pdb";
    pdbnames1[1] = "./test/input/ConsistentTrajectory/K_1/K_1_BOX_1.pdb";

    pdbnamesN[0] = "./test/input/ConsistentTrajectory/K_N/K_N_BOX_0.pdb";
    pdbnamesN[1] = "./test/input/ConsistentTrajectory/K_N/K_N_BOX_1.pdb";

    pdbnamesBaseRestart[0] = "./test/input/ConsistentTrajectory/Base/base_BOX_0_restart.pdb";
    pdbnamesBaseRestart[1] = "./test/input/ConsistentTrajectory/Base/base_BOX_1_restart.pdb";

    pdbnames1Restart[0] = "./test/input/ConsistentTrajectory/K_1/K_1_BOX_0_restart.pdb";
    pdbnames1Restart[1] = "./test/input/ConsistentTrajectory/K_1/K_1_BOX_1_restart.pdb";

    pdbnamesNRestart[0] = "./test/input/ConsistentTrajectory/K_N/K_N_BOX_0_restart.pdb";
    pdbnamesNRestart[1] = "./test/input/ConsistentTrajectory/K_N/K_N_BOX_1_restart.pdb";

    PDBSetup pdbStart, pdbBase, pdb1, pdbN;
    PDBSetup pdbBaseRestart, pdb1Restart, pdbNRestart;

    rsStart.recalcTrajectory = false;
    rsBase.recalcTrajectory = true;
    rs1.recalcTrajectory = true;
    rsN.recalcTrajectory = true;

    // This is needed to get passed Remark
    uint frameNum = 1;
    pdbStart.Init(rsStart, pdbnamesSTART);
    pdbBase.Init(rsBase, pdbnamesBase, frameNum);
    pdb1.Init(rs1, pdbnames1, frameNum);
    pdbN.Init(rsN, pdbnamesN, frameNum);

    frameNum = 11;
    pdbBase.Init(rsBase, pdbnamesBase, frameNum);
    pdb1.Init(rs1, pdbnames1, frameNum);
    pdbN.Init(rsN, pdbnamesN, frameNum);

    config_setup::RestartSettings rsBaseRestart;
    config_setup::RestartSettings rs1Restart;
    config_setup::RestartSettings rsNRestart;

    rsBaseRestart.restartFromCheckpoint = true;
    rs1Restart.restartFromCheckpoint = true;
    rsNRestart.restartFromCheckpoint = true;

    pdbBaseRestart.Init(rsBaseRestart, pdbnamesBaseRestart);
    pdb1Restart.Init(rs1Restart, pdbnames1Restart);
    pdbNRestart.Init(rsNRestart, pdbnamesNRestart);

    // Checks if the coordinates of the traj match the restart file
    for (uint i = 0; i < pdbBase.atoms.count; ++i){
        /* Find mol i's chain index in restart output files */
        ptrdiff_t pos = find(pdbBaseRestart.atoms.chainLetter.begin(),
            pdbBaseRestart.atoms.chainLetter.end(), pdbBase.atoms.chainLetter[i])
            - pdbBaseRestart.atoms.chainLetter.begin();
        if(pdbBase.atoms.x[i] != pdbBaseRestart.atoms.x[pos])
            std::cout << pdbBase.atoms.x[i] << " " << i << " " << pdbBaseRestart.atoms.x[pos] << " " << pos <<  std::endl;
        EXPECT_EQ(pdbBase.atoms.x[i] == pdbBaseRestart.atoms.x[pos], true);
    }

    // Checks if the coordinates of the traj match the restart file
    for (uint i = 0; i < pdb1.atoms.count; ++i){
        /* Find mol i's chain index in restart output files */
        ptrdiff_t pos = find(pdb1Restart.atoms.chainLetter.begin(),
            pdb1Restart.atoms.chainLetter.end(), pdb1.atoms.chainLetter[i])
            - pdb1Restart.atoms.chainLetter.begin();
        if(pdb1.atoms.x[i] != pdb1Restart.atoms.x[pos])
            std::cout << pdbBase.atoms.x[i] << " " << i << " " << pdb1Restart.atoms.x[pos] << " " << pos <<  std::endl;
        EXPECT_EQ(pdb1.atoms.x[i] == pdb1Restart.atoms.x[pos], true);
    }

    // Checks if the coordinates of the traj match the restart file
    for (uint i = 0; i < pdbN.atoms.count; ++i){
        /* Find mol i's chain index in restart output files */
        ptrdiff_t pos = find(pdbNRestart.atoms.chainLetter.begin(),
            pdbNRestart.atoms.chainLetter.end(), pdbN.atoms.chainLetter[i])
            - pdbNRestart.atoms.chainLetter.begin();
        if(pdbN.atoms.x[i] != pdbNRestart.atoms.x[pos])
            std::cout << pdbN.atoms.x[i] << " " << i << " " << pdbNRestart.atoms.x[pos] << " " << pos <<  std::endl;
        EXPECT_EQ(pdbN.atoms.x[i] == pdbNRestart.atoms.x[pos], true);
    }

    int firstFrame = 1;
    int lastFrame = 11;
    pdbBase.Init(rsBase, pdbnamesBase, lastFrame);
    pdb1.Init(rs1, pdbnames1, firstFrame);

    // Checks if the last frame the base traj match the first frame of K_1 traj
    for (uint i = 0; i < pdbBase.atoms.count; ++i){
        /* Find mol i's chain index in restart output files */
        ptrdiff_t pos1 = find(pdb1.atoms.chainLetter.begin(),
            pdb1.atoms.chainLetter.end(), pdbBase.atoms.chainLetter[i])
            - pdb1.atoms.chainLetter.begin();
         ptrdiff_t pos2 = find(pdbBase.atoms.chainLetter.begin(),
            pdbBase.atoms.chainLetter.end(), pdb1.atoms.chainLetter[i])
            - pdbBase.atoms.chainLetter.begin();
        if(pdbBase.atoms.x[i] != pdb1.atoms.x[pos1])
            std::cout << pdbBase.atoms.x[i] << " " << i << " " << pdbBaseRestart.atoms.x[pos1] << " " << pos1 <<  std::endl;
        EXPECT_EQ(pdbBase.atoms.x[i] == pdb1.atoms.x[pos1], true);
        EXPECT_EQ(pdb1.atoms.x[i] == pdbBase.atoms.x[pos2], true);
        EXPECT_EQ(pos1 == pos2, true);

    }
}<|endoftext|>


<commit_before>/*
Copyright (c) 2014, Scott Zuyderduyn
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.

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

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/

//----------------------------------------------------------------------------
// cube.hpp
// An STL-like structure that resides in video memory.
//
// Author: Scott D. Zuyderduyn, Ph.D. (scott.zuyderduyn@utoronto.ca)
//----------------------------------------------------------------------------
#pragma once
#ifndef ECUDA_CUBE_HPP
#define ECUDA_CUBE_HPP

#include <limits>
#include <vector>
#include <estd/cube.hpp>
#include "global.hpp"
#include "containers.hpp"
//#include "iterators.hpp"
#include "matrix.hpp"
#include "memory.hpp"

namespace ecuda {

template<typename T>
class cube {

public:
	typedef T value_type;
	typedef T* pointer;
	typedef const T* const_pointer;
	typedef T& reference;
	typedef const T& const_reference;
	typedef std::ptrdiff_t difference_type;
	typedef std::size_t size_type;

	typedef ecuda::OffsettingContainer< cube<T> > xy_type;
	typedef ecuda::OffsettingContainer< cube<T> > xz_type;
	typedef ecuda::OffsettingContainer< cube<T> > yz_type;
	typedef const ecuda::OffsettingContainer< const cube<T>, size_type, const_pointer > const_xy_type;
	typedef const ecuda::OffsettingContainer< const cube<T>, size_type, const_pointer > const_xz_type;
	typedef const ecuda::OffsettingContainer< const cube<T>, size_type, const_pointer > const_yz_type;

	typedef ecuda::CubeSliceContainer< cube<T>, size_type, pointer > matrix_type;
	typedef const ecuda::CubeSliceContainer< const cube<T>, size_type, const_pointer > const_matrix_type;

private:
	// REMEMBER: numberRows, numberColumns, numberDepths and pitch altered on device memory won't be
	//           reflected on the host object. Don't allow the device to perform any operations that
	//           change their value.
	size_type numberRows;
	size_type numberColumns;
	size_type numberDepths;
	size_type pitch;
	device_ptr<T> deviceMemory;
	//unique_ptr< matrix<T>[] > matrices;

public:
	HOST cube( const size_type numberRows=0, const size_type numberColumns=0, const size_type numberDepths=0, const T& value = T() ) : numberRows(numberRows), numberColumns(numberColumns), numberDepths(numberDepths) {
		if( numberRows and numberColumns and numberDepths ) {
			CUDA_CALL( cudaMallocPitch( deviceMemory.alloc_ptr(), &pitch, numberColumns*numberDepths*sizeof(T), numberRows ) );
			std::vector<T> v( numberColumns*numberDepths, value );
			for( size_t i = 0; i < numberRows; ++i )
				CUDA_CALL( cudaMemcpy2D( deviceMemory.get()+(i*pitch/sizeof(T)), numberColumns*numberDepths*sizeof(T), &v[0], numberColumns*numberDepths*sizeof(T), numberColumns*numberDepths*sizeof(T), 1, cudaMemcpyHostToDevice ) );
		}
	}
	HOST DEVICE cube( const cube<T>& src ) : numberRows(src.numberRows), numberColumns(src.numberColumns), numberDepths(src.numberDepths), pitch(src.pitch), deviceMemory(src.deviceMemory) {}
	template<typename U,typename V,typename W>
	HOST cube( const estd::cube<T,U,V,W>& src ) : numberRows(src.row_size()), numberColumns(src.column_size()), numberDepths(src.depth_size()) {
		if( numberRows and numberColumns and numberDepths ) {
			CUDA_CALL( cudaMallocPitch( deviceMemory.alloc_ptr(), &pitch, numberColumns*numberDepths*sizeof(T), numberRows ) );
			for( size_t i = 0; i < numberRows; ++i ) {
				std::vector<T> v; v.reserve( numberColumns*numberDepths );
				for( size_t j = 0; j < numberColumns; ++j )
					for( size_t k = 0; k < numberDepths; ++k )
						v.push_back( src[i][j][k] );
				CUDA_CALL( cudaMemcpy2D( deviceMemory.get()+(i*pitch/sizeof(T)), numberColumns*numberDepths*sizeof(T), &v[0], numberColumns*numberDepths*sizeof(T), numberColumns*numberDepths*sizeof(T), 1, cudaMemcpyHostToDevice ) );
			}
		}
	}

	// capacity:
	HOST DEVICE inline size_type row_size() const __NOEXCEPT__ { return numberRows; }
	HOST DEVICE inline size_type column_size() const __NOEXCEPT__ { return numberColumns; }
	HOST DEVICE inline size_type depth_size() const __NOEXCEPT__ { return numberDepths; }
	HOST DEVICE inline size_type get_pitch() const { return pitch; }
	HOST DEVICE inline size_type size() const __NOEXCEPT__ { return row_size()*column_size()*depth_size(); }
	HOST DEVICE inline bool empty() const __NOEXCEPT__ { return !size(); }

	// element access:
	DEVICE inline reference at( const size_type rowIndex, const size_type columnIndex, const size_type depthIndex ) { return *(deviceMemory.get()+(rowIndex*pitch/sizeof(T)+columnIndex*numberDepths+depthIndex)); }
	DEVICE inline reference at( const size_type index ) { return at( index/(numberColumns*numberDepths), (index % (numberColumns*numberDepths))/numberDepths, (index % (numberColumns*numberDepths)) % numberDepths ); }
	DEVICE inline const_reference at( const size_type rowIndex, const size_type columnIndex, const size_type depthIndex ) const { return *(deviceMemory.get()+(rowIndex*pitch/sizeof(T)+columnIndex*numberDepths+depthIndex)); }
	DEVICE inline const_reference at( const size_type index ) const { return at( index/(numberColumns*numberDepths), (index % (numberColumns*numberDepths))/numberDepths, (index % (numberColumns*numberDepths)) % numberDepths ); }
	HOST DEVICE inline pointer data() __NOEXCEPT__ { return deviceMemory.get(); }
	HOST DEVICE inline const_pointer data() const __NOEXCEPT__ { return deviceMemory.get(); }

	HOST DEVICE inline matrix_type get_row( const size_type rowIndex ) { return matrix_type( *this, rowIndex ); }
	HOST DEVICE inline const_matrix_type get_row( const size_type rowIndex ) const { return const_matrix_type( *this, rowIndex ); }
	HOST DEVICE inline matrix_type operator[]( const size_type rowIndex ) { return get_row(rowIndex); }
	HOST DEVICE inline const_matrix_type operator[]( const size_type rowIndex ) const { return get_row(rowIndex); }

	//xy_type get_xy( const RowIndexType x, const ColumnIndexType y ) { return contents[x].get_row(y); }
	//xz_type get_xz( const RowIndexType x, const DepthIndexType z ) { return contents[x].get_column(z); }
	//yz_type get_yz( const ColumnIndexType y, const DepthIndexType z ) {	return OffsettingContainer< cube<CellType,RowIndexType,ColumnIndexType,DepthIndexType> >( *this, row_size(), y*depth_size()+z, column_size()*depth_size() ); }
	//const_xy_type get_xy( const RowIndexType x, const ColumnIndexType y ) const { return contents[x].get_row(y); }
	//const_xz_type get_xz( const RowIndexType x, const DepthIndexType z ) const { return contents[x].get_column(z); }
	//const_yz_type get_yz( const ColumnIndexType y, const DepthIndexType z ) const { return OffsettingContainer< const cube<CellType,RowIndexType,ColumnIndexType,DepthIndexType> >( *this, row_size(), y*depth_size()+z, column_size()*depth_size() ); }

	template<typename U,typename V,typename W>
	HOST cube<T>& operator>>( estd::cube<T,U,V,W>& dest ) {
		//TODO: this needs to be re-implemented, it won't work as currently written
		dest.resize( static_cast<U>(numberRows), static_cast<V>(numberColumns), static_cast<W>(numberDepths) );
		for( size_type i = 0; i < numberRows; ++i ) operator[](i) >> dest[i];
		return *this;
	}

};

} // namespace ecuda

#endif

<commit_msg>fixed operator to copy device to host cube<commit_after>/*
Copyright (c) 2014, Scott Zuyderduyn
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.

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

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/

//----------------------------------------------------------------------------
// cube.hpp
// An STL-like structure that resides in video memory.
//
// Author: Scott D. Zuyderduyn, Ph.D. (scott.zuyderduyn@utoronto.ca)
//----------------------------------------------------------------------------
#pragma once
#ifndef ECUDA_CUBE_HPP
#define ECUDA_CUBE_HPP

#include <limits>
#include <vector>
#include <estd/cube.hpp>
#include "global.hpp"
#include "containers.hpp"
//#include "iterators.hpp"
#include "matrix.hpp"
#include "memory.hpp"

namespace ecuda {

template<typename T>
class cube {

public:
	typedef T value_type;
	typedef T* pointer;
	typedef const T* const_pointer;
	typedef T& reference;
	typedef const T& const_reference;
	typedef std::ptrdiff_t difference_type;
	typedef std::size_t size_type;

	typedef ecuda::OffsettingContainer< cube<T> > xy_type;
	typedef ecuda::OffsettingContainer< cube<T> > xz_type;
	typedef ecuda::OffsettingContainer< cube<T> > yz_type;
	typedef const ecuda::OffsettingContainer< const cube<T>, size_type, const_pointer > const_xy_type;
	typedef const ecuda::OffsettingContainer< const cube<T>, size_type, const_pointer > const_xz_type;
	typedef const ecuda::OffsettingContainer< const cube<T>, size_type, const_pointer > const_yz_type;

	typedef ecuda::CubeSliceContainer< cube<T>, size_type, pointer > matrix_type;
	typedef const ecuda::CubeSliceContainer< const cube<T>, size_type, const_pointer > const_matrix_type;

private:
	// REMEMBER: numberRows, numberColumns, numberDepths and pitch altered on device memory won't be
	//           reflected on the host object. Don't allow the device to perform any operations that
	//           change their value.
	size_type numberRows;
	size_type numberColumns;
	size_type numberDepths;
	size_type pitch;
	device_ptr<T> deviceMemory;
	//unique_ptr< matrix<T>[] > matrices;

public:
	HOST cube( const size_type numberRows=0, const size_type numberColumns=0, const size_type numberDepths=0, const T& value = T() ) : numberRows(numberRows), numberColumns(numberColumns), numberDepths(numberDepths) {
		if( numberRows and numberColumns and numberDepths ) {
			CUDA_CALL( cudaMallocPitch( deviceMemory.alloc_ptr(), &pitch, numberColumns*numberDepths*sizeof(T), numberRows ) );
			std::vector<T> v( numberColumns*numberDepths, value );
			for( size_t i = 0; i < numberRows; ++i )
				CUDA_CALL( cudaMemcpy2D( deviceMemory.get()+(i*pitch/sizeof(T)), numberColumns*numberDepths*sizeof(T), &v[0], numberColumns*numberDepths*sizeof(T), numberColumns*numberDepths*sizeof(T), 1, cudaMemcpyHostToDevice ) );
		}
	}
	HOST DEVICE cube( const cube<T>& src ) : numberRows(src.numberRows), numberColumns(src.numberColumns), numberDepths(src.numberDepths), pitch(src.pitch), deviceMemory(src.deviceMemory) {}
	template<typename U,typename V,typename W>
	HOST cube( const estd::cube<T,U,V,W>& src ) : numberRows(src.row_size()), numberColumns(src.column_size()), numberDepths(src.depth_size()) {
		if( numberRows and numberColumns and numberDepths ) {
			CUDA_CALL( cudaMallocPitch( deviceMemory.alloc_ptr(), &pitch, numberColumns*numberDepths*sizeof(T), numberRows ) );
			for( size_t i = 0; i < numberRows; ++i ) {
				std::vector<T> v; v.reserve( numberColumns*numberDepths );
				for( size_t j = 0; j < numberColumns; ++j )
					for( size_t k = 0; k < numberDepths; ++k )
						v.push_back( src[i][j][k] );
				CUDA_CALL( cudaMemcpy2D( deviceMemory.get()+(i*pitch/sizeof(T)), numberColumns*numberDepths*sizeof(T), &v[0], numberColumns*numberDepths*sizeof(T), numberColumns*numberDepths*sizeof(T), 1, cudaMemcpyHostToDevice ) );
			}
		}
	}

	// capacity:
	HOST DEVICE inline size_type row_size() const __NOEXCEPT__ { return numberRows; }
	HOST DEVICE inline size_type column_size() const __NOEXCEPT__ { return numberColumns; }
	HOST DEVICE inline size_type depth_size() const __NOEXCEPT__ { return numberDepths; }
	HOST DEVICE inline size_type get_pitch() const { return pitch; }
	HOST DEVICE inline size_type size() const __NOEXCEPT__ { return row_size()*column_size()*depth_size(); }
	HOST DEVICE inline bool empty() const __NOEXCEPT__ { return !size(); }

	// element access:
	DEVICE inline reference at( const size_type rowIndex, const size_type columnIndex, const size_type depthIndex ) { return *(deviceMemory.get()+(rowIndex*pitch/sizeof(T)+columnIndex*numberDepths+depthIndex)); }
	DEVICE inline reference at( const size_type index ) { return at( index/(numberColumns*numberDepths), (index % (numberColumns*numberDepths))/numberDepths, (index % (numberColumns*numberDepths)) % numberDepths ); }
	DEVICE inline const_reference at( const size_type rowIndex, const size_type columnIndex, const size_type depthIndex ) const { return *(deviceMemory.get()+(rowIndex*pitch/sizeof(T)+columnIndex*numberDepths+depthIndex)); }
	DEVICE inline const_reference at( const size_type index ) const { return at( index/(numberColumns*numberDepths), (index % (numberColumns*numberDepths))/numberDepths, (index % (numberColumns*numberDepths)) % numberDepths ); }
	HOST DEVICE inline pointer data() __NOEXCEPT__ { return deviceMemory.get(); }
	HOST DEVICE inline const_pointer data() const __NOEXCEPT__ { return deviceMemory.get(); }

	HOST DEVICE inline matrix_type get_row( const size_type rowIndex ) { return matrix_type( *this, rowIndex ); }
	HOST DEVICE inline const_matrix_type get_row( const size_type rowIndex ) const { return const_matrix_type( *this, rowIndex ); }
	HOST DEVICE inline matrix_type operator[]( const size_type rowIndex ) { return get_row(rowIndex); }
	HOST DEVICE inline const_matrix_type operator[]( const size_type rowIndex ) const { return get_row(rowIndex); }

	//xy_type get_xy( const RowIndexType x, const ColumnIndexType y ) { return contents[x].get_row(y); }
	//xz_type get_xz( const RowIndexType x, const DepthIndexType z ) { return contents[x].get_column(z); }
	//yz_type get_yz( const ColumnIndexType y, const DepthIndexType z ) {	return OffsettingContainer< cube<CellType,RowIndexType,ColumnIndexType,DepthIndexType> >( *this, row_size(), y*depth_size()+z, column_size()*depth_size() ); }
	//const_xy_type get_xy( const RowIndexType x, const ColumnIndexType y ) const { return contents[x].get_row(y); }
	//const_xz_type get_xz( const RowIndexType x, const DepthIndexType z ) const { return contents[x].get_column(z); }
	//const_yz_type get_yz( const ColumnIndexType y, const DepthIndexType z ) const { return OffsettingContainer< const cube<CellType,RowIndexType,ColumnIndexType,DepthIndexType> >( *this, row_size(), y*depth_size()+z, column_size()*depth_size() ); }

	template<typename U,typename V,typename W>
	HOST cube<T>& operator>>( estd::cube<T,U,V,W>& dest ) {
		//TODO: this needs to be re-implemented, it won't work as currently written
		dest.resize( static_cast<U>(numberRows), static_cast<V>(numberColumns), static_cast<W>(numberDepths) );
		CUDA_CALL( cudaMemcpy2D( &dest[0][0][0], numberColumns*numberDepths*sizeof(T), deviceMemory.get(), pitch, numberColumns*numberDepths*sizeof(T), numberRows, cudaMemcpyDeviceToHost ) );
		//for( size_type i = 0; i < numberRows; ++i ) operator[](i) >> dest[i];
		return *this;
	}

};

} // namespace ecuda

#endif

<|endoftext|>


<commit_before>#ifndef TABLE_PARAMETERS_GRAMMAR_HPP
#define TABLE_PARAMETERS_GRAMMAR_HPP

#include "engine/api/table_parameters.hpp"

#include "server/api/base_parameters_grammar.hpp"

#include <boost/spirit/include/qi_lit.hpp>
#include <boost/spirit/include/qi_uint.hpp>
#include <boost/spirit/include/qi_grammar.hpp>
#include <boost/spirit/include/qi_action.hpp>
#include <boost/spirit/include/qi_optional.hpp>

namespace osrm
{
namespace server
{
namespace api
{

namespace qi = boost::spirit::qi;

struct TableParametersGrammar final : public BaseParametersGrammar
{
    using Iterator = std::string::iterator;
    using SourcesT = std::vector<std::size_t>;
    using DestinationsT = std::vector<std::size_t>;

    TableParametersGrammar() : BaseParametersGrammar(root_rule, parameters)
    {
        const auto set_destiantions = [this](DestinationsT &dests)
        {
            parameters.destinations = std::move(dests);
        };
        const auto set_sources = [this](SourcesT &sources)
        {
            parameters.sources = std::move(sources);
        };
        destinations_rule = qi::lit("destinations=") >> -qi::uint_ % ";";
        sources_rule = qi::lit("sources=") >> -qi::uint_ % ";";
        table_rule = destinations_rule[set_destiantions] | sources_rule[set_sources];
        root_rule = -((base_rule | table_rule) % '&');
    }

    engine::api::TableParameters parameters;

  private:
    qi::rule<Iterator> root_rule, table_rule;
    qi::rule<Iterator, SourcesT()> sources_rule;
    qi::rule<Iterator, DestinationsT()> destinations_rule;
};
}
}
}

#endif
<commit_msg>Fix table parameter parsing<commit_after>#ifndef TABLE_PARAMETERS_GRAMMAR_HPP
#define TABLE_PARAMETERS_GRAMMAR_HPP

#include "engine/api/table_parameters.hpp"

#include "server/api/base_parameters_grammar.hpp"

#include <boost/spirit/include/qi_lit.hpp>
#include <boost/spirit/include/qi_uint.hpp>
#include <boost/spirit/include/qi_grammar.hpp>
#include <boost/spirit/include/qi_action.hpp>
#include <boost/spirit/include/qi_optional.hpp>

namespace osrm
{
namespace server
{
namespace api
{

namespace qi = boost::spirit::qi;

struct TableParametersGrammar final : public BaseParametersGrammar
{
    using Iterator = std::string::iterator;
    using SourcesT = std::vector<std::size_t>;
    using DestinationsT = std::vector<std::size_t>;

    TableParametersGrammar() : BaseParametersGrammar(root_rule, parameters)
    {
        const auto set_destiantions = [this](DestinationsT &dests)
        {
            parameters.destinations = std::move(dests);
        };
        const auto set_sources = [this](SourcesT &sources)
        {
            parameters.sources = std::move(sources);
        };
        destinations_rule = (qi::lit("destinations=") >> (qi::ulong_ % ";")[set_destiantions]) | qi::lit("destinations=all");
        sources_rule = (qi::lit("sources=") >> (qi::ulong_ % ";")[set_sources]) | qi::lit("sources=all");
        table_rule = destinations_rule | sources_rule;
        root_rule = -((base_rule | table_rule) % '&');
    }

    engine::api::TableParameters parameters;

  private:
    qi::rule<Iterator> root_rule, table_rule;
    qi::rule<Iterator> sources_rule;
    qi::rule<Iterator> destinations_rule;
};
}
}
}

#endif
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDataSet.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
// .NAME vtkDataSet - abstract class to specify dataset behavior
// .SECTION Description
// vtkDataSet is an abstract class that specifies an interface for
// data objects. (Data objects are synomous with datasets). vtkDataSet
// also provides methods to provide informations about the data such
// as center, bounding box, and representative length.

#ifndef __vtkDataSet_h
#define __vtkDataSet_h

#include "vtkObject.hh"
#include "vtkIdList.hh"
#include "vtkFloatPoints.hh"
#include "vtkPointData.hh"
#include "vtkCell.hh"

class vtkSource;

class vtkDataSet : public vtkObject
{
public:
  vtkDataSet();
  vtkDataSet(const vtkDataSet& ds);
  char *GetClassName() {return "vtkDataSet";};
  void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // Provides opportunity for data to clean itself up before execution.
  virtual void Update();

  // Description:
  // Create concrete instance of this dataset.
  virtual vtkDataSet *MakeObject() = 0;

  // Description:
  // Copy the geometric and topological structure of an object. Note that
  // the invoking object and the object pointed to by the parameter ds must
  // be of the same type.
  virtual void CopyStructure(vtkDataSet *ds) = 0;

  // Description:
  // Return class name of data type. This is one of vtkStructuredGrid,
  // vtkStructuredPoints, vtkUnstructuredGrid, vtkPolyData.
  virtual char *GetDataType() = 0;

  // Description:
  // Determine number of points composing dataset.
  virtual int GetNumberOfPoints() = 0;

  // Description:
  // Determine number of cells composing dataset.
  virtual int GetNumberOfCells() = 0;

  // Description:
  // Get point coordinates with ptId such that: 0 <= ptId < NumberOfPoints
  virtual float *GetPoint(int ptId) = 0;

  // Description:
  // Copy point coordinates into user provided array x[3] for specified
  // point id.
  virtual void GetPoint(int id, float x[3]);

  // Description:
  // Get cell with cellId such that: 0 <= cellId < NumberOfCells
  virtual vtkCell *GetCell(int cellId) = 0;

  // Description:
  // Get type of cell with cellId such that: 0 <= cellId < NumberOfCells
  virtual int GetCellType(int cellId) = 0;

  // Description:
  // Topological inquiry to get points defining cell.
  virtual void GetCellPoints(int cellId, vtkIdList& ptIds) = 0;

  // Description:
  // Topological inquiry to get cells using point.
  virtual void GetPointCells(int ptId, vtkIdList& cellIds) = 0;

  // Description:
  // Topological inquiry to get all cells using list of points exclusive of
  // cell specified (e.g., cellId)
  virtual void GetCellNeighbors(int cellId, vtkIdList& ptIds, vtkIdList& cellIds);

  // Description:
  // Locate cell based on global coordinate x and tolerance squared. If
  // cell is non-NULL, then search starts from this cell and looks at
  // immediate neighbors. Returns cellId >= 0 if inside, < 0 otherwise.
  // The parametric coordinates are provided in pcoords[3]. The interpolation
  // weights are returned in weights[]. Tolerance is used to control how close
  // the point is to be considered "in" the cell.
  virtual int FindCell(float x[3], vtkCell *cell, float tol2, int& subId, float pcoords[3], float weights[VTK_MAX_CELL_SIZE]) = 0;

  // Datasets are composite objects and need to check each part for MTime
  unsigned long int GetMTime();

  // Description:
  // Release data back to system to conserve memory resource. Used during
  // visualization network execution.
  void ReleaseData();

  // Description:
  // Return flag indicating whether data should be released after use
  // by a filter.
  int ShouldIReleaseData();

  // Description:
  // Set/Get the DataReleased ivar.
  vtkSetMacro(DataReleased,int);
  vtkGetMacro(DataReleased,int);

  // Description:
  // Turn on/off flag to control whether this object's data is released
  // after being used by a filter.
  vtkSetMacro(ReleaseDataFlag,int);
  vtkGetMacro(ReleaseDataFlag,int);
  vtkBooleanMacro(ReleaseDataFlag,int);

  // Description:
  // Turn on/off flag to control whether every object releases its data
  // after being used by a filter.
  vtkSetMacro(GlobalReleaseDataFlag,int);
  vtkGetMacro(GlobalReleaseDataFlag,int);
  vtkBooleanMacro(GlobalReleaseDataFlag,int);

  // return pointer to this dataset's point data
  vtkPointData *GetPointData() {return &this->PointData;};

  // Description:
  // Reclaim any extra memory used to store data.
  virtual void Squeeze();

  // Description:
  // Set the owner of this data object for Sources.
  vtkSetObjectMacro(Source,vtkSource);

  // compute geometric bounds, center, longest side
  virtual void ComputeBounds();
  float *GetBounds();
  void GetBounds(float bounds[6]);
  float *GetCenter();
  void GetCenter(float center[3]);
  float GetLength();

  // Restore data object to initial state,
  virtual void Initialize();

  // Description:
  // Convenience method to get the range of the scalar data if there is any.
  // otherwise it will return 0 to 1.
  float *GetScalarRange();

protected:
  vtkSource *Source; // if I am the output of a Source this is a pntr to it
  vtkPointData PointData;   // Scalars, vectors, etc. associated w/ each point
  vtkTimeStamp ComputeTime; // Time at which bounds, center, etc. computed
  float Bounds[6];  // (xmin,xmax, ymin,ymax, zmin,zmax) geometric bounds

  int DataReleased; //keep track of data release during network execution
  int ReleaseDataFlag; //data will release after use by a filter
  static int GlobalReleaseDataFlag; //all data will release after use by a filter
};

inline void vtkDataSet::GetPoint(int id, float x[3])
{
  float *pt = this->GetPoint(id);
  x[0] = pt[0]; x[1] = pt[1]; x[2] = pt[2];
}

#endif
<commit_msg>ERR: spelling.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDataSet.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
// .NAME vtkDataSet - abstract class to specify dataset behavior
// .SECTION Description
// vtkDataSet is an abstract class that specifies an interface for
// data objects. (Data objects are synonymous with datasets). vtkDataSet
// also provides methods to provide informations about the data such
// as center, bounding box, and representative length.

#ifndef __vtkDataSet_h
#define __vtkDataSet_h

#include "vtkObject.hh"
#include "vtkIdList.hh"
#include "vtkFloatPoints.hh"
#include "vtkPointData.hh"
#include "vtkCell.hh"

class vtkSource;

class vtkDataSet : public vtkObject
{
public:
  vtkDataSet();
  vtkDataSet(const vtkDataSet& ds);
  char *GetClassName() {return "vtkDataSet";};
  void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // Provides opportunity for data to clean itself up before execution.
  virtual void Update();

  // Description:
  // Create concrete instance of this dataset.
  virtual vtkDataSet *MakeObject() = 0;

  // Description:
  // Copy the geometric and topological structure of an object. Note that
  // the invoking object and the object pointed to by the parameter ds must
  // be of the same type.
  virtual void CopyStructure(vtkDataSet *ds) = 0;

  // Description:
  // Return class name of data type. This is one of vtkStructuredGrid,
  // vtkStructuredPoints, vtkUnstructuredGrid, vtkPolyData.
  virtual char *GetDataType() = 0;

  // Description:
  // Determine number of points composing dataset.
  virtual int GetNumberOfPoints() = 0;

  // Description:
  // Determine number of cells composing dataset.
  virtual int GetNumberOfCells() = 0;

  // Description:
  // Get point coordinates with ptId such that: 0 <= ptId < NumberOfPoints
  virtual float *GetPoint(int ptId) = 0;

  // Description:
  // Copy point coordinates into user provided array x[3] for specified
  // point id.
  virtual void GetPoint(int id, float x[3]);

  // Description:
  // Get cell with cellId such that: 0 <= cellId < NumberOfCells
  virtual vtkCell *GetCell(int cellId) = 0;

  // Description:
  // Get type of cell with cellId such that: 0 <= cellId < NumberOfCells
  virtual int GetCellType(int cellId) = 0;

  // Description:
  // Topological inquiry to get points defining cell.
  virtual void GetCellPoints(int cellId, vtkIdList& ptIds) = 0;

  // Description:
  // Topological inquiry to get cells using point.
  virtual void GetPointCells(int ptId, vtkIdList& cellIds) = 0;

  // Description:
  // Topological inquiry to get all cells using list of points exclusive of
  // cell specified (e.g., cellId)
  virtual void GetCellNeighbors(int cellId, vtkIdList& ptIds, vtkIdList& cellIds);

  // Description:
  // Locate cell based on global coordinate x and tolerance squared. If
  // cell is non-NULL, then search starts from this cell and looks at
  // immediate neighbors. Returns cellId >= 0 if inside, < 0 otherwise.
  // The parametric coordinates are provided in pcoords[3]. The interpolation
  // weights are returned in weights[]. Tolerance is used to control how close
  // the point is to be considered "in" the cell.
  virtual int FindCell(float x[3], vtkCell *cell, float tol2, int& subId, float pcoords[3], float weights[VTK_MAX_CELL_SIZE]) = 0;

  // Datasets are composite objects and need to check each part for MTime
  unsigned long int GetMTime();

  // Description:
  // Release data back to system to conserve memory resource. Used during
  // visualization network execution.
  void ReleaseData();

  // Description:
  // Return flag indicating whether data should be released after use
  // by a filter.
  int ShouldIReleaseData();

  // Description:
  // Set/Get the DataReleased ivar.
  vtkSetMacro(DataReleased,int);
  vtkGetMacro(DataReleased,int);

  // Description:
  // Turn on/off flag to control whether this object's data is released
  // after being used by a filter.
  vtkSetMacro(ReleaseDataFlag,int);
  vtkGetMacro(ReleaseDataFlag,int);
  vtkBooleanMacro(ReleaseDataFlag,int);

  // Description:
  // Turn on/off flag to control whether every object releases its data
  // after being used by a filter.
  vtkSetMacro(GlobalReleaseDataFlag,int);
  vtkGetMacro(GlobalReleaseDataFlag,int);
  vtkBooleanMacro(GlobalReleaseDataFlag,int);

  // return pointer to this dataset's point data
  vtkPointData *GetPointData() {return &this->PointData;};

  // Description:
  // Reclaim any extra memory used to store data.
  virtual void Squeeze();

  // Description:
  // Set the owner of this data object for Sources.
  vtkSetObjectMacro(Source,vtkSource);

  // compute geometric bounds, center, longest side
  virtual void ComputeBounds();
  float *GetBounds();
  void GetBounds(float bounds[6]);
  float *GetCenter();
  void GetCenter(float center[3]);
  float GetLength();

  // Restore data object to initial state,
  virtual void Initialize();

  // Description:
  // Convenience method to get the range of the scalar data if there is any.
  // otherwise it will return 0 to 1.
  float *GetScalarRange();

protected:
  vtkSource *Source; // if I am the output of a Source this is a pntr to it
  vtkPointData PointData;   // Scalars, vectors, etc. associated w/ each point
  vtkTimeStamp ComputeTime; // Time at which bounds, center, etc. computed
  float Bounds[6];  // (xmin,xmax, ymin,ymax, zmin,zmax) geometric bounds

  int DataReleased; //keep track of data release during network execution
  int ReleaseDataFlag; //data will release after use by a filter
  static int GlobalReleaseDataFlag; //all data will release after use by a filter
};

inline void vtkDataSet::GetPoint(int id, float x[3])
{
  float *pt = this->GetPoint(id);
  x[0] = pt[0]; x[1] = pt[1]; x[2] = pt[2];
}

#endif
<|endoftext|>


<commit_before>#pragma once

#include <chrono>
#include <string>
#include <thread>

#include <boost/type_traits/remove_cv.hpp>
#include <boost/variant/apply_visitor.hpp>

#include "blackhole/attribute.hpp"
#include "blackhole/attributes.hpp"
#include "blackhole/extensions/writer.hpp"
#include "blackhole/record.hpp"
#include "blackhole/severity.hpp"

#include "blackhole/detail/attribute.hpp"
#include "blackhole/detail/record.hpp"

// TODO: Move `into_view` and `from_view` traits.

namespace blackhole {
inline namespace v1 {
namespace detail {

struct into_owned_t {
    typedef attribute::value_t result_type;

    template<typename T>
    auto operator()(T value) const -> result_type {
        return {value};
    }

    auto operator()(const attribute::view_t::string_type& value) const -> result_type {
        return {value.to_string()};
    }

    // TODO: Consider mapping into function.
    auto operator()(const attribute::view_t::function_type& value) const -> result_type {
        writer_t wr;
        value(wr);
        return {wr.result().to_string()};
    }
};

/// Represents a trait for mapping an owned types to their associated lightweight view types.
// TODO: Partially copies the same trait from `blackhole::v1` namespace.
template<typename T>
struct view_of;

template<>
struct view_of<std::string> {
    typedef string_view type;
    typedef std::string buffer_type;

    static auto from(const buffer_type& value) -> type {
        return {value};
    }
};

template<>
struct view_of<attributes_t> {
    typedef attribute_list type;
    typedef attributes_t buffer_type;

    static auto from(const buffer_type& value) -> type {
        type result;
        std::copy(std::begin(value), std::end(value), std::back_inserter(result));
        return result;
    }
};

template<typename T>
struct owned_pair {
    T data;
    typename view_of<T>::type view;

    explicit owned_pair(T value) :
        data(std::move(value)),
        view(view_of<T>::from(data))
    {}

    owned_pair(const owned_pair& other) = delete;
    owned_pair(owned_pair&& other) :
        data(std::move(other.data)),
        view(view_of<T>::from(data))
    {}

    auto operator=(const owned_pair& other) -> owned_pair& = delete;
    auto operator=(owned_pair&& other) -> owned_pair& {
        if (this != &other) {
            data = std::move(other.data);
            view = std::move(other.view);
            view = view_of<T>::from(data);
        }

        return *this;
    }
};

/// An owned, mutable record.
class recordbuf_t {
    owned_pair<std::string> message;
    owned_pair<std::string> formatted;
    owned_pair<attributes_t> attributes;

    attribute_pack pack;

    typedef std::aligned_storage<sizeof(record_t::inner_t)>::type storage_type;
    storage_type storage;

public:
    /// Constructs an empty invalid record.
    ///
    /// Required only by MPSC queue API. All access to such object will likely result in segfault.
    recordbuf_t() : message(""), formatted(""), attributes({}) {}

    /// Converts a record to an owned recordbuf.
    ///
    /// \throw std::bad_alloc on memory allocation failure.
    explicit recordbuf_t(const record_t& record) :
        message(record.message().to_string()),
        formatted(record.formatted().to_string()),
        attributes(flatten(record.attributes()))
    {
        pack.emplace_back(attributes.view);

        auto& inner = this->inner();
        inner.message = message.view;
        inner.formatted = formatted.view;
        inner.severity = record.severity();
        inner.timestamp = record.timestamp();
        inner.tid = record.tid();
        inner.attributes = pack;
    }

    recordbuf_t(const recordbuf_t& other) = delete;

    recordbuf_t(recordbuf_t&& other) noexcept :
        message(std::move(other.message)),
        formatted(std::move(other.formatted)),
        attributes(std::move(other.attributes)),
        storage(other.storage),
        pack(std::move(other.pack))
    {
        BOOST_ASSERT(pack.size() == 1);
        pack.back() = attributes.view;

        auto& inner = this->inner();
        inner.message = message.view;
        inner.formatted = formatted.view;
        inner.attributes = pack;
    }

    auto operator=(const recordbuf_t& other) -> recordbuf_t& = delete;

    auto operator=(recordbuf_t&& other) noexcept -> recordbuf_t& {
        if (this != &other) {
            message = std::move(other.message);
            formatted = std::move(other.formatted);
            attributes = std::move(other.attributes);
            storage = other.storage;
            pack = std::move(other.pack);

            BOOST_ASSERT(pack.size() == 1);
            pack.back() = attributes.view;

            auto& inner = this->inner();
            inner.message = message.view;
            inner.formatted = formatted.view;
            inner.attributes = pack;
        }

        return *this;
    }

    auto into_view() const noexcept -> record_t {
        return {inner()};
    }

private:
    auto inner() noexcept -> record_t::inner_t& {
        return reinterpret_cast<record_t::inner_t&>(storage);
    }

    auto inner() const noexcept -> const record_t::inner_t& {
        return reinterpret_cast<const record_t::inner_t&>(storage);
    }

    static auto flatten(const attribute_pack& pack) -> attributes_t {
        attributes_t result;

        for (auto list : pack) {
            for (auto kv : list.get()) {
                result.emplace_back(
                    kv.first.to_string(),
                    boost::apply_visitor(into_owned_t(), kv.second.inner().value)
                );
            }
        }

        return result;
    }
};

}  // namespace detail
}  // namespace v1
}  // namespace blackhole
<commit_msg>fix: proper initialization order<commit_after>#pragma once

#include <chrono>
#include <string>
#include <thread>

#include <boost/type_traits/remove_cv.hpp>
#include <boost/variant/apply_visitor.hpp>

#include "blackhole/attribute.hpp"
#include "blackhole/attributes.hpp"
#include "blackhole/extensions/writer.hpp"
#include "blackhole/record.hpp"
#include "blackhole/severity.hpp"

#include "blackhole/detail/attribute.hpp"
#include "blackhole/detail/record.hpp"

// TODO: Move `into_view` and `from_view` traits.

namespace blackhole {
inline namespace v1 {
namespace detail {

struct into_owned_t {
    typedef attribute::value_t result_type;

    template<typename T>
    auto operator()(T value) const -> result_type {
        return {value};
    }

    auto operator()(const attribute::view_t::string_type& value) const -> result_type {
        return {value.to_string()};
    }

    // TODO: Consider mapping into function.
    auto operator()(const attribute::view_t::function_type& value) const -> result_type {
        writer_t wr;
        value(wr);
        return {wr.result().to_string()};
    }
};

/// Represents a trait for mapping an owned types to their associated lightweight view types.
// TODO: Partially copies the same trait from `blackhole::v1` namespace.
template<typename T>
struct view_of;

template<>
struct view_of<std::string> {
    typedef string_view type;
    typedef std::string buffer_type;

    static auto from(const buffer_type& value) -> type {
        return {value};
    }
};

template<>
struct view_of<attributes_t> {
    typedef attribute_list type;
    typedef attributes_t buffer_type;

    static auto from(const buffer_type& value) -> type {
        type result;
        std::copy(std::begin(value), std::end(value), std::back_inserter(result));
        return result;
    }
};

template<typename T>
struct owned_pair {
    T data;
    typename view_of<T>::type view;

    explicit owned_pair(T value) :
        data(std::move(value)),
        view(view_of<T>::from(data))
    {}

    owned_pair(const owned_pair& other) = delete;
    owned_pair(owned_pair&& other) :
        data(std::move(other.data)),
        view(view_of<T>::from(data))
    {}

    auto operator=(const owned_pair& other) -> owned_pair& = delete;
    auto operator=(owned_pair&& other) -> owned_pair& {
        if (this != &other) {
            data = std::move(other.data);
            view = std::move(other.view);
            view = view_of<T>::from(data);
        }

        return *this;
    }
};

/// An owned, mutable record.
class recordbuf_t {
    owned_pair<std::string> message;
    owned_pair<std::string> formatted;
    owned_pair<attributes_t> attributes;

    attribute_pack pack;

    typedef std::aligned_storage<sizeof(record_t::inner_t)>::type storage_type;
    storage_type storage;

public:
    /// Constructs an empty invalid record.
    ///
    /// Required only by MPSC queue API. All access to such object will likely result in segfault.
    recordbuf_t() : message(""), formatted(""), attributes({}) {}

    /// Converts a record to an owned recordbuf.
    ///
    /// \throw std::bad_alloc on memory allocation failure.
    explicit recordbuf_t(const record_t& record) :
        message(record.message().to_string()),
        formatted(record.formatted().to_string()),
        attributes(flatten(record.attributes()))
    {
        pack.emplace_back(attributes.view);

        auto& inner = this->inner();
        inner.message = message.view;
        inner.formatted = formatted.view;
        inner.severity = record.severity();
        inner.timestamp = record.timestamp();
        inner.tid = record.tid();
        inner.attributes = pack;
    }

    recordbuf_t(const recordbuf_t& other) = delete;

    recordbuf_t(recordbuf_t&& other) noexcept :
        message(std::move(other.message)),
        formatted(std::move(other.formatted)),
        attributes(std::move(other.attributes)),
        pack(std::move(other.pack)),
        storage(other.storage)
    {
        BOOST_ASSERT(pack.size() == 1);
        pack.back() = attributes.view;

        auto& inner = this->inner();
        inner.message = message.view;
        inner.formatted = formatted.view;
        inner.attributes = pack;
    }

    auto operator=(const recordbuf_t& other) -> recordbuf_t& = delete;

    auto operator=(recordbuf_t&& other) noexcept -> recordbuf_t& {
        if (this != &other) {
            message = std::move(other.message);
            formatted = std::move(other.formatted);
            attributes = std::move(other.attributes);
            storage = other.storage;
            pack = std::move(other.pack);

            BOOST_ASSERT(pack.size() == 1);
            pack.back() = attributes.view;

            auto& inner = this->inner();
            inner.message = message.view;
            inner.formatted = formatted.view;
            inner.attributes = pack;
        }

        return *this;
    }

    auto into_view() const noexcept -> record_t {
        return {inner()};
    }

private:
    auto inner() noexcept -> record_t::inner_t& {
        return reinterpret_cast<record_t::inner_t&>(storage);
    }

    auto inner() const noexcept -> const record_t::inner_t& {
        return reinterpret_cast<const record_t::inner_t&>(storage);
    }

    static auto flatten(const attribute_pack& pack) -> attributes_t {
        attributes_t result;

        for (auto list : pack) {
            for (auto kv : list.get()) {
                result.emplace_back(
                    kv.first.to_string(),
                    boost::apply_visitor(into_owned_t(), kv.second.inner().value)
                );
            }
        }

        return result;
    }
};

}  // namespace detail
}  // namespace v1
}  // namespace blackhole
<|endoftext|>