text:
//
// Copyright 2016 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
//    names, trademarks, service marks, or product names of the Licensor
//    and its affiliates, except as required to comply with Section 4(c) of
//    the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "pxr/usd/usd/attribute.h"

#include "pxr/usd/usd/conversions.h"
#include "pxr/usd/usd/stage.h"
#include "pxr/usd/usd/interpolators.h"
#include "pxr/usd/usd/resolveInfo.h"

#include "pxr/usd/ar/resolver.h"
#include "pxr/usd/ar/resolverContextBinder.h"
#include "pxr/usd/sdf/attributeSpec.h"
#include "pxr/usd/sdf/layer.h"
#include "pxr/usd/sdf/primSpec.h"
#include "pxr/usd/sdf/schema.h"

// NOTE: this is not actually used, but AttributeSpec requires it
#include "pxr/usd/sdf/relationshipSpec.h"

#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/utility/enable_if.hpp>
#include <vector>

// ------------------------------------------------------------------------- //
// UsdAttribute
// ------------------------------------------------------------------------- //

SdfVariability
UsdAttribute::GetVariability() const
{
    return _GetStage()->_GetVariability(*this);
}

bool
UsdAttribute::SetVariability(SdfVariability variability) const
{
    return SetMetadata(SdfFieldKeys->Variability, variability);
}

SdfValueTypeName
UsdAttribute::GetTypeName() const
{
    TfToken typeName;
    GetMetadata(SdfFieldKeys->TypeName, &typeName);
    return SdfSchema::GetInstance().FindType(typeName);
}

TfToken
UsdAttribute::GetRoleName() const
{
    return GetTypeName().GetRole();
}

bool
UsdAttribute::SetTypeName(const SdfValueTypeName& typeName) const
{
    return SetMetadata(SdfFieldKeys->TypeName, typeName.GetAsToken());
}

void
UsdAttribute::Block()
{
    Clear();
    Set(VtValue(SdfValueBlock()), UsdTimeCode::Default());
}

bool
UsdAttribute::GetTimeSamples(std::vector<double>* times) const
{
    return _GetStage()->_GetTimeSamplesInInterval(*this,
        GfInterval::GetFullInterval(), times);
}

size_t
UsdAttribute::GetNumTimeSamples() const
{
    return _GetStage()->_GetNumTimeSamples(*this);
}

bool
UsdAttribute::GetBracketingTimeSamples(double desiredTime,
                                       double* lower,
                                       double* upper,
                                       bool* hasTimeSamples) const
{
    return _GetStage()->_GetBracketingTimeSamples(
        *this, desiredTime, /*requireAuthored*/ false,
        lower, upper, hasTimeSamples);
}

bool
UsdAttribute::GetTimeSamplesInInterval(const GfInterval& interval,
                                       std::vector<double>* times) const
{
    return _GetStage()->_GetTimeSamplesInInterval(*this, interval, times);
}

bool
UsdAttribute::HasAuthoredValueOpinion() const
{
    Usd_ResolveInfo resolveInfo;
    _GetStage()->_GetResolveInfo(*this, &resolveInfo);
    bool authoredValueFound =
        resolveInfo.source == Usd_ResolveInfoSourceDefault
        or resolveInfo.source == Usd_ResolveInfoSourceTimeSamples
        or resolveInfo.source == Usd_ResolveInfoSourceValueClips;

    return authoredValueFound or resolveInfo.valueIsBlocked;
}

bool
UsdAttribute::HasValue() const
{
    Usd_ResolveInfo resolveInfo;
    _GetStage()->_GetResolveInfo(*this, &resolveInfo);
    return resolveInfo.source != Usd_ResolveInfoSourceNone;
}

bool
UsdAttribute::HasFallbackValue() const
{
    return _GetStage()->_GetAttributeDefinition(*this)->HasDefaultValue();
}

bool
UsdAttribute::ValueMightBeTimeVarying() const
{
    return _GetStage()->_ValueMightBeTimeVarying(*this);
}

template <typename T>
bool
UsdAttribute::_Get(T* value, UsdTimeCode time) const
{
    return _GetStage()->_GetValue(time, *this, value);
}

bool
UsdAttribute::Get(VtValue* value, UsdTimeCode time) const
{
    auto stage = _GetStage();
    bool foundValue = stage->_GetValue(time, *this, value);

    // Special case for SdfAssetPath -- compute the resolved asset path.
    if (foundValue and value) {
        stage->_MakeResolvedAssetPaths(time, *this, value);
    }

    return foundValue;
}

// Specializations for SdfAssetPath(Array) that do path resolution.
template <>
bool
UsdAttribute::_Get(SdfAssetPath *assetPath, UsdTimeCode time) const
{
    auto stage = _GetStage();

    if (stage->_GetValue(time, *this, assetPath)) {
        stage->_MakeResolvedAssetPaths(time, *this, assetPath, 1);
        return true;
    }

    return false;
}

template <>
bool
UsdAttribute::_Get(VtArray<SdfAssetPath> *assetPaths, UsdTimeCode time) const
{
    auto stage = _GetStage();

    if (stage->_GetValue(time, *this, assetPaths)) {
        stage->_MakeResolvedAssetPaths(time, *this, assetPaths->data(),
                                       assetPaths->size());
        return true;
    }

    return false;
}

bool
UsdAttribute::_UntypedSet(const SdfAbstractDataConstValue& value,
                          UsdTimeCode time) const
{
    return _GetStage()->_SetValue(time, *this, value);
}

bool
UsdAttribute::Set(const VtValue& value, UsdTimeCode time) const
{
    return _GetStage()->_SetValue(time, *this, value);
}

bool
UsdAttribute::Clear() const
{
    return ClearDefault()
       and ClearMetadata(SdfFieldKeys->TimeSamples);
}

bool
UsdAttribute::ClearAtTime(UsdTimeCode time) const
{
    return _GetStage()->_ClearValue(time, *this);
}

bool
UsdAttribute::ClearDefault() const
{
    return ClearAtTime(UsdTimeCode::Default());
}

SdfAttributeSpecHandle
UsdAttribute::_CreateSpec(const SdfValueTypeName& typeName, bool custom,
                          const SdfVariability &variability) const
{
    UsdStage *stage = _GetStage();

    if (variability != SdfVariabilityVarying and
        variability != SdfVariabilityUniform){
        TF_CODING_ERROR("UsdAttributes can only possess variability "
                        "varying or uniform.  Cannot create attribute %s.%s",
                        GetPrimPath().GetText(), _PropName().GetText());
        return TfNullPtr;
    }

    // Try to create a spec for editing either from the definition or from
    // copying existing spec info.
    TfErrorMark m;
    if (SdfAttributeSpecHandle attrSpec =
        stage->_CreateAttributeSpecForEditing(*this))
        return attrSpec;

    // If creating the spec on the stage failed without issuing an error, that
    // means there was no existing authored scene description to go on (i.e. no
    // builtin info from prim type, and no existing authored spec).  Stamp a
    // spec with the provided default values.
    if (m.IsClean()) {
        SdfChangeBlock block;
        return SdfAttributeSpec::New(
            stage->_CreatePrimSpecForEditing(GetPrimPath()),
            _PropName(), typeName, variability, custom);
    }
    return TfNullPtr;
}

bool
UsdAttribute::_Create(const SdfValueTypeName& typeName, bool custom,
                      const SdfVariability &variability) const
{
    return _CreateSpec(typeName, custom, variability);
}

// Explicitly instantiate templated getters for all Sdf value
// types.
#define _INSTANTIATE_GET(r, unused, elem)                               \
    template bool UsdAttribute::_Get(                                   \
        SDF_VALUE_TRAITS_TYPE(elem)::Type*, UsdTimeCode) const;         \
    template bool UsdAttribute::_Get(                                   \
        SDF_VALUE_TRAITS_TYPE(elem)::ShapedType*, UsdTimeCode) const;

BOOST_PP_SEQ_FOR_EACH(_INSTANTIATE_GET, ~, SDF_VALUE_TYPES)
#undef _INSTANTIATE_GET


text:
#pragma once

#include <route_solver/structs/data_structs.hpp>
#include <route_solver/solution/fail_statistics.hpp>
#include <Eigen/Core>

namespace rs {

struct PointStat
{
	PointStat(
		std::uint32_t nodeId,
		std::size_t time,
		double workload,
		double volume,
		double distance,
		int tasksCount
	);

	std::uint32_t nodeId;
	std::size_t time;
	double workload;
	double volume;
	double distance;
	int tasksCount;
};

class CurrentRouteState {
public:

	CurrentRouteState(
		const Vehicle& vehicle,
		const Eigen::MatrixXd& destTimeTable,
		const Eigen::MatrixXd& destTable,
		FailedStatisticsCollector& failsCollector,
		std::vector<PointStat>* stats = 0);

	void moveNextStart(std::int32_t nextNode, const Task& task);

	bool processLoad(const Task& task);

	bool processUnload(const Task& task);

	bool moveNextEnd(std::int32_t nextNode, const Task& task);

	std::size_t totalTimeSpend() const;

	double totalDistance() const;

	double totalCostOfRoute() const;

	void pushStatsIfNeeded(double nodeDistance);

private:
	const Vehicle& m_vehicle;
	const Eigen::MatrixXd& m_destTimeTable;
	const Eigen::MatrixXd& m_destTable;

	std::size_t m_currentTime = 0;
	double m_currentDistanceMeters = 0;
	std::size_t m_routeStartTime = 0;
	double m_currentLoad = 0;
	double m_currentVolume = 0;

	std::uint32_t m_taskTaken = 0;
	std::int32_t m_currentNode = -1;
	std::vector<PointStat>* m_stats;
	FailedStatisticsCollector& m_failsCollector;
};

}

ext: hpp


text:
#include "break_constraint.h"

#include <boost/algorithm/string/join.hpp>
#include <boost/date_time/time.hpp>

#include "solver_wrapper.h"

namespace rows {

    BreakConstraint::BreakConstraint(const operations_research::RoutingDimension *dimension,
                                     const operations_research::RoutingIndexManager *index_manager,
                                     int vehicle,
                                     std::vector<operations_research::IntervalVar *> break_intervals,
                                     RealProblemData &problem_data)
            : Constraint(dimension->model()->solver()),
              dimension_(dimension),
              index_manager_(index_manager),
              vehicle_(vehicle),
              break_intervals_(std::move(break_intervals)),
              status_(solver()->MakeBoolVar((boost::format("status %1%") % vehicle).str())),
              problem_data_(problem_data) {}

    void BreakConstraint::Post() {
        operations_research::RoutingModel *const model = dimension_->model();
        operations_research::Constraint *const path_connected_const
                = solver()->MakePathConnected(model->Nexts(),
                                              {model->Start(vehicle_)},
                                              {model->End(vehicle_)},
                                              {status_});

        solver()->AddConstraint(path_connected_const);
        operations_research::Demon *const demon = solver()->MakeConstraintInitialPropagateCallback(this);
        status_->WhenBound(demon);
    }

