text:
#include <regex>
#include <boost/format.hpp>
#include "netlist_paths/Netlist.hpp"
#include "netlist_paths/ReadVerilatorXML.hpp"

using namespace netlist_paths;

Netlist::Netlist(const std::string &filename) {
  Options::getInstance(); // Create singleton object.
  ReadVerilatorXML(graph, files, dtypes, filename);
  graph.markAliasRegisters();
  graph.splitRegVertices();
  graph.updateVarAliases();
}

std::vector<Vertex*>
Netlist::createVertexPtrVec(VertexIDVec vertices) const {
  auto result = std::vector<Vertex*>();
  for (auto vertexId : vertices) {
    result.push_back(graph.getVertexPtr(vertexId));
  }
  return result;
}

std::vector<std::vector<Vertex*> >
Netlist::createVertexPtrVecVec(std::vector<VertexIDVec> paths) const {
  auto result = std::vector<std::vector<Vertex*> >();
  for (auto vertexIdVec : paths) {
    result.push_back(createVertexPtrVec(vertexIdVec));
  }
  return result;
}

const std::string
Netlist::reportMultipleMatches(VertexIDVec vertices,
                               const std::string name,
                               const std::string patternType) const {
  std::stringstream msg;
  msg << "multiple vertices matching " << patternType << " pattern: " << name << "\n";
  for (auto vertexID : vertices) {
    auto vertex = graph.getVertex(vertexID);
    msg << boost::format("%s %s\n") % vertex.getName() % vertex.getAstTypeStr();
  }
  return msg.str();
}

VertexID Netlist::getVertex(const std::string &name,
                                 VertexNetlistType vertexType) const {
  auto vertices = graph.getVertices(name, vertexType);
  if (vertices.size() > 1) {
    throw Exception(reportMultipleMatches(vertices, name));
  }
  if (vertices.size() == 1) {
    return vertices.front();
  }
  return graph.nullVertex();
}

VertexID Netlist::getRegVertex(const std::string &name, bool matchAny) const {
  auto vertices = graph.getRegVertices(name);
  if (!matchAny) {
    if (vertices.size() > 1) {
      throw Exception(reportMultipleMatches(vertices, name, "register"));
    }
    if (vertices.size() == 1) {
      return vertices.front();
    }
  } else {
    if (vertices.size()) {
      return vertices.front();
    }
  }
  return graph.nullVertex();
}

VertexID Netlist::getRegAliasVertex(const std::string &name, bool matchAny) const {
  auto vertices = graph.getRegAliasVertices(name);
  if (!matchAny) {
    if (vertices.size() > 1) {
      throw Exception(reportMultipleMatches(vertices, name, "register alias"));
    }
    if (vertices.size() == 1) {
      return vertices.front();
    }
  } else {
    if (vertices.size()) {
      return vertices.front();
    }
  }
  return graph.nullVertex();
}

VertexID Netlist::getStartVertex(const std::string &name, bool matchAny) const {
  auto vertices = graph.getStartVertices(name);
  if (!matchAny) {
    if (vertices.size() > 1) {
      throw Exception(reportMultipleMatches(vertices, name, "start point"));
    }
    if (vertices.size() == 1) {
      return vertices.front();
    }
  } else {
    if (vertices.size()) {
      return vertices.front();
    }
  }
  return graph.nullVertex();
}

VertexID Netlist::getEndVertex(const std::string &name, bool matchAny) const {
  auto vertices = graph.getEndVertices(name);
  if (!matchAny) {
    if (vertices.size() > 1) {
      throw Exception(reportMultipleMatches(vertices, name, "end point"));
    }
    if (vertices.size() == 1) {
      return vertices.front();
    }
  } else {
    if (vertices.size()) {
      return vertices.front();
    }
  }
  return graph.nullVertex();
}

VertexID Netlist::getMidVertex(const std::string &name, bool matchAny) const {
  auto vertices = graph.getMidVertices(name);
  if (!matchAny) {
    if (vertices.size() > 1) {
      throw Exception(reportMultipleMatches(vertices, name, "mid point"));
    }
    if (vertices.size() == 1) {
      return vertices.front();
    }
  } else {
    if (vertices.size()) {
      return vertices.front();
    }
  }
  return graph.nullVertex();
}

const std::string
Netlist::getVertexDTypeStr(const std::string &name,
                           VertexNetlistType vertexType) const {
  auto vertex = getVertex(name, vertexType);
  if (vertex == graph.nullVertex()) {
    throw Exception(std::string("could not find vertex "+name));
  }
  return graph.getVertex(vertex).getDTypeStr();
}

size_t
Netlist::getVertexDTypeWidth(const std::string &name,
                             VertexNetlistType vertexType) const {
  auto vertex = getVertex(name, vertexType);
  if (vertex == graph.nullVertex()) {
    throw Exception(std::string("could not find vertex "+name));
  }
  return graph.getVertex(vertex).getDTypeWidth();
}

const std::shared_ptr<DType> Netlist::getDType(const std::string &name) const {
  auto dtype = std::find_if(std::begin(dtypes), std::end(dtypes),
                            [&name](const std::shared_ptr<DType> &dt) {
                              return dt->getName() == name; });
  if (dtype != std::end(dtypes)) {
    return *dtype;
  } else {
    return std::shared_ptr<DType>();
  }
}

size_t Netlist::getDTypeWidth(const std::string &name) const {
  if (auto dtype = getDType(name)) {
    return dtype->getWidth();
  } else {
    throw Exception(std::string("could not find dtype "+name));
  }
}

VertexIDVec Netlist::readWaypoints(Waypoints waypoints) const {
  VertexIDVec waypointIDs;
  for (auto it = waypoints.getWaypoints().begin();
            it != waypoints.getWaypoints().end(); ++it) {
    VertexID vertex;
    // Start
    if (it == waypoints.getWaypoints().begin()) {
      vertex = getStartVertex(*it, Options::getInstance().isMatchAnyVertex());
      if (vertex == graph.nullVertex()) {
        throw Exception(std::string("could not find start vertex matching ")+*it);
      }
    // Finish
    } else if (it+1 == waypoints.getWaypoints().end()) {
      vertex = getEndVertex(*it, Options::getInstance().isMatchAnyVertex());
      if (vertex == graph.nullVertex()) {
        throw Exception(std::string("could not find end vertex matching ")+*it);
      }
    // Mid
    } else {
      vertex = getMidVertex(*it, Options::getInstance().isMatchAnyVertex());
      if (vertex == graph.nullVertex()) {
        throw Exception(std::string("could not find through vertex ")+*it);
      }
    }
    waypointIDs.push_back(vertex);
  }
  return waypointIDs;
}

VertexIDVec Netlist::readAvoidPoints(Waypoints waypoints) const {
  VertexIDVec avoidPointIDs;
  for (auto name : waypoints.getAvoidPoints()) {
    auto vertex = getMidVertex(name, Options::getInstance().isMatchAnyVertex());
    if (vertex == graph.nullVertex()) {
      throw Exception(std::string("could not find vertex to avoid ")+name);
    }
    avoidPointIDs.push_back(vertex);
  }
  // Sort the IDs so they can be binary searched.
  std::sort(avoidPointIDs.begin(), avoidPointIDs.end());
  return avoidPointIDs;
}

bool Netlist::startpointExists(const std::string &name) const {
  return getStartVertex(name, false) != graph.nullVertex();
}

bool Netlist::endpointExists(const std::string &name) const {
  return getEndVertex(name, false) != graph.nullVertex();
}

bool Netlist::anyStartpointExists(const std::string &name) const {
  return getStartVertex(name, true) != graph.nullVertex();
}

bool Netlist::anyEndpointExists(const std::string &name) const {
  return getEndVertex(name, true) != graph.nullVertex();
}

bool Netlist::anyRegExists(const std::string &name) const {
  // Allow matching with register or register alias variables.
  auto regVertices = graph.getRegVertices(name);
  auto regAliasVertices = graph.getRegAliasVertices(name);
  return (regVertices.size() != 0) || (regAliasVertices.size() != 0);
}

bool Netlist::regExists(const std::string &name) const {
  // Allow matching with register or register alias variables.
  return (getRegVertex(name, false) != graph.nullVertex()) ||
         (getRegAliasVertex(name, false) != graph.nullVertex());
}

bool Netlist::pathExists(Waypoints waypoints) const {
  auto waypointIDs = readWaypoints(waypoints);
  auto avoidPointIDs = readAvoidPoints(waypoints);
  return !graph.getAnyPointToPoint(waypointIDs, avoidPointIDs).empty();
}

std::vector<Vertex*> Netlist::getAnyPath(Waypoints waypoints) const {
  auto waypointIDs = readWaypoints(waypoints);
  auto avoidPointIDs = readAvoidPoints(waypoints);
  return createVertexPtrVec(graph.getAnyPointToPoint(waypointIDs,
                                                       avoidPointIDs));
}

std::vector<std::vector<Vertex*> > Netlist::getAllPaths(Waypoints waypoints) const {
  auto waypointIDs = readWaypoints(waypoints);
  auto avoidPointIDs = readAvoidPoints(waypoints);
  return createVertexPtrVecVec(graph.getAllPointToPoint(waypointIDs,
                                                          avoidPointIDs));
}

std::vector<std::vector<Vertex*> > Netlist::getAllFanOut(const std::string startName) const {
  auto vertex = getStartVertex(startName, Options::getInstance().isMatchAnyVertex());
  if (vertex == graph.nullVertex()) {
    throw Exception(std::string("could not find start vertex "+startName));
  }
  return createVertexPtrVecVec(graph.getAllFanOut(vertex));
}

std::vector<std::vector<Vertex*> > Netlist::getAllFanIn(const std::string endName) const {
  auto vertex = getEndVertex(endName, Options::getInstance().isMatchAnyVertex());
  if (vertex == graph.nullVertex()) {
    throw Exception(std::string("could not find end vertex "+endName));
  }
  return createVertexPtrVecVec(graph.getAllFanIn(vertex));
}

std::vector<std::reference_wrapper<const Vertex> >
Netlist::getNamedVertices(const std::string pattern) const {
  // Collect vertices.
  std::vector<std::reference_wrapper<const Vertex>> vertices;
  for (auto vertexId : graph.getVertices(pattern, VertexNetlistType::IS_NAMED)) {
    vertices.push_back(std::ref(graph.getVertex(vertexId)));
  }
  // Sort them.
  auto compare = [](const Vertex& a, const Vertex& b) {
                   return a.compareLessThan(b); };
  std::sort(vertices.begin(), vertices.end(), compare);
  return vertices;
}

max_stars_repo_name: jameshanlon/netlist-paths

max_issues_repo_name: jameshanlon/netlist-paths

max_forks_repo_name: jameshanlon/netlist-paths


text:
/*!
@file
Defines `boost::hana::lockstep`.

@copyright Louis Dionne 2013-2016
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
 */

#ifndef BOOST_HANA_FUNCTIONAL_LOCKSTEP_HPP
#define BOOST_HANA_FUNCTIONAL_LOCKSTEP_HPP

#include <boost/hana/basic_tuple.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/detail/decay.hpp>

#include <cstddef>
#include <utility>

BOOST_HANA_NAMESPACE_BEGIN
    //! @ingroup group-functional
    //! Invoke a function with the result of invoking other functions on its
    //! arguments, in lockstep.
    //!
    //! Specifically, `lockstep(f)(g1, ..., gN)` is a function such that
    //! @code
    //!     lockstep(f)(g1, ..., gN)(x1, ..., xN) == f(g1(x1), ..., gN(xN))
    //! @endcode
    //!
    //! Since each `g` is invoked on its corresponding argument in lockstep,
    //! the number of arguments must match the number of `g`s.
    //!
    //!
    //! Example
    //! -------
    //! @include example/functional/lockstep.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto lockstep = [](auto&& f, auto&& ...g) {
        return [perfect-capture](auto&& ...x) -> decltype(auto) {
            return forwarded(f)(forwarded(g)(forwarded(x))...);
        };
    };
