text:
/* ----------------------------------------------------------------------- *//**
 *
 * @file link.hpp
 *
 *//* ----------------------------------------------------------------------- */

#ifndef MADLIB_MODULES_GLM_LINK_HPP
#define MADLIB_MODULES_GLM_LINK_HPP

#include <cmath>
#include <modules/prob/boost.hpp>
#include <boost/math/distributions.hpp>
#include <boost/math/special_functions/erf.hpp>

// ------------------------------------------------------------

using namespace madlib::dbal::eigen_integration;

namespace madlib {

namespace modules {

namespace glm {

using namespace std;

// ------------------------------------------------------------

class Identity {
public:
    static double init(const double &y) { return y + 0.1; }
    static double link_func(const double &mu) { return mu; }
    static double mean_func(const double &ita) { return ita; }
    static double mean_derivative(const double &) { return 1.; }
};

// ------------------------------------------------------------

class Log {
public:
    static double init(const double &y) { return std::max(y, 0.1); }
    static double link_func(const double &mu) { return log(mu); }
    static double mean_func(const double &ita) { return exp(ita); }
    static double mean_derivative(const double &ita) { return exp(ita); }
};

// ------------------------------------------------------------

class Sqrt {
public:
    static double init(const double &y) { return std::max(y, 0.); }
    static double link_func(const double &mu) { return sqrt(mu); }
    static double mean_func(const double &ita) { return ita * ita; }
    static double mean_derivative(const double &ita) { return 2 * ita; }
};

// ------------------------------------------------------------
class Inverse {
public:
    static double init(const double &y) { return y == 0 ? 0.1 : y + 0.1; }
    static double link_func(const double &mu) { return 1./mu; }
    static double mean_func(const double &ita) { return 1./ita; }
    static double mean_derivative(const double &ita) { return -1./(ita*ita); }
};

// ------------------------------------------------------------

class SqrInverse {
public:
    static double init(const double &y) { return y == 0 ? 0.1 : y + 0.1; }
    static double link_func(const double &mu) { return 1./mu/mu; }
    static double mean_func(const double &ita) { return 1./sqrt(ita); }
    static double mean_derivative(const double &ita) { return -1./2/sqrt(ita*ita*ita); }
};

// ------------------------------------------------------------

class Probit
{
public:
    static double init(const double &y) { return (y + 0.5) / 2; }
    static double link_func(const double &mu) {
        double root_2 = sqrt(2);
        return root_2 * boost::math::erf_inv(2*mu-1);
    }

    static double mean_func(const double &ita) {
        return prob::cdf(prob::normal(), ita);
    }

    static double mean_derivative(const double &ita) {
        return exp(-ita*ita/2.)/sqrt(2*M_PI);
    }
};

// ------------------------------------------------------------

class Logit {
public:
    static double init(const double &y) { return (y + 0.5) / 2; }
    static double link_func(const double &mu) {
        return log(mu / (1 - mu));
    }
    static double mean_func(const double &ita) {
        return 1./(1 + exp(-ita));
    }
    static double mean_derivative(const double &ita) {
        return 1./((1 + exp(-ita)) * (1 + exp(ita)));
    }
};

// ------------------------------------------------------------

class MultiLogit {
public:
    static void init(ColumnVector &mu) {
        mu.fill(1./static_cast<double>(mu.size()+1)); // later we may consider to use y to initialize mu
    }
    static void link_func(const ColumnVector &mu, ColumnVector &ita) {
        for (int i=0;i<mu.size();i++)
          ita(i) = log(mu(i)) - log(1-mu.sum());
    }
    static void mean_func(const ColumnVector &ita, ColumnVector &mu) {
        double temp=0;
        for(int i=0;i<ita.size();i++)
           temp += exp(ita(i));
        temp = temp+1;
        for(int i=0;i<ita.size();i++)
           mu(i) = exp(ita(i))/temp;
    }
    static void mean_derivative(const ColumnVector &ita, Matrix &mu_prime) {
        double temp=0;
        for(int i=0;i<ita.size();i++)
           temp += exp(ita(i));
        temp = temp+1;
        for(int i=0;i<ita.size();i++) {
          for(int j=0;j<ita.size();j++) {
             if(i==j)
                mu_prime(i,j)=exp(ita(i))*(temp - exp(ita(i)))/(temp*temp);
             else
                mu_prime(i,j)=-exp(ita(i))*exp(ita(j))/(temp*temp);
          }
        }
    }
};

// ------------------------------------------------------------

class OrdinalLogit {
public:
    static void init(ColumnVector &mu) {
        mu.fill(1./static_cast<double>(mu.size()+1)); // later we may consider to use y to initialize mu
    }
    static void link_func(const ColumnVector &mu, ColumnVector &ita) {
        ColumnVector sum_vec(mu.size());
        sum_vec(0) = mu(0);
        for (int i=1;i<mu.size();i++)
            sum_vec(i) = sum_vec(i-1) + mu(i);
        for (int i=0;i<mu.size();i++)
            ita(i) = log(sum_vec(i)/(1-sum_vec(i)));
    }
    static void mean_func(const ColumnVector &ita, ColumnVector &mu) {
        mu(0) = exp(ita(0))/(1+exp(ita(0)));
        for(int i=1;i<ita.size();i++)
           mu(i) = exp(ita(i))/(1+exp(ita(i)))- exp(ita(i-1))/(1+exp(ita(i-1)));
    }
    static void mean_derivative(const ColumnVector &ita, Matrix &mu_prime) {
        mu_prime.fill(0);
        for(int i=0;i<ita.size();i++) {
            for(int j=0;j<=i;j++) {
                if(i==j)
                    mu_prime(i,j)=exp(ita(i))/(1+exp(ita(i)))/(1+exp(ita(i)));
                else if(i==(j+1))
                    mu_prime(i,j)=-exp(ita(j))/(1+exp(ita(j)))/(1+exp(ita(j)));
                else
                    mu_prime(i,j)=0;
            }
        }
    }
};

// ------------------------------------------------------------

class OrdinalProbit {
public:
    static void init(ColumnVector &mu) {
        mu.fill(1./static_cast<double>(mu.size()+1)); // later we may consider to use y to initialize mu
    }
    static void link_func(const ColumnVector &mu, ColumnVector &ita) {
        ColumnVector sum_vec(mu.size());
        double root_2 = sqrt(2);
        sum_vec(0) = mu(0);
        for (int i=1;i<mu.size();i++)
            sum_vec(i) = sum_vec(i-1) + mu(i);
        for (int i=0;i<mu.size();i++)
            ita(i) = root_2 * boost::math::erf_inv(2*sum_vec(i)-1);
    }
    static void mean_func(const ColumnVector &ita, ColumnVector &mu) {
        mu(0) = prob::cdf(prob::normal(), ita(0));
        for(int i=1;i<ita.size();i++)
            mu(i) = prob::cdf(prob::normal(), ita(i))-prob::cdf(prob::normal(), ita(i-1));
    }
    static void mean_derivative(const ColumnVector &ita, Matrix &mu_prime) {
        mu_prime.fill(0);
        for(int i=0;i<ita.size();i++) {
            for(int j=0;j<=i;j++) {
                if(i==j)
                    mu_prime(i,j) = exp(-ita(i)*ita(i)/2.)/sqrt(2*M_PI);
                else if(i==(j+1))
                    mu_prime(i,j) = -exp(-ita(j)*ita(j)/2.)/sqrt(2*M_PI);
                else
                    mu_prime(i,j)=0;
            }
        }
    }
};

} // namespace glm

} // namespace modules

} // namespace madlib

#endif // defined(MADLIB_MODULES_GLM_LINK_HPP)


