text:
// Copyright 2015 Christian Aichinger <Greek0@gmx.net>
//
// 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
//
// 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 <string>
#include <iostream>

#include "../include/rastermap.h"

#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(rastermap)

static std::wstring empty_wstr(L"");

class MockGeoDrawable : public GeoDrawable {
public:
    virtual ~MockGeoDrawable() {};
    virtual bool
    PixelToLatLon(const MapPixelCoord &pos, LatLon *result) const {
        return false;
    }
    virtual bool
    LatLonToPixel(const LatLon &pos, MapPixelCoord *result) const {
        return false;
    }

    virtual DrawableType GetType() const { return TYPE_MAP; }
    virtual unsigned int GetWidth() const { return 64; }
    virtual unsigned int GetHeight() const { return 64; }
    virtual MapPixelDeltaInt GetSize() const {
        return MapPixelDeltaInt(64, 64);
    }

    virtual PixelBuf GetRegion(const MapPixelCoordInt &pos,
                               const MapPixelDeltaInt &size) const
    {
        return PixelBuf();
    }

    virtual Projection GetProj() const { return Projection(""); }
    virtual const std::wstring &GetFname() const { return empty_wstr; }
    virtual const std::wstring &GetTitle() const { return empty_wstr; }
    virtual const std::wstring &GetDescription() const { return empty_wstr; }

    virtual ODMPixelFormat GetPixelFormat() const { return ODM_PIX_RGBA4; }
};

class LatLonTransGeoDrawable : public GeoPixels {
public:
    LatLonTransGeoDrawable(double factor_x, double factor_y,
                           bool fail_p2l, bool fail_l2p)
        : m_factor_x(factor_x), m_factor_y(factor_y),
          m_fail_p2l(fail_p2l), m_fail_l2p(fail_l2p)
    {}
    virtual ~LatLonTransGeoDrawable() {};
    virtual bool
    PixelToLatLon(const MapPixelCoord &pos, LatLon *result) const {
        result->lat = pos.x * m_factor_x;
        result->lon = pos.y * m_factor_y;
        return !m_fail_p2l;
    }
    virtual bool
    LatLonToPixel(const LatLon &pos, MapPixelCoord *result) const {
        result->x = pos.lat / m_factor_x;
        result->y = pos.lon / m_factor_y;
        return !m_fail_l2p;
    }
private:
    double m_factor_x, m_factor_y;
    bool m_fail_p2l, m_fail_l2p;
};

#define CHECK_COORD_CLOSE(lhs, rhs, percent)                           \
    do {                                                               \
        auto &lhs_ = (lhs);                                            \
        auto &rhs_ = (rhs);                                            \
        BOOST_CHECK_CLOSE(lhs_.x, rhs_.x, percent);                    \
        BOOST_CHECK_CLOSE(lhs_.y, rhs_.y, percent);                    \
    } while (0)

BOOST_AUTO_TEST_CASE(MapCoordToMapCoord)
{
    auto coord_in =  MapPixelCoord(4, 6);
    auto coord_out = MapPixelCoord(4.0 * 100 / 300, 6.0 * 200 / 500);

    auto map_from = LatLonTransGeoDrawable(100, 200, false, false);
    auto map_to =   LatLonTransGeoDrawable(300, 500, false, false);
    auto map_fail_p2l = LatLonTransGeoDrawable(300, 500, true, false);
    auto map_fail_l2p = LatLonTransGeoDrawable(100, 200, false, true);

    CHECK_COORD_CLOSE(MapPixelToMapPixel(coord_in, map_from,     map_to),
                      coord_out, 0.1);
    CHECK_COORD_CLOSE(MapPixelToMapPixel(coord_in, map_from,     map_fail_p2l),
                      coord_out, 0.1);
    CHECK_COORD_CLOSE(MapPixelToMapPixel(coord_in, map_fail_l2p, map_to),
                      coord_out, 0.1);

    BOOST_CHECK_THROW(MapPixelToMapPixel(coord_in, map_fail_p2l, map_to),
                      std::runtime_error);
    BOOST_CHECK_THROW(MapPixelToMapPixel(coord_in, map_from,     map_fail_l2p),
                      std::runtime_error);
}

BOOST_AUTO_TEST_SUITE_END()


text:
/**
 * @file rnn.hpp
 * @author Marcus Edel
 *
 * Definition of the RNN class, which implements recurrent neural networks.
 */
#ifndef __MLPACK_METHODS_ANN_RNN_HPP
#define __MLPACK_METHODS_ANN_RNN_HPP

#include <mlpack/core.hpp>

#include <boost/ptr_container/ptr_vector.hpp>

#include <mlpack/methods/ann/network_traits.hpp>
#include <mlpack/methods/ann/performance_functions/cee_function.hpp>
#include <mlpack/methods/ann/layer/layer_traits.hpp>
#include <mlpack/methods/ann/connections/connection_traits.hpp>

namespace mlpack {
namespace ann /** Artificial Neural Network. */ {

/**
 * An implementation of a recurrent neural network.
 *
 * @tparam ConnectionTypes Tuple that contains all connection module which will
 * be used to construct the network.
 * @tparam OutputLayerType The outputlayer type used to evaluate the network.
 * @tparam PerformanceFunction Performance strategy used to claculate the error.
 * @tparam MaType of data (arma::mat or arma::sp_mat).
 * @tparam VecTypeDelta Type of the delta (arma::colvec, arma::mat or
 * arma::sp_mat).
 */
template <
  typename ConnectionTypes,
  typename OutputLayerType,
  class PerformanceFunction = CrossEntropyErrorFunction<>,
  typename MatType = arma::mat,
  typename VecTypeDelta = arma::colvec
>
class RNN
{
  public:
    /**
     * Construct the RNN object, which will construct a recurrent neural
     * network with the specified layers.
     *
     * @param network The network modules used to construct the network.
     * @param outputLayer The outputlayer used to evaluate the network.
     */
    RNN(const ConnectionTypes& network, OutputLayerType& outputLayer) :
        network(network), err(0),  trainError(0), seqNum(0),
        outputLayer(outputLayer)
    {
      // Nothing to do here.
    }

    /**
     * Run a single iteration of the feed forward algorithm, using the given
     * input and target vector, updating the resulting error into the error
     * vector.
     *
     * @param input Input data used for evaluating the network.
     * @param target Target data used to calculate the network error.
     * @param error The calulated error of the output layer.
     * @tparam VecType Type of target data (arma::colvec, arma::mat or
     * arma::sp_mat).
     */
    template <typename VecType>
    void FeedForward(const MatType& input,
                     const VecType& target,
                     MatType& error)
    {
      // Initialize the activation storage only once.
      if (!activations.size())
      {
        InitLayer(network, input);
      }
      else
      {
        // Expand the activation storage to handle sequences of
        // different length.
        if (activations[0].n_cols < input.n_elem)
        {
          for (size_t i = 0; i < activations.size(); i++)
          {
            activations[i].insert_cols(activations[i].n_cols,
                arma::zeros<MatType>(activations[i].n_rows,
                input.n_elem - activations[i].n_cols));
          }
        }
      }

      seqLen = input.n_rows / inputSize;
      seqOutput = outputSize < target.n_elem ? true : false;
      error = MatType(outputSize, outputSize < target.n_elem ? seqLen : 1);

      // Iterate through the input sequence and perform the feed forward pass.
      for (seqNum = 0; seqNum < seqLen; seqNum++)
      {
        // Reset the network by zeroing the layer activations.
        ResetActivations(network);

        // Set the current input activation.
        std::get<0>(std::get<0>(
            network)).InputLayer().InputActivation() = input.submat(
            seqNum * inputSize, 0, (seqNum + 1) * inputSize - 1, 0);

        // Perform the forward pass and calculate the output error.
        LayerForward(network);
        if (seqOutput)
        {
          arma::colvec seqError = error.unsafe_col(seqNum);
          arma::colvec seqTarget = target.subvec(seqNum * outputSize,
              (seqNum + 1) * outputSize - 1);

          OutputError(network, seqTarget, seqError);
        }

        // Save the network activation for the backward/forward pass and update
        // the recurrent connections.
        if (seqNum < (input.n_rows / inputSize - 1))
        {
          layerNum = 0;
          SaveActivations(network);
        }
      }

      // Calculate the error only once for a non-sequence input.
      if (!seqOutput)
      {
        seqNum = 0;
        arma::colvec seqError = error.unsafe_col(seqNum);
        OutputError(network, target, seqError);
      }
    }

    /**
     * Run a single iteration of the feed backward algorithm, using the given
     * error of the output layer.
     *
     * @param error The calulated error of the output layer.
     */
    void FeedBackward(const MatType& error)
    {
      // Reset the network deltas by zeroing the storage.
      for (size_t i = 0; i < delta.size(); i++)
          delta[i].zeros();

      // Iterate through the input sequence and perform the feed backward pass.
      for (seqNum = seqLen - 1; seqNum >= 0; seqNum--)
      {
        deltaNum = 0;

        // Perform the backward pass and update the gradient storage.
        arma::colvec seqError = error.unsafe_col(seqOutput ? seqNum : 0);
        LayerBackward(network, seqError);
        UpdateGradients(network);

        // Load the network activation for the upcoming backward pass.
        if (seqNum > 0)
        {
          layerNum = 0;
          LoadActivations(network);
        }
        else if (seqNum == 0) break;
      }
    }

    /**
     * Updating the weights using the specified optimizer.
     *
     */
    void ApplyGradients()
    {
      ApplyGradients(network);

      // Reset the overall error.
      err = 0;
      trainError = 0;
      seqNum = 0;
    }

    /**
     * Evaluate the network using the given input. The output activation is
     * stored into the output parameter.
     *
     * @param input Input data used to evaluate the network.
     * @param output Output data used to store the output activation
     * @tparam VecType Type of data (arma::colvec, arma::mat or arma::sp_mat).
     */
    template <typename VecType>
    void Predict(const VecType& input, VecType& output)
    {
      seqLen = input.n_rows / inputSize;

      // Iterate through the input sequence and perform the feed forward pass.
      for (seqNum = 0; seqNum < seqLen; seqNum++)
      {
        // Reset the network by zeroing the layer activations.
        ResetActivations(network);

        // Set the current input activation.
        std::get<0>(std::get<0>(
            network)).InputLayer().InputActivation() = input.submat(
            seqNum * inputSize, 0, (seqNum + 1) * inputSize - 1, 0);

        // Perform the forward pass and calculate the output error.
        LayerForward(network);
        if (seqOutput)
        {
          arma::colvec targetCol;
          OutputPrediction(network, targetCol);
          output = arma::join_cols(output, targetCol);
        }

        // Save the network activation for the backward/forward pass and update
        // the recurrent connections.
        if (seqNum < (input.n_rows / inputSize - 1))
        {
          layerNum = 0;
          SaveActivations(network);
        }
      }

      if (!seqOutput)
        OutputPrediction(network, output);
    }

    /**
     * Evaluate the trained network using the given input and compare the output
     * with the given target vector.
     *
     * @param input Input data used to evaluate the trained network.
     * @param target Target data used to calculate the network error.
     * @param error The calulated error of the output layer.
     * @tparam VecType Type of data (arma::colvec, arma::mat or arma::sp_mat).
     */
    template <typename VecType>
    double Evaluate(const MatType& input,
                     const VecType& target,
                     MatType& error)
    {
      FeedForward(input, target, error);
      return err;
    }

    //! Get the error of the network.
    double Error() const { return trainError; }