    void BreakConstraint::InitialPropagate() {
        if (status_->Bound()) {
            OnPathClosed();
        }
    }

    void BreakConstraint::OnPathClosed() {
        using boost::posix_time::time_duration;
        using boost::posix_time::seconds;

        if (status_->Max() == 0) {
            for (operations_research::IntervalVar *const break_interval : break_intervals_) {
                break_interval->SetPerformed(false);
            }
            return;
        }

        const auto initial_number_of_failures = solver()->failures();

        std::vector<operations_research::IntervalVar *> all_intervals;
        operations_research::IntervalVar *last_travel_interval = nullptr;
        operations_research::IntervalVar *last_last_visit_interval = nullptr;
        operations_research::IntervalVar *last_visit_interval = nullptr;

        operations_research::RoutingModel *const model = dimension_->model();
        int64 current_index = model->Start(vehicle_);
        while (!model->IsEnd(current_index)) {
            const auto current_node = index_manager_->IndexToNode(current_index);
            const auto next_index = model->NextVar(current_index)->Value();
            const auto next_node = index_manager_->IndexToNode(next_index);

            // create visit interval
            if (RealProblemData::DEPOT != current_node) {
                const auto visit_duration = problem_data_.ServiceTime(current_node);
                DCHECK_GT(visit_duration, 0);

                operations_research::IntervalVar *const visit_interval = solver()->MakeFixedDurationIntervalVar(
                        dimension_->CumulVar(current_index),
                        visit_duration,
                        (boost::format("visit %1%") % current_index).str());
                all_intervals.push_back(visit_interval);

                if (last_travel_interval) {
                    solver()->AddConstraint(solver()->MakeIntervalVarRelation(visit_interval,
                                                                              operations_research::Solver::STARTS_AFTER_END,
                                                                              last_travel_interval));
                }

                last_last_visit_interval = last_visit_interval;
                last_visit_interval = visit_interval;
            } else {
                last_last_visit_interval = last_visit_interval;
                last_visit_interval = nullptr;
            }

            // create travel interval
            const auto travel_duration = problem_data_.Distance(current_node, next_node);
            if (travel_duration > 0) {
                int64 min_travel_start = 0;
                if (last_visit_interval != nullptr) {
                    min_travel_start = last_visit_interval->EndMin();
                }

                const auto max_travel_start = std::min(dimension_->CumulVar(next_index)->Max() - travel_duration,
                                                       RealProblemData::SECONDS_IN_DIMENSION);
                if (min_travel_start > max_travel_start) {
                    solver()->Fail();
                }

                operations_research::IntervalVar *const travel_interval = solver()->MakeFixedDurationIntervalVar(
                        min_travel_start,
                        max_travel_start,
                        travel_duration,
                        false,
                        (boost::format("travel %1%-%2%") % current_index % next_index).str());
                all_intervals.push_back(travel_interval);

                if (last_visit_interval) {
                    solver()->AddConstraint(solver()->MakeIntervalVarRelation(travel_interval,
                                                                              operations_research::Solver::STARTS_AFTER_END,
                                                                              last_visit_interval));
                    solver()->AddConstraint(
                            solver()->MakeLessOrEqual(last_visit_interval->EndExpr(), travel_interval->StartExpr()));
                    CHECK_GE(travel_interval->StartMin(), last_visit_interval->EndMin());
                }

                last_travel_interval = travel_interval;
            } else {
                if (last_last_visit_interval && last_visit_interval) {
                    solver()->AddConstraint(solver()->MakeIntervalVarRelation(last_visit_interval,
                                                                              operations_research::Solver::STARTS_AFTER_END,
                                                                              last_last_visit_interval));
                }
                last_travel_interval = nullptr;
            }

            current_index = next_index;
        }

        if (break_intervals_.size() > 1) {
            const auto break_interval_end = std::end(break_intervals_);
            auto last_break_it = std::begin(break_intervals_);
            auto break_interval_it = std::next(last_break_it);
            while (break_interval_it != break_interval_end) {
                solver()->AddConstraint(solver()->MakeIntervalVarRelation(*break_interval_it,
                                                                          operations_research::Solver::STARTS_AFTER_END,
                                                                          *last_break_it));

                last_break_it = break_interval_it;
                break_interval_it = std::next(break_interval_it);
            }
        }

        const auto current_number_of_failures = solver()->failures();
        if (current_number_of_failures > initial_number_of_failures) {
            LOG(WARNING) << "Registered a failure and have no way to jump...";
        } else {
            std::copy(std::begin(break_intervals_), std::end(break_intervals_), std::back_inserter(all_intervals));
            solver()->AddConstraint(solver()->MakeDisjunctiveConstraint(all_intervals,
                                                                        (boost::format("Vehicle breaks %1%")
                                                                         % vehicle_).str()));
        }
    }
}

ext: cpp

max_stars_repo_name: pmateusz/cordia

max_issues_repo_name: pmateusz/cordia

max_forks_repo_name: pmateusz/cordia


text: #include <boost/iterator/iterator_categories.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
//          Copyright Oliver Kowalke 2014.
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_COROUTINES2_DETAIL_CONFIG_H
#define BOOST_COROUTINES2_DETAIL_CONFIG_H

#include <boost/config.hpp>
#include <boost/context/detail/config.hpp>
#include <boost/detail/workaround.hpp>

#ifdef BOOST_COROUTINES2_DECL
#undef BOOST_COROUTINES2_DECL
#endif

#if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_COROUTINES2_DYN_LINK)) &&    \
    !defined(BOOST_COROUTINES2_STATIC_LINK)
#if defined(BOOST_COROUTINES2_SOURCE)
#define BOOST_COROUTINES2_DECL BOOST_SYMBOL_EXPORT
#else
#define BOOST_COROUTINES2_DECL BOOST_SYMBOL_IMPORT
#endif
#endif

#if !defined(BOOST_COROUTINES2_DECL)
#define BOOST_COROUTINES2_DECL
#endif

#endif // BOOST_COROUTINES2_DETAIL_CONFIG_H

max_stars_repo_name: henrywarhurst/matrix

max_issues_repo_name: henrywarhurst/matrix

max_forks_repo_name: henrywarhurst/matrix


text:
// Copyright DEWETRON GmbH 2020

#include "wav_writer.h"

//#include "uni_math_constants.h"
#include <cmath>
#include <boost/test/unit_test.hpp>

#if _MSC_VER > 1920
#pragma warning(disable:4996)
#endif

BOOST_AUTO_TEST_SUITE(uni_wav_writer_test_suite)

namespace
{
    const int CHUNK_SIZE = 8;
    const int RIFFWAVE_SIZE = CHUNK_SIZE + 4;
    const int FORMAT_SIZE = CHUNK_SIZE + 16;
}

BOOST_AUTO_TEST_CASE(WriteHeaderTest)
{
    FILE* tmp = std::tmpfile();
    WavWriter writer(tmp);
    writer.writeHeader(WavFormatTag::WAV_FORMAT_PCM, 16, 44100, 2, 0);

    struct header
    {
        char riff[4];
        uint32_t length;
        char wave[4];
    };
    BOOST_CHECK_EQUAL(sizeof(header), RIFFWAVE_SIZE);

    BOOST_REQUIRE_EQUAL(0, fseek(tmp, 0, SEEK_SET));
    header buffer;
    BOOST_REQUIRE_EQUAL(1, fread(&buffer, sizeof(header), 1, tmp));
    BOOST_CHECK(!std::strncmp(buffer.riff, "RIFF", 4));
    BOOST_CHECK_EQUAL(buffer.length, 4 + FORMAT_SIZE + CHUNK_SIZE);
    BOOST_CHECK(!std::strncmp(buffer.wave, "WAVE", 4));

    struct fmtheader
    {
        char fmt[4];
        uint32_t length;
        uint16_t format_tag;
        uint16_t channels;
        uint32_t sample_rate;
        uint32_t bytes_per_second;
        uint16_t block_align;
        uint16_t bits_per_sample;
    } fmt;

    BOOST_REQUIRE_EQUAL(1, fread(&fmt, sizeof(fmt), 1, tmp));
    BOOST_CHECK(!std::strncmp(fmt.fmt, "fmt ", 4));
    BOOST_CHECK_EQUAL(fmt.length, 16);
    BOOST_CHECK_EQUAL(fmt.format_tag, 1);
    BOOST_CHECK_EQUAL(fmt.channels, 2);
    BOOST_CHECK_EQUAL(fmt.sample_rate, 44100);
    BOOST_CHECK_EQUAL(fmt.bytes_per_second, 2 * 2 * 44100);
    BOOST_CHECK_EQUAL(fmt.block_align, 2 * 2);
    BOOST_CHECK_EQUAL(fmt.bits_per_sample, 16);

    struct dataheader
    {
        char data[4];
        uint32_t length;
    } dataheader;
    BOOST_REQUIRE_EQUAL(1, fread(&dataheader, sizeof(dataheader), 1, tmp));
    BOOST_CHECK(!std::strncmp(dataheader.data, "data ", 4));
    BOOST_CHECK_EQUAL(dataheader.length, 0);
}

BOOST_AUTO_TEST_CASE(WriteSamplesTest)
{
    FILE* tmp = std::tmpfile();
    WavWriter writer(tmp);
    writer.writeHeader(WavFormatTag::WAV_FORMAT_PCM, 16, 44100, 2, 10);
    for (int16_t n = 0; n < 10; ++n)
    {
        writer.appendSamples(&n, sizeof(int16_t));
    }
    BOOST_CHECK_EQUAL(writer.samplesWritten(), 10);

    // batch add samples
    std::vector<int16_t> data(10, 0);
    writer.appendSamples(data.data(), data.size() * sizeof(int16_t));
    BOOST_CHECK_EQUAL(writer.samplesWritten(), 20);

    BOOST_REQUIRE_EQUAL(0, fseek(tmp, RIFFWAVE_SIZE + FORMAT_SIZE + CHUNK_SIZE, SEEK_SET));
    std::vector<uint16_t> samples(2 * 10);
    BOOST_REQUIRE_EQUAL(samples.size(), fread(samples.data(), sizeof(uint16_t), samples.size(), tmp));
    for (uint16_t n = 0; n < 10; ++n)
    {
        BOOST_CHECK_EQUAL(samples[n], n);
    }
}

#if 0
BOOST_AUTO_TEST_CASE(ExternalUsabiliyTest)
{
    // This test is used to generate a WAV file with various settings to test the import into a 3rd party audio program
    WavWriter writer("C:\\Temp\\export.wav");
    const uint32_t Fs = 44100;
    const double f0 = 440;
    const std::size_t num_samples = Fs * 2;
    const std::size_t bit_depth = 24;

    writer.writeHeader(WavFormatTag::WAV_FORMAT_PCM, bit_depth, Fs, 1, num_samples);
    const double w = uni::math::constants::two_pi * f0 / Fs;
    const double lambda = -2.0 / Fs;
    const double conversion_factor = (1 << (bit_depth - 1)) - 1;
    for (std::size_t n = 0; n < num_samples; ++n)
    {
        double scale = std::exp(lambda * n);
        const double a = scale * std::sin(w * n);
        sint64 sample = static_cast<sint64>(a * conversion_factor);
        writer.appendSamples(&sample, bit_depth / 8);
    }
    writer.close();
}