text:
//==================================================================================================
/*!

  Copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#include <boost/simd/function/scalar/toint.hpp>
#include <boost/simd/function/fast.hpp>
#include <scalar_test.hpp>
#include <boost/simd/detail/dispatch/meta/as_integer.hpp>
#include <boost/simd/constant/inf.hpp>
#include <boost/simd/constant/minf.hpp>
#include <boost/simd/constant/mone.hpp>
#include <boost/simd/constant/nan.hpp>
#include <boost/simd/constant/one.hpp>
#include <boost/simd/constant/zero.hpp>

STF_CASE_TPL (" toint real",  STF_IEEE_TYPES)
{
  namespace bs = boost::simd;
  namespace bd = boost::dispatch;
  using bs::toint;
  using r_t = decltype(toint(T()));

  // return type conformity test
  STF_TYPE_IS(r_t, (bd::as_integer_t<T, signed>));

  // specific values tests
  STF_EQUAL(toint(T(0.4)), r_t(0));
  STF_EQUAL(toint(T(0.5)), r_t(0));
  STF_EQUAL(toint(T(0.6)), r_t(0));
  STF_EQUAL(toint(bs::Mone<T>()), bs::Mone<r_t>());
  STF_EQUAL(toint(bs::One<T>()),  bs::One<r_t>());
  STF_EQUAL(toint(bs::Zero<T>()), bs::Zero<r_t>());

} // end of test for floating_

STF_CASE_TPL (" toint unsigned_int",  STF_UNSIGNED_INTEGRAL_TYPES)
{
  namespace bs = boost::simd;
  namespace bd = boost::dispatch;
  using bs::toint;
  using r_t = decltype(toint(T()));

  // return type conformity test
  STF_TYPE_IS(r_t, (bd::as_integer_t<T, signed>));

  // specific values tests
  STF_EQUAL(toint(bs::One<T>()),  bs::One<r_t>());
  STF_EQUAL(toint(bs::Zero<T>()), bs::Zero<r_t>());
} // end of test for unsigned_int_

STF_CASE_TPL (" toint signed",  STF_SIGNED_INTEGRAL_TYPES)
{
  namespace bs = boost::simd;
  namespace bd = boost::dispatch;
  using bs::toint;
  using r_t = decltype(toint(T()));

  // return type conformity test
  STF_TYPE_IS(r_t, (bd::as_integer_t<T, signed>));

  // specific values tests
  STF_EQUAL(toint(bs::Mone<T>()), bs::Mone<r_t>());
  STF_EQUAL(toint(bs::One<T>()),  bs::One<r_t>());
  STF_EQUAL(toint(bs::Zero<T>()), bs::Zero<r_t>());
} // end of test for signed_int_

ext: cpp

max_stars_repo_name: nickporubsky/boost-simd-clone

max_issues_repo_name: nickporubsky/boost-simd-clone

max_forks_repo_name: nickporubsky/boost-simd-clone


text:
#include "joiners/example_joiner.h"
#include "test_common.h"
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_CASE(example_joiner_test_cb) {
  auto vw = VW::initialize("--quiet --binary_parser --cb_explore_adf", nullptr,
                           false, nullptr, nullptr);

  example_joiner joiner(vw);
  v_array<example *> examples;

  joiner.set_problem_type_config(v2::ProblemType_CB);

  std::string input_files = get_test_files_location();
  auto interaction_buffer = read_file(input_files + "/fb_events/cb_v2.fb");
  // need to keep the fb buffer around in order to process the event
  std::vector<flatbuffers::DetachedBuffer> int_detached_buffers;

  auto joined_cb_events =
      wrap_into_joined_events(interaction_buffer, int_detached_buffers);

  for (auto &je : joined_cb_events) {
    joiner.process_event(*je);
    examples.push_back(&VW::get_unused_example(vw));
  }

  // need to keep the fb buffer around in order to process the event
  std::vector<flatbuffers::DetachedBuffer> obs_detached_buffers;

  auto observation_buffer =
      read_file(input_files + "/fb_events/f-reward_v2.fb");
  joined_cb_events =
      wrap_into_joined_events(observation_buffer, obs_detached_buffers);

  for (auto &je : joined_cb_events) {
    joiner.process_event(*je);
  }

  BOOST_CHECK_EQUAL(joiner.processing_batch(), true);

  joiner.process_joined(examples);

  BOOST_CHECK_EQUAL(examples.size(), 4);
  // first example is shared example
  BOOST_CHECK_EQUAL(CB::ec_is_example_header(*examples[0]), true);
  // second example has label set and non of the other do
  BOOST_CHECK_EQUAL(examples[1]->l.cb.costs.size(), 1);
  BOOST_CHECK_EQUAL(examples[2]->l.cb.costs.size(), 0);
  // last example is empty
  BOOST_CHECK_EQUAL(example_is_newline(*examples[3]), true);

  // check label
  BOOST_CHECK_EQUAL(examples[1]->l.cb.costs[0].action, 1);
  BOOST_CHECK_EQUAL(examples[1]->l.cb.costs[0].cost, -1.5f);
  BOOST_CHECK_CLOSE(examples[1]->l.cb.costs[0].probability, 0.9, FLOAT_TOL);
  BOOST_CHECK_EQUAL(examples[1]->l.cb.weight, 1.0f);

  // check example features
  // from example_gen payload is JSON_CB_CONTEXT =
  // R"({"GUser":{"id":"a","major":"eng","hobby":"hiking"},"_multi":[{"TAction":{"a1":"f1"}},{"TAction":{"a2":"f2"}}]})";
  BOOST_CHECK_EQUAL(examples[0]->indices.size(), 1);
  BOOST_CHECK_EQUAL(examples[0]->indices[0], 'G');
  BOOST_CHECK_EQUAL(examples[1]->indices.size(), 1);
  BOOST_CHECK_EQUAL(examples[1]->indices[0], 'T');
  BOOST_CHECK_EQUAL(examples[2]->indices.size(), 1);
  BOOST_CHECK_EQUAL(examples[2]->indices[0], 'T');
  BOOST_CHECK_EQUAL(examples[3]->indices.size(), 0); // newline example

  BOOST_CHECK_EQUAL(joiner.processing_batch(), false);
  clear_examples(examples, vw);
  VW::finish(*vw);
}

BOOST_AUTO_TEST_CASE(example_joiner_test_cbb) {
  auto vw = VW::initialize("--quiet --binary_parser --ccb_explore_adf", nullptr,
                           false, nullptr, nullptr);

  example_joiner joiner(vw);
  v_array<example *> examples;

  joiner.set_problem_type_config(v2::ProblemType_CCB);

  std::string input_files = get_test_files_location();
  auto interaction_buffer = read_file(input_files + "/fb_events/ccb_v2.fb");
  // need to keep the fb buffer around in order to process the event
  std::vector<flatbuffers::DetachedBuffer> int_detached_buffers;

  auto joined_ccb_events =
      wrap_into_joined_events(interaction_buffer, int_detached_buffers);

  for (auto &je : joined_ccb_events) {
    joiner.process_event(*je);
    examples.push_back(&VW::get_unused_example(vw));
  }

  // need to keep the fb buffer around in order to process the event
  std::vector<flatbuffers::DetachedBuffer> obs_detached_buffers;

  auto observation_buffer =
      read_file(input_files + "/fb_events/fi-reward_v2.fb");
  joined_ccb_events =
      wrap_into_joined_events(observation_buffer, obs_detached_buffers);

  for (auto &je : joined_ccb_events) {
    joiner.process_event(*je);
  }

  BOOST_CHECK_EQUAL(joiner.processing_batch(), true);

  joiner.process_joined(examples);
  // learn/predict isn't called in the unit test but cleanup examples expects
  // shared pred to be set
  examples[0]->pred.decision_scores = {v_init<ACTION_SCORE::action_score>()};
  examples[0]->pred.decision_scores[0].push_back({0, 0.f});

  // shared, two actions, two slots and one empty (end of multiline)
  BOOST_CHECK_EQUAL(examples.size(), 6);
  // first example is shared example
  BOOST_CHECK_EQUAL(CCB::ec_is_example_header(*examples[0]), true);
  // next two examples are actions
  BOOST_CHECK_EQUAL(examples[1]->l.conditional_contextual_bandit.type,
                    CCB::example_type::action);
  BOOST_CHECK_EQUAL(examples[2]->l.conditional_contextual_bandit.type,
                    CCB::example_type::action);
  // next two examples are slots
  BOOST_CHECK_EQUAL(examples[3]->l.conditional_contextual_bandit.type,
                    CCB::example_type::slot);
  BOOST_CHECK_EQUAL(examples[4]->l.conditional_contextual_bandit.type,
                    CCB::example_type::slot);
  // last example is empty
  BOOST_CHECK_EQUAL(example_is_newline(*examples[5]), true);

  // check slot labels
  BOOST_CHECK_EQUAL(
      examples[3]
          ->l.conditional_contextual_bandit.outcome->probabilities.size(),
      2);
  BOOST_CHECK_EQUAL(
      examples[4]
          ->l.conditional_contextual_bandit.outcome->probabilities.size(),
      1);

  // check example features
  // from example_gen payload is JSON_CCB_CONTEXT =
  // R"({"GUser":{"id":"a","major":"eng","hobby":"hiking"},"_multi":[{"TAction":{"a1":"f1"}},{"TAction":{"a2":"f2"}}],"_slots":[{"Slot":{"a1":"f1"}},{"Slot":{"a1":"f1"}}]})";

  BOOST_CHECK_EQUAL(examples[0]->indices.size(), 1);
  BOOST_CHECK_EQUAL(examples[0]->indices[0], 'G');
  BOOST_CHECK_EQUAL(examples[1]->indices.size(), 1);
  BOOST_CHECK_EQUAL(examples[1]->indices[0], 'T');
  BOOST_CHECK_EQUAL(examples[2]->indices.size(), 1);
  BOOST_CHECK_EQUAL(examples[2]->indices[0], 'T');
  BOOST_CHECK_EQUAL(examples[3]->indices.size(), 1);
  BOOST_CHECK_EQUAL(examples[3]->indices[0], 'S');
  BOOST_CHECK_EQUAL(examples[4]->indices.size(), 1);
  BOOST_CHECK_EQUAL(examples[4]->indices[0], 'S');
  BOOST_CHECK_EQUAL(examples[5]->indices.size(), 0); // newline example

  BOOST_CHECK_EQUAL(joiner.processing_batch(), false);
  clear_examples(examples, vw);
  VW::finish(*vw);
}

BOOST_AUTO_TEST_CASE(example_joiner_test_joiner_ready) {
  auto vw = VW::initialize("--quiet --binary_parser --cb_explore_adf", nullptr,
                           false, nullptr, nullptr);

  example_joiner joiner(vw);

  //the initial state of the joiner is not ready
  BOOST_CHECK_EQUAL(joiner.joiner_ready(), false);

  //all values but problem type have a default value
  joiner.set_problem_type_config(v2::ProblemType_CB);

  BOOST_CHECK_EQUAL(joiner.joiner_ready(), true);

  VW::finish(*vw);
}

BOOST_AUTO_TEST_CASE(example_joiner_test_stickyness) {
  auto vw = VW::initialize("--quiet --binary_parser --cb_explore_adf", nullptr,
                           false, nullptr, nullptr);

  example_joiner joiner(vw);

  BOOST_CHECK_EQUAL(joiner.joiner_ready(), false);

  //all values but problem type have a default value
  joiner.set_problem_type_config(v2::ProblemType_CB, false);
  BOOST_CHECK_EQUAL(joiner.problem_type_config(), v2::ProblemType_CB);

  joiner.set_problem_type_config(v2::ProblemType_SLATES, true);
  BOOST_CHECK_EQUAL(joiner.problem_type_config(), v2::ProblemType_SLATES);

  // once the value is sticky, it cannot be modified
  joiner.set_problem_type_config(v2::ProblemType_CB, false);
  BOOST_CHECK_EQUAL(joiner.problem_type_config(), v2::ProblemType_SLATES);

  joiner.set_problem_type_config(v2::ProblemType_CB, true);
  BOOST_CHECK_EQUAL(joiner.problem_type_config(), v2::ProblemType_SLATES);

  VW::finish(*vw);
}

ext: cc


text:
//
// Copyright (c) 2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//

#ifndef BOOST_BEAST_STREAM_TRAITS_HPP
#define BOOST_BEAST_STREAM_TRAITS_HPP

#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/detail/stream_traits.hpp>

namespace boost {
namespace beast {

/** A trait to determine the lowest layer type of a stack of stream layers.

    If `t.next_layer()` is well-defined for an object `t` of type `T`,
    then `lowest_layer_type<T>` will be an alias for
    `lowest_layer_type<decltype(t.next_layer())>`,
    otherwise it will be the type
    `std::remove_reference<T>`.

    @param T The type to determine the lowest layer type of.

    @return The type of the lowest layer.
*/
template<class T>
#if BOOST_BEAST_DOXYGEN
using lowest_layer_type = __see_below__;
#else
using lowest_layer_type = detail::lowest_layer_type<T>;
#endif

/** Return the lowest layer in a stack of stream layers.

    If `t.next_layer()` is well-defined, returns
    `get_lowest_layer(t.next_layer())`. Otherwise, it returns `t`.

    A stream layer is an object of class type which wraps another object through
    composition, and meets some or all of the named requirements of the wrapped
    type while optionally changing behavior. Examples of stream layers include
    `net::ssl::stream` or @ref beast::websocket::stream. The owner of a stream
    layer can interact directly with the wrapper, by passing it to stream
    algorithms. Or, the owner can obtain a reference to the wrapped object by
    calling `next_layer()` and accessing its members. This is necessary when it is
    desired to access functionality in the next layer which is not available
    in the wrapper. For example, @ref websocket::stream permits reading and
    writing, but in order to establish the underlying connection, members
    of the wrapped stream (such as `connect`) must be invoked directly.

    Usually the last object in the chain of composition is the concrete socket
    object (for example, a `net::basic_socket` or a class derived from it).
    The function @ref get_lowest_layer exists to easily obtain the concrete
    socket when it is desired to perform an action that is not prescribed by
    a named requirement, such as changing a socket option, cancelling all
    pending asynchronous I/O, or closing the socket (perhaps by using
    @ref close_socket).

    @par Example
    @code
    // Set non-blocking mode on a stack of stream
    // layers with a regular socket at the lowest layer.
    template <class Stream>
    void set_non_blocking (Stream& stream)
    {
        error_code ec;
        // A compile error here means your lowest layer is not the right type!
        get_lowest_layer(stream).non_blocking(true, ec);
        if(ec)
            throw system_error{ec};
    }
    @endcode

    @param t The layer in a stack of layered objects for which the lowest layer is returned.

    @see @ref close_socket, @ref lowest_layer_type
*/
template<class T>
lowest_layer_type<T>&
get_lowest_layer(T& t) noexcept
{
    return detail::get_lowest_layer_impl(
        t, detail::has_next_layer<T>{});
}

//------------------------------------------------------------------------------

/** A trait to determine the return type of get_executor.

    This type alias will be the type of values returned by
    by calling member `get_exector` on an object of type `T&`.

    @param T The type to query

    @return The type of values returned from `get_executor`.
*/
// Workaround for ICE on gcc 4.8
#if BOOST_BEAST_DOXYGEN
template<class T>
using executor_type = __see_below__;
#elif BOOST_WORKAROUND(BOOST_GCC, < 40900)
template<class T>
using executor_type =
    typename std::decay<T>::type::executor_type;
#else
template<class T>
using executor_type =
    decltype(std::declval<T&>().get_executor());
#endif

/** Determine if `T` has the `get_executor` member function.

    Metafunctions are used to perform compile time checking of template
    types. This type will be `std::true_type` if `T` has the member
    function with the correct signature, else type will be `std::false_type`.

    @par Example

    Use with tag dispatching:

    @code
    template<class T>
    void maybe_hello(T const& t, std::true_type)
    {
        net::post(
            t.get_executor(),
            []
            {
                std::cout << "Hello, world!" << std::endl;
            });
    }

    template<class T>
    void maybe_hello(T const&, std::false_type)
    {
        // T does not have get_executor
    }

    template<class T>
    void maybe_hello(T const& t)
    {
        maybe_hello(t, has_get_executor<T>{});
    }
    @endcode

    Use with `static_assert`:

    @code
    struct stream
    {
        using executor_type = net::io_context::executor_type;
        executor_type get_executor() noexcept;
    };

    static_assert(has_get_executor<stream>::value, "Missing get_executor member");
    @endcode
*/
#if BOOST_BEAST_DOXYGEN
template<class T>
struct has_get_executor : std::integral_constant<bool, ...>{};
#else
template<class T, class = void>
struct has_get_executor : std::false_type {};

template<class T>
struct has_get_executor<T, boost::void_t<decltype(
    std::declval<T&>().get_executor())>> : std::true_type {};
#endif

//------------------------------------------------------------------------------

/** Determine if `T` meets the requirements of @b SyncReadStream.

    Metafunctions are used to perform compile time checking of template
    types. This type will be `std::true_type` if `T` meets the requirements,
    else the type will be `std::false_type`.

    @par Example

    Use with `static_assert`:

    @code
    template<class SyncReadStream>
    void f(SyncReadStream& stream)
    {
        static_assert(is_sync_read_stream<SyncReadStream>::value,
            "SyncReadStream requirements not met");
    ...
    @endcode

    Use with `std::enable_if` (SFINAE):

    @code
    template<class SyncReadStream>
    typename std::enable_if<is_sync_read_stream<SyncReadStream>::value>::type
    f(SyncReadStream& stream);
    @endcode
*/
#if BOOST_BEAST_DOXYGEN
template<class T>
struct is_sync_read_stream : std::integral_constant<bool, ...>{};
#else
template<class T, class = void>
struct is_sync_read_stream : std::false_type {};