  private:
    /**
     * Helper function to reset the network by zeroing the layer activations.
     *
     * enable_if (SFINAE) is used to iterate through the network connection
     * modules. The general case peels off the first type and recurses, as usual
     * with variadic function templates.
     */
    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    ResetActivations(std::tuple<Tp...>& /* unused */) { }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    ResetActivations(std::tuple<Tp...>& t)
    {
      Reset(std::get<I>(t));
      ResetActivations<I + 1, Tp...>(t);
    }

    /**
     * Reset the network by zeroing the layer activations.
     *
     * enable_if (SFINAE) is used to iterate through the network connections.
     * The general case peels off the first type and recurses, as usual with
     * variadic function templates.
     */
    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    Reset(std::tuple<Tp...>& /* unused */) { }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    Reset(std::tuple<Tp...>& t)
    {
      Parameter<I, typename std::remove_reference<
          decltype(std::get<I>(t).InputLayer())>::type, Tp...>(t);

      std::get<I>(t).OutputLayer().InputActivation().zeros(
          std::get<I>(t).OutputLayer().InputSize());

      // Reset the recurrent connection only at the beginning of a new sequence.
      if (seqNum == 0 && (ConnectionTraits<typename std::remove_reference<
          decltype(std::get<I>(t))>::type>::IsSelfConnection ||
          ConnectionTraits<typename std::remove_reference<decltype(
          std::get<I>(t))>::type>::IsFullselfConnection))
      {
        std::get<I>(t).InputLayer().InputActivation().zeros(
          std::get<I>(t).InputLayer().InputSize());
      }

      Reset<I + 1, Tp...>(t);
    }

    /**
     * Update the sequence length for a specific layer.
     *
     * enable_if (SFINAE) is used to determine if classes passed contains the
     * SeqLen function.
     */
    template<size_t I, typename LayerType, typename... Tp>
    typename std::enable_if<
        LayerTraits<LayerType>::IsLSTMLayer == false, void>::type
    Parameter(std::tuple<Tp...>& /* unused */) { }

    /**
     * Update the sequence length for a specific layer.
     *
     * enable_if (SFINAE) is used to determine if classes passed contains the
     * SeqLen function.
     */
    template<size_t I, typename LayerType, typename... Tp>
    typename std::enable_if<
        LayerTraits<LayerType>::IsLSTMLayer == true, void>::type
    Parameter(std::tuple<Tp...>& t)
    {
      std::get<I>(t).InputLayer().SeqLen() = seqLen;
    }

    /**
     * Run a single iteration of the feed forward algorithm, using the given
     * input and target vector, updating the resulting error into the error
     * vector.
     *
     * enable_if (SFINAE) is used to select between two template overloads of
     * the get function - one for when I is equal the size of the tuple of
     * connections, and one for the general case which peels off the first type
     * and recurses, as usual with variadic function templates.
     */
    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    LayerForward(std::tuple<Tp...>& /* unused */) { }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    LayerForward(std::tuple<Tp...>& t)
    {
      ConnectionForward(std::get<I>(t));

      // Use the first connection to perform the feed forward algorithm.
      std::get<0>(std::get<I>(t)).OutputLayer().FeedForward(
          std::get<0>(std::get<I>(t)).OutputLayer().InputActivation(),
          std::get<0>(std::get<I>(t)).OutputLayer().InputActivation());

      LayerForward<I + 1, Tp...>(t);
    }

    /**
     * Sum up all layer activations by evaluating all connections.
     *
     * enable_if (SFINAE) is used to iterate through the network connections.
     * The general case peels off the first type and recurses, as usual with
     * variadic function templates.
     */
    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    ConnectionForward(std::tuple<Tp...>& /* unused */) { }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    ConnectionForward(std::tuple<Tp...>& t)
    {
      std::get<I>(t).FeedForward(std::get<I>(t).InputLayer().InputActivation());
      ConnectionForward<I + 1, Tp...>(t);
    }

    /*
     * Calculate the output error and update the overall error.
     */
    template<typename VecType, typename... Tp>
    void OutputError(std::tuple<Tp...>& t,
                     const VecType& target,
                     VecType& error)
    {
       // Calculate and store the output error.
      outputLayer.CalculateError(std::get<0>(
          std::get<sizeof...(Tp) - 1>(t)).OutputLayer().InputActivation(),
          target, error);

      // Save the output activation for the upcoming feed backward pass.
      activations.back().unsafe_col(seqNum) = std::get<0>(
          std::get<sizeof...(Tp) - 1>(t)).OutputLayer().InputActivation();

      // Masures the network's performance with the specified performance
      // function.
      err = PerformanceFunction::Error(std::get<0>(
          std::get<sizeof...(Tp) - 1>(t)).OutputLayer().InputActivation(),
          target);

      // Update the overall training error.
      trainError += err;
    }

    /*
     * Calculate and store the output activation.
     */
    template<typename VecType, typename... Tp>
    void OutputPrediction(std::tuple<Tp...>& t, VecType& output)
    {
       // Calculate and store the output prediction.
      outputLayer.OutputClass(std::get<0>(
          std::get<sizeof...(Tp) - 1>(t)).OutputLayer().InputActivation(),
          output);
    }

    /**
     * Run a single iteration of the feed backward algorithm, using the given
     * error of the output layer. Note that we iterate backward through the
     * connection modules.
     *
     * enable_if (SFINAE) is used to select between two template overloads of
     * the get function - one for when I is equal the size of the tuple of
     * connections, and one for the general case which peels off the first type
     * and recurses, as usual with variadic function templates.
     */
    template<size_t I = 0, typename VecType, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp) + 1, void>::type
    LayerBackward(std::tuple<Tp...>& /* unused */, VecType& /* unused */)
    { }

    template<size_t I = 1, typename VecType, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp) + 1, void>::type
    LayerBackward(std::tuple<Tp...>& t, VecType& error)
    {
      // Distinguish between the output layer and the other layer. In case of
      // the output layer use the specified error vector to store the error and
      // to perform the feed backward pass.
      if (I == 1)
      {
        // Use the first connection from the last connection module to
        // calculate the error.
        std::get<0>(std::get<sizeof...(Tp) - I>(t)).OutputLayer().FeedBackward(
            activations.back().unsafe_col(seqNum), error,
            std::get<0>(std::get<sizeof...(Tp) - I>(t)).OutputLayer().Delta());
      }

      ConnectionBackward(std::get<sizeof...(Tp) - I>(t), std::get<0>(std::get<
          sizeof...(Tp) - I>(t)).OutputLayer().Delta(), I, sizeof...(Tp));

      LayerBackward<I + 1, VecType, Tp...>(t, error);
    }

    /**
     * Back propagate the given error and store the delta in the connection
     * between the corresponding layer.
     *
     * enable_if (SFINAE) is used to iterate through the network connections.
     * The general case peels off the first type and recurses, as usual with
     * variadic function templates.
     */
    template<size_t I = 0, typename VecType, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    ConnectionBackward(std::tuple<Tp...>& /* unused */,
                       VecType& /* unused */,
                       const size_t /* unused */,
                       const size_t /* unused */) { }

    template<size_t I = 0, typename VecType, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    ConnectionBackward(std::tuple<Tp...>& t,
                       VecType& error,
                       const size_t layer,
                       const size_t layerNum)
    {
      std::get<I>(t).FeedBackward(error);

      // Update the recurrent delta.
      if (ConnectionTraits<typename std::remove_reference<decltype(
          std::get<I>(t))>::type>::IsSelfConnection ||
          ConnectionTraits<typename std::remove_reference<decltype(
          std::get<I>(t))>::type>::IsFullselfConnection)
      {
        std::get<I>(t).FeedBackward(delta[deltaNum]);
        delta[deltaNum++] = std::get<I>(t).Delta();
      }

      // We calculate the delta only for non bias layer and self connections.
      if (!(ConnectionTraits<typename std::remove_reference<decltype(
            std::get<I>(t))>::type>::IsSelfConnection ||
        LayerTraits<typename std::remove_reference<decltype(
            std::get<I>(t).InputLayer())>::type>::IsBiasLayer ||
        ConnectionTraits<typename std::remove_reference<decltype(
            std::get<I>(t))>::type>::IsFullselfConnection) && layer < layerNum)
      {
        // Sum up the stored delta for recurrent connections.
        if (recurrentLayer[layer])
        {
          std::get<I>(t).Delta() += delta[deltaNum].subvec(
              0, std::get<I>(t).InputLayer().OutputSize() - 1);
        }

        // Perform the backward pass.
        std::get<I>(t).InputLayer().FeedBackward(
            std::get<I>(t).InputLayer().InputActivation(),
            std::get<I>(t).Delta(), std::get<I>(t).InputLayer().Delta());

        // Update the delta storage for the next backward pass.
        if (recurrentLayer[layer])
          delta[deltaNum] = std::get<I>(t).InputLayer().Delta();
      }

      ConnectionBackward<I + 1, VecType, Tp...>(t, error, layer, layerNum);
    }

    /**
     * Helper function to update the gradient storage.
     *
     * enable_if (SFINAE) is used to select between two template overloads of
     * the get function - one for when I is equal the size of the tuple of
     * connections, and one for the general case which peels off the first type
     * and recurses, as usual with variadic function templates.
     */
    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    UpdateGradients(std::tuple<Tp...>& /* unused */) { }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    UpdateGradients(std::tuple<Tp...>& t)
    {
      Gradients(std::get<I>(t));
      UpdateGradients<I + 1, Tp...>(t);
    }

    /**
     * Sum up all gradients and store the results in the gradients storage.
     *
     * enable_if (SFINAE) is used to iterate through the network connections.
     * The general case peels off the first type and recurses, as usual with
     * variadic function templates.
     */
    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    Gradients(std::tuple<Tp...>& /* unused */) { }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    Gradients(std::tuple<Tp...>& t)
    {
      std::get<I>(t).Optimizer().Update();
      Gradients<I + 1, Tp...>(t);
    }

    /**
     * Helper function to update the weights using the specified optimizer and
     * the given input.
     *
     * enable_if (SFINAE) is used to select between two template overloads of
     * the get function - one for when I is equal the size of the tuple of
     * connections, and one for the general case which peels off the first type
     * and recurses, as usual with variadic function templates.
     */
    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    ApplyGradients(std::tuple<Tp...>& /* unused */) { }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    ApplyGradients(std::tuple<Tp...>& t)
    {
      Apply(std::get<I>(t));
      ApplyGradients<I + 1, Tp...>(t);
    }

    /**
     * Update the weights using the specified optimizer,the given input and the
     * calculated delta.
     *
     * enable_if (SFINAE) is used to select between two template overloads of
     * the get function - one for when I is equal the size of the tuple of
     * connections, and one for the general case which peels off the first type
     * and recurses, as usual with variadic function templates.
     */
    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    Apply(std::tuple<Tp...>& /* unused */) { }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    Apply(std::tuple<Tp...>& t)
    {
      std::get<I>(t).Optimizer().Optimize();
      std::get<I>(t).Optimizer().Reset();

      Apply<I + 1, Tp...>(t);
    }

