text:
/******************************************************************************
**
** Copyright (C) 2009-2011 Kyle Lutz <kyle.r.lutz@gmail.com>
** All rights reserved.
**
** This file is a part of the chemkit project. For more information
** see <http://www.chemkit.org>.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in the
**     documentation and/or other materials provided with the distribution.
**   * Neither the name of the chemkit project nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
******************************************************************************/

#include <string>
#include <iostream>

#include <boost/scoped_ptr.hpp>
#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>

#include <chemkit/chemkit.h>
#include <chemkit/foreach.h>
#include <chemkit/molecule.h>
#include <chemkit/lineformat.h>
#include <chemkit/moleculefile.h>
#include <chemkit/substructurequery.h>

void printHelp(char *argv[], const boost::program_options::options_description &options)
{
    std::cout << "Usage: " << argv[0] << " [OPTIONS] PATTERN FILE\n";
    std::cout << "\n";
    std::cout << "Search for molecules matching PATTERN in FILE. PATTERN is a line\n";
    std::cout << "representation (e.g. InChI or SMILES) of a molecule to search\n";
    std::cout << "for. A matching molecule is either an exact match or a\n";
    std::cout << "superstructure of PATTERN.\n";
    std::cout << "\n";
    std::cout << "Options:\n";
    std::cout << options << "\n";
}

int main(int argc, char *argv[])
{
    std::string formula;
    std::string fileName;

    boost::program_options::options_description options;
    options.add_options()
        ("formula",
            boost::program_options::value<std::string>(&formula),
            "Input formula to match against.")
        ("file",
            boost::program_options::value<std::string>(&fileName),
            "Input file to search.")
        ("composition,c",
            "Match composition rather than structure.")
        ("exact-match,e",
            "Return molecules that exactly match PATTERN.")
        ("invert-match,v",
            "Return only non-matching molecules.")
        ("names-only,n",
            "Output only the names of matching molecules.")
        ("help,h",
            "Shows this help message");

    boost::program_options::positional_options_description positionalOptions;
    positionalOptions.add("formula", 1).add("file", 1);

    boost::program_options::variables_map variables;
    boost::program_options::store(
        boost::program_options::command_line_parser(argc, argv)
            .options(options)
            .positional(positionalOptions).run(),
        variables);
    boost::program_options::notify(variables);

    if(variables.count("help")){
        printHelp(argv, options);
        return 0;
    }
    else if(formula.empty()){
        printHelp(argv, options);
        std::cerr << "Error: no input formula given." << std::endl;
        return -1;
    }
    else if(fileName.empty()){
        printHelp(argv, options);
        std::cerr << "Error: no input file given." << std::endl;
        return -1;
    }

    // select input line format based on the input pattern given
    std::string inputFormat;
    if(boost::algorithm::starts_with(formula, "InChI=") || isdigit(formula[0])){
        inputFormat = "inchi";
    }
    else{
        inputFormat = "smiles";
    }

    // create input line format
    boost::scoped_ptr<chemkit::LineFormat> patternFormat(chemkit::LineFormat::create(inputFormat));
    if(!patternFormat){
        std::cerr << "Error: failed to create line format." << std::endl;
        return -1;
    }

    // read input molecule
    boost::shared_ptr<chemkit::Molecule> patternMolecule(patternFormat->read(formula));
    if(!patternMolecule){
        std::cerr << "Error: failed to read pattern molecule: " << patternFormat->errorString() << std::endl;
        return -1;
    }

    // read input file
    chemkit::MoleculeFile inputFile(fileName);
    if(!inputFile.read()){
        std::cerr << "Error: failed to read input file: " << inputFile.errorString() << std::endl;
        return -1;
    }

    // get options
    bool compositionOnly = variables.find("composition") != variables.end();
    bool exactMatch = variables.find("exact-match") != variables.end();
    bool invertMatch = variables.find("invert-match") != variables.end();
    bool namesOnly = variables.find("names-only") != variables.end();

    int flags = 0;
    if(compositionOnly){
        flags |= chemkit::SubstructureQuery::CompareAtomsOnly;
    }
    if(exactMatch){
        flags |= chemkit::SubstructureQuery::CompareExact;
    }

    chemkit::SubstructureQuery query;
    query.setMolecule(patternMolecule);
    query.setFlags(flags);

    chemkit::MoleculeFile outputFile;

    foreach(const boost::shared_ptr<chemkit::Molecule> &molecule, inputFile.molecules()){
        bool match = query.matches(molecule.get());

        if((match && !invertMatch) || (!match && invertMatch)){
            outputFile.addMolecule(molecule);
        }
    }

    if(namesOnly){
        foreach(const boost::shared_ptr<chemkit::Molecule> &molecule, outputFile.molecules()){
            std::cout << molecule->name() << "\n";
        }
    }
    else{
        bool ok = outputFile.write(std::cout, inputFile.formatName());
        if(!ok){
            std::cerr << "Error: failed to write output file: " << outputFile.errorString() << std::endl;
            return -1;
        }
    }

    return 0;
}

max_stars_repo_name: quizzmaster/chemkit

max_issues_repo_name: soplwang/chemkit

max_forks_repo_name: soplwang/chemkit


text:
#ifndef STAN_VARIATIONAL_ITER_HPP
#define STAN_VARIATIONAL_ITER_HPP

#include <cmdstan/arguments/singleton_argument.hpp>
#include <stan/services/experimental/advi/defaults.hpp>
#include <boost/lexical_cast.hpp>

namespace cmdstan {

  using stan::services::experimental::advi::max_iterations;

  class arg_variational_iter: public int_argument {
  public:
    arg_variational_iter(): int_argument() {
      _name = "iter";
      _description = max_iterations::description();
      _validity = "0 < iter";
      _default = boost::lexical_cast<std::string>(max_iterations::default_value());
      _default_value = max_iterations::default_value();
      _constrained = true;
      _good_value = max_iterations::default_value();
      _bad_value = -1.0;
      _value = _default_value;
    }

    bool is_valid(int value) {
      return value > 0;
    }
  };

}
#endif

ext: hpp

max_stars_repo_name: danluu/cmdstan

max_issues_repo_name: danluu/cmdstan

max_forks_repo_name: danluu/cmdstan


text:
// Copyright (C) 2020 T. Zachary Laine
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_TEXT_UNENCODED_ROPE_VIEW_HPP
#define BOOST_TEXT_UNENCODED_ROPE_VIEW_HPP

#include <boost/text/segmented_vector.hpp>
#include <boost/text/unencoded_rope_fwd.hpp>
#include <boost/text/rope_fwd.hpp>
#include <boost/text/detail/rope_iterator.hpp>
#include <boost/text/detail/rope.hpp>

#include <boost/stl_interfaces/view_interface.hpp>

namespace boost { namespace text {