template<class T>
struct is_sync_read_stream<T, boost::void_t<decltype(
    std::declval<std::size_t&>() = std::declval<T>().read_some(
        std::declval<detail::MutableBufferSequence>()),
    std::declval<std::size_t&>() = std::declval<T>().read_some(
        std::declval<detail::MutableBufferSequence>(),
        std::declval<boost::system::error_code&>())
            )>> : std::true_type {};
#endif

/** Determine if `T` meets the requirements of @b SyncWriteStream.

    Metafunctions are used to perform compile time checking of template
    types. This type will be `std::true_type` if `T` meets the requirements,
    else the type will be `std::false_type`.

    @par Example

    Use with `static_assert`:

    @code
    template<class SyncReadStream>
    void f(SyncReadStream& stream)
    {
        static_assert(is_sync_read_stream<SyncReadStream>::value,
            "SyncReadStream requirements not met");
    ...
    @endcode

    Use with `std::enable_if` (SFINAE):

    @code
    template<class SyncReadStream>
    typename std::enable_if<is_sync_read_stream<SyncReadStream>::value>::type
    f(SyncReadStream& stream);
    @endcode
*/
#if BOOST_BEAST_DOXYGEN
template<class T>
struct is_sync_write_stream : std::integral_constant<bool, ...>{};
#else
template<class T, class = void>
struct is_sync_write_stream : std::false_type {};

template<class T>
struct is_sync_write_stream<T, boost::void_t<decltype(
    (
    std::declval<std::size_t&>() = std::declval<T&>().write_some(
        std::declval<detail::ConstBufferSequence>()))
    ,std::declval<std::size_t&>() = std::declval<T&>().write_some(
        std::declval<detail::ConstBufferSequence>(),
        std::declval<boost::system::error_code&>())
            )>> : std::true_type {};
#endif

/** Determine if `T` meets the requirements of @b SyncStream.

    Metafunctions are used to perform compile time checking of template
    types. This type will be `std::true_type` if `T` meets the requirements,
    else the type will be `std::false_type`.

    @par Example

    Use with `static_assert`:

    @code
    template<class SyncStream>
    void f(SyncStream& stream)
    {
        static_assert(is_sync_stream<SyncStream>::value,
            "SyncStream requirements not met");
    ...
    @endcode

    Use with `std::enable_if` (SFINAE):

    @code
    template<class SyncStream>
    typename std::enable_if<is_sync_stream<SyncStream>::value>::type
    f(SyncStream& stream);
    @endcode
*/
#if BOOST_BEAST_DOXYGEN
template<class T>
struct is_sync_stream : std::integral_constant<bool, ...>{};
#else
template<class T>
using is_sync_stream = std::integral_constant<bool,
    is_sync_read_stream<T>::value && is_sync_write_stream<T>::value>;
#endif

//------------------------------------------------------------------------------

/** Determine if `T` meets the requirements of @b AsyncReadStream.

    Metafunctions are used to perform compile time checking of template
    types. This type will be `std::true_type` if `T` meets the requirements,
    else the type will be `std::false_type`.

    @par Example

    Use with `static_assert`:

    @code
    template<class AsyncReadStream>
    void f(AsyncReadStream& stream)
    {
        static_assert(is_async_read_stream<AsyncReadStream>::value,
            "AsyncReadStream requirements not met");
    ...
    @endcode

    Use with `std::enable_if` (SFINAE):

    @code
        template<class AsyncReadStream>
        typename std::enable_if<is_async_read_stream<AsyncReadStream>::value>::type
        f(AsyncReadStream& stream);
    @endcode
*/
#if BOOST_BEAST_DOXYGEN
template<class T>
struct is_async_read_stream : std::integral_constant<bool, ...>{};
#else
template<class T, class = void>
struct is_async_read_stream : std::false_type {};

template<class T>
struct is_async_read_stream<T, boost::void_t<decltype(
    std::declval<T>().async_read_some(
        std::declval<detail::MutableBufferSequence>(),
        std::declval<detail::ReadHandler>())
            )>> : std::integral_constant<bool,
    has_get_executor<T>::value
        > {};
#endif

/** Determine if `T` meets the requirements of @b AsyncWriteStream.

    Metafunctions are used to perform compile time checking of template
    types. This type will be `std::true_type` if `T` meets the requirements,
    else the type will be `std::false_type`.

    @par Example

    Use with `static_assert`:

    @code
    template<class AsyncWriteStream>
    void f(AsyncWriteStream& stream)
    {
        static_assert(is_async_write_stream<AsyncWriteStream>::value,
            "AsyncWriteStream requirements not met");
    ...
    @endcode

    Use with `std::enable_if` (SFINAE):

    @code
    template<class AsyncWriteStream>
    typename std::enable_if<is_async_write_stream<AsyncWriteStream>::value>::type
    f(AsyncWriteStream& stream);
    @endcode
*/
#if BOOST_BEAST_DOXYGEN
template<class T>
struct is_async_write_stream : std::integral_constant<bool, ...>{};
#else
template<class T, class = void>
struct is_async_write_stream : std::false_type {};

template<class T>
struct is_async_write_stream<T, boost::void_t<decltype(
    std::declval<T>().async_write_some(
        std::declval<detail::ConstBufferSequence>(),
        std::declval<detail::WriteHandler>())
            )>> : std::integral_constant<bool,
    has_get_executor<T>::value
        > {};
#endif

/** Determine if `T` meets the requirements of @b AsyncStream.

    Metafunctions are used to perform compile time checking of template
    types. This type will be `std::true_type` if `T` meets the requirements,
    else the type will be `std::false_type`.

    @par Example

    Use with `static_assert`:

    @code
    template<class AsyncStream>
    void f(AsyncStream& stream)
    {
        static_assert(is_async_stream<AsyncStream>::value,
            "AsyncStream requirements not met");
    ...
    @endcode

    Use with `std::enable_if` (SFINAE):

    @code
    template<class AsyncStream>
    typename std::enable_if<is_async_stream<AsyncStream>::value>::type
    f(AsyncStream& stream);
    @endcode
*/
#if BOOST_BEAST_DOXYGEN
template<class T>
struct is_async_stream : std::integral_constant<bool, ...>{};
#else
template<class T>
using is_async_stream = std::integral_constant<bool,
    is_async_read_stream<T>::value && is_async_write_stream<T>::value>;
#endif

} // beast
} // boost

#endif

ext: hpp

max_stars_repo_name: bebuch/beast

max_issues_repo_name: bebuch/beast

max_forks_repo_name: bebuch/beast


text:
#ifndef KOMUNA_VEKTORO_HPP
#define KOMUNA_VEKTORO_HPP

#include "../torent/Torentu.hpp"
#include "../trajtoj/numero.hpp"
#include <cmath>
#include <boost/serialization/access.hpp>
#ifdef ĈU_UZAS_QT
#include <QPoint>
#include <QPointF>
#endif

template<class T>
class Vektor2D
{
public:
    struct Ordiganto
    {
        Buleo operator()(const Vektor2D<T>& a, const Vektor2D<T>& b) const
        {
            eligu a.x < b.x aŭ (a.x == b.x kaj a.y < b.y);
        }
    };

    Vektor2D() : x(0), y(0) {}
    Vektor2D(T x, T y) : x(x), y(y) {}//-«
    Nenio operator+=(const Vektor2D<T> alia) { x += alia.x; y += alia.y; }
    Nenio operator-=(const Vektor2D<T> alia) { x -= alia.x; y -= alia.y; }  //»-
    Buleo operator==(const Vektor2D<T> alia) const { eligu x == alia.x && y == alia.y; }
    Buleo operator!=(const Vektor2D<T> alia) const { eligu x != alia.x || y != alia.y; }
    Vektor2D<T> operator+(const Vektor2D<T> alia) const { eligu Vektor2D<T>(x + alia.x, y + alia.y); }
    Vektor2D<T> operator-(const Vektor2D<T> alia) const { eligu Vektor2D<T>(x - alia.x, y - alia.y); }
    Vektor2D<T> operator*(const Vektor2D<T> alia) const { eligu Vektor2D<T>(x * alia.x, y * alia.y); }
    Vektor2D<T> operator/(const Vektor2D<T> alia) const { eligu Vektor2D<T>(x / alia.x, y / alia.y); }
    Vektor2D<T> operator*(const T s) const { eligu Vektor2D<T>(x * s, y * s); }
    Vektor2D<T> operator/(const T s) const { eligu Vektor2D<T>(x / s, y / s); }
    Vektor2D<T> operator%(const T s) const { eligu Vektor2D<T>(x % s, y % s); }
    T skalaranProduton(const Vektor2D<T> alia) const { eligu x * alia.x + y * alia.y; }; //-«
    template<class K> Vektor2D<K> al() const { eligu Vektor2D<K>(ŝanĝu_al<K>(x), ŝanĝu_al<K>(y)); } //»-
    ℚ normon() const { eligu sqrt((ℚ) (x * x + y * y)); }
    Vektor2D<T> dikunNormo(T celnormo) const;

#ifdef ĈU_UZAS_QT
    UZU_SE_(T, ĉu_estas_ℤ<P1>)
    Vektor2D(const QPoint& p) : x(p.x()), y(p.y()) {};
    UZU_SE_(T, ĉu_estas_ℚ_krom_ℤ<P1>)
    Vektor2D(const QPointF& p) : x(p.x()), y(p.y()) {};
    UZU_SE_(T, ĉu_estas_ℤ<P1>)
    operator QPoint() { eligu QPoint(x, y); }
    UZU_SE_(T, ĉu_estas_ℚ_krom_ℤ<P1>)
    operator QPointF() { eligu QPointF(x, y); }
#endif

    T x, y;
    TORENTU { torento & x & y; }
};

template<class T>
class Vektor
{
public:
    struct Ordiganto
    {
        Buleo operator()(const Vektor<T>& a, const Vektor<T>& b) const
        {
            eligu a.x < b.x aŭ (a.x == b.x kaj (a.y < b.y aŭ (a.y == b.y kaj a.z < b.z)));
        }
    };

    template<class K>
    static Vektor<T> prenuEl(const K& k) { eligu Vektor<T>(k.x, k.y, k.z); };
    Vektor() : x(0), y(0), z(0) {}
    Vektor(T x, T y, T z) : x(x), y(y), z(z) {}
    explicit Vektor(Vektor2D<T> xy, T z = 0) : x(xy.x), y(xy.y), z(z) {} //-«
    Buleo operator==(const Vektor<T> alia) const { eligu x == alia.x && y == alia.y && z == alia.z; }
    Buleo operator!=(const Vektor<T> alia) const { eligu x != alia.x || y != alia.y || z != alia.z; }
    Nenio operator+=(const Vektor<T> alia) { x += alia.x; y += alia.y; z += alia.z; }
    Nenio operator-=(const Vektor<T> alia) { x -= alia.x; y -= alia.y; z -= alia.z; } //»-
    Vektor<T> operator+(const Vektor<T> alia) const { eligu Vektor<T>(x + alia.x, y + alia.y, z + alia.z); }
    Vektor<T> operator-(const Vektor<T> alia) const { eligu Vektor<T>(x - alia.x, y - alia.y, z - alia.z); }
    Vektor<T> operator*(const T s) const { eligu Vektor<T>(x * s, y * s, z * s); }
    Vektor<T> operator/(const T s) const { eligu Vektor<T>(x / s, y / s, z / s); }
    T skalaranProduton(const Vektor<T> alia) const { eligu x * alia.x + y * alia.y + z * alia.z; }; // -«
    Vektor<T> ortanProduton(const Vektor<T> a) const { eligu {y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x};}
    template<class K> Vektor<K> al() const { eligu Vektor<K>(ŝanĝu_al<K>(x), ŝanĝu_al<K>(y), ŝanĝu_al<K>(z)); }
    Vektor2D<T> xy() const { eligu Vektor2D<T>(x, y); }
    ℚ normon() const { eligu sqrt((ℚ)(x * x + y * y + z * z)); }
    Vektor<T> dikunNormo(T celnormo) const { premisu (normon() != 0); eligu (*this * celnormo) / normon(); } //»-

    T x, y, z;
    TORENTU { torento & x & y & z; }
};