    /**
     * Helper function to iterate through all connection modules and to build
     * the activation, gradients and delta storage.
     *
     * enable_if (SFINAE) is used to select between two template overloads of
     * the get function - one for when I is equal the size of the tuple of
     * connections, and one for the general case which peels off the first type
     * and recurses, as usual with variadic function templates.
     */
    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    InitLayer(std::tuple<Tp...>& t, const MatType& input)
    {
      recurrentLayer.push_back(false);
      outputSize = std::get<0>(std::get<I - 1>(t)).OutputLayer().OutputSize();
      activations.push_back(new MatType(outputSize, input.n_elem));
    }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    InitLayer(std::tuple<Tp...>& t, const MatType& input)
    {
      if (I == 0)
        inputSize = std::get<0>(std::get<I>(t)).InputLayer().InputSize();

      recurrentLayer.push_back(false);
      Recurrent(std::get<sizeof...(Tp) - I - 1>(t));

      Layer(std::get<I>(t), input, I);
      InitLayer<I + 1, Tp...>(t, input);
    }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    Recurrent(std::tuple<Tp...>& /* unusded */) { }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    Recurrent(std::tuple<Tp...>& t)
    {
      if (ConnectionTraits<typename std::remove_reference<decltype(
              std::get<I>(t))>::type>::IsSelfConnection ||
          ConnectionTraits<typename std::remove_reference<decltype(
            std::get<I>(t))>::type>::IsFullselfConnection)
      {
        recurrentLayer.back() = true;
        delta.push_back(new VecTypeDelta(std::get<I>(t).Weights().n_rows));
      }
      else
      {
        Recurrent<I + 1, Tp...>(t);
      }
    }

    /**
     * Iterate through all connections and build the the activation, gradients
     * and delta storage.
     *
     * enable_if (SFINAE) is used to select between two template overloads of
     * the get function - one for when I is equal the size of the tuple of
     * connections, and one for the general case which peels off the first type
     * and recurses, as usual with variadic function templates.
     */
    template<size_t I = 0, typename VecType, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    Layer(std::tuple<Tp...>& /* unusded */,
          const VecType& /* unused */,
          const size_t /* unsued */) { }

    template<size_t I = 0, typename VecType, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    Layer(std::tuple<Tp...>& t, const VecType& input, const size_t layer)
    {
      activations.push_back(new MatType(
        std::get<I>(t).InputLayer().OutputSize(), input.n_elem));

      Layer<I + 1, VecType, Tp...>(t, input, layer);
    }

    /**
     * Helper function to iterate through all connection modules and to load
     * the layer activations.
     *
     * enable_if (SFINAE) is used to iterate through the network connection
     * modules. The general case peels off the first type and recurses, as usual
     * with variadic function templates.
     */
    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    LoadActivations(std::tuple<Tp...>& /* unused */) { }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    LoadActivations(std::tuple<Tp...>& t)
    {
      Load(std::get<I>(t));
      LoadActivations<I + 1, Tp...>(t);
    }

    /**
     * Load and set the network layer activations.
     *
     * enable_if (SFINAE) is used to iterate through the network connections.
     * The general case peels off the first type and recurses, as usual with
     * variadic function templates.
     */
    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    Load(std::tuple<Tp...>& /* unused */) { }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    Load(std::tuple<Tp...>& t)
    {
      std::get<I>(t).InputLayer().InputActivation() =
          activations[layerNum++].unsafe_col(seqNum - 1);
      Load<I + 1, Tp...>(t);
    }

    /**
     * Helper function to iterate through all connection modules and to save
     * the layer activations.
     *
     * enable_if (SFINAE) is used to iterate through the network connection
     * modules. The general case peels off the first type and recurses, as usual
     * with variadic function templates.
     */
    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    SaveActivations(std::tuple<Tp...>& /* unused */) { }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    SaveActivations(std::tuple<Tp...>& t)
    {
      Save(std::get<I>(t));
      SaveActivations<I + 1, Tp...>(t);
    }

    /**
     * Save the network layer activations.
     *
     * enable_if (SFINAE) is used to iterate through the network connections.
     * The general case peels off the first type and recurses, as usual with
     * variadic function templates.
     */
    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I == sizeof...(Tp), void>::type
    Save(std::tuple<Tp...>& /* unused */) { }

    template<size_t I = 0, typename... Tp>
    typename std::enable_if<I < sizeof...(Tp), void>::type
    Save(std::tuple<Tp...>& t)
    {
      activations[layerNum++].unsafe_col(seqNum) =
          std::get<I>(t).InputLayer().InputActivation();

      // Use the activation from the corresponding outputlayer for
      // self connections.
      if (ConnectionTraits<typename std::remove_reference<decltype(
              std::get<I>(t))>::type>::IsSelfConnection ||
          ConnectionTraits<typename std::remove_reference<decltype(
              std::get<I>(t))>::type>::IsFullselfConnection)
      {
        std::get<I>(t).InputLayer().InputActivation() =
            std::get<I>(t).OutputLayer().InputActivation();
      }

      Save<I + 1, Tp...>(t);
    }

    //! The layer we are using to build the network.
    ConnectionTypes network;

    //! The current error of the network.
    double err;

    //! The current training error of the network.
    double trainError;

    //! The activation storage we are using to perform the feed backward pass.
    boost::ptr_vector<MatType> activations;

    //! The index of the current sequence number.
    size_t seqNum;

    //! The index of the currently activate layer.
    size_t layerNum;

    //! The index of the currently activate delta.
    size_t deltaNum;

    //! Locally stored network output size.
    size_t outputSize;

    //! Locally stored network input size.
    size_t inputSize;

    //! Locally stored parameter that indicates if the input is a sequence.
    bool seqOutput;

    //! The outputlayer used to evaluate the network
    OutputLayerType& outputLayer;

    //! Locally stored number of samples in one input sequence.
    size_t seqLen;

    //! The recurrentLayer storage we are using to perform the backward pass.
    std::vector<bool> recurrentLayer;

    //! The detla storage we are using to perform the feed backward pass.
    boost::ptr_vector<VecTypeDelta> delta;
}; // class RNN

//! Network traits for the FFNN network.
template <
  typename ConnectionTypes,
  typename OutputLayerType,
  class PerformanceFunction
>
class NetworkTraits<RNN<ConnectionTypes, OutputLayerType, PerformanceFunction> >
{
 public:
  static const bool IsFNN = false;
  static const bool IsRNN = true;
  static const bool IsCNN = false;
};

}; // namespace ann
}; // namespace mlpack

#endif

ext: hpp

max_stars_repo_name: vj-ug/Contribution-to-mlpack

max_issues_repo_name: vj-ug/Contribution-to-mlpack

max_forks_repo_name: vj-ug/Contribution-to-mlpack


text:
/*
 * Dijkstra.cpp
 *
 * 	\brief     My dijkstra implementation for the tenth exercise
 *  \details   This class computes the longest shortest path for given startingPoint
 *  \author    Julia Baumbach
 *  \date      15.07.2017
 */

#include "DijkstraSolver.h"

#include <climits>
#include <iostream>
#include <boost/heap/fibonacci_heap.hpp>
#include <exception>

/**
 * \struct compare_function
 * \brief defines how 2 dijkstra pairs should be compared at fibonacci-heap
 * \param edge1 first edge to compare
 * \param edge2 second edge to compare
 * \return true if the weight of edge2 is smaller than edge1's weight
 */
struct compare_function{
	bool operator()(const DijkstraPair edge1, const DijkstraPair edge2) const{
		return edge1.second > edge2.second;
	}
};

/**
 * \fn the constructor
 * \brief initialize a new dijkstra instance while sorting the given edges
 * \param weights Vector of the weights for the given graph
 * \param edges Vector of the edges for the given graph
 * \return the new dijkstra instance
 */
DijkstraSolver::DijkstraSolver(SortedEdges sortedEdges, unsigned int numberOfVertices):
	sortedEdges(sortedEdges), numberOfVertices(numberOfVertices) {
}

/**
 * \fn void dijkstra::computeShortestPath
 * \brief computes all shortest paths from given start vertex for the initialized dijkstra instance and save the weights and predecessorMaps in the given maps
 * \param unsigned int numberOfVertices Number of Vertices for the graph
 * \param WeightMap& weightsToVertices map to store the weight to the i-th node at the i-th position
 * \param vector<int>& predecessorMap map to store the i-th's predecessor at the i-th position
 */
void DijkstraSolver::computeShortestPath(unsigned int startNode, WeightMap& weightsToVertices, std::vector<int>& predecessorMap){
	if(startNode > numberOfVertices){
		std::cerr << "Index of StartVertex must be less or equal to number of vertices" << std::endl;
		throw std::exception();
	}
	VisitedMap alreadyVisited(numberOfVertices+1, false);

	//Start in point startNode
	weightsToVertices[startNode] = 0;
	predecessorMap[startNode] = startNode;
	int currentVertex = startNode;
	int currentDist = 0;

	boost::heap::fibonacci_heap<DijkstraPair, boost::heap::compare<compare_function>> heap;
	//Put the start vertex in the verticesToVisit list
	heap.push(std::make_pair(startNode, 0));

	while(!heap.empty()){
		if (!alreadyVisited.at(heap.top().first)){
			currentVertex = heap.top().first;
			currentDist = heap.top().second;

			heap.pop();

			std::vector<DijkstraPair> currentEdges = sortedEdges.at(currentVertex);

			for (const DijkstraPair pair : currentEdges){
				//Find out the current neighbor vertex and the weight of the current edge
				int neighborVertex = pair.first;
				int currentWeight = pair.second;
				//Search for the right position in verticesToVisit-list. If Vertex is already visited, don't add this edge
				if (!alreadyVisited.at(neighborVertex)){
					heap.push(std::make_pair(neighborVertex, currentDist + currentWeight));
				}

				int currentDistance = currentDist + currentWeight;

				//Update the predecessor and weightsToVerices maps
				if (currentDistance < weightsToVertices[neighborVertex]){
					weightsToVertices[neighborVertex] = currentDistance;
					predecessorMap[neighborVertex] = currentVertex;
				}
			}
			//Current vertex is visited now
			alreadyVisited.at(currentVertex) = true;
		} else {
			heap.pop();
		}
	}
}

/*
 * \fn int updateEdgeWeight(int edgeStart, int edgeEnd)
 * \brief sets EdgeWeight of edge (edgestart, edgeEnd) to 0
 * \param int edgeStart start vertex of the edge
 * \param int edgeEnd end vertex of the edge
 * \return returns the old weight of the edge
 */
int DijkstraSolver::setEdgeWeightToZero(int edgeStart, int edgeEnd){
	std::vector<DijkstraPair>& edges = sortedEdges[edgeStart];

	for(DijkstraPair& pair : edges){
		if(pair.first == edgeEnd){
			int oldWeight = pair.second;
			pair.second = 0;
			return oldWeight;
		}
	}

	return 0;
}

ext: cpp

max_stars_repo_name: appfs/appfs

max_issues_repo_name: appfs/appfs

max_forks_repo_name: appfs/appfs


text:
//==============================================================================
//         Copyright 2003 - 2011   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2013   LRI    UMR 8623 CNRS/Univ Paris Sud XI
//         Copyright 2012 - 2013   MetaScale SAS
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#ifndef BOOST_SIMD_SDK_MEMORY_ALIGN_PTR_INCLUDED
#define BOOST_SIMD_SDK_MEMORY_ALIGN_PTR_INCLUDED

/*!
  @file
  @brief Defines and implements make_aligned function
**/

#include <boost/simd/sdk/memory/meta/align_ptr.hpp>
#include <boost/simd/sdk/memory/is_aligned.hpp>
#include <boost/dispatch/attributes.hpp>
#include <boost/assert.hpp>

