text:
/**
 * @file storageRouterHelperProxy.cc
 * @author Bartek Kryza
 * @copyright (C) 2021 ACK CYFRONET AGH
 * @copyright This software is released under the MIT license cited in
 * 'LICENSE.txt'
 */

#include "bufferedStorageHelper.h"
#include "keyValueAdapter.h"
#include "s3Helper.h"

#include <boost/make_shared.hpp>
#include <boost/python.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/raw_function.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <folly/executors/IOThreadPoolExecutor.h>

#include <chrono>
#include <future>
#include <string>
#include <thread>

#include <iostream>

using ReadDirResult = std::vector<std::string>;

using namespace boost::python;
using namespace one::helpers;

namespace {
struct Stat {
    time_t atime;
    time_t mtime;
    time_t ctime;
    int gid;
    int uid;
    int mode;
    size_t size;

    static Stat fromStat(const struct stat &attr)
    {
        Stat res;
        res.size = attr.st_size;
        res.atime = attr.st_atim.tv_sec;
        res.mtime = attr.st_mtim.tv_sec;
        res.ctime = attr.st_ctim.tv_sec;
        res.gid = attr.st_gid;
        res.uid = attr.st_uid;
        res.mode = attr.st_mode;

        return res;
    }

    bool operator==(const Stat &o) const
    {
        return atime == o.atime && mtime == o.mtime && ctime == o.ctime &&
            gid == o.gid && uid == o.uid && mode == o.mode && size == o.size;
    }
};
}

class ReleaseGIL {
public:
    ReleaseGIL()
        : threadState{PyEval_SaveThread(), PyEval_RestoreThread}
    {
    }

private:
    std::unique_ptr<PyThreadState, decltype(&PyEval_RestoreThread)> threadState;
};

class BufferedStorageHelperProxy {
public:
    /**
     * Test BufferedStorage proxy based on an S3Helper and a single buckeet
     */
    BufferedStorageHelperProxy(std::string scheme, std::string hostName,
        std::string bucketName, std::string accessKey, std::string secretKey,
        int threadNumber, int blockSize)
        : m_executor{std::make_shared<folly::IOThreadPoolExecutor>(
              threadNumber, std::make_shared<StorageWorkerFactory>("buffer_t"))}
    {
        auto bufferStorageHelper =
            std::make_shared<one::helpers::KeyValueAdapter>(
                std::make_shared<one::helpers::S3Helper>(hostName, bucketName,
                    accessKey, secretKey, std::numeric_limits<size_t>::max(),
                    0664, 0775, scheme == "https", std::chrono::seconds{20},
                    StoragePathType::FLAT),
                m_executor, blockSize);

        auto mainStorageHelper =
            std::make_shared<one::helpers::KeyValueAdapter>(
                std::make_shared<one::helpers::S3Helper>(hostName, bucketName,
                    accessKey, secretKey, std::numeric_limits<size_t>::max(),
                    0664, 0775, scheme == "https", std::chrono::seconds{20},
                    StoragePathType::CANONICAL),
                m_executor, 0);

        m_helper = std::make_shared<one::helpers::BufferedStorageHelper>(
            std::move(bufferStorageHelper), std::move(mainStorageHelper),
            ExecutionContext::ONECLIENT, ".__onedata__buffer");
    }

    ~BufferedStorageHelperProxy() { }

    void open(std::string fileId, int flags)
    {
        ReleaseGIL guard;
        m_helper->open(fileId, flags, {})
            .thenValue([&](one::helpers::FileHandlePtr &&handle) {
                handle->release();
            });
    }

    std::string read(std::string fileId, int offset, int size)
    {
        ReleaseGIL guard;
        return m_helper->open(fileId, O_RDONLY, {})
            .thenValue([&](one::helpers::FileHandlePtr &&handle) {
                return handle->read(offset, size).thenValue([](auto &&buf) {
                    std::string data;
                    std::move(buf).appendToString(data);
                    return data;
                });
            })
            .get();
    }

    std::size_t write(std::string fileId, std::string data, int offset)
    {
        ReleaseGIL guard;
        return m_helper->open(fileId, O_WRONLY, {})
            .thenValue([&](one::helpers::FileHandlePtr &&handle) {
                folly::IOBufQueue buf{folly::IOBufQueue::cacheChainLength()};
                buf.append(data);
                return handle->write(offset, std::move(buf), {});
            })
            .get();
    }

    Stat getattr(std::string fileId)
    {
        ReleaseGIL guard;
        auto attr = m_helper->getattr(fileId).get();

        return Stat::fromStat(attr);
    }

    void access(std::string fileId)
    {
        ReleaseGIL guard;
        m_helper->access(fileId, {}).get();
    }

    ReadDirResult listobjects(std::string fileId, std::string marker, int count)
    {
        ReleaseGIL guard;
        ReadDirResult res;
        for (auto &direntry :
            m_helper->listobjects(fileId, marker, 0, count).get()) {
            res.emplace_back(std::get<0>(direntry).toStdString());
        }
        return res;
    }

    std::string readlink(std::string fileId)
    {
        ReleaseGIL guard;
        return m_helper->readlink(fileId).get().toStdString();
    }

    void mknod(std::string fileId, mode_t mode, std::vector<Flag> flags)
    {
        ReleaseGIL guard;
        m_helper->mknod(fileId, mode, FlagsSet(flags.begin(), flags.end()), 0)
            .get();
    }

    void mkdir(std::string fileId, mode_t mode)
    {
        ReleaseGIL guard;
        m_helper->mkdir(fileId, mode).get();
    }

    void unlink(std::string fileId, int size)
    {
        ReleaseGIL guard;
        m_helper->unlink(fileId, size).get();
    }

    void truncate(std::string fileId, int size, int currentSize)
    {
        ReleaseGIL guard;
        m_helper->truncate(fileId, size, currentSize).get();
    }

    void flushBuffer(std::string fileId, int size)
    {
        ReleaseGIL guard;
        m_helper->flushBuffer(fileId, size).get();
    }

private:
    std::shared_ptr<folly::IOExecutor> m_executor;
    std::shared_ptr<one::helpers::BufferedStorageHelper> m_helper;
};

namespace {
boost::shared_ptr<BufferedStorageHelperProxy> create(std::string scheme,
    std::string hostName, std::string bucketName, std::string accessKey,
    std::string secretKey, int threadNumber, int blockSize)
{
    return boost::make_shared<BufferedStorageHelperProxy>(scheme, hostName,
        bucketName, accessKey, secretKey, threadNumber, blockSize);
}
} // namespace

BOOST_PYTHON_MODULE(bufferedstorage_helper)
{
    class_<Stat>("Stat")
        .def_readwrite("st_atime", &Stat::atime)
        .def_readwrite("st_mtime", &Stat::mtime)
        .def_readwrite("st_ctime", &Stat::ctime)
        .def_readwrite("st_gid", &Stat::gid)
        .def_readwrite("st_uid", &Stat::uid)
        .def_readwrite("st_mode", &Stat::mode)
        .def_readwrite("st_size", &Stat::size)
        .def("__eq__", &Stat::operator==);

    class_<BufferedStorageHelperProxy, boost::noncopyable>(
        "BufferedStorageHelperProxy", no_init)
        .def("__init__", make_constructor(create))
        .def("access", &BufferedStorageHelperProxy::access)
        .def("getattr", &BufferedStorageHelperProxy::getattr)
        .def("mknod", &BufferedStorageHelperProxy::mknod)
        .def("mkdir", &BufferedStorageHelperProxy::mkdir)
        .def("listobjects", &BufferedStorageHelperProxy::listobjects)
        .def("unlink", &BufferedStorageHelperProxy::unlink)
        .def("read", &BufferedStorageHelperProxy::read)
        .def("write", &BufferedStorageHelperProxy::write)
        .def("flushBuffer", &BufferedStorageHelperProxy::flushBuffer)
        .def("truncate", &BufferedStorageHelperProxy::truncate);
}

max_stars_repo_name: onedata/helpers

max_issues_repo_name: onedata/helpers

max_forks_repo_name: onedata/helpers


text:
// Boost.Geometry (aka GGL, Generic Geometry Library)

// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.

// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Custom Box Example

#include <iostream>

#include <boost/geometry/algorithms/make.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/box.hpp>
#include <boost/geometry/strategies/strategies.hpp>
#include <boost/geometry/util/write_dsv.hpp>

struct my_point
{
    double x, y;
};

struct my_int_point
{
    int x, y;
};

struct my_box
{
    my_point ll, ur;
};

struct my_box_ltrb
{
    int left, top, right, bottom;
};

struct my_box_4
{
    double coors[4];
};

template <typename P>
struct my_box_t
{
    P ll, ur;
};