//-«
template <class K> const Vektor2D<K> nulvektor2D = Vektor2D<K>(0, 0);
template <class K> const Vektor<K> nulvektor = Vektor<K>(0, 0, 0);
template <class K> const Vektor2D<K> nenie2D = Vektor2D<K>(maximumDe<K>, maximumDe<K>);
template <class K> const Vektor<K> nenie = Vektor<K>(maximumDe<K>, maximumDe<K>, maximumDe<K>);

template <class K> Vektor<K> operator*(const K s, Vektor<K> v) { eligu v * s; }
template <class K> Vektor2D<K> operator*(const K s, Vektor2D<K> v) { eligu v * s; }//»-

typedef Vektor<ℕ2> BazaKoordinato;
typedef Vektor2D<ℕ2> BazaKoordinato2D;
//typedef Vektor<FiksitaKomo<ℕ4, pow(2, bitojDen<ℕ4> - bitojDen<ℕ2>)>> BazaSubkoordinato;

template<class K>
Vektor2D<K> Vektor2D<K>::dikunNormo(K celnormo) const
{
    premisu (*this != nulvektor2D<K>);
    eligu (*this * celnormo) / (K) normon();
}

#endif //KOMUNA_VEKTORO_HPP

max_stars_repo_name: cnsuhao/wortserchilo

max_issues_repo_name: cnsuhao/wortserchilo

max_forks_repo_name: cnsuhao/wortserchilo


text:
// Shasta.
#include "DynamicConflictReadGraph.hpp"
using namespace shasta;

// Boost libraries.
#include <boost/graph/iteration_macros.hpp>

// Standard library.
#include "fstream.hpp"

DynamicConflictReadGraph::DynamicConflictReadGraph(const ConflictReadGraph& conflictReadGraph)
{
    DynamicConflictReadGraph& graph = *this;

    // Create the vertices.
    vector<vertex_descriptor> vertexTable;
    for(VertexId vertexId=0; vertexId<conflictReadGraph.vertices.size(); vertexId++) {
        const vertex_descriptor v = boost::add_vertex(DynamicConflictReadGraphVertex(vertexId), graph);
        vertexTable.push_back(v);
    }

    // Create the edges.
    for(EdgeId edgeId=0; edgeId<conflictReadGraph.edges.size(); edgeId++) {
        const VertexId vertexId0 = conflictReadGraph.v0(edgeId);
        const VertexId vertexId1 = conflictReadGraph.v1(edgeId);
        const vertex_descriptor v0 = vertexTable[vertexId0];
        const vertex_descriptor v1 = vertexTable[vertexId1];
        boost::add_edge(v0, v1, DynamicConflictReadGraphEdge(edgeId), graph);
    }
}

void DynamicConflictReadGraph::writeGraphviz(const string& fileName) const
{
    ofstream file(fileName);
    writeGraphviz(file);
}
void DynamicConflictReadGraph::writeGraphviz(ostream& s) const
{
    s << "graph G{\n";

    const auto& graph = *this;
    BGL_FORALL_VERTICES(v, graph, DynamicConflictReadGraph) {
        writeGraphviz(s, v);
    }
    BGL_FORALL_EDGES(E, graph, DynamicConflictReadGraph) {
        writeGraphviz(s, E);
    }

    s << "}\n";
}

void DynamicConflictReadGraph::writeGraphviz(ostream& s, vertex_descriptor v) const
{
    const auto& graph = *this;
    const auto& vertex = graph[v];
    const OrientedReadId orientedReadId = vertex.getOrientedReadId();

    s << "\"" << orientedReadId << "\"";
    s << "[";

    // Tooltip.
    s << "tooltip=\"" << orientedReadId;
    if(vertex.isColored()) {
        s << " component " << vertex.componentId << " color " << vertex.color;
    }
    s << "\"";

    // Color.
    if(vertex.isColored()) {
        const string color = "/set18/" + to_string(1 + vertex.color%8);
        s << " style=filled";
        s << " color=\"" << color << "\"";
        s << " fillcolor=\"" << color << "\"";
    }

    s << "];\n";
}

void DynamicConflictReadGraph::writeGraphviz(ostream& s, edge_descriptor e) const
{
    const auto& graph = *this;
    const vertex_descriptor v0 = source(e, graph);
    const vertex_descriptor v1 = target(e, graph);

    s << "\"" << graph[v0].getOrientedReadId() << "\"--\"" <<
        graph[v1].getOrientedReadId() << "\";\n";
}

max_stars_repo_name: yatisht/shasta

max_issues_repo_name: yatisht/shasta

max_forks_repo_name: yatisht/shasta


text:
#ifndef BPNN_H
#define BPNN_H

#include <Eigen/Dense>

#include <vector>
#include <iostream>
#include <string>
#include <cstdio>
#include <cmath>
#include <random>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <gsl/gsl_assert>

namespace Jacobian {
#define BUFFER_SIZE 600*1024
#define LARGE_BUF 600*1024*15
enum class Regularization {L1, L2};

class Layer {
public:
	Eigen::MatrixXf contents;
	Eigen::MatrixXf weights;
	Eigen::MatrixXf bias;
	Eigen::MatrixXf dZ;
	Eigen::MatrixXf v;
	Eigen::MatrixXf m;
	std::function<float(float)> activation;
	std::function<float(float)> activation_deriv;

	Layer(int rows, int columns);
	Layer(float* vals, int rows, int columns);
	void operator=(const Layer& that);
	void init_weights(Layer next);

};

class Network {
	char buf[BUFFER_SIZE];
	char* p;
protected:
	int instances;
	float epoch_acc;
	float epoch_cost;
	float val_acc;
	float val_cost;
	std::function<void(float&)> decay;
	std::function<void(std::vector<Eigen::MatrixXf>, int, int)> grad_calc;
	std::function<void(Layer&, Eigen::MatrixXf, float)> update;
	void next_batch(int fd);
public:
	int data;
	int val_data;
	int val_instances;
	int test_instances;
	std::vector<Layer> layers;
	int length = 0;
	int batch_size;
	float learning_rate;
	float bias_lr;
	Regularization reg_type;
	float lambda;
	bool early_stop;
	float threshold;
	bool silenced = false;
	int epochs = 0;
	int batches = 0;
	Eigen::MatrixXf* labels;

	Network(const char* path, int batch_sz, float learn_rate,
			float bias_rate, Regularization regularization,
			float l, float ratio, bool early_exit=true, float cutoff=0);
	~Network();
	void add_layer(int nodes, std::function<float(float)> activation, std::function<float(float)> activation_deriv);
	void initialize();
	void init_optimizer(std::function<void(Layer &, Eigen::MatrixXf, float)> f)
	{
		update = f;
	};
	void init_decay(std::function<void(float&)> f);
	void set_activation(int index, std::function<float(float)> custom, std::function<float(float)> custom_deriv);
	void feedforward();
	void softmax();
	void list_net();
	void interactive_next_batch();
	float cost();
	float accuracy();
	Eigen::MatrixXf backpropagate();
	void validate(const char* path);
	void train();
	float get_acc() {return epoch_acc;}
	float get_val_acc() {return val_acc;}
	float get_cost() {return epoch_cost;}
	float get_val_cost()
	{
		return val_cost;
	}
};

int prep_file(const char *path, const char *out_path);
int split_file(const char *path, int lines, float ratio);

void prep(const char *rname, const char *wname);
void compress(const char *rname, const char *wname);
Eigen::MatrixXf l1_deriv(Eigen::MatrixXf m);

#define MAXLINE 1024

#if (!RECKLESS)
#define checknan(x, loc)                                                       \
	if (x == INFINITY || x == NAN || x == -INFINITY)                       \
	throw ValueError("Detected NaN in operation", loc)
#define Expects(cond) assert(cond);
#define Ensures(cond) assert(cond);
#else
#define checknan(x, loc)
#define Expects(cond) GSL_ASSUME(cond);
#define Ensures(cond) GSL_ASSUME(cond);
#endif

#define SHUFFLED_PATH "./shuffled.txt"
#define VAL_PATH "./test.txt"
#define TRAIN_PATH "./train.txt"
#define VAL_BIN_PATH "./test.bin"
#define TRAIN_BIN_PATH "./train.bin"

}
#endif /* MODULE_H */

max_stars_repo_name: richardfeynmanrocks/ml-in-parallel

max_issues_repo_name: quantumish/Jacobian

max_forks_repo_name: quantumish/Jacobian


text:
// Copyright (c) 2014-2020 Daniel Kraft
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <base58.h>
#include <chainparams.h>
#include <core_io.h>
#include <init.h>
#include <key_io.h>
#include <names/common.h>
#include <names/main.h>
#include <primitives/transaction.h>
#include <rpc/names.h>
#include <rpc/server.h>
#include <script/names.h>
#include <txmempool.h>
#include <index/txindex.h>
#include <util/strencodings.h>
#include <validation.h>
#ifdef ENABLE_WALLET
#include <wallet/rpcwallet.h>
#include <wallet/wallet.h>
#endif

#include <univalue.h>

#include <boost/xpressive/xpressive_dynamic.hpp>

#include <algorithm>
#include <cassert>
#include <memory>
#include <stdexcept>

namespace {

NameEncoding
EncodingFromOptionsJson(const UniValue& options, const std::string& field, const NameEncoding defaultValue)
{
    NameEncoding res = defaultValue;
    RPCTypeCheckObj(options,
        {
            {field, UniValueType(UniValue::VSTR)},
        },
        true, false);
    if (options.exists(field))
        try {
            res = EncodingFromString(options[field].get_str());
        } catch (const std::invalid_argument& exc) {
            LogPrintf("Invalid value for %s in options: %s\n  using default %s\n",
                field, exc.what(), EncodingToString(defaultValue));
        }

    return res;
}

} // anonymous namespace

/**
 * Utility routine to construct a "name info" object to return.  This is used
 * for name_show and also name_list.
 */
UniValue
getNameInfo(const UniValue& options,
    const valtype& name,
    const valtype& value,
    const COutPoint& outp,
    const CScript& addr)
{
    UniValue obj(UniValue::VOBJ);
    AddEncodedNameToUniv(obj, "name", name, EncodingFromOptionsJson(options, "nameEncoding", ConfiguredNameEncoding()));
    AddEncodedNameToUniv(obj, "value", value,
        EncodingFromOptionsJson(options, "valueEncoding",
            ConfiguredValueEncoding()));
    obj.pushKV("txid", outp.hash.GetHex());
    obj.pushKV("vout", static_cast<int>(outp.n));

    /* Try to extract the address.  May fail if we can't parse the script
     as a "standard" script.  */
    CTxDestination dest;
    std::string addrStr;
    if (ExtractDestination(addr, dest))
        addrStr = EncodeDestination(dest);
    else
        addrStr = "<nonstandard>";
    obj.pushKV("address", addrStr);

    return obj;
}

/**
 * Return name info object for a CNameData object.
 */
UniValue
getNameInfo(const UniValue& options,
    const valtype& name,
    const CNameData& data)
{
    UniValue result = getNameInfo(options,
        name, data.getValue(),
        data.getUpdateOutpoint(),
        data.getAddress());
    addExpirationInfo(data.getHeight(), result);
    return result;
}

/**
 * Adds expiration information to the JSON object, based on the last-update
 * height for the name given.
 */
void addExpirationInfo(const int height, UniValue& data)
{
    const int curHeight = ::ChainActive().Height();
    const Consensus::Params& params = Params().GetConsensus();
    const int expireDepth = params.rules->NameExpirationDepth(curHeight);
    const int expireHeight = height + expireDepth;
    const int expiresIn = expireHeight - curHeight;
    const bool expired = (expiresIn <= 0);
    data.pushKV("height", height);
    data.pushKV("expires_in", expiresIn);
    data.pushKV("expired", expired);
}

#ifdef ENABLE_WALLET
/**
 * Adds the "ismine" field giving ownership info to the JSON object.
 */
void addOwnershipInfo(const CScript& addr, const CWallet* pwallet, UniValue& data)
{
    if (pwallet == nullptr)
        return;

    AssertLockHeld(pwallet->cs_wallet);
    const isminetype mine = pwallet->IsMine(addr);
    const bool isMine = (mine & ISMINE_SPENDABLE);
    data.pushKV("ismine", isMine);
}
#endif