#else
    template <typename Indices, typename F, typename ...G>
    struct lockstep_t;

    template <typename F>
    struct pre_lockstep_t;

    struct make_pre_lockstep_t {
        struct secret { };
        template <typename F>
        constexpr pre_lockstep_t<typename detail::decay<F>::type> operator()(F&& f) const {
            return {static_cast<F&&>(f)};
        }
    };

    template <std::size_t ...n, typename F, typename ...G>
    struct lockstep_t<std::index_sequence<n...>, F, G...> {
        template <typename ...T>
        constexpr lockstep_t(make_pre_lockstep_t::secret, T&& ...t)
            : storage_{static_cast<T&&>(t)...}
        { }

        basic_tuple<F, G...> storage_;

        template <typename ...X>
        constexpr decltype(auto) operator()(X&& ...x) const& {
            return hana::get_impl<0>(storage_)(
                hana::get_impl<n+1>(storage_)(static_cast<X&&>(x))...
            );
        }

        template <typename ...X>
        constexpr decltype(auto) operator()(X&& ...x) & {
            return hana::get_impl<0>(storage_)(
                hana::get_impl<n+1>(storage_)(static_cast<X&&>(x))...
            );
        }

        template <typename ...X>
        constexpr decltype(auto) operator()(X&& ...x) && {
            return static_cast<F&&>(hana::get_impl<0>(storage_))(
                static_cast<G&&>(hana::get_impl<n+1>(storage_))(static_cast<X&&>(x))...
            );
        }
    };

    template <typename F>
    struct pre_lockstep_t {
        F f;

        template <typename ...G>
        constexpr lockstep_t<std::make_index_sequence<sizeof...(G)>, F,
                             typename detail::decay<G>::type...>
        operator()(G&& ...g) const& {
            return {make_pre_lockstep_t::secret{}, this->f, static_cast<G&&>(g)...};
        }

        template <typename ...G>
        constexpr lockstep_t<std::make_index_sequence<sizeof...(G)>, F,
                             typename detail::decay<G>::type...>
        operator()(G&& ...g) && {
            return {make_pre_lockstep_t::secret{}, static_cast<F&&>(this->f),
                                                   static_cast<G&&>(g)...};
        }
    };

    constexpr make_pre_lockstep_t lockstep{};
#endif
BOOST_HANA_NAMESPACE_END

#endif // !BOOST_HANA_FUNCTIONAL_LOCKSTEP_HPP

ext: hpp

max_stars_repo_name: EuroLine/nheqminer


text:
#ifndef HERMIT_SPIRIT_QI_ASCTIME_HPP
#define HERMIT_SPIRIT_QI_ASCTIME_HPP

#include <iostream>
#include <vector>
#include <string>
#include <boost/date_time/date_defs.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/gregorian_calendar.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace hermit {
  namespace spirit {
    namespace qi {
      template <typename InputIterator>
        class asctime :
          public boost::spirit::qi::grammar< InputIterator, boost::posix_time::ptime() > {
            public:
              asctime() : asctime::base_type( root ) {
                namespace qi = boost::spirit::qi;
                namespace dt = boost::date_time;
                namespace phx = boost::phoenix;
                root = ( wkday >> qi::omit[ +qi::standard::space ] >> date )[
                  qi::_pass = qi::_1 == phx::bind( &boost::gregorian::date::day_of_week, &phx::at_c< 0 >( qi::_2 ) ),
                  qi::_val = phx::construct< boost::posix_time::ptime >(
                    phx::at_c< 0 >( qi::_2 ), phx::at_c< 1 >( qi::_2 )
                  )
                ];
                date = ( month >> qi::omit[ +qi::standard::space ] >> dec2_p >> qi::omit[ +qi::standard::space ] >>
                         time >> qi::omit[ +qi::standard::space ] >> dec4_p )[
                  qi::_pass = qi::_2 <= phx::bind( boost::gregorian::gregorian_calendar::end_of_month_day, qi::_4, qi::_2 ),
                  phx::at_c< 0 >( qi::_val ) = phx::construct< boost::gregorian::date >( qi::_4, qi::_1, qi::_2 ),
                  phx::at_c< 1 >( qi::_val ) = qi::_3
                ];
                time = ( dec2_p >> ':' >> dec2_p >> ':' >> dec2_p )[
                  qi::_pass = qi::_1 < 24u && qi::_2 < 60u && qi::_3 < 60u,
                  qi::_val = phx::construct< boost::posix_time::time_duration >( qi::_1, qi::_2, qi::_3 )
                ];
                wkday.add( "Mon", dt::Monday )( "Tue", dt::Tuesday )( "Wed", dt::Wednesday )( "Thu", dt::Thursday )
                         ( "Fri", dt::Friday )( "Sat", dt::Saturday )( "Sun", dt::Sunday );
                month.add( "Jan", dt::Jan )( "Feb", dt::Feb )( "Mar", dt::Mar )( "Apr", dt::Apr )
                         ( "May", dt::May )( "Jun", dt::Jun )( "Jul", dt::Jul )( "Aug", dt::Aug )
                         ( "Sep", dt::Sep )( "Oct", dt::Oct )( "Nov", dt::Nov )( "Dec", dt::Dec );
              }
            private:
              boost::spirit::qi::uint_parser<unsigned int, 10, 2, 2> dece2_p;
              boost::spirit::qi::uint_parser<unsigned int, 10, 1, 2> dec2_p;
              boost::spirit::qi::uint_parser<unsigned int, 10, 1, 4> dec4_p;
              boost::spirit::qi::rule< InputIterator, boost::posix_time::ptime() > root;
              boost::spirit::qi::rule< InputIterator, boost::fusion::vector< boost::gregorian::date, boost::posix_time::time_duration >() > date;
              boost::spirit::qi::rule< InputIterator, boost::posix_time::time_duration() > time;
              boost::spirit::qi::symbols< char, boost::date_time::weekdays > wkday;
              boost::spirit::qi::symbols< char, boost::posix_time::time_duration > zone_name;
              boost::spirit::qi::symbols< char, boost::date_time::months_of_year > month;
      };
    }
  }
}

#endif

max_stars_repo_name: Fadis/hermit

max_issues_repo_name: Fadis/hermit

max_forks_repo_name: Fadis/hermit


text:
// (C) Copyright Renaud Detry   2007-2008.
// 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)

/** @file */

#ifndef NUKLEI_TRSL_IS_PICKED_SYSTEMATIC_HPP
#define NUKLEI_TRSL_IS_PICKED_SYSTEMATIC_HPP

#include <nuklei/trsl/common.hpp>
#include <nuklei/trsl/weight_accessor.hpp>

#include <algorithm>
#include <functional>
#include <utility>
#include <cstdlib> // rand & random
#include <limits>
#include <cassert>
#include <boost/static_assert.hpp>

/** @brief Public namespace. */
namespace nuklei_trsl {

  /**
   * @brief Functor to use with persistent_filter_iterator for
   * systematic sampling of a range.
   *
   * The sampling method is systematic sampling [1, 2].
   *
   * This class is intended to be used as a predicate functor to
   * trsl::persistent_filter_iterator to form a sample
   * iterator. The sample iterator accesses a population of
   * elements through a range defined by a pair of Forward Iterators
   * (begin/end), and provides on-the-fly iteration through a sample
   * of the population.
   *
   * Systematic sampling may perform very badly if the order in which
   * the input population is presented is following a pattern. If a
   * pattern is likely to occur in the population, the user may want to
   * pipe the sample iterator after a
   * trsl::random_permutation_iterator, or use is_picked_systematic with
   * ppfilter_iterator.  The resulting iterator effectively implements
   * probability sampling.  The price to pay for probability
   * sampling is a Random Access Iterator. While
   * persistent_filter_iterator will work e.g. with <tt>std::list</tt>,
   * ppfilter_iterator requires e.g. <tt>std::vector</tt> or
   * <tt>std::deque</tt>.
   *
   * @param ElementType Type of the elements in the
   * population. Constness and
   * reference modifiers are handled internally; this parameter should be
   * a bare type, e.g. <tt>Particle</tt> (not <tt>const Particle&</tt>).
   *
   * @param WeightType Element weight type, should be a floating point type.
   * Defaults to <tt>double</tt>.
   *
   * @param WeightAccessor Type of the accessor that will allow to
   * extract weights from elements. Defaults to mp_weight_accessor,
   * see @ref accessor for further details on accessors.
   *
   * References:
   *
   * - [1] R. Douc, O. Cappe, and E. Moulines. Comparison of
   * resampling schemes for particle filtering. International
   * Symposium on Parallel and Distributed Processing and
   * Applications, 2005:64, 2005.
   *
   * - [2] J. Hol, T. Schön, and F. Gustafsson. On resampling
   * algorithms for particle filters. In Nonlinear Statistical Signal
   * Processing Workshop, 2006.
   */
  template<
    typename ElementType,
    typename WeightType = double,
    typename WeightAccessor = mp_weight_accessor<WeightType, ElementType>
  > class is_picked_systematic
  {
  private:
    BOOST_STATIC_ASSERT((std::numeric_limits<WeightType>::is_integer == false));
  public:
    typedef ElementType element_type;
    typedef WeightType weight_type;
    typedef WeightAccessor weight_accessor_type;

    /**
     * @brief Default constructor, shoud not be used explicitely.
     *
     * This constructor makes an invalid predicate. It should only be used in
     * cases where the predicate is never used.
     */
    is_picked_systematic() :
      sampleSize_(0),
      populationWeight_(0)
      {
        initialize( 0 );
      }

    /**
     * @brief Construction with system-provided random number.
     *
     * The systematic sampling predicate initialization needs a random
     * number in <tt>[0,1[</tt>.  This constructor uses
     * trsl::rand_gen::uniform_01 to generate that number.  See @ref
     * random for more details.
     *
     * @param sampleSize Number of elements in the sample, within
     * <tt>[0, infinity[</tt>.
     *
     * @param populationWeight Total weight of the
     * population, within <tt>]0, infinity[</tt>. Generally equal to 1.
     *
     * @param wac Weight accessor. Defaults to
     * mp_weight_accessor. Note that if you don't pass explicitly a
     * mp_weight_accessor(<tt>&ElementType::GETWEIGHTMETHOD</tt>), the
     * default constructor for mp_weight_accessor will setup to always
     * return 1, ignoring element weights. See @ref accessor for
     * further details.
     *
     * The population weight has to be strictly larger than 0. Also,
     * @p WeightType should be fine enough to allow the sum of all
     * element weights to be close to @p populationWeight.
     */
    is_picked_systematic(size_t sampleSize,
                         WeightType populationWeight,
                         WeightAccessor const& wac = WeightAccessor()) :
      wac_(wac), sampleSize_(sampleSize),
      populationWeight_(populationWeight)
      {
        initialize( rand_gen::uniform_01<WeightType>() );
      }

    /**
     * @brief Construction with user-provided random number.
     *
     * The systematic sampling predicate initialization needs a random
     * number in <tt>[0,1[</tt>.  This constructor allows the user to
     * provide that number directly; the user is free to choose a
     * fancy random number generator, such as the Boost
     * Random Number Library or GSL.
     *
     * @param sampleSize Number of elements in the sample, within
     * <tt>[0, infinity[</tt>.
     *
     * @param populationWeight Total weight of the
     * population, within <tt>]0, infinity[</tt>. Generally equal to 1.
     *
     * @param uniform01 Random number in <tt>[0,1[</tt>.
     *
     * @param wac Weight accessor. Defaults to
     * mp_weight_accessor. Note that if you don't pass explicitly a
     * mp_weight_accessor(<tt>&ElementType::GETWEIGHTMETHOD</tt>), the
     * default constructor for mp_weight_accessor will setup to always
     * return 1, ignoring element weights. See @ref accessor for
     * further details.
     *
     * The population weight has to be strictly larger than 0. Also,
     * @p WeightType should be fine enough to allow the sum of all
     * element weights to be close to @p populationWeight.
     */
    is_picked_systematic(size_t sampleSize,
                         WeightType populationWeight,
                         WeightType uniform01,
                         WeightAccessor const& wac = WeightAccessor()) :
      wac_(wac), sampleSize_(sampleSize),
      populationWeight_(populationWeight)
      {
        initialize(uniform01);
      }

    /**
     * @brief Decides whether <tt>e</tt> should be picked or not (used
     * by persistent_filter_iterator).
     *
     * Part of the requirements for persistent_filter_iterator
     * predicates.
     */
    bool operator()(const ElementType & e)
      {
        if (sampleSize_ == 0) return false;

#ifdef NUKLEI_TRSL_USE_SYSTEMATIC_INTUITIVE_ALGORITHM
        // This algorithm is the intuitive implementation of
        // systematic sampling, where one pictures a wheel with
        // N_SAMPLE spokes and distributes the population around the
        // wheel as segments of tire of length proportional to their
        // weight; the spokes point to picked elements.
        WeightType arrow = k_*step_;
        assert(cumulative_ <= arrow);
        if (arrow < cumulative_ + wac_(e))
        {
          k_++;
          return true;
        }
        cumulative_ += wac_(e);
        return false;
#else
        // This algorithm is a massaged version of the intuitive
        // algorithm.  Both algorithms are conceptually identical, but
        // this version is faster.
        assert(position_ >= 0);
        if (position_ < wac_(e))
        {
          position_ += step_;
          return true;
        }
        position_ -= wac_(e);
        return false;
#endif
      }

    /**
     * @brief Return whether @p e has been picked already.
     *
     * This method will return a coherent value only if the last
     * call of operator()(const ElementType&) was on @p e and returned true.
     * When is_picked_systematic is used with a presistent_filter_iterator @p i,
     * this assumption is always valid for @p *i as long as @p i is not the end.
     *
     * This method is awkward to use directly; it is meant to be called by
     * trsl::is_first_pick.
     */
    bool is_first_pick(const ElementType & e) const
    {
      if (wac_(e) <= step_) return true;
#ifdef NUKLEI_TRSL_USE_SYSTEMATIC_INTUITIVE_ALGORITHM
      return k_*step_ - cumulative_ < 2*step_;
#else
      return position_ < 2*step_;
#endif
    }

    /**
     * @brief Returns whether two predicates are at the same sampling
     * advancement.
     *
     * Part of the requirements for persistent_filter_iterator
     * predicates.
     */
    bool operator== (const is_picked_systematic<ElementType, WeightType, WeightAccessor> &p) const
      {
        if (sampleSize_ != p.sampleSize_ ||
            populationWeight_ != p.populationWeight_) return false;

#ifdef NUKLEI_TRSL_USE_SYSTEMATIC_INTUITIVE_ALGORITHM
        if (cumulative_ != p.cumulative_ ||
            k_ != p.k_) return false;
#else
        if (position_ != p.position_) return false;
#endif

        return true;
      }

  private:
    void initialize(WeightType randomReal)
      {
        // If one could rely on
        //
        //   (x!=0.0)/0.0 == inf (with the sign of x)
        //
        // and on
        //
        //   0.0 * inf == NaN,
        //
        // neither of these throwing exceptions, then the following
        // block could be avoided, and the case sampleSize_ == 0 would
        // be implicitly handled by inf/NaN arithmetic.
        //
        // However, it would be necessary to maintain two different
        // implementations depending on
        // std::numeric_limits<double>::is_iec559, and even then I'm
        // not sure if inf/NaN arithmetic is reliable.
        if (sampleSize_ != 0)
          step_ = populationWeight_ / sampleSize_;
        else
          // A semantically correct value for step_ would be inf, but
          // we don't want to get into has_infinity trouble...
          // When sampleSize_==0, step_ should be considered undefined.
          step_ = 0;

        WeightType randomWeight = randomReal * step_;
#ifdef NUKLEI_TRSL_USE_SYSTEMATIC_INTUITIVE_ALGORITHM
        cumulative_ = -randomWeight;
        k_ = 0;
#else
        position_ = randomWeight;
#endif
      }

  private:
    WeightAccessor wac_;
    size_t sampleSize_;
    WeightType populationWeight_;
    WeightType step_;

#ifdef NUKLEI_TRSL_USE_SYSTEMATIC_INTUITIVE_ALGORITHM
    WeightType cumulative_;
    size_t k_;
#else
    WeightType position_;
#endif
  };