namespace boost { namespace simd {  namespace memory
{
  /*!
    @brief Mark pointer as properly aligned

    Make the compiler's optimizer assume that a given pointer is aligned on a
    given alignment boundary. This function takes an already aligned pointer and
    flags it as aligned so the compiler can keep track of this constraint in its
    optimization pass.

    @tparam T         Type of the pointee.
    @tparam Alignment A power of 2 alignment constraint.
    @param pointer Pointer to flag. Must already be aligned on @c Alignment

    @return A properly flagged pointer equals to the input argument but with
            compiler-specific attribute added to its type.
  **/
  template<std::size_t Alignment, typename T>
  BOOST_FORCEINLINE typename meta::align_ptr<T,Alignment>::type
  align_ptr(T* const pointer)
  {
    BOOST_ASSERT_MSG
    ( boost::simd::is_aligned(pointer,Alignment)
    , "The pointer you try to mark as aligned is not aligned "
      "on the specified alignment in this context"
    );

    return meta::align_ptr<T,Alignment>::value(pointer);
  }

} } }

#endif


text:
//---------------------------------------------------------------------------//
// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
//
// 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
//
// See http://boostorg.github.com/compute for more information.
//---------------------------------------------------------------------------//

#ifndef BOOST_COMPUTE_FUNCTION_HPP
#define BOOST_COMPUTE_FUNCTION_HPP

#include <map>
#include <string>
#include <sstream>
#include <vector>

#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/preprocessor/repetition.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/static_assert.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/function_traits.hpp>

#include <boost/compute/cl.hpp>
#include <boost/compute/config.hpp>
#include <boost/compute/type_traits/type_name.hpp>

namespace boost {
namespace compute {
namespace detail {

template<class ResultType, class ArgTuple>
class invoked_function
{
public:
    typedef ResultType result_type;

    BOOST_STATIC_CONSTANT(
        size_t, arity = boost::tuples::length<ArgTuple>::value
    );

    invoked_function(const std::string &name,
                     const std::string &source)
        : m_name(name),
          m_source(source)
    {
    }

    invoked_function(const std::string &name,
                     const std::string &source,
                     const std::map<std::string, std::string> &definitions)
        : m_name(name),
          m_source(source),
          m_definitions(definitions)
    {
    }

    invoked_function(const std::string &name,
                     const std::string &source,
                     const ArgTuple &args)
        : m_name(name),
          m_source(source),
          m_args(args)
    {
    }

    invoked_function(const std::string &name,
                     const std::string &source,
                     const std::map<std::string, std::string> &definitions,
                     const ArgTuple &args)
        : m_name(name),
          m_source(source),
          m_definitions(definitions),
          m_args(args)
    {
    }

    std::string name() const
    {
        return m_name;
    }

    std::string source() const
    {
        return m_source;
    }

    const std::map<std::string, std::string>& definitions() const
    {
        return m_definitions;
    }

    const ArgTuple& args() const
    {
        return m_args;
    }

private:
    std::string m_name;
    std::string m_source;
    std::map<std::string, std::string> m_definitions;
    ArgTuple m_args;
};

} // end detail namespace

/// \class function
/// \brief A function object.
template<class Signature>
class function
{
public:
    /// \internal_
    typedef typename
        boost::function_traits<Signature>::result_type result_type;

    /// \internal_
    BOOST_STATIC_CONSTANT(
        size_t, arity = boost::function_traits<Signature>::arity
    );

    /// \internal_
    typedef Signature signature;

    /// Creates a new function object with \p name.
    function(const std::string &name)
        : m_name(name)
    {
    }

    /// Destroys the function object.
    ~function()
    {
    }

    /// \internal_
    std::string name() const
    {
        return m_name;
    }

    /// \internal_
    void set_source(const std::string &source)
    {
        m_source = source;
    }

    /// \internal_
    std::string source() const
    {
        return m_source;
    }

    /// \internal_
    void define(std::string name, std::string value = std::string())
    {
        m_definitions[name] = value;
    }

    bool operator==(const function<Signature>& other) const
    {
        return
            (m_name == other.m_name)
                && (m_definitions == other.m_definitions)
                && (m_source == other.m_source);
    }

    bool operator!=(const function<Signature>& other) const
    {
        return !(*this == other);
    }

    /// \internal_
    detail::invoked_function<result_type, boost::tuple<> >
    operator()() const
    {
        BOOST_STATIC_ASSERT_MSG(
            arity == 0,
            "Non-nullary function invoked with zero arguments"
        );

        return detail::invoked_function<result_type, boost::tuple<> >(
            m_name, m_source, m_definitions
        );
    }

    /// \internal_
    template<class Arg1>
    detail::invoked_function<result_type, boost::tuple<Arg1> >
    operator()(const Arg1 &arg1) const
    {
        BOOST_STATIC_ASSERT_MSG(
            arity == 1,
            "Non-unary function invoked one argument"
        );

        return detail::invoked_function<result_type, boost::tuple<Arg1> >(
            m_name, m_source, m_definitions, boost::make_tuple(arg1)
        );
    }

    /// \internal_
    template<class Arg1, class Arg2>
    detail::invoked_function<result_type, boost::tuple<Arg1, Arg2> >
    operator()(const Arg1 &arg1, const Arg2 &arg2) const
    {
        BOOST_STATIC_ASSERT_MSG(
            arity == 2,
            "Non-binary function invoked with two arguments"
        );

        return detail::invoked_function<result_type, boost::tuple<Arg1, Arg2> >(
            m_name, m_source, m_definitions, boost::make_tuple(arg1, arg2)
        );
    }

    /// \internal_
    template<class Arg1, class Arg2, class Arg3>
    detail::invoked_function<result_type, boost::tuple<Arg1, Arg2, Arg3> >
    operator()(const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3) const
    {
        BOOST_STATIC_ASSERT_MSG(
            arity == 3,
            "Non-ternary function invoked with three arguments"
        );

        return detail::invoked_function<result_type, boost::tuple<Arg1, Arg2, Arg3> >(
            m_name, m_source, m_definitions, boost::make_tuple(arg1, arg2, arg3)
        );
    }

private:
    std::string m_name;
    std::string m_source;
    std::map<std::string, std::string> m_definitions;
};

/// Creates a function object given its \p name and \p source.
///
/// \param name The function name.
/// \param source The function source code.
///
/// \see BOOST_COMPUTE_FUNCTION()
template<class Signature>
inline function<Signature>
make_function_from_source(const std::string &name, const std::string &source)
{
    function<Signature> f(name);
    f.set_source(source);
    return f;
}

namespace detail {

// given a string containing the arguments declaration for a function
// like: "(int a, const float b)", returns a vector containing the name
// of each argument (e.g. ["a", "b"]).
inline std::vector<std::string> parse_argument_names(const char *arguments)
{
    BOOST_ASSERT_MSG(
        arguments[0] == '(' && arguments[std::strlen(arguments)-1] == ')',
        "Arguments should start and end with parentheses"
    );

    std::vector<std::string> args;

    size_t last_space = 0;
    size_t skip_comma = 0;
    for(size_t i = 1; i < std::strlen(arguments) - 2; i++){
        const char c = arguments[i];

        if(c == ' '){
            last_space = i;
        }
        else if(c == ',' && !skip_comma){
            std::string name(
                arguments + last_space + 1, i - last_space - 1
            );
            args.push_back(name);
        }
        else if(c == '<'){
            skip_comma++;
        }
        else if(c == '>'){
            skip_comma--;
        }
    }

    std::string last_argument(
        arguments + last_space + 1, std::strlen(arguments) - last_space - 2
    );
    args.push_back(last_argument);

    return args;
}

struct signature_argument_inserter
{
    signature_argument_inserter(std::stringstream &s_, const char *arguments, size_t last)
        : s(s_)
    {
        n = 0;
        m_last = last;

        m_argument_names = parse_argument_names(arguments);

        BOOST_ASSERT_MSG(
            m_argument_names.size() == last,
            "Wrong number of arguments"
        );
    }

    template<class T>
    void operator()(const T*)
    {
        s << type_name<T>() << " " << m_argument_names[n];
        if(n+1 < m_last){
            s << ", ";
        }
        n++;
    }

    size_t n;
    size_t m_last;
    std::stringstream &s;
    std::vector<std::string> m_argument_names;
};

template<class Signature>
inline std::string make_function_declaration(const char *name, const char *arguments)
{
    typedef typename
        boost::function_traits<Signature>::result_type result_type;
    typedef typename
        boost::function_types::parameter_types<Signature>::type parameter_types;
    typedef typename
        mpl::size<parameter_types>::type arity_type;

    std::stringstream s;
    s << "inline " << type_name<result_type>() << " " << name;
    s << "(";

    if(arity_type::value > 0){
        signature_argument_inserter i(s, arguments, arity_type::value);
        mpl::for_each<
            typename mpl::transform<parameter_types, boost::add_pointer<mpl::_1>
        >::type>(i);
    }

    s << ")";
    return s.str();
}

struct argument_list_inserter
{
    argument_list_inserter(std::stringstream &s_, const char first, size_t last)
        : s(s_)
    {
        n = 0;
        m_last = last;
        m_name = first;
    }

    template<class T>
    void operator()(const T*)
    {
        s << type_name<T>() << " " << m_name++;
        if(n+1 < m_last){
            s << ", ";
        }
        n++;
    }

    size_t n;
    size_t m_last;
    char m_name;
    std::stringstream &s;
};

template<class Signature>
inline std::string generate_argument_list(const char first = 'a')
{
    typedef typename
        boost::function_types::parameter_types<Signature>::type parameter_types;
    typedef typename
        mpl::size<parameter_types>::type arity_type;

    std::stringstream s;
    s << '(';

    if(arity_type::value > 0){
        argument_list_inserter i(s, first, arity_type::value);
        mpl::for_each<
            typename mpl::transform<parameter_types, boost::add_pointer<mpl::_1>
        >::type>(i);
    }

    s << ')';
    return s.str();
}

// used by the BOOST_COMPUTE_FUNCTION() macro to create a function
// with the given signature, name, arguments, and source.
template<class Signature>
inline function<Signature>
make_function_impl(const char *name, const char *arguments, const char *source)
{
    std::stringstream s;
    s << make_function_declaration<Signature>(name, arguments);
    s << source;

    return make_function_from_source<Signature>(name, s.str());
}

} // end detail namespace
} // end compute namespace
} // end boost namespace

/// Creates a function object with \p name and \p source.
///
/// \param return_type The return type for the function.
/// \param name The name of the function.
/// \param arguments A list of arguments for the function.
/// \param source The OpenCL C source code for the function.
///
/// The function declaration and signature are automatically created using
/// the \p return_type, \p name, and \p arguments macro parameters.
///
/// The source code for the function is interpreted as OpenCL C99 source code
/// which is stringified and passed to the OpenCL compiler when the function
/// is invoked.
///
/// For example, to create a function which squares a number:
/// \code
/// BOOST_COMPUTE_FUNCTION(float, square, (float x),
/// {
///     return x * x;
/// });
/// \endcode
///
/// And to create a function which sums two numbers:
/// \code
/// BOOST_COMPUTE_FUNCTION(int, sum_two, (int x, int y),
/// {
///     return x + y;
/// });
/// \endcode
///
/// \see BOOST_COMPUTE_CLOSURE()
#ifdef BOOST_COMPUTE_DOXYGEN_INVOKED
#define BOOST_COMPUTE_FUNCTION(return_type, name, arguments, source)
#else
#define BOOST_COMPUTE_FUNCTION(return_type, name, arguments, ...) \
    ::boost::compute::function<return_type arguments> name = \
        ::boost::compute::detail::make_function_impl<return_type arguments>( \
            #name, #arguments, #__VA_ARGS__ \
        )