namespace {

void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
{
    // Call into TxToUniv() in bitcoin-common to decode the transaction hex.
    //
    // Blockchain contextual information (confirmations and blocktime) is not
    // available to code in bitcoin-common, so we query them here and push the
    // data into the returned UniValue.
    TxToUniv(tx, uint256(), entry, true, RPCSerializationFlags());

    if (!hashBlock.IsNull()) {
        LOCK(cs_main);

        entry.pushKV("blockhash", hashBlock.GetHex());
        CBlockIndex* pindex = LookupBlockIndex(hashBlock);
        if (pindex) {
            if (::ChainActive().Contains(pindex)) {
                entry.pushKV("confirmations", 1 + ::ChainActive().Height() - pindex->nHeight);
                entry.pushKV("time", pindex->GetBlockTime());
                entry.pushKV("blocktime", pindex->GetBlockTime());
            }
            else
                entry.pushKV("confirmations", 0);
        }
    }
}

valtype
DecodeNameValueFromRPCOrThrow(const UniValue& val, const UniValue& opt, const std::string& optKey, const NameEncoding defaultEnc)
{
    const NameEncoding enc = EncodingFromOptionsJson(opt, optKey, defaultEnc);
    try {
        return DecodeName(val.get_str(), enc);
    } catch (const InvalidNameString& exc) {
        std::ostringstream msg;
        msg << "Name/value is invalid for encoding " << EncodingToString(enc);
        throw JSONRPCError(RPC_NAME_INVALID_ENCODING, msg.str());
    }
}

} // anonymous namespace

valtype
DecodeNameFromRPCOrThrow(const UniValue& val, const UniValue& opt)
{
    return DecodeNameValueFromRPCOrThrow(val, opt, "nameEncoding",
        ConfiguredNameEncoding());
}

valtype
DecodeValueFromRPCOrThrow(const UniValue& val, const UniValue& opt)
{
    return DecodeNameValueFromRPCOrThrow(val, opt, "valueEncoding",
        ConfiguredValueEncoding());
}

void pushTimestampOfDataTx(const CNameData entry, bool f_txindex_ready, UniValue& resRecord, const std::string keyName) {
    CTransactionRef tx;
    uint256 hash_block;
    if (!GetTransaction(entry.getUpdateOutpoint().hash, tx, Params().GetConsensus(), hash_block, nullptr)) {
        std::string errmsg;
        if (!g_txindex) {
            errmsg = "No such mempool transaction. Use -txindex or provide a block hash to enable blockchain transaction queries";
        } else if (!f_txindex_ready) {
            errmsg = "No such mempool transaction. Blockchain transactions are still in the process of being indexed";
        } else {
            errmsg = "No such mempool or blockchain transaction";
        }
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, errmsg + ". Use gettransaction for wallet transactions.");
    }
    UniValue resTx(UniValue::VOBJ);
    TxToJSON(*tx, hash_block, resTx);
    resRecord.pushKV(keyName, resTx["time"].get_int());
}

namespace {

/**
 * Helper class that extracts the wallet for the current RPC request, if any.
 * It handles the case of disabled wallet support or no wallet being present,
 * so that it is suitable for the non-wallet RPCs here where we just want to
 * provide optional extra features (like the "ismine" field).
 *
 * The main benefit of having this class is that we can easily LOCK2 with the
 * wallet and another lock we need, without having to care about the special
 * cases where no wallet is present or wallet support is disabled.
 */
class MaybeWalletForRequest
{
private:
#ifdef ENABLE_WALLET
    std::shared_ptr<CWallet> wallet;
#endif

public:
    explicit MaybeWalletForRequest(const JSONRPCRequest& request)
    {
#ifdef ENABLE_WALLET
        wallet = GetWalletForJSONRPCRequest(request);
#endif
    }

    RecursiveMutex*
    getLock() const
    {
#ifdef ENABLE_WALLET
        return (wallet != nullptr ? &wallet->cs_wallet : nullptr);
#else
        return nullptr;
#endif
    }

#ifdef ENABLE_WALLET
    CWallet*
    getWallet()
    {
        return wallet.get();
    }

    const CWallet*
    getWallet() const
    {
        return wallet.get();
    }
#endif
};

/**
 * Variant of addOwnershipInfo that uses a MaybeWalletForRequest.  This takes
 * care of disabled wallet support.
 */
void addOwnershipInfo(const CScript& addr, const MaybeWalletForRequest& wallet, UniValue& data)
{
#ifdef ENABLE_WALLET
    addOwnershipInfo(addr, wallet.getWallet(), data);
#endif
}

/**
 * Utility variant of getNameInfo that already includes ownership information.
 * This is the most common call for methods in this file.
 */
UniValue
getNameInfo(const UniValue& options,
    const valtype& name,
    const CNameData& data,
    const MaybeWalletForRequest& wallet)
{
    UniValue res = getNameInfo(options, name, data);
    addOwnershipInfo(data.getAddress(), wallet, res);
    return res;
}

} // anonymous namespace

/* ************************************************************************** */

NameInfoHelp::NameInfoHelp()
{
    withField({RPCResult::Type::STR, "name", "the requested name"});
    withField({RPCResult::Type::STR, "name_encoding", "the encoding of \"name\""});
    withField({RPCResult::Type::STR, "name_error",
        "replaces \"name\" in case there is an error"});
    withField({RPCResult::Type::STR, "value", "the name's current value"});
    withField({RPCResult::Type::STR, "value_encoding", "the encoding of \"value\""});
    withField({RPCResult::Type::STR, "value_error",
        "replaces \"value\" in case there is an error"});

    withField({RPCResult::Type::STR_HEX, "txid", "the name's last update tx"});
    withField({RPCResult::Type::NUM, "vout",
        "the index of the name output in the last update"});
    withField({RPCResult::Type::STR, "address", "the address holding the name"});
#ifdef ENABLE_WALLET
    withField({RPCResult::Type::BOOL, "ismine",
        "whether the name is owned by the wallet"});
#endif
}

NameInfoHelp&
NameInfoHelp::withExpiration()
{
    withField({RPCResult::Type::NUM, "height", "the name's last update height"});
    withField({RPCResult::Type::NUM, "expires_in", "expire counter for the name"});
    withField({RPCResult::Type::BOOL, "expired", "whether the name is expired"});
    return *this;
}

NameOptionsHelp::NameOptionsHelp()
{
}

NameOptionsHelp&
NameOptionsHelp::withArg(const std::string& name, const RPCArg::Type type, const std::string& doc)
{
    return withArg(name, type, "", doc);
}

NameOptionsHelp&
NameOptionsHelp::withArg(const std::string& name, const RPCArg::Type type, const std::string& defaultValue, const std::string& doc)
{
    if (defaultValue.empty())
        innerArgs.push_back(RPCArg(name, type, RPCArg::Optional::OMITTED, doc));
    else
        innerArgs.push_back(RPCArg(name, type, defaultValue, doc));

    return *this;
}

NameOptionsHelp&
NameOptionsHelp::withWriteOptions()
{
    withArg("destAddress", RPCArg::Type::STR,
        "The address to send the name output to");

    withArg("sendCoins", RPCArg::Type::OBJ_USER_KEYS,
        "Addresses to which coins should be sent additionally");

    return *this;
}

NameOptionsHelp&
NameOptionsHelp::withNameEncoding()
{
    withArg("nameEncoding", RPCArg::Type::STR,
        "Encoding (\"ascii\", \"utf8\" or \"hex\") of the name argument");
    return *this;
}

NameOptionsHelp&
NameOptionsHelp::withValueEncoding()
{
    withArg("valueEncoding", RPCArg::Type::STR,
        "Encoding (\"ascii\", \"utf8\" or \"hex\") of the value argument");
    return *this;
}

RPCArg
NameOptionsHelp::buildRpcArg() const
{
    return RPCArg("options", RPCArg::Type::OBJ,
        RPCArg::Optional::OMITTED_NAMED_ARG,
        "Options for this RPC call",
        innerArgs, "options");
}

/* ************************************************************************** */
namespace {

UniValue
name_show(const JSONRPCRequest& request)
{
    NameOptionsHelp optHelp;
    optHelp
        .withNameEncoding()
        .withValueEncoding();

    RPCHelpMan("name_show",
        "\nLooks up the current data for the given name.  Fails if the name doesn't exist.\n",
        {
            {"name", RPCArg::Type::STR, RPCArg::Optional::NO, "The name to query for"},
            optHelp.buildRpcArg(),
        },
        NameInfoHelp()
            .withExpiration()
            .finish(),
        RPCExamples{
            HelpExampleCli("name_show", "\"myname\"") + HelpExampleRpc("name_show", "\"myname\"")})
        .Check(request);

    RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});

    if (::ChainstateActive().IsInitialBlockDownload())
        throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD,
            "Namecoin is downloading blocks...");

    UniValue options(UniValue::VOBJ);
    if (request.params.size() >= 2)
        options = request.params[1].get_obj();

    const valtype name = DecodeNameFromRPCOrThrow(request.params[0], options);

    CNameData data;
    {
        LOCK(cs_main);
        if (!::ChainstateActive().CoinsTip().GetName(name, data)) {
            std::ostringstream msg;
            msg << "name not found: " << EncodeNameForMessage(name);
            throw JSONRPCError(RPC_WALLET_ERROR, msg.str());
        }
    }

    MaybeWalletForRequest wallet(request);
    LOCK(wallet.getLock());
    return getNameInfo(options, name, data, wallet);
}

/* ************************************************************************** */

UniValue
name_history(const JSONRPCRequest& request)
{
    NameOptionsHelp optHelp;
    optHelp
        .withNameEncoding()
        .withValueEncoding();

    RPCHelpMan("name_history",
        "\nLooks up the current and all past data for the given name.  -namehistory must be enabled.\n",
        {
            {"name", RPCArg::Type::STR, RPCArg::Optional::NO, "The name to query for"},
            optHelp.buildRpcArg(),
        },
        RPCResult{RPCResult::Type::ARR, "", "",
            {NameInfoHelp()
                    .withExpiration()
                    .finish()}},
        RPCExamples{
            HelpExampleCli("name_history", "\"myname\"") + HelpExampleRpc("name_history", "\"myname\"")})
        .Check(request);

    RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});

    if (!fNameHistory)
        throw std::runtime_error("-namehistory is not enabled");

    if (::ChainstateActive().IsInitialBlockDownload())
        throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD,
            "Namecoin is downloading blocks...");

    UniValue options(UniValue::VOBJ);
    if (request.params.size() >= 2)
        options = request.params[1].get_obj();

    const valtype name = DecodeNameFromRPCOrThrow(request.params[0], options);

    CNameData data;
    CNameHistory history;

    {
        LOCK(cs_main);

        const auto& coinsTip = ::ChainstateActive().CoinsTip();
        if (!coinsTip.GetName(name, data)) {
            std::ostringstream msg;
            msg << "name not found: " << EncodeNameForMessage(name);
            throw JSONRPCError(RPC_WALLET_ERROR, msg.str());
        }

        if (!coinsTip.GetNameHistory(name, history))
            assert(history.empty());
    }

    MaybeWalletForRequest wallet(request);
    LOCK(wallet.getLock());

    UniValue res(UniValue::VARR);
    for (const auto& entry : history.getData())
        res.push_back(getNameInfo(options, name, entry, wallet));
    res.push_back(getNameInfo(options, name, data, wallet));

    return res;
}

/* ************************************************************************** */