BOOST_AUTO_TEST_CASE(ExternalUsabiliyFloatTest)
{
    // This test is used to generate a WAV file with various settings to test the import into a 3rd party audio program
    WavWriter writer("C:\\Temp\\export_float.wav");
    const uint32_t Fs = 44100;
    const double f0 = 440;
    const std::size_t num_samples = Fs * 2;
    using sample_format = float;
    const std::size_t bit_depth = sizeof(sample_format) * 8;

    writer.writeHeader(WavFormatTag::WAV_FORMAT_FLOAT, bit_depth, Fs, 1, num_samples);
    const double w = uni::math::constants::two_pi * f0 / Fs;
    const double lambda = -2.0 / Fs;
    for (std::size_t n = 0; n < num_samples; ++n)
    {
        double scale = std::exp(lambda * n);
        const double a = scale * std::sin(w * n);
        sample_format sample = static_cast<sample_format>(a);
        writer.appendSamples(&sample, sizeof(sample));
    }
    writer.close();
}
#endif

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: HpLightcorner/OXYGEN-SDK

max_issues_repo_name: HpLightcorner/OXYGEN-SDK

max_forks_repo_name: HpLightcorner/OXYGEN-SDK


text:
/**
 * @file srdf_model.cpp
 * @brief Parse srdf xml
 *
 * @author Levi Armstrong, Ioan Sucan
 * @date May 12, 2020
 * @version TODO
 * @bug No known bugs
 *
 * @copyright Copyright (c) 2020, Southwest Research Institute
 *
 * @par License
 * Software License Agreement (Apache License)
 * @par
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * @par
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <tesseract_common/macros.h>
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#include <unordered_map>
#include <vector>
#include <utility>
#include <console_bridge/console.h>
#include <fstream>
#include <tinyxml2.h>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
TESSERACT_COMMON_IGNORE_WARNINGS_POP

#include <tesseract_srdf/groups.h>
#include <tesseract_srdf/group_states.h>
#include <tesseract_srdf/group_tool_center_points.h>
#include <tesseract_srdf/group_opw_kinematics.h>
#include <tesseract_srdf/group_rep_kinematics.h>
#include <tesseract_srdf/group_rop_kinematics.h>
#include <tesseract_srdf/disabled_collisions.h>
#include <tesseract_srdf/collision_margins.h>
#include <tesseract_srdf/srdf_model.h>
#include <tesseract_common/utils.h>

namespace tesseract_srdf
{
void SRDFModel::initFile(const tesseract_scene_graph::SceneGraph& scene_graph, const std::string& filename)
{
  // get the entire file
  std::string xml_string;
  std::fstream xml_file(filename.c_str(), std::fstream::in);
  if (xml_file.is_open())
  {
    while (xml_file.good())
    {
      std::string line;
      std::getline(xml_file, line);
      xml_string += (line + "\n");
    }
    xml_file.close();
    try
    {
      initString(scene_graph, xml_string);
    }
    catch (...)
    {
      std::throw_with_nested(std::runtime_error("SRDF: Failed to parse file '" + filename + "'!"));
    }
  }
  else
  {
    std::throw_with_nested(std::runtime_error("SRDF: Failed to open file '" + filename + "'!"));
  }
}

void SRDFModel::initString(const tesseract_scene_graph::SceneGraph& scene_graph, const std::string& xmlstring)
{
  tinyxml2::XMLDocument xml_doc;
  tinyxml2::XMLError status = xml_doc.Parse(xmlstring.c_str());
  if (status != tinyxml2::XMLError::XML_SUCCESS)
    std::throw_with_nested(std::runtime_error("SRDF: Failed to create XMLDocument from xml string!"));

  clear();

  const tinyxml2::XMLElement* srdf_xml = xml_doc.FirstChildElement("robot");
  if (!srdf_xml)
    std::throw_with_nested(std::runtime_error("SRDF: Missing 'robot' element in the xml file!"));

  if (!srdf_xml || std::strncmp(srdf_xml->Name(), "robot", 5) != 0)
    std::throw_with_nested(std::runtime_error("SRDF: Missing 'robot' element in the xml file!"));

  // get the robot name
  status = tesseract_common::QueryStringAttributeRequired(srdf_xml, "name", name);
  if (status != tinyxml2::XML_SUCCESS)
    std::throw_with_nested(std::runtime_error("SRDF: Missing or failed to parse attribute 'name'!"));

  if (name != scene_graph.getName())
    CONSOLE_BRIDGE_logError("Semantic description is not specified for the same robot as the URDF");

  std::string version_string;
  status = tesseract_common::QueryStringAttribute(srdf_xml, "version", version_string);
  if (status != tinyxml2::XML_NO_ATTRIBUTE && status != tinyxml2::XML_SUCCESS)
  {
    std::throw_with_nested(std::runtime_error("SRDF: Failed to parse attribute 'version'!"));
  }
  else if (status != tinyxml2::XML_NO_ATTRIBUTE)
  {
    std::vector<std::string> tokens;
    boost::split(tokens, version_string, boost::is_any_of("."), boost::token_compress_on);
    if (tokens.size() < 2 || tokens.size() > 3 || !tesseract_common::isNumeric(tokens))
      std::throw_with_nested(std::runtime_error("SRDF: Failed to parse attribute 'version'!"));

    tesseract_common::toNumeric<int>(tokens[0], version[0]);
    tesseract_common::toNumeric<int>(tokens[1], version[1]);
    if (tokens.size() == 3)
      tesseract_common::toNumeric<int>(tokens[2], version[2]);
    else
      version[2] = 0;
  }
  else
  {
    CONSOLE_BRIDGE_logDebug("SRDF Parser: The version number warning can be suppressed by adding the attribute: "
                            "version=%i.%i.%i",
                            version[0],
                            version[1],
                            version[2]);
  }

  std::tuple<GroupNames, ChainGroups, JointGroups, LinkGroups> groups_info;
  try
  {
    groups_info = parseGroups(scene_graph, srdf_xml, version);
  }
  catch (...)
  {
    std::throw_with_nested(std::runtime_error("SRDF: Error parsing srdf groups for robot '" + name + "'!"));
  }

  kinematics_information.group_names = std::get<0>(groups_info);
  kinematics_information.chain_groups = std::get<1>(groups_info);
  kinematics_information.joint_groups = std::get<2>(groups_info);
  kinematics_information.link_groups = std::get<3>(groups_info);

  try
  {
    kinematics_information.group_states =
        parseGroupStates(scene_graph, kinematics_information.group_names, srdf_xml, version);
  }
  catch (...)
  {
    std::throw_with_nested(std::runtime_error("SRDF: Error parsing srdf groups states for robot '" + name + "'!"));
  }

  try
  {
    kinematics_information.group_tcps = parseGroupTCPs(scene_graph, srdf_xml, version);
  }
  catch (...)
  {
    std::throw_with_nested(
        std::runtime_error("SRDF: Error parsing srdf groups tool center points for robot '" + name + "'!"));
  }

  try
  {
    kinematics_information.group_opw_kinematics = parseGroupOPWKinematics(scene_graph, srdf_xml, version);
  }
  catch (...)
  {
    std::throw_with_nested(
        std::runtime_error("SRDF: Error parsing srdf group opw kinematics for robot '" + name + "'!"));
  }

  try
  {
    kinematics_information.group_rop_kinematics = parseGroupROPKinematics(scene_graph, srdf_xml, version);
  }
  catch (...)
  {
    std::throw_with_nested(std::runtime_error("SRDF: Error parsing srdf group robot on a positioner kinematics for "
                                              "robot '" +
                                              name + "'!"));
  }

  try
  {
    kinematics_information.group_rep_kinematics = parseGroupREPKinematics(scene_graph, srdf_xml, version);
  }
  catch (...)
  {
    std::throw_with_nested(std::runtime_error("SRDF: Error parsing srdf group robot with external positioner "
                                              "kinematics for robot '" +
                                              name + "'!"));
  }

  try
  {
    acm = parseDisabledCollisions(scene_graph, srdf_xml, version);
  }
  catch (...)
  {
    std::throw_with_nested(
        std::runtime_error("SRDF: Error parsing srdf disabled collisions for robot '" + name + "'!"));
  }

  try
  {
    collision_margin_data = parseCollisionMargins(scene_graph, srdf_xml, version);
  }
  catch (...)
  {
    std::throw_with_nested(
        std::runtime_error("SRDF: Error parsing srdf collision margin data for robot '" + name + "'!"));
  }
}

bool SRDFModel::saveToFile(const std::string& file_path) const
{
  tinyxml2::XMLDocument doc;
  tinyxml2::XMLElement* xml_root = doc.NewElement("robot");
  xml_root->SetAttribute("name", name.c_str());
  xml_root->SetAttribute(
      "version",
      (std::to_string(version[0]) + "." + std::to_string(version[1]) + "." + std::to_string(version[2])).c_str());

  for (const auto& chain : kinematics_information.chain_groups)
  {
    tinyxml2::XMLElement* xml_group = doc.NewElement("group");
    xml_group->SetAttribute("name", chain.first.c_str());
    for (const auto& pair : chain.second)  // <chain base_link="base_link" tip_link="tool0" />
    {
      tinyxml2::XMLElement* xml_pair = doc.NewElement("chain");
      xml_pair->SetAttribute("base_link", pair.first.c_str());
      xml_pair->SetAttribute("tip_link", pair.second.c_str());
      xml_group->InsertEndChild(xml_pair);
    }
    xml_root->InsertEndChild(xml_group);
  }

  for (const auto& joint : kinematics_information.joint_groups)
  {
    tinyxml2::XMLElement* xml_group = doc.NewElement("group");
    xml_group->SetAttribute("name", joint.first.c_str());
    for (const auto& joint_name : joint.second)  // <chain base_link="base_link" tip_link="tool0" />
    {
      tinyxml2::XMLElement* xml_joint = doc.NewElement("joint");
      xml_joint->SetAttribute("name", joint_name.c_str());
      xml_group->InsertEndChild(xml_joint);
    }
    xml_root->InsertEndChild(xml_group);
  }

  for (const auto& link : kinematics_information.link_groups)
  {
    tinyxml2::XMLElement* xml_group = doc.NewElement("group");
    xml_group->SetAttribute("name", link.first.c_str());
    for (const auto& link_name : link.second)  // <chain base_link="base_link" tip_link="tool0" />
    {
      tinyxml2::XMLElement* xml_link = doc.NewElement("link");
      xml_link->SetAttribute("name", link_name.c_str());
      xml_group->InsertEndChild(xml_link);
    }
    xml_root->InsertEndChild(xml_group);
  }

  for (const auto& rop : kinematics_information.group_rop_kinematics)
  {
    tinyxml2::XMLElement* xml_group_rop = doc.NewElement("group_rop");
    xml_group_rop->SetAttribute("group", rop.first.c_str());
    tinyxml2::XMLElement* xml_manip = doc.NewElement("manipulator");
    xml_manip->SetAttribute("group", rop.second.manipulator_group.c_str());
    xml_manip->SetAttribute("ik_solver", rop.second.manipulator_ik_solver.c_str());
    xml_manip->SetAttribute("reach", rop.second.manipulator_reach);
    xml_group_rop->InsertEndChild(xml_manip);

    tinyxml2::XMLElement* xml_positioner = doc.NewElement("positioner");
    xml_positioner->SetAttribute("group", rop.second.positioner_group.c_str());
    xml_positioner->SetAttribute("fk_solver", rop.second.positioner_fk_solver.c_str());
    for (const auto& pair : rop.second.positioner_sample_resolution)
    {
      tinyxml2::XMLElement* xml_joint = doc.NewElement("joint");
      xml_joint->SetAttribute("name", pair.first.c_str());
      xml_joint->SetAttribute("resolution", pair.second);
      xml_positioner->InsertEndChild(xml_joint);
    }
    xml_group_rop->InsertEndChild(xml_positioner);
    xml_root->InsertEndChild(xml_group_rop);
  }

  for (const auto& rep : kinematics_information.group_rep_kinematics)
  {
    tinyxml2::XMLElement* xml_group_rep = doc.NewElement("group_rep");
    xml_group_rep->SetAttribute("group", rep.first.c_str());
    tinyxml2::XMLElement* xml_manip = doc.NewElement("manipulator");
    xml_manip->SetAttribute("group", rep.second.manipulator_group.c_str());
    xml_manip->SetAttribute("ik_solver", rep.second.manipulator_ik_solver.c_str());
    xml_manip->SetAttribute("reach", rep.second.manipulator_reach);
    xml_group_rep->InsertEndChild(xml_manip);

    tinyxml2::XMLElement* xml_positioner = doc.NewElement("positioner");
    xml_positioner->SetAttribute("group", rep.second.positioner_group.c_str());
    xml_positioner->SetAttribute("fk_solver", rep.second.positioner_fk_solver.c_str());
    for (const auto& pair : rep.second.positioner_sample_resolution)
    {
      tinyxml2::XMLElement* xml_joint = doc.NewElement("joint");
      xml_joint->SetAttribute("name", pair.first.c_str());
      xml_joint->SetAttribute("resolution", pair.second);
      xml_positioner->InsertEndChild(xml_joint);
    }
    xml_group_rep->InsertEndChild(xml_positioner);
    xml_root->InsertEndChild(xml_group_rep);
  }

  for (const auto& group_state : kinematics_information.group_states)
  {
    for (const auto& joint_state : group_state.second)  // <chain base_link="base_link" tip_link="tool0" />
    {
      tinyxml2::XMLElement* xml_group_state = doc.NewElement("group_state");
      xml_group_state->SetAttribute("name", joint_state.first.c_str());
      xml_group_state->SetAttribute("group", group_state.first.c_str());

      for (const auto& joint : joint_state.second)
      {
        tinyxml2::XMLElement* xml_joint = doc.NewElement("joint");
        xml_joint->SetAttribute("name", joint.first.c_str());
        xml_joint->SetAttribute("value", joint.second);
        xml_group_state->InsertEndChild(xml_joint);
      }
      xml_root->InsertEndChild(xml_group_state);
    }
  }

  Eigen::IOFormat eigen_format(Eigen::StreamPrecision, Eigen::DontAlignCols, " ", " ");
  for (const auto& group_tcp : kinematics_information.group_tcps)
  {
    tinyxml2::XMLElement* xml_group_tcps = doc.NewElement("group_tcps");
    xml_group_tcps->SetAttribute("group", group_tcp.first.c_str());

    for (const auto& tcp : group_tcp.second)
    {
      tinyxml2::XMLElement* xml_tcp = doc.NewElement("tcp");
      xml_tcp->SetAttribute("name", tcp.first.c_str());

      std::stringstream xyz_string;
      xyz_string << tcp.second.translation().format(eigen_format);
      xml_tcp->SetAttribute("xyz", xyz_string.str().c_str());

      std::stringstream wxyz_string;
      Eigen::Quaterniond q(tcp.second.linear());
      wxyz_string << Eigen::Vector4d(q.w(), q.x(), q.y(), q.z()).format(eigen_format);

      xml_tcp->SetAttribute("wxyz", wxyz_string.str().c_str());
      xml_group_tcps->InsertEndChild(xml_tcp);
    }
    xml_root->InsertEndChild(xml_group_tcps);
  }

  for (const auto& group_opw : kinematics_information.group_opw_kinematics)
  {
    tinyxml2::XMLElement* xml_group_opw = doc.NewElement("group_opw");
    xml_group_opw->SetAttribute("group", group_opw.first.c_str());
    xml_group_opw->SetAttribute("a1", group_opw.second.a1);
    xml_group_opw->SetAttribute("a2", group_opw.second.a2);
    xml_group_opw->SetAttribute("b", group_opw.second.b);
    xml_group_opw->SetAttribute("c1", group_opw.second.c1);
    xml_group_opw->SetAttribute("c2", group_opw.second.c2);
    xml_group_opw->SetAttribute("c3", group_opw.second.c3);
    xml_group_opw->SetAttribute("c4", group_opw.second.c4);

    std::string offsets_string = std::to_string(group_opw.second.offsets[0]);
    std::string sign_corrections_string = std::to_string(group_opw.second.sign_corrections[0]);

    for (std::size_t i = 1; i < 6; ++i)
    {
      offsets_string += (" " + std::to_string(group_opw.second.offsets[i]));
      sign_corrections_string += (" " + std::to_string(group_opw.second.sign_corrections[i]));
    }

    xml_group_opw->SetAttribute("offsets", offsets_string.c_str());
    xml_group_opw->SetAttribute("sign_corrections", sign_corrections_string.c_str());

    xml_root->InsertEndChild(xml_group_opw);
  }

  for (const auto& entry : acm.getAllAllowedCollisions())
  {
    tinyxml2::XMLElement* xml_acm_entry = doc.NewElement("disable_collisions");
    xml_acm_entry->SetAttribute("link1", entry.first.first.c_str());
    xml_acm_entry->SetAttribute("link2", entry.first.second.c_str());
    xml_acm_entry->SetAttribute("reason", entry.second.c_str());
    xml_root->InsertEndChild(xml_acm_entry);
  }

  if (collision_margin_data != nullptr)
  {
    tinyxml2::XMLElement* xml_cm_entry = doc.NewElement("collision_margins");
    xml_cm_entry->SetAttribute("default_margin", collision_margin_data->getDefaultCollisionMargin());
    for (const auto& entry : collision_margin_data->getPairCollisionMargins())
    {
      tinyxml2::XMLElement* xml_cm_pair_entry = doc.NewElement("pair_margin");
      xml_cm_pair_entry->SetAttribute("link1", entry.first.first.c_str());
      xml_cm_pair_entry->SetAttribute("link2", entry.first.second.c_str());
      xml_cm_pair_entry->SetAttribute("margin", entry.second);
      xml_cm_entry->InsertEndChild(xml_cm_pair_entry);

      xml_root->InsertEndChild(xml_cm_entry);
    }
  }

  doc.InsertFirstChild(xml_root);
  tinyxml2::XMLError status = doc.SaveFile(file_path.c_str());
  if (status != tinyxml2::XMLError::XML_SUCCESS)
  {
    CONSOLE_BRIDGE_logError("Failed to save SRDF XML File: %s", file_path.c_str());
    return false;
  }

  return true;
}

void SRDFModel::clear()
{
  name = "undefined";
  version = { { 1, 0, 0 } };
  acm.clearAllowedCollisions();
  kinematics_information.clear();
  collision_margin_data = nullptr;
}

}  // namespace tesseract_srdf

max_stars_repo_name: jf---/tesseract

max_issues_repo_name: jf---/tesseract

max_forks_repo_name: jf---/tesseract


text:
/*
 * Copyright (c) 2016 Richard B Tilley <btilley@gatech.edu>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

// Standard Includes
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <map>
#include <queue>
#include <string>

// Crypto++
#include <cryptopp/sha.h>
#include <cryptopp/hex.h>
#include <cryptopp/pwdbased.h>  // for pbkdf2

// Boost
#include <boost/algorithm/string.hpp>  // for trims

// Local Includes
#include "global.hpp"
#include "jars.hpp"

const std::string do_PBKDF2( const std::string& sentence, const std::string& word )
{
    // Use sentence and word as input to PBKDF2
    // Return hex encoded PBKDF2
    char random_bytes[64];

    CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA512> pbkdf;
    pbkdf.DeriveKey(
                 // buffer that holds the derived key
                 (byte *)random_bytes,
                 // Length of derived key in bytes
                 64,
                 // purpose byte. unused by this PBKDF implementation.
                 0,
                 // sentence bytes (User provided)
                 (const byte *)sentence.data(),
                 sentence.size(),
                 // word bytes (User provided. This is salt)
                 (const byte *)word.data(),
                 word.size(),
                 // iteration count
                 32768,
                 0 );

    // Hex Encode
    std::string result;
    CryptoPP::HexEncoder hexencoder;
    hexencoder.Attach( new CryptoPP::StringSink( result ) );
    hexencoder.Put( (byte*)random_bytes, sizeof(random_bytes) );
    hexencoder.MessageEnd();

    return result;
}

const std::string get_passwd( const std::string& sentence, const std::string& word, const std::uint32_t len )
{
    // Get PBKDF2
    const std::string PBKDF2_hex = do_PBKDF2( sentence, word );

    // hex decode
    std::string raw_bytes;
    CryptoPP::HexDecoder hexdecoder;
    hexdecoder.Attach( new CryptoPP::StringSink( raw_bytes ) );
    hexdecoder.Put( (byte*)PBKDF2_hex.c_str(), PBKDF2_hex.size() );
    hexdecoder.MessageEnd();

    std::map<int, std::string> lower_map   = lower();
    std::map<int, std::string> upper_map   = upper();
    std::map<int, std::string> special_map = special();
    std::map<int, std::string> number_map  = numbers();

    std::queue<std::uint8_t> number_queue;

    std::string::const_iterator sit = raw_bytes.begin();
    for( sit = raw_bytes.begin(); sit != raw_bytes.end(); ++sit )
    {
        const std::uint8_t byte_number = reinterpret_cast<const std::uint8_t&>(*sit);
        number_queue.push( byte_number );

        if( DEBUG )
        {
            std::cout << "get_passwd() byte: " << (std::uint16_t)byte_number << "\n";
        }
    }

    // Randomly pick len-3 characters
    std::string result;
    std::uint32_t bits = 0;

    while( result.size() < (len-3) )
    {
        result += lower_map.find( number_queue.front() )->second;
        number_queue.pop();
        bit_strength( LOWER.size(), bits );
    }

    // Add special, upper and number
    result += special_map.find( number_queue.front() )->second;
    number_queue.pop();
    bit_strength( SPECIAL.size(), bits );

    result += upper_map.find( number_queue.front() )->second;
    number_queue.pop();
    bit_strength( UPPER.size(), bits );

    result += number_map.find( number_queue.front() )->second;
    number_queue.pop();
    bit_strength( NUMBERS.size(), bits );

    boost::trim( result );

    if( DEBUG )
    {
        std::cout << "get_passwd() bits: "             << bits                << "\n";
        std::cout << "get_passwd() result: "           << result              << "\n";
        std::cout << "get_passwd() LOWER size: "       << LOWER.size()        << "\n";
        std::cout << "get_passwd() UPPER size: "       << UPPER.size()        << "\n";
        std::cout << "get_passwd() NUMBERS size: "     << NUMBERS.size()      << "\n";
        std::cout << "get_passwd() SPECIAL size: "     << SPECIAL.size()      << "\n";
        std::cout << "get_passwd() lower_map size: "   << lower_map.size()    << "\n";
        std::cout << "get_passwd() upper_map size: "   << upper_map.size()    << "\n";
        std::cout << "get_passwd() special_map size: " << special_map.size()  << "\n";
        std::cout << "get_passwd() number_map size: "  << number_map.size()   << "\n";
        std::cout << "get_passwd() number_que size: "  << number_queue.size() << "\n";
        std::cout << "get_passwd() PBKDF2_hex: "       << PBKDF2_hex          << "\n";
        std::cout << "get_passwd() sentence: "         << sentence            << "\n";
        std::cout << "get_passwd() word: "             << word                << "\n";
        std::cout << "get_passwd() len: "              << len                 << "\n";
        std::cout << "----------------- "              << "\n";
    }

    return result;
}

const std::string get_passphrase( const std::string& sentence, const std::string& word, const std::uint32_t len )
{
    // Get PBKDF2
    const std::string PBKDF2_hex = do_PBKDF2( sentence, word );

    // hex decode
    std::string raw_bytes;
    CryptoPP::HexDecoder hexdecoder;
    hexdecoder.Attach( new CryptoPP::StringSink( raw_bytes ) );
    hexdecoder.Put( (byte*)PBKDF2_hex.c_str(), PBKDF2_hex.size() );
    hexdecoder.MessageEnd();

    std::map<int, std::string> word_map    = words();
    std::map<int, std::string> upper_map   = upper();
    std::map<int, std::string> special_map = special();
    std::map<int, std::string> number_map  = numbers();

    std::queue<std::uint8_t> number_queue;

    std::string::const_iterator sit = raw_bytes.begin();
    for( sit = raw_bytes.begin(); sit != raw_bytes.end(); ++sit )
    {
        const std::uint8_t byte_number = reinterpret_cast<const std::uint8_t&>(*sit);
        number_queue.push( byte_number );

        if( DEBUG )
        {
            std::cout << "get_passphrase() byte: " << (std::uint16_t)byte_number << "\n";
        }
    }

    // Randomly pick len words
    std::string result;
    std::uint32_t bits = 0;

    std::uint32_t i = 0;
    while( i < len )
    {
        result += word_map.find( number_queue.front() )->second;
        number_queue.pop();
        ++i;
        bit_strength( word_map.size(), bits );
    }

    // Add special, upper and number
    result += special_map.find( number_queue.front() )->second;
    number_queue.pop();
    bit_strength( SPECIAL.size(), bits );

    result += upper_map.find( number_queue.front() )->second;
    number_queue.pop();
    bit_strength( UPPER.size(), bits );

    result += number_map.find( number_queue.front() )->second;
    number_queue.pop();
    bit_strength( NUMBERS.size(), bits );

    boost::trim( result );

    if( DEBUG )
    {
        std::cout << "get_passphrase() bits: "             << bits                << "\n";
        std::cout << "get_passphrase() result: "           << result              << "\n";
        std::cout << "get_passphrase() WORDS size: "       << WORDS.size()        << "\n";
        std::cout << "get_passphrase() UPPER size: "       << UPPER.size()        << "\n";
        std::cout << "get_passphrase() NUMBERS size: "     << NUMBERS.size()      << "\n";
        std::cout << "get_passphrase() SPECIAL size: "     << SPECIAL.size()      << "\n";
        std::cout << "get_passphrase() word_map size: "    << word_map.size()     << "\n";
        std::cout << "get_passphrase() upper_map size: "   << upper_map.size()    << "\n";
        std::cout << "get_passphrase() special_map size: " << special_map.size()  << "\n";
        std::cout << "get_passphrase() number_map size: "  << number_map.size()   << "\n";
        std::cout << "get_passphrase() number_que size: "  << number_queue.size() << "\n";
        std::cout << "get_passphrase() PBKDF2_hex: "       << PBKDF2_hex          << "\n";
        std::cout << "get_passphrase() sentence: "         << sentence            << "\n";
        std::cout << "get_passphrase() word: "             << word                << "\n";
        std::cout << "get_passphrase() len: "              << len                 << "\n";
        std::cout << "--------------------- "              << "\n";
    }

    return result;
}

std::string readable( const std::string& password )
{
    std::uint32_t x = 0;
    std::string readablePassword = "";

    while( x < password.length() )
    {
        readablePassword += password.substr(x, 3) + " ";
        if (DEBUG)
        {
            std::cout << "readable() part: " << readablePassword << "\n";
        }
        x += 3;
    }

    boost::trim( readablePassword );

    if (DEBUG)
    {
        std::cout << "readable() password: "         << password         << "\n";
        std::cout << "readable() readablePassword: " << readablePassword << "\n";
    }

    return readablePassword;
}

max_stars_repo_name: tonyallan/dpg

max_issues_repo_name: tonyallan/dpg

max_forks_repo_name: tonyallan/dpg


text: #include <boost/smart_ptr/intrusive_ptr.hpp>


text:
// (c) 2012 by Fraunhofer IPK

#ifndef ZeissSeparationInterface_hpp
#define ZeissSeparationInterface_hpp

#include <string>
#include <vector>
#include <limits>
#include <boost/shared_array.hpp>
#include <stdint.h>

#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
#   ifdef ZeissSeparationInterface_EXPORTS
#      define API_ZeissSeparationInterface __declspec(dllexport)
#   else
#      define API_ZeissSeparationInterface __declspec(dllimport)
#   endif
#else
#   define API_ZeissSeparationInterface
#endif

#ifndef ZeissInterface_COMMON
#define ZeissInterface_COMMON

struct VolumeSize {
   unsigned int size[3];     // number of voxels in x, y and z direction.
   double voxel_size[3];     // size of one voxel in x, y and z direction in millimeters
};

struct Volume : public VolumeSize {
   const uint16_t* data;     // data block containing the voxel data. data is read only,
                             // and caller is responsible for memory management
};

struct OutVolume : public VolumeSize {
   boost::shared_array<uint16_t> data;  // data block of the result memory is owned by the shared_array.
};

struct Scaling {
   unsigned int factor[3];   // Scaling factor between original data and output.
};

#endif

struct VolumeHeader : public VolumeSize{
   unsigned int header_size;  // size of *.uint16_scv file header.
};

struct Parameter {
   Parameter() :
      max_memory(std::numeric_limits<size_t>::max()),
      min_part_size(5.0),
      min_part_volume(150.0),
      border_size(5.0),
      expand_mask(0),
      num_threads(1),
      histogram_analysis(true)
   {}

   size_t max_memory;          // maximal memory used, in byte
   double min_part_size;       // minimum size (edge length) of a part in mm
   double min_part_volume;     // minimum volume of a part in cubed mm
   double border_size;         // additional border around separated parts in mm
   size_t expand_mask;         // how many times to run a dilation on the mask
   size_t num_threads;         // how many threads should the separation algorithm use
   bool   histogram_analysis;  // calculate the histogram resolutions automatically (true), otherwise a extern threshold is needed!

};

struct ROI {
   unsigned int frontLowerLeft[3];  // the front lower left position (offset) of the region
   unsigned int backUpperRight[3];  // the back upper right position of the region
   uint32_t     index;              // index number of the region, corresponds to the part index in the mask volume
};

struct ZeissSeparationInterfaceInternalState; // Internal use only, fwd decl

struct API_ZeissSeparationInterface ZeissSeparationInterface {

   // reading the input from either ...
   // ... the provided memory.
   // NOTE: the Image data needs to stay valid until the separation is done!
   void setInputVolume( const Volume& v );

   // ... or from a *.vgi file.
   void setInputVolume( const std::string& vgi_filename );
   void setInputVolume( const char*        vgi_filename );

   // ... or from a *.uint16_scv file with known header informations
   void setInputVolume( const std::string& uint16_scv_filename, const VolumeHeader headerinfo );
   void setInputVolume( const char*        uint16_scv_filename, const VolumeHeader headerinfo );

   // set algorithm parameters.
   // optional defaults are
   //   max_memory = unlimited
   //   min_part_size = 5mm
   //   min_part_volume = 150mm^3;
   //   border_size = 5mm;
   void setParameter( const Parameter& p );

   // Alternative 1: fully automatic calculation of the separation in one step
   void doSeparation();

   // Alternative 2: two step separation with the possibility to manually override the threshold
   double getThreshold();
   void doSeparation(double threshold);  // threshold needs to be inside the [0.0, 1.0] range

   // retrieve results either ...

   // ... for further processing
   // get the mask Volume
   OutVolume getMaskVolume() const;
   // get the list of Regions of interest. By default the individual ROIs
   // use the same dimensions as the output volume. The optional boolean parameter
   // can be used to get the regions in the (higher) input volume dimensions.
   std::vector<ROI> getROIs(bool useOriginalVolumeSize = false) const;
   // get the detected background-peak value
   uint16_t getBackgroundPeakValue() const;
   // get the mask scaling in x, y and z direction
   Scaling getMaskScaling() const;

   // ... or save them directly to disk
   void saveParts(const std::string& filename = "");
   void saveParts(const char*        filename = "");

   // get algorithms current calculation state or cancel it
   // for this to work/make sense doSegmentation() and getMaterialRegions()
   // need to be started in a thread.
   double progress() const;  // returns progress, normalized to [0..1]
   void cancel();            // do not do any further processing on this instance after calling cancel().

   // Lifecycle
   ZeissSeparationInterface();
   ~ZeissSeparationInterface();

   // internal
   private:
      // can not be copied!
      ZeissSeparationInterface(const ZeissSeparationInterface&);
      ZeissSeparationInterface& operator=(const ZeissSeparationInterface&);

      ZeissSeparationInterfaceInternalState* m_pState;
};

/*
void usageExample1() {

   // 1. introduce the interface
   ZeissSeparationInterface separation;

   // 2. Read input dataset from a file with the name of input.vgi
   separation.setInputVolume("input.vgi");

   // 3. This step is optional, you only need it if you want to override the defaults.
   Parameter param;
      param.max_memory = 2048 * 1024 * 1024;
   separation.setParameter(param);

   // 4. This does the real work and takes the longest time.
   // can be started in a different thread.
   separation.doSeparation();

   // 5. save the results int separate files following the schema output_part0.vgi, output_part1.vgi, ...
   separation.saveParts("output.vgi");
}

void usageExample2() {

   // 1. introduce the interface
   ZeissSeparationInterface separation;

   // 2. Pass input datasets memory location. Will be left unmodified!
   Volume volume;
      volume.data = <YourDatasMemoryLocation>;
      volume.size[0] = <InputWidth>;
      volume.size[1] = <InputHeight>;
      volume.size[2] = <InputDepth>;
      volume.voxel_size[0] = volume.voxel_size[1] = volume.voxel_size[2] = <voxel_size in mm>;

   separation.setInputVolume(volume);

   // 3. This step is optional, you only need it if you want to override the defaults.
   Parameter param;
      param.max_memory = static_cast<size_t>(2048) * 1024 * 1024;
   separation.setParameter(param);

   // 4. This does the real work and takes the longest time.
   // can be started in a different thread.
   separation.doSeparation();

   // 5. get the results for further processing.
   std::vector<ROI> ROIs = separation.getROIs();
   OutVolume mask = separation.getMaskVolume();

   // the data in mask.data stays valid as long as one shared pointer to it is held!
   // no explicit cleanup is needed.
}

void usageExample3 {

   // 1. introduce the interface
   ZeissSeparationInterface separation;

   // 2. Pass input datasets memory location. Will be left unmodified!
   Volume volume;
   volume.data = <YourDatasMemoryLocation>;
   volume.size[0] = <InputWidth>;
   volume.size[1] = <InputHeight>;
   volume.size[2] = <InputDepth>;
   volume.voxel_size[0] = volume.voxel_size[1] = volume.voxel_size[2] = <voxel_size in mm>;

   separation.setInputVolume(volume);

   // 3. This step is optional, you only need it if you want to override the defaults.
   Parameter param;
   param.max_memory = static_cast<size_t>(2048) * 1024 * 1024;
   separation.setParameter(param);

   // 4. This does the real work and takes the longest time.
   // can be started in a different thread.
   double threshold = separation.getThreshold();

   let_the_user_change_the_proposed_threshold(threshold);

   separation.doSeparation(threshold);

   // 5. get the results for further processing.
   std::vector<ROI> ROIs = separation.getROIs();
   OutVolume mask = separation.getMaskVolume();
   uint16 backgroundpeakvalue = separation.getBackgroundPeakValue();

   // Simplified pseudo-code example on what to do with the Output.
   // copies each individual part to its own memory location (without scaling)
   for(auto ROI = ROIs.begin(), endROI = ROIs.end(); ROI != endROI; ++ROI) {

      uint16* partVolume = allocate_new_memoryregion(calc_memory_size(*ROI));

      for(unsigned int z = ROI->frontLowerLeft[2]; z < ROI->backUpperRight[2]; ++z ) {
         for(unsigned int y = ROI->frontLowerLeft[1]; y < ROI->backUpperRight[1]; ++y ) {
            for(unsigned int x = ROI->frontLowerLeft[0]; x < ROI->backUpperRight[0]; ++x ) {
               if (mask.data[calc_position(x,y,z)] == ROI->index || mask.data[calc_position(x,y,z)] == 0) {
                  partVolume[calc_out_position(*ROI, x,y,z)] = volume.data[calc_position(x,y,z)];
               } else {
                  partVolume[calc_out_position(*ROI, x,y,z)] = backgroundpeakvalue;
               }
            }
         }
      }

      pass_part_volume_somewhere_else(partVolume);
   }

   return;
}
*/

