text:
#include <catch2/catch.hpp>

#include "constitutive/internal_variables.hpp"
#include "constitutive/constitutive_model_factory.hpp"
#include "constitutive/mechanics/solid/gaussian_ageing_affine_microsphere.hpp"

#include "exceptions.hpp"
#include "numeric/dense_matrix.hpp"
#include "io/json.hpp"

#include <Eigen/Eigenvalues>

#include <iostream>

std::string json_input_file()
{
    return "{\"name\": \"rubber\", \"elastic_modulus\": 2.0, \"poissons_ratio\": 0.45}";
}

constexpr auto ZERO_MARGIN = 1E-5;

using neon::json;
using namespace neon;

TEST_CASE("Gaussian affine microsphere model with ageing")
{
    using namespace neon::mechanics::solid;

    auto variables = std::make_shared<internal_variables_t>(1);

    // Add the required variables for an updated Lagrangian formulation
    variables->add(variable::second::deformation_gradient, variable::second::cauchy_stress);

    variables->add(variable::scalar::DetF);

    auto const material_data{"{\"name\" : \"rubber\","
                             "\"shear_modulus\" : 2.0e6,"
                             "\"bulk_modulus\" : 100e6,"
                             "\"segments_per_chain\" : 50,"
                             "\"cure_time\" : 100,"
                             "\"scission_probability\" : 1.0e-5,"
                             "\"recombination_probability\" : 1.0e-5}"};

    auto const constitutive_data{"{\"constitutive\" : {\"name\": \"microsphere\","
                                 "\"type\":\"affine\","
                                 "\"statistics\":\"gaussian\","
                                 "\"quadrature\":\"BO21\","
                                 "\"ageing\":\"BAND\"}}"};

    auto affine = make_constitutive_model(variables,
                                          json::parse(material_data),
                                          json::parse(constitutive_data));

    auto [deformation_gradients,
          cauchy_stresses] = variables->get(variable::second::deformation_gradient,
                                            variable::second::cauchy_stress);

    auto& jacobians = variables->get(variable::scalar::DetF);
    std::fill(begin(jacobians), end(jacobians), 1.0);

    auto& material_tangents = variables->get(variable::fourth::tangent_operator);

    Eigen::EigenSolver<Eigen::MatrixXd> eigen_solver;

    SECTION("Setup checks")
    {
        REQUIRE(affine->is_symmetric());
        REQUIRE(affine->is_finite_deformation());
        REQUIRE(affine->intrinsic_material().name() == "rubber");

        REQUIRE(variables->has(variable::scalar::active_shear_modulus));
        REQUIRE(variables->has(variable::scalar::inactive_shear_modulus));
        REQUIRE(variables->has(variable::scalar::active_segments));
        REQUIRE(variables->has(variable::scalar::inactive_segments));
        REQUIRE(variables->has(variable::scalar::reduction_factor));

        for (auto segment : variables->get(variable::scalar::active_segments))
        {
            REQUIRE(segment == Approx(50.0));
        }
        for (auto shear_modulus : variables->get(variable::scalar::active_shear_modulus))
        {
            REQUIRE(shear_modulus == Approx(2.0e6));
        }
    }
    SECTION("no load")
    {
        std::fill(begin(deformation_gradients), end(deformation_gradients), neon::matrix3::Identity());

        affine->update_internal_variables(1.0);

        // Check the network parameters
        auto [active_segments,
              inactive_segments,
              active_shear_moduli,
              inactive_shear_moduli,
              reductions] = variables->get(variable::scalar::active_segments,
                                           variable::scalar::inactive_segments,
                                           variable::scalar::active_shear_modulus,
                                           variable::scalar::inactive_shear_modulus,
                                           variable::scalar::reduction_factor);

        for (auto active_segment : active_segments)
        {
            REQUIRE(active_segment > 49.0);
            REQUIRE(active_segment < 50.0);
        }
        for (auto inactive_segment : inactive_segments)
        {
            REQUIRE(inactive_segment > 20.0);
            REQUIRE(inactive_segment < 25.0);
        }
        for (auto shear_modulus : active_shear_moduli)
        {
            REQUIRE(shear_modulus < 2.01e6);
            REQUIRE(shear_modulus > 2.0e6);
        }
        for (auto shear_modulus : inactive_shear_moduli)
        {
            REQUIRE(shear_modulus < 2000.0);
            REQUIRE(shear_modulus > 1000.0);
        }
        for (auto reduction : reductions)
        {
            REQUIRE(reduction > 0.99);
            REQUIRE(reduction < 1.0);
        }

        // Check for zero Cauchy stresses under no load
        for (auto const& cauchy_stress : variables->get(variable::second::cauchy_stress))
        {
            REQUIRE(cauchy_stress.norm() == Approx(0.0).margin(ZERO_MARGIN));
        }

        for (auto const& material_tangent : material_tangents)
        {
            REQUIRE((material_tangent - material_tangent.transpose()).norm()
                    == Approx(0.0).margin(ZERO_MARGIN));

            eigen_solver.compute(material_tangent);
            REQUIRE((eigen_solver.eigenvalues().real().array() > 0.0).all());
        }
    }
    SECTION("uniaxial load")
    {
        std::fill(begin(deformation_gradients), end(deformation_gradients), matrix3::Identity());

        affine->update_internal_variables(1.0);

        for (auto& cauchy_stress : cauchy_stresses)
        {
            REQUIRE(cauchy_stress.norm() == Approx(0.0).margin(ZERO_MARGIN));
        }

        std::cout << "setting to stretch 1.1\n";

        for (auto& F : deformation_gradients)
        {
            F(0, 0) = 1.1;
            F(1, 1) = 1.0 / std::sqrt(1.1);
            F(2, 2) = 1.0 / std::sqrt(1.1);
        }

        affine->update_internal_variables(1.0);

        for (auto& cauchy_stress : cauchy_stresses)
        {
            std::cout << cauchy_stress << "\n\n";
            REQUIRE(cauchy_stress.norm() > 0.0);
        }

        affine->update_internal_variables(1.0);

        for (auto& cauchy_stress : cauchy_stresses)
        {
            std::cout << cauchy_stress << "\n\n";
            REQUIRE(cauchy_stress.norm() > 0.0);
        }

        std::cout << "setting to unity\n";
        std::fill(begin(deformation_gradients), end(deformation_gradients), matrix3::Identity());

        affine->update_internal_variables(1.0);

        for (auto& cauchy_stress : cauchy_stresses)
        {
            std::cout << cauchy_stress << "\n\n";
            REQUIRE(cauchy_stress.norm() >= 0.0);
        }

        std::cout << "finished the analysis\n";

        for (auto const& material_tangent : material_tangents)
        {
            REQUIRE((material_tangent - material_tangent.transpose()).norm()
                    == Approx(0.0).margin(ZERO_MARGIN));

            eigen_solver.compute(material_tangent);
            REQUIRE((eigen_solver.eigenvalues().real().array() > 0.0).all());
        }
    }
}
TEST_CASE("Gaussian affine microsphere model with crosslinking only")
{
    using namespace neon::mechanics::solid;

    auto variables = std::make_shared<internal_variables_t>(1);

    // Add the required variables for an updated Lagrangian formulation
    variables->add(variable::second::deformation_gradient, variable::second::cauchy_stress);

    variables->add(variable::scalar::DetF);

    auto const material_data{"{\"name\" : \"rubber\","
                             "\"shear_modulus\" : 2.0e6,"
                             "\"bulk_modulus\" : 100e6,"
                             "\"segments_per_chain\" : 50,"
                             "\"cure_time\" : 100,"
                             "\"scission_probability\" : 0.0,"
                             "\"recombination_probability\" : 1.0e-5}"};

    auto const constitutive_data{"{\"constitutive\" : {\"name\": \"microsphere\","
                                 "\"type\":\"affine\","
                                 "\"statistics\":\"gaussian\","
                                 "\"quadrature\":\"BO21\","
                                 "\"ageing\":\"BAND\"}}"};

    auto affine = make_constitutive_model(variables,
                                          json::parse(material_data),
                                          json::parse(constitutive_data));

    auto [deformation_gradients,
          cauchy_stresses] = variables->get(variable::second::deformation_gradient,
                                            variable::second::cauchy_stress);

    auto& jacobians = variables->get(variable::scalar::DetF);
    std::fill(begin(jacobians), end(jacobians), 1.0);

    auto& material_tangents = variables->get(variable::fourth::tangent_operator);

    Eigen::EigenSolver<Eigen::MatrixXd> eigen_solver;

    SECTION("no load")
    {
        std::fill(begin(deformation_gradients), end(deformation_gradients), neon::matrix3::Identity());

        affine->update_internal_variables(1.0);

        // Check the network parameters
        auto [active_segments,
              inactive_segments,
              active_shear_moduli,
              inactive_shear_moduli,
              reductions] = variables->get(variable::scalar::active_segments,
                                           variable::scalar::inactive_segments,
                                           variable::scalar::active_shear_modulus,
                                           variable::scalar::inactive_shear_modulus,
                                           variable::scalar::reduction_factor);

        for (auto active_segment : active_segments)
        {
            REQUIRE(active_segment > 49.0);
            REQUIRE(active_segment < 50.0);
        }
        for (auto inactive_segment : inactive_segments)
        {
            REQUIRE(inactive_segment == Approx(0.0).margin(0.0));
        }
        for (auto shear_modulus : active_shear_moduli)
        {
            REQUIRE(shear_modulus < 2.01e6);
            REQUIRE(shear_modulus > 2.0e6);
        }
        for (auto shear_modulus : inactive_shear_moduli)
        {
            REQUIRE(shear_modulus == Approx(0.0).margin(0.0));
        }
        for (auto reduction : reductions)
        {
            REQUIRE(reduction <= 1.0);
        }

        for (auto const& material_tangent : material_tangents)
        {
            REQUIRE((material_tangent - material_tangent.transpose()).norm()
                    == Approx(0.0).margin(ZERO_MARGIN));

            eigen_solver.compute(material_tangent);
            REQUIRE((eigen_solver.eigenvalues().real().array() > 0.0).all());
        }
    }
    SECTION("constant load")
    {
        std::fill(begin(deformation_gradients), end(deformation_gradients), neon::matrix3::Identity());

        affine->update_internal_variables(1.0);

        for (auto& F : deformation_gradients)
        {
            F(0, 0) = 1.1;
            F(1, 1) = 1.0 / std::sqrt(1.1);
            F(2, 2) = 1.0 / std::sqrt(1.1);
        }

        affine->update_internal_variables(1.0);

        for (auto const& cauchy_stress : cauchy_stresses)
        {
            std::cout << "Step 1: cauchy_stress\n" << cauchy_stress << "\n\n";
        }

        affine->update_internal_variables(1.0);

        for (auto const& cauchy_stress : cauchy_stresses)
        {
            std::cout << "Step 2: cauchy_stress\n" << cauchy_stress << "\n\n";
        }

        affine->update_internal_variables(1.0);

        for (auto const& cauchy_stress : cauchy_stresses)
        {
            std::cout << "Step 3: cauchy_stress\n" << cauchy_stress << "\n\n";
        }

        affine->update_internal_variables(1.0);

        for (auto const& cauchy_stress : cauchy_stresses)
        {
            std::cout << "Step 3: cauchy_stress\n" << cauchy_stress << "\n\n";
        }

        affine->update_internal_variables(1.0);

        for (auto const& cauchy_stress : cauchy_stresses)
        {
            std::cout << "Step 3: cauchy_stress\n" << cauchy_stress << "\n\n";
        }

        for (auto const& material_tangent : material_tangents)
        {
            std::cout << "tangent_matrix\n" << material_tangent << "\n";

            REQUIRE((material_tangent - material_tangent.transpose()).norm()
                    == Approx(0.0).margin(ZERO_MARGIN));

            eigen_solver.compute(material_tangent);
            REQUIRE((eigen_solver.eigenvalues().real().array() > 0.0).all());
        }
    }
}
// TEST_CASE("Finite J2 plasticity")
// {
//     using namespace neon::mechanics::solid;
//
//     // Create a json reader object from a string
//     std::string
//         input_data = "{\"name\": \"steel\", \"elastic_modulus\": 200.0e9, \"poissons_ratio\": 0.3,
//         "
//                      "\"yield_stress\": 200.0e6, \"isotropic_hardening_modulus\": 400.0e6}";
//
//     std::string simulation_input = "{\"constitutive\" : {\"name\" : \"small_strain_J2_plasticity\", "
//                                    "\"finite_strain\":true}}";
//
//     Json::Value material_data, simulation_data;
//
//     Json::Reader reader;
//
//     REQUIRE(reader.parse(input_data.c_str(), material_data));
//     REQUIRE(reader.parse(simulation_input.c_str(), simulation_data));
//
//     internal_variables variables(1);
//
//     // Add the required variables for an updated Lagrangian formulation
//     variables->add(variable::second::deformation_gradient,
//     variable::second::cauchy_stress); variables->add(variable::scalar::DetF);
//
//     auto small_strain_J2_plasticity = make_constitutive_model(variables, material_data,
//     simulation_data);
//
//     // Get the tensor variables
//     auto[deformation_gradients, cauchy_stresses] =
//     variables->get(variable::second::deformation_gradient,
//                                               variable::second::cauchy_stress);
//
//     auto& jacobians = variables->get(variable::scalar::DetF);
//
//     auto& material_tangents = variables->get(variable::fourth::tangent_operator);
//
//     for (auto& F : deformation_gradients) F = neon::matrix3::Identity();
//     for (auto& J : jacobians) J = 1.0;
//
//     variables.commit();
//
//     SECTION("Sanity checks")
//     {
//         REQUIRE(small_strain_J2_plasticity->is_finite_deformation() == true);
//         REQUIRE(small_strain_J2_plasticity->intrinsic_material().name() == "steel");
//
//         REQUIRE(variables->has(variable::scalar::von_mises_stress));
//         REQUIRE(variables->has(variable::scalar::effective_plastic_strain));
//         REQUIRE(variables->has(variable::second::hencky_strain_elastic));
//         REQUIRE(variables->has(variable::fourth::tangent_operator));
//     }
//     SECTION("Initial material tangent symmetry")
//     {
//         for (auto const& material_tangent : material_tangents)
//         {
//             REQUIRE((material_tangent - material_tangent.transpose()).norm()
//                     == Approx(0.0).margin(ZERO_MARGIN));
//         }
//     }
//     SECTION("No load")
//     {
//         small_strain_J2_plasticity->update_internal_variables(1.0);
//
//         for (auto const& material_tangent : material_tangents)
//         {
//             REQUIRE((material_tangent - material_tangent.transpose()).norm()
//                     == Approx(0.0).margin(ZERO_MARGIN));
//         }
//         for (auto& cauchy_stress : cauchy_stresses)
//         {
//             REQUIRE(cauchy_stress.norm() == Approx(0.0).margin(ZERO_MARGIN));
//         }
//     }
//     // SECTION("Uniaxial elastic load")
//     // {
//     //     for (auto& F : deformation_gradients) F(2, 2) = 1.001;
//     //
//     //     small_strain_J2_plasticity->update_internal_variables(1.0);
//     //
//     //     for (auto const& material_tangent : material_tangents)
//     //     {
//     //         REQUIRE((material_tangent - material_tangent.transpose()).norm() ==
//     //         Approx(0.0).margin(ZERO_MARGIN));
//     //     }
//     //     for (auto& cauchy_stress : cauchy_stresses)
//     //     {
//     //         REQUIRE((cauchy_stress - cauchy_stress.transpose()).norm() ==
//     Approx(0.0).margin(ZERO_MARGIN));
//     //
//     //         // Shear components should be close to zero
//     //         REQUIRE(cauchy_stress(0, 1) == Approx(0.0).margin(ZERO_MARGIN));
//     //         REQUIRE(cauchy_stress(0, 2) == Approx(0.0).margin(ZERO_MARGIN));
//     //         REQUIRE(cauchy_stress(1, 2) == Approx(0.0).margin(ZERO_MARGIN));
//     //         REQUIRE(cauchy_stress(0, 0) > 0.0);
//     //         REQUIRE(cauchy_stress(1, 1) > 0.0);
//     //         REQUIRE(cauchy_stress(2, 2) > 0.0);
//     //     }
//     //     for (auto& von_mises_stress :
//     variables->get(variable::scalar::von_mises_stress))
//     //     {
//     //         REQUIRE(von_mises_stress < 200.0e6);
//     //     }
//     // }
//     // SECTION("Plastic uniaxial elastic load")
//     // {
//     //     for (auto& F : deformation_gradients) F(2, 2) = 0.003;
//     //
//     //     small_strain_J2_plasticity->update_internal_variables(1.0);
//     //
//     //     auto[von_mises_stresses, accumulated_plastic_strains] =
//     //     variables->get(variable::scalar::von_mises_stress,
//     // variable::scalar::effective_plastic_strain);
//     //
//     //     // Ensure symmetry is correct
//     //     for (auto const& material_tangent : material_tangents)
//     //     {
//     //         REQUIRE((material_tangent - material_tangent.transpose()).norm() ==
//     //         Approx(0.0).margin(ZERO_MARGIN));
//     //     }
//     //     for (auto& cauchy_stress : cauchy_stresses)
//     //     {
//     //         REQUIRE(cauchy_stress.norm() != Approx(0.0).margin(ZERO_MARGIN));
//     //
//     //         // Shear components should be close to zero
//     //         REQUIRE(cauchy_stress(0, 1) == Approx(0.0).margin(ZERO_MARGIN));
//     //         REQUIRE(cauchy_stress(0, 2) == Approx(0.0).margin(ZERO_MARGIN));
//     //         REQUIRE(cauchy_stress(1, 2) == Approx(0.0).margin(ZERO_MARGIN));
//     //         REQUIRE(cauchy_stress(0, 0) > 0.0);
//     //         REQUIRE(cauchy_stress(1, 1) > 0.0);
//     //         REQUIRE(cauchy_stress(2, 2) > 0.0);
//     //     }
//     //     for (auto& accumulated_plastic_strain : accumulated_plastic_strains)
//     //     {
//     //         REQUIRE(accumulated_plastic_strain > 0.0);
//     //     }
//     //     for (auto& von_mises_stress : von_mises_stresses)
//     //     {
//     //         // Should experience hardening
//     //         REQUIRE(von_mises_stress <= 201.0e6);
//     //         REQUIRE(von_mises_stress > 200.0e6);
//     //     }
//     // }
// }