BOOST_GEOMETRY_REGISTER_POINT_2D(my_point, double, cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_POINT_2D(my_int_point, int, cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_BOX(my_box, my_point, ll, ur)
BOOST_GEOMETRY_REGISTER_BOX_TEMPLATED(my_box_t, ll, ur)
BOOST_GEOMETRY_REGISTER_BOX_2D_4VALUES(my_box_ltrb, my_int_point, left, top, right, bottom)
BOOST_GEOMETRY_REGISTER_BOX_2D_4VALUES(my_box_4, my_point, coors[0], coors[1], coors[2], coors[3])

int main()
{
    my_point p = boost::geometry::make<my_point>(3.5, 3.5);
    my_box b = boost::geometry::make<my_box>(0, 0, 2, 2);
    my_box_ltrb b1 = boost::geometry::make<my_box_ltrb>(0, 0, 3, 3);
    my_box_4 b4 = boost::geometry::make<my_box_4>(0, 0, 4, 4);
    my_box_t<my_point> bt = boost::geometry::make<my_box_t<my_point> >(0, 0, 5, 5);

    std::cout << boost::geometry::dsv(p) << " IN " << boost::geometry::dsv(b)
            << " : " << int(boost::geometry::within(p, b)) << std::endl;
    std::cout << boost::geometry::dsv(p) << " IN " << boost::geometry::dsv(b1)
            << " : " << int(boost::geometry::within(p, b1)) << std::endl;
    std::cout << boost::geometry::dsv(p) << " IN " << boost::geometry::dsv(b4)
            << " : " << int(boost::geometry::within(p, b4)) << std::endl;
    std::cout << boost::geometry::dsv(p) << " IN " << boost::geometry::dsv(bt)
            << " : " << int(boost::geometry::within(p, bt)) << std::endl;

    return 0;
}

ext: cpp


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

#ifndef BOOST_HTTP_PROTO_RESPONSE_PARSER_HPP
#define BOOST_HTTP_PROTO_RESPONSE_PARSER_HPP

#include <boost/http_proto/detail/config.hpp>
#include <boost/http_proto/error.hpp>
#include <boost/http_proto/parser.hpp>
#include <boost/http_proto/response_view.hpp>
#include <boost/http_proto/status.hpp>
#include <cstddef>

namespace boost {
namespace http_proto {

class BOOST_SYMBOL_VISIBLE
    response_parser
    : public parser
{
public:
    BOOST_HTTP_PROTO_DECL
    response_parser(
        config const& cfg,
        std::size_t buffer_bytes);

private:
    char*
    parse_start_line(
        char*,
        char const*,
        error_code&) noexcept override;

    void
    finish_header(
        error_code& ec) override;

    int status_;
};

} // http_proto
} // boost

#endif

ext: hpp


text:
#include <eve/function/ellint_3.hpp>
#include <boost/math/special_functions/ellint_3.hpp>
#include <eve/wide.hpp>
#include <iostream>

using wide_ft = eve::wide<float, eve::fixed<4>>;

int main()
{
  wide_ft pf = {0.1f, 0.0f, 0.2f, 3.0f};
  wide_ft qf = {0.1f, 1.5f, 0.2f, 0.5f};
  wide_ft rf = {2.0f, 1.0f, 0.1f, 1.0f};

  std::cout << "---- simd" << '\n'
            << "<- pf                    = " << pf << '\n'
            << "<- qf                    = " << qf << '\n'
            << "<- rf                    = " << rf << '\n'
            << "-> ellint_3(pf, qf, rf) = " << eve::ellint_3(pf, qf, rf) << '\n';

  float xf = 3.0f;
  float yf = 0.5f;
  float zf = 1.0f;

  std::cout << "---- scalar" << '\n'
            << "<- xf                    = " << xf << '\n'
            << "<- yf                    = " << yf << '\n'
            << "<- zf                    = " << zf << '\n'
            << "-> ellint_3(xf, yf, zf) = " << eve::ellint_3(xf, yf, zf) << '\n';

  return 0;
}

max_stars_repo_name: orao/eve

max_issues_repo_name: orao/eve

max_forks_repo_name: orao/eve


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

#include <nt2/sdk/bench/benchmark.hpp>
#include <nt2/sdk/bench/protocol/until.hpp>
#include <nt2/sdk/bench/metric/cycles_per_element.hpp>
#include <nt2/sdk/bench/details/process_functor.hpp>
#include <nt2/sdk/bench/setup/combination.hpp>
#include <nt2/sdk/bench/setup/fixed.hpp>
#include <nt2/sdk/bench/stats/median.hpp>
#include <nt2/sdk/meta/type_id.hpp>

#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/cat.hpp>

/// INTERNAL ONLY
#define NT2_TIMING_TYPES(r,d,i,e)                                              \
BOOST_PP_COMMA_IF(i) BOOST_PP_REMOVE_PARENS(BOOST_PP_TUPLE_ELEM(3,0,e))       \
/**/

/// INTERNAL ONLY
#define NT2_TIMING_RANGE_ELEM(r,d,i,e)                                         \
BOOST_PP_COMMA_IF(i) nt2::bench                                                \
                        ::fixed ( std::make_pair( BOOST_PP_TUPLE_ELEM(3,1,e)   \
                                                , BOOST_PP_TUPLE_ELEM(3,2,e)   \
                                                )                              \
                                )                                              \
/**/

/// INTERNAL ONLY
/// We generate a string externally so we're sure its .c_str() is valid all along
#define NT2_TIMING_IMPL(NAME, FUNC, CODE, RANGE )                              \
std::string const BOOST_PP_CAT(str_,NAME)                                      \
                    = nt2::type_id<FUNC                                        \
                            (BOOST_PP_SEQ_FOR_EACH_I(NT2_TIMING_TYPES,~,RANGE))\
                                  >();                                         \
void BOOST_PP_CAT(NT2_UNIT_PREFIX,NAME)();                                     \
nt2::details::bench const                                                      \
BOOST_PP_CAT(NAME,NT2_UNIT_PREFIX)                                             \
                        ( &nt2::details::benchmarks                            \
                        , BOOST_PP_CAT(NT2_UNIT_PREFIX,NAME)                   \
                        , BOOST_PP_CAT(str_,NAME).c_str()                      \
                        );                                                     \
void BOOST_PP_CAT(NT2_UNIT_PREFIX,NAME)()                                      \
{                                                                              \
  nt2::bench::run_until_with                                                   \
    <                                                                          \
      nt2::details::process_functor                                            \
      < CODE                                                                   \
      , BOOST_PP_SEQ_SIZE(RANGE)                                               \
      , BOOST_PP_SEQ_FOR_EACH_I(NT2_TIMING_TYPES,~,RANGE)                      \
      >                                                                        \
    >                                                                          \
    ( nt2::bench::args("duration",1.)                                          \
    , nt2::bench::args("iteration",1000000U)                                   \
    , nt2::bench::and_                                                         \
      ( nt2::bench::fixed(nt2::bench::args("samples",1024u))                   \
      , BOOST_PP_SEQ_FOR_EACH_I(NT2_TIMING_RANGE_ELEM,~,RANGE)                 \
      )                                                                        \
    , nt2::bench::cycles_per_element<nt2::bench::stats::median_>()             \
    );                                                                         \
}                                                                              \
/**/

/*!

**/
#define NT2_TIMING(FUNC, RANGE )                                               \
NT2_TIMING_IMPL ( BOOST_PP_CAT(timing_,__LINE__), FUNC                         \
                , boost::dispatch::functor<FUNC>, RANGE                        \
                )                                                              \
/**/

/*!

**/
#define NT2_TIMING_EXT(FUNC, RANGE )                                           \
NT2_TIMING_IMPL ( BOOST_PP_CAT(timing_,__LINE__), FUNC, FUNC, RANGE )          \
/**/

#endif


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

  Copyright 2015 NumScale SAS
  Copyright 2015 J.T.Lapreste

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_FUNCTION_SIMD_NEGIF_INCLUDED
#define BOOST_SIMD_FUNCTION_SIMD_NEGIF_INCLUDED

#include <boost/simd/function/scalar/negif.hpp>
#include <boost/simd/arch/common/generic/function/autodispatcher.hpp>
#include <boost/simd/arch/common/simd/function/negif.hpp>

#endif


text:
#include <boost/pfr.hpp>
#include <boost/endian/conversion.hpp>

#include <iostream>

/** Prints a "value" in hex notation. Borrowed from
 * https://stackoverflow.com/questions/10599068/how-do-i-print-bytes-as-hexadecimal */
template <typename T>
void printHex(const std::string& appendix, const T& value) {
    std::cout << std::hex << std::setfill('0');  // needs to be set only once
    auto *ptr = reinterpret_cast<const unsigned char *>(&value);
    for (int i = 0; i < sizeof(value); i++, ptr++) {
        if (i % sizeof(uint64_t) == 0) {
            std::cout << std::endl;
        }
        std::cout << std::setw(2) << static_cast<unsigned>(*ptr) << " ";
    }
    std::cout << " " << appendix;
}

/** A sample struct with some PODs */
struct EndianTest {
    uint32_t u1;
    uint16_t u2;
    uint8_t u3;
    uint64_t u4;
    double f1;
    float f2;
};

int main() {
    EndianTest test{1, 2, 3, 4, 5.5, 6.6};
    boost::pfr::flat_for_each_field(test,
        [] (const auto& field) {
            printHex("(native)", field);
            auto copy = field;
            boost::endian::endian_reverse_inplace(copy);
            printHex("(converted)", copy);
        });
    return 0;
}


text:
/**
 * Copyright (c) 2009 Carnegie Mellon University.
 *     All rights reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an "AS
 *  IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 *  express or implied.  See the License for the specific language
 *  governing permissions and limitations under the License.
 *
 * For more about this software visit:
 *
 *      http://www.graphlab.ml.cmu.edu
 *
 */

#ifndef GRAPHLAB_IS_POD_HPP
#define GRAPHLAB_IS_POD_HPP
#include <boost/type_traits.hpp>

namespace graphlab {

  template <typename T>
  struct gl_is_pod{
    // it is a pod and is not an integer since we have special handlings for integers

    BOOST_STATIC_CONSTANT(bool, value =
                          (
                           boost::type_traits::ice_and<
                             boost::is_scalar<T>::value,
                             boost::type_traits::ice_not<
                               boost::type_traits::ice_and<
                                 boost::is_integral<T>::value,
                                 sizeof(T) >= 2
                                 >::value
                               >::value
                             >::value
                          ));

    // standard POD detection is no good because things which contain pointers
    // are POD, but are not serializable
    // (T is POD and  T is not an integer of size >= 2)
    /*BOOST_STATIC_CONSTANT(bool, value =
                          (
                           boost::type_traits::ice_and<
                             boost::is_pod<T>::value,
                             boost::type_traits::ice_not<
                               boost::type_traits::ice_and<
                                 boost::is_integral<T>::value,
                                 sizeof(T) >= 2
                                 >::value
                               >::value
                             >::value
                          ));*/

  };

}

#endif

max_stars_repo_name: iivek/graphlab-cmu-mirror

max_issues_repo_name: iivek/graphlab-cmu-mirror

max_forks_repo_name: iivek/graphlab-cmu-mirror


text:
#include "external_referee.hpp"

#include <stdexcept>

#include <boost/algorithm/string/predicate.hpp>
#include <fmt/ostream.h>
#include <spdlog/spdlog.h>

#include <rj_common/multicast.hpp>
#include <rj_common/network.hpp>
#include <rj_common/referee_enums.hpp>
#include <rj_common/utils.hpp>
#include <rj_constants/constants.hpp>
#include <rj_constants/topic_names.hpp>
#include <rj_param_utils/param.hpp>
#include <rj_utils/logging_macros.hpp>
#include <unistd.h>

#include "world_state.hpp"

namespace referee {

using referee_module_enums::Command;
using referee_module_enums::Stage;

/// Distance in meters that the ball must travel for a kick to be detected
static const float kKickThreshold = kBallRadius * 3;

/// How many milliseconds the ball must be more than KickThreshold meters away
/// from its position when the referee indicated Ready for us to detect the ball
/// as having been kicked.
static const int kKickVerifyTimeMs = 250;

// Whether we cancel ball placement on a halt.
// If we want ball placement to continue after
// the ref halts/stops, make this false
static const bool kCancelBallPlaceOnHalt = true;

DEFINE_STRING(kRefereeParamModule, team_name, "RoboJackets",
              "The team name we should use when automatically assigning team "
              "colors from referee");
DEFINE_STRING(kRefereeParamModule, interface, "127.0.0.1", "The interface for referee operation");

ExternalReferee::ExternalReferee() : RefereeBase{"external_referee"}, asio_socket_{io_service_} {
    set_team_name(PARAM_team_name);

    raw_ref_pub_ = create_publisher<RawProtobufMsg>(referee::topics::kRefereeRawPub, 10);

    network_timer_ = create_wall_timer(std::chrono::milliseconds(10), [this]() { this->update(); });

    // Set up networking for external referee packets
    setup_referee_multicast();
    start_receive();
}

void ExternalReferee::start_receive() {
    // Set a receive callback
    asio_socket_.async_receive_from(
        boost::asio::buffer(recv_buffer_), sender_endpoint_,
        [this](const boost::system::error_code& error, std::size_t num_bytes) {
            receive_packet(error, num_bytes);
            start_receive();
        });
}

void ExternalReferee::receive_packet(const boost::system::error_code& error, size_t num_bytes) {
    if (error != boost::system::errc::success) {
        SPDLOG_ERROR("Error receiving: ", error);
        return;
    }

    SSL_Referee ref_packet;
    if (!ref_packet.ParseFromArray(recv_buffer_.data(), num_bytes)) {
        SPDLOG_ERROR("Got bad packet of {} bytes from {}", num_bytes, sender_endpoint_);
        SPDLOG_ERROR("Address: {}", fmt::ptr(&kRefereeAddress));
        return;
    }

    // Publish the raw packet
    RawProtobufMsg msg;
    msg.data.resize(ref_packet.ByteSizeLong());
    if (!ref_packet.SerializeToArray(msg.data.data(), msg.data.size())) {
        EZ_ERROR("Failed to serialize referee packet.");
    }
    raw_ref_pub_->publish(msg);

    // Update and publish team information
    // FIXME(Kyle): Expiry times are only valid when we stay in the Playing
    // state
    TeamInfo blue_info = TeamInfo::from_refbox_packet(ref_packet.blue());
    TeamInfo yellow_info = TeamInfo::from_refbox_packet(ref_packet.yellow());
    set_team_info(blue_info, yellow_info);

    // Update game state
    std::optional<rj_geometry::Point> designated_position;
    if (ref_packet.has_designated_position()) {
        designated_position = rj_geometry::Point(ref_packet.designated_position().x() / 1000.0,
                                                 ref_packet.designated_position().y() / 1000.0);
    }
    handle_command({ref_packet.command(), designated_position});
    handle_stage(ref_packet.stage());
    set_stage_time_left(std::chrono::duration_cast<RJ::Seconds>(
        std::chrono::microseconds(ref_packet.stage_time_left())));
    send();
}

void ExternalReferee::setup_referee_multicast() {
    const auto any_address = boost::asio::ip::address_v4::any();
    boost::asio::ip::udp::endpoint listen_endpoint{any_address, kProtobufRefereePort};

    asio_socket_.open(listen_endpoint.protocol());
    asio_socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
    try {
        asio_socket_.bind(listen_endpoint);
    } catch (const boost::system::system_error& e) {
        throw std::runtime_error("Failed to bind to shared referee port");
    }
    // Join multicast group
    const boost::asio::ip::address_v4 multicast_address =
        boost::asio::ip::address::from_string(kRefereeAddress).to_v4();
    asio_socket_.set_option(boost::asio::ip::multicast::join_group(
        multicast_address, boost::asio::ip::address_v4::any()));
}

void ExternalReferee::update() { io_service_.poll(); }

void ExternalReferee::handle_command(const ExternalReferee::Command& command) {
    const auto& [command_enum, maybe_placement_point] = command;

    if (command == last_command_) {
        return;
    }

    // We keep track of yellow's play state by default, so yellow has ours=true.
    constexpr auto YELLOW = true;
    constexpr auto BLUE = false;

    if (!maybe_placement_point.has_value()) {
        SPDLOG_WARN("Placement point not set but placement command given!");
    }

    const auto placement_point = maybe_placement_point.value_or(rj_geometry::Point());

    switch (command_enum) {
        case SSL_Referee::HALT:
            set_play_state(PlayState::halt());
            break;
        case SSL_Referee::STOP:
            set_play_state(PlayState::stop());
            break;
        case SSL_Referee::NORMAL_START:
            set_play_state(yellow_play_state().advanced_from_normal_start());
            break;
        case SSL_Referee::FORCE_START:
            set_play_state(PlayState::playing());
            break;
        case SSL_Referee::PREPARE_KICKOFF_YELLOW:
            set_play_state(PlayState::setup_kickoff(YELLOW));
            break;
        case SSL_Referee::PREPARE_KICKOFF_BLUE:
            set_play_state(PlayState::setup_kickoff(BLUE));
            break;
        case SSL_Referee::PREPARE_PENALTY_YELLOW:
            set_play_state(PlayState::setup_penalty(YELLOW));
            break;
        case SSL_Referee::PREPARE_PENALTY_BLUE:
            set_play_state(PlayState::setup_penalty(BLUE));
            break;
        case SSL_Referee::DIRECT_FREE_YELLOW:
            set_play_state(PlayState::ready_direct(YELLOW));
            break;
        case SSL_Referee::DIRECT_FREE_BLUE:
            set_play_state(PlayState::ready_direct(BLUE));
            break;
        case SSL_Referee::INDIRECT_FREE_YELLOW:
            set_play_state(PlayState::ready_indirect(YELLOW));
            break;
        case SSL_Referee::INDIRECT_FREE_BLUE:
            set_play_state(PlayState::ready_indirect(BLUE));
            break;
        case SSL_Referee::TIMEOUT_YELLOW:
        case SSL_Referee::TIMEOUT_BLUE:
            set_play_state(PlayState::halt());
            break;
        case SSL_Referee::GOAL_YELLOW:
        case SSL_Referee::GOAL_BLUE:
            break;
        case SSL_Referee::BALL_PLACEMENT_YELLOW:
            set_play_state(PlayState::ball_placement(YELLOW, placement_point));
            break;
        case SSL_Referee::BALL_PLACEMENT_BLUE:
            set_play_state(PlayState::ball_placement(BLUE, placement_point));
            break;
    }

    last_command_ = command;
}

MatchState::Period ExternalReferee::period_from_proto(SSL_Referee::Stage stage) {
    switch (stage) {
        case SSL_Referee::NORMAL_FIRST_HALF_PRE:
        case SSL_Referee::NORMAL_FIRST_HALF:
            return MatchState::FirstHalf;
        case SSL_Referee::NORMAL_HALF_TIME:
            return MatchState::Halftime;
        case SSL_Referee::NORMAL_SECOND_HALF_PRE:
        case SSL_Referee::NORMAL_SECOND_HALF:
            return MatchState::SecondHalf;
        case SSL_Referee::EXTRA_TIME_BREAK:
            return MatchState::FirstHalf;
        case SSL_Referee::EXTRA_FIRST_HALF_PRE:
        case SSL_Referee::EXTRA_FIRST_HALF:
            return MatchState::Overtime1;
        case SSL_Referee::EXTRA_HALF_TIME:
            return MatchState::Halftime;
        case SSL_Referee::EXTRA_SECOND_HALF_PRE:
        case SSL_Referee::EXTRA_SECOND_HALF:
            return MatchState::Overtime2;
        case SSL_Referee::PENALTY_SHOOTOUT_BREAK:
        case SSL_Referee::PENALTY_SHOOTOUT:
            return MatchState::PenaltyShootout;
        case SSL_Referee::POST_GAME:
            return MatchState::Overtime2;
        default:
            return MatchState::FirstHalf;
    }
}

void ExternalReferee::handle_stage(SSL_Referee::Stage stage) {
    set_period(ExternalReferee::period_from_proto(stage));
}

}  // namespace referee


text:
/*--------------------------------------------------------------------------------------
 Ethanon Engine (C) Copyright 2008-2013 Andre Santee
 http://ethanonengine.com/

	Permission is hereby granted, free of charge, to any person obtaining a copy of this
	software and associated documentation files (the "Software"), to deal in the
	Software without restriction, including without limitation the rights to use, copy,
	modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
	and to permit persons to whom the Software is furnished to do so, subject to the
	following conditions:

	The above copyright notice and this permission notice shall be included in all
	copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
	INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
	PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
	CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
	OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------------*/

#include "ETHDateTime.h"

#define _SCL_SECURE_NO_WARNINGS
#pragma warning( push )
#pragma warning( disable : 4127 )
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#pragma warning( pop )
#undef _SCL_SECURE_NO_WARNINGS

ETHDateTime::ETHDateTime()
{
	m_ref = 1;
	Update();
}

void ETHDateTime::AddRef()
{
	m_ref++;
}

void ETHDateTime::Release()
{
	if (--m_ref == 0)
	{
		delete this;
	}
}

void ETHDateTime::Update()
{
	boost::posix_time::ptime local_time = boost::posix_time::second_clock::local_time();
	boost::gregorian::date d = local_time.date();

	m_day = d.day();
	m_month = d.month();
	m_year = d.year();

	const boost::posix_time::time_duration& duration = local_time.time_of_day();
	m_hours   = duration.hours();
	m_minutes = duration.minutes();
	m_seconds = duration.seconds();
}

unsigned int ETHDateTime::GetDay() const
{
	return m_day;
}

unsigned int ETHDateTime::GetMonth() const
{
	return m_month;
}

unsigned int ETHDateTime::GetYear() const
{
	return m_year;
}

unsigned int ETHDateTime::GetHours() const
{
	return m_hours;
}

unsigned int ETHDateTime::GetMinutes() const
{
	return m_minutes;
}

unsigned int ETHDateTime::GetSeconds() const
{
	return m_seconds;
}

max_stars_repo_name: LuizTedesco/ethanon

max_issues_repo_name: theomission/ethanon

max_forks_repo_name: theomission/ethanon


text:
/* vim:set ts=3 sw=3 sts=3 et: */
/**
 * Copyright © 2008-2013 Last.fm Limited
 *
 * This file is part of libmoost.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

// Include boost test framework required headers
#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>

// Include CRT/STL required header(s)
#include <stdexcept>
#include <csignal>
#include <set>

#include <boost/bind.hpp>

// Include thrift headers

// Include application required header(s)
#include "../../include/moost/utils/scope_exit.hpp"

// Imported required namespace(s)
using namespace moost::utils;

// Name the test suite
BOOST_AUTO_TEST_SUITE( MoostUtilsScopeExitTest )

// Define the test fixture
struct Fixture
{
   // C_tor
   Fixture()
   {
   }

   // D_tor
   ~Fixture()
   {
   }
};

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_set_default_value, Fixture )
{
   bool b = false; // default is false
   {
      scope_exit::type<bool>::set_default_value se(b);
      b = true;
   }
   BOOST_CHECK(!b);

   std::sig_atomic_t sig = 0;
   {
      scope_exit::type<std::sig_atomic_t>::set_default_value se(sig);
      sig = 1;
   }
   BOOST_CHECK(0 == sig);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_set_default_value_cancel, Fixture )
{
   bool b = false; // default is false
   {
      scope_exit::type<bool>::set_default_value se(b);
      b = true;
      se.cancel();
   }
   BOOST_CHECK(b);

   std::sig_atomic_t sig = 0;
   {
      scope_exit::type<std::sig_atomic_t>::set_default_value se(sig);
      sig = 1;
      se.cancel();
   }
   BOOST_CHECK(1 == sig);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_set_specific_value, Fixture )
{
   int i = 0; // specific is false
   {
      scope_exit::type<int>::set_specific_value se(i, 10);
      i = 5;
   }
   BOOST_CHECK(i == 10);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_set_specific_value_cancel, Fixture )
{
   int i = 0; // specific is false
   {
      scope_exit::type<int>::set_specific_value se(i, 10);
      i = 5;
      se.cancel();
   }
   BOOST_CHECK(i == 5);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_restore_original_value, Fixture )
{
   bool b = true;
   {
      scope_exit::type<bool>::restore_original_value se(b);
      b = false;
   }
   BOOST_CHECK(b);

   std::sig_atomic_t sig = 1;
   {
      scope_exit::type<std::sig_atomic_t>::restore_original_value se(sig);
      sig = 0;
   }
   BOOST_CHECK(1 == sig);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_restore_original_value_cancel, Fixture )
{
   bool b = true;
   {
      scope_exit::type<bool>::restore_original_value se(b);
      b = false;
      se.cancel();
   }
   BOOST_CHECK(!b);

   std::sig_atomic_t sig = 1;
   {
      scope_exit::type<std::sig_atomic_t>::restore_original_value se(sig);
      sig = 0;
      se.cancel();
   }
   BOOST_CHECK(0 == sig);
}

namespace
{
   struct Scoped
   {
      Scoped (std::sig_atomic_t sig) : sig(sig)
      {
      }

      void operator()()
      {
         sig = 0;
      }

      std::sig_atomic_t sig;
   };
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_member_function_default_, Fixture )
{
   Scoped scoped = 0;
   {
      scope_exit::type<Scoped>::call_member_function se(scoped);
      scoped.sig = 1;
   }
   BOOST_CHECK(0 == scoped.sig);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_member_function_default_cancel, Fixture )
{
   Scoped scoped = 0;
   {
      scope_exit::type<Scoped>::call_member_function se(scoped);
      scoped.sig = 1;
      se.cancel();
   }
   BOOST_CHECK(1 == scoped.sig);
}

namespace
{
   struct ScopedReset
   {
      ScopedReset (std::sig_atomic_t sig) : sig(sig)
      {
      }

      void reset()
      {
         sig = 0;
      }

      std::sig_atomic_t sig;
   };
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_member_function, Fixture )
{
   ScopedReset scoped = 0;
   {
      scope_exit::type<ScopedReset>::call_member_function se(scoped, &ScopedReset::reset);
      scoped.sig = 1;
   }
   BOOST_CHECK(0 == scoped.sig);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_member_function_cancel, Fixture )
{
   ScopedReset scoped = 0;
   {
      scope_exit::type<ScopedReset>::call_member_function se(scoped, &ScopedReset::reset);
      scoped.sig = 1;
      se.cancel();
   }
   BOOST_CHECK(1 == scoped.sig);
}

namespace
{
   struct ScopedPod
   {
      std::sig_atomic_t sig;
   };

   void scope_reset(ScopedPod & scoped)
   {
      scoped.sig = 0;
   }

   struct scope_reset_functor
   {
      void operator() (ScopedPod & scoped) const
      {
         scoped.sig = 0;
      }
   };
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_free_function_with_ref, Fixture )
{
   ScopedPod scoped = { 0 };
   {
      scope_exit::type<ScopedPod>::call_free_function_with_ref se(scoped, scope_reset);
      scoped.sig = 1;
   }
   BOOST_CHECK(0 == scoped.sig);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_free_function_with_ref_cancel, Fixture )
{
   ScopedPod scoped = { 0 };
   {
      scope_exit::type<ScopedPod>::call_free_function_with_ref se(scoped, scope_reset);
      scoped.sig = 1;
      se.cancel();
   }
   BOOST_CHECK(1 == scoped.sig);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_free_functor_with_ref, Fixture )
{
   ScopedPod scoped = { 0 };
   {
      scope_exit::type<ScopedPod>::call_free_function_with_ref se(scoped, scope_reset_functor());
      scoped.sig = 1;
   }
   BOOST_CHECK(0 == scoped.sig);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_free_functor_with_ref_cancel, Fixture )
{
   ScopedPod scoped = { 0 };
   {
      scope_exit::type<ScopedPod>::call_free_function_with_ref se(scoped, scope_reset_functor());
      scoped.sig = 1;
      se.cancel();
   }
   BOOST_CHECK(1 == scoped.sig);
}

namespace
{
   int global = 0;

   void set_global(int i_)
   {
      global = i_;
   }

   struct set_global_functor
   {
      void operator()(int i_)
      {
         global = i_;
      }
   };
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_free_function_with_val, Fixture )
{
   global = 0;
   {
      scope_exit::type<int>::call_free_function_with_val se(10, set_global);
      BOOST_CHECK(0 == global);
   }

   BOOST_CHECK(10 == global);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_free_function_with_val_cancel, Fixture )
{
   global = 0;
   {
      scope_exit::type<int>::call_free_function_with_val se(10, set_global);
      BOOST_CHECK(0 == global);
      se.cancel();
   }

   BOOST_CHECK(0 == global);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_functor_with_val, Fixture )
{
   global = 0;
   {
      scope_exit::type<int>::call_free_function_with_val se(10, set_global_functor());
      BOOST_CHECK(0 == global);
   }

   BOOST_CHECK(10 == global);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_functor_with_val_cancel, Fixture )
{
   global = 0;
   {
      scope_exit::type<int>::call_free_function_with_val se(10, set_global_functor());
      BOOST_CHECK(0 == global);
      se.cancel();
   }

   BOOST_CHECK(0 == global);
}

namespace
{
   struct functor
   {
      functor(int & x): x_(x) {}

      void member_func()
      {
         x_ = 10;
      }

      int & x_;
   };
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_functor, Fixture )
{
   int x = 0;

   global = 0;
   {
      scope_exit::call_functor se(boost::bind(&functor::member_func, functor(x)));
      BOOST_CHECK(0 == x);
   }

   BOOST_CHECK(10 == x);
}

BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_functor_cancel, Fixture )
{
   int x = 0;

   global = 0;
   {
      scope_exit::call_functor se(boost::bind(&functor::member_func, functor(x)));
      BOOST_CHECK(0 == x);
      se.cancel();
   }

   BOOST_CHECK(0 == x);
}

// Define end of test suite
BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: lastfm/libmoost

max_issues_repo_name: lastfm/libmoost

max_forks_repo_name: lastfm/libmoost


text:
/* $Id: zenbutools_old.cpp,v 1.1 2014/03/12 07:38:15 severin Exp $ */

/****

 NAME

 zdxtools - DESCRIPTION of Object

 DESCRIPTION

 zdxtools is a ZENBU system command line tool to access and process data both
 remotely on ZENBU federation servers and locally with ZDX file databases.
 The API is designed to both enable ZENBU advanced features, but also to provide
 a backward compatibility to samtools and bedtools so that zdxtools can be a "drop in"
 replacement for these other tools.

 CONTACT

 Jessica Severin <jessica.severin@gmail.com>

 LICENSE

 * Software License Agreement (BSD License)
 * MappedQueryDB [MQDB] toolkit
 * copyright (c) 2006-2009 Jessica Severin
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Jessica Severin nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 APPENDIX

 The rest of the documentation details each of the object methods. Internal methods are usually preceded with a _

 ***/

#include <stdio.h>
#include <string>
#include <math.h>
#include <sys/time.h>
#include <sys/dir.h>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>

#include <MQDB/Database.h>
#include <MQDB/MappedQuery.h>
#include <MQDB/DBStream.h>
#include <EEDB/Assembly.h>
#include <EEDB/Chrom.h>
#include <EEDB/Metadata.h>
#include <EEDB/Symbol.h>
#include <EEDB/MetadataSet.h>
#include <EEDB/Datatype.h>
#include <EEDB/FeatureSource.h>
#include <EEDB/Experiment.h>
#include <EEDB/EdgeSource.h>
#include <EEDB/Peer.h>
#include <EEDB/Feature.h>
#include <EEDB/SPStream.h>
#include <EEDB/SPStreams/Dummy.h>
#include <EEDB/SPStreams/SourceStream.h>
#include <EEDB/SPStreams/MultiMergeStream.h>
#include <EEDB/SPStreams/FederatedSourceStream.h>
#include <EEDB/SPStreams/FeatureEmitter.h>
#include <EEDB/SPStreams/TemplateCluster.h>
#include <EEDB/SPStreams/OSCFileDB.h>
#include <EEDB/SPStreams/BAMDB.h>
#include <EEDB/SPStreams/RemoteServerStream.h>
#include <EEDB/Tools/OSCFileParser.h>
#include <EEDB/Tools/RemoteUserTool.h>
#include <EEDB/User.h>
#include <EEDB/Collaboration.h>
#include <EEDB/Feature.h>
#include <EEDB/ZDX/ZDXstream.h>
#include <EEDB/ZDX/ZDXsegment.h>
#include <EEDB/WebServices/WebBase.h>

#include <math.h>
#include <sys/time.h>

#define BUFSIZE         8192*3

using namespace std;
using namespace MQDB;

map<string,string>        _parameters;

void usage();

void zdx_read_test3();
void zdx_read_sources();
void update_bamdb_q20();
void zdx_load_from_osc();
void zdx_export();

void user_list_uploads();

int main(int argc, char *argv[]) {
  srand(time(NULL));
  if(argc==1) { usage(); }

  for(int argi=1; argi<argc; argi++) {
    if(argv[argi][0] != '-') { continue; }
    string arg = argv[argi];

    vector<string> argvals;
    while((argi+1<argc) and (argv[argi+1][0] != '-')) {
      argi++;
      argvals.push_back(argv[argi]);
    }

    if(arg == "-help")   { usage(); }
    if(arg == "-ids") {
      string ids;
      for(unsigned int j=0; j<argvals.size(); j++) {
        ids += " "+ argvals[j];
      }
      _parameters["ids"] += ids;
    }

    if(arg == "-peers") {
      string peers;
      for(unsigned int j=0; j<argvals.size(); j++) {
        if(!peers.empty()) { peers += ","; }
        peers += argvals[j];
      }
      _parameters["peers"] += peers;
    }

    if(arg == "-mode")          { _parameters["mode"] = argvals[0]; }

    if(arg == "-file")          { _parameters["_input_file"] = argvals[0]; }
    if(arg == "-f")             { _parameters["_input_file"] = argvals[0]; }
    if(arg == "-out")           { _parameters["_output_file"] = argvals[0]; }

    if(arg == "-url")           { _parameters["_url"] = argvals[0]; }

    if(arg == "-tmpdir")        { _parameters["_build_dir"] = argvals[0]; }
    if(arg == "-builddir")      { _parameters["_build_dir"] = argvals[0]; }
    if(arg == "-keywords")      { _parameters["keywords"] = argvals[0]; }
    if(arg == "-display_name")  { _parameters["display_name"] = argvals[0]; }
    if(arg == "-description")   { _parameters["description"] = argvals[0]; }
    if(arg == "-platform")      { _parameters["platform"] = argvals[0]; }
    if(arg == "-ignore_int_asm"){ _parameters["ignore_internal_assembly"] = "true"; }
    if(arg == "-score_express") { _parameters["score_as_expression"] = argvals[0]; }
    if(arg == "-test")          { _parameters["test_stream"] = "true"; }
    if(arg == "-owner_openid")  { _parameters["owner_openid"] = argvals[0]; }
    if(arg == "-single_tagmap") { _parameters["singletagmap_expression"] = "true"; }
    if(arg == "-buildtime")     { _parameters["buildtime"] = argvals[0]; }

    if(arg == "-score_express") { _parameters["score_as_expression"] = argvals[0]; }
    if(arg == "-single_tagmap") { _parameters["singletagmap_expression"] = "true"; }

    if(arg == "-assembly")      { _parameters["genome_assembly"] = argvals[0]; }
    if(arg == "-asm")           { _parameters["genome_assembly"] = argvals[0]; }
    if(arg == "-asmb")          { _parameters["genome_assembly"] = argvals[0]; }
    if(arg == "-chr")           { _parameters["chrom"] = argvals[0]; }
    if(arg == "-chrom")         { _parameters["chrom"] = argvals[0]; }
    if(arg == "-start")         { _parameters["start"] = argvals[0]; }
    if(arg == "-end")           { _parameters["end"] = argvals[0]; }

    if(arg == "-sources")       { _parameters["mode"] = "sources"; }
    if(arg == "-experiments")   { _parameters["mode"] = "sources"; _parameters["source"] = "Experiment"; }
    if(arg == "-fsrc")          { _parameters["mode"] = "sources"; _parameters["source"] = "FeatureSource"; }
    if(arg == "-chroms")        { _parameters["mode"] = "chroms"; }
    if(arg == "-format")        { _parameters["format"] = argvals[0]; }
    if(arg == "-filter")        { _parameters["filter"] = argvals[0]; }

    if(arg == "-show")         { _parameters["show"] = "true"; }

    if(arg == "-user") {
      if(argvals[0] == "list") {
        _parameters["mode"] = "list_uploads";

        string filter;
        for(unsigned int j=1; j<argvals.size(); j++) {
          filter += " "+ argvals[j];
        }
        _parameters["filter"] += filter;
      }
    }

  }

  if(_parameters["mode"] == "sources") {
    zdx_read_sources();
  }
  if(_parameters["mode"] == "load") {
    zdx_load_from_osc();
  }
  if(_parameters["mode"] == "bamdb_q20") {
    update_bamdb_q20();
  }
  if(_parameters["mode"] == "list_uploads") {
    user_list_uploads();
  }
  if(_parameters["mode"] == "export") {
    zdx_export();
  }

  exit(1);
}

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

void usage() {
  printf("zenbutools [options]\n");
  printf("  -help                     : print this help\n");
  printf("  -file <path>              : path to a ZDX file\n");
  printf("zenbutools v%s\n", EEDB::WebServices::WebBase::zenbu_version);

  exit(1);
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//
// main functions
//
/////////////////////////////////////////////////////////////////////////////////////////////////

void zdx_read_sources() {
  struct timeval                        starttime,endtime,difftime;
  EEDB::SPStream                        *stream = NULL;
  long count=0;

  printf("\n=== zdx_read_sources ====\n");

  count=0;

  gettimeofday(&starttime, NULL);
  EEDB::ZDX::ZDXstream *zdxstream = EEDB::ZDX::ZDXstream::open(_parameters["_input_file"]);
  stream = zdxstream;

  count=0;
  stream->stream_peers();
  while(MQDB::DBObject *obj = stream->next_in_stream()) {
    EEDB::Peer *peer = (EEDB::Peer*)obj;
    count++;
  }
  printf("%ld peers\n", count);

  count=0;
  stream->stream_data_sources(_parameters["source"], _parameters["filter"]);
  while(EEDB::DataSource *source = (EEDB::DataSource*)stream->next_in_stream()) {
    if(_parameters["format"] == "fullxml") {
      printf("%s\n", source->xml().c_str());
    } else {
      printf("%s", source->simple_xml().c_str());
    }
    count++;
  }
  gettimeofday(&endtime, NULL);
  timersub(&endtime, &starttime, &difftime);
  if(difftime.tv_sec ==0) {
    printf("%ld sources in %1.6f msec \n", count, (double)difftime.tv_sec*1000.0 + ((double)difftime.tv_usec)/1000.0);
  } else {
    printf("%ld sources in %1.6f sec \n", count, (double)difftime.tv_sec + ((double)difftime.tv_usec)/1000000.0);
  }
}

void zdx_export() {
  struct timeval       starttime,endtime,difftime;
  EEDB::SPStream       *stream = NULL;
  char                 buffer[2048];
  string               assembly_name = _parameters["assembly_name"];

  gettimeofday(&starttime, NULL);
  EEDB::ZDX::ZDXstream *zdxstream = EEDB::ZDX::ZDXstream::open(_parameters["_input_file"]);
  ZDXdb* zdxdb = zdxstream->zdxdb();

  long numsegs, numbuilt, numclaimed;
  EEDB::ZDX::ZDXsegment::build_stats(zdxdb, assembly_name, "", -1, -1, numsegs, numbuilt, numclaimed);
  long unbuilt= numsegs-numbuilt-numclaimed;
  fprintf(stderr, " numsegs=\"%ld\" built=\"%ld\" claimed=\"%ld\" unbuilt=\"%ld\"", numsegs, numbuilt, numclaimed, unbuilt);

  long total_count = 0;
  long raw_count = 0;

  string format = _parameters["format"];
  if(format.find("gff") != string::npos) { format = "gff"; }
  if(format.find("bed") != string::npos) { format = "bed"; }

  // get chroms
  vector<EEDB::Chrom*> chroms = EEDB::ZDX::ZDXsegment::fetch_all_chroms(zdxdb);
  sort(chroms.begin(), chroms.end(), chrom_length_sort_func);
  fprintf(stderr,"zdx_export %ld chroms\n", chroms.size());

  //make sure all sources are cached for lazyload later
  zdxstream->stream_data_sources();
  while(EEDB::DataSource* source = (EEDB::DataSource*)zdxstream->next_in_stream()) {
    EEDB::DataSource::add_to_sources_cache(source);
  }

  string output_buffer;

  //now stream each chrom out
  vector<EEDB::Chrom*>::iterator chr_it;
  for(chr_it=chroms.begin(); chr_it!=chroms.end(); chr_it++) {

    if(!output_buffer.empty()) {
      printf("%s", output_buffer.c_str());
      output_buffer.clear();
    }

    EEDB::Chrom *chrom = (*chr_it);
    string last_feature_id;
    //fprintf(stderr,"zdx_export [%s] [%s]\n", chrom->assembly_name().c_str(), chrom->chrom_name().c_str());

    zdxstream->stream_by_named_region(chrom->assembly_name(), chrom->chrom_name(), -1, -1);
    while(MQDB::DBObject *obj = zdxstream->next_in_stream()) {
      EEDB::Feature    *feature = NULL;
      EEDB::Expression *expression = NULL;
      if(obj->classname() == EEDB::Feature::class_name) { feature = (EEDB::Feature*)obj; }
      if(obj->classname() == EEDB::Expression::class_name) {
        feature    = ((EEDB::Expression*)obj)->feature();
        expression = (EEDB::Expression*)obj;
      }
      if(feature == NULL) { obj->release(); continue; }
      if((expression !=NULL) and (expression->value()==0.0) and (format=="gff" or format=="bed")) { obj->release(); continue; }

      if(format == "bed") {
        if(expression!=NULL) { output_buffer += expression->bed_description(_parameters["format"]) + "\n"; }
        else { output_buffer += feature->bed_description(_parameters["format"]) + "\n"; }
      }
      if(expression!=NULL and (last_feature_id == feature->db_id())) { obj->release(); continue; }

      if(format == "gff") { output_buffer += feature->gff_description(false) + "\n"; }
      //if(format == "osc" && (_osctable_generator!=NULL))  {
      //  output_buffer += _osctable_generator->osctable_feature_output(feature) + "\n";
      //}
      if(format == "das")  { output_buffer += feature->dasgff_xml(); }
      if(format == "xml")  {
        if(total_count==1) { feature->chrom()->simple_xml(output_buffer); }
        if(_parameters["submode"] == "simple_feature") {
          feature->simple_xml(output_buffer);
        } else if(_parameters["submode"] == "subfeature") {
          feature->_xml_start(output_buffer);
          feature->_xml_subfeatures(output_buffer);
          feature->_xml_end(output_buffer);
        } else {
          feature->xml(output_buffer);
        }
      }
      total_count++;
      last_feature_id = feature->db_id();
      obj->release();

      if(!output_buffer.empty()) {
        printf("%s", output_buffer.c_str());
        output_buffer.clear();
      }
    }

    gettimeofday(&endtime, NULL);
    timersub(&endtime, &starttime, &difftime);
    double runtime  = (double)difftime.tv_sec + ((double)difftime.tv_usec)/1000000.0;
    fprintf(stderr, "%s :: %1.2f obj/sec  %ld \n", chrom->fullname().c_str(), (total_count/runtime), total_count);
  }

  if(!output_buffer.empty()) {
    printf("%s", output_buffer.c_str());
    output_buffer.clear();
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////

void zdx_load_from_osc() {
  struct timeval            starttime,endtime,difftime;
  double                    mbytes, rate, runtime;
  EEDB::t_outputmode        outmode = EEDB::FULL_FEATURE;
  char                      buffer[8192];
  map<string, EEDB::Chrom*> chroms;
  long int                      count=0;
  map<string, EEDB::Datatype*>  datatypes;
  map<string, bool>             sourceid_filter;

  gettimeofday(&starttime, NULL);

  string input_file = _parameters["_input_file"];
  if(input_file.empty()) {
    fprintf(stderr, "ERROR: no specified input file\n\n");
    usage();
  }

  //initialize oscfileparser
  EEDB::Tools::OSCFileParser  *parser = new EEDB::Tools::OSCFileParser();
  map<string,string>::iterator    p_it;
  for(p_it=_parameters.begin(); p_it!=_parameters.end(); p_it++) {
    if((*p_it).first[0] == '_') { continue; }
    parser->set_parameter((*p_it).first, (*p_it).second);
  }
  if(!parser->init_from_file(input_file)) {
    fprintf(stderr, "ERROR: unable to parse oscfile header\n\n");
    usage();
  }
  if(!parser->default_assembly()) { //to make sure it is initialized
    fprintf(stderr, "ERROR: genome_assembly is undefined\n\n");
    usage();
  }
  if(!parser->primary_feature_source()) { //to make sure it is initialized
    fprintf(stderr, "ERROR: problem creating oscfile primary_feature_source\n\n");
    usage();
  }
  int chrom_idx, start_idx, end_idx, strand_idx;
  parser->get_genomic_column_indexes(chrom_idx, start_idx, end_idx, strand_idx);
  if(chrom_idx== -1 || start_idx==-1) {
    fprintf(stderr, "ERROR: oscfile header does not defined chrom or chrom_start columns\n\n");
    usage();
  }

  parser->sort_input_file();

  // create zdx file
  string output_file = _parameters["_output_file"];
  if(output_file.empty()) { output_file = "test1.zdx"; }
  EEDB::ZDX::ZDXstream *zdxstream = EEDB::ZDX::ZDXstream::create_new(output_file.c_str());
  if(!zdxstream) {
    fprintf(stderr, "ERROR: could not make output zdx file\n\n");
    usage();
  }

  //get chromsomes and segment zdx
  string genome = parser->default_assembly()->assembly_name();
  fprintf(stderr, "genome[%s]\n", genome.c_str());
  EEDB::SPStreams::RemoteServerStream *rstream = EEDB::SPStreams::RemoteServerStream::new_from_url("http://fantom.gsc.riken.jp/zenbu/");
  if(!rstream) {
    fprintf(stderr, "ERROR: unable to connect to remote zenbu to get genome stats\n\n");
    usage();
  }
  printf("have remote connection\n");
  rstream->stream_chromosomes(genome, "");
  while(MQDB::DBObject *obj = rstream->next_in_stream()) {
    if(!obj) { continue; }
    if(obj->classname() != EEDB::Chrom::class_name) { continue; }
    EEDB::Chrom* chrom = (EEDB::Chrom*)obj;
    printf("create chrom [%s]\n", chrom->xml().c_str());
    zdxstream->create_chrom(chrom);
    obj->release();
  }

  // read the input file and load into a ZDX file
  gzFile gz = gzopen(input_file.c_str(), "rb");
  if(!gz) {
    fprintf(stderr, "ERROR: failed to open input file\n\n");
    usage();
  }

  char* _data_buffer = (char*)malloc(BUFSIZE);  // 24 kilobytes
  bzero(_data_buffer, BUFSIZE);

  string filetype  = parser->get_parameter("filetype");

  //
  // input file is sorted so can load into consecutive zsegments
  //

  EEDB::ZDX::ZDXsegment* zseg = NULL;
  ZDXdb* zdxdb = zdxstream->zdxdb();

  gettimeofday(&starttime, NULL);
  while(gzgets(gz, _data_buffer, BUFSIZE) != NULL) {  //get one line to <cr>
    if(filetype == "osc") {
      if(_data_buffer[0] == '#') { continue; }
      if(count==0) { //first non-parameter/comment line is the header columns line
        count++;
        continue;
      }
    }
    count++;

    char *p1=_data_buffer;
    while((*p1 != '\0') && (*p1 != '\n') && (*p1 != '\r')) { p1++; }
    *p1 = '\0';  //null terminate line if \n or \r

    //fprintf(stderr, "convert_dataline [%s]\n", _data_buffer);
    EEDB::Feature* feature = parser->convert_dataline_to_feature(_data_buffer, outmode, datatypes, sourceid_filter);
    if(!feature) { //unable to parse the line
      continue;
    }
    feature->primary_id(count);

    if(feature->chrom() == NULL) {
      feature->release();
      continue;
    }
    //fprintf(stderr, "%s\n", feature->chrom_location().c_str());

    if(zseg!=NULL &&
       (feature->chrom_name() != zseg->chrom_name() ||
        feature->chrom_start() < zseg->chrom_start() ||
        feature->chrom_start() > zseg->chrom_end())) {
      //finished with zseg
      fprintf(stderr, "finish segment %s\n", zseg->xml().c_str());
      zseg->write_segment_features(); //flush remaining features and unclaim
      zseg->release();
      zseg = NULL;
    }

    if(zseg==NULL) {
      zseg = EEDB::ZDX::ZDXsegment::fetch(zdxdb, genome, feature->chrom()->chrom_name(), feature->chrom_start());
    }
    if(!zseg) {
      fprintf(stderr, "ERROR not able to fetch zsegment [%s::%s:%ld]\n", genome.c_str(), feature->chrom()->chrom_name().c_str(), feature->chrom_start());
      feature->release();
      continue;
    }
    zseg->claim_segment();

    feature->chrom(zseg->chrom());

    zseg->add_sorted_feature(feature);

    feature->release();

    if(count % 1000 == 0) {
      mbytes = ((double)gztell(gz)) / (1024.0*1024.0);
      gettimeofday(&endtime, NULL);
      timersub(&endtime, &starttime, &difftime);
      rate = (double)count / ((double)difftime.tv_sec + ((double)difftime.tv_usec)/1000000.0);
      fprintf(stderr, "%10ld features  %13.2f obj/sec", count, rate);
      rate = (double)mbytes / ((double)difftime.tv_sec + ((double)difftime.tv_usec)/1000000.0);
      fprintf(stderr, "  %13.3f mbytes/sec\n", rate);
    }
  }
  if(zseg) {
    fprintf(stderr, "finish segment\n");
    zseg->write_segment_features(); //flush remaining features and unclaim
    zseg->release();
    zseg = NULL;
  }

  mbytes = ((double)gztell(gz)) / (1024.0*1024.0);
  gettimeofday(&endtime, NULL);
  timersub(&endtime, &starttime, &difftime);
  rate = (double)count / ((double)difftime.tv_sec + ((double)difftime.tv_usec)/1000000.0);
  fprintf(stderr, "%10ld features  %13.2f obj/sec", count, rate);
  rate = (double)mbytes / ((double)difftime.tv_sec + ((double)difftime.tv_usec)/1000000.0);
  fprintf(stderr, "  %13.3f mbytes/sec\n", rate);

  //after finished all sources are defined
  zdxstream->add_peer(parser->peer());

  vector<EEDB::DataSource*> sources = parser->datasources();
  for(unsigned i=0; i<sources.size(); i++) {
    zdxstream->add_datasource(sources[i]);
  }
  zdxstream->write_source_section();

  //close files
  gzclose(gz);
  zdxstream->release();
}

//
//
//////////////////////////////////////////////////////////////////////////////////////
//
//

void zdx_read_test3() {
  struct timeval                        starttime,endtime,difftime;
  EEDB::SPStream                        *stream = NULL;

  printf("\n=== zdx_read_test3 ====\n");
  long count=0;
  int64_t size=0;
  gettimeofday(&starttime, NULL);
  ZDX::ZDXdb *zdxdb = ZDX::ZDXdb::open_zdx("test1.zdx");
  EEDB::ZDX::ZDXsegment* segment = EEDB::ZDX::ZDXsegment::fetch(zdxdb, "hg19", "chr8", -1);
  while(segment) {
    printf("%s\n", segment->xml().c_str());
    long s1 = segment->test_next_znode();
    while(s1>0) {
      size += s1;
      s1 = segment->test_next_znode();
    }
    gettimeofday(&endtime, NULL);
    timersub(&endtime, &starttime, &difftime);
    printf("%1.3f MB/sec\n", (size/1024.0/1024.0) /((double)difftime.tv_sec + ((double)difftime.tv_usec)/1000000.0));

    EEDB::ZDX::ZDXsegment* seg = segment->next_segment();
    segment->release();
    segment = seg;
  }

  gettimeofday(&endtime, NULL);
  timersub(&endtime, &starttime, &difftime);
  printf("%ld in %1.6f msec \n", count, (double)difftime.tv_sec*1000.0 + ((double)difftime.tv_usec)/1000.0);
  printf("%ld in %1.6f sec \n", count, (double)difftime.tv_sec + ((double)difftime.tv_usec)/1000000.0);
  printf("%1.3f obj/sec\n", count /((double)difftime.tv_sec + ((double)difftime.tv_usec)/1000000.0));
  printf("%1.3f MB/sec\n", (size/1024.0/1024.0) /((double)difftime.tv_sec + ((double)difftime.tv_usec)/1000000.0));
  sleep(100);
}

void update_bamdb_q20() {
  if(_parameters.find("db_url") == _parameters.end()) {
    printf("\nERROR: must specify -url for the peer\n");
    return usage();
  }

  EEDB::Peer *peer = EEDB::Peer::new_from_url(_parameters["db_url"]);
  if(!peer) {
    printf("\nERROR: unable to connect to peer [%s]!!\n\n", _parameters["db_url"].c_str());
    return usage();
  }
  if(peer->driver() != "bamdb") {
    printf("\nERROR: q20_tpm update only available for bamdb\n\n");
    return usage();
  }

  printf("db_url [%s]\n", peer->db_url().c_str());

  EEDB::SPStreams::BAMDB *bamdb = (EEDB::SPStreams::BAMDB*)(peer->source_stream());
  long long q20_total = bamdb->calc_q20_count();
  fprintf(stderr, "_calc_q20_count  %lld\n", q20_total);

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

void user_list_uploads() {
  string url = _parameters["_url"];
  string filter = _parameters["filter"];

  printf("user_list_uploads [%s]\n", url.c_str());
  if(url.empty()) { return; }
  if(!filter.empty()) { printf("  filter[%s]\n", filter.c_str()); }

  EEDB::Tools::RemoteUserTool *zremote = EEDB::Tools::RemoteUserTool::new_from_url(url);
  if(!zremote) { return; }

  if(!zremote->verify_remote_user()) {
    fprintf(stderr, "uable to connect to %s with user authentication\n", url.c_str());
    return;
  }
  fprintf(stderr, "remote user is OK\n");

  if(_parameters.find("format") == _parameters.end()) { _parameters["format"] = "list"; }

  if(_parameters.find("peers") != _parameters.end()) {
    zremote->set_peer_uuids(_parameters["peers"]);
  }

  long peer_count=0;
  long exp_count=0;
  long fsrc_count=0;

  EEDB::SPStream *stream = zremote->stream_uploaded_data_sources("", filter);
  while(MQDB::DBObject* obj = stream->next_in_stream()) {
    if(obj->classname() == EEDB::Peer::class_name) { peer_count++; continue; }

    string   uuid, objClass;
    long int objID;
    MQDB::unparse_dbid(obj->db_id(), uuid, objID, objClass);
    //printf("        uuid: %s\n", uuid.c_str());
    EEDB::Peer *peer = EEDB::Peer::check_cache(uuid);

    EEDB::DataSource* source = (EEDB::DataSource*)obj;
    if(obj->classname() == EEDB::Experiment::class_name) { exp_count++; }
    if(obj->classname() == EEDB::FeatureSource::class_name) { fsrc_count++; }

    if(_parameters["format"] == "xml") {
      printf("%s\n", source->xml().c_str());
    }
    if(_parameters["format"] == "list") {
      printf("%60s   %s\n", obj->db_id().c_str(),source->display_name().c_str());
    }
    if(_parameters["format"] == "detail") {
      printf("-------\n");
      printf("       db_id: %s\n", obj->db_id().c_str());
      printf("        name: %s\n", source->display_name().c_str());
      printf(" description: %s\n", source->description().c_str());
      if(peer) { printf("    peer: %s\n", peer->db_url().c_str()); }
    }

    source->release();
  }
  fprintf(stderr, "%ld peers --- %ld featuresources --- %ld experiments\n", peer_count, fsrc_count, exp_count);
  stream->disconnect();
}


text:
#include <burst/container/make_forward_list.hpp>
#include <burst/container/make_list.hpp>
#include <burst/container/make_vector.hpp>
#include <burst/iterator/buffered_chunk_iterator.hpp>
#include <burst/iterator/end_tag.hpp>
#include <burst/range/istream_range.hpp>

#include <doctest/doctest.h>

#include <boost/range/concepts.hpp>
#include <boost/range/iterator_range.hpp>

#include <algorithm>
#include <istream>
#include <iterator>
#include <sstream>
#include <vector>

TEST_SUITE("buffered_chunk_iterator")
{
    TEST_CASE("Буферизованный кусочный итератор всегда однопроходный")
    {
        SUBCASE("Входной итератор — произвольного доступа")
        {
            const auto v = burst::make_vector({1, 2, 3});

            auto initial = v.begin();
            BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<decltype(initial)>));

            auto chunk = burst::make_buffered_chunk_iterator(initial, v.end(), 2);
            BOOST_CONCEPT_ASSERT((boost::InputIterator<decltype(chunk)>));
        }

        SUBCASE("Входной итератор двунаправленный")
        {
            const auto l = burst::make_list({4, 5, 6, 7});

            auto initial = l.begin();
            BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator<decltype(initial)>));

            auto chunk = burst::make_buffered_chunk_iterator(initial, l.end(), 3);
            BOOST_CONCEPT_ASSERT((boost::InputIterator<decltype(chunk)>));
        }

        SUBCASE("Входной итератор однонаправленный")
        {
            const auto fl = burst::make_forward_list({'q', 'w', 'e'});

            auto initial = fl.begin();
            BOOST_CONCEPT_ASSERT((boost::ForwardIterator<decltype(initial)>));

            auto chunk = burst::make_buffered_chunk_iterator(initial, fl.end(), 1);
            BOOST_CONCEPT_ASSERT((boost::InputIterator<decltype(chunk)>));
        }

        SUBCASE("Входной итератор однопроходный")
        {
            std::stringstream stream("1 2 3 4");

            auto initial = std::istream_iterator<int>(stream);
            BOOST_CONCEPT_ASSERT((boost::InputIterator<decltype(initial)>));

            auto end = std::istream_iterator<int>{};
            auto chunk = burst::make_buffered_chunk_iterator(initial, end, 3);
            BOOST_CONCEPT_ASSERT((boost::InputIterator<decltype(chunk)>));
        }
    }

    TEST_CASE("Конец итератора создаётся из его начала с помощью специальной метки-индикатора")
    {
        auto stream = std::stringstream("1 2 3 4 5");

        auto begin = burst::make_buffered_chunk_iterator(burst::make_istream_range<int>(stream), 3);
        auto end = burst::make_buffered_chunk_iterator(burst::iterator::end_tag, begin);

        CHECK(std::next(begin, 2) == end);
    }

    TEST_CASE("Последний кусок может быть нецелым")
    {
        auto stream = std::stringstream("1 2 3 4 5");

        auto first = burst::make_buffered_chunk_iterator(burst::make_istream_range<int>(stream), 3);
        ++first;

        const auto expected = std::vector<int>{4, 5};
        CHECK(*first == expected);
    }

    TEST_CASE("Буферизованный кусочный итератор умеет продвигаться вперёд")
    {
        const auto v = burst::make_list({'a', 'b', 'c', 'd', 'e'});
        auto iterator = burst::make_buffered_chunk_iterator(v.begin(), v.end(), 2);

        ++iterator;
        CHECK(*iterator == burst::make_vector({'c', 'd'}));

        iterator++;
        CHECK(*iterator == burst::make_vector({'e'}));
    }

    TEST_CASE("Буфер может быть изменён")
    {
        auto stream = std::stringstream("a b c d e f g");

        const auto n = 2;
        auto iterator =
            burst::make_buffered_chunk_iterator(burst::make_istream_range<char>(stream), n);

        std::fill(iterator->begin(), iterator->end(), 'z');

        CHECK(std::count(iterator->begin(), iterator->end(), 'z') == n);
    }

    TEST_CASE("Проход по всем элементам всех блоков перечисляет все элементы исходного диапазона, "
        "причём ровно один раз")
    {
        const auto container = burst::make_vector({9, 8, 7, 6, 5, 4, 3, 2, 1, 0});

        auto begin = burst::make_buffered_chunk_iterator(container, 3);
        auto end = burst::make_buffered_chunk_iterator(burst::iterator::end_tag, begin);

        std::vector<int> encountered;
        std::for_each(begin, end,
            [& encountered] (const auto & range)
            {
                std::copy(range.begin(), range.end(), std::back_inserter(encountered));
            });

        CHECK(encountered == container);
    }
}

max_stars_repo_name: izvolov/thrust

max_issues_repo_name: izvolov/burst

max_forks_repo_name: izvolov/thrust


text:
/*
 * Website:
 *      https://github.com/wo3kie/dojo
 *
 * Author:
 *      Lukasz Czerwinski
 *
 * Compilation:
 *      g++ --std=c++11 json.cpp -o json
 *
 * Usage:
 *      $ ./json
 */

#include <cassert>
#include <fstream>
#include <iostream>
#include <string>

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

void print( boost::property_tree::ptree const & pt, int indent = 0 ){
    for( auto const & object : pt ){
        if( object.first == "names" ){
            auto const & objectName = object.first;
            auto const & array = object.second;

            std::cout
                << std::string( indent, ' ' )
                << objectName
                << std::endl;

            for( auto const & item : array ){
                auto const & name = item.first;
                assert( name == "" ); // for array a key is an empty string

                auto const & attrs = item.second;

                std::cout
                    << std::string( indent + 4, ' ' );

                for( auto const & attr : attrs ){
                    auto const & attrName = attr.first;
                    auto const & attrValue = attr.second.get_value< std::string >();

                    std::cout
                        << " "
                        << attrName << ": "
                        << attrValue;
                }

                std::cout << std::endl;
            }
        }
        else if( object.first == "doc" ){
            std::cout
                << std::string( indent, ' ' )
                << object.first
                << std::endl;
        }

        print( object.second, indent + 4 );
    }
}

int main(){
    std::ifstream input( "./json.json" );

    boost::property_tree::ptree propertyTree;
    read_json( input, propertyTree );
    print( propertyTree );

    return 0;
}


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

#ifndef IROHA_QUERY_ERROR_RESPONSE_VISITOR_HPP
#define IROHA_QUERY_ERROR_RESPONSE_VISITOR_HPP

#include <boost/variant.hpp>
#include "interfaces/query_responses/error_query_response.hpp"

namespace shared_model {
  namespace interface {
    template <typename Error>
    class QueryErrorResponseChecker : public boost::static_visitor<bool> {
     public:
      bool operator()(
          const shared_model::interface::ErrorQueryResponse &status) const {
        return iroha::visit_in_place(status.get(),
                                     [](const Error &) { return true; },
                                     [](const auto &) { return false; });
      }

      template <typename T>
      bool operator()(const T &) const {
        return false;
      }
    };
  }  // namespace interface
}  // namespace shared_model

#endif  // IROHA_QUERY_ERROR_RESPONSE_VISITOR_HPP

max_stars_repo_name: truongnmt/iroha

max_issues_repo_name: truongnmt/iroha

max_forks_repo_name: truongnmt/iroha


text:
// Copyright 2014, D. E. Shaw Research.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt )

#include "m128_traits.hpp"
#include <boost/random/counter_based_engine.hpp>
#include <boost/timer.hpp>
#include <iostream>

using namespace boost::random;

// This is the ARS pseudo-random function from Salmon et al. 2011,
// implemented using the AESNI _mm_aesenc_si128 hardware intrinsics.
// On Intel hardware with the AESNI instructions, it's the fastest
// Crush-resistant RNG we know of.  It runs at 2.7nsec/uint64
// on a 3.07GHz Xeon, i.e., just about 1 cycle-per-byte.
//
// This is in examples/ rather than boost/random because these
// intrinsics (_mm_aesenc_si128) and data types (__m128i) are too
// machine/compiler-specific for the main 'boost' tree.  Nevertheless,
// this example demonstrates that it's possible (and not that hard) to
// create hardware-dependent Prfs  that can be used by the standard
// counter_based_engine.
template <unsigned R=7>
struct ars_prf{
    typedef __m128i domain_type;
    typedef __m128i range_type;
    typedef __m128i key_type ;

    range_type operator()(domain_type v){
        __m128i kweyl = _mm_set_epi64x(UINT64_C(0xBB67AE8584CAA73B), /* sqrt(3) - 1.0 */
                                       UINT64_C(0x9E3779B97F4A7C15)); /* golden ratio */
        __m128i kk = k;
        if( R>1 ){
            kk = _mm_add_epi64(kk, kweyl);
            v = _mm_aesenc_si128(v, kk);
        }
        if( R>2 ){
            kk = _mm_add_epi64(kk, kweyl);
            v = _mm_aesenc_si128(v, kk);
        }
        if( R>3 ){
            kk = _mm_add_epi64(kk, kweyl);
            v = _mm_aesenc_si128(v, kk);
        }
        if( R>4 ){
            kk = _mm_add_epi64(kk, kweyl);
            v = _mm_aesenc_si128(v, kk);
        }
        if( R>5 ){
            kk = _mm_add_epi64(kk, kweyl);
            v = _mm_aesenc_si128(v, kk);
        }
        if( R>6 ){
            kk = _mm_add_epi64(kk, kweyl);
            v = _mm_aesenc_si128(v, kk);
        }
        if( R>7 ){
            kk = _mm_add_epi64(kk, kweyl);
            v = _mm_aesenc_si128(v, kk);
        }
        if( R>8 ){
            kk = _mm_add_epi64(kk, kweyl);
            v = _mm_aesenc_si128(v, kk);
        }
        if( R>9 ){
            kk = _mm_add_epi64(kk, kweyl);
            v = _mm_aesenc_si128(v, kk);
        }
        kk = _mm_add_epi64(kk, kweyl);
        v = _mm_aesenclast_si128(v, kk);
        return v;
    }

    ars_prf(key_type _k) : k(_k){
        //std::cerr << "ars_prf(key_type)\n";
    }

    ars_prf() { k = key_type(); }

    ars_prf(const ars_prf& v) : k(v.k) {
        //std::cerr << "ars_prf(const ars_prf&)\n";
    }

    void setkey(key_type _k){ k = _k; }
    key_type getkey() const { return k; }

    bool operator==(const ars_prf& rhs) const{
        return boost::random::detail::counter_traits<__m128i>::is_equal(k, rhs.k);
    }

    bool operator!=(const ars_prf& rhs) const{
        return !(k == rhs.k);
    }
protected:
    key_type k;
};

static const double cpu_frequency = 3.07e9;

void show_elapsed(double end, int iter, const std::string & name)
{
  double usec = end/iter*1e6;
  double cycles = usec * cpu_frequency/1e6;
  std::cout << name << ": "
            << usec*1e3 << " nsec/loop = "
            << cycles << " CPU cycles"
            << std::endl;
}

int main(int argc, char **argv){
    counter_based_engine<uint32_t, ars_prf<5> > e;
    std::cout << std::hex;
    std::cout << e() << "\n";
    std::cout << e() << "\n";
    std::cout << e() << "\n";
    std::cout << e() << "\n";
    std::cout << e() << "\n";
    std::cout << e() << "\n";
    std::cout << e() << "\n";
    std::cout << e() << "\n";

    std::cout << std::dec;
    std::cout << "state of the generator: " << e << "\n";

    counter_based_engine<uint32_t, ars_prf<5> > f;
    BOOST_ASSERT(e != f);

    // Aggressive parameters:  5 rounds is "Crush-resistant"
    // but with no safety margin.
    // 64-bit output minimizes loop-overhead.
    counter_based_engine<uint64_t, ars_prf<5> > g;
    uint32_t ss[4] = {1, 2, 3, 4};
    uint32_t *ss0 = &ss[0];
    g.seed(ss0, &ss[4]);
    size_t N = 100000000;
    boost::timer t;
    uint64_t tmp = 0;
    for(size_t i=0; i<N; ++i){
        tmp ^= g();
    }
    show_elapsed(t.elapsed(), N, "ars<5/64>");
    if(tmp == 0)
        std::cout << "tmp==0.  That's odd...";

    std::cout << "state of the generator: " << g << "\n";
    return 0;
}


text:
#include <nar/narnode/utility.h>
#include <nar/lib/Exception/Exception.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string>
#include <algorithm>
#include <string>
#include <sstream>
#include <iostream>
#include <boost/filesystem.hpp>
#include <nar/lib/Logging/logger.h>
extern nar::Logger* anar_log;
#define aNAR_LOG *anar_log
nar::Logger *anar_log = new nar::Logger(std::cout);

std::string nar::get_message(nar::Socket* skt) {
    return get_message(*skt);
}

void nar::divide_nar_path (std::string& dir_name, std::string &dir_path, std::string& file_name) {
    std::vector<std::string> names;
    std::size_t found;
    std::size_t last_found;
    std::string temp;
    std::string sql_string = "";
    if((dir_name[dir_name.length()-1] == '/') && dir_name.length()>1 ){
        dir_name = dir_name.substr(0,dir_name.length()-1);
    }
    if((dir_name[0] == '/') && dir_name.length()>1){
        found = dir_name.find("/",1);
        last_found = 1;
    }
    else{
        found = dir_name.find("/");
        last_found = 0;
    }

    while(found != std::string::npos){
        if(found == 0 && last_found == 0){
            temp = dir_name.substr(last_found,1);
            last_found = found+1;
            found = dir_name.find("/",last_found);
            names.push_back(temp);
        }
        else{
            temp = dir_name.substr(last_found,found-last_found);
            last_found = found+1;
            found = dir_name.find("/",last_found);
            names.push_back(temp);
        }

    }
    if(dir_name.length() != 1){
        temp = dir_name.substr(last_found);
        names.push_back(temp);
    }
    dir_path =  std::string("");
    file_name = std::string("");
    for(int i=0;i<names.size();i++) {
        if(i == names.size()-1) {
            file_name = names[i];
        }
        else {
            dir_path += names[i]+ std::string("/");

        }
    }
}

/* LOW LEVEL SOCKET MESSAGE EXCHANGE
*
* CODES
* \x01 -> [ERROR]Denotes that the start of message is not integer.
* \x02 -> [ERROR]Integer overflow, message too big.
* \x03 -> [SUCCESS]
*
*/

/*
 *
 *
 * @throws: nar::Exception::Socket::WrongSocketType, if socket is a server socket (acceptor)
 * @throws: nar::Exception::Socket::SystemError, if socket is closed or an unknown error is encountered
 * @throws: nar::Exception::LowLevelMessaging::NoSize("Message does not contain a size field."), if received message does not have a size field.
 * @throws: nar::Exception::LowLevelMessaging::SizeIntOverflow("Size is too big."), if received message size overflows int.
 *
 *
 *
*/
std::string nar::get_message(nar::Socket& skt) {
    static const char* codes = "\x01\x02\x03";
    char buf[1035];
    char nmin = 0;

    int len = 0;
    int prev_len = 0;
    int idx = 0;
    skt.recv(&nmin, 1);
    while(nmin != ' ') {
        if(nmin > '9' || nmin < '0') {
            skt.send(codes, 1);
            throw nar::Exception::LowLevelMessaging::NoSize("Message does not contain a size field.");
        }
        prev_len = len;
        len*=10;
        len += nmin - '0';
        if(prev_len > len) {
            skt.send(codes+1, 1);
            throw nar::Exception::LowLevelMessaging::SizeIntOverflow("Size is too big.");
        }
        skt.recv(&nmin, 1);
    }

    //std::cout << "LL recv len: " << len << std::endl;

    std::string data;

    while(len > 0) {
        int rec = skt.recv(buf, std::min(len, std::min(len, 1024)));
        data.append(buf, rec);
        len -= rec;
    }

    skt.send(codes+2, 1);
    return data;
}

/*
 *
 *
 * @throws: nar::Exception::Socket::WrongSocketType, if socket is a server socket (acceptor)
 * @throws: nar::Exception::Socket::SystemError, if socket is closed or an unknown error is encountered
 * @throws: nar::Exception::LowLevelMessaging::SizeIntOverflow("Size is too big."), if message to be sent has size that overflows int of computer.
 * @throws: nar::Exception::LowLevelMessaging::FormatError("Format error."), if server reports that format is not accurate (NOT NORMAL !!!)
 * @throws: nar::Exception::LowLevelMessaging::ServerSizeIntOverflow("Message size is greater than max in of server", sizei), if message to be sent has size that overflows int of the server.
 *
*/
void nar::send_message(nar::Socket& skt, std::string message) {
    long long int sizell = message.size();
    int sizei = message.size();
    if(sizell != sizei) {
        throw nar::Exception::LowLevelMessaging::SizeIntOverflow("Message size is greater than max int of this computer");
    }
    message = std::to_string(message.size()) + std::string(" ") + message;

    skt.send((char*)message.c_str(), (int)message.size());
    char recv_code;
    skt.recv(&recv_code, 1);
    if(recv_code == 0x1) {
        throw nar::Exception::LowLevelMessaging::FormatError("Format error.");
    } else if(recv_code == 0x2) {
        throw nar::Exception::LowLevelMessaging::ServerSizeIntOverflow("Message size is greater than max in of server", sizei);
    } else if(recv_code == 0x3) {
        return;
    }
}

void nar::send_message(nar::Socket* skt, std::string message) {
    nar::send_message(*skt, message);
}

/* LOW LEVEL SOCKET MESSAGE EXCHANGE END */

byte* nar::string_to_byte(std::string &key) {
    int len = key.length();
    byte *aes = new byte[len];
    for(int i=0; i<len; i++) {
        aes[i] = (unsigned char )key[i];
    }
    return aes;
}

std::string nar::byte_to_hex(byte* arr, int len) {
    std::string res;
    for(int i=0; i<len; i++) {
        res.push_back(hexmap[(arr[i] & 0xf0) >> 4]);
        res.push_back(hexmap[arr[i] & 0xf]);
    }
    return res;
}

byte* nar::hex_to_byte(std::string hex) {
    byte* res = new byte[hex.size()/2];
    for(int i=0; i<hex.size()/2; i++) {
        if(hex[i<<1] >= '0' && hex[i<<1] <= '9')
            res[i] = ((hex[i<<1] - '0') << 4);
        else if(hex[i<<1] >= 'a' && hex[i<<1] <= 'f')
            res[i] = ((hex[i<<1] - 'a' + 10) << 4);

        if(hex[(i<<1) + 1] >= '0' &&  hex[(i<<1) + 1] <= '9')
            res[i] += hex[(i<<1) + 1] - '0';
        else if(hex[(i<<1) + 1] >= 'a' &&  hex[(i<<1) + 1] <= 'f')
            res[i] += hex[(i<<1) + 1] - 'a' + 10;
    }
    return res;
}

std::string nar::trim(std::string inp) {
    size_t first = inp.find_first_not_of(std::string(" \n"));
    if(std::string::npos == first)
        return inp;
    size_t last = inp.find_last_not_of(std::string(" \n"));
    return inp.substr(first, (last-first+1));
}

bool nar::isChunkExists(std::string& file_name) {
	bool isexists = true;
	boost::filesystem::path dir(file_name);
    try {
        dir = boost::filesystem::canonical(dir);
    } catch (boost::filesystem::filesystem_error er) {
        aNAR_LOG << er.what() << '\n';
		isexists = false;
        return isexists;
    }
	return isexists;
}

max_stars_repo_name: webcok/nar

max_issues_repo_name: webcok/nar

max_forks_repo_name: webcok/nar


text:
///////////////////////////////////////////////////////////////////////////////
/// \file promotion.hpp
/// Defines the result matrices of adding, subtracting, multiplying and
/// dividing the various flavors of time series
//
//  Copyright 2006 Eric Niebler. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_TIME_SERIES_TRAITS_PROMOTION_EAN_04_27_2006
#define BOOST_TIME_SERIES_TRAITS_PROMOTION_EAN_04_27_2006

#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/time_series/time_series_fwd.hpp>

namespace boost { namespace time_series { namespace traits
{
    // Addition / Subtraction promotion rules
    template<typename Tag>
    struct is_delta
      : is_same<Tag, delta_storage_tag>
    {};

    template<typename Tag>
    struct is_dense
      : is_same<Tag, dense_storage_tag>
    {};

    template<typename Tag>
    struct is_constant
      : is_same<Tag, constant_storage_tag>
    {};

    template<typename Tag>
    struct is_piecewise_constant
      : is_same<Tag, piecewise_constant_storage_tag>
    {};

    template<typename Tag>
    struct is_piecewise
      : mpl::or_<
            is_same<Tag, characteristic_storage_tag>
          , is_same<Tag, heaviside_storage_tag>
          , is_same<Tag, inverse_heaviside_storage_tag>
          , mpl::or_<is_constant<Tag>, is_piecewise_constant<Tag> >
        >
    {};

    template<typename Tag>
    struct is_piecewise<scaled_storage_tag<Tag> >
      : is_piecewise<Tag>
    {};

    template<typename Tag>
    struct is_sparse
      : mpl::or_<is_same<Tag, sparse_storage_tag>, is_same<Tag, delta_storage_tag> >
    {};

    template<typename Tag>
    struct is_sparse<scaled_storage_tag<Tag> >
      : is_sparse<Tag>
    {};

    // 1) Adding anything to a dense array gives a dense array
    // 2) Adding two of (piecewise_constant, heaviside, inverse heaviside,
    //      characteristic or constant) yields a piecewise_constant.
    // 3) Adding two of (sparse or delta) yields a sparse array
    template<typename Left, typename Right>
    struct plus
      : mpl::eval_if<
            mpl::or_<is_dense<Left>, is_dense<Right> >
          , mpl::identity<dense_storage_tag>
          , mpl::eval_if<
                mpl::or_<is_piecewise<Left>, is_piecewise<Right> >
              , mpl::identity<piecewise_constant_storage_tag>
              , mpl::if_<
                    mpl::or_<is_sparse<Left>, is_sparse<Right> >
                  , sparse_storage_tag
                  , void
                >
            >
        >
    {};

    // Special case: adding two constant_series gives a constant series
    template<>
    struct plus<constant_storage_tag, constant_storage_tag>
    {
        typedef constant_storage_tag type;
    };

    // Subtraction follows the same rules as addition
    template<typename Left, typename Right>
    struct minus
      : plus<Left, Right>
    {};

    template<typename Tag>
    struct is_unit
      : mpl::or_<
            is_same<Tag, heaviside_storage_tag>
          , is_same<Tag, inverse_heaviside_storage_tag>
          , is_same<Tag, characteristic_storage_tag>
          , is_same<Tag, delta_storage_tag>
        >
    {};

    template<typename Tag>
    struct is_unit<scaled_storage_tag<Tag> >
      : is_unit<Tag>
    {};

    // Matthias
    // heaviside series, inverse heaviside series, characteristic series and
    // their scaled variants:
    // These act like filters on the range of allowed indices. Thus the return type of multiplying
    // them with any other series is usually of the type of that other series.
    // The only special cases are products of these series with themselves. Multiplying
    // two series of the same type gives a series of that type (e.g. heaviside series multiplied
    // with heaviside series gives a heaviside series). Multiplying two different
    // types always gives a characteristic series (e.g. multiplying heaviside series with
    // inverse heaviside series). The range of allowed indices is the intersection of the runs.
    // If one of the series is scaled (and not a unit series), the result will also be scaled.
    template<
        typename Left
      , typename Right
      , typename IsLeftUnit = typename is_unit<Left>::type
      , typename IsRightUnit = typename is_unit<Right>::type
    >
    struct unit_mult;

    template<typename Unit>
    struct unit_mult<Unit, Unit, mpl::true_, mpl::true_>
    {
        typedef Unit type;
    };

    template<typename Left, typename Right>
    struct unit_mult<Left, Right, mpl::true_, mpl::true_>
    {
        typedef characteristic_storage_tag type;
    };

    template<typename Left, typename Right>
    struct unit_mult<Left, Right, mpl::false_, mpl::true_>
    {
        typedef Left type;
    };

    template<typename Left, typename Right>
    struct unit_mult<Left, Right, mpl::true_, mpl::false_>
    {
        typedef Right type;
    };

    template<typename Left, typename Right>
    struct multiplies
      : mpl::eval_if<
            mpl::or_<is_delta<Left>, is_delta<Right> >
          , scaled_storage_tag<delta_storage_tag>
          , mpl::eval_if<
                mpl::or_<is_sparse<Left>, is_sparse<Right> >
              , mpl::identity<sparse_storage_tag>
              , mpl::eval_if<
                    mpl::or_<is_unit<Left>, is_unit<Right> >
                  , unit_mult<Left, Right>
                  , mpl::if_<
                        mpl::and_<is_piecewise_constant<Left>, is_piecewise_constant<Right> >
                      , piecewise_constant_storage_tag
                      , dense_storage_tag
                    >
                >
            >
        >
    {};

    // Special case: multiplying any unit array by a constant array
    // yields a scaled variant of the unit array. Otherwise, it leaves
    // other types unchanged.
    template<typename Left>
    struct multiplies<Left, constant_storage_tag>
      : mpl::eval_if<
            is_unit<Left>
          , scaled_storage_tag<Left>
          , mpl::identity<Left>
        >
    {};

    template<typename Right>
    struct multiplies<constant_storage_tag, Right>
      : mpl::eval_if<
            is_unit<Right>
          , scaled_storage_tag<Right>
          , mpl::identity<Right>
        >
    {};

    template<>
    struct multiplies<constant_storage_tag, constant_storage_tag>
    {
        typedef constant_storage_tag type;
    };

    template<>
    struct multiplies<delta_storage_tag, delta_storage_tag>
    {
        typedef delta_storage_tag type;
    };

    // Not all series types can be used as the divisor in series division.
    template<typename Divisor>
    struct is_valid_divisor
      : mpl::or_<
            is_same<Divisor, dense_storage_tag>
          , is_same<Divisor, constant_storage_tag>
          , is_same<Divisor, piecewise_constant_storage_tag>
        >
    {};

    // Matthias:
    // Note that dividing by anything but a dense series, constant series or
    // piecewise constant series is generally not well defined, and should
    // probably not be implemented at all for these types
    template<typename Left, typename Right>
    struct divides
      : multiplies<Left, Right>
    {
        BOOST_MPL_ASSERT((is_valid_divisor<Right>));
    };

}}} // boost::time_series::traits

#endif