#endif

max_stars_repo_name: avinfinity/UnmanagedCodeSnippets

max_issues_repo_name: avinfinity/UnmanagedCodeSnippets

max_forks_repo_name: avinfinity/UnmanagedCodeSnippets


text:
//  Copyright (c) 2005-2007 Andre Merzky (andre@merzky.net)
//  Copyright (c) 2005-2009 Hartmut Kaiser
//  Copyright (c) 2005 Michel Zandstra (michelzandstra@gmail.com)
//
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
//  job LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef SAGA_IMPL_ENGINE_PROXY_HPP
#define SAGA_IMPL_ENGINE_PROXY_HPP

#include <map>

#include <boost/thread/thread.hpp>
#include <boost/thread/recursive_mutex.hpp>

#include <saga/saga/uuid.hpp>
#include <saga/impl/runtime.hpp>

// include CPI's
#include <saga/impl/config.hpp>
#include <saga/impl/engine/cpi.hpp>
#include <saga/impl/engine/engine.hpp>
#include <saga/impl/engine/session.hpp>
#include <saga/impl/engine/cpi_list.hpp>
#include <saga/impl/exception_list.hpp>

#include <saga/saga/adaptors/instance_data_base.hpp>

///////////////////////////////////////////////////////////////////////////////
namespace saga { namespace impl {