#endif

#endif // BOOST_COMPUTE_FUNCTION_HPP

max_stars_repo_name: kindlychung/mediasoup-sfu-cpp

max_issues_repo_name: kindlychung/mediasoup-sfu-cpp

max_forks_repo_name: kindlychung/mediasoup-sfu-cpp


text:
/* Copyright 2020 Sébastien Kéroack. All Rights Reserved.

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

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 "pch.hpp"

// Boost.
#include <boost/spirit/home/x3.hpp>

// Standard.
#include <iostream>
#include <fstream>
#include <regex>
#include <stdarg.h>

// This.
#include <Strings/String.hpp>
#include <Time/Time.hpp>

namespace MyEA::String
{
    template <typename T>
    bool Parse_Number(char *&ptr_array_characters_received,
                      char *const ptr_last_character_received,
                      T &ref_output_received)
    {
        auto tmp_Assign([&ref_output_received](auto &ref_ctx_received)
        {
            ref_output_received = _attr(ref_ctx_received);
        });

        auto tmp_Initializer([&tmp_Assign]()
        {
            if      constexpr (std::is_same<T, char              >::value) { return(boost::spirit::x3::char_     [tmp_Assign]); }
            else if constexpr (std::is_same<T, int               >::value) { return(boost::spirit::x3::int_      [tmp_Assign]); }
            else if constexpr (std::is_same<T, short             >::value) { return(boost::spirit::x3::short_    [tmp_Assign]); }
            else if constexpr (std::is_same<T, long              >::value) { return(boost::spirit::x3::long_     [tmp_Assign]); }
            else if constexpr (std::is_same<T, long long         >::value) { return(boost::spirit::x3::long_long [tmp_Assign]); }
            else if constexpr (std::is_same<T, unsigned short    >::value) { return(boost::spirit::x3::ushort_   [tmp_Assign]); }
            else if constexpr (std::is_same<T, unsigned int      >::value) { return(boost::spirit::x3::uint_     [tmp_Assign]); }
            else if constexpr (std::is_same<T, unsigned long     >::value) { return(boost::spirit::x3::ulong_    [tmp_Assign]); }
            else if constexpr (std::is_same<T, unsigned long long>::value) { return(boost::spirit::x3::ulong_long[tmp_Assign]); }
            else if constexpr (std::is_same<T, float             >::value) { return(boost::spirit::x3::float_    [tmp_Assign]); }
            else if constexpr (std::is_same<T, double            >::value) { return(boost::spirit::x3::double_   [tmp_Assign]); }
            else { throw(std::logic_error("NotImplementedException")); }
        });

        return(boost::spirit::x3::phrase_parse(ptr_array_characters_received,
                                               ptr_last_character_received,
                                               tmp_Initializer(),
                                               boost::spirit::x3::ascii::space));
    }

    bool Read_Stream_Block(size_t &ref_block_size_received,
                           size_t const desired_block_size_received,
                           size_t const step_block_size_received,
                           std::vector<char> &ref_vector_buffers_received,
                           std::ifstream &ref_ifstream_received,
                           char const until_reach_received)
    {
        if(ref_ifstream_received.eof()) { return(true); }

        // Current position.
        std::streampos const tmp_current_tellg(ref_ifstream_received.tellg());

        if(ref_ifstream_received.fail())
        {
            MyEA::String::Error("Can not gets the current position from the input stream.");

            return(false);
        }

        // Remaining characters based on current position.
        ref_ifstream_received.seekg(0, std::ios::end);

        if(ref_ifstream_received.fail())
        {
            MyEA::String::Error("Can not sets the position of the input stream.");

            return(false);
        }

        size_t const tmp_remaining_size(static_cast<size_t>(ref_ifstream_received.tellg() - tmp_current_tellg)),
                     tmp_block_size(tmp_remaining_size < desired_block_size_received ? tmp_remaining_size : desired_block_size_received);

        if(ref_ifstream_received.fail())
        {
            MyEA::String::Error("Can not gets the position from the input stream.");

            return(false);
        }

        // Return to the last position.
        ref_ifstream_received.seekg(tmp_current_tellg, std::ios::beg);

        if(ref_ifstream_received.fail())
        {
            MyEA::String::Error("Can not sets the position of the input stream to the beginning.");

            return(false);
        }

        // If not enough space in the buffer resize it.
        if(ref_vector_buffers_received.size() < tmp_block_size) { ref_vector_buffers_received.resize(tmp_block_size); }

        // Read block into buffers.
        ref_ifstream_received.read(&ref_vector_buffers_received[0], tmp_block_size);

        if(ref_ifstream_received.fail())
        {
            MyEA::String::Error("Can not read properly the file.");

            return(false);
        }

        // Store current block size.
        ref_block_size_received = tmp_block_size;

        // If we continue to read until reach a specific character.
        if(until_reach_received != 0x00
           &&
           ref_vector_buffers_received[tmp_block_size - 1] != until_reach_received
           &&
           ref_ifstream_received.eof() == false
           &&
           tmp_remaining_size != tmp_block_size)
        {
            // do while until reach.
            do
            {
                // If not enough space in the buffer resize it.
                if(ref_vector_buffers_received.size() < ref_block_size_received + 1) { ref_vector_buffers_received.resize(ref_block_size_received + 1 + step_block_size_received); }

                // Read character into buffer.
                ref_ifstream_received.read(&ref_vector_buffers_received[ref_block_size_received], 1);
            } while(ref_ifstream_received.eof() == false
                    &&
                    ref_ifstream_received.fail() == false
                    &&
                    ref_vector_buffers_received[ref_block_size_received++] != until_reach_received);

            if(ref_ifstream_received.fail())
            {
                MyEA::String::Error("Can not read properly the character (%c).", ref_vector_buffers_received[ref_block_size_received - 1]);

                return(false);
            }
        }

        return(true);
    }

    template <typename T>
    bool Read_Stream_Block_And_Parse_Number(char *&ptr_array_characters_received,
                                            char *&ptr_last_character_received,
                                            size_t &ref_block_size_received,
                                            size_t const desired_block_size_received,
                                            size_t const step_block_size_received,
                                            T &ref_output_received,
                                            std::vector<char> &ref_vector_buffers_received,
                                            std::ifstream &ref_ifstream_received,
                                            char const until_reach_received)
    {
        if(ptr_array_characters_received == ptr_last_character_received)
        {
            if(MyEA::String::Read_Stream_Block(ref_block_size_received,
                                               desired_block_size_received,
                                               step_block_size_received,
                                               ref_vector_buffers_received,
                                               ref_ifstream_received,
                                               until_reach_received) == false)
            {
                MyEA::String::Error("An error has been triggered from the `Read_Stream_Block(%zu, %zu, %zu, vector, ifstream, %s)` function.",
                                    ref_block_size_received,
                                    desired_block_size_received,
                                    step_block_size_received,
                                    until_reach_received);

                return(false);
            }

            ptr_array_characters_received = &ref_vector_buffers_received[0];
            ptr_last_character_received = ptr_array_characters_received + ref_block_size_received;
        }

        if(MyEA::String::Parse_Number<T>(ptr_array_characters_received,
                                         ptr_last_character_received,
                                         ref_output_received) == false)
        {
            MyEA::String::Error("An error has been triggered from the \"Parse_Number()\" function.");

            return(false);
        }

        return(true);
    }

    template bool Read_Stream_Block_And_Parse_Number<char              >(char *&, char *&, size_t &, size_t const, size_t const, char               &, std::vector<char> &, std::ifstream &, char const);
    template bool Read_Stream_Block_And_Parse_Number<int               >(char *&, char *&, size_t &, size_t const, size_t const, int                &, std::vector<char> &, std::ifstream &, char const);
    template bool Read_Stream_Block_And_Parse_Number<short             >(char *&, char *&, size_t &, size_t const, size_t const, short              &, std::vector<char> &, std::ifstream &, char const);
    template bool Read_Stream_Block_And_Parse_Number<long              >(char *&, char *&, size_t &, size_t const, size_t const, long               &, std::vector<char> &, std::ifstream &, char const);
    template bool Read_Stream_Block_And_Parse_Number<long long         >(char *&, char *&, size_t &, size_t const, size_t const, long long          &, std::vector<char> &, std::ifstream &, char const);
    template bool Read_Stream_Block_And_Parse_Number<unsigned short    >(char *&, char *&, size_t &, size_t const, size_t const, unsigned short     &, std::vector<char> &, std::ifstream &, char const);
    template bool Read_Stream_Block_And_Parse_Number<unsigned int      >(char *&, char *&, size_t &, size_t const, size_t const, unsigned int       &, std::vector<char> &, std::ifstream &, char const);
    template bool Read_Stream_Block_And_Parse_Number<unsigned long     >(char *&, char *&, size_t &, size_t const, size_t const, unsigned long      &, std::vector<char> &, std::ifstream &, char const);
    template bool Read_Stream_Block_And_Parse_Number<unsigned long long>(char *&, char *&, size_t &, size_t const, size_t const, unsigned long long &, std::vector<char> &, std::ifstream &, char const);
    template bool Read_Stream_Block_And_Parse_Number<float             >(char *&, char *&, size_t &, size_t const, size_t const, float              &, std::vector<char> &, std::ifstream &, char const);
    template bool Read_Stream_Block_And_Parse_Number<double            >(char *&, char *&, size_t &, size_t const, size_t const, double             &, std::vector<char> &, std::ifstream &, char const);

    template <typename T>
    T Cin_Number(T const minimum_number_received,
                 T const maximum_number_received,
                 std::string const &ref_prefix_received)
    {
        T tmp_return(0);

        std::string tmp_string_digit;

        std::smatch tmp_smatch;

        std::regex tmp_regex("^([-+]?[0-9]+)$");

        do
        {
            PRINT(ref_prefix_received);

            getline(std::cin, tmp_string_digit);

            if(tmp_string_digit.empty()) { continue; }

            if(std::regex_match(tmp_string_digit,
                                tmp_smatch,
                                tmp_regex,
                                std::regex_constants::match_default))
            {
                try
                {
                    tmp_return = std::stoi(tmp_smatch[1u]);

                    if      constexpr (std::is_same<T, int               >::value) { tmp_return = std::stoi  (tmp_smatch[1u]); }
                    else if constexpr (std::is_same<T, long              >::value) { tmp_return = std::stol  (tmp_smatch[1u]); }
                    else if constexpr (std::is_same<T, long long         >::value) { tmp_return = std::stoll (tmp_smatch[1u]); }
                    else if constexpr (std::is_same<T, unsigned int      >::value
                                       ||
                                       std::is_same<T, unsigned long     >::value) { tmp_return = std::stoul (tmp_smatch[1u]); }
                    else if constexpr (std::is_same<T, unsigned long long>::value) { tmp_return = std::stoull(tmp_smatch[1u]); }
                    else { throw(std::logic_error("NotImplementedException")); }

                    if(     tmp_return < minimum_number_received) { continue; }
                    else if(tmp_return > maximum_number_received) { continue; }

                    return(tmp_return);
                }
                catch(...) { continue; }
            }
        } while(true);
    }

    template int                Cin_Number<int               >(int                const, int                const, std::string const &);
    template long               Cin_Number<long              >(long               const, long               const, std::string const &);
    template long long          Cin_Number<long long         >(long long          const, long long          const, std::string const &);
    template unsigned int       Cin_Number<unsigned int      >(unsigned int       const, unsigned int       const, std::string const &);
    template unsigned long      Cin_Number<unsigned long     >(unsigned long      const, unsigned long      const, std::string const &);
    template unsigned long long Cin_Number<unsigned long long>(unsigned long long const, unsigned long long const, std::string const &);

    template <typename T>
    T Cin_Number(T const minimum_number_received, std::string const &ref_prefix_received)
    {
        return(Cin_Number(minimum_number_received,
                          (std::numeric_limits<T>::max)(),
                          ref_prefix_received));
    }

    template int                Cin_Number<int               >(int                const, std::string const &);
    template long               Cin_Number<long              >(long               const, std::string const &);
    template long long          Cin_Number<long long         >(long long          const, std::string const &);
    template unsigned int       Cin_Number<unsigned int      >(unsigned int       const, std::string const &);
    template unsigned long      Cin_Number<unsigned long     >(unsigned long      const, std::string const &);
    template unsigned long long Cin_Number<unsigned long long>(unsigned long long const, std::string const &);

    template <typename T>
    T Cin_Real_Number(T const minimum_real_number_received,
                      T const maximum_real_number_received,
                      std::string const &ref_prefix_received)
    {
        T tmp_return(0);

        std::string tmp_string_digit;

        std::smatch tmp_smatch;

        std::regex tmp_regex("^([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?)$");

        do
        {
            PRINT(ref_prefix_received);

            getline(std::cin, tmp_string_digit);

            if(tmp_string_digit.empty()) { continue; }

            if(std::regex_match(tmp_string_digit,
                                tmp_smatch,
                                tmp_regex,
                                std::regex_constants::match_default))
            {
                try
                {
                    if      constexpr (std::is_same<T, float      >::value) { tmp_return = std::stof (tmp_smatch[1u]); }
                    else if constexpr (std::is_same<T, double     >::value) { tmp_return = std::stod (tmp_smatch[1u]); }
                    else if constexpr (std::is_same<T, double long>::value) { tmp_return = std::stold(tmp_smatch[1u]); }
                    else { throw(std::logic_error("NotImplementedException")); }

                    if(     tmp_return < minimum_real_number_received) { continue; }
                    else if(tmp_return > maximum_real_number_received) { continue; }

                    return(tmp_return);
                }
                catch(...) { continue; }
            }
        } while(true);
    }

    template float       Cin_Real_Number<float      >(float       const, float       const, std::string const &);
    template double      Cin_Real_Number<double     >(double      const, double      const, std::string const &);
    template double long Cin_Real_Number<double long>(double long const, double long const, std::string const &);

    template <typename T>
    T Cin_Real_Number(T const minimum_real_number_received, std::string const &ref_prefix_received)
    {
        return(Cin_Real_Number(minimum_real_number_received,
                               (std::numeric_limits<T>::max)(),
                               ref_prefix_received));
    }

    template float       Cin_Real_Number<float      >(float       const, std::string const &);
    template double      Cin_Real_Number<double     >(double      const, std::string const &);
    template double long Cin_Real_Number<double long>(double long const, std::string const &);

    bool Accept(std::string const &ref_prefix_received)
    {
        std::string tmp_string_option;

        bool tmp_is_digit;

        int tmp_option;

        while(true)
        {
            std::cout << ref_prefix_received << " (No:[0], Yes:[1]): ";

            getline(std::cin, tmp_string_option);

            if(tmp_string_option.empty() == false)
            {
                tmp_is_digit = true;

                for(char &tmp_ref_char : tmp_string_option)
                {
                    if(isdigit(tmp_ref_char) == false)
                    {
                        tmp_is_digit = false;

                        break;
                    }
                }

                if(tmp_is_digit)
                {
                    tmp_option = std::stoi(tmp_string_option);

                    if(tmp_string_option.size() == 1_zu)
                    {
                        if(     tmp_option == 1) { return(true ); }
                        else if(tmp_option == 0) { return(false); }
                    }
                }
                else if(tmp_string_option.size() <= 3_zu)
                {
                    std::transform(tmp_string_option.begin(),
                                   tmp_string_option.end(),
                                   tmp_string_option.begin(),
                                   ::tolower);
                    if(strcmp(tmp_string_option.c_str(), "yes") == 0
                       ||
                       strcmp(tmp_string_option.c_str(), "ye" ) == 0
                       ||
                       strcmp(tmp_string_option.c_str(), "y"  ) == 0)
                    { return(true); }
                    else if(strcmp(tmp_string_option.c_str(), "no") == 0
                            ||
                            strcmp(tmp_string_option.c_str(), "n" ) == 0)
                    { return(false); }
                }
            }
        }
    }

    std::string To_Upper(std::string string_received)
    {
        std::locale tmp_locale;

        for(std::string::size_type i(0); i != string_received.length(); ++i)
        {
            string_received[i] = std::toupper(string_received[i], tmp_locale);
        }

        return(string_received);
    }

    void Print(char const *ptr_fmt_received, ...)
    {
        std::cout << MyEA::Time::Date_Time_Acc_Now() << ": ";

        va_list args; va_start(args, ptr_fmt_received);

        vprintf(ptr_fmt_received, args);

        va_end(args);

        std::cout << std::endl;
    }

    void Print_With_Prefix(std::string const &ref_prefix_received, char const *ptr_fmt_received, ...)
    {
        std::cout << MyEA::Time::Date_Time_Acc_Now() << ": " << ref_prefix_received;

        va_list args; va_start(args, ptr_fmt_received);

        vprintf(ptr_fmt_received, args);

        va_end(args);

        std::cout << std::endl;
    }
}

max_stars_repo_name: SebastienKeroack/MyEA

max_issues_repo_name: SebastienKeroack/MyEA

max_forks_repo_name: SebastienKeroack/MyEA


text:
#include <boost/test/unit_test.hpp>
#include "../util.hpp"
#include <iostream>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/expressions.hpp>

BOOST_AUTO_TEST_SUITE(util_test)
BOOST_AUTO_TEST_CASE(find_delinator_test) {
    std::vector<std::string> del;
    del.push_back(";");
    findDelineatorResult res = findDelineator("a;baa; ads;", del);
    BOOST_ASSERT(res.pos == 1);
    BOOST_ASSERT(res.delineator == ";");
    res = findDelineator("c ;d dd", del);
    BOOST_ASSERT(res.pos == 2);
}

BOOST_AUTO_TEST_CASE(split_string_basic_test) {
    std::vector<std::string> delinator;
    delinator.push_back(" ");
    delinator.push_back("\t");
    delinator.push_back(",");
    std::vector<std::string> result = splitString("a123 b123, c123 d123,e123,f123", delinator);
    BOOST_ASSERT(result.size() == 7);
    BOOST_ASSERT(result.at(0) == "a123");
    BOOST_ASSERT(result.at(1) == "b123");
    BOOST_ASSERT(result.at(2) == "");
    BOOST_ASSERT(result.at(3) == "c123");
    BOOST_ASSERT(result.at(4) == "d123");
    BOOST_ASSERT(result.at(5) == "e123");
    BOOST_ASSERT(result.at(6) == "f123");
}

BOOST_AUTO_TEST_CASE(split_string_remove_empty_test) {
    std::vector<std::string> delinator;
    delinator.push_back(" ");
    delinator.push_back("\t");
    delinator.push_back(",");
    std::vector<std::string> result = splitStringRemoveEmpty("a123 b123, c123 d123,e123,f123", delinator);
    BOOST_ASSERT(result.size() == 6);
    BOOST_ASSERT(result.at(0) == "a123");
    BOOST_ASSERT(result.at(1) == "b123");
    BOOST_ASSERT(result.at(2) == "c123");
    BOOST_ASSERT(result.at(3) == "d123");
    BOOST_ASSERT(result.at(4) == "e123");
    BOOST_ASSERT(result.at(5) == "f123");
}

BOOST_AUTO_TEST_CASE(isNumber_test) {
    BOOST_ASSERT(isNumber("-123") == true);
    BOOST_ASSERT(isNumber("123") == true);
    BOOST_ASSERT(isNumber("s-s") == false);
    BOOST_ASSERT(isNumber("asd") == false);
}
BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: noah-witt/riscv-engine

max_issues_repo_name: noah-witt/riscv-engine

max_forks_repo_name: noah-witt/riscv-engine


text:
#include <cradle/breakpad.hpp>

#include <codecvt>
#include <locale>

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>

#pragma warning(push, 0)
#include <client/windows/crash_generation/client_info.h>
#include <client/windows/crash_generation/crash_generation_server.h>
#include <client/windows/handler/exception_handler.h>
#include <client/windows/common/ipc_protocol.h>
#pragma warning(pop)

#include <cradle/io/file.hpp>

#ifdef NDEBUG
    #pragma comment(lib, "breakpad/lib/release/common")
    #pragma comment(lib, "breakpad/lib/release/crash_generation_server")
    #pragma comment(lib, "breakpad/lib/release/crash_generation_client")
    #pragma comment(lib, "breakpad/lib/release/exception_handler")
#else
    #pragma comment(lib, "breakpad/lib/debug/common")
    #pragma comment(lib, "breakpad/lib/debug/crash_generation_server")
    #pragma comment(lib, "breakpad/lib/debug/crash_generation_client")
    #pragma comment(lib, "breakpad/lib/debug/exception_handler")
#endif

namespace cradle {

struct crash_reporting_implementation
{
    alia__shared_ptr<google_breakpad::ExceptionHandler> handler;
    alia__shared_ptr<google_breakpad::CrashGenerationServer> server;
};

void static
start_crash_server(crash_reporting_implementation& impl,
    std::wstring const& crash_dir, std::wstring const& pipe_name)
{
    if (impl.server)
        return;

    impl.server.reset(
        new google_breakpad::CrashGenerationServer(
            pipe_name, NULL, NULL, NULL, NULL, NULL,
            NULL, NULL, NULL, NULL, true, &crash_dir));

    if (!impl.server->Start())
    {
        impl.server.reset();
        throw cradle::exception("Unable to start crash reporting server.");
    }
}

std::wstring static
to_wstring(string const& s)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t> > convert;
    return convert.from_bytes(s);
}

void static
begin_crash_reporting(crash_reporting_implementation& impl,
    file_path const& crash_dir, string const& app_id, string const& version)
{
    std::ostringstream pipe_stream;
    boost::uuids::uuid pipe_uuid = boost::uuids::random_generator()();
    pipe_stream << "\\\\.\\pipe\\CRADLE\\" + app_id + "\\" << pipe_uuid;
    auto pipe_name = to_wstring(pipe_stream.str());

    auto wide_app_id = to_wstring(app_id);
    auto wide_version = to_wstring(version);

    static size_t custom_info_count = 2;
    static google_breakpad::CustomInfoEntry custom_info_entries[] = {
        google_breakpad::CustomInfoEntry(L"app", wide_app_id.c_str()),
        google_breakpad::CustomInfoEntry(L"version", wide_version.c_str())
    };
    google_breakpad::CustomClientInfo custom_info =
        { custom_info_entries, custom_info_count};

    auto wide_crash_dir = crash_dir.string<std::wstring>();

    start_crash_server(impl, wide_crash_dir, pipe_name);
    // This is needed for CRT to not show dialog for invalid param
    // failures and instead let the code handle it.
    _CrtSetReportMode(_CRT_ASSERT, 0);
    impl.handler.reset(
        new google_breakpad::ExceptionHandler(
            wide_crash_dir, NULL, NULL, NULL,
            google_breakpad::ExceptionHandler::HANDLER_ALL,
            MiniDumpNormal, pipe_name.c_str(), &custom_info));
}

void crash_reporting_context::begin(
    file_path const& crash_dir, string const& app_id, string const& version)
{
    impl_ = new crash_reporting_implementation;
    begin_crash_reporting(*impl_, crash_dir, app_id, version);
}

void crash_reporting_context::end()
{
    delete impl_;
    impl_ = 0;
}

}

max_stars_repo_name: dotdecimal/open-cradle

max_issues_repo_name: dotdecimal/open-cradle

max_forks_repo_name: dotdecimal/open-cradle


text:
#ifndef BOOST_NETWORK_SUPPORT_SYNC_ONLY_HPP_20100927
#define BOOST_NETWORK_SUPPORT_SYNC_ONLY_HPP_20100927

//          Copyright Dean Michael Berris 2010.
// 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)

#include <boost/mpl/replace.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/network/tags.hpp>
#include <boost/mpl/placeholders.hpp>

namespace boost { namespace network {

    template <class Tag>
    struct sync_only :
        mpl::inherit_linearly<
            typename mpl::replace_if<
                typename tags::components<Tag>::type,
                is_same<mpl::placeholders::_,tags::async>,
                tags::sync
            >::type
            , mpl::inherit<mpl::placeholders::_1, mpl::placeholders::_2>
        >
    {};

} /* network */

} /* boost */