  /**
   * @brief Return whether @p *i has been picked already.
   *
   * This function calls <tt>i.predicate().is_first_pick(*i)</tt>.
   *
   * When sampling from a population, elements with a large weight may be selected several times.
   * This function checks if the element pointed by @p *i has been selected already, e.g. at <tt>*(i-1)</tt>.
   *
   * @param Iterator Will typically be trsl::pp_filter_iterator or trsl::persitent_filter_iterator.
   *
   * @param i Instance of pp_filter_iterator or persitent_filter_iterator. Should not be the end.
   */
  template<class Iterator>
  bool is_first_pick(const Iterator& i)
  {
    return i.predicate().is_first_pick(*i);
  }

}

#endif // include guard

max_stars_repo_name: chungying/nuklei

max_issues_repo_name: chungying/nuklei

max_forks_repo_name: chungying/nuklei


text:
#include "probability.h"

#include "plugin_factory.h"

#include "logger.h"
#include "fetcher.h"
#include "writer.h"

#include "ensemble.h"
#include "lagged_ensemble.h"
#include "util.h"

#include <boost/thread.hpp>

#include <algorithm>
#include <exception>
#include <iostream>

#include "radon.h"
#include <math.h>

namespace himan
{
namespace plugin
{
static std::mutex singleFileWriteMutex;

static const std::string kClassName = "himan::plugin::probability";

/// @brief Used for calculating wind vector magnitude
static inline double Magnitude(double u, double v) { return sqrt(u * u + v * v); }
probability::probability()
{
	itsCudaEnabledCalculation = false;
	itsLogger = logger("probability");

	itsEnsembleSize = 0;
	itsMaximumMissingForecasts = 0;
	itsUseNormalizedResult = false;
	itsUseLaggedEnsemble = false;
	itsLag = 0;
	itsLaggedSteps = 0;
}

probability::~probability() {}
/// @brief Configuration reading
/// @param outParamConfig is modified to have information about the threshold value and input parameters
/// @returns param to be pushed in the calculatedParams vector in Process()
static param GetConfigurationParameter(const std::string& name, const std::shared_ptr<const plugin_configuration> conf,
                                       param_configuration* outParamConfig)
{
	if (conf->ParameterExists(name))
	{
		const auto paramOpts = conf->GetParameterOptions(name);

		param param1;
		param param2;

		// NOTE These are plugin dependent
		for (auto&& p : paramOpts)
		{
			if (p.first == "threshold")
			{
				outParamConfig->gridThreshold = std::stod(p.second);
			}
			else if (p.first == "input_param1")
			{
				param1.Name(p.second);
			}
			else if (p.first == "input_param2")
			{
				param2.Name(p.second);
			}
			else
			{
				auto elems = util::Split(p.first, "_", false);
				if (elems.size() == 2 && elems[0] == "threshold")
				{
					outParamConfig->stationThreshold[std::stoi(elems[1])] = std::stod(p.second);
				}
			}
		}

		if (param1.Name() == "XX-X")
		{
			throw std::runtime_error("probability : configuration error:: input parameter not specified for '" + name +
			                         "'");
		}
		outParamConfig->parameter = param1;

		// NOTE param2 is used only with wind calculation at the moment
		if (param2.Name() != "XX-X")
		{
			outParamConfig->parameter2 = param2;
		}
	}
	else
	{
		throw std::runtime_error(
		    "probability : configuration error:: requested parameter doesn't exist in the configuration file '" + name +
		    "'");
	}

	return param(name);
}

void probability::Process(const std::shared_ptr<const plugin_configuration> conf)
{
	Init(conf);

	//
	// 1. Parse json configuration specific to this plugin
	//

	// Most of the plugin operates by the configuration in the json file.
	// Here we collect all the parameters we want to calculate, and the parameters that are used for the calculation.
	// If the configuration is invalid we will bail out asap!

	// Get the number of forecasts this ensemble has from plugin configuration
	if (itsConfiguration->Exists("ensemble_size"))
	{
		const int ensembleSize = std::stoi(itsConfiguration->GetValue("ensemble_size"));
		if (ensembleSize <= 0)
		{
			throw std::runtime_error(ClassName() + " invalid ensemble_size in plugin configuration");
		}
		itsEnsembleSize = ensembleSize;
	}
	else
	{
		throw std::runtime_error(ClassName() + " ensemble_size not specified in plugin configuration");
	}

	// Find out whether we want probabilities in [0,1] range or [0,100] range
	if (itsConfiguration->Exists("normalized_results"))
	{
		const std::string useNormalized = itsConfiguration->GetValue("normalized_results");

		itsUseNormalizedResult = (useNormalized == "true") ? true : false;
	}
	else
	{
		// default to [0,100] for compatibility
		itsUseNormalizedResult = false;
		itsLogger.Info(
		    "'normalized_results' not found from the configuration, results will be written in [0,100] range");
	}

	// Maximum number of missing forecasts for an ensemble
	if (itsConfiguration->Exists("max_missing_forecasts"))
	{
		const int maxMissingForecasts = std::stoi(itsConfiguration->GetValue("max_missing_forecasts"));
		if (maxMissingForecasts < 0)
		{
			throw std::runtime_error(ClassName() +
			                         " invalid max_missing_forecasts value specified in plugin configuration");
		}
		itsMaximumMissingForecasts = maxMissingForecasts;
	}

	// Are we using lagged ensemble?
	// NOTE 'lag' needs to be specified first
	if (itsConfiguration->Exists("lag"))
	{
		int lag = std::stoi(itsConfiguration->GetValue("lag"));
		if (lag == 0)
		{
			throw std::runtime_error(ClassName() + ": specify lag < 0");
		}
		else if (lag > 0)
		{
			itsLogger.Warning("negating lag value " + std::to_string(-lag));
			lag = -lag;
		}

		itsLag = lag;
		itsUseLaggedEnsemble = true;
	}
	else
	{
		itsUseLaggedEnsemble = false;
	}

	// How many lagged steps to include in the calculation
	if (itsUseLaggedEnsemble)
	{
		if (itsConfiguration->Exists("lagged_steps"))
		{
			const int steps = std::stoi(itsConfiguration->GetValue("lagged_steps"));
			if (steps <= 0)
			{
				throw std::runtime_error(ClassName() + ": invalid lagged_steps value. Allowed range >= 0");
			}
			itsLaggedSteps = steps;
		}
		else
		{
			throw std::runtime_error(ClassName() + ": specify lagged_steps when using time lagging ('lag')");
		}
	}

	//
	// 2. Setup input and output parameters from the json configuration.
	//    `calculatedParams' will hold the output parameter, it's inputs,
	//    and the 'threshold' value.
	//
	params calculatedParams;

	int targetInfoIndex = 0;
	const auto& names = conf->GetParameterNames();
	for (const std::string& name : names)
	{
		param_configuration config;

		config.targetInfoIndex = targetInfoIndex;
		config.output.Name(name);

		param p = GetConfigurationParameter(name, conf, &config);

		if (p.Name() == "")
		{
			throw std::runtime_error(ClassName() + "Misconfigured parameter definition in JSON");
		}

		itsParamConfigurations.push_back(config);
		calculatedParams.push_back(p);
		targetInfoIndex++;
	}

	SetParams(calculatedParams);

	// Make sure that limit exists for all stations (if source data is stations)
	auto tempInfo = std::make_shared<himan::info>(*conf->Info());
	tempInfo->First();

	if (tempInfo->Grid()->Type() == kPointList)
	{
		auto r = GET_PLUGIN(radon);
		for (tempInfo->ResetLocation(); tempInfo->NextLocation();)
		{
			const auto st = tempInfo->Station();

			for (auto& pc : itsParamConfigurations)
			{
				auto it = pc.stationThreshold.find(st.Id());

				if (it == pc.stationThreshold.end())
				{
					itsLogger.Trace("Fetching threshold for param " + pc.output.Name() + ", station " +
					                std::to_string(st.Id()) + " from radon");
					double limit = r->RadonDB().GetProbabilityLimitForStation(st.Id(), pc.output.Name());

					if (limit == kFloatMissing)
					{
						itsLogger.Fatal("Threshold not found for param " + pc.output.Name() + ", station " +
						                std::to_string(st.Id()));
						abort();
					}

					pc.stationThreshold[st.Id()] = limit;
				}
			}
		}
	}

	// NOTE
	// NOTE We circumvent the usual Himan Start => Run => RunAll / RunTimeDimension - control flow structure
	// NOTE

	//
	// 3. Process parameters in LIFO order by spawning threads for each parameter.
	//	  (We don't divide timesteps between threads)
	//
	boost::thread_group g;
	auto paramConfigurations = itsParamConfigurations;

	// Set iterators at this stage to avoid invalid indexing when loading from auxiliary files
	itsInfo->First();

	int threadIdx = 0;

	for (const auto& pc : paramConfigurations)
	{
		g.add_thread(new boost::thread(&himan::plugin::probability::Calculate, this, threadIdx, boost::ref(pc)));

		if (threadIdx == itsThreadCount)
		{
			g.join_all();
			threadIdx = 0;
		}

		threadIdx++;
	}

	g.join_all();

	Finish();
}

static void CalculateNormal(std::shared_ptr<info> targetInfo, uint16_t threadIndex,
                            const param_configuration& paramConf, int infoIndex, bool normalized,
                            std::unique_ptr<ensemble>& ens);

static void CalculateNegative(std::shared_ptr<info> targetInfo, uint16_t threadIndex,
                              const param_configuration& paramConf, const int infoIndex, const bool normalized,
                              std::unique_ptr<ensemble>& ens);

static void CalculateWind(const logger& log, std::shared_ptr<info> targetInfo, uint16_t threadIndex,
                          const param_configuration& paramConf, int infoIndex, bool normalized,
                          std::unique_ptr<ensemble>& ens1, std::unique_ptr<ensemble>& ens2);

void probability::Calculate(uint16_t threadIndex, const param_configuration& pc)
{
	info myTargetInfo = *itsInfo;

	auto threadedLogger = logger("probabilityThread # " + std::to_string(threadIndex));
	const std::string deviceType = "CPU";

	const double threshold = pc.gridThreshold;
	const int infoIndex = pc.targetInfoIndex;
	const int ensembleSize = itsEnsembleSize;
	const bool normalized = itsUseNormalizedResult;

	myTargetInfo.First();

	std::unique_ptr<ensemble> ens1;
	std::unique_ptr<ensemble> ens2;  // used with wind calculation

	if (itsUseLaggedEnsemble)
	{
		threadedLogger.Info("Using lagged ensemble for ensemble #1");
		ens1 = std::unique_ptr<ensemble>(
		    new lagged_ensemble(pc.parameter, ensembleSize, kHourResolution, itsLag, itsLaggedSteps + 1));
	}
	else
	{
		ens1 = std::unique_ptr<ensemble>(new ensemble(pc.parameter, ensembleSize));
	}
	ens1->MaximumMissingForecasts(itsMaximumMissingForecasts);

	if (pc.parameter.Name() == "U-MS" || pc.parameter.Name() == "V-MS")
	{
		// Wind
		if (itsUseLaggedEnsemble)
		{
			threadedLogger.Info("Using lagged ensemble for ensemble #2");
			ens2 = std::unique_ptr<ensemble>(
			    new lagged_ensemble(pc.parameter2, ensembleSize, kHourResolution, itsLag, itsLaggedSteps + 1));
		}
		else
		{
			ens2 = std::unique_ptr<ensemble>(new ensemble(pc.parameter2, ensembleSize));
		}
		ens2->MaximumMissingForecasts(itsMaximumMissingForecasts);
	}

	// NOTE we only loop through the time steps here
	do
	{
		threadedLogger.Info("Calculating " + pc.output.Name() + " time " +
		                    static_cast<std::string>(myTargetInfo.Time().ValidDateTime()) + " threshold '" +
		                    std::to_string(threshold) + "' infoIndex " + std::to_string(infoIndex));

		//
		// Setup input data, data fetching
		//

		try
		{
			ens1->Fetch(itsConfiguration, myTargetInfo.Time(), myTargetInfo.Level());

			if (pc.parameter.Name() == "U-MS" || pc.parameter.Name() == "V-MS")
			{
				ens2->Fetch(itsConfiguration, myTargetInfo.Time(), myTargetInfo.Level());
			}
		}
		catch (const HPExceptionType& e)
		{
			if (e == kFileDataNotFound)
			{
				continue;
			}
			else
			{
				itsLogger.Fatal("Received error code " + std::to_string(e));
				abort();
			}
		}

		// Output memory
		if (itsConfiguration->UseDynamicMemoryAllocation())
		{
			AllocateMemory(myTargetInfo);
		}
		assert(myTargetInfo.Data().Size() > 0);

		//
		// Choose the correct calculation function for this parameter and do the actual calculation
		//
		// Unfortunately we use both the input parameter name and output parameter name for doing this.
		//
		if (pc.parameter.Name() == "U-MS" || pc.parameter.Name() == "V-MS")
		{
			CalculateWind(threadedLogger, std::make_shared<info>(myTargetInfo), threadIndex, pc, infoIndex, normalized,
			              ens1, ens2);
		}
		else if (pc.output.Name() == "PROB-TC-0" || pc.output.Name() == "PROB-TC-1" ||
		         pc.output.Name() == "PROB-TC-2" || pc.output.Name() == "PROB-TC-3" ||
		         pc.output.Name() == "PROB-TC-4" || pc.output.Name() == "PROB-WATLEV-LOW-1")
		{
			CalculateNegative(std::make_shared<info>(myTargetInfo), threadIndex, pc, infoIndex, normalized, ens1);
		}
		else
		{
			CalculateNormal(std::make_shared<info>(myTargetInfo), threadIndex, pc, infoIndex, normalized, ens1);
		}

		if (itsConfiguration->StatisticsEnabled())
		{
			itsConfiguration->Statistics()->AddToMissingCount(myTargetInfo.Data().MissingCount());
			itsConfiguration->Statistics()->AddToValueCount(myTargetInfo.Data().Size());
		}

		// Finally write this parameter out
		WriteToFile(myTargetInfo, pc.targetInfoIndex);

	} while (myTargetInfo.NextTime());

	threadedLogger.Info("[" + deviceType + "] Missing values: " + std::to_string(myTargetInfo.Data().MissingCount()) +
	                    "/" + std::to_string(myTargetInfo.Data().Size()));
}

// Usually himan writes all the parameters out on a call to WriteToFile, but probability calculates
// each parameter separately in separate threads so this makes no sense (writing all out if we've only
// calculated one parameter)
void probability::WriteToFile(const info& targetInfo, size_t targetInfoIndex, write_options opts)
{
	auto writer = GET_PLUGIN(writer);

	writer->WriteOptions(opts);

	auto info = targetInfo;

	info.ResetParam();
	info.ParamIndex(targetInfoIndex);

	if (itsConfiguration->FileWriteOption() == kDatabase || itsConfiguration->FileWriteOption() == kMultipleFiles)
	{
		writer->ToFile(info, itsConfiguration);
	}
	else
	{
		std::lock_guard<std::mutex> lock(singleFileWriteMutex);

		writer->ToFile(info, itsConfiguration, itsConfiguration->ConfigurationFile());
	}

	if (itsConfiguration->UseDynamicMemoryAllocation())
	{
		DeallocateMemory(info);
	}
}

double GetThreshold(std::shared_ptr<info>& targetInfo, const param_configuration& paramConf, bool isGrid)
{
	if (isGrid)
	{
		return paramConf.gridThreshold;
	}
	else
	{
		const int stationId = targetInfo->Station().Id();
		const auto iter = paramConf.stationThreshold.find(stationId);

		if (iter == paramConf.stationThreshold.end())
		{
			throw std::runtime_error("Threshold for station " + std::to_string(stationId) + " not found");
		}

		return iter->second;
	}
}

void CalculateWind(const logger& log, std::shared_ptr<info> targetInfo, uint16_t threadIndex,
                   const param_configuration& paramConf, int infoIndex, bool normalized,
                   std::unique_ptr<ensemble>& ens1, std::unique_ptr<ensemble>& ens2)
{
	targetInfo->ParamIndex(infoIndex);
	targetInfo->ResetLocation();
	ens1->ResetLocation();
	ens2->ResetLocation();

	const size_t ensembleSize = ens1->Size();
	if (ensembleSize != ens2->Size())
	{
		log.Fatal(" CalculateWind(): U and V ensembles are of different size, aborting");
		abort();
	}

	const double invN =
	    normalized ? 1.0 / static_cast<double>(ensembleSize) : 100.0 / static_cast<double>(ensembleSize);

	const bool isGrid = (targetInfo->Grid()->Type() != kPointList);

	while (targetInfo->NextLocation() && ens1->NextLocation() && ens2->NextLocation())
	{
		double probability = 0.0;
		const double threshold = GetThreshold(targetInfo, paramConf, isGrid);

		for (size_t i = 0; i < ensembleSize; i++)
		{
			const auto u = ens1->Value(i);
			const auto v = ens2->Value(i);

			if ((u == kFloatMissing) || (v == kFloatMissing))
			{
				continue;
			}

			if (Magnitude(u, v) >= threshold)
			{
				probability += invN;
			}
		}
		targetInfo->Value(probability);
	}
}

void CalculateNegative(std::shared_ptr<info> targetInfo, uint16_t threadIndex, const param_configuration& paramConf,
                       int infoIndex, bool normalized, std::unique_ptr<ensemble>& ens)
{
	targetInfo->ParamIndex(infoIndex);
	targetInfo->ResetLocation();
	ens->ResetLocation();

	const size_t ensembleSize = ens->Size();
	const double invN =
	    normalized ? 1.0 / static_cast<double>(ensembleSize) : 100.0 / static_cast<double>(ensembleSize);

	const bool isGrid = (targetInfo->Grid()->Type() != kPointList);

	while (targetInfo->NextLocation() && ens->NextLocation())
	{
		double probability = 0.0;
		const double threshold = GetThreshold(targetInfo, paramConf, isGrid);

		for (size_t i = 0; i < ensembleSize; i++)
		{
			const auto x = ens->Value(i);
			if ((x != kFloatMissing) && (x <= threshold))
			{
				probability += invN;
			}
		}
		targetInfo->Value(probability);
	}
}

void CalculateNormal(std::shared_ptr<info> targetInfo, uint16_t threadIndex, const param_configuration& paramConf,
                     int infoIndex, bool normalized, std::unique_ptr<ensemble>& ens)
{
	targetInfo->ParamIndex(infoIndex);
	targetInfo->ResetLocation();
	ens->ResetLocation();

	const size_t ensembleSize = ens->Size();
	const double invN =
	    normalized ? 1.0 / static_cast<double>(ensembleSize) : 100.0 / static_cast<double>(ensembleSize);

	const bool isGrid = (targetInfo->Grid()->Type() != kPointList);

	while (targetInfo->NextLocation() && ens->NextLocation())
	{
		double probability = 0.0;
		const double threshold = GetThreshold(targetInfo, paramConf, isGrid);

		for (size_t i = 0; i < ensembleSize; i++)
		{
			const auto x = ens->Value(i);
			if ((x != kFloatMissing) && (x >= threshold))
			{
				probability += invN;
			}
		}
		targetInfo->Value(probability);
	}
}

}  // plugin

}  // namespace