    enum run_mode
    {
        Unknown     = -1,
        Sync_Sync   =  0,
        Sync_Async  =  1,
        Async_Sync  =  2,
        Async_Async =  3
    };

  /**
   * The base class of all proxy classes
   *
   * Contains functions to handle the shared adaptor data objects,
   * and a pointer to the session handle
   */
  class proxy
    : public saga::impl::object
  {
    protected:
      typedef v1_0::preference_type preference_type;
      typedef v1_0::cpi cpi;

      typedef TR1::shared_ptr<v1_0::cpi> cpi_type;

    private:
      saga::session session_;

    public:
      typedef boost::recursive_mutex mutex_type;
      cpi_list cpis_;

    protected:
      // instance data
      mutex_type instance_data_mtx_;
      TR1::shared_ptr<adaptors::instance_data_base> instance_data_;

    public:
      /** constructor */
      explicit proxy (saga::object::type type, saga::session const& session)
      :   object(type), session_(session)
      {
      }

      /** destructor */
      virtual ~proxy (void)
      {
          release_cpis();
      }

      void release_cpis()
      {
          mutex_type::scoped_lock lock(mtx_);

          // Clear dangling pointers. We're relinquishing ownership of the cpi.
          cpi_list::iterator end = cpis_.end();

          for (cpi_list::iterator it = cpis_.begin(); it != end; ++it)
          {
              (*it)->proxy_ = 0;
          }

          cpis_.clear();
      }

      saga::session& get_session() { return session_; }
      saga::session const& get_session() const { return session_; }

      std::string get_cpi_name (void) const
      {
        return saga::adaptors::get_cpi_name(this->get_type());
      }

      /**
       * Asks Saga engine for a new adaptor of type CpiType, that
       * matches the description table. If file was already bound to an
       * adaptor, it is destroyed first. UNLESS this adaptor has fixed
       * itself. In that case, instead of creating a new adaptor, file
       * simply uses this fixed one.
       *
       * @param table a description table describing the adaptor needed
       */
      SAGA_EXPORT bool get_adaptor (std::string     const & cpi_name,
                                    std::string     const & op_name,
                                    preference_type const & prefs,
                                    adaptor_selector::adaptor_info_list_type & no_no_list,
                                    v1_0::op_info         & oi);

      /**
       * Asks the Saga engine, whether the given adaptor supports a certain
       * operation.
       */
      SAGA_EXPORT bool test_adaptor (cpi_type                cpi,
                                     std::string     const & cpi_name,
                                     std::string     const & op_name,
                                     preference_type const & prefs,
                                     v1_0::op_info         & oi);

      // find out, which execution type a given adaptor prefers to be used
      SAGA_EXPORT run_mode test_adaptor_helper (cpi_type            cpi,
                                                std::string     const & cpi_name,
                                                std::string     const & call_name,
                                                preference_type const & prefs,
                                                bool                    is_sync,
                                                v1_0::op_info         & oi);

      /////////////////////////////////////////////////////////////////////////
      //  Helper function to be called from inside the implementation object's
      //  constructor. It creates and initializes a new CPI instance
      SAGA_EXPORT bool initcpi (std::string  const& cpi_name);

      // create a new CPI instance, and figure out what execution preferences
      // this CPI has for the given function.
      //
      // This function gets called for every CPI function to be called,
      // whenever the CPI was newly created for this CPI call.
      SAGA_EXPORT run_mode get_adaptor_helper (std::string     const & cpi_name,
                                               std::string     const & call_name,
                                               preference_type const & prefs,
                                               bool                    is_sync,
                                               adaptor_selector::adaptor_info_list_type & no_no_list,
                                               v1_0::op_info         & oi);

      // create a new CPI instance, and figure out what execution preferences
      // this CPI has for the given function
      SAGA_EXPORT run_mode get_adaptor_for_init (std::string     const & cpi_name,
                                                 preference_type const & prefs,
                                                 adaptor_selector::adaptor_info_list_type & no_no_list,
                                                 v1_0::op_info         & oi);

      /////////////////////////////////////////////////////////////////////////
      //  This is the main 'API' function for adaptor selection and
      //  preparation.
      //
      //  select_run_mode() is called for every API function to bind an
      //  appropriate cpi instance claiming to be able to handle the request.
      SAGA_EXPORT run_mode select_run_mode (std::string     const & cpi_name,
                                            std::string     const & call_name,
                                            preference_type const & prefs,
                                            bool                    is_sync,
                                            adaptor_selector::adaptor_info_list_type & no_no_list,
                                            v1_0::op_info         & oi);

      /////////////////////////////////////////////////////////////////////////
      //  This returns the type of the first attached CPI instance object
      SAGA_EXPORT saga::object::type get_cpitype (void) const;

      /////////////////////////////////////////////////////////////////////////
      // handle API object instance data
      SAGA_EXPORT TR1::shared_ptr<adaptors::instance_data_base>
          register_instance_data (TR1::shared_ptr <adaptors::instance_data_base> o);

      SAGA_EXPORT void release_instance_data (void);

      SAGA_EXPORT TR1::shared_ptr<adaptors::instance_data_base>
          check_out_instance_data (void);

      SAGA_EXPORT void check_in_instance_data();

      /////////////////////////////////////////////////////////////////////////
      //  helper for enable_shared_from_this support
      SAGA_EXPORT TR1::shared_ptr<proxy      > shared_from_this();
      SAGA_EXPORT TR1::shared_ptr<proxy const> shared_from_this() const;

  }; // class proxy