#endif /* BOOST_NETWORK_SUPPORT_SYNC_ONLY_HPP_20100927 */

max_stars_repo_name: antoinelefloch/cpp-netlib

max_issues_repo_name: waTeim/boost

max_forks_repo_name: waTeim/boost


text:
#include <boost/graph/graph_concepts.hpp>
#include <boost/graph/properties.hpp>
#include <boost/iterator/counting_iterator.hpp>
//#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/astar_search.hpp>

#include "boost/tuple/tuple.hpp"
#include <iostream>
#include <utility>
#include <map>

class knight_graph;
class knight_incident_edge_iterator;
class knight_adjacency_iterator;
struct edge_weight_map;

static const size_t BOARD_SIZE = 8;
static const size_t NUM_KNIGHT_MOVES = 8;
typedef int cost;

namespace boost {
  template<>
  struct property_map< knight_graph, edge_weight_t > {
    typedef edge_weight_map type;
    typedef edge_weight_map const_type;
  };

  template<>
  struct property_map< const knight_graph, edge_weight_t > {
    typedef edge_weight_map type;
    typedef edge_weight_map const_type;
  };
}

struct knight_traversal_category:
  virtual public boost::bidirectional_graph_tag,
  virtual public boost::incidence_graph_tag,
  virtual public boost::vertex_list_graph_tag
  {};