    template<typename Char, typename String>
#if BOOST_TEXT_USE_CONCEPTS
    // clang-format off
        requires std::is_same_v<Char, std::ranges::range_value_t<String>>
#endif
    struct basic_unencoded_rope_view
        // clang-format on
        : stl_interfaces::view_interface<
              basic_unencoded_rope_view<Char, String>>
    {
        using value_type = Char;
        using size_type = std::size_t;
        using iterator = detail::const_rope_view_iterator<Char, String>;
        using const_iterator = iterator;
        using reverse_iterator = stl_interfaces::reverse_iterator<iterator>;
        using const_reverse_iterator = reverse_iterator;

        using string = String;
        using string_view = boost::text::basic_string_view<Char>;

        /** Default ctor.

            \post size() == 0 && begin() == end() */
        basic_unencoded_rope_view() noexcept :
            ref_(rope_ref()), which_(which::r)
        {}

        basic_unencoded_rope_view(
            basic_unencoded_rope_view const & other) noexcept :
            ref_(string_view()), which_(other.which_)
        {
            switch (which_) {
            case which::r: ref_.r_ = other.ref_.r_; break;
            case which::tv: ref_.tv_ = other.ref_.tv_; break;
            }
        }

        /** Constructs a substring of `r`, comprising the elements at offsets
            `[lo, hi)`.  If either of `lo` or `hi` is a negative value `x`,
            `x` is taken to be an offset from the end, and so `x + size()` is
            used instead.

            These preconditions apply to the values used after `size()` is
            added to any negative arguments.

            \pre 0 <= lo && lo <= r.size()
            \pre 0 <= hi && lhi <= r.size()
            \pre lo <= hi
            \post size() == r.size() && begin() == r.begin() + lo && end() ==
            r.begin() + hi */
        basic_unencoded_rope_view(
            basic_unencoded_rope<Char, String> const & r,
            size_type lo,
            size_type hi);

        /** Constructs a `basic_unencoded_rope_view` covering the entire given
            string. */
        basic_unencoded_rope_view(string const & s) noexcept :
            ref_(string_view(s.data(), s.size())), which_(which::tv)
        {}

        /** Forbid construction from a temporary `string`. */
        basic_unencoded_rope_view(string && r) noexcept = delete;

        /** Constructs a substring of `s`, comprising the elements at offsets
            `[lo, hi)`.  If either of `lo` or `hi` is a negative value `x`,
            `x` is taken to be an offset from the end, and so `x + size()` is
            used instead.

            These preconditions apply to the values used after `size()` is
            added to any negative arguments.

            \pre 0 <= lo && lo <= s.size()
            \pre 0 <= hi && lhi <= s.size()
            \pre lo <= hi
            \post size() == s.size() && begin() == s.begin() + lo && end() ==
            s.begin() + hi */
        basic_unencoded_rope_view(
            string const & s, size_type lo, size_type hi) :
            ref_(detail::substring(s, lo, hi)), which_(which::tv)
        {}

        /** Constructs a `basic_unencoded_rope_view` from a null-terminated C
            string. */
        basic_unencoded_rope_view(value_type const * c_str) noexcept :
            ref_(string_view(c_str)), which_(which::tv)
        {}

        /** Constructs a `basic_unencoded_rope_view` covering the entire given
            `string_view`. */
        basic_unencoded_rope_view(string_view sv) noexcept :
            ref_(sv), which_(which::tv)
        {}

#ifdef BOOST_TEXT_DOXYGEN

        /** Constructs a `basic_unencoded_rope_view` from a range of
            `value_type`.

            This function only participates in overload resolution if
            `ContigCharRange` models the ContigCharRange concept. */
        template<typename ContigCharRange>
        explicit basic_unencoded_rope_view(ContigCharRange const & r);

#else

#if BOOST_TEXT_USE_CONCEPTS
        template<std::ranges::contiguous_range R>
        // clang-format off
            requires std::is_same_v<std::ranges::range_value_t<R>, value_type>
        explicit basic_unencoded_rope_view(R const & r) :
        // clang-format on
#else
        template<typename R>
        explicit basic_unencoded_rope_view(
            R const & r, detail::contig_rng_alg_ret_t<int *, R> = 0) :
#endif
            ref_(rope_ref())
        {
            if (std::begin(r) == std::end(r)) {
                *this = basic_unencoded_rope_view();
            } else {
                *this = basic_unencoded_rope_view(
                    string_view(&*std::begin(r), std::end(r) - std::begin(r)));
            }
        }

#endif

        const_iterator begin() const noexcept
        {
            switch (which_) {
            case which::r:
                return const_iterator(ref_.r_.r_->begin() + ref_.r_.lo_);
            case which::tv: return const_iterator(ref_.tv_.begin());
            }
            return const_iterator(); // This should never execute.
        }
        const_iterator end() const noexcept
        {
            switch (which_) {
            case which::r:
                return const_iterator(ref_.r_.r_->begin() + ref_.r_.hi_);
            case which::tv: return const_iterator(ref_.tv_.end());
            }
            return const_iterator(); // This should never execute.
        }

        const_iterator cbegin() const noexcept { return begin(); }
        const_iterator cend() const noexcept { return end(); }

        const_reverse_iterator rbegin() const noexcept
        {
            return const_reverse_iterator{end()};
        }
        const_reverse_iterator rend() const noexcept
        {
            return const_reverse_iterator{begin()};
        }

        const_reverse_iterator crbegin() const noexcept { return rbegin(); }
        const_reverse_iterator crend() const noexcept { return rend(); }

        /** Returns a substring of `*this`, comprising the elements at offsets
            `[lo, hi)`.  If either of `lo` or `hi` is a negative value `x`,
            `x` is taken to be an offset from the end, and so `x + size()` is
            used instead.

            These preconditions apply to the values used after `size()` is
            added to any negative arguments.

            \pre 0 <= lo && lo <= size()
            \pre 0 <= hi && lhi <= size()
            \pre lo <= hi */
        basic_unencoded_rope_view
        operator()(std::ptrdiff_t lo, std::ptrdiff_t hi) const
        {
            if (lo < 0)
                lo += this->size();
            if (hi < 0)
                hi += this->size();
            BOOST_ASSERT(0 <= lo && lo <= (std::ptrdiff_t)this->size());
            BOOST_ASSERT(0 <= hi && hi <= (std::ptrdiff_t)this->size());
            BOOST_ASSERT(lo <= hi);
            switch (which_) {
            case which::r:
                return basic_unencoded_rope_view(
                    ref_.r_.r_, ref_.r_.lo_ + lo, ref_.r_.lo_ + hi);
            case which::tv:
                return basic_unencoded_rope_view(
                    detail::substring(ref_.tv_, lo, hi));
            }
            return *this; // This should never execute.
        }

        /** Lexicographical compare.  Returns a value `< 0` when `*this` is
            lexicographically less than `rhs`, `0` if `*this == rhs`, and a
            value `> 0` if `*this` is lexicographically greater than `rhs`. */
        int compare(basic_unencoded_rope_view rhs) const noexcept
        {
            if (which_ == which::tv && rhs.which_ == which::tv)
                return ref_.tv_.compare(rhs.ref_.tv_);
            if (this->empty())
                return rhs.empty() ? 0 : -1;
            return boost::text::lexicographical_compare_three_way(
                begin(), end(), rhs.begin(), rhs.end());
        }

        basic_unencoded_rope_view &
        operator=(basic_unencoded_rope_view const & other) noexcept
        {
            which_ = other.which_;
            switch (which_) {
            case which::r: ref_.r_ = other.ref_.r_; break;
            case which::tv: ref_.tv_ = other.ref_.tv_; break;
            }
            return *this;
        }

        /** Assignment from a `basic_unencoded_rope`. */
        basic_unencoded_rope_view &
        operator=(basic_unencoded_rope<Char, String> const & r) noexcept
        {
            return *this = basic_unencoded_rope_view(r);
        }

        /** Assignment from a `string`. */
        basic_unencoded_rope_view & operator=(string const & s) noexcept
        {
            return *this = basic_unencoded_rope_view(s);
        }

        /** Forbid assignment from a `basic_unencoded_rope`. */
        basic_unencoded_rope_view &
        operator=(basic_unencoded_rope<Char, String> && r) noexcept = delete;

        /** Forbid assignment from a `string`. */
        basic_unencoded_rope_view & operator=(string && s) noexcept = delete;

        /** Assignment from a null-terminated C string. */
        basic_unencoded_rope_view & operator=(value_type const * c_str) noexcept
        {
            return *this = basic_unencoded_rope_view(c_str);
        }

        /** Assignment from a `string_view`. */
        basic_unencoded_rope_view & operator=(string_view sv) noexcept
        {
            return *this = basic_unencoded_rope_view(sv);
        }

#ifdef BOOST_TEXT_DOXYGEN

        /** Assignment from a contiguous range of `value_type` elements.

            This function only participates in overload resolution if
            `ContigCharRange` models the ContigCharRange concept. */
        template<typename ContigCharRange>
        basic_unencoded_rope_view & operator=(ContigCharRange const & r);

#else

#if BOOST_TEXT_USE_CONCEPTS
        template<std::ranges::contiguous_range R>
        // clang-format off
            requires std::is_same_v<std::ranges::range_value_t<R>, value_type>
        basic_unencoded_rope_view & operator=(R const & r)
        // clang-format on
#else
        template<typename R>
        auto operator=(R const & r)
            -> detail::contig_rng_alg_ret_t<basic_unencoded_rope_view &, R>
#endif
        {
            return *this = basic_unencoded_rope_view(r);
        }

#endif

        /** Stream inserter; performs unformatted output. */
        friend std::ostream &
        operator<<(std::ostream & os, basic_unencoded_rope_view rv)
        {
            for (auto c : rv) {
                os << c;
            }
            return os;
        }

        friend bool operator==(
            basic_unencoded_rope_view lhs,
            basic_unencoded_rope_view rhs) noexcept
        {
            return lhs.compare(rhs) == 0;
        }

        friend bool operator!=(
            basic_unencoded_rope_view lhs,
            basic_unencoded_rope_view rhs) noexcept
        {
            return lhs.compare(rhs) != 0;
        }

        friend bool operator<(
            basic_unencoded_rope_view lhs,
            basic_unencoded_rope_view rhs) noexcept
        {
            return lhs.compare(rhs) < 0;
        }

        friend bool operator<=(
            basic_unencoded_rope_view lhs,
            basic_unencoded_rope_view rhs) noexcept
        {
            return lhs.compare(rhs) <= 0;
        }

        friend bool operator>(
            basic_unencoded_rope_view lhs,
            basic_unencoded_rope_view rhs) noexcept
        {
            return lhs.compare(rhs) > 0;
        }

        friend bool operator>=(
            basic_unencoded_rope_view lhs,
            basic_unencoded_rope_view rhs) noexcept
        {
            return lhs.compare(rhs) >= 0;
        }

        friend void
        swap(basic_unencoded_rope_view & lhs, basic_unencoded_rope_view & rhs)
        {
            lhs.swap(rhs);
        }

#ifndef BOOST_TEXT_DOXYGEN

    private:
        enum class which{r, tv};

        struct rope_ref
        {
            rope_ref() : r_(nullptr), lo_(0), hi_(0) {}
            rope_ref(
                segmented_vector<value_type, string> const * r,
                std::ptrdiff_t lo,
                std::ptrdiff_t hi) :
                r_(r), lo_(lo), hi_(hi)
            {}

            segmented_vector<value_type, string> const * r_;
            size_type lo_;
            size_type hi_;
        };

        union ref
        {
            ref(rope_ref r) : r_(r) {}
            ref(string_view tv) : tv_(tv) {}

            rope_ref r_;
            string_view tv_;
        };

        basic_unencoded_rope_view(
            segmented_vector<value_type, string> const * r,
            std::size_t lo,
            std::size_t hi) :
            ref_(rope_ref(r, lo, hi)), which_(which::r)
        {}

        ref ref_;
        which which_;

        friend basic_unencoded_rope<Char, String>;
        friend basic_rope_view<nf::c, Char, String>;
        friend basic_rope_view<nf::kc, Char, String>;
        friend basic_rope_view<nf::d, Char, String>;
        friend basic_rope_view<nf::kd, Char, String>;
        friend basic_rope_view<nf::fcc, Char, String>;
#endif
    };

}}

#include <boost/text/unencoded_rope.hpp>

namespace boost { namespace text {

    template<typename Char, typename String>
    int operator+(
        basic_unencoded_rope_view<Char, String> lhs,
        basic_unencoded_rope_view<Char, String> rhs) = delete;

}}

#ifndef BOOST_TEXT_DOXYGEN

namespace std {
    template<typename Char, typename String>
    struct hash<boost::text::basic_unencoded_rope_view<Char, String>>
    {
        using argument_type =
            boost::text::basic_unencoded_rope_view<Char, String>;
        using result_type = std::size_t;
        result_type operator()(argument_type const & urv) const noexcept
        {
            return boost::text::detail::hash_char_range(urv);
        }
    };
}

#endif

#if BOOST_TEXT_USE_CONCEPTS

namespace std::ranges {
    template<typename Char, typename String>
    inline constexpr bool enable_borrowed_range<
        boost::text::basic_unencoded_rope_view<Char, String>> = true;
}

#endif

#endif


text:
#include <rbdl/rbdl.h>

#include "urdfreader.h"

#include <assert.h>
#include <iostream>
#include <fstream>
#include <map>
#include <stack>

#ifdef RBDL_USE_ROS_URDF_LIBRARY
  #include <urdf_model/model.h>
  #include <urdf_parser/urdf_parser.h>
  #include <boost/shared_ptr.hpp>

  typedef urdf::LinkSharedPtr LinkPtr;
  typedef const urdf::LinkConstSharedPtr ConstLinkPtr;
  typedef urdf::JointSharedPtr JointPtr;
  typedef urdf::ModelInterfaceSharedPtr ModelPtr;

#else
  #include <urdf/urdfdom_headers/urdf_model/include/urdf_model/model.h>
  #include <urdf/urdfdom/urdf_parser/include/urdf_parser/urdf_parser.h>

  typedef my_shared_ptr<urdf::Link> LinkPtr;
  typedef const my_shared_ptr<const urdf::Link> ConstLinkPtr;
  typedef my_shared_ptr<urdf::Joint> JointPtr;
  typedef my_shared_ptr<urdf::ModelInterface> ModelPtr;

#endif

using namespace std;