  /////////////////////////////////////////////////////////////////////////////
}} // namespace saga::impl

#include <saga/impl/engine/run_mode_wrapper.hpp>

#endif // SAGA_IMPL_ENGINE_PROXY_HPP

max_stars_repo_name: saga-project/saga-cpp

max_issues_repo_name: saga-project/saga-cpp

max_forks_repo_name: saga-project/saga-cpp


text:
/*
 * test_export.cpp
 *
 *  Created on: 2018-2-10
 *      Author: fasiondog
 */

#ifdef TEST_ALL_IN_ONE
    #include <boost/test/unit_test.hpp>
#else
    #define BOOST_TEST_MODULE test_hikyuu_trade_sys_suite
    #include <boost/test/unit_test.hpp>
#endif

#include <hikyuu/config.h>

#if HKU_SUPPORT_SERIALIZATION

#include <fstream>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <hikyuu/StockManager.h>
#include <hikyuu/trade_sys/selector/crt/SE_Fixed.h>
#include <hikyuu/trade_sys/system/crt/SYS_Simple.h>

using namespace hku;

/**
 * @defgroup test_selector_serialization test_selector_serialization
 * @ingroup test_hikyuu_trade_sys_suite
 * @{
 */

/** @par 检测点 */
BOOST_AUTO_TEST_CASE( test_SE_FIXED_export ) {
    StockManager& sm = StockManager::instance();
    string filename(sm.tmpdir());
    filename += "/SE_FIXED.xml";

    SYSPtr sys = SYS_Simple();
    StockList stkList;
    stkList.push_back(sm["sh600000"]);
    stkList.push_back(sm["sz000001"]);

    SEPtr se1 = SE_Fixed(stkList, sys);
    {
        std::ofstream ofs(filename);
        boost::archive::xml_oarchive oa(ofs);
        oa << BOOST_SERIALIZATION_NVP(se1);
    }

    SEPtr se2;
    {
        std::ifstream ifs(filename);
        boost::archive::xml_iarchive ia(ifs);
        ia >> BOOST_SERIALIZATION_NVP(se2);
    }

    BOOST_CHECK(se1->name() == se2->name());
}