max_stars_repo_name: dbeurle/neon

max_issues_repo_name: dbeurle/neon

max_forks_repo_name: dbeurle/neon


text:
//
// Copyright Jason Rice 2016
// 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 NBDL_FWD_MESSAGE_HPP
#define NBDL_FWD_MESSAGE_HPP

#include <boost/hana/integral_constant.hpp>
#include <type_traits>
#include <utility>

namespace nbdl::message
{
  struct upstream_create_tag { };
  struct upstream_read_tag { };
  struct upstream_update_tag { };
  struct upstream_delete_tag { };

  struct downstream_create_tag { };
  struct downstream_read_tag { };
  struct downstream_update_tag { };
  struct downstream_delete_tag { };

  template <typename...>
  struct upstream_create;

  template <typename...>
  struct upstream_read;

  template <typename...>
  struct upstream_update;

  template <typename...>
  struct upstream_delete;

  template <typename...>
  struct downstream_create;

  template <typename...>
  struct downstream_read;

  template <typename...>
  struct downstream_update;

  template <typename...>
  struct downstream_delete;

  // create_path

  struct create_path_tag { };

  template <typename Key, typename ParentPath>
  struct create_path
  {
    using key = Key;
    using hana_tag = create_path_tag;

    ParentPath parent_path;
  };

  template <typename Key>
  struct make_create_path_fn
  {
    template <typename ParentPath>
    constexpr auto operator()(ParentPath&&) const
      -> create_path<Key, std::decay_t<ParentPath>>;
  };

  template <typename Key>
  constexpr make_create_path_fn<Key> make_create_path{};

  /*
   * The action and channel tags serve to
   * indicate how the message should be
   * dispatched.
   */

  namespace action
  {
    struct create { };
    struct read { };
    struct update { };
    struct delete_ { };
  }

  namespace channel
  {
    struct upstream { };
    struct downstream { };
  }

  // channel/action traits
  template <typename Message> constexpr bool is_upstream_impl         = false;
  template <typename Message> constexpr bool is_downstream_impl       = false;
  template <typename Message> constexpr bool is_create_impl           = false;
  template <typename Message> constexpr bool is_read_impl             = false;
  template <typename Message> constexpr bool is_update_impl           = false;
  template <typename Message> constexpr bool is_delete_impl           = false;

  template <typename Message> constexpr bool is_upstream    = is_upstream_impl<std::decay_t<Message>>;
  template <typename Message> constexpr bool is_downstream  = is_downstream_impl<std::decay_t<Message>>;
  template <typename Message> constexpr bool is_create      = is_create_impl<std::decay_t<Message>>;
  template <typename Message> constexpr bool is_read        = is_read_impl<std::decay_t<Message>>;
  template <typename Message> constexpr bool is_update      = is_update_impl<std::decay_t<Message>>;
  template <typename Message> constexpr bool is_delete      = is_delete_impl<std::decay_t<Message>>;

  struct no_impl { };

  // impls - See corresponding *_fn for info
  template <typename Message, typename = void> constexpr auto get_channel_impl            = no_impl{};
  template <typename Message, typename = void> constexpr auto get_action_impl             = no_impl{};
  template <typename Message, typename = void> constexpr auto get_path_impl               = no_impl{};
  template <typename Message, typename = void> constexpr auto get_uid_impl                = no_impl{};
  template <typename Message, typename = void> constexpr auto is_confirmed_impl           = no_impl{};
  template <typename Message, typename = void> constexpr auto get_payload_impl            = no_impl{};
  template <typename Message, typename = void> constexpr auto get_private_payload_impl    = no_impl{};
  template <typename Message, typename = void> constexpr auto to_downstream_impl          = no_impl{};
  template <typename Message, typename = void> constexpr auto to_downstream_with_key_impl = no_impl{};
  template <typename Message, typename = void> constexpr auto to_downstream_read_impl     = no_impl{};
  template <typename Message, typename = void>
  constexpr auto get_normalized_path_impl = get_path_impl<Message>;
  template <typename Message, typename = void>
  constexpr bool requires_key_for_downstream_impl = false;

  // traits

  template <typename Message>
  constexpr bool has_uid = !std::is_same<const no_impl,
    decltype(get_uid_impl<std::decay_t<Message>>)>::value;

  template <typename Message>
  constexpr bool has_is_confirmed = !std::is_same<const no_impl,
    decltype(is_confirmed_impl<std::decay_t<Message>>)>::value;

  template <typename Message>
  constexpr bool has_payload = !std::is_same<const no_impl,
    decltype(get_payload_impl<std::decay_t<Message>>)>::value;

  template <typename Message>
  constexpr bool has_private_payload = !std::is_same<const no_impl,
    decltype(get_uid_impl<std::decay_t<Message>>)>::value;

  template <typename Message>
  constexpr bool is_path_normalizable = !std::is_same<const no_impl,
    decltype(get_normalized_path_impl<std::decay_t<Message>>)>::value;

  template <typename Message>
  constexpr bool requires_key_for_downstream = requires_key_for_downstream_impl<std::decay_t<Message>>;

  struct get_channel_fn
  {
    template <typename Message>
    constexpr auto operator()(Message&&) const;
  };

  struct get_action_fn
  {
    template <typename Message>
    constexpr auto operator()(Message&&) const;
  };

  struct get_path_fn
  {
    template <typename Message>
    constexpr auto operator()(Message&&) const;
  };

  struct get_uid_fn
  {
    template <typename Message>
    constexpr auto operator()(Message&& m) const
      -> decltype(get_uid_impl<std::decay_t<Message>>(std::forward<Message>(m)));
  };

  struct is_confirmed_fn
  {
    template <typename Message>
    constexpr auto operator()(Message&& m) const
      -> decltype(is_confirmed_impl<std::decay_t<Message>>(std::forward<Message>(m)));