namespace RigidBodyDynamics
{

namespace Addons
{

using namespace Math;

typedef vector<LinkPtr> URDFLinkVector;
typedef vector<JointPtr> URDFJointVector;
typedef map<string, LinkPtr> URDFLinkMap;
typedef map<string, JointPtr> URDFJointMap;

bool construct_model(Model *rbdl_model, ModelPtr urdf_model, bool floating_base,
                     bool verbose)
{
  LinkPtr urdf_root_link;

  URDFLinkMap link_map;
  link_map = urdf_model->links_;

  URDFJointMap joint_map;
  joint_map = urdf_model->joints_;

  vector<string> joint_names;

  // Holds the links that we are processing in our depth first traversal
  // with the top element being the current link.
  stack<LinkPtr> link_stack;
  // Holds the child joint index of the current link
  stack<int> joint_index_stack;

  // add the bodies in a depth-first order of the model tree
  link_stack.push(link_map[(urdf_model->getRoot()->name)]);

  // add the root body
  ConstLinkPtr &root = urdf_model->getRoot();
  Vector3d root_inertial_rpy;
  Vector3d root_inertial_position;
  Matrix3d root_inertial_inertia;
  double root_inertial_mass;

  if (root->inertial) {
    root_inertial_mass = root->inertial->mass;

    root_inertial_position.set(
      root->inertial->origin.position.x,
      root->inertial->origin.position.y,
      root->inertial->origin.position.z);

    root_inertial_inertia(0, 0) = root->inertial->ixx;
    root_inertial_inertia(0, 1) = root->inertial->ixy;
    root_inertial_inertia(0, 2) = root->inertial->ixz;

    root_inertial_inertia(1, 0) = root->inertial->ixy;
    root_inertial_inertia(1, 1) = root->inertial->iyy;
    root_inertial_inertia(1, 2) = root->inertial->iyz;

    root_inertial_inertia(2, 0) = root->inertial->ixz;
    root_inertial_inertia(2, 1) = root->inertial->iyz;
    root_inertial_inertia(2, 2) = root->inertial->izz;

    root->inertial->origin.rotation.getRPY(root_inertial_rpy[0],
                                           root_inertial_rpy[1],
                                           root_inertial_rpy[2]);

    Body root_link = Body(root_inertial_mass,
                          root_inertial_position,
                          root_inertial_inertia);

    Joint root_joint(JointTypeFixed);
    if (floating_base) {
      root_joint = JointTypeFloatingBase;
    }

    SpatialTransform root_joint_frame = SpatialTransform();

    if (verbose) {
      cout << "+ Adding Root Body " << endl;
      cout << "  joint frame: " << root_joint_frame << endl;
      if (floating_base) {
        cout << "  joint type : floating" << endl;
      } else {
        cout << "  joint type : fixed" << endl;
      }
      cout << "  body inertia: " << endl
           << root_link.mInertia << endl;
      cout << "  body mass   : " << root_link.mMass << endl;
      cout << "  body name   : " << root->name << endl;
    }

    rbdl_model->AppendBody(root_joint_frame,
                           root_joint,
                           root_link,
                           root->name);
  }

  // depth first traversal: push the first child onto our joint_index_stack
  joint_index_stack.push(0);

  while (link_stack.size() > 0) {
    LinkPtr cur_link = link_stack.top();

    unsigned int joint_idx = joint_index_stack.top();

    // Add any child bodies and increment current joint index if we still
    // have child joints to process.
    if (joint_idx < cur_link->child_joints.size()) {
      JointPtr cur_joint = cur_link->child_joints[joint_idx];

      // increment joint index
      joint_index_stack.pop();
      joint_index_stack.push(joint_idx + 1);

      link_stack.push(link_map[cur_joint->child_link_name]);
      joint_index_stack.push(0);

      if (verbose) {
        for (unsigned int i = 1; i < joint_index_stack.size() - 1; i++) {
          cout << "  ";
        }
        cout << "joint '" << cur_joint->name << "' child link '" <<
             link_stack.top()->name << "' type = " << cur_joint->type << endl;
      }

      joint_names.push_back(cur_joint->name);
    } else {
      link_stack.pop();
      joint_index_stack.pop();
    }
  }

  unsigned int j;
  for (j = 0; j < joint_names.size(); j++) {
    JointPtr urdf_joint = joint_map[joint_names[j]];
    LinkPtr urdf_parent = link_map[urdf_joint->parent_link_name];
    LinkPtr urdf_child = link_map[urdf_joint->child_link_name];

    // determine where to add the current joint and child body
    unsigned int rbdl_parent_id = 0;

    if (urdf_parent->name != "base_link") {
      rbdl_parent_id = rbdl_model->GetBodyId(urdf_parent->name.c_str());
    }

    if (rbdl_parent_id == std::numeric_limits<unsigned int>::max())
      cerr << "Error while processing joint '" << urdf_joint->name
           << "': parent link '" << urdf_parent->name
           << "' could not be found." << endl;

    // create the joint
    Joint rbdl_joint;
    if (urdf_joint->type == urdf::Joint::REVOLUTE ||
        urdf_joint->type == urdf::Joint::CONTINUOUS) {
      rbdl_joint = Joint(SpatialVector(urdf_joint->axis.x, urdf_joint->axis.y,
                                       urdf_joint->axis.z, 0., 0., 0.));
    } else if (urdf_joint->type == urdf::Joint::PRISMATIC) {
      rbdl_joint = Joint(SpatialVector(0., 0., 0., urdf_joint->axis.x,
                                       urdf_joint->axis.y, urdf_joint->axis.z));
    } else if (urdf_joint->type == urdf::Joint::FIXED) {
      rbdl_joint = Joint(JointTypeFixed);
    } else if (urdf_joint->type == urdf::Joint::FLOATING) {
      // todo: what order of DoF should be used?
      rbdl_joint = Joint(
                     SpatialVector(0., 0., 0., 1., 0., 0.),
                     SpatialVector(0., 0., 0., 0., 1., 0.),
                     SpatialVector(0., 0., 0., 0., 0., 1.),
                     SpatialVector(1., 0., 0., 0., 0., 0.),
                     SpatialVector(0., 1., 0., 0., 0., 0.),
                     SpatialVector(0., 0., 1., 0., 0., 0.));
    } else if (urdf_joint->type == urdf::Joint::PLANAR) {
      // todo: which two directions should be used that are perpendicular
      // to the specified axis?
      cerr << "Error while processing joint '" << urdf_joint->name <<
           "': planar joints not yet supported!" << endl;
      return false;
    }

    // compute the joint transformation
    Vector3d joint_rpy;
    Vector3d joint_translation;
    urdf_joint->parent_to_joint_origin_transform.rotation.getRPY(joint_rpy[0],
        joint_rpy[1], joint_rpy[2]);
    joint_translation.set(
      urdf_joint->parent_to_joint_origin_transform.position.x,
      urdf_joint->parent_to_joint_origin_transform.position.y,
      urdf_joint->parent_to_joint_origin_transform.position.z);
    SpatialTransform rbdl_joint_frame =
      Xrot(joint_rpy[0], Vector3d(1., 0., 0.)) * Xrot(joint_rpy[1], Vector3d(0., 1.,
          0.)) * Xrot(joint_rpy[2], Vector3d(0., 0.,
                      1.)) * Xtrans(Vector3d(joint_translation));

    // assemble the body
    Vector3d link_inertial_position;
    Vector3d link_inertial_rpy;
    Matrix3d link_inertial_inertia = Matrix3d::Zero();
    double link_inertial_mass = 0.;

    // but only if we actually have inertial data
    if (urdf_child->inertial) {
      link_inertial_mass = urdf_child->inertial->mass;

      link_inertial_position.set(
        urdf_child->inertial->origin.position.x,
        urdf_child->inertial->origin.position.y,
        urdf_child->inertial->origin.position.z);
      urdf_child->inertial->origin.rotation.getRPY(link_inertial_rpy[0],
          link_inertial_rpy[1], link_inertial_rpy[2]);

      link_inertial_inertia(0, 0) = urdf_child->inertial->ixx;
      link_inertial_inertia(0, 1) = urdf_child->inertial->ixy;
      link_inertial_inertia(0, 2) = urdf_child->inertial->ixz;

      link_inertial_inertia(1, 0) = urdf_child->inertial->ixy;
      link_inertial_inertia(1, 1) = urdf_child->inertial->iyy;
      link_inertial_inertia(1, 2) = urdf_child->inertial->iyz;

      link_inertial_inertia(2, 0) = urdf_child->inertial->ixz;
      link_inertial_inertia(2, 1) = urdf_child->inertial->iyz;
      link_inertial_inertia(2, 2) = urdf_child->inertial->izz;

      if (link_inertial_rpy != Vector3d(0., 0., 0.)) {
        cerr << "Error while processing body '" << urdf_child->name <<
             "': rotation of body frames not yet supported. Please rotate" <<
             "the joint frame instead."
             << endl;
        return false;
      }
    }

    Body rbdl_body = Body(link_inertial_mass, link_inertial_position,
                          link_inertial_inertia);

    if (verbose) {
      cout << "+ Adding Body: " << urdf_child->name << endl;
      cout << "  parent_id  : " << rbdl_parent_id << endl;
      cout << "  joint frame: " << rbdl_joint_frame << endl;
      cout << "  joint dofs : " << rbdl_joint.mDoFCount << endl;
      for (unsigned int j = 0; j < rbdl_joint.mDoFCount; j++) {
        cout << "    " << j << ": " << rbdl_joint.mJointAxes[j].transpose() << endl;
      }
      cout << "  body inertia: " << endl
           << rbdl_body.mInertia << endl;
      cout << "  body mass   : " << rbdl_body.mMass << endl;
      cout << "  body name   : " << urdf_child->name << endl;
    }

    if (urdf_joint->type == urdf::Joint::FLOATING) {
      Matrix3d zero_matrix = Matrix3d::Zero();
      Body null_body(0., Vector3d::Zero(3), zero_matrix);
      Joint joint_txtytz(JointTypeTranslationXYZ);
      string trans_body_name = urdf_child->name + "_Translate";
      rbdl_model->AddBody(rbdl_parent_id, rbdl_joint_frame, joint_txtytz, null_body,
                          trans_body_name);

      Joint joint_euler_zyx(JointTypeEulerXYZ);
      rbdl_model->AppendBody(SpatialTransform(), joint_euler_zyx, rbdl_body,
                             urdf_child->name);
    } else {
      rbdl_model->AddBody(rbdl_parent_id, rbdl_joint_frame, rbdl_joint, rbdl_body,
                          urdf_child->name);
    }
  }

  return true;
}

RBDL_DLLAPI bool URDFReadFromFile(const char *filename, Model *model,
                                  bool floating_base, bool verbose)
{
  ifstream model_file(filename);
  if (!model_file) {
    cerr << "Error opening file '" << filename << "'." << endl;
    abort();
  }

  // reserve memory for the contents of the file
  string model_xml_string;
  model_file.seekg(0, std::ios::end);
  model_xml_string.reserve(model_file.tellg());
  model_file.seekg(0, std::ios::beg);
  model_xml_string.assign((std::istreambuf_iterator<char>(model_file)),
                          std::istreambuf_iterator<char>());

  model_file.close();

  return URDFReadFromString(model_xml_string.c_str(), model, floating_base,
                            verbose);
}

RBDL_DLLAPI bool URDFReadFromString(const char *model_xml_string, Model *model,
                                    bool floating_base, bool verbose)
{
  assert(model);

  ModelPtr urdf_model = urdf::parseURDF(model_xml_string);

  if (!construct_model(model, urdf_model, floating_base, verbose)) {
    cerr << "Error constructing model from urdf file." << endl;
    return false;
  }

  model->gravity.set(0., 0., -9.81);

  return true;
}

} // namespace Addons

} // namespace RigidBodyDynamics

ext: cc