UniValue
name_scan(const JSONRPCRequest& request)
{
    NameOptionsHelp optHelp;
    optHelp
        .withNameEncoding()
        .withValueEncoding()
        .withArg("minConf", RPCArg::Type::NUM, "1",
            "Minimum number of confirmations")
        .withArg("maxConf", RPCArg::Type::NUM,
            "Maximum number of confirmations")
        .withArg("prefix", RPCArg::Type::STR,
            "Filter for names with the given prefix")
        .withArg("regexp", RPCArg::Type::STR,
            "Filter for names matching the regexp");

    RPCHelpMan("name_scan",
        "\nLists names in the database.\n",
        {
            {"start", RPCArg::Type::STR, "", "Skip initially to this name"},
            {"count", RPCArg::Type::NUM, "500", "Stop after this many names"},
            optHelp.buildRpcArg(),
        },
        RPCResult{RPCResult::Type::ARR, "", "",
            {NameInfoHelp()
                    .withExpiration()
                    .finish()}},
        RPCExamples{
            HelpExampleCli("name_scan", "") + HelpExampleCli("name_scan", "\"d/abc\"") + HelpExampleCli("name_scan", "\"d/abc\" 10") + HelpExampleRpc("name_scan", "\"d/abc\"")})
        .Check(request);

    RPCTypeCheck(request.params,
        {UniValue::VSTR, UniValue::VNUM, UniValue::VOBJ});

    if (::ChainstateActive().IsInitialBlockDownload())
        throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD,
            "Namecoin is downloading blocks...");

    UniValue options(UniValue::VOBJ);
    if (request.params.size() >= 3)
        options = request.params[2].get_obj();

    valtype start;
    if (request.params.size() >= 1)
        start = DecodeNameFromRPCOrThrow(request.params[0], options);

    int count = 500;
    if (request.params.size() >= 2)
        count = request.params[1].get_int();

    /* Parse and interpret the name_scan-specific options.  */
    RPCTypeCheckObj(options,
        {
            {"minConf", UniValueType(UniValue::VNUM)},
            {"maxConf", UniValueType(UniValue::VNUM)},
            {"prefix", UniValueType(UniValue::VSTR)},
            {"regexp", UniValueType(UniValue::VSTR)},
        },
        true, false);

    int minConf = 1;
    if (options.exists("minConf"))
        minConf = options["minConf"].get_int();
    if (minConf < 1)
        throw JSONRPCError(RPC_INVALID_PARAMETER, "minConf must be >= 1");

    int maxConf = -1;
    if (options.exists("maxConf")) {
        maxConf = options["maxConf"].get_int();
        if (maxConf < 0)
            throw JSONRPCError(RPC_INVALID_PARAMETER,
                "maxConf must not be negative");
    }

    valtype prefix;
    if (options.exists("prefix"))
        prefix = DecodeNameFromRPCOrThrow(options["prefix"], options);

    bool haveRegexp = false;
    boost::xpressive::sregex regexp;
    if (options.exists("regexp")) {
        haveRegexp = true;
        regexp = boost::xpressive::sregex::compile(options["regexp"].get_str());
    }

    /* Iterate over names and produce the result.  */
    UniValue res(UniValue::VARR);
    if (count <= 0)
        return res;

    MaybeWalletForRequest wallet(request);
    LOCK2(cs_main, wallet.getLock());

    const int maxHeight = ::ChainActive().Height() - minConf + 1;
    int minHeight = -1;
    if (maxConf >= 0)
        minHeight = ::ChainActive().Height() - maxConf + 1;

    valtype name;
    CNameData data;
    const auto& coinsTip = ::ChainstateActive().CoinsTip();
    std::unique_ptr<CNameIterator> iter(coinsTip.IterateNames());
    for (iter->seek(start); count > 0 && iter->next(name, data);) {
        const int height = data.getHeight();
        if (height > maxHeight)
            continue;
        if (minHeight >= 0 && height < minHeight)
            continue;

        if (name.size() < prefix.size())
            continue;
        if (!std::equal(prefix.begin(), prefix.end(), name.begin()))
            continue;

        if (haveRegexp) {
            try {
                const std::string nameStr = EncodeName(name, NameEncoding::UTF8);
                boost::xpressive::smatch matches;
                if (!boost::xpressive::regex_search(nameStr, matches, regexp))
                    continue;
            } catch (const InvalidNameString& exc) {
                continue;
            }
        }

        res.push_back(getNameInfo(options, name, data, wallet));
        --count;
    }

    return res;
}
/* ************************************************************************** */

UniValue
name_export(const JSONRPCRequest& request)
{
    NameOptionsHelp optHelp;
    optHelp
        .withArg("withHistory", RPCArg::Type::BOOL, "false",
            "Should export with name history?")
        .withArg("count", RPCArg::Type::NUM, "-1",
            "Number of names to export (-1 means all names)");

    RPCHelpMan("name_export",
        "\nExport names from a given namespace to the given file.\n",
        {
            {"regexp", RPCArg::Type::STR, RPCArg::Optional::NO, "Namespace to be exported"},
            {"path", RPCArg::Type::STR, RPCArg::Optional::NO, "Path to the export file"},
            optHelp.buildRpcArg(),
        },
        RPCResult{RPCResult::Type::STR, "", "number of exported names"},
        RPCExamples{
            HelpExampleCli("name_export", "\"^d\\/.+\" /path/to/export/file") + HelpExampleRpc("name_export", "\"^d\\/.+\" /path/to/export/file")})
        .Check(request);

    if (::ChainstateActive().IsInitialBlockDownload())
        throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD,
            "Namecoin is downloading blocks...");

    RPCTypeCheck(request.params,
        {UniValue::VSTR, UniValue::VSTR, UniValue::VOBJ});

    if (::ChainstateActive().IsInitialBlockDownload())
        throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD,
            "Namecoin is downloading blocks...");

    UniValue options(UniValue::VOBJ);
    if (request.params.size() >= 3)
        options = request.params[2].get_obj();

    boost::xpressive::sregex regexp;
    std::string regexpStr;
    if (request.params.size() >= 1) {
        regexpStr = request.params[0].get_str();
        regexp = boost::xpressive::sregex::compile(regexpStr);
    }

    std::string path;
    if (request.params.size() >= 2)
        path = request.params[1].get_str();

    bool withHistory = false;
    if (options.exists("withHistory"))
        withHistory = options["withHistory"].get_bool();

     if (withHistory && !fNameHistory)
        throw std::runtime_error("-namehistory is not enabled");

    int maxCount = -1;
    if (options.exists("count"))
        maxCount = options["count"].get_int();

    MaybeWalletForRequest wallet(request);
    LOCK2(cs_main, wallet.getLock());

    valtype name;
    int count = 0;
    CNameData data;
    std::ofstream outfile;
    outfile.open(path);
    outfile << "[" << std::endl;
    const auto& coinsTip = ::ChainstateActive().CoinsTip();
    std::unique_ptr<CNameIterator> iter(coinsTip.IterateNames());
    while (iter->next(name, data)) {
        try {
            const std::string nameStr = EncodeName(name, NameEncoding::UTF8);
            boost::xpressive::smatch matches;
            if (!boost::xpressive::regex_search(nameStr, matches, regexp))
                continue;
            if (withHistory) {
                bool f_txindex_ready = false;
                if (g_txindex) {
                    f_txindex_ready = g_txindex->BlockUntilSyncedToCurrentChain();
                }

                UniValue resObj = getNameInfo(options, name, data, wallet);
                pushTimestampOfDataTx(data, f_txindex_ready, resObj, "last_updated");
                UniValue resHistory(UniValue::VARR);

                CNameHistory history;
                if (!coinsTip.GetNameHistory(name, history))
                     assert(history.empty());
                for (const auto& entry : history.getData()) {
                    UniValue resRecord = getNameInfo(options, name, entry, wallet);
                    pushTimestampOfDataTx(entry, f_txindex_ready, resRecord, "time");
                    resHistory.push_back(resRecord);
                }
                resObj.pushKV("history", resHistory);
                if (count == 0) {
                    outfile << resObj.write();
                } else {
                    outfile  << ',' << resObj.write();
                }

            } else {
                UniValue resultString(UniValue::VType::VSTR);
                resultString.setStr(nameStr);
                if (count == 0) {
                    outfile << resultString.write();
                } else {
                    outfile  << ',' << std::endl << resultString.write();
                }
            }
            count++;
            LogPrintf("Handling %d: '%s' \n", count, nameStr);
            if (maxCount != -1 && count >= maxCount)
                break;

        } catch (const InvalidNameString& exc) {
            continue;
        }
    }
    outfile << std::endl << "]";
    outfile.close();

    UniValue res(UniValue::VSTR);
    std::stringstream ss;
    ss << "Found " << count << " names with \"" << regexpStr << "\" regexp";
    res.setStr(ss.str());
    LogPrintf("Found %d names with %s regexp. Options: %s \n", count, regexpStr, options.write());
    return res;
} // namespace

/* ************************************************************************** */

UniValue
name_pending(const JSONRPCRequest& request)
{
    NameOptionsHelp optHelp;
    optHelp
        .withNameEncoding()
        .withValueEncoding();

    RPCHelpMan("name_pending",
        "\nLists unconfirmed name operations in the mempool.\n"
        "\nIf a name is given, only check for operations on this name.\n",
        {
            {"name", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Only look for this name"},
            optHelp.buildRpcArg(),
        },
        RPCResult{RPCResult::Type::ARR, "", "",
            {NameInfoHelp()
                    .withField({RPCResult::Type::STR, "op", "the operation being performed"})
                    .withExpiration()
                    .finish()}},
        RPCExamples{
            HelpExampleCli("name_pending", "") + HelpExampleCli("name_pending", "\"d/domob\"") + HelpExampleRpc("name_pending", "")})
        .Check(request);

    RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ}, true);

    MaybeWalletForRequest wallet(request);
    LOCK2(wallet.getLock(), mempool.cs);

    UniValue options(UniValue::VOBJ);
    if (request.params.size() >= 2)
        options = request.params[1].get_obj();

    std::vector<uint256> txHashes;
    mempool.queryHashes(txHashes);

    const bool hasNameFilter = !request.params[0].isNull();
    valtype nameFilter;
    if (hasNameFilter)
        nameFilter = DecodeNameFromRPCOrThrow(request.params[0], options);

    UniValue arr(UniValue::VARR);
    for (const auto& txHash : txHashes) {
        std::shared_ptr<const CTransaction> tx = mempool.get(txHash);
        if (!tx || !tx->IsNamecoin())
            continue;

        for (size_t n = 0; n < tx->vout.size(); ++n) {
            const auto& txOut = tx->vout[n];
            const CNameScript op(txOut.scriptPubKey);
            if (!op.isNameOp() || !op.isAnyUpdate())
                continue;
            if (hasNameFilter && op.getOpName() != nameFilter)
                continue;

            UniValue obj = getNameInfo(options,
                op.getOpName(), op.getOpValue(),
                COutPoint(tx->GetHash(), n),
                op.getAddress());
            addOwnershipInfo(op.getAddress(), wallet, obj);
            switch (op.getNameOp()) {
            case OP_NAME_FIRSTUPDATE:
                obj.pushKV("op", "name_firstupdate");
                break;
            case OP_NAME_UPDATE:
                obj.pushKV("op", "name_update");
                break;
            default:
                assert(false);
            }

            arr.push_back(obj);
        }
    }

    return arr;
}

/* ************************************************************************** */