    template <typename Message>
    constexpr auto operator()(Message const& m) const
      -> std::enable_if_t<!has_is_confirmed<Message>, boost::hana::false_>;
  };

  struct get_payload_fn
  {
    template <typename Message>
    constexpr auto operator()(Message&&) const;
  };

  struct get_private_payload_fn
  {
    template <typename Message>
    constexpr auto operator()(Message&& m) const
      -> decltype(get_private_payload_impl<std::decay_t<Message>>(std::forward<Message>(m)));
  };

  struct get_normalized_path_fn
  {
    template <typename Message>
    constexpr auto operator()(Message&& m) const
      -> decltype(get_normalized_path_impl<std::decay_t<Message>>(std::forward<Message>(m)));
  };

  struct to_downstream_fn
  {
    template <typename Message, typename IsConfirmed>
    constexpr auto operator()(Message&&, IsConfirmed is_confirmed) const;
  };

  struct to_downstream_with_key_fn
  {
    template <typename Message, typename Key>
    constexpr auto operator()(Message&&, Key&&) const;
  };

  struct to_downstream_with_key_confirmed_fn
  {
    template <typename Message, typename Key>
    constexpr auto operator()(Message&&, Key&&) const;
  };

  struct to_downstream_read_fn
  {
    template <typename Message, typename Payload>
    constexpr auto operator()(Message&&, Payload&&) const;
  };

  constexpr get_channel_fn                       get_channel{};
  constexpr get_action_fn                        get_action{};
  constexpr get_path_fn                          get_path{};
  constexpr get_uid_fn                           get_uid{};
  constexpr is_confirmed_fn                      is_confirmed{};
  constexpr get_payload_fn                       get_payload{};
  constexpr get_private_payload_fn               get_private_payload{};
  constexpr get_normalized_path_fn               get_normalized_path{};
  constexpr to_downstream_fn                     to_downstream{};
  constexpr to_downstream_with_key_fn            to_downstream_with_key{};
  constexpr to_downstream_with_key_confirmed_fn  to_downstream_with_key_confirmed{};
  constexpr to_downstream_read_fn                to_downstream_read{};

  constexpr auto to_downstream_confirmed = [](auto&& m)
  {
    return to_downstream(std::forward<decltype(m)>(m), true);
  };

  // no_uid - readable param for no_impl

  constexpr no_impl no_uid{};

  // no_is_confirmed - readable param for no_impl

  constexpr no_impl no_is_confirmed{};

  // no_is_private_payload - readable param for no_impl

  constexpr no_impl no_private_payload{};

  // make functions

  struct make_upstream_create_fn
  {
    template <typename Path, typename Uid, typename Payload, typename PrivatePayload>
    auto operator()(Path&&, Uid&&, Payload&&, PrivatePayload&&) const;

    template <typename Path, typename Uid, typename Payload>
    auto operator()(Path&&, Uid&&, Payload&&) const;
  };

  struct make_upstream_read_fn
  {
    template <typename Path, typename Uid>
    auto operator()(Path&&, Uid&&) const;

    template <typename Path>
    auto operator()(Path&& path) const;
  };

  struct make_upstream_update_fn
  {
    template <typename Path, typename Uid, typename Payload>
    auto operator()(Path&&, Uid&&, Payload&&) const;
  };

  struct make_upstream_delete_fn
  {
    template <typename Path, typename Uid>
    auto operator()(Path&&, Uid&&) const;
  };

  struct make_downstream_create_fn
  {
    template <typename Path, typename Uid, typename Payload, typename IsConfirmed>
    auto operator()(Path&&, Uid&&, Payload&&, IsConfirmed) const;
  };

  struct make_downstream_read_fn
  {
    template <typename Path, typename Uid, typename Payload>
    auto operator()(Path&&, Uid&&, Payload&&) const;
  };

  struct make_downstream_update_fn
  {
    template <typename Path, typename Uid, typename Payload, typename IsConfirmed>
    auto operator()(Path&&, Uid&&, Payload&&, IsConfirmed) const;
  };

  struct make_downstream_delete_fn
  {
    template <typename Path, typename Uid, typename IsConfirmed>
    auto operator()(Path&&, Uid&&, IsConfirmed) const;
  };

  constexpr make_upstream_create_fn make_upstream_create{};
  constexpr make_upstream_read_fn   make_upstream_read{};
  constexpr make_upstream_update_fn make_upstream_update{};
  constexpr make_upstream_delete_fn make_upstream_delete{};
  constexpr make_downstream_create_fn make_downstream_create{};
  constexpr make_downstream_read_fn   make_downstream_read{};
  constexpr make_downstream_update_fn make_downstream_update{};
  constexpr make_downstream_delete_fn make_downstream_delete{};

  // get_path_type

  struct get_path_type_fn
  {
    template <typename Message>
    constexpr auto operator()(Message const& m) const;
  };

  constexpr get_path_type_fn get_path_type{};
}

#endif

ext: hpp

max_stars_repo_name: ricejasonf/nbdl

max_issues_repo_name: ricejasonf/nbdl

max_forks_repo_name: ricejasonf/nbdl


text:
/*
Copyright (c) 2016, Blue Brain Project
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
3. Neither the name of the copyright holder 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 HOLDER 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.
*/

#define BOOST_TEST_MODULE cmdline_interface
#define BOOST_TEST_MAIN

#include <boost/test/unit_test.hpp>
#include "nrniv/cellorder.h"
using namespace coreneuron;
BOOST_AUTO_TEST_CASE(interleave_info_test) {
    size_t nwarp = 4;
    size_t nstride = 6;

    InterleaveInfo info1;

    int data1[] = {11, 37, 45, 2, 18, 37, 7, 39, 66, 33};
    size_t data2[] = {111, 137, 245, 12, 118, 237, 199, 278, 458};

    info1.nwarp = nwarp;
    info1.nstride = nstride;

    // to avoid same values, different sub-array is used to initialize different members
    copy_array(info1.stridedispl, data1, nwarp + 1);
    copy_array(info1.stride, data1 + 1, nstride);
    copy_array(info1.firstnode, data1 + 1, nwarp + 1);
    copy_array(info1.lastnode, data1 + 1, nwarp + 1);

    // check if copy_array works
    BOOST_CHECK_NE(info1.firstnode, info1.lastnode);
    BOOST_CHECK_EQUAL_COLLECTIONS(info1.firstnode, info1.firstnode + nwarp + 1, info1.lastnode,
                                  info1.lastnode + nwarp + 1);

    copy_array(info1.cellsize, data1 + 4, nwarp);
    copy_array(info1.nnode, data2, nwarp);
    copy_array(info1.ncycle, data2 + 1, nwarp);
    copy_array(info1.idle, data2 + 2, nwarp);
    copy_array(info1.cache_access, data2 + 3, nwarp);
    copy_array(info1.child_race, data2 + 4, nwarp);

    // copy constructor
    InterleaveInfo info2(info1);

    // assignment operator
    InterleaveInfo info3;
    info3 = info1;

    std::vector<InterleaveInfo*> infos;

    infos.push_back(&info2);
    infos.push_back(&info3);

    // test few members
    for (size_t i = 0; i < infos.size(); i++) {
        BOOST_CHECK_EQUAL(info1.nwarp, infos[i]->nwarp);
        BOOST_CHECK_EQUAL(info1.nstride, infos[i]->nstride);

        BOOST_CHECK_EQUAL_COLLECTIONS(info1.stridedispl, info1.stridedispl + nwarp + 1,
                                      infos[i]->stridedispl, infos[i]->stridedispl + nwarp + 1);

        BOOST_CHECK_EQUAL_COLLECTIONS(info1.stride, info1.stride + nstride, infos[i]->stride,
                                      infos[i]->stride + nstride);

        BOOST_CHECK_EQUAL_COLLECTIONS(info1.cellsize, info1.cellsize + nwarp, infos[i]->cellsize,
                                      infos[i]->cellsize + nwarp);

        BOOST_CHECK_EQUAL_COLLECTIONS(info1.child_race, info1.child_race + nwarp,
                                      infos[i]->child_race, infos[i]->child_race + nwarp);
    }
}

ext: cpp

max_stars_repo_name: tapaswenipathak/CoreNeuron

max_issues_repo_name: tapaswenipathak/CoreNeuron

max_forks_repo_name: tapaswenipathak/CoreNeuron


text:
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <queue>
#include <unordered_map>
#include <set>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <utility>
#include <cstdio>
#include <boost/program_options.hpp>
#include <boost/system/error_code.hpp>
#include <boost/filesystem.hpp>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dbus-c++/dbus.h>
#include "file_functions.h"

#include "FclipClient.h"

using namespace std;
namespace po = boost::program_options;
namespace fs = boost::filesystem;

// global options:
bool oVerbose;
// semi-global options:
bool oAbsPaths;
bool oFiles;
bool oDirs;
bool oLinks;
bool oRecursive;
// "for-each" options:
bool oForEachRemove;
bool oForEachPrint;
// "list" options:
bool oAll;

typedef bool (*action_f)(const vector<string> &, FclipClient &);
typedef po::options_description (*options_f)();

struct Command {
  action_f action;
  options_f options;
  string usage;
  Command(action_f action_, options_f options_, string usage_) :
    action(action_), options(options_), usage(usage_) {}
};

unordered_map<string,Command> commands;

DBus::BusDispatcher dispatcher;

vector<string> serverMessages;

ostream &msg(){
  return cout << "fclip: ";
}

ostream &err(){
  return cerr << "fclip: ";
}

string expandCommand(string cmd){
  if(cmd == "rm") return "remove";
  if(cmd == "ls") return "list";
  if(cmd == "each" || cmd == "foreach") return "for-each";
  return cmd;
}

po::options_description general_options(){
  po::options_description options("Options");
  options.add_options()
          ("help,h", "display help and exit")
          ("verbose,v", po::bool_switch(&oVerbose), "explain what is being done");
  return options;
}

po::options_description help_options(){
  return po::options_description();
}

po::options_description add_options(){
  po::options_description options("Options");
  options.add_options()
          ("recursive,r", po::bool_switch(&oRecursive), "mark files as 'recursive'");
  return move(options);
}

po::options_description remove_options(){
  po::options_description options("Options");
  options.add_options()
          ("recursive,r", po::bool_switch(&oRecursive), "remove directory contents recursively");
  return move(options);
}

po::options_description list_options(){
  po::options_description options("Options");
  options.add_options()
          ("all,a", po::bool_switch(&oAll), "show hidden files");
  return move(options);
}

po::options_description forEach_options(){
  po::options_description options("Options");
  options.add_options()
          ("absolute,a", po::bool_switch(&oAbsPaths), "force absolute paths")
          ("exec,c", po::value<vector<string> >(), "execute the given command for each file")
          ("print,p", po::bool_switch(&oForEachPrint), "write all paths to output")
          ("files,F", po::bool_switch(&oFiles), "only process regular files")
          ("dirs,D", po::bool_switch(&oDirs), "only process directories")
          ("links,L", po::bool_switch(&oLinks), "only process symlinks");
  return move(options);
}

po::options_description clear_options(){
  return po::options_description();
}

po::options_description stash_options(){
  return po::options_description();
}

po::options_description status_options(){
  return po::options_description();
}

void help_run(const vector<string> &argv){
  po::options_description options = help_options();
  options.add_options()
          ("command", po::value<string>());
  po::positional_options_description positional;
  positional.add("command", 1);
  po::variables_map vm;
  po::store(po::command_line_parser(argv)
          .options(options).positional(positional).allow_unregistered().run(), vm);
  po::notify(vm);

  if(vm.count("command")){
    const string &cmd = expandCommand(vm["command"].as<string>());
    auto it = commands.find(cmd);
    if(it != commands.end()){
      cout << (*it).second.usage << endl << endl;
      cout << (*it).second.options() << endl;
      return;
    }
  }

  cout << "usage: fclip [<options>] <command> [<command-options>]" << endl << endl;
  cout << "Commands:" << endl;
  cout << left;
  cout << setw(24) << "  add " << "add files to clipboard" << endl;
  cout << setw(24) << "  clear " << "clear clipboard" << endl;
  cout << setw(24) << "  foreach, each " << "perform actions for each file in clipboard" << endl;
  cout << setw(24) << "  list, ls " << "show info about files in the current directory" << endl;
  cout << setw(24) << "  help " << "get help about a command" << endl;
  cout << setw(24) << "  remove, rm " << "remove files from clipboard" << endl;
  cout << setw(24) << "  stash " << "temporarily save and restore clipboard contents" << endl;
  cout << setw(24) << "  status " << "show info about clipboard" << endl;
  cout << endl;
  cout << general_options() << endl;
  return;
}