text:
// Copyright 2019-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef HEADER_058638D3_7069_42DC_809F_5DB533FCFBA3_INCLUDED
#define HEADER_058638D3_7069_42DC_809F_5DB533FCFBA3_INCLUDED

#include <cassert>
#include <chrono>
#include <iostream>
#include <unordered_map>
#include <vector>

#include <boost/core/noncopyable.hpp>
#include <boost/log/trivial.hpp>

namespace genny::metrics {

/*
 * Could add a template policy class on Registry to let the following types be templatized.
 */
using count_type = long long;
using gauged_type = long long;

// Convenience (wouldn't want to be configurable in the future)

template <typename ClockSource>
class period {
private:
    typename ClockSource::duration duration;

public:
    period() = default;

    operator typename ClockSource::duration() const {
        return duration;
    }

    // recursive case
    template <typename Arg0, typename... Args>
    period(Arg0 arg0, Args&&... args)
        : duration(std::forward<Arg0>(arg0), std::forward<Args>(args)...) {}

    // base-case for arg that is implicitly-convertible to ClockSource::duration
    template <typename Arg,
              typename = typename std::enable_if<
                  std::is_convertible<Arg, typename ClockSource::duration>::value,
                  void>::type>
    period(Arg&& arg) : duration(std::forward<Arg>(arg)) {}

    // base-case for arg that isn't explicitly-convertible to ClockSource::duration; marked explicit
    template <typename Arg,
              typename = typename std::enable_if<
                  !std::is_convertible<Arg, typename ClockSource::duration>::value,
                  void>::type,
              typename = void>
    explicit period(Arg&& arg) : duration(std::forward<Arg>(arg)) {}

    friend std::ostream& operator<<(std::ostream& os, const period& p) {
        return os << p.duration.count();
    }
};

// The v1 namespace is here for two reasons:
// 1) it's a step towards an ABI. These classes are basically the pimpls of the outer classes.
// 2) it prevents auto-completion of metrics::{X}Impl when you really want metrics::{X}.
//
// Note: Counter, Timer and Guage have been deprecated. Use Operation instead when writing actors.

/**
 * @namespace genny::metrics::v1 this namespace is private and only intended to be used by Genny's
 * internals. Actors should never have to type `genny::*::v1` into any types.
 */
namespace v1 {

/**
 * The ReporterT is given read-access to metrics data for the purposes
 * of reporting data. The ReporterT class is the only separately-compiled
 * component of the metrics library. It is not ABI safe.
 */
template <typename MetricsClockSource>
class ReporterT;

/**
 * Ignore this. Used for passkey for some methods.
 */
class Evil {
protected:
    Evil() = default;
};
class Permission : private Evil {

private:
    constexpr Permission() = default;

    template <typename MetricsClockSource>
    friend class ReporterT;
};

static_assert(std::is_empty<Permission>::value, "empty");

/**
 * Not intended to be used directly.
 * This is used by the *Impl classes as storage for TSD values.
 *
 * @tparam T The value to record at a particular time-point.
 */
template <class ClockSource, class T>
class TimeSeries : private boost::noncopyable {

public:
    using time_point = typename ClockSource::time_point;

    explicit constexpr TimeSeries() {
        // could make 10000*10000 a param passed down
        // from Registry if needed
        _vals.reserve(1000 * 1000);
    }

    /**
     * Add a TSD data point occurring `now()`.
     * Args are forwarded to the `T` constructor.
     */
    template <class... Args>
    void add(Args&&... args) {
        _vals.emplace_back(ClockSource::now(), std::forward<Args>(args)...);
    }

    // passkey:
    /**
     * Internal method to expose data-points for reporting, etc.
     * @return raw data
     */
    const std::vector<std::pair<time_point, T>>& getVals(Permission) const {
        return _vals;
    }

    /**
     * @return number of data points
     */
    long getDataPointCount(Permission) const {
        return std::distance(_vals.begin(), _vals.end());
    }

private:
    std::vector<std::pair<time_point, T>> _vals;
};

/**
 * Data-storage backing a `Counter`.
 * Please see the documentation there.
 */
template <typename ClockSource>
class CounterImpl : private boost::noncopyable {

public:
    void reportValue(const count_type& delta) {
        auto nval = (this->_count += delta);
        _timeSeries.add(nval);
    }

    // passkey:
    const TimeSeries<ClockSource, count_type>& getTimeSeries(Permission) const {
        return this->_timeSeries;
    }

private:
    TimeSeries<ClockSource, count_type> _timeSeries;
    count_type _count{};
};

/**
 * Data-storage backing a `Gauge`.
 * Please see the documentation there.
 */
template <typename ClockSource>
class GaugeImpl : private boost::noncopyable {

public:
    void set(const gauged_type& count) {
        _timeSeries.add(count);
    }

    // passkey:
    const TimeSeries<ClockSource, count_type>& getTimeSeries(Permission) const {
        return this->_timeSeries;
    }

private:
    TimeSeries<ClockSource, count_type> _timeSeries;
};

/**
 * Data-storage backing a `Timer`.
 * Please see the documentation there.
 */
template <typename ClockSource>
class TimerImpl : private boost::noncopyable {

public:
    void report(const typename ClockSource::time_point& started) {
        _timeSeries.add(ClockSource::now() - started);
    }

    // passkey:
    const TimeSeries<ClockSource, period<ClockSource>>& getTimeSeries(Permission) const {
        return this->_timeSeries;
    }

private:
    TimeSeries<ClockSource, period<ClockSource>> _timeSeries;
};

template <typename ClockSource>
class OperationImpl {

public:
    OperationImpl(const std::string& name,
                  TimerImpl<ClockSource>& timer,
                  CounterImpl<ClockSource>& iters,
                  CounterImpl<ClockSource>& docs,
                  CounterImpl<ClockSource>& bytes)
        : _opName{name},
          _timer{std::addressof(timer)},
          _iters{std::addressof(iters)},
          _docs{std::addressof(docs)},
          _bytes{std::addressof(bytes)} {}

    /**
     * Operation name getter to help with exception reporting.
     */
    const std::string& getOpName() const {
        return _opName;
    }

    void report(const typename ClockSource::time_point& started) {
        this->_timer->report(started);
        this->_iters->reportValue(1);
    }

    void reportBytes(const count_type& total) {
        this->_bytes->reportValue(total);
    }

    void reportOps(const count_type& total) {
        this->_docs->reportValue(total);
    }

private:
    const std::string _opName;
    TimerImpl<ClockSource>* _timer;
    CounterImpl<ClockSource>* _iters;
    CounterImpl<ClockSource>* _docs;
    CounterImpl<ClockSource>* _bytes;
};

/**
 * Counter is deprecated in favor of Operation.
 *
 * A Counter lets callers indicate <b>deltas</b> of a value at a particular time.
 * A Counter has an (internal, hidden) current value that can be incremented or
 * decremented over time.
 *
 * This is useful when simply recording the number of operations completed.
 *
 * ```c++
 * // setup:
 * auto requests = registry.counter("requests");
 *
 * // main method
 * while(true) {
 *   requests.incr();
 * }
 * ```
 */
template <typename ClockSource>
class Counter {

public:
    explicit constexpr Counter(v1::CounterImpl<ClockSource>& counter)
        : _counter{std::addressof(counter)} {}

    void incr(const count_type& val = 1) {
        _counter->reportValue(val);
    }
    void decr(const count_type& val = -1) {
        _counter->reportValue(val);
    }

private:
    v1::CounterImpl<ClockSource>* _counter;
};

/**
 * Gauge is deprecated in favor of Operation.
 *
 * A Gauge lets you record a known value. E.g. the number
 * of active sessions, how many threads are waiting on something, etc.
 * It is defined by each metric what the value is interpreted to be
 * between calls to `set()`. E.g.
 *
 * ```cpp
 * sessions.set(3);
 * // do something
 * sessions.set(5);
 * ```
 *
 * How to determine the value for the "do something" time-period
 * needs to be interpreted for each metric individually.
 */
template <typename ClockSource>
class Gauge {

public:
    explicit constexpr Gauge(v1::GaugeImpl<ClockSource>& gauge) : _gauge{std::addressof(gauge)} {}

    void set(const gauged_type& value) {
        _gauge->set(value);
    }

private:
    v1::GaugeImpl<ClockSource>* _gauge;
};

/**
 * A timer object that automatically reports the elapsed
 * time from when it was constructed in its dtor.
 *
 * Example usage:
 *
 * ```cpp
 * // setup:
 * auto timer = registry.timer("loops");
 *
 * // main method:
 * for(int i=0; i<5; ++i) {
 *     auto r = timer.raii();
 * }
 * ```
 *
 * You can call `.report()` multiple times manually
 * but that does not prevent the timer from reporting on
 * its own in its dtor.
 */
template <typename ClockSource>
class RaiiStopwatch {

public:
    explicit RaiiStopwatch(v1::TimerImpl<ClockSource>& timer)
        : _timer{std::addressof(timer)}, _started{ClockSource::now()} {}
    RaiiStopwatch(const RaiiStopwatch<ClockSource>& other) = delete;
    RaiiStopwatch(RaiiStopwatch<ClockSource>&& other) noexcept : _started{other._started} {
        this->_timer = other._timer;
        other._timer = nullptr;
    }

    RaiiStopwatch<ClockSource>& operator=(RaiiStopwatch<ClockSource> other) noexcept = delete;

    ~RaiiStopwatch() {
        if (this->_timer != nullptr) {
            this->report();
        };
    }

    void report() {
        assert(this->_timer);
        this->_timer->report(_started);
    }

private:
    using time_point = typename ClockSource::time_point;

    v1::TimerImpl<ClockSource>* _timer;
    const time_point _started;
};

/**
 * Similar to `RaiiStopwatch` but doesn't automatically
 * report on its own. Records the time at which it was constructed
 * and then emits a metric event every time `.report()` is called.
 *
 * Example usage:
 *
 * ```c++
 * // setup
 * auto oper = registry.timer("operation.success");
 *
 * // main method
 * for(int i=0; i<10; ++i) {
 *     auto t = oper.start();
 *     try {
 *         // do something
 *         t.report();
 *     } catch(...) { ... }
 * }
 * ```
 *
 * The `.report()` is only called in the successful
 * scenarios, not if an exception is thrown.
 */
template <typename ClockSource>
class Stopwatch {

public:
    explicit Stopwatch(v1::TimerImpl<ClockSource>& timer)
        : _timer{std::addressof(timer)}, _started{ClockSource::now()} {}

    void report() {
        this->_timer->report(_started);
    }

private:
    using time_point = typename ClockSource::time_point;

    v1::TimerImpl<ClockSource>* const _timer;
    const time_point _started;
};

/**
 * Timer is deprecated in favor of Operation.
 */
template <typename ClockSource>
class Timer {

public:
    explicit constexpr Timer(v1::TimerImpl<ClockSource>& t) : _timer{std::addressof(t)} {}