ext: cpp

max_stars_repo_name: jrintala/fmi-data

max_issues_repo_name: jrintala/fmi-data

max_forks_repo_name: jrintala/fmi-data


text:
/**
 * Source file for status.h
 * Please see status.h for documentation
 */

#include "statsdcc/status.h"

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/trim.hpp>

#include <cstring>
#include <fstream>
#include <iostream>

namespace statsdcc {

bool read_status(std::string status_file,
                 const std::vector<std::string> &keys,
                 Json::Value& status) {
  std::ifstream proc_file(status_file);
  if (!proc_file.is_open()) return false;

  std::string line;
  while (getline(proc_file, line)) {
    std::vector<std::string> key_value;
    boost::split(key_value, line, boost::is_any_of(":"));
    std::string key = boost::trim_right_copy(key_value[0]);

    if (key_value.size() == 2)  {
      std::string key = boost::trim_right_copy(key_value[0]);
      if (keys.size() != 0 &&
          std::find(keys.cbegin(), keys.cend(), key) == keys.cend()) {
        continue;
      }

      std::string value = boost::trim_left_copy(key_value[1]);
      boost::replace_all(value, "\t", "    ");
      status[key] = value;
    }
  }
  return true;
}

}  // namespace statsdcc

ext: cc


text:
#ifdef STAND_ALONE
#   define BOOST_TEST_MODULE Main
#else
#ifndef _WIN32
#   define BOOST_TEST_MODULE Assembler
#endif
#endif