bool add_run(const vector<string> &argv, FclipClient &fclip){
  po::options_description options = add_options();
  options.add_options()
          ("file", po::value<vector<string> >());
  po::positional_options_description positional;
  positional.add("file", -1);
  po::variables_map vm;
  po::store(po::command_line_parser(argv)
          .options(options).positional(positional).run(), vm);
  po::notify(vm);

  vector<string> files;
  if(vm.count("file")){
    files = vm["file"].as<vector<string> >();
  }else{
    string line;
    while(getline(cin, line)){
      if(line != "")
        files.push_back(line);
    }
  }

  // make file paths canonical
  for(auto it = files.begin(); it != files.end(); ++it){
    boost::system::error_code ec;
    string path = file_functions::getCanonicalPathToSymlink(*it, ec).string();
    if(ec.value() != boost::system::errc::success){
      err() << "cannot access " << *it << ": " << ec.message() << endl;
      it = files.erase(it);
      if(it == files.end()) break;
    }else{
      *it = move(path);
      if(oVerbose)
        cout << *it << endl;
    }
  }

  bool success;
  fclip.Add(files, oRecursive, serverMessages, success);
  return success;
}

bool remove_run(const vector<string> &argv, FclipClient &fclip){
  po::options_description options = remove_options();
  options.add_options()
          ("file", po::value<vector<string> >());
  po::positional_options_description positional;
  positional.add("file", -1);
  po::variables_map vm;
  po::store(po::command_line_parser(argv)
          .options(options).positional(positional).run(), vm);
  po::notify(vm);

  vector<string> files;
  if(vm.count("file")){
    files = vm["file"].as<vector<string> >();
  }else{
    string line;
    while(getline(cin, line)){
      if(line != "")
        files.push_back(line);
    }
  }

  // make file paths canonical
  for(auto it = files.begin(); it != files.end(); ++it){
    boost::system::error_code ec;
    string path = file_functions::getCanonicalPathToSymlink(*it, ec).string();
    if(ec.value() != boost::system::errc::success){
      // silently pass non-canonical path; will be handled on server
      path = fs::absolute(*it, fs::current_path()).string();
    }

    *it = move(path);
    if(oVerbose)
      cout << *it << endl;
  }

  bool success;
  fclip.Remove(files, oRecursive, serverMessages, success);
  return success;
}

bool list_run(const vector<string> &argv, FclipClient &fclip){
  po::options_description options = list_options();
  options.add_options()
          ("path", po::value<string>());
  po::positional_options_description positional;
  positional.add("path", 1);
  po::variables_map vm;
  po::store(po::command_line_parser(argv)
          .options(options).positional(positional).run(), vm);
  po::notify(vm);

  string strPath = ".";
  if(vm.count("path")){
    strPath = vm["path"].as<string>();
  }

  fs::path path;
  {
    boost::system::error_code ec;
    path = file_functions::getCanonicalPathToSymlink(strPath, ec);
    if(ec.value() != boost::system::errc::success){
      throw runtime_error("cannot access " + strPath + ": " + ec.message());
    }
    strPath = path.string();
  }

  bool success, dirRecursive;
  vector<::DBus::Struct<string,bool,bool>> files;
  fclip.DirectoryListing(strPath, files, dirRecursive, serverMessages, success);
  if(success){
    unordered_map<string,::DBus::Struct<string,bool,bool> > cbFileMap;
    set<string> fileSet; // for sorting by filename
    for(auto const &f : files){
      cbFileMap.emplace(f._1, f);
      fileSet.insert(f._1);
    }

    try{
      for(fs::directory_iterator dirIt(path), dirEnd; dirIt != dirEnd; ++dirIt){
        string name = dirIt->path().filename().string();
        if(name[0] != '.' || oAll){
          fileSet.insert(name);
        }
      }
    }catch(const fs::filesystem_error& ex){
      throw runtime_error("cannot list " + strPath + ": " + ex.code().message());
    }

    for(auto const &f : fileSet){
      if(dirRecursive){
        cout << "[^] ";
      }else{
        auto it = cbFileMap.find(f);
        if(it != cbFileMap.end()){
          const string &name = it->second._1;
          const bool &inClipboard = it->second._2;
          const bool &recursive = it->second._3;

          if(!inClipboard)
            cout << "[>] ";
          else if(recursive)
            cout << "[*] ";
          else
            cout << "[+] ";
        }else{
          cout << "[ ] ";
        }
      }
      cout << f << endl;
    }
    return true;
  }else return false;
}

typedef pair<string,bool> file;

void forEachDoActions(const fs::path &path, fs::file_status fstatus,
        const string &baseDir, const vector<string> &commands){
  if(oFiles || oDirs || oLinks){ // type specified
    if(!oFiles && fs::is_regular_file(fstatus)) return;
    if(!oDirs  && fs::is_directory(fstatus)) return;
    if(!oLinks && fs::is_symlink(fstatus)) return;
  }

  if(oForEachPrint)
    cout << path.string() << endl;

  for(string cmd : commands){
    // replace {} with path
    {
      string braces("{}");
      size_t pos = 0;
      while((pos = cmd.find(braces, pos)) != string::npos){
        cmd.replace(pos, braces.length(), path.string());
      }
    }

    if(oVerbose)
      cout << cmd << endl;

    // execute command
    FILE *output = popen(cmd.c_str(), "r");
    if(output){
      char buf[512]; size_t count;
      while(count = fread(buf, 1, sizeof(buf), output)){
        cout.write(buf, count);
      }
      pclose(output);
    }else{
      err() << "error executing " << cmd << endl;
    }
  }
}

void forEachWorker(const string &baseDir, const vector<string> &commands,
        queue<file> &qu, mutex &qLock, const bool &done, condition_variable &cv){
  int workDirFd;
  if(baseDir != ""){
    if(oVerbose)
      cout << "cd " << baseDir << endl;
    workDirFd = open(".", O_RDONLY);
    if(chdir(baseDir.c_str()) != 0){
      err() << "cannot chdir to " << baseDir << endl;
      return;
    }
  }

  while(true){
    // get the next file from the queue
    fs::path path;
    bool recursive;
    {
      unique_lock<mutex> lk(qLock);
      if(qu.empty()){
        if(done) break;
        cv.wait(lk);
        continue;
      }

      path = qu.front().first;
      recursive = qu.front().second;
      qu.pop();
    }

    // now do the actual work

    // get file type
    boost::system::error_code ec;
    fs::file_status fstatus = fs::symlink_status(baseDir / path, ec);
    if(ec.value() != boost::system::errc::success){
      err() << "cannot access " << path.string() << ": " << ec.message() << endl;
      continue;
    }

    forEachDoActions(oAbsPaths ? baseDir / path : path, fstatus, baseDir, commands);

    // iterate over directory contents recursively
    if(recursive && fs::is_directory(fstatus)){
      try{
        fs::recursive_directory_iterator it(baseDir / path);
        fs::recursive_directory_iterator end;

        while(it != end){
          fs::path p = (*it).path();
          if(!oAbsPaths){
            p = file_functions::removePathPrefix(p, baseDir);
          }

          fstatus = fs::symlink_status(baseDir / p, ec);
          if(ec.value() == boost::system::errc::success){
            forEachDoActions(p, fstatus, baseDir, commands);
          }else{
            err() << "cannot access " << p.string() << ": " << ec.message() << endl;
          }

          // don't follow symlinks
          if(fs::is_directory(*it) && fs::is_symlink(*it))
            it.no_push();

          try{ ++it; }
          catch(exception& ex){
            err() << "cannot access contents of " << (*it).path().string() << endl;
            it.no_push();
            try{ ++it; }
            catch(exception& ex2){
              err() << ex2.what() << endl;
              it.pop();
            }
          }
        }
      }catch(exception& ex){
        err() << "cannot access contents of " << baseDir / path << endl;
      }
    }
  }

  if(baseDir != ""){
    fchdir(workDirFd);
  }
}

bool forEach_run(const vector<string> &argv, FclipClient &fclip){
  fclip.Introspect(); // will throw exception if server not available

  po::options_description options = forEach_options();
  options.add_options()
          ("base-dir", po::value<string>());
  po::positional_options_description positional;
  positional.add("base-dir", 1);

  po::variables_map vm;
  po::store(po::command_line_parser(argv)
          .options(options).positional(positional) .run(), vm);
  po::notify(vm);

  vector<string> commands;
  if(vm.count("exec"))
    commands = vm["exec"].as<vector<string> >();

  string baseDir = "";
  if(vm.count("base-dir")){
    boost::system::error_code ec;
    baseDir = vm["base-dir"].as<string>();
    string baseDir_ = fs::canonical(baseDir, ec).string();
    if(ec.value() != boost::system::errc::success){
      throw runtime_error("Cannot access " + baseDir + ": " + ec.message());
    }
    baseDir = baseDir_;
  }

  string pipePath;
  {
    fs::path pipePath_ = fs::temp_directory_path() / fs::unique_path();
    pipePath = pipePath_.string();
  }

  if(mkfifo(pipePath.c_str(), S_IFIFO | 0666) != 0)
    throw runtime_error("cannot create named pipe");

  fclip.ListFilesToStream(baseDir, false, pipePath);

  queue<file> qu;
  mutex qLock;
  bool done = false;
  condition_variable cv;
  thread worker(forEachWorker, ref(baseDir), ref(commands), ref(qu), ref(qLock), ref(done), ref(cv));

  try{
    ifstream pipe(pipePath, ios_base::in);

    // read paths from pipe
    string line;
    while (std::getline(pipe, line, '\0')){
      std::istringstream iss(line);
      bool recursive; size_t length;
      if(!(iss >> recursive >> length))
        throw runtime_error("invalid data received from server");

      char *c_str = new char[length];
      pipe.read(c_str, length);
      pipe.get(); // read the newline character
      string str(c_str, length);

      if(str.length() != length)
        throw runtime_error("invalid data received from server");

      {
        // push path to queue and wake up worker
        unique_lock<mutex> lk(qLock);
        qu.emplace(str, recursive);
        cv.notify_all();
      }
    }
    fs::remove(pipePath);
  }catch(...){
    fs::remove(pipePath);
    {
      // notify worker that no more paths will be added to the queue
      unique_lock<mutex> lk(qLock);
      done = true;
      cv.notify_all();
    }
    throw;
  }

  {
    // notify worker that no more paths will be added to the queue
    unique_lock<mutex> lk(qLock);
    done = true;
    cv.notify_all();
  }
  worker.join();

  return true;
}

bool clear_run(const vector<string> &argv, FclipClient &fclip){
  po::options_description options = forEach_options();
  po::variables_map vm;
  po::store(po::command_line_parser(argv).options(options).run(), vm);
  po::notify(vm);

  fclip.Clear();
  return true;
}