    /**
     * @return
     *  a `Stopwatch` instance that must be manually reported via `.report()`.
     *  When calling `.report()`, the amount of time elapsed from the calling of `.start()`
     *  to calling `.report()` is reported to the metrics back-end. Can call `.report()` multiple
     *  times. Use `.start()` when you want to record successful outcomes of some specific
     *  code-path. If you never call `.report()`, no metrics data will be recorded.
     *
     *  Both `Stopwatch` and `RaiiStopwatch` record timing data, and they can share names.
     *  They are simply two APIs for reporting timing data.
     */
    [[nodiscard]] Stopwatch<ClockSource> start() const {
        return Stopwatch<ClockSource>{*_timer};
    }

    /**
     * @return
     *  an `RaiiStopwatch` that will automatically report the time elapsed since it was
     *  constructed in its dtor. Call `.raii()` at the start of your method or scope to
     *  record how long that method or scope takes even in the case of exceptions or early-returns.
     *  You can also manually call `.report()` multiple times, but it's unclear if this is
     *  useful.
     *
     * Both `Stopwatch` and `RaiiStopwatch` record timing data, and they can share names.
     * They are simply two APIs for reporting timing data.
     */
    [[nodiscard]] RaiiStopwatch<ClockSource> raii() const {
        return RaiiStopwatch<ClockSource>{*_timer};
    };

private:
    v1::TimerImpl<ClockSource>* _timer;
};

template <typename ClockSource>
class OperationContextT {

public:
    explicit OperationContextT(v1::OperationImpl<ClockSource>& op)
        : _op{std::addressof(op)}, _started{ClockSource::now()} {}

    OperationContextT(OperationContextT<ClockSource>&& rhs) noexcept
        : _op{std::move(rhs._op)},
          _started{std::move(rhs._started)},
          _isClosed{std::move(rhs._isClosed)},
          _totalBytes{std::move(rhs._totalBytes)},
          _totalOps{std::move(rhs._totalOps)} {
        rhs._isClosed = true;
    }

    ~OperationContextT() {
        if (!_isClosed) {
            BOOST_LOG_TRIVIAL(warning)
                << "Metrics not reported because operation '" << this->_op->getOpName()
                << "' did not close with success() or fail().";
        }
    }

    void addBytes(const count_type& size) {
        _totalBytes += size;
    }

    void addOps(const count_type& size) {
        _totalOps += size;
    }

    void success() {
        this->report();
        _isClosed = true;
    }

    /**
     * An operation does not report metrics upon failure.
     */
    void fail() {
        _isClosed = true;
    }

private:
    using time_point = typename ClockSource::time_point;

    void report() {
        this->_op->report(_started);
        this->_op->reportBytes(_totalBytes);
        this->_op->reportOps(_totalOps);
    }

    v1::OperationImpl<ClockSource>* _op;
    time_point _started;
    count_type _totalBytes = 0;
    count_type _totalOps = 0;
    bool _isClosed = false;
};

template <typename ClockSource>
class OperationT {

public:
    explicit OperationT(v1::OperationImpl<ClockSource> op) : _op{std::move(op)} {}

    OperationContextT<ClockSource> start() {
        return OperationContextT<ClockSource>(this->_op);
    }

private:
    v1::OperationImpl<ClockSource> _op;
};

class MetricsClockSource {
private:
    using clock_type = std::chrono::steady_clock;

public:
    using duration = clock_type::duration;
    using time_point = std::chrono::time_point<clock_type>;

    static time_point now() {
        return clock_type::now();
    }
};

/**
 * Supports recording a number of types of Time-Series Values:
 *
 * - Counters:   a count of things that can be incremented or decremented
 * - Gauges:     a "current" number of things; a value that can be known and observed
 * - Timers:     recordings of how long certain operations took
 *
 * All data-points are recorded along with the ClockSource::now() value of when
 * the points are recorded.
 *
 * It is expensive to create a distinct metric name but cheap to record new values.
 * The first time `registry.counter("foo")` is called for a distinct counter
 * name "foo", a large block of memory is reserved to store its data-points. But
 * all calls to `registry.counter("foo")` return pimpl-backed wrappers that are cheap
 * to construct and are safe to pass-by-value. Same applies for other metric types.
 *
 * As of now, none of the metrics classes are thread-safe, however they are all
 * thread-compatible. Two threads may not record values to the same metrics names
 * at the same time.
 *
 * `metrics::Reporter` instances have read-access to the TSD data, but that should
 * only be used by workload-drivers to produce a report of the metrics at specific-points
 * in their workload lifecycle.
 */
template <typename ClockSource>
class RegistryT {

public:
    using clock = ClockSource;

    explicit RegistryT() = default;

    v1::Counter<ClockSource> counter(const std::string& name) {
        return v1::Counter<ClockSource>{this->_counters[name]};
    }
    v1::Timer<ClockSource> timer(const std::string& name) {
        return v1::Timer<ClockSource>{this->_timers[name]};
    }
    v1::Gauge<ClockSource> gauge(const std::string& name) {
        return v1::Gauge<ClockSource>{this->_gauges[name]};
    }
    OperationT<ClockSource> operation(const std::string& name) {
        auto op = v1::OperationImpl<ClockSource>(name,
                                                 this->_timers[name + "_timer"],
                                                 this->_counters[name + "_iters"],
                                                 this->_counters[name + "_docs"],
                                                 this->_counters[name + "_bytes"]);
        return OperationT{std::move(op)};
    }

    // passkey:
    const std::unordered_map<std::string, v1::CounterImpl<ClockSource>>& getCounters(
        v1::Permission) const {
        return this->_counters;
    };

    const std::unordered_map<std::string, v1::TimerImpl<ClockSource>>& getTimers(
        v1::Permission) const {
        return this->_timers;
    };

    const std::unordered_map<std::string, v1::GaugeImpl<ClockSource>>& getGauges(
        v1::Permission) const {
        return this->_gauges;
    };

    const typename ClockSource::time_point now(v1::Permission) const {
        return ClockSource::now();
    }

private:
    std::unordered_map<std::string, v1::CounterImpl<ClockSource>> _counters;
    std::unordered_map<std::string, v1::TimerImpl<ClockSource>> _timers;
    std::unordered_map<std::string, v1::GaugeImpl<ClockSource>> _gauges;
};

}  // namespace v1

using Registry = v1::RegistryT<v1::MetricsClockSource>;

static_assert(std::is_move_constructible<Registry>::value, "move");
static_assert(std::is_move_assignable<Registry>::value, "move");

// Registry::clock is actually the ClockSource template parameter, so we check the underlying
// clock_type in a roundabout way by going through the time_point type it exposes.
static_assert(Registry::clock::time_point::clock::is_steady, "clock must be steady");

using Operation = v1::OperationT<Registry::clock>;
using OperationContext = v1::OperationContextT<Registry::clock>;

}  // namespace genny::metrics

#endif  // HEADER_058638D3_7069_42DC_809F_5DB533FCFBA3_INCLUDED

max_stars_repo_name: vrachev/genny

max_issues_repo_name: vrachev/genny

max_forks_repo_name: vrachev/genny


text:
#define BOOST_TEST_DYN_LINK
#include <canard/net/ofp/v13/message/flow_delete.hpp>
#include <boost/test/unit_test.hpp>

#include <cstdint>
#include <vector>
#include <canard/net/ofp/v13/instructions.hpp>
#include <canard/net/ofp/v13/common/oxm_match.hpp>

#include "../../test_utility.hpp"

namespace of = canard::net::ofp;
namespace v13 = of::v13;
namespace match = v13::oxm_match_fields;
namespace protocol = v13::protocol;

namespace  {

  struct flow_entry_fixture {
    match::in_port in_port{4};
    match::eth_dst eth_dst{"\x01\x02\x03\x04\x05\x06"_mac};
    match::eth_src eth_src{"\x11\x12\x13\x14\x15\x16"_mac};
    v13::oxm_match match{in_port, eth_dst, eth_src}; // 4 + 8 + 10 + 10 = 32
    std::uint16_t priority = protocol::OFP_DEFAULT_PRIORITY;
    std::uint64_t cookie = 0xf1f2f3f4f5f6f7f8;
    v13::instruction_set instructions{};
    v13::flow_entry entry{match, priority, cookie, instructions};
  };

  struct flow_delete_parameter : flow_entry_fixture {
    std::uint8_t table_id = protocol::OFPTT_ALL;
    v13::cookie_mask cookie_mask{0xf1f2f3f4f5f6f7f8, 0x0f0f0f0f0f0f0f0f};
    std::uint32_t out_port = protocol::OFPP_ANY;
    std::uint32_t out_group = 33;
    std::uint32_t xid = 0xff56ff78;
  };
  struct flow_delete_fixture : flow_delete_parameter
  {
    v13::messages::flow_delete sut{
      entry.match(), table_id, cookie_mask, out_port, out_group, xid
    };
    std::vector<std::uint8_t> bin
      = "\x04\x0e\x00\x50\xff\x56\xff\x78" "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8"
        "\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f" "\xff\x03\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\xff\xff\xff\xff" "\x00\x00\x00\x21\x00\x00\x00\x00"

        "\x00\x01\x00\x20\x80\x00\x00\x04" "\x00\x00\x00\x04\x80\x00\x06\x06"
        "\x01\x02\x03\x04\x05\x06\x80\x00" "\x08\x06\x11\x12\x13\x14\x15\x16"_bin
        ;
  };

  struct flow_delete_strict_parameter : flow_entry_fixture {
    std::uint8_t table_id = 0x8f;
    std::uint32_t out_port = protocol::OFPP_CONTROLLER;
    std::uint32_t out_group = protocol::OFPG_MAX;
    v13::cookie_mask cookie_mask{0xf1f2f3f4f5f6f7f8, 0x0f0f0f0f0f0f0f0f};
    std::uint32_t xid = 0xff56ff78;
  };
  struct flow_delete_strict_fixture : flow_delete_strict_parameter {
    v13::messages::flow_delete_strict sut{
      entry, table_id, out_port, out_group, xid
    };
    std::vector<std::uint8_t> bin
      = "\x04\x0e\x00\x50\xff\x56\xff\x78" "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8"
        "\xff\xff\xff\xff\xff\xff\xff\xff" "\x8f\x04\x00\x00\x00\x00\x80\x00"
        "\x00\x00\x00\x00\xff\xff\xff\xfd" "\xff\xff\xff\x00\x00\x00\x00\x00"

        "\x00\x01\x00\x20\x80\x00\x00\x04" "\x00\x00\x00\x04\x80\x00\x06\x06"
        "\x01\x02\x03\x04\x05\x06\x80\x00" "\x08\x06\x11\x12\x13\x14\x15\x16"_bin
        ;
  };

}