#include <boost/test/unit_test.hpp>

#include "assembler_tests.h"

BOOST_FIXTURE_TEST_SUITE( AssemblerTestSuite, AssemblerFixture )

BOOST_AUTO_TEST_CASE( DummyTest )
{
	// TODO
}

BOOST_AUTO_TEST_SUITE_END()


text:
//  (C) Copyright 2014 Alvaro J. Genial (http://alva.ro)
//  Use, modification and distribution are subject to the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).

#ifndef AJG_SYNTH_ENGINES_BASE_CONTEXT_HPP_INCLUDED
#define AJG_SYNTH_ENGINES_BASE_CONTEXT_HPP_INCLUDED

#include <map>
#include <deque>
#include <utility>

#include <boost/function.hpp>
#include <boost/optional.hpp>
#include <boost/noncopyable.hpp>

#include <ajg/synth/exceptions.hpp>
#include <ajg/synth/detail/find.hpp>
#include <ajg/synth/detail/text.hpp>

namespace ajg {
namespace synth {
namespace engines {

//
// context
////////////////////////////////////////////////////////////////////////////////////////////////////

template <class Value>
struct context : boost::noncopyable {
  public:

    typedef Value                                                               key_type;
    typedef Value                                                               value_type;
    typedef context                                                             context_type;

    typedef typename value_type::range_type                                     range_type;
    typedef typename value_type::sequence_type                                  sequence_type;
    typedef typename value_type::association_type                               association_type;
    typedef typename value_type::arguments_type                                 arguments_type;
    typedef typename value_type::attribute_type                                 attribute_type;
    typedef typename value_type::attributes_type                                attributes_type;
    typedef typename value_type::traits_type                                    traits_type;

    typedef typename traits_type::boolean_type                                  boolean_type;
    typedef typename traits_type::char_type                                     char_type;
    typedef typename traits_type::size_type                                     size_type;
    typedef typename traits_type::integer_type                                  integer_type;
    typedef typename traits_type::floating_type                                 floating_type;
    typedef typename traits_type::number_type                                   number_type;
    typedef typename traits_type::date_type                                     date_type;
    typedef typename traits_type::time_type                                     time_type;
    typedef typename traits_type::datetime_type                                 datetime_type;
    typedef typename traits_type::duration_type                                 duration_type;
    typedef typename traits_type::timezone_type                                 timezone_type;
    typedef typename traits_type::string_type                                   string_type;
    typedef typename traits_type::symbols_type                                  symbols_type;
    typedef typename traits_type::paths_type                                    paths_type;
    typedef typename traits_type::names_type                                    names_type;
    typedef typename traits_type::language_type                                 language_type;
    typedef typename traits_type::format_type                                   format_type;
    typedef typename traits_type::formats_type                                  formats_type;
    typedef typename traits_type::istream_type                                  istream_type;
    typedef typename traits_type::ostream_type                                  ostream_type;

    typedef value_type                                                          data_type;
    typedef struct metadata {
        boolean_type  caseless;
        boolean_type  safe;
        string_type   application;
        timezone_type timezone;
        language_type language;
        boolean_type  localized;
        formats_type  formats;

        metadata() : caseless(false), safe(false), localized(false) {}
    }                                                                           metadata_type;
    typedef void const*                                                         match_type;
    typedef boost::function<void(ostream_type&, context_type&)>                 block_type;
    typedef boost::optional<value_type>                                         change_type;

  private:

    typedef std::map<string_type, std::deque<block_type> >                      blocks_type;
    typedef std::stack<match_type>                                              matches_type;
    typedef std::map<match_type, size_type>                                     cycles_type;
    typedef std::map<match_type, value_type>                                    changes_type;
    typedef detail::text<string_type>                                           text;

  public:

    inline explicit context(data_type const& data, metadata_type const& metadata = metadata_type())
        : data_(data), metadata_(metadata) {}

  public:

    inline void            set  (key_type const& key, value_type const& value) { this->data_.attribute(this->cased(key), value); }
    inline void            unset(key_type const& key) { this->data_.attribute(this->cased(key), attribute_type()); }
    inline attribute_type  get  (key_type const& key) const { return this->data_.attribute(this->cased(key)); }
    inline boolean_type    has  (key_type const& key) const { return detail::contains(this->cased(key), this->keys()); }
    inline attributes_type keys() const { return this->data_.attributes(); }

 // inline data_type&       data()       { return this->data_; }
    inline data_type const& data() const { return this->data_; }
    inline data_type        data(data_type data) { std::swap(data, this->data_); return data; }

    inline boolean_type caseless() const { return this->metadata_.caseless; }
    inline boolean_type caseless(boolean_type caseless) { std::swap(caseless, this->metadata_.caseless); return caseless; }

    inline boolean_type safe() const { return this->metadata_.safe; }
    inline boolean_type safe(boolean_type safe) { std::swap(safe, this->metadata_.safe); return safe; }

    inline string_type application() const { return this->metadata_.application; }
    inline string_type application(string_type application) { std::swap(application, this->metadata_.application); return application; }

    inline timezone_type timezone() const { return this->metadata_.timezone; }
    inline timezone_type timezone(timezone_type timezone) { std::swap(timezone, this->metadata_.timezone); return timezone; }

    inline language_type language() const { return this->metadata_.language; }
    inline language_type language(language_type language) { std::swap(language, this->metadata_.language); return language; }

    inline boolean_type localized() const { return this->metadata_.localized; }
    inline boolean_type localized(boolean_type localized) { std::swap(localized, this->metadata_.localized); return localized; }

    inline formats_type formats() const { return this->metadata_.formats; }
    inline void         formats(formats_type const& formats) {
        for (auto const& format : formats) {
            this->format(format.first, format.second);
        }
    }

    inline string_type current() const {
        if (this->current_.empty()) {
            AJG_SYNTH_THROW(std::invalid_argument("not in a block"));
        }
        return this->current_;
    }

    inline string_type current(string_type name) {
        std::swap(name, this->current_);
        return name;
    }

    inline block_type get_block(string_type const& name) const {
        typename blocks_type::const_iterator const it = this->blocks_.find(name);
        return (it == this->blocks_.end() || it->second.empty()) ? block_type() : it->second.front();
    }

    inline block_type pop_block(string_type const& name) {
        if (block_type const b = this->get_block(name)) {
            this->blocks_[name].pop_front();
            return b;
        }
        return block_type();
    }

    inline void push_block(string_type const& name, block_type const& block) {
        this->blocks_[name].push_back(block);
    }

    inline match_type get_match() const {
        AJG_SYNTH_ASSERT(!this->matches_.empty());
        match_type const match = this->matches_.top();
        AJG_SYNTH_ASSERT(match);
        return match;
    }

    inline void pop_match() {
        AJG_SYNTH_ASSERT(!this->matches_.empty());
        this->matches_.pop();
    }

    inline void push_match(match_type const match) {
        this->matches_.push(match);
    }

    inline size_type cycle(match_type const match, size_type const total) {
        size_type const current = detail::find(match, this->cycles_).get_value_or(0);
        this->cycles_[match] = (current + 1) % total;
        return current;
    }

    inline change_type change(match_type const match) const {
        return detail::find(match, this->changes_);
    }

    inline void change(match_type const match, value_type const& value) {
        this->changes_[match] = value;
    }

    inline format_type format(string_type const& name) const {
        if (boost::optional<format_type> const f = detail::find(name, this->metadata_.formats)) {
            return *f;
        }
        AJG_SYNTH_THROW(std::invalid_argument("format: " + text::narrow(name))); // TODO: unknown_format/missing_format
    }

    inline format_type format_or(string_type const& name, format_type const& f) const {
        return detail::find(name, this->metadata_.formats).get_value_or(f);
    }

    inline void format(string_type const& name, format_type const& format, boolean_type const overwrite = true) {
        if (overwrite) {
            this->metadata_.formats[name] = format;
        }
        else {
            this->metadata_.formats.insert(std::make_pair(name, format));
        }
    }

  private:

    inline key_type cased(key_type const& original) const {
        if (!this->caseless()) {
            return original;
        }
        string_type const lowercased = text::lower(original.to_string());

        for (auto const& key : this->keys()) {
            if (text::lower(key.to_string()) == lowercased) {
                return key;
            }
        }

        return original;
    }

  private:

    data_type     data_;
    metadata_type metadata_;
    string_type   current_;
    blocks_type   blocks_;
    matches_type  matches_;
    cycles_type   cycles_;
    changes_type  changes_;
};

template <class Context>
struct stage : boost::noncopyable {
  public:

    typedef Context                                                             context_type;

    typedef typename context_type::key_type                                     key_type;
    typedef typename context_type::value_type                                   value_type;

    typedef typename value_type::attribute_type                                 attribute_type;
    typedef typename value_type::attributes_type                                attributes_type;
    typedef typename value_type::traits_type                                    traits_type;

    typedef typename traits_type::boolean_type                                  boolean_type;

  private:

    typedef std::map<key_type, attribute_type>                                  previous_type;

  public:

    stage(context_type& context) : context_(context) {}
    stage(context_type& context, key_type const& key, value_type const& value) : context_(context) { this->set(key, value); }
    stage(context_type& context, boolean_type const empty) : context_(context) { if (empty) this->clear(); }

    ~stage() {
        for (auto const& kv : this->previous_) {
            if (kv.second) {
                this->context_.set(kv.first, *kv.second);
            }
            else {
                this->context_.unset(kv.first);
            }
        }
    }

  public:

    inline void clear() {
        for (auto const& key : context_.keys()) {
            this->unset(key);
        }
    }

    inline void unset(key_type const& key) {
        if (!detail::contains(key, this->previous_)) {
            this->previous_[key] = this->context_.get(key);
        }
        this->context_.unset(key);
    }

    inline void set(key_type const& key, value_type const& value) {
        if (!detail::contains(key, this->previous_)) {
            this->previous_[key] = this->context_.get(key);
        }
        this->context_.set(key, value);
    }

  private:

    context_type& context_;
    previous_type previous_;
};

}}} // namespace ajg::synth::engines

#endif // AJG_SYNTH_ENGINES_BASE_CONTEXT_HPP_INCLUDED

max_stars_repo_name: ajg/synth

max_issues_repo_name: ajg/synth

max_forks_repo_name: ajg/synth


text:
#include <utility>

#include <boost/operators.hpp>

#include <elle/assert.hh>
#include <elle/operator.hh>
#include <elle/Exception.hh>

namespace test
{
  class Operator
    : public boost::totally_ordered<Operator>
  {
  public:
    Operator(std::string const& string):
      _string(new std::string(string))
    {
    }
    ~Operator()
    {
      delete this->_string;
    }

    bool
    operator <(Operator const& other) const
    {
      return (*this->_string < *other._string);
    }
    bool
    operator ==(Operator const& other) const
    {
      return (*this->_string == *other._string);
    }

  private:
    std::string* _string;
  };
}

int main()
{
  test::Operator op1("suce");
  test::Operator op2("mon");
  test::Operator op3("cul");

  ELLE_ASSERT(op1 != op2);
  ELLE_ASSERT(op2 > op3);
  ELLE_ASSERT(op1 >= op2);

  return 0;
}

max_stars_repo_name: infinitio/elle

max_issues_repo_name: infinitio/elle

max_forks_repo_name: infinitio/elle


text:
// Copyright (c) 2019 The Unit-e developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <test/esperanza/finalizationstate_utils.h>
#include <test/test_unite.h>
#include <test/test_unite_mocks.h>
#include <boost/test/unit_test.hpp>

namespace esperanza {
static std::ostream &operator<<(std::ostream &os, const FinalizationState &f) {
  os << f.ToString();
  return os;
}
}  // namespace esperanza

namespace util {
template <>
std::string stringify(const CBlockIndex *const &index) {
  if (index == nullptr) {
    return "null";
  }
  return stringify<uint256>(index->GetBlockHash());
}
}  // namespace util

BOOST_AUTO_TEST_SUITE(state_db_tests)

BOOST_AUTO_TEST_CASE(leveldb_rand) {
  mocks::ActiveChainMock active_chain;
  mocks::BlockIndexMapMock block_index_map;
  Settings settings;
  finalization::StateDBParams params;
  params.inmemory = true;

  esperanza::FinalizationParams finalization_params;
  esperanza::AdminParams admin_params;

  std::unique_ptr<finalization::StateDB> db =
      finalization::StateDB::NewFromParams(params, &settings, &block_index_map, &active_chain);

  LOCK(block_index_map.GetLock());

  std::map<const CBlockIndex *, esperanza::FinalizationState> original;
  for (size_t i = 0; i < 100; ++i) {
    CBlockIndex *block_index = block_index_map.Insert(GetRandHash());
    FinalizationStateSpy state;
    state.shuffle();
    original.emplace(block_index, std::move(state));
  }
  BOOST_REQUIRE(original.size() == 100);

  db->Save(original);

  std::map<const CBlockIndex *, esperanza::FinalizationState> restored;
  bool const result = db->Load(finalization_params, admin_params, &restored);

  BOOST_CHECK(result);
  BOOST_CHECK_EQUAL(restored, original);
}

class ActiveChainTest : public mocks::ActiveChainMock {
 public:
  ActiveChainTest() {
    this->stub_AtHeight = [this](blockchain::Height const h) -> CBlockIndex * {
      const auto it = m_block_heights.find(h);
      return it != m_block_heights.end() ? it->second : nullptr;
    };
  }

  void Add(CBlockIndex &index) {
    this->tip = &index;
    m_block_heights[index.nHeight] = &index;
  }

 private:
  std::map<blockchain::Height, CBlockIndex *> m_block_heights;
};