bool stash_run(const vector<string> &argv, FclipClient &fclip){
  size_t id = 0;

  po::options_description options = stash_options();
  options.add_options()
          ("action", po::value<string>())
          ("id", po::value<size_t>(&id));
  po::positional_options_description positional;
  positional.add("action", 1);
  positional.add("id", 1);

  po::variables_map vm;
  po::store(po::command_line_parser(argv)
          .options(options).positional(positional) .run(), vm);
  po::notify(vm);

  string action("push");
  if(vm.count("action"))
    action = expandCommand(vm["action"].as<string>());

  bool success = true;
  if(action == "push"){
    if(vm.count("id"))
      throw runtime_error("stash push doesn't accept parameters");

    fclip.Stash(serverMessages, success);
    if(success){
      vector<string> list = fclip.ListStash();
      if(list.size()>0)
        msg() << "stashed " << list[0] << " as #0" << endl;
    }
  }else if(action == "pop"){
    vector<string> list = fclip.ListStash();
    fclip.Unstash(id, serverMessages, success);
    if(success && list.size()>0)
      msg() << "unstashed " << list[0] << " (#" << id << ")" << endl;
  }else if(action == "drop"){
    vector<string> list = fclip.ListStash();
    fclip.DropStash(id, serverMessages, success);
    if(success && list.size()>0)
      msg() << "dropped " << list[0] << " (#" << id << ")" << endl;
  }else if(action == "list"){
    vector<string> list = fclip.ListStash();
    for(size_t i=0; i<list.size(); ++i){
      cout << "  #" << i << ": " << list[i] << endl;
    }
  }else if(action == "clear"){
    fclip.ClearStash();
  }else throw runtime_error("unrecognised command: stash " + action);
}

bool status_run(const vector<string> &argv, FclipClient &fclip){
  po::options_description options = status_options();
  po::variables_map vm;
  po::store(po::command_line_parser(argv).options(options).run(), vm);
  po::notify(vm);

  string lca = fclip.LowestCommonAncestor();
  bool success;
  vector<::DBus::Struct<string,bool,bool> > files;
  bool dirRecursive;

  fclip.DirectoryListing(lca, files, dirRecursive, serverMessages, success);
  if(lca == ""){
    if(!files.empty()){
      cout << "Files in:";
      for(const auto &f : files){
        cout << " " << f._1;
      }
      cout << endl;
    }else{
      cout << "Clipboard empty" << endl;
    }
  }else{
    if(!files.empty() || dirRecursive){
      cout << "Files in " << lca << " in clipboard" << endl;
    }else{
      cout << lca << " in clipboard" << endl;
    }
  }

  size_t stashSize = fclip.ListStash().size();
  if(stashSize){
    cout << "Stash contents:" << endl;
    vector<string> list = fclip.ListStash();
    for(size_t i=0; i<list.size(); ++i){
      cout << "  #" << i << ": " << list[i] << endl;
    }
  }else{
    cout << "Stash empty" << endl;
  }

  return true;
}

int main(int argc, char** argv) {
  bool success = true;

  ostringstream oss;

  commands.emplace("help", Command(nullptr, help_options,
    "usage: fclip help [<command>]\n\n"
    "Display help information about a command."
  ));
  commands.emplace("add", Command(add_run, add_options,
    "usage: fclip add [<options>] [<files>...]\n\n"
    "Add one or more files to the clipboard. If no files are specified\n"
    "as arguments, they will be read from standard input."
  ));
  commands.emplace("clear", Command(clear_run, clear_options,
    "usage: fclip clear\n\n"
    "Remove all files from the clipboard."
  ));
  commands.emplace("for-each", Command(forEach_run, forEach_options,
    "usage: fclip for-each [<base-dir>] [<options>]\n"
    "aliases: foreach, each\n\n"
    "Perform actions for each file in the clipboard.\n"
    "If a base-dir is specified, only files in that directory\n"
    "will be processed."
  ));
  commands.emplace("list", Command(list_run, list_options,
    "usage: fclip list [<dir>]\n"
    "alias: ls\n\n"
    "Show the state of each of the files in the current directory\n"
    "or a given directory. The following file states are possible:\n"
    "  [+] in clipboard\n"
    "  [*] in clipboard and marked as 'recursive'\n"
    "  [^] in clipboard because of a 'recursive' parent directory\n"
    "  [>] not in clipboard, but contains files that are\n"
    "  [ ] not in clipboard at all"
  ));
  commands.emplace("remove", Command(remove_run, remove_options,
    "usage: fclip remove [<files>...]\n"
    "alias: rm\n\n"
    "Remove one or more files from the clipboard. If no files are specified\n"
    "as arguments, they will be read from standard input."
  ));
  oss.str("");
  oss << "usage: fclip stash [ push | pop [<id>] | drop [<id>] | list | clear ]\n\n"
      << "Manipulate the stack of saved clipboard states ('stashes'):\n"
      << left
      << setw(24) << "  stash [push]" << "stash the current clipboard on the top\n"
      << setw(24) << "  stash pop [<id>] " << "restore a stash\n"
      << setw(24) << "  stash drop [<id>]" << "remove a stash\n"
      << setw(24) << "  stash list" << "list all stashes\n"
      << setw(24) << "  stash clear" << "remove all stashes";
  commands.emplace("stash", Command(stash_run, stash_options, oss.str()));
  commands.emplace("status", Command(status_run, status_options,
    "usage: fclip status\n\n"
    "Show info about the clipboard."
  ));

  try{
    po::options_description options = general_options();
    po::variables_map vm;
    po::parsed_options parsed = po::command_line_parser(argc, argv)
            .options(options).allow_unregistered().run();
    po::store(parsed, vm);
    po::notify(vm);

    vector<string> subargs = po::collect_unrecognized(parsed.options, po::include_positional);

    if(vm.count("help") || subargs.empty()) {
      subargs.insert(subargs.begin(), "help");
      if(subargs.empty()){
        help_run(subargs);
        return EXIT_FAILURE;
      }
    }

    string cmd = expandCommand(subargs[0]);
    subargs.erase(subargs.begin());

    if(cmd == "help"){
      help_run(subargs);
      return EXIT_FAILURE;
    }

    try{
      DBus::default_dispatcher = &dispatcher;
      DBus::Connection bus = DBus::Connection::SessionBus();
      FclipClient fclip(bus);

      auto it = commands.find(cmd);
      if(it == commands.end()){
        throw runtime_error("unrecognised command or option '" + cmd + "'");
      }
      (*it).second.action(subargs, fclip);

      for(const string &str : serverMessages){
        err() << str << endl;
      }
    }catch(const DBus::Error &e){
      err() << "failed to connect to fclip server" << endl;
      return EXIT_FAILURE;
    }
  }catch(const exception &e){
    err() << e.what() << endl;
    return EXIT_FAILURE;
  }

  return success ? EXIT_SUCCESS : EXIT_FAILURE;
}

max_stars_repo_name: cifkao/fclip

max_issues_repo_name: cifkao/fclip

max_forks_repo_name: cifkao/fclip


text:
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/args.hpp>

namespace {

  /* Slightly modified code from tcsh-6.13.00/sh.glob.c
     http://www.tcsh.org/
   */

  inline
  int
  globcharcoll(int c1, int c2)
  {
      return (c1 - c2);
  }

  /* t_pmatch():
   *      Return 2 on exact match,
   *      Return 1 on substring match.
   *      Return 0 on no match.
   *      *estr will point to the end of the longest exact or substring match.
   */
  int
  t_pmatch(const char *string, const char *pattern, const char **estr,
           char escape_char='\0')
  {
      char    stringc, patternc, patternc_esc;
      int     match, negate_range;
      char    rangec;
      const char *oestr, *pestr;

      for (;; ++string) {
          stringc = *string;
          /*
           * apollo compiler bug: switch (patternc = *pattern++) dies
           */
          patternc = patternc_esc = *pattern++;
          if (   escape_char != '\0'
              && patternc == escape_char) {
            patternc = *pattern++;
          }
          switch (patternc_esc) {
          case '\0':
              *estr = string;
              return (stringc == 0 ? 2 : 1);
          case '?':
              if (stringc == 0)
                  return (0);
              *estr = string;
              break;
          case '*':
              if (!*pattern) {
                  while (*string) string++;
                  *estr = string;
                  return (2);
              }
              oestr = *estr;
              pestr = 0;

              do {
                  switch(t_pmatch(string, pattern, estr, escape_char)) {
                  case 0:
                      break;
                  case 1:
                      pestr = *estr;
                      break;
                  case 2:
                      return 2;
                  default:
                      throw std::runtime_error("Internal error: " __FILE__);
                      /* Cannot happen */
                  }
                  *estr = string;
              }
              while (*string++);

              if (pestr) {
                  *estr = pestr;
                  return 1;
              }
              else {
                  *estr = oestr;
                  return 0;
              }

          case '[':
              match = 0;
              if ((negate_range = (*pattern == '^')) != 0)
                  pattern++;
              while ((rangec = *pattern++) != '\0') {
                  if (rangec == ']')
                      break;
                  if (match)
                      continue;
                  if (rangec == '-'
                      && *(pattern-2) != '[' && *pattern  != ']') {
                      match = (globcharcoll(stringc, *pattern) <= 0 &&
                      globcharcoll(*(pattern-2), stringc) <= 0);
                      pattern++;
                  }
                  else
                      match = (stringc == rangec);
              }
              if (rangec == 0)
                  return (-1);
              if (match == negate_range)
                  return (0);
              *estr = string;
              break;
          default:
              if (patternc != stringc)
                  return (0);
              *estr = string;
              break;
          }
      }
  }

  bool
  is_match(
    std::string const& string,
    std::string const& pattern,
    char escape_char='\0')
  {
    const char* estr;
    return (t_pmatch(string.c_str(), pattern.c_str(), &estr, escape_char)
            == 2);
  }

  void init_module()
  {
    using namespace boost::python;
    def("is_match", is_match, (
      arg("string"), arg("pattern"), arg("escape_char")='\0'));
  }

} // namespace <anonymous>

BOOST_PYTHON_MODULE(iotbx_wildcard_ext)
{
  init_module();
}


text:
#include <boost/test/unit_test.hpp>
#include "functions/addition.hh"
#include "functions/variables.hh"
#include "functions/full_function_defs.hh"
#include "functions/std_functions.hh"
#include "functions/polynomial.hh"
#include "functions/operators.hh"
#include <iostream>
#include "functions/streaming.hh"

BOOST_AUTO_TEST_CASE(addition_test) {
  using namespace manifolds;
  Variable<1> b1;
  Variable<2> b2;
  Variable<4> b3;
  Variable<6> m1;
  Variable<7> m2;
  Variable<8> m3;
  auto c33 = b1 + m1 * t;
  auto c22 = b2 + m2 * t;
  auto c11 = b3 + m3 * t;
  auto part1 = 4_c * c22 * c22 * c11 * c33;
  /*CustomVariableNamer
  vnamer{ std::make_pair(1, "b1"), std::make_pair(2, "b2"),
          std::make_pair(4, "b3"), std::make_pair(6, "m1"),
          std::make_pair(7, "m2"), std::make_pair(8, "m3"), };*/
  // Stream2(std::cout, part1, vnamer) << "\n\n";
  (void)part1;
}

max_stars_repo_name: GuylainGreer/manifolds

max_issues_repo_name: GuylainGreer/manifolds

max_forks_repo_name: GuylainGreer/manifolds


text:
//
// Created by plter on 2019/9/17.
//

#include <um.h>
#include <boost/asio/use_awaitable.hpp>
#include <mysql.h>
#include <memory>

int main() {

    MYSQL *mysql;
    mysql = mysql_init(nullptr);
    mysql_real_connect(mysql, "127.0.0.1", "root", "example", "mydb", 3306, nullptr, 0);
//    mysql_real_query_start()
    mysql_close(mysql);
    return 0;
}

max_stars_repo_name: plter/UnderMountain

max_issues_repo_name: plter/UnderMountain

max_forks_repo_name: plter/UnderMountain


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

#include <boost/bimap.hpp>
#include <spdlog/spdlog.h>
#include <sysrepo-cpp/Session.hpp>
#include <pistache/endpoint.h>
#include <pistache/router.h>
#include <pistache/net.h>
#include <nlohmann/json.hpp>

#pragma once

namespace pdns_sysrepo::remote_backend
{

/**
 * @brief type to shuttle syrepo session errors around
 *
 * The pair is {xpath, error_message}
 */
typedef std::vector<std::pair<std::string, std::string>> sessionErrors;

namespace Http = Pistache::Http;
namespace Rest = Pistache::Rest;
using std::string;

class RemoteBackend
{
public:
  RemoteBackend(sysrepo::S_Connection& connection, const Pistache::Address& addr);
  ~RemoteBackend();