/** @} */

#endif /* HKU_SUPPORT_SERIALIZATION */

max_stars_repo_name: waruqi/hikyuu

max_forks_repo_name: archya/hikyuu


text:
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_IMAGE_VIEW_HPP
#define BOOST_GIL_IMAGE_VIEW_HPP

#include <boost/gil/iterator_from_2d.hpp>

#include <cstddef>
#include <iterator>

namespace boost { namespace gil {

////////////////////////////////////////////////////////////////////////////////////////
/// \class image_view
/// \ingroup ImageViewModel PixelBasedModel
/// \brief A lightweight object that interprets memory as a 2D array of pixels. Models ImageViewConcept,PixelBasedConcept,HasDynamicXStepTypeConcept,HasDynamicYStepTypeConcept,HasTransposedTypeConcept
///
/// Image view consists of a pixel 2D locator (defining the mechanism for navigating in 2D)
/// and the image dimensions.
///
/// Image views to images are what ranges are to STL containers. They are lightweight objects,
/// that don't own the pixels. It is the user's responsibility that the underlying data remains
/// valid for the lifetime of the image view.
///
/// Similar to iterators and ranges, constness of views does not extend to constness of pixels.
/// A const \p image_view does not allow changing its location in memory (resizing, moving) but does
/// not prevent one from changing the pixels. The latter requires an image view whose value_type
/// is const.
///
/// Images have interfaces consistent with STL 1D random access containers, so they can be used
/// directly in STL algorithms like:
/// \code
///  std::fill(img.begin(), img.end(), red_pixel);
/// \endcode
///
/// In addition, horizontal, vertical and 2D random access iterators are provided.
///
/// Note also that \p image_view does not require that its element type be a pixel. It could be
/// instantiated with a locator whose \p value_type models only \p Regular. In this case the image
/// view models the weaker RandomAccess2DImageViewConcept, and does not model PixelBasedConcept.
/// Many generic algorithms don't require the elements to be pixels.
///
////////////////////////////////////////////////////////////////////////////////////////
template <typename Loc>     // Models 2D Pixel Locator
class image_view {
public:

// typedefs required by ConstRandomAccessNDImageViewConcept
    static const std::size_t num_dimensions=2;
    typedef typename Loc::value_type                 value_type;
    typedef typename Loc::reference                  reference;       // result of dereferencing
    typedef typename Loc::coord_t                    coord_t;      // 1D difference type (same for all dimensions)
    typedef coord_t                                  difference_type; // result of operator-(1d_iterator,1d_iterator)
    typedef typename Loc::point_t                    point_t;
    typedef Loc                                      locator;
    typedef image_view<typename Loc::const_t>        const_t;      // same as this type, but over const values
    template <std::size_t D> struct axis {
        typedef typename Loc::template axis<D>::coord_t  coord_t;     // difference_type along each dimension
        typedef typename Loc::template axis<D>::iterator iterator;       // 1D iterator type along each dimension
    };
    typedef iterator_from_2d<Loc>                    iterator;       // 1D iterator type for each pixel left-to-right inside top-to-bottom
    typedef typename const_t::iterator               const_iterator;  // may be used to examine, but not to modify values
    typedef typename const_t::reference              const_reference; // behaves as a const reference
    typedef typename std::iterator_traits<iterator>::pointer pointer; // behaves as a pointer to the value type
    typedef std::reverse_iterator<iterator>          reverse_iterator;
    typedef std::size_t                              size_type;

// typedefs required by ConstRandomAccess2DImageViewConcept
    typedef locator                                  xy_locator;
    typedef typename xy_locator::x_iterator          x_iterator;     // pixel iterator along a row
    typedef typename xy_locator::y_iterator          y_iterator;     // pixel iterator along a column
    typedef typename xy_locator::x_coord_t           x_coord_t;
    typedef typename xy_locator::y_coord_t           y_coord_t;

    template <typename Deref> struct add_deref {
        typedef image_view<typename Loc::template add_deref<Deref>::type> type;
        static type make(const image_view<Loc>& iv, const Deref& d) { return type(iv.dimensions(), Loc::template add_deref<Deref>::make(iv.pixels(),d)); }
    };

    image_view() : _dimensions(0,0) {}
    template <typename View> image_view(const View& iv)                                    : _dimensions(iv.dimensions()), _pixels(iv.pixels()) {}

    template <typename L2> image_view(const point_t& sz            , const L2& loc)        : _dimensions(sz),          _pixels(loc) {}
    template <typename L2> image_view(coord_t width, coord_t height, const L2& loc)        : _dimensions(x_coord_t(width),y_coord_t(height)), _pixels(loc) {}

    template <typename View> image_view& operator=(const View& iv)  { _pixels=iv.pixels(); _dimensions=iv.dimensions(); return *this; }
    image_view& operator=(const image_view& iv)                     { _pixels=iv.pixels(); _dimensions=iv.dimensions(); return *this; }

    template <typename View> bool operator==(const View& v) const   { return pixels()==v.pixels() && dimensions()==v.dimensions(); }
    template <typename View> bool operator!=(const View& v) const   { return !(*this==v); }

    template <typename L2> friend void swap(image_view<L2>& x, image_view<L2>& y);

    /// \brief Exchanges the elements of the current view with those of \a other
    ///       in constant time.
    ///
    /// \note Required by the Collection concept
    /// \see  https://www.boost.org/libs/utility/Collection.html
    void swap(image_view<Loc>& other)
    {
        using boost::gil::swap;
        swap(*this, other);
    }

    /// \brief Returns true if the view has no elements, false otherwise.
    ///
    /// \note Required by the Collection concept
    /// \see  https://www.boost.org/libs/utility/Collection.html
    bool empty() const { return !(width() > 0 && height() > 0); }

    /// \brief Returns a reference to the first element in raster order.
    ///
    /// \note Required by the ForwardCollection, since view model the concept.
    /// \see  https://www.boost.org/libs/utility/Collection.html
    reference front() const { return *begin(); }

    /// \brief Returns a reference to the last element in raster order.
    ///
    /// \note Required by the ForwardCollection, since view model the concept.
    /// \see  https://www.boost.org/libs/utility/Collection.html
    reference back() const { return *rbegin(); }

    const point_t&   dimensions()            const { return _dimensions; }
    const locator&   pixels()                const { return _pixels; }
    x_coord_t        width()                 const { return dimensions().x; }
    y_coord_t        height()                const { return dimensions().y; }
    std::size_t      num_channels()          const { return gil::num_channels<value_type>::value; }
    bool             is_1d_traversable()     const { return _pixels.is_1d_traversable(width()); }

    //\{@
    /// \name 1D navigation
    size_type           size()               const { return width()*height(); }
    iterator            begin()              const { return iterator(_pixels,_dimensions.x); }
    iterator            end()                const { return begin()+(difference_type)size(); }    // potential performance problem!
    reverse_iterator    rbegin()             const { return reverse_iterator(end()); }
    reverse_iterator    rend()               const { return reverse_iterator(begin()); }
    reference operator[](difference_type i)  const { return begin()[i]; }        // potential performance problem!
    iterator            at(difference_type i)const { return begin()+i; }
    iterator            at(const point_t& p) const { return begin()+p.y*width()+p.x; }
    iterator            at(x_coord_t x, y_coord_t y)const { return begin()+y*width()+x; }

    //\}@

    //\{@
    /// \name 2-D navigation
    reference operator()(const point_t& p)        const { return _pixels(p.x,p.y); }
    reference operator()(x_coord_t x, y_coord_t y)const { return _pixels(x,y); }
    template <std::size_t D> typename axis<D>::iterator axis_iterator(const point_t& p) const { return _pixels.template axis_iterator<D>(p); }
    xy_locator xy_at(x_coord_t x, y_coord_t y)    const { return _pixels+point_t(x_coord_t(x),y_coord_t(y)); }
    locator    xy_at(const point_t& p)            const { return _pixels+p; }
    //\}@

    //\{@
    /// \name X navigation
    x_iterator x_at(x_coord_t x, y_coord_t y)     const { return _pixels.x_at(x,y); }
    x_iterator x_at(const point_t& p)             const { return _pixels.x_at(p); }
    x_iterator row_begin(y_coord_t y)             const { return x_at(0,y); }
    x_iterator row_end(y_coord_t y)               const { return x_at(width(),y); }
    //\}@

    //\{@
    /// \name Y navigation
    y_iterator y_at(x_coord_t x, y_coord_t y)     const { return xy_at(x,y).y(); }
    y_iterator y_at(const point_t& p)             const { return xy_at(p).y(); }
    y_iterator col_begin(x_coord_t x)             const { return y_at(x,0); }
    y_iterator col_end(x_coord_t x)               const { return y_at(x,height()); }
    //\}@

private:
    template <typename L2> friend class image_view;