UniValue
namerawtransaction(const JSONRPCRequest& request)
{
    RPCHelpMan("namerawtransaction",
        "\nAdds a name operation to an existing raw transaction.\n"
        "\nUse createrawtransaction first to create the basic transaction, including the required inputs and outputs also for the name.\n",
        {
            {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction hex string"},
            {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The vout of the desired name output"},
            {"nameop", RPCArg::Type::OBJ, RPCArg::Optional::NO, "The name operation to create",
                {
                    {"op", RPCArg::Type::STR, RPCArg::Optional::NO, "The operation to perform, can be \"name_new\", \"name_firstupdate\" and \"name_update\""},
                    {"name", RPCArg::Type::STR, RPCArg::Optional::NO, "The name to operate on"},
                    {"value", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "The new value for the name"},
                    {"rand", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "The nonce value to use for registrations"},
                },
                "nameop"},
        },
        RPCResult{
            RPCResult::Type::OBJ,
            "",
            "",
            {
                {RPCResult::Type::STR_HEX, "hex", "Hex string of the updated transaction"},
                {RPCResult::Type::STR_HEX, "rand", /* optional */ true, "If this is a name_new, the nonce used to create it"},
            },
        },
        RPCExamples{
            HelpExampleCli("namerawtransaction", R"("raw tx hex" 1 "{\"op\":\"name_new\",\"name\":\"my-name\")") + HelpExampleCli("namerawtransaction", R"("raw tx hex" 1 "{\"op\":\"name_firstupdate\",\"name\":\"my-name\",\"value\":\"new value\",\"rand\":\"00112233\")") + HelpExampleCli("namerawtransaction", R"("raw tx hex" 1 "{\"op\":\"name_update\",\"name\":\"my-name\",\"value\":\"new value\")") + HelpExampleRpc("namerawtransaction", R"("raw tx hex", 1, "{\"op\":\"name_update\",\"name\":\"my-name\",\"value\":\"new value\")")})
        .Check(request);

    RPCTypeCheck(request.params,
        {UniValue::VSTR, UniValue::VNUM, UniValue::VOBJ});

    CMutableTransaction mtx;
    if (!DecodeHexTx(mtx, request.params[0].get_str(), true))
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
    mtx.SetNamecoin();

    const size_t nOut = request.params[1].get_int();
    if (nOut >= mtx.vout.size())
        throw JSONRPCError(RPC_INVALID_PARAMETER, "vout is out of range");

    const UniValue nameOp = request.params[2].get_obj();
    RPCTypeCheckObj(nameOp,
        {
            {"op", UniValueType(UniValue::VSTR)},
        });
    const std::string op = find_value(nameOp, "op").get_str();

    /* namerawtransaction does not have an options argument.  This would just
     make the already long list of arguments longer.  Instead of using
     namerawtransaction, namecoin-tx can be used anyway to create name
     operations with arbitrary hex data.  */
    const UniValue NO_OPTIONS(UniValue::VOBJ);

    UniValue result(UniValue::VOBJ);

    if (op == "name_new") {
        RPCTypeCheckObj(nameOp,
            {
                {"name", UniValueType(UniValue::VSTR)},
                {"rand", UniValueType(UniValue::VSTR)},
            },
            true);

        valtype rand;
        if (nameOp.exists("rand")) {
            const std::string randStr = find_value(nameOp, "rand").get_str();
            if (!IsHex(randStr))
                throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "rand must be hex");
            rand = ParseHex(randStr);
        } else {
            rand.resize(20);
            GetRandBytes(&rand[0], rand.size());
        }

        const valtype name = DecodeNameFromRPCOrThrow(find_value(nameOp, "name"), NO_OPTIONS);

        mtx.vout[nOut].scriptPubKey = CNameScript::buildNameNew(mtx.vout[nOut].scriptPubKey, name, rand);
        result.pushKV("rand", HexStr(rand.begin(), rand.end()));
    } else if (op == "name_firstupdate") {
        RPCTypeCheckObj(nameOp,
            {
                {"name", UniValueType(UniValue::VSTR)},
                {"value", UniValueType(UniValue::VSTR)},
                {"rand", UniValueType(UniValue::VSTR)},
            });

        const std::string randStr = find_value(nameOp, "rand").get_str();
        if (!IsHex(randStr))
            throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "rand must be hex");
        const valtype rand = ParseHex(randStr);

        const valtype name = DecodeNameFromRPCOrThrow(find_value(nameOp, "name"), NO_OPTIONS);
        const valtype value = DecodeValueFromRPCOrThrow(find_value(nameOp, "value"),
            NO_OPTIONS);

        mtx.vout[nOut].scriptPubKey = CNameScript::buildNameFirstupdate(mtx.vout[nOut].scriptPubKey,
            name, value, rand);
    } else if (op == "name_update") {
        RPCTypeCheckObj(nameOp,
            {
                {"name", UniValueType(UniValue::VSTR)},
                {"value", UniValueType(UniValue::VSTR)},
            });

        const valtype name = DecodeNameFromRPCOrThrow(find_value(nameOp, "name"), NO_OPTIONS);
        const valtype value = DecodeValueFromRPCOrThrow(find_value(nameOp, "value"),
            NO_OPTIONS);

        mtx.vout[nOut].scriptPubKey = CNameScript::buildNameUpdate(mtx.vout[nOut].scriptPubKey,
            name, value);
    } else
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid name operation");

    result.pushKV("hex", EncodeHexTx(CTransaction(mtx)));
    return result;
}

/* ************************************************************************** */

UniValue
name_checkdb(const JSONRPCRequest& request)
{
    RPCHelpMan("name_checkdb",
        "\nValidates the name DB's consistency.\n"
        "\nRoughly between blocks 139,000 and 180,000, this call is expected to fail due to the historic 'name stealing' bug.\n",
        {},
        RPCResult{RPCResult::Type::BOOL, "", "whether the state is valid"},
        RPCExamples{
            HelpExampleCli("name_checkdb", "") + HelpExampleRpc("name_checkdb", "")})
        .Check(request);

    LOCK(cs_main);
    auto& coinsTip = ::ChainstateActive().CoinsTip();
    coinsTip.Flush();
    return coinsTip.ValidateNameDB();
}

} // namespace
/* ************************************************************************** */

static const CRPCCommand commands[] =
    {
        //  category              name                      actor (function)         argNames
        //  --------------------- ------------------------  -----------------------  ----------
        {"names", "name_show", &name_show, {"name", "options"}},
        {"names", "name_history", &name_history, {"name", "options"}},
        {"names", "name_scan", &name_scan, {"start", "count", "options"}},
        {"names", "name_pending", &name_pending, {"name", "options"}},
        {"names", "name_checkdb", &name_checkdb, {}},
        {"rawtransactions", "namerawtransaction", &namerawtransaction, {"hexstring", "vout", "nameop"}},
        {"names", "name_export", &name_export, {"regexp", "path", "options"}},

};

void RegisterNameRPCCommands(CRPCTable& t)
{
    for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
        t.appendCommand(commands[vcidx].name, &commands[vcidx]);
}

max_stars_repo_name: bayerhonza/namecoin-core

max_issues_repo_name: bayerhonza/namecoin-core

max_forks_repo_name: bayerhonza/namecoin-core


text:
// Copyright 2004-present Facebook. All Rights Reserved.

#include "ClockIPC.h"

#define DEFAULT_LOG_CHANNEL "Cthulhu"
#include <logging/Log.h>

#include <boost/thread/thread_time.hpp>

namespace cthulhu {

ClockIPC::ClockIPC(ClockIPCData* data, bool simTime) : data_(data), simTime_(simTime) {}

ClockIPC::~ClockIPC() = default;

double ClockIPC::getTime() {
  if (simTime_) {
    if (!data_->paused)
      // advance time
      updateTime();
    return data_->latestTime;
  }
  return getWallTime();
}

void ClockIPC::updateTime() {
  double reference = data_->latestTime;
  double wall = getWallTime();
  updateLatestTime(
      data_->realtimeFactor * (wall - data_->wallStartTime) + data_->offset, reference);
}

void ClockIPC::updateLatestTime(double desired, double reference, bool enableBackwards) {
  double latest;
  do {
    latest = data_->latestTime;
    if (latest < reference) {
      break;
    }
    if ((enableBackwards && latest == desired) || (!enableBackwards && latest > desired)) {
      break;
    }
  } while (!data_->latestTime.compare_exchange_weak(latest, desired));
}

ControllableClockIPC::ControllableClockIPC(ClockIPCData* data)
    : ClockIPC(data, true), localControl_(false) {
  thread_ = std::thread(
      [this](std::future<void> signal) -> void {
        uint32_t latestEvent = 0;
        while (signal.wait_for(std::chrono::microseconds(0)) == std::future_status::timeout) {
          if (latestEvent < this->data_->signal_count) {
            int eventNumber;
            ClockEvent event;
            {
              ScopedLockIPC lock(this->data_->signal_lock);
              eventNumber = this->data_->signal_count;
              event = this->data_->event;
            }
            for (const auto& listener : this->listeners_) {
              listener(event);
            }
            if (eventNumber != latestEvent + 1) {
              XR_LOGW("ClockIPC - Missed events between {} and {}", latestEvent, eventNumber);
            }
            latestEvent = eventNumber;
          }
          ScopedLockIPC lock(this->data_->signal_lock);
          this->data_->signal_update.timed_wait(
              lock, boost::get_system_time() + boost::posix_time::milliseconds(1));
        }
      },
      stopSignal_.get_future());
}

ControllableClockIPC::~ControllableClockIPC() {
  setControlLocal();
}

void ControllableClockIPC::setControlLocal() {
  if (localControl_) {
    return;
  }
  stopSignal_.set_value();
  if (thread_.joinable()) {
    thread_.join();
  }
  localControl_ = true;
}

bool ControllableClockIPC::start(double time) {
  if (!simTime_) {
    XR_LOGI("Could not start clock, using real time.");
    return false;
  }
  double reference = data_->latestTime;
  if (!data_->paused) {
    XR_LOGI("Could not start clock that is currently running.");
    return false;
  }

  updateLatestTime(time, reference, true);

  data_->wallStartTime = getWallTime();
  if (time >= 0.) {
    data_->offset = time;
    for (const auto& listener : listeners_) {
      listener(ClockEvent::JUMP);
    }
    signalEventIPC(ClockEvent::JUMP);
  } else {
    data_->offset = data_->latestTime;
  }
  data_->paused = false;
  for (const auto& listener : listeners_) {
    listener(ClockEvent::START);
  }
  signalEventIPC(ClockEvent::START);
  return true;
}

void ControllableClockIPC::pause() {
  // sanity checks
  if (!simTime_) {
    XR_LOGI("Could not pause clock, using real time.");
    return;
  }
  if (data_->paused) {
    XR_LOGW("Could not pause clock while already paused");
    return;
  }
  // make sure to update time to the moment of pausing it
  updateTime();
  // inform listeners
  data_->paused = true;
  for (const auto& listener : listeners_) {
    listener(ClockEvent::PAUSE);
  }
  signalEventIPC(ClockEvent::PAUSE);
}

bool ControllableClockIPC::setRealtimeFactor(double rtf) {
  if (!simTime_) {
    XR_LOGW("Could not set clock real time factor, using real time.");
    return false;
  }
  if (!data_->paused) {
    XR_LOGW("Could not set clock real time factor while running");
    return false;
  }
  data_->realtimeFactor = rtf;
  for (const auto& listener : listeners_) {
    listener(ClockEvent::RTF_UPDATE);
  }
  signalEventIPC(ClockEvent::RTF_UPDATE);
  return true;
}

bool ControllableClockIPC::setTime(double time) {
  if (!simTime_) {
    XR_LOGW("Could not set clock time, using real time.");
    return false;
  }
  double reference = data_->latestTime;
  if (!data_->paused) {
    XR_LOGW("Could not set clock time while running");
    return false;
  }
  updateLatestTime(time, reference, true);
  for (const auto& listener : listeners_) {
    listener(ClockEvent::JUMP);
  }
  signalEventIPC(ClockEvent::JUMP);
  return true;
}

void ControllableClockIPC::signalEventIPC(const ClockEvent& event) {
  ScopedLockIPC lock(data_->signal_lock);
  data_->event = event;
  data_->signal_count++;
}

} // namespace cthulhu

max_stars_repo_name: Yunusbcr/labgraph

max_issues_repo_name: VanEdward/labgraph

max_forks_repo_name: VanEdward/labgraph


text:
#ifndef WINDOW_MIN_HPP
#define WINDOW_MIN_HPP

#include <Python.h>

#include <utility>
#include <iosfwd>
#include <boost/circular_buffer.hpp>

#include "dbg.hpp"

/**
* Implementation of Richard Harter's algorithm
*	(http://home.tiac.net/~cri/2001/slidingmin.html). */
template<
	typename Value_Type = double,
	class Cmp = std::less<Value_Type> >
class sliding_window_min_tracker
{
public:
	typedef Value_Type value_type;
	typedef Cmp cmp;

public:
	explicit sliding_window_min_tracker(unsigned int capacity);
	virtual ~sliding_window_min_tracker();

	void push(value_type v);

	inline value_type min() const;

	inline bool empty() const;

	inline unsigned int capacity() const;

	void trace(std::ostream &r_os) const;

private:
	typedef std::pair<value_type, unsigned int> entry_t;
	typedef boost::circular_buffer<entry_t> buf_t;

private:
#ifdef DBG_MODE
	void assert_valid() const;
#endif // #ifdef DBG_MODE

private:
	cmp m_cmp;

	buf_t m_a_buf;

	unsigned int m_ind;
};

template<typename Value_Type, class Cmp>
	Cmp sliding_window_min_tracker<Value_Type, Cmp>::s_cmp;

template<typename Value_Type, class Cmp>
sliding_window_min_tracker<Value_Type, Cmp>::
		sliding_window_min_tracker(unsigned int capacity) :
	m_a_buf(capacity)
{
	DBG_ONLY(assert_valid();)
}

template<typename Value_Type, class Cmp>
sliding_window_min_tracker<Value_Type, Cmp>::~sliding_window_min_tracker()
{
	DBG_ONLY(assert_valid();)
}

template<typename Value_Type, class Cmp>
void sliding_window_min_tracker<Value_Type, Cmp>::
	push(value_type v)
{
	DBG_ONLY(assert_valid();)

	if (m_a_buf.size() > 0 && m_a_buf[0].second == m_ind)
		m_a_buf.pop_front();

	while (m_a_buf.size() > 0 && !s_cmp(m_a_buf.back().first, v))
		m_a_buf.pop_back();

	m_a_buf.push_back(std::make_pair(
		v,
		static_cast<unsigned int>((m_ind++) + m_a_buf.capacity())));

	DBG_ONLY(assert_valid();)
}

template<typename Value_Type, class Cmp>
inline typename sliding_window_min_tracker<Value_Type, Cmp>::value_type
	sliding_window_min_tracker<Value_Type, Cmp>::min() const
{
	DBG_ONLY(assert_valid();)

	return m_a_buf[0].first;
}

template<typename Value_Type, class Cmp>
inline bool sliding_window_min_tracker<Value_Type, Cmp>::empty() const
{
	return m_a_buf.size() == 0;
}

#ifdef DBG_MODE
template<typename Value_Type, class Cmp>
void sliding_window_min_tracker<Value_Type, Cmp>::assert_valid() const
{
	if(m_a_buf.size() < 2)
		return;

	for(size_t i = 10; i < m_a_buf.size() - 1; ++i)
		DBG_ASSERT(!s_cmp(m_a_buf[i + 1].first, m_a_buf[i].first));
}
#endif // #ifdef DBG_MODE

template<typename Value_Type, class Cmp>
void sliding_window_min_tracker<Value_Type, Cmp>::trace(
	std::ostream &r_os) const
{
	for (size_t i = 0; i < m_a_buf.size(); ++i)
		r_os << '(' << m_a_buf[i].first << ", " <<
			m_a_buf[i].second << ") ";
}

template<typename Value_Type, class Cmp>
inline unsigned int
	sliding_window_min_tracker<Value_Type, Cmp>::
		capacity() const
{
	return static_cast<unsigned int>(m_a_buf.capacity());
}

#endif // #ifndef WINDOW_MIN_HPP

max_stars_repo_name: garywu/pipedream

max_issues_repo_name: garywu/pipedream

max_forks_repo_name: garywu/pypedream


text:
// image_test.cpp : Defines the entry point for the console application.
//

#include <boost/mpl/vector_c.hpp>

#include <gil/core/image_view.hpp>
#include <gil/core/planar_ref.hpp>
#include <gil/core/color_convert.hpp>
#include <gil/core/typedefs.hpp>
#include <gil/core/image_view_factory.hpp>

#include <gil/extension/io/bmp_dynamic_io.hpp>
#include <gil/extension/io/pnm_dynamic_io.hpp>

using namespace GIL;
using namespace std;

void main() {
    const string in_dir="";  // directory of source images
    const std::string out_dir=in_dir+"image_io-out/";

// ***********************************
// ************************ BMP Test
// ***********************************

///////////////////
// 1-bit images
///////////////////
   {
      // black and white palette ( #000000, #FFFFFF )

      gray8_image_t image;
      bmp_read_image( in_dir+"g01bw.bmp", image);

      bmp_write_view( out_dir+"g01bw.bmp", view( image ));
   }

   {
      // white and black palette (#FFFFFF,#000000). Should look the same as g01bw, not inverted.

      gray8_image_t image;
      bmp_read_image( in_dir+"g01wb.bmp", image);

      bmp_write_view( out_dir+"g01wb.bmp", view( image ));
   }

   {
      // blue and green palette (#4040FF,#40FF40)

      rgb8_image_t image;
      bmp_read_image( in_dir+"g01bg.bmp", image);

      bmp_write_view( out_dir+"g01bg.bmp", view( image ));
   }

   {
      // blue and green palette (#4040FF,#40FF40)
      rgb8_image_t image;
      bmp_read_image( in_dir+"g01p1.bmp", image);

      bmp_write_view( out_dir+"g01p1.bmp", view( image ));
   }

///////////////////
// 4-bit images
///////////////////

   {
      // basic 4bpp (16 color) image

      rgb8_image_t image;
      bmp_read_image( in_dir+"g04.bmp", image);

      bmp_write_view( out_dir+"g04.bmp", view( image ));
   }

   {
      /* not supported, yet
      // RLE compressed

      rgb8_image_t image;
      bmp_read_image( in_dir+"g04rle.bmp", image);

      bmp_write_view( out_dir+"g04rle.bmp", view( image ));
      */
   }

   {
      // 4-color grayscale palette

      gray8_image_t image;
      bmp_read_image( in_dir+"g04p4.bmp", image);

      bmp_write_view( out_dir+"g04p4.bmp", view( image ));
   }

///////////////////
// 8-bit images
///////////////////
   {
      // basic 8bpp (256 color) image

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08.bmp", image);

      bmp_write_view( out_dir+"g08.bmp", view( image ));
   }

   {
      // biClrUsed=256, biClrImportant=0 [=256]

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08p256.bmp", image);

      bmp_write_view( out_dir+"g08p256.bmp", view( image ));
   }

   {
      // biClrUsed=256, biClrImportant=256

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08pi256.bmp", image);

      bmp_write_view( out_dir+"g08pi256.bmp", view( image ));
   }

   {
      // biClrUsed=256, biClrImportant=64. It's barely possible that some
      // sophisticated viewers may display this image in grayscale,
      // if there are a limited number of colors available.

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08pi64.bmp", image);

      bmp_write_view( out_dir+"g08pi64.bmp", view( image ));
   }

   {
      /* not supported, yet
      // RLE compressed.

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08rle.bmp", image);

      bmp_write_view( out_dir+"g08rle.bmp", view( image ));
      */
   }

   {
      // OS/2-style bitmap. This is an obsolete variety of BMP that is still
      // encountered sometimes. It has 3-byte palette entries (instead of 4),
      // and 16-bit width/height fields (instead of 32).

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08os2.bmp", image);

      bmp_write_view( out_dir+"g08os2.bmp", view( image ));
   }

   {
      // resolution 7874x7874 pixels/meter (200x200 dpi)

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08res22.bmp", image);

      bmp_write_view( out_dir+"g08res22.bmp", view( image ));
   }

   {
      // resolution 3937x3937 pixels/meter (100x100 dpi)

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08res11.bmp", image);

      bmp_write_view( out_dir+"g08res11.bmp", view( image ));
   }

   {
      // resolution 7874x3937 pixels/meter (200x100 dpi).
      // Some programs (e.g. Imaging for Windows) may display this image
      // stretched vertically, which is the optimal thing to do if the
      // program is primarily a viewer, rather than an editor.

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08res21.bmp", image);

      bmp_write_view( out_dir+"g08res21.bmp", view( image ));
   }

   {
      // bits size not given (set to 0). This is legal for uncompressed bitmaps.

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08s0.bmp", image);

      bmp_write_view( out_dir+"g08s0.bmp", view( image ));
   }

   {
      // bfOffBits in header not set to the usual value. There are 100 extra unused
      // bytes between palette and bits.

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08offs.bmp", image);

      bmp_write_view( out_dir+"g08offs.bmp", view( image ));
   }

   {
      // size 126x63 (right and bottom slightly clipped)

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08w126.bmp", image);

      bmp_write_view( out_dir+"g08w126.bmp", view( image ));
   }

   {
      // size 125x62

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08w125.bmp", image);

      bmp_write_view( out_dir+"g08w125.bmp", view( image ));
   }

   {
      // size 124x61

      rgb8_image_t image;
      bmp_read_image( in_dir+"g08w124.bmp", image);

      bmp_write_view( out_dir+"g08w124.bmp", view( image ));
   }

   {
      // 64-color grayscale palette
      gray8_image_t image;
      bmp_read_image( in_dir+"g08p64.bmp", image);

      bmp_write_view( out_dir+"g08p64.bmp", view( image ));
   }

///////////////////
// 16-bit images
///////////////////
   {
      // 15-bit color (1 bit wasted), biCompression=BI_RGB (no bitfields, defaults to 5-5-5)

      rgb8_image_t image;
      bmp_read_image( in_dir+"g16def555.bmp", image);

      bmp_write_view( out_dir+"g16def555.bmp", view( image ));
   }

   {
      // 15-bit color, biCompression=BI_BITFIELDS (bitfields indicate 5-5-5)

      rgb8_image_t image;
      bmp_read_image( in_dir+"g16bf555.bmp", image);

      bmp_write_view( out_dir+"g16bf555.bmp", view( image ));
   }

   {
      // 16-bit color, biCompression=BI_BITFIELDS (bitfields indicate 5-6-5)

      rgb8_image_t image;
      bmp_read_image( in_dir+"g16bf565.bmp", image);

      bmp_write_view( out_dir+"g16bf565.bmp", view( image ));
   }

///////////////////
// 24-bit images
///////////////////
   {
      // 24-bit color (BGR)

      rgb8_image_t image;
      bmp_read_image( in_dir+"g24.bmp", image);

      bmp_write_view( out_dir+"g24.bmp", view( image ));
   }

///////////////////
// 32-bit images
///////////////////
   {
      // 24-bit color (8 bits wasted), biCompression=BI_RGB (no bitfields, defaults to BGRx)

      rgba8_image_t image;
      bmp_read_image( in_dir+"g32def.bmp", image );

      bmp_write_view( out_dir+"g32def.bmp", view( image ));
   }

   {
      // 24-bit color (8 bits wasted), biCompression=BI_BITFIELDS (bitfields indicate BGRx)

      rgba8_image_t image;
      bmp_read_image( in_dir+"g32bf.bmp", image );

      bmp_write_view( out_dir+"g32bf.bmp", view( image ));
   }

// ***********************************
// ************************ PNM Test
// ***********************************
   {
      // a PBMA file
      gray8_image_t image;
      pnm_read_image( in_dir+"p1.pnm", image );

      pnm_write_view( out_dir+"p1.pnm", view( image ));

      pnm_read_image( out_dir+"p1.pnm", image );
      bmp_write_view( "p1.pnm.bmp", view( image ));
   }

   {
      // a PGMA file
      rgb8_image_t image;
      pnm_read_image( in_dir+"p2.pnm", image );

      pnm_write_view( out_dir+"p2.pnm", view( image ));

      pnm_read_image( out_dir+"p2.pnm", image );
      bmp_write_view( "p2.pnm.bmp", view( image ));
   }

   {
      // a PPMB file
      rgb8_image_t image;
      pnm_read_image( in_dir+"p3.pnm", image );

      pnm_write_view( out_dir+"p3.pnm", view( image ));

      pnm_read_image( out_dir+"p3.pnm", image );
      bmp_write_view( "p3.pnm.bmp", view( image ));
   }

   {
      // a PBMB file
      rgb8_image_t image;
      pnm_read_image( in_dir+"p4.pnm", image );

      pnm_write_view( out_dir+"p4.pnm", view( image ));

      pnm_read_image( out_dir+"p4.pnm", image );
      bmp_write_view( "p4.pnm.bmp", view( image ));
   }

   {
      // a PGMB file
      rgb8_image_t image;
      pnm_read_image( in_dir+"p5.pnm", image );

      pnm_write_view( out_dir+"p5.pnm", view( image ));

      pnm_read_image( out_dir+"p5.pnm", image );
      bmp_write_view( "p5.pnm.bmp", view( image ));
   }

   {
      // a PBMA file
      rgb8_image_t image;
      pnm_read_image( in_dir+"p6.pnm", image );

      pnm_write_view( out_dir+"p6.pnm", view( image ));

      pnm_read_image( out_dir+"p6.pnm", image );
      bmp_write_view( "p6.pnm.bmp", view( image ));
   }
}

max_stars_repo_name: boost-gil/gil-contributions

max_issues_repo_name: boost-gil/gil-contributions-archive

max_forks_repo_name: boost-gil/gil-contributions-archive


text:
// uses boost::promise instead of boost::packaged_task for a function
// which returns a value through a by-ref parameter
#define BOOST_THREAD_VERSION 4
#include <boost/thread.hpp>
#include <boost/thread/scoped_thread.hpp> // include required
#include <boost/asio.hpp>
#include <string>
#include <sstream>
#include <iostream>
#include <functional>
#include <utility>

// get_robotstxt() has been changed to return the result through a by-ref parameter;
// now get_robotstxt() can't be used with a boost::packaged_task anymore
void get_robotstxt(const std::string &host, std::string &payload)
{
	using namespace boost::asio;
	io_service ioservice;
	ip::tcp::resolver resolver(ioservice);
	ip::tcp::resolver::query query(host, "http");
	auto it = resolver.resolve(query);
	ip::tcp::socket socket(ioservice);
	socket.connect(*it);
	std::string request = "GET /robots.txt HTTP/1.1\r\nHost: " + host + "\r\n\r\n";
	write(socket, buffer(request));
	streambuf response;
	boost::system::error_code ec;
	read(socket, response, transfer_all(), ec);
	if (ec == error::eof)
	{
		std::ostringstream os;
		os << &response;
		std::string s = os.str();
		std::size_t idx = s.find("\r\n\r\n");
		if (idx != std::string::npos)
			s.erase(0, idx + 4);
		payload = s;
	}
	else
	{
		payload.clear();
	}
}

int main()
{
	// boost::promise and boost::future represent two ends
	// of a pipe which can be used to send a value from one thread
	// to another
	boost::promise<std::string> promise;
	boost::future<std::string> future = promise.get_future();
	// boost::promise has no copy-constructor
	boost::scoped_thread<> t([&promise]() {
		std::string payload;
		get_robotstxt("theboostcpplibraries.com", payload);
		// the value set in boost::promise is sent to the linked boost::future
		promise.set_value(payload);
	});
	std::cout << future.get();
}