  /**
   * @brief Starts the Remote Backend
   *
   * Must be called for the backend to do something useful
   */
  void start();

protected:
  /**
   * @brief Implements the lookup endpoint
   *
   * https://doc.powerdns.com/authoritative/backends/remote.html#lookup
   *
   * @param request
   * @param response
   */
  void lookup(const Pistache::Rest::Request& request, Http::ResponseWriter response);

  /**
   * @brief Implements the getAllDomains endpoint
   *
   * https://doc.powerdns.com/authoritative/backends/remote.html#getalldomains
   *
   * @param request
   * @param response
   */
  void getAllDomains(const Pistache::Rest::Request& request, Http::ResponseWriter response);

  /**
   * @brief Implements the list endpoint
   *
   * https://doc.powerdns.com/authoritative/backends/remote.html#list
   *
   * @param request
   * @param response
   */
  void list(const Pistache::Rest::Request& request, Http::ResponseWriter response);

  /**
   * @brief Implements the getUpdatedMasters endpoint
   *
   * https://doc.powerdns.com/authoritative/backends/remote.html#getupdatedmasters
   *
   * @param request
   * @param response
   */
  void getUpdatedMasters(const Pistache::Rest::Request& request, Http::ResponseWriter response);

  /**
   * @brief Implements the setNotified endpoint
   *
   * https://doc.powerdns.com/authoritative/backends/remote.html#setNotified
   *
   * @param request
   * @param response
   */
  void setNotified(const Pistache::Rest::Request& request, Http::ResponseWriter response);

  /**
   * @brief Implements the getDomainMetadata endpoint
   *
   * https://doc.powerdns.com/authoritative/backends/remote.html#getDomainMetadata
   *
   * @param request
   * @param response
   */
  void getDomainMetadata(const Pistache::Rest::Request& request, Http::ResponseWriter response);

  /**
   * @brief Sends a 404 with {"result": false}
   *
   * @param request
   * @param response
   */
  void notFound(const Pistache::Rest::Request& request, Http::ResponseWriter response);

  /**
   * @brief Finds the best zone for qname
   *
   * @param qname
   * @return string
   */
  string findBestZone(const string &qname);

  /**
   * @brief Sends an error HTTP response
   *
   * @param response
   * @param error
   * @param code
   */
  void sendError(const Pistache::Rest::Request& request, Http::ResponseWriter& response, const std::string& error, const Http::Code &code = Http::Code::Internal_Server_Error);

  /**
   * @brief Send an HTTP 200 response with ret
   *
   * @param response
   * @param ret
   */
  void sendResponse(const Pistache::Rest::Request& request, Http::ResponseWriter& response, const nlohmann::json& ret);

  /**
   * @brief Returns a JSON object for DomainInfo
   *
   * e.g:
   * { "id": -1,
   *   "zone":"unit.test.",
   *   "masters": ["10.0.0.1"],
   *   "serial":2,
   *   "kind":"native"}
   *
   * All values should be provided by the caller
   *
   * @param zone
   * @param kind
   * @return nlohmann::json
   */
  nlohmann::json makeDomainInfo(const std::string &zone, const std::string &kind);

  /**
   * @brief Returns a JSON object for a record
   *
   * @param name
   * @param rtype
   * @param content
   * @param ttl
   * @return nlohmann::json
   */
  nlohmann::json makeRecord(const std::string& name, const std::string& rtype, const std::string& content, const uint16_t ttl);

  /**
   * @brief Retrieve an Array of records from an RRSet Node
   *
   * Takes a node rooted at '/pdns-server:zones/zones[name]/rrset[owner][type]' and returns a json array like:
   *
   * [
   *   {"qtype":"A", "qname":"www.example.com", "content":"203.0.113.2", "ttl": 60},
   *   {"qtype":"A", "qname":"www.example.com", "content":"192.0.2.2", "ttl": 60}
   * ]
   *
   * @param node
   * @return nlohmann::json::array_t
   */
  nlohmann::json::array_t getRecordsFromRRSetNode(const libyang::S_Data_Node &node);

  /**
   * @brief Get a new Sysrepo session
   *
   * @return sysrepo::S_Session
   */
  sysrepo::S_Session getSession() {
    sysrepo::S_Session ret(new sysrepo::Session(d_connection, SR_DS_RUNNING));
    return ret;
  }

  /**
   * @brief Returns the datatree rooted at `/pdns-server:zones/zones` or an error
   *
   * @param sysrepo::S_Session  optional sysrepo session to use
   * @return libyang::S_Data_Node
   * @throw sysrepo::sysrepo_exception when a sysrepo error occurs
   */
  libyang::S_Data_Node getZoneTree(sysrepo::S_Session session = nullptr);

  /**
   * @brief Get the Errors from the sysrepo session
   *
   * @param session
   * @return sessionErrors
   * @throw logic_error when session is a nullptr
   * @throw sysrepo_exception when the errors can't be retrieved
   */
  sessionErrors getErrorsFromSession(const sysrepo::S_Session& session);

  /**
   * @brief Decodes a url-encoded string
   *
   * @param eString
   * @return std::string
   */
  std::string urlDecode(std::string &eString);

  /**
   * @brief DomainIDs assigned to zones
   *
   * These are only valid during the runtime of this program
   *
   */
  boost::bimap<std::string, uint32_t> d_domainIds;

  /**
   * @brief Get the ID for a domain
   *
   * @param domain
   * @return uint32_t
   */
  uint32_t getDomainID(const std::string& domain);

  /**
   * @brief Get the domain belong to an id
   *
   * @param id
   * @return std::string
   * @throw std::out_of_range when the id is not found
   */
  std::string getDomainFromId(const uint32_t id);

  /**
   * @brief Contains the serial notified for domains
   *
   * The map is keyed with the domain_id
   */
  std::map<uint32_t, uint32_t> d_notifiedMasters;

  void logRequest(const Pistache::Rest::Request &request);
  void logRequestResponse(const Pistache::Rest::Request &request, const Pistache::Http::Response &response, const nlohmann::json& ret);

  sysrepo::S_Connection d_connection;
  std::shared_ptr<Http::Endpoint> d_endpoint;
  Rest::Router d_router;
  const Http::Mime::MediaType s_application_json_mediatype{Http::Mime::MediaType::fromString("application/json")};
};
} // namespace pdns_sysrepo::remote_backend

ext: hh

max_stars_repo_name: Habbie/pdns-sysrepo

max_issues_repo_name: Habbie/pdns-sysrepo

max_forks_repo_name: Habbie/pdns-sysrepo


text:
/*
 * This file is part of the DUDS project. It is subject to the BSD-style
 * license terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://www.somewhere.org/somepath/license.html.
 * No part of DUDS, including this file, may be copied, modified, propagated,
 * or distributed except according to the terms contained in the LICENSE file.
 *
 * Copyright (C) 2017  Jeff Jackowski
 */
#include <fstream>
#include <iostream>
#include <sstream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <duds/time/interstellar/Metricform.hpp>
#include <duds/time/interstellar/Hectoform.hpp>
#include <duds/hardware/devices/clocks/LinuxClockDriver.hpp>
#include <duds/hardware/devices/clocks/PosixClockDriver.hpp>
#include <duds/hardware/devices/clocks/CppClockDriver.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <ratio>
//#include <sys/time.h>

struct beuint32_t {
	std::uint32_t val;
};

std::istream &operator >> (std::istream &is, beuint32_t &bei) {
	std::uint8_t buf[4];
	is.read((char*)buf, 4);
	bei.val = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
	return is;
}

std::ostream &operator << (std::ostream &os, const beuint32_t &bei) {
	os << bei.val;
	return os;
}

struct beuint64_t {
	std::uint64_t val;
};

std::istream &operator >> (std::istream &is, beuint64_t &bei) {
	std::uint8_t buf[8];
	is.read((char*)buf, 8);
	bei.val = ((std::uint64_t)buf[0] << 56) | ((std::uint64_t)buf[1] << 48) |
		((std::uint64_t)buf[2] << 40) | ((std::uint64_t)buf[3] << 32) |
		((std::uint64_t)buf[4] << 24) | ((std::uint64_t)buf[5] << 16) |
		((std::uint64_t)buf[6] << 8) | (std::uint64_t)buf[7];
	return is;
}

std::ostream &operator << (std::ostream &os, const beuint64_t &bei) {
	os << bei.val;
	return os;
}

namespace IST = duds::time::interstellar;

void timeout(const duds::time::planetary::LeapSeconds &ls, std::int64_t t,
const IST::SecondTime &ist) {
	IST::Metricform m(ist);
	IST::Hectoform e(ist);
	IST::Seconds leaps = ls.leapSeconds(ist);
	std::cout << "Time " << std::right << std::setw(16) << t << ": " << m <<
		"   " << e << "  Leap seconds: " << leaps.count() << std::endl;
}

using duds::time::planetary::earth;

// best results from  /usr/share/zoneinfo-leaps/UTC
// seems to be the same from all under  /usr/share/zoneinfo-leaps
int main(int argc, char *argv[])
try {
	const char *zfile = (argc > 1) ? argv[1] : "/usr/share/zoneinfo-leaps/UTC";
	std::ifstream zf(zfile,
		std::ios_base::in | std::ios_base::binary);
	if (!zf.is_open()) {
		std::cerr << "Failed to open " << zfile << std::endl;
		return 1;
	}
	zf.seekg(20 + 4 * 2);
	beuint32_t lsc, lstime, numls, transt, ltt, abr;
	zf >> lsc >> transt >> ltt >> abr;
	zf.seekg(transt.val * 5 + ltt.val * 6 + abr.val, std::ios_base::cur);
	std::cout << "Number of leap second entries: " << lsc.val << std::endl;
	boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
	for (; zf.good() && (lsc.val > 0); --lsc.val) {
		beuint32_t when, count;
		// when will store the time when the leap second is added
		zf >> when >> count;
		IST::Seconds secs(when.val);
		IST::SecondTime ist(secs);
		IST::Metricform m(ist);
		IST::Hectoform e(ist);

		IST::Milliseconds tm(secs);
		IST::Femtoseconds fs(secs);

		std::cout << lsc.val << ":\t" << count.val + 10 << " \t " << when.val <<
		"\t " << (epoch + boost::posix_time::seconds(when.val - count.val -1)).date()
		<< " \t  " << m << "   " << e << std::endl;
	}
	zf.close();
	std::cout << "ptime size = " << sizeof(boost::posix_time::ptime) << std::endl;
	std::cout << "Metricform size = " << sizeof(IST::Metricform) << std::endl;
	std::cout << "Hectoform size = " << sizeof(IST::Hectoform) << std::endl;
	std::cout << "Femtoseconds size = " << sizeof(IST::Femtoseconds) << std::endl;
	std::cout << "Milliseconds size = " << sizeof(IST::Milliseconds) << std::endl;
	earth = std::unique_ptr<duds::time::planetary::Earth>(
		new duds::time::planetary::Earth()
	);
	duds::time::planetary::LeapSeconds &ls = earth->leaps;
	if ((argc > 1) /* && (argv[1][0] == '/') */) {
		ls.readZoneinfo(argv[1]);
	} else {
		ls.readZoneinfo("/usr/share/zoneinfo-leaps/UTC");
	}
	for (int i = 2; i < argc; ++i) {
		if (argv[i][0] != '/') {
			std::istringstream iss(argv[i]);
			std::int64_t t;
			iss >> t;
			IST::Seconds sec(t); // cannot combine this line with the next
			IST::SecondTime ist(sec);
			timeout(ls, t, ist);
		}
	}

	//tzset();

	timeout(ls, 0, IST::SecondClock::now());
	duds::hardware::devices::clocks::LinuxClockDriver lcd;
	duds::hardware::devices::clocks::PosixClockDriver pcd(CLOCK_TAI), rtcd(CLOCK_REALTIME);
	duds::hardware::devices::clocks::CppClockDriver ccd;
	duds::hardware::devices::clocks::LinuxClockDriver::Measurement::TimeSample lts, pts, cts, rtts;
	lcd.sampleTime(lts);
	pcd.sampleTime(pts);
	ccd.sampleTime(cts);
	rtcd.sampleTime(rtts);
	timeout(ls, 0, lts.value);
	timeout(ls, 0, pts.value);
	timeout(ls, 0, cts.value);
	timeout(ls, 0, rtts.value);
	boost::posix_time::ptime pt;
	pt = earth->posix(lts.value);  // should be in UTC
	std::cout << pt << "  <-- lts UTC" << std::endl;
	pt = duds::time::planetary::ToPosix(lts.value);
	std::cout << pt << "  <-- lts TAI" << std::endl;
	pt = earth->posix(pts.value);  // should be wrong (UTC - leaps)
	std::cout << pt << "  <-- wrong" << std::endl;
	pt = duds::time::planetary::ToPosix(pts.value);  // should be in UTC
	std::cout << pt << std::endl;
	pt = duds::time::planetary::ToPosix(cts.value);
	std::cout << pt << std::endl;
	pt = duds::time::planetary::ToPosix(rtts.value);
	std::cout << pt << std::endl;
	pt = earth->timeZero() + boost::posix_time::milliseconds(  // UTC
		IST::MilliTime(rtts.value).time_since_epoch().count());
	std::cout << pt << std::endl;

	//tzset();
	//std::cout << "timezone = " << timezone << std::endl;
	tm testm;
	std::time_t tt = (std::time_t)std::chrono::duration_cast<std::chrono::seconds>(
		lts.value.time_since_epoch()).count();
	localtime_r(&tt, &testm);
	std::cout << "localtime T " << std::setfill(' ') << std::setw(2) << std::right <<
	testm.tm_hour << ':' << std::setfill('0') << std::setw(2) << testm.tm_min <<
	':' << std::setw(2) << testm.tm_sec << " in zone " << testm.tm_zone <<
	" (TAI referenced)" << std::endl;
	tt = earth->timeUtc(lts.value);
	localtime_r(&tt, &testm);
	std::cout << "localtime L " << std::setfill(' ') << std::setw(2) <<
	testm.tm_hour << ':' << std::setfill('0') << std::setw(2) << testm.tm_min <<
	':' << std::setw(2) << testm.tm_sec << " in zone " << testm.tm_zone <<
	std::endl;
	std::cout << "tm_gmtoff = " << testm.tm_gmtoff << std::endl;

	return 0;
}
catch (...) {
	std::cerr << "ERROR: " << boost::current_exception_diagnostic_information()
	<< std::endl;
	return __LINE__;
}