    point_t    _dimensions;
    xy_locator _pixels;
};

template <typename L2>
inline void swap(image_view<L2>& x, image_view<L2>& y) {
    using std::swap;
    swap(x._dimensions,y._dimensions);
    swap(x._pixels, y._pixels);            // TODO: Extend further
}

/////////////////////////////
//  PixelBasedConcept
/////////////////////////////

template <typename L>
struct channel_type<image_view<L> > : public channel_type<L> {};

template <typename L>
struct color_space_type<image_view<L> > : public color_space_type<L> {};

template <typename L>
struct channel_mapping_type<image_view<L> > : public channel_mapping_type<L> {};

template <typename L>
struct is_planar<image_view<L> > : public is_planar<L> {};

/////////////////////////////
//  HasDynamicXStepTypeConcept
/////////////////////////////

template <typename L>
struct dynamic_x_step_type<image_view<L> > {
    typedef image_view<typename dynamic_x_step_type<L>::type> type;
};

/////////////////////////////
//  HasDynamicYStepTypeConcept
/////////////////////////////

template <typename L>
struct dynamic_y_step_type<image_view<L> > {
    typedef image_view<typename dynamic_y_step_type<L>::type> type;
};

/////////////////////////////
//  HasTransposedTypeConcept
/////////////////////////////

template <typename L>
struct transposed_type<image_view<L> > {
    typedef image_view<typename transposed_type<L>::type> type;
};

}}  // namespace boost::gil

#endif


text:
#include "nodes/NodeExpression.h"

#include <string>

#include <boost/variant/recursive_variant.hpp>
#include <boost/variant/apply_visitor.hpp>

#include "Data.h"
#include "Inlet.h"
#include "Outlet.h"
#include "Pipeline.h"
//

using namespace std;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

namespace hm
{
	namespace expression
	{
		/// Evaluator visits an abstract syntax tree created from a parse
		/// and evaluates its outcome.
		struct Evaluator
		{
			typedef Data result_type;
			double timestamp;
			std::vector<std::string> errors;

			Evaluator(double timestamp_)
			: timestamp(timestamp_)
			{}

			Data operator()(Empty) const
			{
//				BOOST_ASSERT(false);
				cerr << "ERROR: Empty passed into Evaluator"<<endl;
				return Data();
			}

			Data operator()(double const& x) const
			{
				return Data(Value(x, timestamp));
			}

			Data operator()(Vec3 const& v)
			{
				Data x = boost::apply_visitor(*this, v.x);
				Data y = boost::apply_visitor(*this, v.y);
				Data z = boost::apply_visitor(*this, v.z);
				if (x.isValue() && y.isValue() && z.isValue())
					return Point3d(x.asValue(), y.asValue(), z.asValue());
				else
				{
					char errorComponent =
					!x.isValue()? 'x' :
					!y.isValue()? 'y' :
					'z';
					BOOST_ASSERT(errorComponent!='z' || !z.isValue());
					errors.push_back(string("Cannot construct vector as ")
									 +errorComponent+
									 " component is not a scalar Value (types are x: "
									 + to_string(x.type()) + ", y: "
									 + to_string(y.type()) + ", z: "
									 + to_string(z.type()) + ").");
					return Data();
				}
			}

			Data operator()(Data const& x) const
			{
				return x;
			}

			Data operator()(InletPtr const& i) const
			{
				return i->data();
			}

			Data operator()(Data const& lhs, Operation const& op)
			{
				Data rhs = boost::apply_visitor(*this, op.operand);
				switch (op.operator_)
				{
					case '+':
						if (lhs.canAdd(rhs))
						{
							return lhs + rhs;
						}
						else
						{
							return failWithOp("add", lhs, rhs);
						}
					case '-':
						return lhs.canSubtract(rhs)? lhs-rhs : failWithOp("subtract", lhs, rhs);
					case '*':
						return lhs.canMultiply(rhs)? lhs*rhs : failWithOp("multiply", lhs, rhs);
					case '/':
						return lhs.canDivide(rhs)? lhs/rhs : failWithOp("divide", lhs, rhs);
				}
				BOOST_ASSERT_MSG(false, ("Invalid binary operator character "+to_string(op.operator_)).c_str());
				return Data();
			}

			Data operator()(double lhs_, Operation const& op)
			{
				Data lhs(Value(lhs_, timestamp));
				Data rhs = boost::apply_visitor(*this, op.operand);
				switch (op.operator_)
				{
					case '+':
						if (lhs.canAdd(rhs))
						{
							return lhs + rhs;
						}
						else
						{
							return failWithOp("add", lhs, rhs);
						}
					case '-':
						return lhs.canSubtract(rhs)? lhs-rhs : failWithOp("subtract", lhs, rhs);
					case '*':
						return lhs.canMultiply(rhs)? lhs*rhs : failWithOp("multiply", lhs, rhs);
					case '/':
						return lhs.canDivide(rhs)? lhs/rhs : failWithOp("divide", lhs, rhs);
				}
				BOOST_ASSERT_MSG(false, ("Invalid binary operator character "+to_string(op.operator_)).c_str());
				return Data();
			}

			Data operator()(Signed const& x)
			{
				Data rhs = boost::apply_visitor(*this, x.operand);
				switch (x.sign)
				{
					case '-': return -rhs;
					case '+': return rhs;
				}
				BOOST_ASSERT_MSG(false, ("Invalid unary operator character "+to_string(x.sign)).c_str());
				return Data();
			}

			Data operator()(Expression const& x)
			{
				Data state = boost::apply_visitor(*this, x.first);
				for(Operation const& op: x.rest)
				{
					state = (*this)(state, op);
				}
				return state;
			}

			Data operator()(Output const& out)
			{
				Data rhs = (*this)(out.expression);
				if (!rhs.isNull())
				{
					out.outlet->outputNewData(rhs);
				}
				return rhs;
			}

			Data operator()(Program const& x)
			{
				return boost::apply_visitor(*this, x.statement);
			}

		private:
			Data failWithOp(std::string const& opName, Data const& lhs, Data const& rhs)
			{
				errors.push_back("Cannot "+opName+" a "+to_string(lhs.type())+" to a "+to_string(rhs.type()));
				return Data();
			}
		};

	} // namespace expression

	NodeExpression::NodeExpression(Node::Params params, string className)
	: NodeUnthreaded(params, className, "Expression", "Write a mathematical expression to define how input is transformed into output.")
	, mGrammar(new expression::Grammar<string::const_iterator>)
	, mProgram(new expression::Program)
	, mIsValid(false)
	, mLastTimestamp(-42.)
	, mDebugPrint(false)
	, mRequestedNumInlets(1)
	, mRequestedNumOutlets(1)
	, mIsReplacingThisNode(false)
	{
		auto numInletsParam = addParameter("Number of inlets", &mRequestedNumInlets);
		numInletsParam->addNewExternalValueCallback([this](){
			this->letCountsChangedCallback();
		});
		numInletsParam->setBounds(0, 100, 0, 100);

		auto numOutletsParam = addParameter("Number of outlets", &mRequestedNumOutlets);
		numOutletsParam->addNewExternalValueCallback([this](){
			this->letCountsChangedCallback();
		});
		numOutletsParam->setBounds(0, 100, 0, 100);

		addParameter("Expression", &mExpression)->addNewExternalValueCallback([this](){
			this->expressionChangedCallback();
		});
//		addParameter("Print final expression (debug)", &mDebugPrint);
		setLetCounts(mRequestedNumInlets, mRequestedNumOutlets);
		expressionChangedCallback();
	}

	NodePtr NodeExpression::create(Node::Params params) const
	{
		return NodePtr(new NodeExpression(params));
	}

	bool NodeExpression::setExpression(std::string const& expression)
	{
		mExpression = expression;
		expressionChangedCallback();
		return mIsValid;
	}

	void NodeExpression::setLetCounts(int inletCount, int outletCount)
	{
		assert(mRequestedNumInlets >= 0 && mRequestedNumOutlets >= 0);
		{
			int i = numInlets();
			while (i > mRequestedNumInlets)
			{
				i--;
				InletPtr inlet_ = inlet(i);
				assert(inlet_);
				if (inlet_)
				{
					removeInlet(inlet_);
				}
			}
			while (i < mRequestedNumInlets)
			{
				string name = "i"+to_string(i+1);
				InletPtr inlet = createInlet(ALL_TYPES, "Input "+name, "Scalar values inputted here here may be used as \""+name+"\" in your expression.");
				i++;
			}
		}
		{
			int i = numOutlets();
			while (i > mRequestedNumOutlets)
			{
				i--;
				OutletPtr outlet_ = outlet(i);
				assert(outlet_);
				if (outlet_)
				{
					removeOutlet(outlet_);
				}
			}
			while (i < mRequestedNumOutlets)
			{
				string name = "o"+to_string(i+1);
				OutletPtr outlet = createOutlet(ALL_TYPES, "Output "+name, "Output here here may be written to as \""+name+"\" in your expression.");
				i++;
			}
		}

		// Update symbol table in mGrammar

		mGrammar->inlets.clear();
		{
			int i=0;
			for (InletPtr inlet: inlets())
			{
				string name = "i"+to_string(i+1);
				mGrammar->inlets.add(name.c_str(), inlet);
				i++;
			}
		}
		{
			int i=0;
			for (OutletPtr outlet: outlets())
			{
				string name = "o"+to_string(i+1);
				mGrammar->outlets.add(name.c_str(), outlet);
				i++;
			}
		}
	}

	void NodeExpression::expressionChangedCallback()
	{
		if (mIsReplacingThisNode)
		{
			return;
		}
		auto iter = mExpression.cbegin();
		mIsValid = qi::phrase_parse(iter, mExpression.cend(), *mGrammar, ascii::space, *mProgram);
		mIsValid = mIsValid && iter == mExpression.cend();
		if (mIsValid)
		{
			hm_debug("Expression "+mExpression+" parsed successfully.");
		}
		else
		{
			hm_debug("Failed to parse "+mExpression);
		}
	}

	void NodeExpression::letCountsChangedCallback()
	{
		// Note that this callback is triggered by updateParameters
		// which will not happen concurrently with step()
		setLetCounts(mRequestedNumInlets, mRequestedNumOutlets);
	}

	void NodeExpression::step()
	{
		if (mIsValid)
		{
			// check if any new data has arrived
			double t = 0.;
			for (int i=0; i<numInlets(); i++)
			{
				t = max(t, inlet(i)->dataTimestamp());
			}
			if (t > mLastTimestamp)
			{
				expression::Evaluator evaluator(t);
				Data outcome = evaluator(*mProgram);
				if (mDebugPrint)
				{
					cout << t << " :" << outcome << endl;
				}
				if (evaluator.errors.size())
				{
					cout << "Evaluation errors: \n";
					for(string error: evaluator.errors)
					{
						cout << error << ". ";
					}
					cout << endl;
				}
				mLastTimestamp = t;
			}
		}
	}

}

max_stars_repo_name: timmb/HarmonicMotion

max_issues_repo_name: timmb/HarmonicMotion

max_forks_repo_name: timmb/HarmonicMotion