class knight_graph {
public:

  // Graph types
  typedef size_t vertex_descriptor;
  typedef boost::undirected_tag directed_category;
  //  typedef boost::directed_tag directed_category;
  typedef boost::disallow_parallel_edge_tag edge_parallel_category;
  typedef knight_traversal_category traversal_category;

  // IncidentGraph types
  typedef std::pair<vertex_descriptor, vertex_descriptor> edge_descriptor;
  typedef knight_incident_edge_iterator out_edge_iterator;
  typedef std::size_t degree_size_type;

  typedef knight_incident_edge_iterator in_edge_iterator;

  // VertexListGraph
  typedef boost::counting_iterator<vertex_descriptor> vertex_iterator;
  typedef std::size_t vertices_size_type;

  // EdgeListGraph associated types
  typedef void edge_iterator;
  typedef void edges_size_type;

  typedef vertex_descriptor vertex_property_type;

  knight_graph(){}

  std::size_t num_vertices()const { return BOARD_SIZE * BOARD_SIZE; }
private:
};

namespace boost
{
    template <> struct graph_traits<knight_graph>
    {
      typedef knight_graph G;

      typedef G::vertex_descriptor      vertex_descriptor;
      typedef G::edge_descriptor        edge_descriptor;
      typedef G::out_edge_iterator      out_edge_iterator;

      typedef G::directed_category      directed_category;
      typedef G::edge_parallel_category edge_parallel_category;
      typedef G::traversal_category     traversal_category;

      typedef G::degree_size_type       degree_size_type;

      typedef G::vertex_iterator vertex_iterator;
      typedef G::vertices_size_type vertices_size_type;

      typedef G::in_edge_iterator in_edge_iterator;
      typedef void edge_iterator;
      typedef void edges_size_type;

      //typedef void adjacency_iterator;
    };
}

typedef boost::graph_traits<knight_graph>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<knight_graph>::edge_descriptor edge_descriptor;
//typedef boost::graph_traits<knight_graph>::out_edge_iterator out_edge_iterator;
typedef boost::graph_traits<knight_graph>::degree_size_type degree_size_type;
typedef boost::graph_traits<knight_graph>::vertex_iterator vertex_iterator;
typedef boost::graph_traits<knight_graph>::vertices_size_type vertices_size_type;

//knight_graph::vertex_descriptor source(knight_graph::edge_descriptor e, const knight_graph&);
//knight_graph::vertex_descriptor target(knight_graph::edge_descriptor e, const knight_graph&);
//std::pair<knight_graph::out_edge_iterator,
//	  knight_graph::out_edge_iterator> out_edges(knight_graph::vertex_descriptor u,
//						     const knight_graph& g);
//knight_graph::degree_size_type out_degree(knight_graph::vertex_descriptor u, const knight_graph& g);

typedef std::pair < int, int > Position;
Position knight_jumps[NUM_KNIGHT_MOVES] = {
  Position(2, -1),
  Position(1, -2),
  Position(-1, -2),
  Position(-2, -1),
  Position(-2, 1),
  Position(-1, 2),
  Position(1, 2),
  Position(2, 1)
};

bool position_valid(Position p) {
  return p.first >= 0 && p.first < BOARD_SIZE && p.second >= 0 && p.second < BOARD_SIZE;
}

Position vertex_to_position(vertex_descriptor v) {
  return std::make_pair(v / BOARD_SIZE, v % BOARD_SIZE);
}

size_t position_to_vertex(Position p) {
  return BOARD_SIZE * p.first + p.second;
}

std::string chess_notation(Position p) {
  char rank_file[] = {'a' + p.first, '1' + p.second, 0};
  return std::string(rank_file);
}

std::ostream& operator<<(std::ostream& os, Position rhs) {
  //os << rhs.first << " " << rhs.second;
  //  os << 'a' + rhs.first << '1' + rhs.second);
  os << chess_notation(rhs);
  return os;
}

Position operator+(const Position & p1, const Position & p2) {
  return Position(p1.first + p2.first, p1.second + p2.second);
}

// IncidenceGraph valid expressions
 knight_graph::vertex_descriptor source(knight_graph::edge_descriptor e,
					const knight_graph&) {
  // The first vertex in the edge pair is the source.
   return e.first;
 }

 knight_graph::vertex_descriptor target(knight_graph::edge_descriptor e,
					const knight_graph&) {
 // The second vertex in the edge pair is the target.
 return e.second;
}

// VertexList expressions
vertices_size_type num_vertices(const knight_graph& g) {
  return g.num_vertices();
}

std::pair<vertex_iterator, vertex_iterator> vertices(const knight_graph& g) {
  return std::pair<vertex_iterator, vertex_iterator>(vertex_iterator(0),
						     vertex_iterator(num_vertices(g)));
}

 struct knight_incident_edge_iterator :
  public boost::iterator_facade<knight_incident_edge_iterator,
				std::pair<size_t, size_t>,
				boost::forward_traversal_tag,
				std::pair<size_t, size_t> >

 {
  knight_incident_edge_iterator():
    _edge_index(0),
    _v(0),
    _g(NULL)
  {}

  knight_incident_edge_iterator(int edge_index, size_t v,
				const knight_graph& g):
    _edge_index(edge_index),
    _v(v),
    _g(&g) {
    next_valid();
  }

   knight_incident_edge_iterator & operator=(const knight_incident_edge_iterator& rhs) {
     _edge_index = rhs._edge_index;
     _v = rhs._v;
     _g = rhs._g;
     return *this;
   }

   bool equal(const knight_incident_edge_iterator& rhs)const { return operator==(rhs); }
   void increment() { operator++(); }

  size_t operator*()const {
    return position_to_vertex(vertex_to_position(_v) +
			      knight_jumps[_edge_index]);
  }
  void operator++() { ++_edge_index; next_valid(); }
  bool operator==(const knight_incident_edge_iterator& rhs)const {
    return _edge_index == rhs._edge_index;
  }
protected:
  int _edge_index;
  size_t _v;
  const knight_graph* _g;

  void next_valid() {
    while (!position_valid(vertex_to_position(_v) + knight_jumps[_edge_index])
	   && _edge_index < NUM_KNIGHT_MOVES) {
      ++_edge_index;
    }
  }
};

 std::pair<knight_graph::out_edge_iterator, knight_graph::out_edge_iterator>
   out_edges(knight_graph::vertex_descriptor u,
	     const knight_graph& g) {
   return std::make_pair(knight_graph::out_edge_iterator(0, u, g),
			 knight_graph::out_edge_iterator(NUM_KNIGHT_MOVES, u, g));
}

 knight_graph::degree_size_type out_degree(knight_graph::vertex_descriptor u,
					   const knight_graph& g) {
   knight_graph::out_edge_iterator e, e_end;
   size_t degree = 0;
   for (boost::tie(e, e_end) = out_edges(u, g); !(e == e_end); ++e) {
     ++degree;
   }
   return degree;
 }

// BidirectionalGraph valid expressions
 std::pair<knight_graph::in_edge_iterator, knight_graph::in_edge_iterator>
  in_edges(knight_graph::vertex_descriptor u, const knight_graph& g) {
  // The in-edges and out-edges are the same in an undirected graph.
  return out_edges(u, g);
}

knight_graph::degree_size_type in_degree(knight_graph::vertex_descriptor u, const knight_graph& g) {
  // The in-degree and out-degree are both equal to the number of incident
  // edges in an undirected graph.
  return out_degree(u, g);
}

knight_graph::degree_size_type degree(knight_graph::vertex_descriptor u, const knight_graph& g) {
  // The in-degree and out-degree are both equal to the number of incident
  // edges in an undirected graph.
  return out_degree(u, g);
}

// euclidean distance heuristic
template <class Graph, class CostType>
  class distance_heuristic : public boost::astar_heuristic<Graph, CostType>
{
public:
  typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
  distance_heuristic(Vertex goal)
    : m_goal(goal) {}
  CostType operator()(Vertex u)
  {
    //    CostType dx = m_location[m_goal].x - m_location[u].x;
    //CostType dy = m_location[m_goal].y - m_location[u].y;
    //return ::sqrt(dx * dx + dy * dy);
    return 0;
  }
private:
  //  LocMap m_location;
  Vertex m_goal;
};

struct found_goal {}; // exception for termination

// visitor that terminates when we find the goal
template <class Vertex>
class astar_goal_visitor : public boost::default_astar_visitor
{
public:
  astar_goal_visitor(Vertex goal) : m_goal(goal) {}
  template <class Graph>
  void examine_vertex(Vertex u, Graph& g) {
    std::cout << "Exploring " << vertex_to_position(u) << "..." << std::endl;
    if(u == m_goal)
      throw found_goal();
  }
private:
  Vertex m_goal;
};