max_stars_repo_name: jjackowski/duds

max_issues_repo_name: jjackowski/duds

max_forks_repo_name: jjackowski/duds


text:
#pragma once

#include <memory>
#include <set>
#include <deque>

#include <eosio/chain/types.hpp>

#include <cyberway/chaindb/common.hpp>
#include <cyberway/chaindb/object_value.hpp>

#include <boost/smart_ptr/intrusive_ref_counter.hpp>

namespace cyberway { namespace chaindb {

    class cache_map_impl;

    struct cache_data {
        virtual ~cache_data() = default;
    }; // struct cache_data

    using cache_data_ptr = std::unique_ptr<cache_data>;

    struct cache_converter_interface {
        cache_converter_interface() = default;
        virtual ~cache_converter_interface() = default;

        virtual void convert_variant(cache_object&, const object_value&) const = 0;
    }; // struct cache_converter_interface

    struct cache_cell {
        enum cache_cell_kind {
            Unknown,
            Pending,
            LRU,
            System,
        }; // enum cell_kind

        cache_map_impl* const map  = nullptr;

        uint64_t size = 0;

        cache_cell(cache_map_impl& m, uint64_t p, cache_cell_kind k)
        : map(&m), pos_(p), kind_(k) {
        }

        cache_cell_kind kind() const {
            return kind_;
        }

        uint64_t pos() const {
            return pos_;
        }

    protected:
        const uint64_t pos_ = 0;
        cache_cell_kind kind_ = Unknown;
    }; // struct cache_cell

    struct cache_object_state {
        cache_cell* const cell = nullptr;
        cache_object_ptr  object_ptr;

        cache_object_state(cache_cell& c, cache_object_ptr ptr)
        : cell(&c), object_ptr(std::move(ptr)) {
        }

        void reset();
        cache_cell::cache_cell_kind kind() const;
    }; // struct cache_object_state

    struct cache_object final: public boost::intrusive_ref_counter<cache_object, boost::thread_unsafe_counter> {
        enum stage_kind {
            Released,
            Active,
            Deleted,
        }; // enum Stage

        cache_object(object_value);

        cache_object(cache_object&&) = delete;
        cache_object(const cache_object&) = delete;

        ~cache_object() = default;

        bool is_valid_cell() const;
        bool has_cell() const;
        bool is_same_cell(const cache_cell& cell) const;

        stage_kind stage() const {
            return stage_;
        }

        bool is_deleted() const {
            return stage_ != Active;
        }

        template <typename Request> bool is_valid_table(const Request& request) const {
            return
                object_.service.code  == request.code  &&
                object_.service.scope == request.scope &&
                object_.service.table == request.table;
        }

        template <typename T, typename... Args> void set_data(Args&&... args) {
            data_ = std::make_unique<T>(*this, std::forward<Args>(args)...);
        }

        void set_blob(bytes blob) {
            blob_ = std::move(blob);
        }

        primary_key_t pk() const {
            return object_.pk();
        }

        const object_value& object() const {
            return object_;
        }

        const service_state& service() const {
            return object_.service;
        }

        bool has_data() const {
            return !!data_;
        }

        template <typename T> T& data() const {
            assert(has_data());
            return *static_cast<T*>(data_.get());
        }

        bool has_blob() const {
            return !blob_.empty();
        }

        const bytes& blob() const {
            assert(has_blob());
            return blob_;
        }

    private:
        cache_object_state* state_ = nullptr;
        object_value        object_;
        bytes               blob_;  // for contracts tables
        cache_data_ptr      data_;  // for interchain tables
        stage_kind          stage_ = Released;

        friend class  cache_map_impl;
        friend struct lru_cache_cell;
        friend struct lru_cache_object_state;
        friend struct system_cache_cell;

        using cache_cell_kind = cache_cell::cache_cell_kind;

        cache_cell&         cell() const;
        cache_cell_kind     kind() const;
        cache_map_impl&     map() const;
        cache_object_state& state() const;
        cache_object_state* swap_state(cache_object_state& state);
    }; // class cache_object

    struct cache_object_key;

    using cache_object_tree = std::map<cache_object_key, cache_object_ptr>;

} } // namespace cyberway::chaindb

max_stars_repo_name: GolosChain/eos

max_issues_repo_name: GolosChain/eos

max_forks_repo_name: GolosChain/eos


text:
#include <boost/connector/snapshot/snapshot.hpp>
#include <catch2/catch.hpp>

TEST_CASE("boost::connector::snapshot")
{
    using namespace boost::connector;

    auto s1 = snapshot {};

    CHECK(s1.status == status_code::error);

    auto s2 = snapshot {};

    CHECK(equivalent(s1, s2));
    s1.source = "s1";
    s2.source = "s2";

    s1.status = status_code::good;

    CHECK(!equivalent(s1, s2));
}


text:
//------------------------------------------------------------------------------
/*
    This file is part of rippled: https://github.com/ripple/rippled
    Copyright (c) 2012-2015 Ripple Labs Inc.

    Permission to use, copy, modify, and/or distribute this software for any
    purpose  with  or without fee is hereby granted, provided that the above
    copyright notice and this permission notice appear in all copies.

    THE  SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    WITH  REGARD  TO  THIS  SOFTWARE  INCLUDING  ALL  IMPLIED  WARRANTIES  OF
    MERCHANTABILITY  AND  FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    ANY  SPECIAL ,  DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    WHATSOEVER  RESULTING  FROM  LOSS  OF USE, DATA OR PROFITS, WHETHER IN AN
    ACTION  OF  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================

#include <BeastConfig.h>

#include <ripple/basics/contract.h>
#include <ripple/core/ConfigSections.h>
#include <ripple/core/SociDB.h>
#include <ripple/core/Config.h>
#include <memory>
#include <soci/sqlite3/soci-sqlite3.h>
#include <soci/mysql/soci-mysql.h>
#include <boost/filesystem.hpp>

namespace ripple {

static auto checkpointPageCount = 1000;

namespace detail {

std::pair<std::string, soci::backend_factory const&>
getSociSqliteInit (std::string const& name,
                   std::string const& dir,
                   std::string const& ext)
{
    if (name.empty ())
    {
        Throw<std::runtime_error> (
            "Sqlite databases must specify a dir and a name. Name: " +
                name + " Dir: " + dir);
    }
    boost::filesystem::path file (dir);
    if (is_directory (file))
        file /= name + ext;
    return std::make_pair (file.string (), std::ref (soci::sqlite3));
}

std::pair<std::string, soci::backend_factory const&>
getSociInit (BasicConfig const& config,
             std::string const& dbName)
{
    auto const& section = config.section ("sqdb");
    auto const backendName = get(section, "backend", "sqlite");

    if (backendName != "sqlite")
        Throw<std::runtime_error> ("Unsupported soci backend: " + backendName);

    auto const path = config.legacy ("database_path");
    auto const ext = dbName == "validators" || dbName == "peerfinder"
                ? ".sqlite" : ".db";
    return detail::getSociSqliteInit(dbName, path, ext);
}

} // detail

SociConfig::SociConfig (
    std::pair<std::string, soci::backend_factory const&> init)
    : connectionString_ (std::move (init.first)),
      backendFactory_ (init.second)
{
}

SociConfig::SociConfig (BasicConfig const& config, std::string const& dbName)
    : SociConfig (detail::getSociInit (config, dbName))
{
}

std::string SociConfig::connectionString () const
{
    return connectionString_;
}

void SociConfig::open (soci::session& s) const
{
    s.open (backendFactory_, connectionString ());
}

void open  (soci::session& s,
            BasicConfig const& config,
            std::string const& dbName)
{
    SociConfig (config, dbName).open(s);
}

void open (soci::session& s,
           std::string const& beName,
           std::string const& connectionString)
{
	if (beName == "sqlite")
		s.open(soci::sqlite3, connectionString);
	else if (beName == "mycat")
		s.open(soci::mysql, connectionString);
    else
        Throw<std::runtime_error> ("Unsupported soci backend: " + beName);
}

static
sqlite_api::sqlite3* getConnection (soci::session& s)
{
    sqlite_api::sqlite3* result = nullptr;
    auto be = s.get_backend ();
    if (auto b = dynamic_cast<soci::sqlite3_session_backend*> (be))
        result = b->conn_;

    if (! result)
        Throw<std::logic_error> ("Didn't get a database connection.");

    return result;
}

size_t getKBUsedAll (soci::session& s)
{
    if (! getConnection (s))
        Throw<std::logic_error> ("No connection found.");
    return static_cast <size_t> (sqlite_api::sqlite3_memory_used () / 1024);
}

size_t getKBUsedDB (soci::session& s)
{
    // This function will have to be customized when other backends are added
    if (auto conn = getConnection (s))
    {
        int cur = 0, hiw = 0;
        sqlite_api::sqlite3_db_status (
            conn, SQLITE_DBSTATUS_CACHE_USED, &cur, &hiw, 0);
        return cur / 1024;
    }
    Throw<std::logic_error> ("");
    return 0; // Silence compiler warning.
}

void convert (soci::blob& from, std::vector<std::uint8_t>& to)
{
    to.resize (from.get_len ());
    if (to.empty ())
        return;
    from.read (0, reinterpret_cast<char*>(&to[0]), from.get_len ());
}

void convert (soci::blob& from, std::string& to)
{
    std::vector<std::uint8_t> tmp;
    convert (from, tmp);
    to.assign (tmp.begin (), tmp.end());

}

void convert (std::vector<std::uint8_t> const& from, soci::blob& to)
{
    if (!from.empty ())
        to.write (0, reinterpret_cast<char const*>(&from[0]), from.size ());
    else
        to.trim (0);
}

void convert (std::string const& from, soci::blob& to)
{
    if (!from.empty ())
        to.write (0, from.data (), from.size ());
    else
        to.trim (0);
}

namespace {

/** Run a thread to checkpoint the write ahead log (wal) for
    the given soci::session every 1000 pages. This is only implemented
    for sqlite databases.

    Note: According to: https://www.sqlite.org/wal.html#ckpt this
    is the default behavior of sqlite. We may be able to remove this
    class.
*/
class WALCheckpointer : public Checkpointer
{
public:
    WALCheckpointer (sqlite_api::sqlite3& conn, JobQueue& q, Logs& logs)
            : conn_ (conn), jobQueue_ (q), j_ (logs.journal ("WALCheckpointer"))
    {
        sqlite_api::sqlite3_wal_hook (&conn_, &sqliteWALHook, this);
    }