BOOST_AUTO_TEST_SUITE(message_test)
BOOST_AUTO_TEST_SUITE(flow_delete)
  BOOST_AUTO_TEST_SUITE(constructor)
    BOOST_FIXTURE_TEST_CASE(constructible_from_table_id, flow_entry_fixture)
    {
      auto const table_id = std::uint8_t{1};

      v13::messages::flow_delete const sut{entry.match(), table_id};

      BOOST_TEST(sut.version() == protocol::OFP_VERSION);
      BOOST_TEST(sut.type() == protocol::OFPT_FLOW_MOD);
      BOOST_TEST(sut.length() == sizeof(protocol::ofp_flow_mod) + 32);
      BOOST_TEST((sut.match() == entry.match()));
      BOOST_TEST(sut.table_id() == table_id);
      BOOST_TEST(sut.cookie() == 0);
      BOOST_TEST(sut.cookie_mask() == 0);
      BOOST_TEST(sut.out_port() == protocol::OFPP_ANY);
      BOOST_TEST(sut.out_group() == protocol::OFPG_ANY);
    }
    BOOST_AUTO_TEST_CASE(constructible_from_out_port)
    {
      auto const empty_match = v13::oxm_match{};
      auto const table_id = std::uint8_t{protocol::OFPTT_ALL};
      auto const out_port = std::uint32_t{1};
      auto const out_group = std::uint32_t{0};

      v13::messages::flow_delete const sut{
        empty_match, table_id, out_port, out_group
      };

      BOOST_TEST(sut.version() == protocol::OFP_VERSION);
      BOOST_TEST(sut.type() == protocol::OFPT_FLOW_MOD);
      BOOST_TEST(sut.length() == sizeof(protocol::ofp_flow_mod) + 8);
      BOOST_TEST((sut.match() == empty_match));
      BOOST_TEST(sut.table_id() == table_id);
      BOOST_TEST(sut.cookie() == 0);
      BOOST_TEST(sut.cookie_mask() == 0);
      BOOST_TEST(sut.out_port() == out_port);
      BOOST_TEST(sut.out_group() == out_group);
    }
    BOOST_AUTO_TEST_CASE(constructible_from_cookie_mask)
    {
      auto const empty_match = v13::oxm_match{};
      auto const table_id = std::uint8_t{254};
      auto const cookie_mask = v13::cookie_mask{0xff, 0xffff};

      v13::messages::flow_delete const sut{empty_match, table_id, cookie_mask};

      BOOST_TEST(sut.version() == protocol::OFP_VERSION);
      BOOST_TEST(sut.type() == protocol::OFPT_FLOW_MOD);
      BOOST_TEST(sut.length() == sizeof(protocol::ofp_flow_mod) + 8);
      BOOST_TEST((sut.match() == empty_match));
      BOOST_TEST(sut.table_id() == table_id);
      BOOST_TEST(sut.cookie() == cookie_mask.value());
      BOOST_TEST(sut.cookie_mask() == cookie_mask.mask());
      BOOST_TEST(sut.out_port() == protocol::OFPP_ANY);
      BOOST_TEST(sut.out_group() == protocol::OFPG_ANY);
    }
    BOOST_AUTO_TEST_CASE(constructible_from_cookie_mask_and_port)
    {
      auto const empty_match = v13::oxm_match{};
      auto const table_id = std::uint8_t{0};
      auto const cookie_mask = v13::cookie_mask{0xff, 0xffff};
      auto const out_port = std::uint32_t{protocol::OFPP_MAX};
      auto const out_group = std::uint32_t{protocol::OFPG_MAX};

      v13::messages::flow_delete const sut{
        empty_match, table_id, cookie_mask, out_port, out_group
      };

      BOOST_TEST(sut.version() == protocol::OFP_VERSION);
      BOOST_TEST(sut.type() == protocol::OFPT_FLOW_MOD);
      BOOST_TEST(sut.length() == sizeof(protocol::ofp_flow_mod) + 8);
      BOOST_TEST((sut.match() == empty_match));
      BOOST_TEST(sut.table_id() == table_id);
      BOOST_TEST(sut.cookie() == cookie_mask.value());
      BOOST_TEST(sut.cookie_mask() == cookie_mask.mask());
      BOOST_TEST(sut.out_port() == out_port);
      BOOST_TEST(sut.out_group() == out_group);
    }
    BOOST_FIXTURE_TEST_CASE(copy_constructible, flow_delete_fixture)
    {
      auto const copy = sut;

      BOOST_TEST((copy == sut));
    }
    BOOST_FIXTURE_TEST_CASE(move_constructible, flow_delete_fixture)
    {
        auto moved = sut;

        auto const copy = std::move(moved);

        BOOST_TEST((copy == sut));
        BOOST_TEST(moved.length() == sizeof(protocol::ofp_flow_mod) + 8);
        BOOST_TEST(moved.match().length() == 4);
    }
  BOOST_AUTO_TEST_SUITE_END() // constructor

  BOOST_FIXTURE_TEST_SUITE(assignment, flow_delete_fixture)
    BOOST_AUTO_TEST_CASE(copy_assignable)
    {
      auto copy = v13::messages::flow_delete{v13::oxm_match{}, 0};

      copy = sut;

      BOOST_TEST((copy == sut));
    }
    BOOST_AUTO_TEST_CASE(move_assignable)
    {
      auto copy = v13::messages::flow_delete{v13::oxm_match{}, 0};
      auto moved = sut;

      copy = std::move(moved);

      BOOST_TEST((copy == sut));
      BOOST_TEST(moved.length() == sizeof(protocol::ofp_flow_mod) + 8);
      BOOST_TEST(moved.match().length() == 4);
    }
  BOOST_AUTO_TEST_SUITE_END() // assignment

  BOOST_FIXTURE_TEST_SUITE(equality, flow_delete_parameter)
    BOOST_AUTO_TEST_CASE(true_if_same_object)
    {
      auto const sut = v13::messages::flow_delete{
        match, table_id, cookie_mask, out_port, out_group, xid
      };

      BOOST_TEST((sut == sut));
    }
    BOOST_AUTO_TEST_CASE(true_if_values_are_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete{
             match, table_id, cookie_mask, out_port, out_group, xid
           }
        == v13::messages::flow_delete{
             match, table_id, cookie_mask, out_port, out_group, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_match_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete{
               v13::oxm_match{eth_src}
             , table_id, cookie_mask, out_port, out_group, xid
           }
        != v13::messages::flow_delete{
               v13::oxm_match{eth_dst}
             , table_id, cookie_mask, out_port, out_group, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_table_id_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete{
             match, 1, cookie_mask, out_port, out_group, xid
           }
        != v13::messages::flow_delete{
             match, 2, cookie_mask, out_port, out_group, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_cookie_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete{
             match, table_id, v13::cookie_mask{1, 0}, out_port, out_group, xid
           }
        != v13::messages::flow_delete{
             match, table_id, v13::cookie_mask{2, 0}, out_port, out_group, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_cookie_mask_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete{
             match, table_id, v13::cookie_mask{0, 1}, out_port, out_group, xid
           }
        != v13::messages::flow_delete{
             match, table_id, v13::cookie_mask{0, 2}, out_port, out_group, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_out_port_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete{
             match, table_id, cookie_mask, 1, out_group, xid
           }
        != v13::messages::flow_delete{
             match, table_id, cookie_mask, 2, out_group, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_out_group_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete{
             match, table_id, cookie_mask, out_port, 1, xid
           }
        != v13::messages::flow_delete{
             match, table_id, cookie_mask, out_port, 2, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_xid_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete{
             match, table_id, cookie_mask, out_port, out_group, 1
           }
        != v13::messages::flow_delete{
             match, table_id, cookie_mask, out_port, out_group, 2
           }));
    }
  BOOST_AUTO_TEST_SUITE_END() // equality

  BOOST_AUTO_TEST_SUITE(encode)
    BOOST_FIXTURE_TEST_CASE(generate_binary, flow_delete_fixture)
    {
      auto buffer = std::vector<std::uint8_t>{};

      sut.encode(buffer);

      BOOST_TEST(buffer.size() == sut.byte_length());
      BOOST_TEST(buffer == bin, boost::test_tools::per_element{});
    }
  BOOST_AUTO_TEST_SUITE_END() // encode

  BOOST_AUTO_TEST_SUITE(decode)
    BOOST_FIXTURE_TEST_CASE(constructible_from_binary, flow_delete_fixture)
    {
      auto it = bin.begin();

      auto const flow_delete
        = v13::messages::flow_delete::decode(it, bin.end());

      BOOST_TEST((it == bin.end()));
      BOOST_TEST((flow_delete == sut));
    }
  BOOST_AUTO_TEST_SUITE_END() // decode
BOOST_AUTO_TEST_SUITE_END() // flow_delete

BOOST_AUTO_TEST_SUITE(flow_delete_strict)
  BOOST_AUTO_TEST_SUITE(constructor)
    BOOST_FIXTURE_TEST_CASE(constructible_from_entry, flow_entry_fixture)
    {
      auto const table_id = std::uint8_t{1};

      v13::messages::flow_delete_strict const sut{entry, table_id};

      BOOST_TEST(sut.version() == protocol::OFP_VERSION);
      BOOST_TEST(sut.type() == protocol::OFPT_FLOW_MOD);
      BOOST_TEST(sut.length() == sizeof(protocol::ofp_flow_mod) + 32);
      BOOST_TEST((sut.match() == entry.match()));
      BOOST_TEST(sut.priority() == entry.priority());
      BOOST_TEST(sut.table_id() == table_id);
      BOOST_TEST(sut.cookie() == entry.cookie());
      BOOST_TEST(sut.cookie_mask() == 0xffffffffffffffff);
      BOOST_TEST(sut.out_port() == protocol::OFPP_ANY);
      BOOST_TEST(sut.out_group() == protocol::OFPG_ANY);
    }
    BOOST_FIXTURE_TEST_CASE(
        constructible_from_entry_and_port, flow_entry_fixture)
    {
      auto const table_id = std::uint8_t{1};
      auto const out_port = std::uint32_t{protocol::OFPP_CONTROLLER};
      auto const out_group = 1;

      v13::messages::flow_delete_strict const sut{
        entry, table_id, out_port, out_group
      };

      BOOST_TEST(sut.version() == protocol::OFP_VERSION);
      BOOST_TEST(sut.type() == protocol::OFPT_FLOW_MOD);
      BOOST_TEST(sut.length() == sizeof(protocol::ofp_flow_mod) + 32);
      BOOST_TEST((sut.match() == entry.match()));
      BOOST_TEST(sut.priority() == entry.priority());
      BOOST_TEST(sut.table_id() == table_id);
      BOOST_TEST(sut.cookie() == entry.cookie());
      BOOST_TEST(sut.cookie_mask() == 0xffffffffffffffff);
      BOOST_TEST(sut.out_port() == out_port);
      BOOST_TEST(sut.out_group() == out_group);
    }
    BOOST_FIXTURE_TEST_CASE(constructible_from_table_id, flow_entry_fixture)
    {
      auto const table_id = std::uint8_t{protocol::OFPTT_ALL};

      v13::messages::flow_delete_strict const sut{
        entry.match(), entry.priority(), table_id
      };

      BOOST_TEST(sut.version() == protocol::OFP_VERSION);
      BOOST_TEST(sut.type() == protocol::OFPT_FLOW_MOD);
      BOOST_TEST(sut.length() == sizeof(protocol::ofp_flow_mod) + 32);
      BOOST_TEST((sut.match() == entry.match()));
      BOOST_TEST(sut.priority() == entry.priority());
      BOOST_TEST(sut.table_id() == table_id);
      BOOST_TEST(sut.cookie() == 0);
      BOOST_TEST(sut.cookie_mask() == 0);
      BOOST_TEST(sut.out_port() == protocol::OFPP_ANY);
      BOOST_TEST(sut.out_group() == protocol::OFPG_ANY);
    }
    BOOST_AUTO_TEST_CASE(constructible_from_cookie_mask)
    {
      auto const empty_match = v13::oxm_match{};
      auto const priority = std::uint16_t{65535};
      auto const table_id = std::uint8_t{0};
      auto const cookie_mask
        = v13::cookie_mask{0x0f0f0f0f0f0f0f0f, 0xffffffff0000000f};

      v13::messages::flow_delete_strict const sut{
        empty_match, priority, table_id, cookie_mask
      };

      BOOST_TEST(sut.version() == protocol::OFP_VERSION);
      BOOST_TEST(sut.type() == protocol::OFPT_FLOW_MOD);
      BOOST_TEST(sut.length() == sizeof(protocol::ofp_flow_mod) + 8);
      BOOST_TEST((sut.match() == empty_match));
      BOOST_TEST(sut.priority() == priority);
      BOOST_TEST(sut.table_id() == table_id);
      BOOST_TEST(sut.cookie() == cookie_mask.value());
      BOOST_TEST(sut.cookie_mask() == cookie_mask.mask());
      BOOST_TEST(sut.out_port() == protocol::OFPP_ANY);
      BOOST_TEST(sut.out_group() == protocol::OFPG_ANY);
    }
    BOOST_AUTO_TEST_CASE(constructible_from_out_port)
    {
      auto const empty_match = v13::oxm_match{};
      auto const priority = std::uint16_t{protocol::OFP_DEFAULT_PRIORITY};
      auto const table_id = std::uint8_t{1};
      auto const out_port = std::uint32_t{1};
      auto const out_group = 254;

      v13::messages::flow_delete_strict const sut{
        empty_match, priority, table_id, out_port, out_group
      };

      BOOST_TEST(sut.version() == protocol::OFP_VERSION);
      BOOST_TEST(sut.type() == protocol::OFPT_FLOW_MOD);
      BOOST_TEST(sut.length() == sizeof(protocol::ofp_flow_mod) + 8);
      BOOST_TEST((sut.match() == empty_match));
      BOOST_TEST(sut.priority() == priority);
      BOOST_TEST(sut.table_id() == table_id);
      BOOST_TEST(sut.cookie() == 0);
      BOOST_TEST(sut.cookie_mask() == 0);
      BOOST_TEST(sut.out_port() == out_port);
      BOOST_TEST(sut.out_group() == out_group);
    }
    BOOST_FIXTURE_TEST_CASE(copy_constructible, flow_delete_strict_fixture)
    {
      auto const copy = sut;

      BOOST_TEST((copy == sut));
    }
    BOOST_FIXTURE_TEST_CASE(move_constructible, flow_delete_strict_fixture)
    {
      auto moved = sut;
      auto const copy = std::move(moved);

      BOOST_TEST((copy == sut));
      BOOST_TEST(moved.length() == sizeof(protocol::ofp_flow_mod) + 8);
      BOOST_TEST(moved.match().length() == 4);
    }
  BOOST_AUTO_TEST_SUITE_END() // constructor

  BOOST_FIXTURE_TEST_SUITE(assignment, flow_delete_strict_fixture)
    BOOST_AUTO_TEST_CASE(copy_assignable)
    {
      auto copy = v13::messages::flow_delete_strict{v13::oxm_match{}, 0, 0};

      copy = sut;

      BOOST_TEST((copy == sut));
    }

    BOOST_AUTO_TEST_CASE(move_assignable)
    {
      auto moved = sut;
      auto copy = v13::messages::flow_delete_strict{v13::oxm_match{}, 0, 0};

      copy = std::move(moved);

      BOOST_TEST((copy == sut));
      BOOST_TEST(moved.length() == sizeof(protocol::ofp_flow_mod) + 8);
      BOOST_TEST(moved.match().length() == 4);
    }
  BOOST_AUTO_TEST_SUITE_END() // assignment

  BOOST_FIXTURE_TEST_SUITE(equality, flow_delete_strict_parameter)
    BOOST_AUTO_TEST_CASE(true_if_same_object)
    {
      auto const sut = v13::messages::flow_delete_strict{
        entry, table_id, out_port, out_group, xid
      };

      BOOST_TEST((sut == sut));
    }
    BOOST_AUTO_TEST_CASE(true_if_values_are_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete_strict{
             entry, table_id, out_port, out_group, xid
           }
        == v13::messages::flow_delete_strict{
             entry, table_id, out_port, out_group, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_match_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete_strict{
               v13::oxm_match{eth_dst}
             , priority, table_id, cookie_mask, out_port, out_group, xid
           }
        != v13::messages::flow_delete_strict{
               v13::oxm_match{eth_src}
             , priority, table_id, cookie_mask, out_port, out_group, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_priority_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete_strict{
             match, 1, table_id, cookie_mask, out_port, out_group, xid
           }
        != v13::messages::flow_delete_strict{
             match, 2, table_id, cookie_mask, out_port, out_group, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_cookie_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete_strict{
               match, priority, table_id
             , v13::cookie_mask{1, 0}, out_port, out_group, xid
           }
        != v13::messages::flow_delete_strict{
               match, priority, table_id
             , v13::cookie_mask{2, 0}, out_port, out_group, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_cookie_mask_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete_strict{
               match, priority, table_id
             , v13::cookie_mask{0, 1}, out_port, out_group, xid
           }
        != v13::messages::flow_delete_strict{
               match, priority, table_id
             , v13::cookie_mask{0, 2}, out_port, out_group, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_table_id_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete_strict{
             entry, 1, out_port, out_group, xid
           }
        != v13::messages::flow_delete_strict{
             entry, 2, out_port, out_group, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_out_port_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete_strict{
             entry, table_id, 1, out_group, xid
           }
        != v13::messages::flow_delete_strict{
             entry, table_id, 2, out_group, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_out_group_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete_strict{
             entry, table_id, out_port, 1, xid
           }
        != v13::messages::flow_delete_strict{
             entry, table_id, out_port, 2, xid
           }));
    }
    BOOST_AUTO_TEST_CASE(false_if_xid_is_not_equal)
    {
      BOOST_TEST(
          (v13::messages::flow_delete_strict{
             entry, table_id, out_port, out_group, 1
           }
        != v13::messages::flow_delete_strict{
             entry, table_id, out_port, out_group, 2
           }));
    }
  BOOST_AUTO_TEST_SUITE_END() // equality

  BOOST_AUTO_TEST_SUITE(encode)
    BOOST_FIXTURE_TEST_CASE(generate_binary, flow_delete_strict_fixture)
    {
      auto buffer = std::vector<std::uint8_t>{};

      sut.encode(buffer);

      BOOST_TEST(buffer.size() == sut.byte_length());
      BOOST_TEST(buffer == bin, boost::test_tools::per_element{});
    }
  BOOST_AUTO_TEST_SUITE_END() // encode

  BOOST_AUTO_TEST_SUITE(decode)
    BOOST_FIXTURE_TEST_CASE(
        constructible_from_binary, flow_delete_strict_fixture)
    {
      auto it = bin.begin();

      auto const flow_delete_strict
        = v13::messages::flow_delete_strict::decode(it, bin.end());

      BOOST_TEST((it == bin.end()));
      BOOST_TEST((flow_delete_strict == sut));
    }
  BOOST_AUTO_TEST_SUITE_END() // decode
BOOST_AUTO_TEST_SUITE_END() // flow_delete_strict
BOOST_AUTO_TEST_SUITE_END() // message_test

ext: cpp


text:
/*
 * Newton simulator header
 *
 * This file is part of the "SoftPixel Engine" (Copyright (c) 2008 by Lukas Hermanns)
 * See "SoftPixelEngine.hpp" for license information.
 */

#ifndef __SP_PHYSICS_NEWTON_SIMULATOR_H__
#define __SP_PHYSICS_NEWTON_SIMULATOR_H__

#include "Base/spStandard.hpp"

#ifdef SP_COMPILE_WITH_NEWTON

#include "Base/spDimension.hpp"
#include "Framework/Physics/spPhysicsSimulator.hpp"

#include <boost/function.hpp>

struct NewtonWorld;

namespace sp
{
namespace physics
{

//! Third party library extension: "Newton Game Dynamics" (v.2.0) physics simulation engine.
class SP_EXPORT NewtonSimulator : public PhysicsSimulator
{

    public:

        NewtonSimulator();
        virtual ~NewtonSimulator();

        virtual io::stringc getVersion() const;

        virtual void updateSimulation(const f32 StepTime = 1.0f / 60.0f);
        virtual void setGravity(const dim::vector3df &Gravity);

        virtual PhysicsMaterial* createMaterial(
            f32 StaticFriction = 0.5f, f32 DynamicFriction = 0.5f, f32 Restitution = 1.0f
        );

        virtual StaticPhysicsObject* createStaticObject(PhysicsMaterial* Material, scene::Mesh* MeshGeom);

        virtual RigidBody* createRigidBody(
            PhysicsMaterial* Material, const ERigidBodies Type, scene::SceneNode* RootNode,
            const SRigidBodyConstruction &Construct = SRigidBodyConstruction()
        );
        virtual RigidBody* createRigidBody(PhysicsMaterial* Material, scene::Mesh* Mesh);

        virtual PhysicsJoint* createJoint(
            const EPhysicsJoints Type, PhysicsBaseObject* Object, const SPhysicsJointConstruct &Construct
        );
        virtual PhysicsJoint* createJoint(
            const EPhysicsJoints Type, PhysicsBaseObject* ObjectA, PhysicsBaseObject* ObjectB, const SPhysicsJointConstruct &Construct
        );

        virtual void setThreadCount(s32 Count);
        virtual s32 getThreadCount() const;

        virtual void setSolverModel(s32 Model);

        static void setContactCallback(const PhysicsContactCallback &Callback);

        //! Returns a pointer to the current NewtonWorld opject.
        static NewtonWorld* getNewtonWorld();

    protected:

        /* === Functions === */

        virtual RigidBody* allocRigidBody(const ERigidBodies Type, const SRigidBodyConstruction &Construct);
        virtual RigidBody* allocRigidBody(scene::Mesh* MeshGeom);

        /* === Members === */

        static NewtonWorld* NtWorld_;

};

} // /namespace physics

} // /namespace sp

#endif

#endif

// ================================================================================

max_stars_repo_name: rontrek/softpixel

max_issues_repo_name: rontrek/softpixel

max_forks_repo_name: rontrek/softpixel


text:
#ifndef BOOST_SERIALIZATION_EXPORT_HPP
#define BOOST_SERIALIZATION_EXPORT_HPP

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// export.hpp: set traits of classes to be serialized

// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is 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)

//  See http://www.boost.org for updates, documentation, and revision history.

// implementation of class export functionality.  This is an alternative to
// "forward declaration" method to provoke instantiation of derived classes
// that are to be serialized through pointers.

#include <utility>

#include <boost/config.hpp>

#include <boost/static_assert.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/void.hpp>
#include <boost/mpl/identity.hpp>

#include <boost/serialization/force_include.hpp>
#include <boost/serialization/extended_type_info.hpp>
#include <boost/serialization/type_info_implementation.hpp>

#include <boost/archive/detail/known_archive_types.hpp>

namespace boost {

namespace archive {
namespace detail {

// forward template declarations
class basic_pointer_iserializer;
template<class Archive, class T>
const basic_pointer_iserializer &
instantiate_pointer_iserializer(Archive * ar, T *);

class basic_pointer_oserializer;
template<class Archive, class T>
const basic_pointer_oserializer &
instantiate_pointer_oserializer(Archive * ar, T *);

namespace export_impl
{
    struct nothing{
        static void instantiate(){}
    };

    template<class Archive, class T>
    struct archive {
        struct i {
            static void invoke(){
                instantiate_pointer_iserializer(
                    static_cast<Archive *>(NULL),
                    static_cast<T *>(NULL)
                );
            }
        };
        struct o {
            static void invoke(){
                instantiate_pointer_oserializer(
                    static_cast<Archive *>(NULL),
                    static_cast<T *>(NULL)
                );
            }
        };
        static void instantiate(){
            #if defined(__GNUC__) && (__GNUC__ >= 3)
            BOOST_STATIC_ASSERT(
                Archive::is_loading::value || Archive::is_saving::value
            );
            #endif
            mpl::eval_if<
                BOOST_DEDUCED_TYPENAME Archive::is_saving,
                mpl::identity<o>,
            // else
            mpl::eval_if<
                BOOST_DEDUCED_TYPENAME Archive::is_loading,
                mpl::identity<i>,
            // else
                mpl::identity<nothing>
            > >::type::invoke();
        }
    };

    template<class ASeq, class T>
    struct for_each_archive {
    private:
        typedef BOOST_DEDUCED_TYPENAME mpl::pop_front<ASeq>::type tail;
        typedef BOOST_DEDUCED_TYPENAME mpl::front<ASeq>::type head;
    public:
        static void instantiate(){
            archive<head, T>::instantiate();
            mpl::eval_if<
                mpl::empty<tail>,
                mpl::identity<nothing>,
                mpl::identity<for_each_archive<tail, T> >
            >::type::instantiate();
        }
    };

} // namespace export_impl

// strictly conforming
template<class T, class ASeq>
struct export_generator {
    export_generator(){
        export_impl::for_each_archive<ASeq, T>::instantiate();
    }
    static const export_generator instance;
};

template<class T, class ASeq>
const export_generator<T, ASeq>
    export_generator<T, ASeq>::instance;

// instantiation of this template creates a static object.
template<class T, class ASeq>
struct guid_initializer {
    struct empty {
        static void key_register(const char *key){}
    };
    struct non_empty {
        typedef BOOST_DEDUCED_TYPENAME boost::serialization::type_info_implementation<T>::type eti_type;
        static void key_register(const char *key){
            boost::serialization::extended_type_info * eti = eti_type::get_instance();
            eti->key_register(key);
        }
    };
    static const guid_initializer instance;
    /* BOOST_DLLEXPORT */  guid_initializer(const char *key = NULL) BOOST_USED ;
};

template<class T, class ASeq>
/* BOOST_DLLEXPORT */ guid_initializer<T, ASeq>::guid_initializer(const char *key){
    typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
        mpl::empty<ASeq>,
        mpl::identity<empty>,
        mpl::identity<non_empty>
    >::type typex;
    typex::key_register(key);
}

template<class T, class ASeq>
const guid_initializer<T, ASeq> guid_initializer<T, ASeq>::instance;

} // namespace detail
} // namespace archive
} // namespace boost

// if no archive headers have been included this is a no op
// this is to permit BOOST_EXPORT etc to be included in a
// file declaration header
#if ! defined(BOOST_ARCHIVE_EXPORT)
    #define BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, K, ASEQ)
#else
    // only gcc seems to be able to explicitly instantiate a static instance.
    // all but can instantiate a function that refers to a static instance
    namespace boost { namespace archive { namespace detail {
    // note declaration to permit gcc trailing function attribute
    template<class T, class ASeq>
    BOOST_DLLEXPORT std::pair<const void *, const void *>
    boost_template_instantiate(T &, ASeq &) BOOST_USED;
    template<class T, class ASeq>
    BOOST_DLLEXPORT std::pair<const void *, const void *>
    boost_template_instantiate(T &, ASeq &){
        return std::pair<const void *, const void *>(
            & export_generator<T, ASeq>::instance,
            & guid_initializer<T, ASeq>::instance
        );
    }
    } } }
    #define BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, K, ASEQ)         \
        namespace boost { namespace archive { namespace detail {     \
        template<>                                                   \
        const guid_initializer<T, ASEQ>                              \
            guid_initializer<T, ASEQ>::instance(K);                  \
        template                                                     \
        BOOST_DLLEXPORT std::pair<const void *, const void *>        \
        boost_template_instantiate(T &, ASEQ &);                     \
        } } }                                                        \
        /**/
#endif

// check for unnecessary export.  T isn't polymorphic so there is no
// need to export it.
#define BOOST_CLASS_EXPORT_CHECK(T)                              \
    BOOST_STATIC_WARNING(                                        \
        boost::serialization::type_info_implementation<T>        \
            ::type::is_polymorphic::value                        \
    );                                                           \
    /**/

// the default list of archives types for which code id generated
#define BOOST_CLASS_EXPORT_GUID(T, K)                            \
    BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(                        \
        T,                                                       \
        K,                                                       \
        boost::archive::detail::known_archive_types<false>::type \
    )                                                            \
    /**/

// the default exportable class identifier is the class name
#define BOOST_CLASS_EXPORT_ARCHIVE_LIST(T, ASEQ)   \
    BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, BOOST_PP_STRINGIZE(T), A)

// the default exportable class identifier is the class name
// the default list of archives types for which code id generated
// are the originally included with this serialization system
#define BOOST_CLASS_EXPORT(T)                                    \
    BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(                        \
        T,                                                       \
        BOOST_PP_STRINGIZE(T),                                   \
        boost::archive::detail::known_archive_types<false>::type \
    )                                                            \
    /**/

#endif // BOOST_SERIALIZATION_EXPORT_HPP

max_stars_repo_name: macaurther/DOCUSA

max_issues_repo_name: macaurther/DOCUSA

max_forks_repo_name: dguenms/Dawn-of-Civilization


text:
#include <boost/config.hpp>

#if !defined(EDBA_TYPES_SUPPORT_STD_SHARED_PTR_HPP) && !defined(BOOST_NO_CXX11_SMART_PTR)
#define EDBA_TYPES_SUPPORT_STD_SHARED_PTR_HPP

#include <edba/statement.hpp>

#include <memory>

namespace edba
{

template<typename T>
struct bind_conversion<std::shared_ptr<T>, void>
{
    template<typename ColOrName>
    static void bind(statement& st, ColOrName col_or_name, const std::shared_ptr<T>& v)
    {
        if (v)
            st.bind(col_or_name, *v);
        else
            st.bind(col_or_name, null);
    }
};

template<typename T>
struct fetch_conversion<std::shared_ptr<T>, typename boost::disable_if< boost::is_const<T> >::type>
{
    template<typename ColOrName>
    static bool fetch(const row& res, ColOrName col_or_name, std::shared_ptr<T>& v)
    {
        std::shared_ptr<T> tmp = std::make_shared<T>();

        if (res.fetch(col_or_name, *tmp))
            v = tmp;
        else
            v.reset();

        return true;
    }
};

}

#endif // EDBA_TYPES_SUPPORT_STD_SHARED_PTR_HPP


text:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <map>
#include <valarray>
#include <boost/algorithm/string.hpp>

using namespace std;

map<string, valarray<int>> DIRECTIONS = {
    // x, y, z
    // Hex cubic labeling
    {"e", {1, -1, 0}},
    {"w", {-1, 1, 0}},
    {"se", {1, 0, -1}},
    {"ne", {0, -1, 1}},
    {"sw", {0, 1, -1}},
    {"nw", {-1, 0, 1}},
};

string hash_loc(valarray<int> loc){
  return (to_string(loc[0]) + ","+
          to_string(loc[1]) + ","+
          to_string(loc[2]));
}

valarray<int> unhash_loc(string hloc) {
  vector<string> split_str;
  boost::split(split_str, hloc, boost::is_any_of(","));
  valarray<int> out = {
      stoi(split_str[0]),
      stoi(split_str[1]),
      stoi(split_str[2]),
  };
  return out;
}

int count_black(map<string, int> tile_flips){
  int num_black = 0;
  for (auto [sloc, flips] : tile_flips) {
    num_black += flips % 2;
  }
  return num_black;
}

int main() {

  map<string, int> tile_flips; // 1 if black

  for (string line; getline(cin, line);){
    // cout << line << endl;
    vector<string> directions;
    int curr_loc=0;
    while (curr_loc < line.size()){
      if ((line[curr_loc] == 'n') ||
          (line[curr_loc] == 's')) {
        directions.push_back(line.substr(curr_loc, 2));
        curr_loc += 2;
      } else{
        directions.push_back(line.substr(curr_loc, 1));
        curr_loc += 1;
      }
    }
    valarray<int> loc = {0,0,0}; // Reference tile
    for (string dir : directions){
      loc += DIRECTIONS[dir];
    }
    tile_flips[hash_loc(loc)] += 1;
  }

  cout << "Part 1: " << count_black(tile_flips) << endl;
  cout << endl;

  // Part 2
  int num_days = 100;
  for (int i=1; i<=num_days; i++){
    auto start_flips = tile_flips;
    // Map of white tiles to num black adjacent
    // Only gets evaluated for tiles with atleast 1 black neighbour
    map<string,int> blackn_count;
    // Look over all known tiles;
    for (auto [hloc, flips] : start_flips){
      bool black = flips % 2;
      valarray<int> loc = unhash_loc(hloc);
      if (black){
        // If a black tile, count adjacent black tiles
        int blackn = 0;
        for (auto [dir, mdir] : DIRECTIONS){
          string nhash = hash_loc(loc + mdir);
          bool is_blackn = (start_flips[nhash] % 2);
          blackn += is_blackn;
          // If neighbour is white, increment
          // the number of black adjacents that
          // that white tile has.
          if (not is_blackn){
            blackn_count[nhash] += 1;
          }
        }
        // Flip if matches rule for black tile
        if ((blackn == 0) || (blackn > 2)){
          tile_flips[hloc]++;
        }
      }
    }

    // Find white tiles with 2 black adjacent.
    for (auto [hloc, nblackn] : blackn_count){
      if (nblackn == 2){
        tile_flips[hloc]++;
      }
    }
    cout << "Day " << i << ": " << count_black(tile_flips) << endl;
  }
  cout << endl;
  cout << "Part 2: " << count_black(tile_flips) << endl;
}