BOOST_AUTO_TEST_CASE(load_best_states) {
  ActiveChainTest active_chain;
  mocks::BlockIndexMapMock block_index_map;
  Settings settings;
  finalization::StateDBParams params;
  params.inmemory = true;

  esperanza::FinalizationParams finalization_params;
  esperanza::AdminParams admin_params;

  std::unique_ptr<finalization::StateDB> db =
      finalization::StateDB::NewFromParams(params, &settings, &block_index_map, &active_chain);

  LOCK(block_index_map.GetLock());
  LOCK(active_chain.GetLock());

  auto generate = [&](CBlockIndex *prev, bool add_to_chain) {
    const blockchain::Height h = prev != nullptr ? prev->nHeight + 1 : 0;
    CBlockIndex *index = block_index_map.Insert(GetRandHash());
    index->pprev = prev;
    index->nHeight = h;
    if (add_to_chain) {
      active_chain.Add(*index);
    }
    return index;
  };

  // Generate active chain
  std::map<const CBlockIndex *, esperanza::FinalizationState> original;
  for (size_t i = 0; i < 100; ++i) {
    CBlockIndex *block_index = generate(active_chain.tip, true);
    FinalizationStateSpy state;
    state.shuffle();
    original.emplace(block_index, std::move(state));
  }
  BOOST_REQUIRE(original.size() == 100);
  BOOST_REQUIRE(active_chain.GetTip()->nHeight == 99);

  // Generate fork 1 higher 50
  {
    CBlockIndex *index = active_chain.stub_AtHeight(50);
    for (size_t i = 0; i < 100; ++i) {
      index = generate(index, false);
      FinalizationStateSpy state;
      state.shuffle();
      original.emplace(index, std::move(state));
    }
  }
  BOOST_REQUIRE(original.size() == 200);
  BOOST_REQUIRE(active_chain.GetTip()->nHeight == 99);

  // Generate fork 2 higher 80
  {
    CBlockIndex *index = active_chain.stub_AtHeight(80);
    for (size_t i = 0; i < 100; ++i) {
      index = generate(index, false);
      FinalizationStateSpy state;
      state.shuffle();
      original.emplace(index, std::move(state));
    }
  }
  BOOST_REQUIRE(original.size() == 300);
  BOOST_REQUIRE(active_chain.GetTip()->nHeight == 99);

  db->Save(original);

  const auto it = original.find(active_chain.GetTip());
  BOOST_REQUIRE(it != original.end());
  const uint32_t expected_last_finalized_epoch = it->second.GetLastFinalizedEpoch();

  // Find last finalized epoch
  {
    boost::optional<uint32_t> last_finalized_epoch = db->FindLastFinalizedEpoch(finalization_params, admin_params);
    BOOST_CHECK(static_cast<bool>(last_finalized_epoch));
    BOOST_CHECK_EQUAL(*last_finalized_epoch, expected_last_finalized_epoch);
  }

  // Simulate that node cannot load state for tip, then it must load most recent state
  // accoring to the main chain. Simply move active chain forward but keep db as is.

  for (size_t i = 0; i < 5; ++i) {
    generate(active_chain.tip, true);
  }
  BOOST_REQUIRE(active_chain.GetTip()->nHeight == 104);

  // Check that db can find last finalized epoch
  {
    boost::optional<uint32_t> last_finalized_epoch = db->FindLastFinalizedEpoch(finalization_params, admin_params);
    BOOST_CHECK(static_cast<bool>(last_finalized_epoch));
    BOOST_CHECK_EQUAL(*last_finalized_epoch, expected_last_finalized_epoch);
  }

  // Load states from height 60.
  // States for active chain starting from 60 must be loaded (40 items).
  // States for fork 2 must be loaded (100 items).
  // States for fork 1 must be ignored.
  {
    std::map<const CBlockIndex *, esperanza::FinalizationState> restored;
    db->LoadStatesHigherThan(59, finalization_params, admin_params, &restored);
    BOOST_CHECK_EQUAL(restored.size(), 140);

    for (auto it = restored.begin(); it != restored.end(); ++it) {
      const CBlockIndex *index = it->first;
      const esperanza::FinalizationState &state = it->second;
      BOOST_CHECK(index->nHeight >= 60);

      const auto oit = original.find(index);
      BOOST_REQUIRE(oit != original.end());

      BOOST_CHECK_EQUAL(state, oit->second);
    }
  }
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: frolosofsky/unit-e

max_issues_repo_name: frolosofsky/unit-e

max_forks_repo_name: frolosofsky/unit-e


text:
#include "filesystem_mock.h"

#include <boost/iostreams/stream.hpp>

namespace possumwood {

namespace {

/// a "source" device stream - wraps a single string into a stream
struct Source {
	typedef char char_type;
	typedef boost::iostreams::seekable_device_tag category;

	Source(const std::string& d) : data(d), offset(0) {
	}

	std::streamsize read(char* s, std::streamsize n) {
		if(offset == data.length())
			return -1;

		if(data.length() >= n + offset) {
			std::copy(data.data() + offset, data.data() + offset + n, s);
			offset += n;
			return n;
		}

		std::copy(data.data() + offset, data.data() + data.length(), s);

		std::streamsize result = data.length() - offset;
		offset = data.length();
		return result;
	}

	std::streamsize write(const char*, std::streamsize n) {
		throw std::runtime_error("Attempting to write to a read-only buffer.");
		return 0;
	}

	boost::iostreams::stream_offset seek(boost::iostreams::stream_offset /*off*/, std::ios_base::seekdir /*way*/) {
		return 0;
	}

	const std::string& data;
	std::size_t offset;
};

/// a "sink" buffer (not a full device) for writing into a string
struct Sink {
	typedef char char_type;
	typedef boost::iostreams::sink_tag category;

	Sink(std::string& d) : data(d) {
	}

	std::streamsize write(const char* s, std::streamsize n) {
		data += std::string(s, n);
		return n;
	}

	std::string& data;
};

}  // namespace

FilesystemMock::FilesystemMock() {
}

void FilesystemMock::addFile(const Filepath& path, const std::string& content) {
	m_content[path] = content;
}

std::unique_ptr<std::istream> FilesystemMock::read(const Filepath& path) {
	return std::unique_ptr<std::istream>(new boost::iostreams::stream<Source>(m_content[path]));
}

std::unique_ptr<std::ostream> FilesystemMock::write(const Filepath& path) {
	m_content[path].clear();
	return std::unique_ptr<std::ostream>(new boost::iostreams::stream<Sink>(m_content[path]));
}

bool FilesystemMock::exists(const Filepath& path) const {
	return m_content.find(path) != m_content.end();
}

boost::filesystem::path FilesystemMock::expandPath(const Filepath& path) const {
	return path.relativePath;
}

Filepath FilesystemMock::shrinkPath(const boost::filesystem::path& path) const {
	return makeFilepath("", path);
}

}  // namespace possumwood

max_stars_repo_name: martin-pr/possumwood

max_issues_repo_name: martin-pr/possumwood

max_forks_repo_name: martin-pr/possumwood


text:
/**
 * Mojang Session API
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * OpenAPI spec version: 2020-06-05
 *
 *
 * NOTE: This class is auto generated by OpenAPI-Generator 3.3.4.
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

#include "SessionApiError.h"

#include <string>
#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;

namespace com {
namespace github {
namespace asyncmc {
namespace mojang {
namespace sessions {
namespace cpp {
namespace restbed {
namespace server {
namespace model {

SessionApiError::SessionApiError()
{
    m_Error = "";
    m_Path = "";

}

SessionApiError::~SessionApiError()
{
}

std::string SessionApiError::toJsonString()
{
	std::stringstream ss;
	ptree pt;
	pt.put("Error", m_Error);
	pt.put("Path", m_Path);
	write_json(ss, pt, false);
	return ss.str();
}

void SessionApiError::fromJsonString(std::string const& jsonString)
{
	std::stringstream ss(jsonString);
	ptree pt;
	read_json(ss,pt);
	m_Error = pt.get("Error", "");
	m_Path = pt.get("Path", "");
}

std::string SessionApiError::getError() const
{
    return m_Error;
}
void SessionApiError::setError(std::string value)
{
    m_Error = value;
}
std::string SessionApiError::getPath() const
{
    return m_Path;
}
void SessionApiError::setPath(std::string value)
{
    m_Path = value;
}

}
}
}
}
}
}
}
}
}

max_stars_repo_name: AsyncMC/Mojang-API-Libs

max_issues_repo_name: AsyncMC/Mojang-API-Libs

max_forks_repo_name: AsyncMC/Mojang-API-Libs


text:
#include "moduletreemodel.hpp"

#include <boost/filesystem.hpp>

#include <chi/Context.hpp>
#include <chi/GraphFunction.hpp>
#include <chi/GraphModule.hpp>
#include <chi/GraphStruct.hpp>
#include <chi/NodeInstance.hpp>
#include <chi/Support/Result.hpp>

#include <KMessageBox>

namespace fs = boost::filesystem;

QIcon ModuleTreeModel::iconForItemType(WorkspaceTree::eType type) {
	switch (type) {
	case WorkspaceTree::MODULE: return QIcon::fromTheme(QStringLiteral("package-available"));
	case WorkspaceTree::FUNCTION: return QIcon::fromTheme(QStringLiteral("code-context"));
	case WorkspaceTree::STRUCT: return QIcon::fromTheme(QStringLiteral("code-class"));
	case WorkspaceTree::FOLDER: return QIcon::fromTheme(QStringLiteral("stock_folder"));
	default: return {};
	}
}

std::unique_ptr<ModuleTreeModel> ModuleTreeModel::createFromContext(chi::Context& context,
                                                                    Filter        filter) {
	auto modules = context.listModulesInWorkspace();

	auto tree = std::make_unique<WorkspaceTree>();

	// add src object
	auto srcTree    = std::make_unique<WorkspaceTree>();
	srcTree->parent = tree.get();
	srcTree->type   = WorkspaceTree::FOLDER;
	srcTree->row    = 0;
	srcTree->name   = QStringLiteral("src");

	// create the tree
	for (const fs::path& mod : modules) {
		WorkspaceTree* parent = srcTree.get();

		// for each component of mod
		for (auto componentIter = mod.begin(); componentIter != mod.end(); ++componentIter) {
			fs::path component = *componentIter;
			bool     isModule  = componentIter == --mod.end();

			// make sure it exists
			bool found = false;
			for (const auto& child : parent->children) {
				if (child->name.toStdString() == component.string() &&
				    (child->type == WorkspaceTree::MODULE) == isModule) {
					found  = true;
					parent = child.get();
					break;
				}
			}
			if (!found) {
				if ((isModule && (filter & ModuleBit)) || (!isModule && (filter & Folders))) {
					// insert it
					auto newChild    = std::make_unique<WorkspaceTree>();
					newChild->parent = parent;
					newChild->type   = isModule ? WorkspaceTree::MODULE : WorkspaceTree::FOLDER;
					newChild->row    = parent->children.size();
					newChild->name   = QString::fromStdString(component.string());
					parent->children.push_back(std::move(newChild));

					parent = parent->children[parent->children.size() - 1].get();
				}
			}
		}
	}

	tree->children.push_back(std::move(srcTree));

	return std::make_unique<ModuleTreeModel>(std::move(tree), context, filter);
}

void ModuleTreeModel::updateModule(const boost::filesystem::path& name) {
	auto idx = indexFromName(name, WorkspaceTree::MODULE);

	if (!idx.isValid()) { return; }

	auto tree = static_cast<WorkspaceTree*>(idx.internalPointer());

	// don't even bother
	if (tree->module == nullptr) { return; }

	// delete all subs
	beginRemoveRows(idx, 0, tree->children.size() - 1);
	tree->children.clear();
	endRemoveRows();

	beginInsertRows(idx, 0,
	                (mFilter & FunctionBit ? tree->module->functions().size() - 1 : 0) +
	                    (mFilter & StructBit ? tree->module->structs().size() - 1 : 0));
	tree->module = nullptr;
	fetchMore(idx);
	endInsertRows();
}

QModelIndex ModuleTreeModel::indexFromName(const boost::filesystem::path& name,
                                           WorkspaceTree::eType           type) {
	auto currentItem = mTree->children[0].get();

	for (auto iter = name.begin(); iter != name.end(); ++iter) {
		bool isLastItem   = iter == --name.end();
		auto expectedType = isLastItem ? type : WorkspaceTree::FOLDER;

		bool succeeded = false;

		// find it in the children
		for (const auto& item : currentItem->children) {
			if (item->name.toStdString() == *iter && item->type == expectedType) {
				currentItem = item.get();
				succeeded   = true;
				break;
			}
		}

		if (!succeeded) { return {}; }
	}

	return createIndex(currentItem->row, 0, currentItem);
}

int ModuleTreeModel::columnCount(const QModelIndex& parent) const { return 1; }

QModelIndex ModuleTreeModel::index(int row, int column, const QModelIndex& parent) const {
	if (!hasIndex(row, column, parent)) { return {}; }

	WorkspaceTree* parentItem;
	if (parent.isValid()) {
		parentItem = static_cast<WorkspaceTree*>(parent.internalPointer());
	} else {
		parentItem = tree();
	}

	// make cast valid
	Q_ASSERT(row >= 0);

	if ((size_t)row < parentItem->children.size()) {
		return createIndex(row, column, parentItem->children[row].get());
	}
	return {};
}

QModelIndex ModuleTreeModel::parent(const QModelIndex& index) const {
	if (!index.isValid()) { return {}; }

	auto childItem  = static_cast<WorkspaceTree*>(index.internalPointer());
	auto parentItem = childItem->parent;

	if (parentItem == tree()) { return {}; }

	return createIndex(parentItem->row, 0, parentItem);
}

bool ModuleTreeModel::hasChildren(const QModelIndex& index) const {
	if (!index.isValid()) { return true; }

	auto item = static_cast<WorkspaceTree*>(index.internalPointer());

	// if both struct and function are disabled, then just return false for module
	return (item->type == WorkspaceTree::MODULE &&
	        (mFilter & StructBit || mFilter & FunctionBit)) ||
	       item->type == WorkspaceTree::FOLDER;
}

bool ModuleTreeModel::canFetchMore(const QModelIndex& index) const {
	if (!index.isValid()) { return false; }

	auto item = static_cast<WorkspaceTree*>(index.internalPointer());

	return item->type == WorkspaceTree::MODULE && (mFilter & StructBit || mFilter & FunctionBit);
}

void ModuleTreeModel::fetchMore(const QModelIndex& index) {
	if (!index.isValid()) { return; }

	auto item = static_cast<WorkspaceTree*>(index.internalPointer());

	if (item->module != nullptr) {
		// it's already been fetched
		return;
	}

	// get the name
	fs::path p = item->fullName();

	// load it
	chi::ChiModule* mod;
	chi::Result     res = mCtx->loadModule(p, &mod);
	if (!res) {
		KMessageBox::detailedError(nullptr,
		                           R"(Failed to load JsonModule from file ")" +
		                               QString::fromStdString(p.string()) + R"(")",
		                           QString::fromStdString(res.dump()), "Error Loading");

		return;
	}

	item->module = static_cast<chi::GraphModule*>(mod);

	if (mFilter & FunctionBit) {
		// add functions
		for (const auto& func : item->module->functions()) {
			auto child    = std::make_unique<WorkspaceTree>();
			child->func   = func.get();
			child->parent = item;
			child->name   = QString::fromStdString(func->name());
			child->row    = item->children.size();
			child->type   = WorkspaceTree::FUNCTION;

			item->children.push_back(std::move(child));
		}
	}

	if (mFilter & StructBit) {
		// add structs
		for (const auto& str : item->module->structs()) {
			auto child    = std::make_unique<WorkspaceTree>();
			child->str    = str.get();
			child->name   = QString::fromStdString(str->name());
			child->parent = item;
			child->row    = item->children.size();
			child->type   = WorkspaceTree::STRUCT;

			item->children.push_back(std::move(child));
		}
	}
}

int ModuleTreeModel::rowCount(const QModelIndex& index) const {
	WorkspaceTree* parentItem;
	if (index.isValid()) {
		parentItem = static_cast<WorkspaceTree*>(index.internalPointer());
	} else {
		parentItem = tree();
	}

	return parentItem->children.size();
}

QVariant ModuleTreeModel::data(const QModelIndex& index, int role) const {
	if (!index.isValid()) { return {}; }

	auto item = static_cast<WorkspaceTree*>(index.internalPointer());

	switch (role) {
	case Qt::DisplayRole:
		if (item->dirty) {
			return "* " + item->name;
		} else {
			return item->name;
		}
	case Qt::DecorationRole: return iconForItemType(item->type);
	case Qt::FontRole:
		if (item->dirty || (item->parent != nullptr && item->parent->dirty)) {
			QFont bold;
			bold.setBold(true);
			return bold;
		}
		return {};
	default: return {};
	}
}

Qt::ItemFlags ModuleTreeModel::flags(const QModelIndex& index) const {
	if (!index.isValid()) { return {}; }

	auto item = static_cast<WorkspaceTree*>(index.internalPointer());

	Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;

	if (item->type == WorkspaceTree::FUNCTION || item->type == WorkspaceTree::STRUCT) {
		flags |= Qt::ItemIsEditable;
	}

	return flags;
}

bool ModuleTreeModel::setData(const QModelIndex& index, const QVariant& value, int role) {
	if (!index.isValid()) { return {}; }

	if (role == Qt::EditRole) {
		auto item = static_cast<WorkspaceTree*>(index.internalPointer());

		if (value.toString().isEmpty()) { return false; }

		switch (item->type) {
		case WorkspaceTree::FUNCTION: {
			auto oldName = item->func->name();

			// set the function name
			auto nodesToUpdate = item->func->setName(value.toString().toStdString());
			item->name         = QString::fromStdString(item->func->name());

			emit functionRenamed(*item->func, oldName, nodesToUpdate);

		} break;
		case WorkspaceTree::STRUCT: {
			auto oldName = item->str->name();

			// set the struct name
			auto nodesToUpdate = item->str->setName(value.toString().toStdString());
			item->name         = QString::fromStdString(item->str->name());

			emit structRenamed(*item->str, oldName, nodesToUpdate);

		} break;
		default: return false;
		}

		dataChanged(index, index, {Qt::DisplayRole});
		return true;
	}

	return false;
}

max_stars_repo_name: undeadinu/chigraph-gui

max_issues_repo_name: undeadinu/chigraph-gui

max_forks_repo_name: undeadinu/chigraph-gui


text:
#include <cctbx/boost_python/flex_fwd.h>

#include <cctbx/xray/scatterer_utils.h>
#include <cctbx/crystal/direct_space_asu.h>
#include <cctbx/eltbx/henke.h>
#include <cctbx/eltbx/sasaki.h>
#include <boost/python/class.hpp>
#include <boost/python/def.hpp>
#include <boost/python/args.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/return_by_value.hpp>

namespace cctbx { namespace xray { namespace boost_python {

namespace {

  struct scatterer_wrappers
  {
    typedef scatterer<> w_t;
    typedef w_t::float_type flt_t;

    static void
    wrap()
    {
      using namespace boost::python;
      typedef return_value_policy<return_by_value> rbv;
      typedef default_call_policies dcp;
      class_<w_t>("scatterer", no_init)
        .def(init<w_t const&>(arg("other")))
        .def(init<std::string const&,
                  fractional<flt_t> const&,
                  flt_t const&,
                  flt_t const&,
                  std::string const&,
                  flt_t const&,
                  flt_t const&>((
          arg("label"),
          arg("site"),
          arg("u_iso"),
          arg("occupancy"),
          arg("scattering_type"),
          arg("fp"),
          arg("fdp"))))
        .def(init<std::string const&,
                  fractional<flt_t> const&,
                  scitbx::sym_mat3<flt_t> const&,
                  flt_t const&,
                  std::string const&,
                  flt_t const&,
                  flt_t const&>((
          arg("label"),
          arg("site"),
          arg("u_star"),
          arg("occupancy"),
          arg("scattering_type"),
          arg("fp"),
          arg("fdp"))))
        .add_property("label", make_getter(&w_t::label, rbv()),
                               make_setter(&w_t::label, dcp()))
        .add_property("scattering_type",
          make_getter(&w_t::scattering_type, rbv()),
          make_setter(&w_t::scattering_type, dcp()))
        .add_property("fp", make_getter(&w_t::fp, rbv()),
                            make_setter(&w_t::fp, dcp()))
        .add_property("fdp", make_getter(&w_t::fdp, rbv()),
                             make_setter(&w_t::fdp, dcp()))
        .add_property("site", make_getter(&w_t::site, rbv()),
                              make_setter(&w_t::site, dcp()))
        .add_property("occupancy", make_getter(&w_t::occupancy, rbv()),
                                   make_setter(&w_t::occupancy, dcp()))
        .add_property("u_iso", make_getter(&w_t::u_iso, rbv()),
                               make_setter(&w_t::u_iso, dcp()))
        .add_property("u_star", make_getter(&w_t::u_star, rbv()),
                                make_setter(&w_t::u_star, dcp()))
        .def_readwrite("flags", &w_t::flags)
        .def("set_use_u", &w_t::set_use_u, (arg("iso"),arg("aniso")))
        .def("set_use_u_iso_only", &w_t::set_use_u_iso_only)
        .def("set_use_u_aniso_only", &w_t::set_use_u_aniso_only)
        .def("convert_to_isotropic", &w_t::convert_to_isotropic, (
          arg("unit_cell")))
        .def("convert_to_anisotropic", &w_t::convert_to_anisotropic, (
          arg("unit_cell")))
        .def("is_positive_definite_u",
          (bool(w_t::*)(uctbx::unit_cell const&) const)
            &w_t::is_positive_definite_u, (
          arg("unit_cell")))
        .def("is_positive_definite_u",
          (bool(w_t::*)(uctbx::unit_cell const&, double const&) const)
            &w_t::is_positive_definite_u, (
          arg("unit_cell"),
          arg("u_cart_tolerance")))
        .def("u_iso_or_equiv", &w_t::u_iso_or_equiv, (arg("unit_cell")))
        .def("b_iso", &w_t::b_iso)
        .def("u_cart_plus_u_iso", &w_t::u_cart_plus_u_iso, (arg("unit_cell")))
        .def("tidy_u",
          (void(w_t::*)(
            uctbx::unit_cell const&,
            sgtbx::site_symmetry_ops const&,
            double const&,
            double const&,
            double const&)) &w_t::tidy_u, (
          arg("unit_cell"),
          arg("site_symmetry_ops"),
          arg("u_min"),
          arg("u_max"),
          arg("anisotropy_min")))
        .def("shift_u",
          (void(w_t::*)(
            uctbx::unit_cell const&,
            double const&)) &w_t::shift_u, (
          arg("unit_cell"),
          arg("u_shift")))
        .def("shift_occupancy",
          (void(w_t::*)(
            double const&)) &w_t::shift_occupancy, (
          arg("q_shift")))
        .def("apply_symmetry",
          (sgtbx::site_symmetry(w_t::*)(
            uctbx::unit_cell const&,
            sgtbx::space_group const&,
            double const&,
            double const&,
            bool)) &w_t::apply_symmetry, (
              arg("unit_cell"),
              arg("space_group"),
              arg("min_distance_sym_equiv")=0.5,
              arg("u_star_tolerance")=0,
              arg("assert_min_distance_sym_equiv")=true))
        .def("apply_symmetry",
          (void(w_t::*)(
            sgtbx::site_symmetry_ops const&,
            double const&)) &w_t::apply_symmetry, (
              arg("site_symmetry_ops"),
              arg("u_star_tolerance")=0))
        .def("apply_symmetry_site", &w_t::apply_symmetry_site, (
          arg("site_symmetry_ops")))
        .def("apply_symmetry_u_star", &w_t::apply_symmetry_u_star, (
          arg("site_symmetry_ops"),
          arg("u_star_tolerance")=0))
        .def("multiplicity", &w_t::multiplicity)
        .def("weight_without_occupancy", &w_t::weight_without_occupancy)
        .def("weight", &w_t::weight)
        .def("report_details", &w_t::report_details, (
          arg("unit_cell"),
          arg("prefix")))
      ;
    }
  };

} // namespace <anoymous>

  void wrap_scatterer()
  {
    using namespace boost::python;

    scatterer_wrappers::wrap();

    def("is_positive_definite_u",
      (af::shared<bool>(*)(
        af::const_ref<scatterer<> > const&,
        uctbx::unit_cell const&)) is_positive_definite_u, (
          arg("scatterers"),
          arg("unit_cell")));

    def("is_positive_definite_u",
      (af::shared<bool>(*)(
        af::const_ref<scatterer<> > const&,
        uctbx::unit_cell const&,
        double)) is_positive_definite_u, (
          arg("scatterers"),
          arg("unit_cell"),
          arg("u_cart_tolerance")));

    def("tidy_us",
      (void(*)(
        af::ref<scatterer<> > const&,
        uctbx::unit_cell const&,
        sgtbx::site_symmetry_table const&,
        double u_min,
        double u_max,
        double anisotropy_min)) tidy_us, (
          arg("scatterers"),
          arg("unit_cell"),
          arg("site_symmetry_table"),
          arg("u_min"),
          arg("u_max"),
          arg("anisotropy_min")));

    def("u_star_plus_u_iso",
      (void(*)(
        af::ref<scatterer<> > const&,
        uctbx::unit_cell const&)) u_star_plus_u_iso, (
          arg("scatterers"),
          arg("unit_cell")));

    def("shift_us",
      (void(*)(
        af::ref<scatterer<> > const&,
        uctbx::unit_cell const&,
        double u_min)) shift_us, (
          arg("scatterers"),
          arg("unit_cell"),
          arg("u_shift")));

    def("shift_us",
      (void(*)(
        af::ref<scatterer<> > const&,
        uctbx::unit_cell const&,
        double u_min,
        af::const_ref<std::size_t> const&)) shift_us, (
          arg("scatterers"),
          arg("unit_cell"),
          arg("u_shift"),
          arg("selection")));

    def("shift_occupancies",
      (void(*)(
        af::ref<scatterer<> > const&,
        double,
        af::const_ref<std::size_t> const&)) shift_occupancies, (
          arg("scatterers"),
          arg("q_shift"),
          arg("selection")));

    def("shift_occupancies",
      (void(*)(
        af::ref<scatterer<> > const&,
        double)) shift_occupancies, (
          arg("scatterers"),
          arg("q_shift")));

    def("apply_symmetry_sites",
      (void(*)(
        sgtbx::site_symmetry_table const&,
        af::ref<scatterer<> > const&)) apply_symmetry_sites, (
          arg("site_symmetry_table"),
          arg("scatterers")));

    def("apply_symmetry_u_stars",
      (void(*)(
        sgtbx::site_symmetry_table const&,
        af::ref<scatterer<> > const&,
        double)) apply_symmetry_u_stars, (
          arg("site_symmetry_table"),
          arg("scatterers"),
          arg("u_star_tolerance")=0));

    def("add_scatterers_ext",
      (void(*)(
        uctbx::unit_cell const&,
        sgtbx::space_group const&,
        af::ref<scatterer<> > const&,
        sgtbx::site_symmetry_table&,
        sgtbx::site_symmetry_table const&,
        double,
        double,
        bool,
        bool)) add_scatterers_ext, (
          arg("unit_cell"),
          arg("space_group"),
          arg("scatterers"),
          arg("site_symmetry_table"),
          arg("site_symmetry_table_for_new"),
          arg("min_distance_sym_equiv"),
          arg("u_star_tolerance"),
          arg("assert_min_distance_sym_equiv"),
          arg("non_unit_occupancy_implies_min_distance_sym_equiv_zero")));

    def("change_basis",
      (af::shared<scatterer<> >(*)(
        af::const_ref<scatterer<> > const&,
        sgtbx::change_of_basis_op const&)) change_basis, (
      arg("scatterers"), arg("cb_op")));

    def("expand_to_p1",
      (af::shared<scatterer<> >(*)(
        uctbx::unit_cell const&,
        sgtbx::space_group const&,
        af::const_ref<scatterer<> > const&,
        sgtbx::site_symmetry_table const&,
        bool)) expand_to_p1, (
          arg("unit_cell"),
          arg("space_group"),
          arg("scatterers"),
          arg("site_symmetry_table"),
          arg("append_number_to_labels")));

    def("n_undefined_multiplicities",
      (std::size_t(*)(
        af::const_ref<scatterer<> > const&)) n_undefined_multiplicities, (
      arg("scatterers")));

    def("asu_mappings_process",
      (void(*)(
        crystal::direct_space_asu::asu_mappings<>&,
        af::const_ref<scatterer<> > const&,
        sgtbx::site_symmetry_table const&)) asu_mappings_process, (
      arg("asu_mappings"), arg("scatterers"), arg("site_symmetry_table")));

    def("rotate",
      (af::shared<scatterer<> >(*)(
        uctbx::unit_cell const&,
        scitbx::mat3<double> const&,
        af::const_ref<scatterer<> > const&)) rotate, (
          arg("unit_cell"),
          arg("rotation_matrix"),
          arg("scatterers")));

    typedef return_value_policy<return_by_value> rbv;
    class_<apply_rigid_body_shift<> >("apply_rigid_body_shift")
      .def(init<af::shared<scitbx::vec3<double> > const&,
                af::shared<scitbx::vec3<double> > const&,
                scitbx::mat3<double> const&,
                scitbx::vec3<double> const&,
                af::const_ref<double> const&,
                uctbx::unit_cell const&,
                af::const_ref<std::size_t> const& >((arg("sites_cart"),
                                              arg("sites_frac"),
                                              arg("rot"),
                                              arg("trans"),
                                              arg("atomic_weights"),
                                              arg("unit_cell"),
                                              arg("selection"))))
      .add_property("sites_frac",  make_getter(
                             &apply_rigid_body_shift<>::sites_frac, rbv()))
      .add_property("sites_cart",  make_getter(
                             &apply_rigid_body_shift<>::sites_cart, rbv()))
      .add_property("center_of_mass",  make_getter(
                             &apply_rigid_body_shift<>::center_of_mass, rbv()))
    ;

    def("set_inelastic_form_factors_from_henke",
      (void(*)(af::ref<scatterer<> > const &,
               eltbx::wavelengths::characteristic,
               bool))
        inelastic_form_factors<eltbx::henke::table>::set,
        (arg("scatterers"), arg("photon"), arg("set_use_fp_fdp")=true));
    def("set_inelastic_form_factors_from_sasaki",
      (void(*)(af::ref<scatterer<> > const &,
               eltbx::wavelengths::characteristic,
               bool))
        inelastic_form_factors<eltbx::sasaki::table>::set,
        (arg("scatterers"), arg("photon"), arg("set_use_fp_fdp")=true));
    def("set_inelastic_form_factors_from_henke",
      (void(*)(af::ref<scatterer<> > const &, float, bool))
        inelastic_form_factors<eltbx::henke::table>::set,
        (arg("scatterers"), arg("wavelength"), arg("set_use_fp_fdp")=true));
    def("set_inelastic_form_factors_from_sasaki",
      (void(*)(af::ref<scatterer<> > const &, float, bool))
        inelastic_form_factors<eltbx::sasaki::table>::set,
        (arg("scatterers"), arg("wavelength"), arg("set_use_fp_fdp")=true));
  }

}}} // namespace cctbx::xray::boost_python