    ~WALCheckpointer () override = default;

private:
    sqlite_api::sqlite3& conn_;
    std::mutex mutex_;
    JobQueue& jobQueue_;

    bool running_ = false;
    beast::Journal j_;

    static
    int sqliteWALHook (
        void* cp, sqlite_api::sqlite3*, const char* dbName, int walSize)
    {
        if (walSize >= checkpointPageCount)
        {
            if (auto checkpointer = reinterpret_cast <WALCheckpointer*> (cp))
                checkpointer->scheduleCheckpoint();
            else
                Throw<std::logic_error> ("Didn't get a WALCheckpointer");
        }
        return SQLITE_OK;
    }

    void scheduleCheckpoint ()
    {
        {
            std::lock_guard <std::mutex> lock (mutex_);
            if (running_)
                return;
            running_ = true;
        }

        jobQueue_.addJob (jtWAL, "WAL", [this] (Job&) { checkpoint(); });
    }

    void checkpoint ()
    {
        int log = 0, ckpt = 0;
        int ret = sqlite3_wal_checkpoint_v2 (
            &conn_, nullptr, SQLITE_CHECKPOINT_PASSIVE, &log, &ckpt);

        auto fname = sqlite3_db_filename (&conn_, "main");
        if (ret != SQLITE_OK)
        {
            auto jm = (ret == SQLITE_LOCKED) ? j_.trace() : j_.warn();
            JLOG (jm)
                << "WAL(" << fname << "): error " << ret;
        }
        else
        {
            JLOG (j_.trace())
                << "WAL(" << fname << "): frames="
                << log << ", written=" << ckpt;
        }

        std::lock_guard <std::mutex> lock (mutex_);
        running_ = false;
    }
};

} // namespace

std::unique_ptr <Checkpointer> makeCheckpointer (
    soci::session& session, JobQueue& queue, Logs& logs)
{
    if (auto conn = getConnection (session))
        return std::make_unique <WALCheckpointer> (*conn, queue, logs);
    return {};
}

}

max_stars_repo_name: AgreeTechnology/ABC

max_issues_repo_name: AgreeTechnology/ABC

max_forks_repo_name: AgreeTechnology/ABC


text:
//==================================================================================================
/*!
  @file

  @copyright 2016 NumScale SAS
  @copyright 2016 J.T. Lapreste

  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_SIMD_FUNCTION_COMBINE_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_COMBINE_HPP_INCLUDED

#if defined(DOXYGEN_ONLY)
namespace boost { namespace simd
{

 /*!

    @ingroup group-swar
    Function object implementing combine capabilities

  **/
  const boost::dispatch::functor<tag::combine_> combine = {};
} }
#endif

#include <boost/simd/function/scalar/combine.hpp>
#include <boost/simd/function/simd/combine.hpp>

#endif


text:
// Copyright 2010-2014, D. E. Shaw Research.
// 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_RANDOM_THREEFRY_HPP
#define BOOST_RANDOM_THREEFRY_HPP

#include <boost/array.hpp>
#include <boost/static_assert.hpp>
#include <boost/cstdint.hpp>
#include <boost/limits.hpp>
#include <boost/random/detail/rotl.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/for_each.hpp>

namespace boost{
namespace random{

// threefry_constants is an abstract template that will be
// specialized with the KS_PARITY and Rotation constants
// of the threefry generators.  These constants are carefully
// chosen to achieve good randomization.
//  threefry_constants<2, uint32_t>
//  threefry_constants<2, uint64_t>
//  threefry_constants<4, uint32_t>
//  threefry_constants<4, uint64_t>
// The constants here are from Salmon et al <FIXME REF>.
//
// See Salmon et al, or Schneier's original work on Threefish <FIXME
// REF> for information about how the constants were obtained.
template <unsigned _N, typename Uint>
struct threefry_constants{
};

// 2x32 constants
template <>
struct threefry_constants<2, uint32_t>{
    static const uint32_t KS_PARITY = UINT32_C(0x1BD11BDA);
    static const unsigned Rotations[8];
};
const unsigned
threefry_constants<2, uint32_t>::Rotations[]  =
    {13, 15, 26, 6, 17, 29, 16, 24};

// 4x32 contants
template <>
struct threefry_constants<4, uint32_t>{
    static const uint32_t KS_PARITY = UINT32_C(0x1BD11BDA);
    static const unsigned Rotations0[8];
    static const unsigned Rotations1[8];
};
const unsigned
threefry_constants<4, uint32_t>::Rotations0[]  =
    {10, 11, 13, 23, 6, 17, 25, 18};

const unsigned
threefry_constants<4, uint32_t>::Rotations1[]  =
    {26, 21, 27, 5, 20, 11, 10, 20};

// 2x64 constants
template <>
struct threefry_constants<2, uint64_t>{
    static const uint64_t KS_PARITY = UINT64_C(0x1BD11BDAA9FC1A22);
    static const unsigned Rotations[8];
};
const unsigned
threefry_constants<2, uint64_t>::Rotations[]  =
    {16, 42, 12, 31, 16, 32, 24, 21};

// 4x64 constants
template <>
struct threefry_constants<4, uint64_t>{
    static const uint64_t KS_PARITY = UINT64_C(0x1BD11BDAA9FC1A22);
    static const unsigned Rotations0[8];
    static const unsigned Rotations1[8];
};
const unsigned
threefry_constants<4, uint64_t>::Rotations0[]  =
    {14, 52, 23, 5, 25, 46, 58, 32};

const unsigned
threefry_constants<4, uint64_t>::Rotations1[]  = {
    16, 57, 40, 37, 33, 12, 22, 32};

template <unsigned N, typename Uint, unsigned R=20, typename Constants=threefry_constants<N, Uint> >
struct threefry{
    BOOST_STATIC_ASSERT( N==2 || N==4 );
    // should never be instantiated.
    // Only the specializations on N=2 and 4 are
    // permitted/implemented.
};

// specialize threefry<2, Uint, R>
template<typename Uint, unsigned R, typename Constants>
struct threefry<2, Uint, R, Constants>{
    typedef array<Uint, 2> domain_type;
    typedef array<Uint, 2> range_type;
    typedef array<Uint, 2> key_type ;

    threefry() : k(){}
    threefry(key_type _k) : k(_k) {}
    threefry(const threefry& v) : k(v.k){}

    void setkey(key_type _k){
        k = _k;
    }

    key_type getkey() const{
        return k;
    }

    bool operator==(const threefry& rhs) const{
        return k == rhs.k;
    }

    bool operator!=(const threefry& rhs) const{
        return k != rhs.k;
    }

    domain_type operator()(domain_type c){
        Uint ks[3];
        ks[2] = Constants::KS_PARITY;
        ks[0] = this->k[0]; ks[2] ^= this->k[0]; c[0] += this->k[0];
        ks[1] = this->k[1]; ks[2] ^= this->k[1]; c[1] += this->k[1];
#if 1   // gcc doesn't want to unroll this without some help from mpl::for_each
        _roundapplyer ra(c, ks);
        mpl::for_each<mpl::range_c<unsigned, 0, R> >( ra );
        return c;
#else
        for(unsigned r=0; r<R; ){
            c[0] += c[1]; c[1] = detail::rotl(c[1],Constants::Rotations[r%8]); c[1] ^= c[0];
            ++r;
            if((r&3)==0){
                unsigned r4 = r>>2;
                c[0] += ks[r4%3];
                c[1] += ks[(r4+1)%3] + r4;
            }
        }
        return c;
#endif
    }

protected:
    struct _roundapplyer{
        domain_type& c;
        Uint* ks;
        _roundapplyer(domain_type& _c, Uint* _ks) : c(_c), ks(_ks){}
        void operator()(unsigned r){
            c[0] += c[1]; c[1] = detail::rotl(c[1],Constants::Rotations[r%8]); c[1] ^= c[0];
            unsigned rplus = r+1;
            if((rplus&3)==0){
                unsigned r4 = rplus>>2;
                c[0] += ks[r4%3];
                c[1] += ks[(r4+1)%3] + r4;
            }
        }
    };
    key_type k;
};

// specialize threefry<4, Uint, R>
template<typename Uint, unsigned R, typename Constants>
struct threefry<4, Uint, R, Constants>{
    typedef array<Uint, 4> domain_type;
    typedef array<Uint, 4> range_type;
    typedef array<Uint, 4> key_type ;

    threefry() : k(){}
    threefry(key_type _k) : k(_k) {}
    threefry(const threefry& v) : k(v.k){}

    void setkey(key_type _k){
        k = _k;
    }

    key_type getkey() const{
        return k;
    }

    bool operator==(const threefry& rhs) const{
        return k == rhs.k;
    }

    bool operator!=(const threefry& rhs) const{
        return k != rhs.k;
    }

    range_type operator()(domain_type c){
        Uint ks[5];
        ks[4] = Constants::KS_PARITY;
        ks[0] = this->k[0]; ks[4] ^= this->k[0]; c[0] += this->k[0];
        ks[1] = this->k[1]; ks[4] ^= this->k[1]; c[1] += this->k[1];
        ks[2] = this->k[2]; ks[4] ^= this->k[2]; c[2] += this->k[2];
        ks[3] = this->k[3]; ks[4] ^= this->k[3]; c[3] += this->k[3];

#if 1   // gcc doesn't want to unroll this without some help from mpl::for_each
        _roundapplyer ra(c, ks);
        mpl::for_each<mpl::range_c<unsigned, 0, R> >( ra );
        return c;
#else
        for(unsigned r=0; r<R; ){
            if((r&1)==0){
                c[0] += c[1]; c[1] = detail::rotl(c[1],Constants::Rotations0[r%8]); c[1] ^= c[0];
                c[2] += c[3]; c[3] = detail::rotl(c[3],Constants::Rotations1[r%8]); c[3] ^= c[2];
            }else{
                c[0] += c[3]; c[3] = detail::rotl(c[3],Constants::Rotations0[r%8]); c[3] ^= c[0];
                c[2] += c[1]; c[1] = detail::rotl(c[1],Constants::Rotations1[r%8]); c[1] ^= c[2];
            }
            ++r;
            if((r&3)==0){
                unsigned r4 = r>>2;
                c[0] += ks[(r4+0)%5];
                c[1] += ks[(r4+1)%5];
                c[2] += ks[(r4+2)%5];
                c[3] += ks[(r4+3)%5] + r4;
            }
        }
        return c;
#endif
    }

protected:
    struct _roundapplyer{
        domain_type& c;
        Uint* ks;
        _roundapplyer(domain_type& _c, Uint* _ks) : c(_c), ks(_ks){}
        void operator()(unsigned r){
            if((r&1)==0){
                c[0] += c[1]; c[1] = detail::rotl(c[1],Constants::Rotations0[r%8]); c[1] ^= c[0];
                c[2] += c[3]; c[3] = detail::rotl(c[3],Constants::Rotations1[r%8]); c[3] ^= c[2];
            }else{
                c[0] += c[3]; c[3] = detail::rotl(c[3],Constants::Rotations0[r%8]); c[3] ^= c[0];
                c[2] += c[1]; c[1] = detail::rotl(c[1],Constants::Rotations1[r%8]); c[1] ^= c[2];
            }
            ++r;
            if((r&3)==0){
                unsigned r4 = r>>2;
                c[0] += ks[(r4+0)%5];
                c[1] += ks[(r4+1)%5];
                c[2] += ks[(r4+2)%5];
                c[3] += ks[(r4+3)%5] + r4;
            }
        }
    };
    key_type k;
};

} // namespace random
} // namespace boost

#endif // BOOST_RANDOM_THREEFRY_HPP