struct PredecessorMap {
  PredecessorMap() {}
  PredecessorMap(PredecessorMap const& rhs) : p(rhs.p) {}

  typedef size_t key_type;
  typedef size_t value_type;
  typedef size_t & reference_type;
  typedef boost::read_write_property_map_tag category;

  size_t & operator[](size_t v) { return p[v]; }

  std::map<size_t,size_t> p;
};

size_t get(PredecessorMap const& pm, size_t v) {
  std::map<size_t, size_t>::const_iterator found = pm.p.find(v);
  return (found != pm.p.end()) ? found->second : v;
}

void put(PredecessorMap & pm, size_t key, size_t value) {
    pm.p[key] = value;
}

struct edge_weight_map {
  typedef int value_type;
  typedef value_type reference;
  typedef edge_descriptor key_type;
  typedef boost::readable_property_map_tag category;

  // Edges have a weight equal to the average of their endpoint indexes.
  reference operator[](key_type e) const {
    return 1;
  }
};

typedef boost::property_map<knight_graph,
                            boost::edge_weight_t>::const_type
        const_edge_weight_map;
typedef boost::property_traits<const_edge_weight_map>::reference
        edge_weight_map_value_type;
typedef boost::property_traits<const_edge_weight_map>::key_type
        edge_weight_map_key;

// PropertyMap valid expressions
edge_weight_map_value_type
get(const_edge_weight_map pmap, edge_weight_map_key e) {
  return pmap[e];
}

// ReadablePropertyGraph valid expressions
const_edge_weight_map get(boost::edge_weight_t, const knight_graph&) {
  return const_edge_weight_map();
}

edge_weight_map_value_type get(boost::edge_weight_t tag,
                               const knight_graph& g,
                               edge_weight_map_key e) {
  return get(tag, g)[e];
}

// This expression is not part of a graph concept, but is used to return the
// default vertex index map used by the Dijkstra search algorithm.
boost::identity_property_map get(boost::vertex_index_t, const knight_graph&) {
  // The vertex descriptors are already unsigned integer indices, so just
  // return an identity map.
  return boost::identity_property_map();
}

int main(int argc, char **argv)
{
  using namespace boost;
  std::cout << "Running knight-graph" << std::endl;

  //BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept<knight_graph> ));
  //  BOOST_CONCEPT_ASSERT(( IncidentGraphConcept<knight_graph> ));
  BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<knight_graph> ));

  knight_graph g;

  std::cout << "vertices(g) =\n";
  boost::graph_traits<knight_graph>::vertex_iterator vi, vi_end;

  for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
    //   std::cout << "Vertex " << vertex_to_position(*vi) << std::endl;
  }

  int v = 50;
  std::cout << "out_degree(v, g) " << out_degree(v, g) << "\n";
  std::cout << vertex_to_position(v) <<  " adjacents\n";
  knight_graph::out_edge_iterator e, e_end;
  for (boost::tie(e, e_end) = out_edges(v, g); e != e_end; ++e) {
    std::cout << "e " << vertex_to_position(*e) << "\n";
  }

  std::vector<vertex_descriptor> p(g.num_vertices());
  std::vector<cost> d(g.num_vertices());
  //  astar_search_no_init(g, 0, distance_heuristic<knight_graph, cost>(10),
  //		       predecessor_map(&p[0]).
  //		       distance_map(&d[0]).
  //		       visitor(astar_goal_visitor<vertex_descriptor>(10)));

  knight_graph::vertex_descriptor source = 0;
  std::vector<knight_graph::vertex_descriptor> pred(g.num_vertices());
  std::vector<int> dist(g.num_vertices());

  //  dijkstra_shortest_paths(g, source,
  //			  predecessor_map(&pred[0]).distance_map(&dist[0]));
  std::cout << std::endl;
  return 0;
}

max_stars_repo_name: danielgrigg/sandbox

max_issues_repo_name: danielgrigg/sandbox

max_forks_repo_name: danielgrigg/sandbox


text:
#ifndef CPU_ONLY

#include <boost/thread.hpp>
#include <cstdlib>
#include <cstring>

#include "caffe/util/gpu_manager.hpp"

using std::malloc;
using std::realloc;
using std::free;

namespace caffe {
  // Make sure each thread can have different values.
  static boost::thread_specific_ptr<GpuStreamPool> thread_gsp_instance_;

  GpuStreamPool& GpuStreamPool::Get() {
    if (!thread_gsp_instance_.get()) {
      thread_gsp_instance_.reset(new GpuStreamPool());
    }

    return *(thread_gsp_instance_.get());
  }

  void GpuStreamPool::Reset() {
    thread_gsp_instance_.reset();
    return ;
  }

  void GpuStreamPool::SetPoolSize(size_t pool_size) {
    if (pool_size > GetCUDASettings(this->device_id_)) {
      LOG(INFO) << "Maximum concurrent streams between DEVICE " << this->device_id_
      << " and HOST is " << GetCUDASettings(this->device_id_) << ".";
      pool_size = GetCUDASettings(this->device_id_);
    }

    if ((this->handle_num_ >= pool_size) or pool_size <= 1) {
      return ;
    } else {
      LOG(INFO) << "Pool size: " << handle_num_ << " ---> " << pool_size;
      cudaStream_t* temp_streams = NULL;
      cublasHandle_t* temp_cublas_handler = NULL;
#ifdef USE_CUDNN
      cudnnHandle_t* temp_cudnn_handler = NULL;
#endif
      if (this->handle_num_ != 0) {
        temp_streams = this->streams_;
        temp_cublas_handler = this->cublas_handles_;
#ifdef USE_CUDNN
        temp_cudnn_handler = this->cudnn_handles_;
#endif
      }

      this->streams_ = new cudaStream_t[pool_size];
      this->cublas_handles_ = new cublasHandle_t[pool_size];

      if (this->streams_ == NULL || this->cublas_handles_ == NULL) {
        LOG(FATAL) << "Failed to malloc GpuStreamPool member handler.";
      }

#ifdef USE_CUDNN
      this->cudnn_handles_ = new cudnnHandle_t[pool_size];
      if (this->cudnn_handles_ == NULL) {
        LOG(FATAL) << "Failed to malloc cuDNN handler.";
      }
#endif

      memcpy(this->streams_, temp_streams, sizeof(cudaStream_t) * this->handle_num_);
      memcpy(this->cublas_handles_, temp_cublas_handler,
          sizeof(cublasHandle_t) * this->handle_num_);
#ifdef USE_CUDNN
      memcpy(this->cudnn_handles_, temp_cudnn_handler,
          sizeof(cudnnHandle_t) * this->handle_num_);
#endif
      for (int i = this->handle_num_; i < pool_size; ++ i) {
        CUDA_CHECK(cudaStreamCreate(&this->streams_[i]));
        CUBLAS_CHECK(cublasCreate(&this->cublas_handles_[i]));
        CUBLAS_CHECK(cublasSetStream(this->cublas_handles_[i], this->streams_[i]));
#ifdef USE_CUDNN
        CUDNN_CHECK(cudnnCreate(&this->cudnn_handles_[i]));
        CUDNN_CHECK(cudnnSetStream(this->cudnn_handles_[i], this->streams_[i]));
#endif
      }

      if (this->handle_num_ != 0) {
        if (temp_streams != NULL) {
          delete[] temp_streams;
        }
        if (temp_cublas_handler != NULL) {
          delete[] temp_cublas_handler;
        }
#ifdef USE_CUDNN
        if (temp_cudnn_handler != NULL) {
          delete[] temp_cudnn_handler;
        }
#endif
      }

      this->handle_num_ = pool_size;
    }
  }

  GpuStreamPool::GpuStreamPool() {
    CUDA_CHECK(cudaGetDevice(&this->device_id_));
    this->handle_num_ = 0;
    this->streams_ = NULL;
    this->cublas_handles_ = NULL;
#ifdef USE_CUDNN
    this->cudnn_handles_ = NULL;
#endif

    CUBLAS_CHECK(cublasCreate(&default_cublas_handle_));
    CUBLAS_CHECK(cublasSetStream(default_cublas_handle_, 0));
#ifdef USE_CUDNN
    CUDNN_CHECK(cudnnCreate(&default_cudnn_handle_));
    CUDNN_CHECK(cudnnSetStream(default_cudnn_handle_, 0));
#endif
  }

  GpuStreamPool::~GpuStreamPool() {
    cudaSetDevice(this->device_id_);
    for (int i = 0; i < handle_num_; ++ i) {
      CUBLAS_CHECK(cublasDestroy(cublas_handles_[i]));
#ifdef USE_CUDNN
      CUDNN_CHECK(cudnnDestroy(cudnn_handles_[i]));
#endif
      CUDA_CHECK(cudaStreamDestroy(streams_[i]));
    }

    CUBLAS_CHECK(cublasDestroy(default_cublas_handle_));
#ifdef USE_CUDNN
    CUDNN_CHECK(cudnnDestroy(default_cudnn_handle_));
#endif

    if (this->handle_num_ != 0) {
      delete[] this->streams_;
      delete[] this->cublas_handles_;
#ifdef USE_CUDNN
      delete[] this->cudnn_handles_;
#endif
    }
    this->handle_num_ = 0;
  }

  size_t GpuStreamPool::GetCUDASettings(const int device_id) {
    size_t temp_handles_num = 0;
    const char* cuda_connections = std::getenv("CUDA_DEVICE_MAX_CONNECTIONS");
    // CUDA_CHECK(cudaGetDevice(&this->device_id_));
    CUDA_CHECK(cudaGetDeviceProperties(&this->device_prop_, device_id));

    if (cuda_connections != NULL && strlen(cuda_connections) != 0) {
      temp_handles_num = static_cast<size_t>(std::atoi(cuda_connections));
    } else {
      GetCUDAConnNum(this->device_prop_.major,
          this->device_prop_.minor,
          temp_handles_num);
    }

    return temp_handles_num;
  }

  void GpuStreamPool::SetDevice(const int device_id) {
    if (device_id_ == device_id) {
      return ;
    } else {
      CUBLAS_CHECK(cublasDestroy(default_cublas_handle_));
#ifdef USE_CUDNN
      CUDNN_CHECK(cudnnDestroy(default_cudnn_handle_));
#endif

      if (this->handle_num_ != 0) {
        for (int i = 0; i < this->handle_num_; ++ i) {
          CUBLAS_CHECK(cublasDestroy(this->cublas_handles_[i]));
#ifdef USE_CUDNN
          CUDNN_CHECK(cudnnDestroy(this->cudnn_handles_[i]));
#endif
          CUDA_CHECK(cudaStreamDestroy(this->streams_[i]));
        }

        delete[] this->streams_;
        delete[] this->cublas_handles_;
#ifdef USE_CUDNN
        delete[] this->cudnn_handles_;
#endif
      }
    }

    CUDA_CHECK(cudaSetDevice(device_id));
    this->device_id_ = device_id;
    this->handle_num_ = 0;

    CUBLAS_CHECK(cublasCreate(&this->default_cublas_handle_));
    CUBLAS_CHECK(cublasSetStream(this->default_cublas_handle_, 0));
#ifdef USE_CUDNN
    CUDNN_CHECK(cudnnCreate(&this->default_cudnn_handle_));
    CUDNN_CHECK(cudnnSetStream(this->default_cudnn_handle_, 0));
#endif

    return ;
  }
}

#endif    /** CPU_ONLY **/