text:
#include "qasioeventdispatcher.h"
#include <boost/asio/io_service.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/bind.hpp>

#include <qpa/qwindowsysteminterface.h>
//#include "qplatformdefs.h"

#include "qcoreapplication.h"
#include "qpair.h"
#include "qsocketnotifier.h"
#include "qthread.h"
#include "qelapsedtimer.h"

#include "private/qtimerinfo_unix_p.h"

#define LOG(expr) #expr": " << (expr) << "; "

/* TODO:
 * - error types of sockets
 * - handling flags passed to processEvents
 */

// One object per fd; three QSocketNotifier's may be connected to it;
struct QAsioSockNotifier
{
    QAsioSockNotifier()
        : pending_operations(0)
    {
        for(int i=0; i<3; ++i) {
            notif[i]=0;
            revision[i]=0;
        }
    }

    QSocketNotifier *notif[3]; //notifiers for {Read, Write, Exception}
    int revision[3]; //revision[x] is incremented each time notif[i] is changed (therefore a new completion handler loop is started)
    int fd;
    boost::asio::posix::stream_descriptor *sd;
    int pending_operations;
};

class Q_CORE_EXPORT QAsioEventDispatcherPrivate : public QAbstractEventDispatcherPrivate
{
    Q_DECLARE_PUBLIC(QAsioEventDispatcher)

public:
    QAsioEventDispatcherPrivate(boost::asio::io_service &io_service);
    ~QAsioEventDispatcherPrivate();

    boost::asio::io_service &io_service;
    boost::asio::steady_timer nearest_timer;
    QList<QAsioSockNotifier *> socketNotifiers;
    QTimerInfoList timerList;

    QAtomicInt interrupt;
    QAsioSockNotifier *socketNotifierForFd(int fd, bool createIfNotFound);
    void cleanupSocketNotifiers(bool forceRemoveAll);
    void timerTimeout(const boost::system::error_code &error);
    void timerStart();
    void timerCancel();
};

QAsioEventDispatcherPrivate::QAsioEventDispatcherPrivate(boost::asio::io_service &io_service_)
    : io_service(io_service_)
    , nearest_timer(io_service)
{
}

QAsioEventDispatcherPrivate::~QAsioEventDispatcherPrivate()
{
    cleanupSocketNotifiers(true);
    Q_ASSERT(socketNotifiers.empty());
    // cleanup timers
    qDeleteAll(timerList);
}

QAsioEventDispatcher::QAsioEventDispatcher(boost::asio::io_service &io_service, QObject *parent)
    : QAbstractEventDispatcher(*new QAsioEventDispatcherPrivate(io_service), parent)
{
}

QAsioEventDispatcher::QAsioEventDispatcher(QAsioEventDispatcherPrivate &dd, QObject *parent)
    : QAbstractEventDispatcher(dd, parent)
{ }

QAsioEventDispatcher::~QAsioEventDispatcher()
{
}

void QAsioEventDispatcherPrivate::timerTimeout(const boost::system::error_code& error)
{
    if(!error) {
        (void) timerList.activateTimers();
    }
}

void QAsioEventDispatcherPrivate::timerStart()
{
    timespec tv = { 0l, 0l };
#if BOOST_ASIO_HAS_STD_CHRONO
    using namespace std::chrono;
#else
    using namespace boost::chrono;
#endif
    if (/*FIXME: !(src->processEventsFlags & QEventLoop::X11ExcludeTimers) && */timerList.timerWait(tv)) {
        nearest_timer.cancel();
        nearest_timer.expires_from_now(seconds(tv.tv_sec) + nanoseconds(tv.tv_nsec ));
        nearest_timer.async_wait(boost::bind(&QAsioEventDispatcherPrivate::timerTimeout, this, _1));
    }
}

void QAsioEventDispatcherPrivate::timerCancel()
{
    nearest_timer.cancel();
}

void QAsioEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj)
{
#ifndef QT_NO_DEBUG
    if (timerId < 1 || interval < 0 || !obj) {
        qWarning("QAsioEventDispatcher::registerTimer: invalid arguments");
        return;
    } else if (obj->thread() != thread() || thread() != QThread::currentThread()) {
        qWarning("QObject::startTimer: timers cannot be started from another thread");
        return;
    }
#endif

    Q_D(QAsioEventDispatcher);
    d->timerList.registerTimer(timerId, interval, timerType, obj);
}

/*!
    \internal
*/
bool QAsioEventDispatcher::unregisterTimer(int timerId)
{
#ifndef QT_NO_DEBUG
    if (timerId < 1) {
        qWarning("QAsioEventDispatcher::unregisterTimer: invalid argument");
        return false;
    } else if (thread() != QThread::currentThread()) {
        qWarning("QObject::killTimer: timers cannot be stopped from another thread");
        return false;
    }
#endif

    Q_D(QAsioEventDispatcher);
    return d->timerList.unregisterTimer(timerId);
}

/*!
    \internal
*/
bool QAsioEventDispatcher::unregisterTimers(QObject *object)
{
#ifndef QT_NO_DEBUG
    if (!object) {
        qWarning("QAsioEventDispatcher::unregisterTimers: invalid argument");
        return false;
    } else if (object->thread() != thread() || thread() != QThread::currentThread()) {
        qWarning("QObject::killTimers: timers cannot be stopped from another thread");
        return false;
    }
#endif

    Q_D(QAsioEventDispatcher);
    return d->timerList.unregisterTimers(object);
}

QList<QAsioEventDispatcher::TimerInfo>
QAsioEventDispatcher::registeredTimers(QObject *object) const
{
    if (!object) {
        qWarning("QAsioEventDispatcher:registeredTimers: invalid argument");
        return QList<TimerInfo>();
    }

    Q_D(const QAsioEventDispatcher);
    return d->timerList.registeredTimers(object);
}

int QAsioEventDispatcher::remainingTime(int timerId)
{
#ifndef QT_NO_DEBUG
    if (timerId < 1) {
        qWarning("QAsioEventDispatcher::remainingTime: invalid argument");
        return -1;
    }
#endif
    //FIXME
    Q_D(QAsioEventDispatcher);
    return d->timerList.timerRemainingTime(timerId);
}

QAsioSockNotifier *QAsioEventDispatcherPrivate::socketNotifierForFd(int fd, bool createIfNotFound)
{
    for(int i = 0; i < socketNotifiers.count(); ++i) {
        QAsioSockNotifier *n = socketNotifiers.at(i);
        if(n->fd == fd) return n;
    }
    if(createIfNotFound)
    {
        QAsioSockNotifier *sn = new QAsioSockNotifier;
        sn->fd = fd;
        sn->sd = new boost::asio::posix::stream_descriptor(io_service, fd);
        socketNotifiers.push_back(sn);
        return sn;
    }
    return 0;
}

void QAsioEventDispatcherPrivate::cleanupSocketNotifiers(bool forceRemoveAll = false)
{
    for(int i = 0; i < socketNotifiers.count();) {
        QAsioSockNotifier *sn = socketNotifiers.at(i);
        if(sn->pending_operations == 0 || forceRemoveAll) {
            if(!forceRemoveAll) {
                Q_ASSERT(sn->notif[0] == 0
                    && sn->notif[1] == 0
                    && sn->notif[2] == 0);
            }
            //removeAll, but there should be only one instance in the list
            socketNotifiers.removeAll(sn);
            delete sn->sd;
            delete sn;
        }
        else {
            ++i;
        }
    }
}

static void fdReadStart(QAsioSockNotifier *sn);
static void fdWriteStart(QAsioSockNotifier *sn);

static void fdReadReady(QAsioSockNotifier *sn, const boost::system::error_code& error, int revision)
{
    sn->pending_operations--;
    int type = (int)QSocketNotifier::Read;
    bool sn_changed = sn->revision[type] != revision;

    if(!sn_changed && !error) {
        fdReadStart(sn);
        QEvent event(QEvent::SockAct);
        QCoreApplication::sendEvent(sn->notif[type], &event);
    }
    else {
    }
}

static void fdWriteReady(QAsioSockNotifier *sn, const boost::system::error_code& error, int revision)
{
    sn->pending_operations--;
    int type = (int)QSocketNotifier::Write;
    bool sn_changed = sn->revision[type] != revision;

    if(!sn_changed && !error) {
        fdWriteStart(sn);
        QEvent event(QEvent::SockAct);
        QCoreApplication::sendEvent(sn->notif[type], &event);
    }
    else {
    }
}

static void fdReadStart(QAsioSockNotifier *sn)
{
    int type = (int)QSocketNotifier::Read;
    sn->pending_operations++;
    Q_ASSERT(sn->notif[type]);
    sn->sd->async_read_some(boost::asio::null_buffers(), boost::bind(fdReadReady, sn, _1, sn->revision[type]));
}

static void fdWriteStart(QAsioSockNotifier *sn)
{
    int type = (int)QSocketNotifier::Write;
    sn->pending_operations++;
    Q_ASSERT(sn->notif[type]);
    sn->sd->async_write_some(boost::asio::null_buffers(), boost::bind(fdWriteReady, sn, _1, sn->revision[type]));
}

void QAsioEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
{
    //std::clog<< __PRETTY_FUNCTION__ << LOG(notifier->type()) << LOG(notifier->socket())  << std::endl;
    Q_ASSERT(notifier);
    int sockfd = notifier->socket();
    int type = notifier->type();
#ifndef QT_NO_DEBUG
    if (sockfd < 0
        || unsigned(sockfd) >= FD_SETSIZE) {
        qWarning("QSocketNotifier: Internal error");
        return;
    } else if (notifier->thread() != thread()
               || thread() != QThread::currentThread()) {
        qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");
        return;
    }
#endif

    Q_D(QAsioEventDispatcher);
    //std::clog << LOG(d->socketNotifiers.size()) << std::endl;

    QAsioSockNotifier *sn = d->socketNotifierForFd(sockfd, true);

    Q_ASSERT(sn);
    Q_ASSERT(type<3 && type>=0);
    Q_ASSERT(sn->notif[type] == 0);

    sn->notif[type] = notifier;
    sn->revision[type]++;
    switch(type)
    {
        case QSocketNotifier::Read:
            fdReadStart(sn);
            break;
        case QSocketNotifier::Write:
            fdWriteStart(sn);
            break;
        default:
            qFatal("Not supported socket type");
        //TODO: write, error...
    }
}

void QAsioEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
{
    //std::clog<< __PRETTY_FUNCTION__ << LOG(notifier->type()) << LOG(notifier->socket()) << std::endl;
    Q_ASSERT(notifier);
    int sockfd = notifier->socket();
    int type = notifier->type();
#ifndef QT_NO_DEBUG
    if (sockfd < 0
        || unsigned(sockfd) >= FD_SETSIZE) {
        qWarning("QSocketNotifier: Internal error");
        return;
    } else if (notifier->thread() != thread()
               || thread() != QThread::currentThread()) {
        qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");
        return;
    }
#endif

    Q_D(QAsioEventDispatcher);
    QAsioSockNotifier *sn = d->socketNotifierForFd(sockfd, false);
    Q_ASSERT(sn);
    if(sn)
    {
        Q_ASSERT(sn->notif[type] == notifier);
        sn->notif[type] = 0;
        sn->revision[type]++;
        if(sn->notif[0] == 0
                && sn->notif[1] == 0
                && sn->notif[2] == 0
                ) {
            //if no more socket notifiers on given fd are pending, we don't need it anymore
            //but we cannot delete "sn" yet, since some handlers that use it may be pending (see fdMaybeCleanup())
            sn->sd->cancel();
            //sn->sd->close();
            //d->removeSocketNotifier(sn);
            //FIXME: what if we create a new sn on the same fd soon (while handlers are still pending)?
        }
        //if not all notifiers are unregistered, we don't cancel pending handler, since we cannot do it selectively (i.e. cancel only read or only write)
        //however, it's not a problem, since it will notice that sn->revision doesn't match and will "cancel" itself during the next call
    }
}

bool QAsioEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
{
    Q_D(QAsioEventDispatcher);
    d->interrupt.store(0);

    //QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); //unix dispatcher use this
    QCoreApplication::sendPostedEvents(); //glib dispatcher call this after every call of "awake".

    const bool canWait = (/*d->threadData->canWaitLocked()
                          &&*/ !d->interrupt.load() //it may have been set during the call of QCoreApplication::sendPostedEvents()
                          && (flags & QEventLoop::WaitForMoreEvents));

    if (d->interrupt.load())
    {
        return false; //unix event dispatcher returns false if nothing more than "postedEvents" were dispatched
    }

    if (!(flags & QEventLoop::X11ExcludeTimers)) {
        d->timerStart();
    }

    int total_events = 0; /* FIXME: +1 for stop? */

    if (canWait) {
        //run at least one handler - may block
        emit aboutToBlock();
        d->io_service.reset();
        total_events += d->io_service.run_one();
        emit awake();
    }

    int events;
    do
    {
        if (!(flags & QEventLoop::X11ExcludeTimers)) {
            d->timerStart();
        }

        d->io_service.reset();
        //run all ready handlers
        events = d->io_service.poll();

        if ((flags & QEventLoop::ExcludeSocketNotifiers)) {
            //FIXME: ignore stream descriptors
        }

        if ((flags & QEventLoop::X11ExcludeTimers)) {
            //FIXME: ignore timers?
        }

        total_events += events;
        QCoreApplication::sendPostedEvents();
        total_events += QWindowSystemInterface::sendWindowSystemEvents(flags) ? 1 : 0;
    } while(events>0);

    d->cleanupSocketNotifiers();

    // return true if we handled events, false otherwise
    return  (total_events > 0);
}

bool QAsioEventDispatcher::hasPendingEvents()
{
    //This is copy-pasted from QUnixEventDispatcherQPA. I don't really understand how it works.
    extern uint qGlobalPostedEventsCount(); // from qapplication.cpp
    return qGlobalPostedEventsCount() || QWindowSystemInterface::windowSystemEventsQueued();
}

void QAsioEventDispatcher::wakeUp()
{
    Q_D(QAsioEventDispatcher);
    //I don't know what a logic stays behind it, but qeventdispatcher_glib works in such a way, that after every "wakeUp", the following function is called
    //io_service.post(QCoreApplication::sendPostedEvents);
    d->io_service.stop(); //exit from run_one
}

void QAsioEventDispatcher::interrupt()
{
    Q_D(QAsioEventDispatcher);
    d->interrupt.store(1);
    wakeUp();
}

void QAsioEventDispatcher::flush()
{
    /* It does nothing in glib event dispatcher.
     *
     * QUnixEventDispatcherQPA calls QCoreApplication::instance()->sendPostedEvents here.
     *
     * But the docs of QAbstractEventDispatcher says:
     * "flushes the event queue. This normally returns almost immediately. Does nothing on platforms other than X11"
     *
     * I'm a bit confused. FIXME
     */
}

QT_END_NAMESPACE

max_stars_repo_name: mikalv/qtasio

max_issues_repo_name: mikalv/qtasio

max_forks_repo_name: mikalv/qtasio


text:
#include <terra/interpreter.h>

#include <terra/expr_visitor.h>
#include <terra/line_observer.h>
#include <terra/tile.h>
#include <terra/tile_observer.h>

#include <terra/exprs/literals.h>
#include <terra/exprs/var_ref.h>
#include <terra/exprs/vector_combiner.h>

#include <algorithm>
#include <type_traits>
#include <vector>

#include <Eigen/Dense>

namespace terra {

namespace {

template<typename Scalar>
Scalar
Clamp(Scalar x, Scalar min, Scalar max) noexcept
{
  return std::min(std::max(x, min), max);
}

struct BuiltinVars final
{
  float uCenter;
  float vCenter;
};

namespace impl {

template<typename Scalar, size_t Size>
using Vector = Eigen::Matrix<Scalar, Size, 1>;

template<typename Type>
class Expr
{
public:
  virtual ~Expr() = default;

  virtual Type Eval(const BuiltinVars&) const noexcept = 0;
};

template<typename Scalar, size_t Size>
using VectorExpr = Expr<Vector<Scalar, Size>>;

class UCenterExpr final : public Expr<float>
{
public:
  float Eval(const BuiltinVars& builtinVars) const noexcept override
  {
    return builtinVars.uCenter;
  }
};

class VCenterExpr final : public Expr<float>
{
public:
  float Eval(const BuiltinVars& builtinVars) const noexcept override
  {
    return builtinVars.vCenter;
  }
};

template<typename Scalar, size_t Size>
class VectorCombinerExpr final : public VectorExpr<Scalar, Size>
{
public:
  VectorCombinerExpr(std::array<std::unique_ptr<Expr<Scalar>>, Size> elements)
    : mElements(std::move(elements))
  {}

  auto Eval(const BuiltinVars& builtinVars) const noexcept
    -> Vector<Scalar, Size> override
  {
    Vector<Scalar, Size> result;

    for (size_t i = 0; i < Size; i++)
      result(i) = mElements[i]->Eval(builtinVars);

    return result;
  }

private:
  std::array<std::unique_ptr<Expr<Scalar>>, Size> mElements;
};

template<typename Scalar>
class LiteralExpr final : public Expr<Scalar>
{
public:
  LiteralExpr(Scalar value) noexcept
    : mValue(value)
  {}

  Scalar Eval(const BuiltinVars&) const noexcept override { return mValue; }

private:
  Scalar mValue;
};

} // namespace impl

template<typename Type>
class ExprBuilder final : public ExprVisitor
{
public:
  auto TakeExpr() -> std::unique_ptr<impl::Expr<Type>>
  {
    return std::move(mExpr);
  }

  void Visit(const VarRefExpr& varRef) override
  {
    switch (varRef.GetID()) {
      case VarRefExpr::ID::CenterU:
        if constexpr (std::is_same<Type, float>::value)
          mExpr.reset(new impl::UCenterExpr());
        break;
      case VarRefExpr::ID::CenterV:
        if constexpr (std::is_same<Type, float>::value)
          mExpr.reset(new impl::VCenterExpr());
        break;
    }
  }

  void Visit(const IntLiteralExpr& intLiteral) override
  {
    if constexpr (std::is_same<Type, int>::value)
      mExpr.reset(new impl::LiteralExpr<int>(intLiteral.GetValue()));
  }

  void Visit(const FloatLiteralExpr& floatLiteral) override
  {
    if constexpr (std::is_same<Type, float>::value)
      mExpr.reset(new impl::LiteralExpr<float>(floatLiteral.GetValue()));
  }

  void Visit(const FloatToIntExpr&) override {}

  void Visit(const IntToFloatExpr&) override {}

  void Visit(const UnaryExpr&) override {}

  void Visit(const BinaryExpr&) override {}

  void Visit(const VectorCombiner<2>& vecCombiner) override
  {
    if constexpr (std::is_same<Type, impl::Vector<float, 2>>::value)
      HandleVectorCombiner(vecCombiner);
  }

  void Visit(const VectorCombiner<3>& vecCombiner) override
  {
    if constexpr (std::is_same<Type, impl::Vector<float, 3>>::value)
      HandleVectorCombiner(vecCombiner);
  }

  void Visit(const VectorCombiner<4>& vecCombiner) override
  {
    if constexpr (std::is_same<Type, impl::Vector<float, 4>>::value)
      HandleVectorCombiner(vecCombiner);
  }

private:
  template<size_t Size>
  void HandleVectorCombiner(const VectorCombiner<Size>& vecCombiner)
  {
    std::array<std::unique_ptr<impl::Expr<float>>, Size> elements;

    for (size_t i = 0; i < Size; i++) {

      ExprBuilder<float> elementBuilder;

      vecCombiner.GetElement(i).Accept(elementBuilder);

      elements[i] = elementBuilder.TakeExpr();
    }

    mExpr.reset(new impl::VectorCombinerExpr<float, Size>(std::move(elements)));
  }

private:
  std::unique_ptr<impl::Expr<Type>> mExpr;
};

struct FrameStatus final
{
  FrameStatus(size_t tilesPerRow, size_t tilesPerCol, size_t w, size_t h)
    : tileCount(tilesPerRow * tilesPerCol)
    , tileIndex(0)
    , resX(w)
    , resY(h)
  {}

  size_t tileCount = 0;

  size_t tileIndex = 0;

  size_t resX = 0;

  size_t resY = 0;

  size_t GetNextXOffset() const noexcept
  {
    return (tileIndex * TileSize()) % resX;
  }

  size_t GetNextYOffset() const noexcept
  {
    return ((tileIndex * TileSize()) / resX) * TileSize();
  }

  size_t GetNextWidth() const noexcept
  {
    auto offset = GetNextXOffset();

    auto end = offset + TileSize();

    return std::min(end, resX) - offset;
  }

  size_t GetNextHeight() const noexcept
  {
    auto offset = GetNextYOffset();

    auto end = offset + TileSize();

    return std::min(end, resY) - offset;
  }
};

class RenderTask final
{
public:
  RenderTask(Tile& tile, const impl::Expr<float>& heightExpr)
    : mTile(tile)
    , mHeightExpr(heightExpr)
  {}

  void operator()() noexcept
  {
    auto& buffer = mTile.GetBuffer();

    for (size_t i = 0; i < (TileSize() * TileSize()); i++) {

      size_t x = i % TileSize();
      size_t y = i / TileSize();

      BuiltinVars builtinVars;
      builtinVars.uCenter = (x + 0.5f) / TileSize();
      builtinVars.vCenter = (y + 0.5f) / TileSize();

      auto h = mHeightExpr.Eval(builtinVars);

      buffer[(i * 4) + 0] = h;
      buffer[(i * 4) + 1] = 0;
      buffer[(i * 4) + 2] = 0;
      buffer[(i * 4) + 3] = 0;
    }
  }

private:
  Tile& mTile;

  const impl::Expr<float>& mHeightExpr;
};

class TileInterpreterImpl final : public TileInterpreter
{
public:
  void AddTileObserver(std::shared_ptr<TileObserver> observer) override
  {
    mTileObservers.emplace_back(std::move(observer));
  }

  bool FrameIsDone() const noexcept override { return TilesRemaining() == 0; }

  size_t TilesRemaining() const noexcept override
  {
    if (!mFrameStatus)
      return 0;

    return mFrameStatus->tileCount - mFrameStatus->tileIndex;
  }

  bool BeginFrame() override
  {
    if (mFrameStatus)
      return false;

    size_t tilesPerRow = (mResX + (TileSize() - 1)) / TileSize();

    size_t tilesPerCol = (mResY + (TileSize() - 1)) / TileSize();

    mFrameStatus.reset(new FrameStatus(tilesPerRow, tilesPerCol, mResX, mResY));

    return true;
  }

  bool PollTiles(size_t) override
  {
    if (!mFrameStatus || !mHeightExpr)
      return false;

    auto x = mFrameStatus->GetNextXOffset();
    auto y = mFrameStatus->GetNextYOffset();
    auto w = mFrameStatus->GetNextWidth();
    auto h = mFrameStatus->GetNextHeight();

    Tile tile(x, y, w, h);

    RenderTask renderTask(tile, *mHeightExpr);

    renderTask();

    NotifyTileObservers(tile);

    mFrameStatus->tileIndex++;

    return true;
  }

  bool EndFrame() override
  {
    if (!mFrameStatus)
      return false;

    mFrameStatus.reset();

    return true;
  }

  bool SetHeightExpr(const terra::Expr& heightExpr) override
  {
    ExprBuilder<float> exprBuilder;

    heightExpr.Accept(exprBuilder);

    mHeightExpr = exprBuilder.TakeExpr();

    return !!mHeightExpr;
  }

  void SetResolution(size_t w, size_t h) override
  {
    mResX = w;
    mResY = h;
  }

private:
  void NotifyTileObservers(const Tile& tile)
  {
    for (auto& tileObserver : mTileObservers)
      tileObserver->Observe(tile);
  }

private:
  size_t mResX = 0;

  size_t mResY = 0;

  std::vector<std::shared_ptr<TileObserver>> mTileObservers;

  std::unique_ptr<FrameStatus> mFrameStatus;

  std::unique_ptr<impl::Expr<float>> mHeightExpr;
};

} // namespace

auto
TileInterpreter::Make() -> std::unique_ptr<TileInterpreter>
{
  return std::unique_ptr<TileInterpreter>(new TileInterpreterImpl());
}

namespace {

class LineInterpreterImpl final : public LineInterpreter
{
public:
  LineInterpreterImpl(size_t w, size_t h, LineObserver& lineObserver)
    : mWidth(w)
    , mHeight(h)
    , mLineObserver(lineObserver)
  {}

  bool SetHeightExpr(const Expr& heightExpr) override
  {
    ExprBuilder<float> exprBuilder;

    heightExpr.Accept(exprBuilder);

    mHeightExpr = exprBuilder.TakeExpr();

    return true;
  }

  bool SetColorExpr(const Expr& expr) override
  {
    ExprBuilder<impl::Vector<float, 3>> exprBuilder;

    expr.Accept(exprBuilder);

    mColorExpr = exprBuilder.TakeExpr();

    return true;
  }

  bool Execute() override
  {
    if (!mHeightExpr || !mColorExpr)
      return false;

    std::vector<float> heightAndRgbBuffer(mWidth * 4);

    for (size_t y = 0; y < mHeight; y++) {

      for (size_t x = 0; x < mWidth; x++) {

        BuiltinVars builtinVars;
        builtinVars.uCenter = (x + 0.5f) / mWidth;
        builtinVars.vCenter = (y + 0.5f) / mHeight;

        auto h = mHeightExpr->Eval(builtinVars);

        auto c = mColorExpr->Eval(builtinVars);

        heightAndRgbBuffer[(x * 4) + 0] = h;
        heightAndRgbBuffer[(x * 4) + 1] = Clamp(c(0) * 255.0f, 0.0f, 255.0f);
        heightAndRgbBuffer[(x * 4) + 2] = Clamp(c(1) * 255.0f, 0.0f, 255.0f);
        heightAndRgbBuffer[(x * 4) + 3] = Clamp(c(2) * 255.0f, 0.0f, 255.0f);
      }

      mLineObserver.Observe(heightAndRgbBuffer.data());
    }

    return true;
  }

private:
  size_t mWidth;

  size_t mHeight;

  LineObserver& mLineObserver;

  std::unique_ptr<impl::Expr<float>> mHeightExpr;

  std::unique_ptr<impl::Expr<impl::Vector<float, 3>>> mColorExpr;
};

} // namespace

auto
LineInterpreter::Make(size_t w, size_t h, LineObserver& lineObserver)
  -> std::unique_ptr<LineInterpreter>
{
  using Ret = std::unique_ptr<LineInterpreter>;

  return Ret(new LineInterpreterImpl(w, h, lineObserver));
}

} // namespace terra

ext: cpp


text:
//==============================================================================
//         Copyright 2003 - 2012 LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012 LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          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 BOOST_SIMD_OPERATOR_FUNCTIONS_SIMD_COMMON_DETAILS_DETAILS_LOAD_STORE_HPP_INCLUDED
#define BOOST_SIMD_OPERATOR_FUNCTIONS_SIMD_COMMON_DETAILS_DETAILS_LOAD_STORE_HPP_INCLUDED

#include <boost/dispatch/functor/meta/make_functor.hpp>
#include <boost/dispatch/meta/as.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/fusion/include/value_at.hpp>

////////////////////////////////////////////////////////////////////////////////
// Helpers for load and store over a fusion sequence.
////////////////////////////////////////////////////////////////////////////////
namespace boost { namespace simd { namespace details
{
  template<class Tag, class A0, class A1, class A2>
  struct loader
  {
    loader(A0 const& a0_, A1 const& a1_, A2& a2_)
    : a0(a0_), a1(a1_), a2(a2_)
    {}

    template<int I>
    void operator()() const
    {
      typename dispatch::
      make_functor< Tag
                  , typename fusion::result_of::value_at_c<A0,I>::type
                  >::type callee;
      fusion::at_c<I>(a2) = callee( fusion::at_c<I>(a0)
                                  , a1
                                  , dispatch::meta::as_<typename fusion::result_of::value_at_c<A2,I>::type>());
    }

    A0 const& a0;
    A1 const& a1;
    A2 &      a2;
  };

  template<class Tag, class A0, class A1, class A2>
  struct storer
  {
    storer(A0 const& a0_, A1 const& a1_, A2 const& a2_)
    : a0(a0_), a1(a1_), a2(a2_)
    {}

    template<int I>
    void operator()() const
    {
      typename dispatch::
      make_functor< Tag
                  , typename fusion::result_of::value_at_c<A0,I>::type
                  >::type callee;
      callee( fusion::at_c<I>(a0)
            , fusion::at_c<I>(a1)
            , a2
            );
    }

    A0 const& a0;
    A1 const& a1;
    A2 const& a2;
  };

} } }

#endif

ext: hpp


text:
#include <typeinfo>
#include <iostream>
#include <boost/mpl/size.hpp>

#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>//das kommt aber bitte nich in greatcontainer
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/set.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/iterator_range.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/copy_if.hpp>
#include <boost/mpl/inserter.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/erase_key.hpp>

namespace mpl = boost::mpl;

namespace stl {
  namespace concepts {
    struct container { };
    struct random_access_container {
      typedef mpl::vector1<container> implies;
    };

    struct adapter { };
    struct sequence { };

    struct type_holder { };
  }

  struct vector {
    template<typename Before, typename After>
    struct fragment : public Before { };

    typedef mpl::vector1<concepts::container> concept;
    typedef mpl::vector1<concepts::type_holder> require_before;
  };

  template<typename T>
  struct type {
    template<typename Before, typename After>
    struct fragment : public Before {
      typedef T value_type; // ...
    };

    typedef mpl::vector1<concepts::type_holder> concept;
  };

  struct stack {
    template<typename Before, typename After>
    struct fragment : protected Before { };

    typedef mpl::vector2<concepts::sequence, concepts::adapter> concept;
    typedef mpl::vector2<concepts::type_holder, concepts::container> require_before;
    typedef mpl::map1<mpl::pair<concepts::container, vector> > default_fragment;
    typedef boost::mpl::true_ shadow;
  };
}

namespace concepts {
  struct container {
  };
  struct random_access_container {
    typedef mpl::vector1<container> implies;
  };

  struct foo {
    typedef boost::mpl::false_ shadow;
  };
  struct bar {
    typedef mpl::vector1<random_access_container> implies;
    typedef boost::mpl::false_ shadow;
  };
  struct baz { typedef mpl::vector0< > implies; };

  struct shads {
    typedef mpl::vector1<random_access_container> implies;
    typedef boost::mpl::true_ shadow;
  };

  struct implies_shads {
    typedef mpl::vector1<shads> implies;
  };
}
using namespace concepts;

struct fragment0 {
  template<typename Before, typename After>
  struct fragment : public Before { };

  typedef mpl::vector2<container, foo> concept;
  /*  typedef mpl::vector<X> require;
  typedef mpl::vector<X> require_before;
  typedef mpl::vector<X> require_after;
  typedef mpl::vector<X> demote_concepts;*/
};

struct fragment1 {
  template<typename Before, typename After>
  struct fragment : public Before { };

  typedef mpl::vector1<bar> concept;
  /*typedef mpl::vector<container> require;
    typedef mpl::vector<X> require_before;
  typedef mpl::vector<X> require_after;
  typedef mpl::vector<X> demote_concepts;*/
};

struct fragment2 {
  template<typename Before, typename After>
  struct fragment : public Before { };

  typedef mpl::vector1<random_access_container> concept;
  /*typedef mpl::vector<container> require;
    typedef mpl::vector<X> require_before;
  typedef mpl::vector<X> require_after;
  typedef mpl::vector<X> demote_concepts;*/
};

struct fragment3 {
  template<typename Before, typename After>
  struct fragment : public Before { };

  typedef mpl::vector1<foo> concept;
  typedef mpl::vector1<container> require_before;
  /*  typedef mpl::vector<X> require_before;
  typedef mpl::vector<X> require_after;
  typedef mpl::vector<X> demote_concepts;*/
};

template<typename Sequence>
struct fragment_holder {
  //
};

namespace utils {
  namespace detail {
    BOOST_MPL_HAS_XXX_TRAIT_DEF(implies)

    template<typename FragmentSeq, typename Concept,
             bool empty = mpl::empty<FragmentSeq>::value>
    struct checker {
      typedef typename mpl::front<FragmentSeq>::type checked_concept;

      template<typename CheckedConcept, bool = has_implies<CheckedConcept>::value>
      struct implies {
        static bool const value =
          checker<typename CheckedConcept::implies, Concept>::value;
      };

      template<typename CheckedConcept>
      struct implies<CheckedConcept, false> {
        static bool const value = false;
      };

      static bool const value =
        boost::is_same<checked_concept, Concept>::value ?
        true :
        ( implies<checked_concept>::value ?
          true :
          checker<typename mpl::pop_front<FragmentSeq>::type, Concept>::value);
    };

    template<typename FragmentSeq, typename Concept>
    struct checker<FragmentSeq, Concept, true> {
      static bool const value = false;
    };
  }

  template<typename FragmentClass, typename Concept>
  struct supports_concept
  : boost::integral_constant<bool, detail::checker<typename FragmentClass::concept, Concept>::value>
  {};

  template<typename FragmentList, typename Concept>
  struct has_concept
  : boost::mpl::not_<
      boost::is_same<
        typename boost::mpl::find_if<
          FragmentList,
          supports_concept<boost::mpl::_1, Concept>
        >::type,
        typename boost::mpl::end<FragmentList>::type
      >
    >::type
  { };

  namespace detail {
    BOOST_MPL_HAS_XXX_TRAIT_DEF(require)
    BOOST_MPL_HAS_XXX_TRAIT_DEF(require_before)
    BOOST_MPL_HAS_XXX_TRAIT_DEF(require_after)

    template<
      typename Requirements,
      typename Sequence,
      bool empty = boost::mpl::empty<Requirements>::value
    >
    struct check_requirements
    : boost::mpl::and_<
        typename has_concept<
          Sequence,
          typename boost::mpl::front<Requirements>::type
        >::type,
        typename check_requirements<
          typename boost::mpl::pop_front<Requirements>::type,
          Sequence
        >::type
      >
    { };

    template<
      typename Requirements,
      typename Sequence
    >
    struct check_requirements<Requirements, Sequence, true>
    : boost::mpl::true_ { };

    template<typename Sequence, typename Iterator>
    struct check_requirements_all {
      typedef typename detail::check_requirements<
          typename boost::mpl::deref<Iterator>::type::require,
          Sequence
        >::type type;
    };

    template<typename Sequence, typename Iterator>
    struct check_requirements_before {
      typedef typename detail::check_requirements<
          typename boost::mpl::deref<Iterator>::type::require_before,
          boost::mpl::iterator_range<
            typename boost::mpl::begin<Sequence>::type,
            Iterator
          >
        >::type type;
    };

    template<typename Sequence, typename Iterator>
    struct check_requirements_after {
      typedef typename detail::check_requirements<
          typename boost::mpl::deref<Iterator>::type::require_after,
          boost::mpl::iterator_range<
            typename boost::mpl::next<Iterator>::type,
            typename boost::mpl::end<Sequence>::type
          >
        >::type type;
    };
  }

  template<typename Sequence,
           typename Iterator = typename boost::mpl::begin<Sequence>::type>
  struct check_concepts;

  namespace detail {
    template<typename Sequence, typename Iterator>
    struct check_concepts_impl
    {
      typedef
      boost::mpl::and_<
        check_concepts<
          Sequence,
          typename boost::mpl::next<Iterator>::type
        >,
        boost::mpl::eval_if<
          detail::has_require<
            typename boost::mpl::deref<Iterator>::type
          >,
          detail::check_requirements_all<Sequence, Iterator>,
          boost::mpl::true_
        >,
        boost::mpl::eval_if<
          detail::has_require_before<
            typename boost::mpl::deref<Iterator>::type
          >,
          detail::check_requirements_before<Sequence, Iterator>,
          boost::mpl::true_
        >,
        boost::mpl::eval_if<
          detail::has_require_after<
            typename boost::mpl::deref<Iterator>::type
          >,
          detail::check_requirements_after<Sequence, Iterator>,
          boost::mpl::true_
        >
      >
      type;
    };
  }

  template<typename Sequence,
           typename Iterator>
  struct check_concepts
  : boost::mpl::eval_if<
      boost::is_same<Iterator, typename boost::mpl::end<Sequence>::type>,
      boost::mpl::true_,
      detail::check_concepts_impl<Sequence, Iterator>
    >::type
  { };

  namespace detail {
    template<typename First, typename Last, typename Result>
    struct flatten {
      typedef typename boost::mpl::deref<First>::type deref;

      template<typename T>
      struct subflatten {
        typedef
          typename flatten<
            typename boost::mpl::begin<typename T::implies>::type,
            typename boost::mpl::end<typename T::implies>::type,
            boost::mpl::vector0<>
          >::type type;
      };

      typedef typename boost::mpl::insert_range<
          Result,
          typename boost::mpl::end<Result>::type,
          typename boost::mpl::eval_if<
            has_implies<deref>,
            subflatten<deref>,
            mpl::vector0<>
          >::type
        >::type with_implies;
      typedef typename boost::mpl::insert<
          with_implies,
          typename boost::mpl::end<with_implies>::type,
          deref
        >::type with_deref;

      typedef typename flatten<
          typename boost::mpl::next<First>::type,
          Last,
          with_deref
        >::type type;
    };

    template<typename First, typename Result>
    struct flatten<First, First, Result> {
      typedef Result type;
    };
  }

  template<typename Sequence>
  struct flatten {
    typedef typename detail::flatten<
        typename boost::mpl::begin<Sequence>::type,
        typename boost::mpl::end<Sequence>::type,
        boost::mpl::vector0<>
      >::type
    type;
  };

  namespace detail {
    BOOST_MPL_HAS_XXX_TRAIT_DEF(shadow)

    template<typename Concept, bool x = has_shadow<Concept>::value>
    struct is_shadowing
      : Concept::shadow
    { };

    template<typename Concept>
    struct is_shadowing<Concept, false>
      : boost::mpl::false_
    { };

    template<typename ConceptSeq,
             typename Iterator = typename boost::mpl::begin<ConceptSeq>::type>
    struct is_shadowing_concept_seq;

    template<typename Concept, bool x = has_implies<Concept>::value>
    struct is_shadowing_implies
      : is_shadowing_concept_seq<typename Concept::implies>
    { };

    template<typename Concept>
    struct is_shadowing_implies<Concept, false>
      : boost::mpl::false_
    { };

    template<typename ConceptSeq, typename Iterator>
    struct is_shadowing_concept_seq
    : boost::mpl::eval_if<
        is_shadowing<
          typename boost::mpl::deref<Iterator>::type
        >,
        boost::mpl::true_,
        boost::mpl::or_<
          typename is_shadowing_implies<
            typename boost::mpl::deref<Iterator>::type
          >::type,
          typename is_shadowing_concept_seq<
            ConceptSeq,
            typename boost::mpl::next<Iterator>::type
          >::type
        >
      >::type
    { };

    template<typename ConceptSeq>
    struct is_shadowing_concept_seq
           <
             ConceptSeq,
             typename boost::mpl::end<ConceptSeq>::type
           >
      : boost::mpl::false_
    { };

    template<typename Concept>
    struct is_shadowing_concept
      : boost::mpl::or_<
      typename is_shadowing<Concept>::type,
      typename is_shadowing_implies<Concept>::type
        >::type
    { };

    template<
      typename Sequence,
      typename Iterator = typename boost::mpl::begin<Sequence>::type
    >
    struct do_shadowing {
      typedef typename
        boost::mpl::eval_if<
          is_shadowing_concept<typename boost::mpl::deref<Iterator>::type>,
          do_shadowing<
            boost::mpl::iterator_range<
              Iterator,
              typename boost::mpl::end<Sequence>::type
            >,
            typename boost::mpl::next<Iterator>::type
          >,
          do_shadowing<
            Sequence,
            typename boost::mpl::next<Iterator>::type
          >
        >::type type;
    };

    template<typename Sequence>
    struct do_shadowing<
      Sequence,
      typename boost::mpl::end<Sequence>::type
    >
    {
      typedef Sequence type;
    };

    template<typename SeqA, typename SeqB>
    struct concat {
      typedef typename boost::mpl::insert_range<
          SeqA,
          typename boost::mpl::end<SeqA>::type,
          SeqB
        >::type type;
    };

    template<typename FragmentSeq,
             bool empty = boost::mpl::empty<FragmentSeq>::value >
    struct get_list_of_concepts {
      typedef typename concat<
          typename boost::mpl::front<FragmentSeq>::type::concept,
          typename get_list_of_concepts<
            typename boost::mpl::pop_front<FragmentSeq>::type
          >::type
        >::type
        type;
    };

    template<typename FragmentSeq>
    struct get_list_of_concepts<FragmentSeq, true> {
      typedef FragmentSeq type;
    };
  }
  template<typename FragmentSeq>
  struct resulting_concept {
    typedef typename flatten<
      typename detail::do_shadowing<
        typename detail::get_list_of_concepts<FragmentSeq>::type
        >::type
      >::type
    type;
  };

  namespace detail {
    template<
      typename FragmentSeq,
      typename Concept,
      bool no_fragments_left = boost::mpl::empty<FragmentSeq>::value
    >
    struct get_matching_fragment {
      typedef typename boost::mpl::front<
          FragmentSeq
         >::type front;
      typedef typename boost::mpl::eval_if<
          supports_concept<front, Concept>,
          boost::mpl::identity<front>,
          get_matching_fragment<
            typename boost::mpl::pop_front<
              FragmentSeq
            >::type,
            Concept
          >
        >::type type;
    };

    template<
      typename FragmentSeq,
      typename Concept
    >
    struct get_matching_fragment<
      FragmentSeq,
      Concept,
      true
    >;

    template<
      typename Requirements,
      typename FragmentSeq,
      typename Fragment,
      typename Graph,
      template<typename, typename> class PairMaker,
      bool no_requirements_left = boost::mpl::empty<Requirements>::value
    >
    struct fragment_graph {
      typedef typename PairMaker<
          Fragment,
          typename get_matching_fragment<
            FragmentSeq,
            typename boost::mpl::front<Requirements>::type
          >::type
        >::type pair;
      typedef boost::mpl::pair<
          typename pair::first,
          typename boost::mpl::insert<
            typename boost::mpl::at<Graph, typename pair::first>::type,
            typename pair::second
          >::type
        > real_pair;
      typedef typename boost::mpl::insert<
          Graph,
          real_pair
        >::type graph;
      typedef typename fragment_graph<
          typename boost::mpl::pop_front<Requirements>::type,
          FragmentSeq,
          Fragment,
          graph,
          PairMaker
        >::type type;
    };

    template<
      typename Requirements,
      typename FragmentSeq,
      typename Fragment,
      typename Graph,
      template<typename, typename> class PairMaker
    >
    struct fragment_graph<
      Requirements,
      FragmentSeq,
      Fragment,
      Graph,
      PairMaker,
      true
    > {
      typedef Graph type;
    };

    template<typename From, typename To>
    struct before_pair {
      typedef boost::mpl::pair<From, To> type;
    };

    template<typename To, typename From>
    struct after_pair {
      typedef boost::mpl::pair<From, To> type;
    };

    template<
      typename FragmentSeq,
      typename Fragment,
      typename Graph,
      bool has_require_before = has_require_before<Fragment>::value
    >
    struct fragment_graph_before {
      typedef typename fragment_graph<
          typename Fragment::require_before,
          FragmentSeq,
          Fragment,
          Graph,
          before_pair
        >::type type;
    };

    template<typename FragmentSeq, typename Fragment, typename Graph>
    struct fragment_graph_before<FragmentSeq, Fragment, Graph, false> {
      typedef Graph type;
    };

    template<
      typename FragmentSeq,
      typename Fragment,
      typename Graph,
      bool has_require_after = has_require_after<Fragment>::value
    >
    struct fragment_graph_after {
      typedef typename fragment_graph<
          typename Fragment::require_after,
          FragmentSeq,
          Fragment,
          Graph,
          after_pair
        >::type type;
    };

    template<typename FragmentSeq, typename Fragment, typename Graph>
    struct fragment_graph_after<FragmentSeq, Fragment, Graph, false> {
      typedef Graph type;
    };

    template<
      typename FragmentSeq,
      bool empty = boost::mpl::empty<FragmentSeq>::value
    >
    struct init_graph {
      typedef typename boost::mpl::insert<
          typename init_graph<
            typename boost::mpl::pop_front<FragmentSeq>::type
          >::type,
          boost::mpl::pair<
            typename boost::mpl::front<FragmentSeq>::type,
            boost::mpl::set0<>
          >
        >::type type;
    };

    template<typename FragmentSeq>
    struct init_graph<FragmentSeq, true> {
      typedef boost::mpl::map0<> type;
    };

    template<
      typename Graph,
      typename First = typename boost::mpl::begin<Graph>::type,
      typename Last = typename boost::mpl::end<Graph>::type,
      typename Result = boost::mpl::map0<>
    >
    struct clean_graph {
      typedef typename boost::mpl::deref<First>::type::first key;
      typedef typename boost::mpl::if_<
          typename boost::mpl::has_key<
            Result,
            key
          >::type,
          Result,
          typename boost::mpl::insert<
            Result,
            boost::mpl::pair<
              key,
              typename boost::mpl::at<
                Graph,
                key
              >::type
            >
          >::type
        >::type next;
      typedef typename clean_graph<
          Graph,
          typename boost::mpl::next<First>::type,
          Last,
          next
        >::type type;
    };

    template<typename Graph, typename First, typename Result>
    struct clean_graph<Graph, First, First, Result> {
      typedef Result type;
    };

    template<
      typename FragmentSeq,
      typename Graph = typename init_graph<FragmentSeq>::type,
      bool = boost::mpl::empty<FragmentSeq>::value
    >
    struct order_graph {
      typedef typename boost::mpl::front<FragmentSeq>::type fragment;

      typedef typename fragment_graph_before<
          FragmentSeq,
          fragment,
          Graph
        >::type before;

      typedef typename fragment_graph_after<
          FragmentSeq,
          fragment,
          before
        >::type after;

      typedef typename order_graph<
          typename boost::mpl::pop_front<FragmentSeq>::type,
          after
        >::type type;
    };

    template<typename FragmentSeq, typename Graph>
    struct order_graph<FragmentSeq, Graph, true> {
      typedef typename clean_graph<Graph>::type type;
    };

    template<
      typename Result,
      typename After,
      typename First,
      typename Last
    >
    struct add_edges {
      typedef typename boost::mpl::deref<First>::type x;
      typedef typename boost::mpl::if_<
          typename boost::mpl::has_key<Result, x>::type,
          typename boost::mpl::at<Result, x>::type,
          boost::mpl::set0<>
        >::type old;
      typedef boost::mpl::pair<
          x,
          typename boost::mpl::insert<
            old,
            After
          >::type
        > new_pair;
      typedef typename boost::mpl::insert<
          Result,
          new_pair
        >::type new_result;
      typedef typename add_edges<
          new_result,
          After,
          typename boost::mpl::next<First>::type,
          Last
        >::type type;
    };

    template<typename Result, typename After, typename First>
    struct add_edges<Result, After, First, First> {
      typedef Result type;
    };

    template<
      typename First,
      typename Last,
      typename Result
    >
    struct reverse_graph {
      typedef typename boost::mpl::deref<First>::type x;
      typedef typename x::first after;
      typedef typename x::second before;
      typedef typename reverse_graph<
          typename boost::mpl::next<First>::type,
          Last,
          typename add_edges<
            Result,
            after,
            typename boost::mpl::begin<before>::type,
            typename boost::mpl::end<before>::type
          >::type
        >::type type;
    };

    template<typename First, typename Result>
    struct reverse_graph<First, First, Result> {
      typedef typename clean_graph<Result>::type type;
    };

    template<
      typename FragmentSeq,
      typename Fragments,
      typename Graph,
      typename Result = boost::mpl::vector0<>,
      typename NIt = typename boost::mpl::find_if<
          Fragments,
          boost::mpl::empty<
            boost::mpl::at<
              Graph,
              boost::mpl::_1
            >
          >
        >::type,
      typename End = typename boost::mpl::end<Fragments>::type
    >
    struct reorder {
      typedef typename boost::mpl::deref<NIt>::type N;
      typedef typename boost::mpl::push_back<
          Result,
          N
        >::type next;
      typedef typename reverse_graph<
          typename boost::mpl::begin<Graph>::type,
          typename boost::mpl::end<Graph>::type,
          boost::mpl::map0<>
        >::type reverse;
      typedef typename boost::mpl::erase_key<
          reverse,
          N
        >::type deconnect_N;
      typedef typename reverse_graph<
          typename boost::mpl::begin<deconnect_N>::type,
          typename boost::mpl::end<deconnect_N>::type,
          typename init_graph<FragmentSeq>::type
        >::type next_graph;
      typedef typename reorder<
          FragmentSeq,
          typename boost::mpl::erase_key<
            Fragments,
            N
          >::type,
          next_graph,
          next
        >::type type;
    };

    template<
      typename FragmentSeq,
      typename Fragments,
      typename Graph,
      typename Result,
      typename It
    >
    struct reorder<FragmentSeq, Fragments, Graph, Result, It, It> {
      // check for cycles
      BOOST_STATIC_ASSERT((
        boost::is_same<
          typename boost::mpl::find_if<
            Graph,
            boost::mpl::not_<
              boost::mpl::empty<
                boost::mpl::second<
                  boost::mpl::_1
                >
              >
            >
          >::type,
          typename boost::mpl::end<Graph>::type
        >::value
      ));
      typedef Result type;
    };
  }

  /*
  while (N = find node without incoming edge (Graph) )
    output N
    Graph = reverse<insert<reverse<Graph>, pair<N, set0<> > > > -- remove all edges E from N to M in Graph
  */
  template<typename FragmentSeq>
  struct reorder {
    typedef typename boost::mpl::copy<
        FragmentSeq,
        boost::mpl::inserter<
          boost::mpl::set0<>,
          boost::mpl::insert<boost::mpl::_1, boost::mpl::_2>
        >
      >::type fragments;
    typedef typename detail::order_graph<FragmentSeq>::type graph;
    typedef typename detail::reorder<FragmentSeq, fragments, graph>::type type;
  };

  namespace detail {
    BOOST_MPL_HAS_XXX_TRAIT_DEF(default_fragment)

    template<
      typename Fragment,
      bool has = has_require_before<Fragment>::value
    >
    struct get_requirements_before {
      typedef typename Fragment::require_before type;
    };

    template<typename Fragment>
    struct get_requirements_before<Fragment, false> {
      typedef boost::mpl::vector0< > type;
    };

    template<
      typename Fragment,
      bool has = has_require_after<Fragment>::value
    >
    struct get_requirements_after {
      typedef typename Fragment::require_after type;
    };

    template<typename Fragment>
    struct get_requirements_after<Fragment, false> {
      typedef boost::mpl::vector0< > type;
    };

    template<
      typename Fragment,
      bool has = has_require<Fragment>::value
    >
    struct get_requirements {
      typedef typename Fragment::require type;
    };

    template<typename Fragment>
    struct get_requirements<Fragment, false> {
      typedef boost::mpl::vector0< > type;
    };

    template<
      typename Fragment,
      typename Concept,
      typename DefaultFragment = typename Fragment::default_fragment
    >
    struct default_fragment {
      BOOST_STATIC_ASSERT((boost::mpl::has_key<DefaultFragment, Concept>::value));
      typedef typename boost::mpl::at<DefaultFragment, Concept>::type type;
    };

    template<
      typename Fragment,
      typename Concept
    >
    struct get_default_for {
      BOOST_STATIC_ASSERT((has_default_fragment<Fragment, Concept>::value));
      typedef typename default_fragment<Fragment, Concept>::type type;
    };

    template<typename Seq, typename Fragment, typename Requirement>
    struct add_default {
      typedef typename boost::mpl::push_back<
          Seq,
          typename get_default_for<
            Fragment,
            Requirement
          >::type
        >::type type;
    };

    template<
      typename Fragment,
      typename Requirements,
      typename FragmentSeq,
      bool no_requirements_left = boost::mpl::empty<Requirements>::value
    >
    struct match_or_apply_default_fragment {
      typedef typename boost::mpl::front<Requirements>::type requirement;
      typedef typename boost::mpl::pop_front<Requirements>::type requ_seq;

      typedef typename match_or_apply_default_fragment<
        Fragment,
        requ_seq,
        FragmentSeq
      >::type next_default;
      typedef typename boost::mpl::eval_if<
        has_concept<
          FragmentSeq,
          requirement
        >,
        boost::mpl::identity<next_default>,
        add_default<next_default, Fragment, requirement>
      >::type type;
    };

    template<
      typename Fragment,
      typename Requirements,
      typename FragmentSeq
    >
    struct match_or_apply_default_fragment<
      Fragment,
      Requirements,
      FragmentSeq,
      true
    >
    {
      typedef boost::mpl::vector0< > type;
    };

    template<
      typename FragmentSeq,
      long i = 0,
      long n = boost::mpl::size<FragmentSeq>::value
    >
    struct apply_default_fragments {
      typedef typename boost::mpl::at_c<FragmentSeq, i>::type fragment;

      typedef typename concat<
        typename get_requirements_before<fragment>::type,
        typename concat<
          typename get_requirements_after<fragment>::type,
          typename get_requirements<fragment>::type
        >::type
      >::type requirements;

      typedef typename concat<
        FragmentSeq,
        typename match_or_apply_default_fragment<
          fragment,
          requirements,
          FragmentSeq
        >::type
      >::type new_fragment_seq;

      typedef typename apply_default_fragments<
        new_fragment_seq,
        i + 1
      >::type type;
    };

    template<
      typename FragmentSeq,
      long n
    >
    struct apply_default_fragments<FragmentSeq, n, n> {
      typedef FragmentSeq type;
    };
  }

  template<typename FragmentSeq>
  struct apply_default_fragments {
    typedef typename detail::apply_default_fragments<FragmentSeq>::type type;
  };

// ----
// create_vector from greatcontainer3
  template<typename Sequence, int Size>
  struct create_vector_impl;

  template<typename Sequence>
  struct create_vector {
    typedef
      typename create_vector_impl<Sequence, boost::mpl::size<Sequence>::value >::type
      type;
  };

  #define ELEMENT_AT(z, n, t) \
    BOOST_PP_COMMA_IF(n) \
    typename boost::mpl::at_c<Sequence, n>::type

  #define CREATE_VECTOR_IMPL(z, n, t) \
    template<typename Sequence> \
    struct create_vector_impl<Sequence, n> { \
      typedef BOOST_PP_CAT(boost::mpl::vector, n)< \
        BOOST_PP_REPEAT(n, ELEMENT_AT, ~) \
      > type; \
    };

  BOOST_PP_REPEAT(20, CREATE_VECTOR_IMPL, ~)

  #undef CREATE_VECTOR_IMPL
  #undef ELEMENT_AT
// ----
}

namespace tests {
  template<typename Seq, typename ShadowConcept>
  void test_do_shadowing() {
    typedef typename utils::detail::do_shadowing<Seq>::type results;

    std::cout << "shadowing: " << boost::mpl::size<results>::value << '\n';
    BOOST_STATIC_ASSERT((boost::is_same<
                         typename boost::mpl::front<results>::type,
                         ShadowConcept>::value));
  }

  template<typename Seq, typename Has, bool expect>
  void has_concept() {
    std::cout << "has_concept\n";
    BOOST_STATIC_ASSERT((utils::has_concept<Seq, Has>::value == expect));
  }

  template<typename Fragment, typename Concept, bool expect>
  void supports_concept() {
    std::cout << "supports_concept\n";
    BOOST_STATIC_ASSERT((utils::supports_concept<Fragment, Concept>::value
                         == expect));
  }

  template<typename Seq, bool expect>
  void check_concepts() {
    std::cout << "check_concepts\n";
    BOOST_STATIC_ASSERT((utils::check_concepts<Seq>::value == expect));
  }

  template<typename Seq>
  void flatten() {
    typedef typename utils::flatten<Seq>::type result;
    std::cout << "flatten: " << boost::mpl::size<result>::value << '\n';
  }

  template<typename FragmentSeq>
  void resulting_concept() {
    typedef typename utils::resulting_concept<FragmentSeq>::type result_;
    typedef typename utils::create_vector<result_>::type result;
    std::cout << "resulting concept: " << boost::mpl::size<result>::value;
    std::cout << " _Z1x" << typeid(result).name() << '\n';
  }
}

int main() {
  tests::supports_concept<fragment1, concepts::container, true>();

  tests::has_concept<mpl::vector2<fragment3, fragment1>, concepts::container,
    true>();
  tests::has_concept<mpl::vector0<>, concepts::container, false>();

  tests::check_concepts<mpl::vector2<fragment3, fragment1>, false>();
  tests::check_concepts<mpl::vector0< >, true>();
  tests::check_concepts<mpl::vector2<fragment1, fragment3>, true>();

  tests::test_do_shadowing<mpl::vector4<bar, foo, shads, baz>, shads>();
  tests::test_do_shadowing<mpl::vector4<bar, foo, implies_shads, baz>,
    implies_shads>();
  tests::test_do_shadowing<mpl::vector0< >, boost::mpl::void_>();

  tests::flatten<mpl::vector2<bar, bar> >();
  tests::flatten<mpl::vector0< > >();
  std::cout << "_Z1x" << typeid(utils::create_vector<utils::flatten<mpl::vector2<bar, bar> >::type>::type).name() << '\n';

  tests::resulting_concept<mpl::vector2<fragment1, fragment3> >();

  typedef mpl::vector3<stl::stack, stl::vector, stl::type<int> > c3;
  typedef utils::detail::order_graph<c3>::type graph;
  typedef utils::detail::clean_graph<
      mpl::map3<
        mpl::pair<stl::vector, mpl::set1<stl::type<int> > >
        ,      mpl::pair<stl::stack, mpl::set2<stl::vector, stl::type<int> > >
        ,      mpl::pair<stl::type<int>, mpl::set0<> >
      >
    >::type graph2;
  typedef utils::detail::init_graph<c3>::type ig;
  typedef utils::detail::reverse_graph<
      mpl::begin<graph>::type,
      mpl::end<graph>::type,
      ig
    >::type rg;
 typedef utils::detail::reverse_graph<
      mpl::begin<graph2>::type,
      mpl::end<graph2>::type,
      ig
    >::type rg2;

  std::cout << "_Z1a" << typeid(graph).name() << '\n';
  std::cout << "_Z1b" << typeid(graph2).name() << '\n';
  std::cout << boost::mpl::size<graph>::value << ',' << boost::mpl::size<graph2>::value << '\n';
  std::cout << "_Z1A" << typeid(rg).name() << '\n';
  std::cout << "_Z1B" << typeid(rg2).name() << '\n';
  std::cout << boost::mpl::size<rg>::value << ',' << boost::mpl::size<rg2>::value << '\n';

  std::cout << "_Z1r" << typeid(utils::create_vector<utils::reorder<c3>::type>::type).name() << '\n';

  std::cout << "_Z1x" << typeid(utils::create_vector<utils::apply_default_fragments<mpl::vector2<stl::stack, stl::type<int> > >::type>::type).name() << '\n';
}

max_stars_repo_name: aristidb/fragments

max_issues_repo_name: aristidb/fragments

max_forks_repo_name: aristidb/fragments


text:
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE crypto_AES

#include <algorithm>
#include <boost/predef.h>
#include <boost/test/unit_test.hpp>
#include <openssl/aes.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include "crypto/crypto_AES.hpp"

BOOST_AUTO_TEST_CASE(test_crypto_aes_1)
{
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    unsigned char key[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key) == 0);

    unsigned char key2[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key2) == 0);
    BOOST_REQUIRE(strcmp((char *)key, (char *)key2) != 0);

    unsigned char iv[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv) == 0);

    unsigned char iv2[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv2) == 0);
    BOOST_REQUIRE(strcmp((char *)iv, (char *)iv2) != 0);

    unsigned char plaintext[] = "The quick brown fox jumps over the lazy dog";
    unsigned char aad[] = "Some AAD data";

    unsigned char ciphertext[128];
    unsigned char decryptedtext[128];

    unsigned char tag[16];

    int decryptedtext_len = 0, ciphertext_len = 0;
    ciphertext_len
        = my::crypto::Encrypt_AES(plaintext, strlen(reinterpret_cast<char *>(plaintext)), aad, strlen(reinterpret_cast<char *>(aad)), key, iv, ciphertext, tag);

    decryptedtext_len = my::crypto::Decrypt_AES(ciphertext, ciphertext_len, aad, strlen(reinterpret_cast<char *>(aad)), tag, key, iv, decryptedtext);

    BOOST_REQUIRE(decryptedtext_len >= 0);
    decryptedtext[decryptedtext_len] = '\0';

    BOOST_REQUIRE(strlen(reinterpret_cast<char *>(decryptedtext)) == strlen(reinterpret_cast<char *>(plaintext)));
    BOOST_REQUIRE(strcmp((char *)decryptedtext, (char *)plaintext) == 0);

    ERR_free_strings();
}

BOOST_AUTO_TEST_CASE(test_crypto_aes_2)
{
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    unsigned char key[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key) == 0);

    unsigned char key2[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key2) == 0);
    BOOST_REQUIRE(strcmp((char *)key, (char *)key2) != 0);

    unsigned char iv[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv) == 0);

    unsigned char iv2[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv2) == 0);
    BOOST_REQUIRE(strcmp((char *)iv, (char *)iv2) != 0);

    unsigned char plaintext[] = "Bonjour, je suis là depuis des années, transformée en chatton";
    unsigned char aad[] = "";

    unsigned char ciphertext[128];
    unsigned char decryptedtext[128];

    unsigned char tag[16];

    int decryptedtext_len = 0, ciphertext_len = 0;
    ciphertext_len
        = my::crypto::Encrypt_AES(plaintext, strlen(reinterpret_cast<char *>(plaintext)), aad, strlen(reinterpret_cast<char *>(aad)), key, iv, ciphertext, tag);

    decryptedtext_len = my::crypto::Decrypt_AES(ciphertext, ciphertext_len, aad, strlen(reinterpret_cast<char *>(aad)), tag, key, iv, decryptedtext);

    BOOST_REQUIRE(decryptedtext_len >= 0);
    decryptedtext[decryptedtext_len] = '\0';

    BOOST_REQUIRE(strlen(reinterpret_cast<char *>(decryptedtext)) == strlen(reinterpret_cast<char *>(plaintext)));
    BOOST_REQUIRE(strcmp((char *)decryptedtext, (char *)plaintext) == 0);

    ERR_free_strings();
}

BOOST_AUTO_TEST_CASE(test_crypto_aes_3)
{
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    unsigned char key[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key) == 0);

    unsigned char key2[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key2) == 0);
    BOOST_REQUIRE(strcmp((char *)key, (char *)key2) != 0);

    unsigned char iv[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv) == 0);

    unsigned char iv2[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv2) == 0);
    BOOST_REQUIRE(strcmp((char *)iv, (char *)iv2) != 0);

    unsigned char plaintext[] = "Les chaussettes de l'archiduchesse sont-elles sèches?  Archi-sèches ?";
    unsigned char aad[] = "";

    unsigned char ciphertext[128];
    unsigned char decryptedtext[128];

    unsigned char tag[16];

    int decryptedtext_len = 0, ciphertext_len = 0;
    ciphertext_len
        = my::crypto::Encrypt_AES(plaintext, strlen(reinterpret_cast<char *>(plaintext)), aad, strlen(reinterpret_cast<char *>(aad)), key, iv, ciphertext, tag);

    decryptedtext_len = my::crypto::Decrypt_AES(ciphertext, ciphertext_len, aad, strlen(reinterpret_cast<char *>(aad)), tag, key, iv, decryptedtext);

    BOOST_REQUIRE(decryptedtext_len >= 0);
    decryptedtext[decryptedtext_len] = '\0';

    BOOST_REQUIRE(strlen(reinterpret_cast<char *>(decryptedtext)) == strlen(reinterpret_cast<char *>(plaintext)));
    BOOST_REQUIRE(strcmp((char *)decryptedtext, (char *)plaintext) == 0);

    ERR_free_strings();
}

BOOST_AUTO_TEST_CASE(test_crypto_aes_4)
{
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    unsigned char key[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key) == 0);

    unsigned char key2[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key2) == 0);
    BOOST_REQUIRE(strcmp((char *)key, (char *)key2) != 0);

    unsigned char iv[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv) == 0);

    unsigned char iv2[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv2) == 0);
    BOOST_REQUIRE(strcmp((char *)iv, (char *)iv2) != 0);

    unsigned char plaintext[] = "Un chasseur sachant chasser doit savoir chasser sans son chien.";
    unsigned char aad[] = "Cinq chiens chassent six chats.";

    unsigned char ciphertext[128];
    unsigned char decryptedtext[128];

    unsigned char tag[16];

    int decryptedtext_len = 0, ciphertext_len = 0;
    ciphertext_len
        = my::crypto::Encrypt_AES(plaintext, strlen(reinterpret_cast<char *>(plaintext)), aad, strlen(reinterpret_cast<char *>(aad)), key, iv, ciphertext, tag);

    decryptedtext_len = my::crypto::Decrypt_AES(ciphertext, ciphertext_len, aad, strlen(reinterpret_cast<char *>(aad)), tag, key, iv, decryptedtext);

    BOOST_REQUIRE(decryptedtext_len >= 0);
    decryptedtext[decryptedtext_len] = '\0';

    BOOST_REQUIRE(strlen(reinterpret_cast<char *>(decryptedtext)) == strlen(reinterpret_cast<char *>(plaintext)));
    BOOST_REQUIRE(strcmp((char *)decryptedtext, (char *)plaintext) == 0);

    ERR_free_strings();
}

BOOST_AUTO_TEST_CASE(test_crypto_aes_5)
{
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    unsigned char key[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key) == 0);

    unsigned char key2[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key2) == 0);
    BOOST_REQUIRE(strcmp((char *)key, (char *)key2) != 0);

    unsigned char iv[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv) == 0);

    unsigned char iv2[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv2) == 0);
    BOOST_REQUIRE(strcmp((char *)iv, (char *)iv2) != 0);

    unsigned char plaintext[] = "lol";
    unsigned char aad[] = "Chattons";

    unsigned char ciphertext[128];
    unsigned char decryptedtext[128];

    unsigned char tag[16];

    int decryptedtext_len = 0, ciphertext_len = 0;
    ciphertext_len
        = my::crypto::Encrypt_AES(plaintext, strlen(reinterpret_cast<char *>(plaintext)), aad, strlen(reinterpret_cast<char *>(aad)), key, iv, ciphertext, tag);

    decryptedtext_len = my::crypto::Decrypt_AES(ciphertext, ciphertext_len, aad, strlen(reinterpret_cast<char *>(aad)), tag, key, iv, decryptedtext);

    BOOST_REQUIRE(decryptedtext_len >= 0);
    decryptedtext[decryptedtext_len] = '\0';

    BOOST_REQUIRE(strlen(reinterpret_cast<char *>(decryptedtext)) == strlen(reinterpret_cast<char *>(plaintext)));
    BOOST_REQUIRE(strcmp((char *)decryptedtext, (char *)plaintext) == 0);

    ERR_free_strings();
}

BOOST_AUTO_TEST_CASE(test_crypto_aes_6)
{
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    unsigned char key[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key) == 0);

    unsigned char key2[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key2) == 0);
    BOOST_REQUIRE(strcmp((char *)key, (char *)key2) != 0);

    unsigned char iv[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv) == 0);

    unsigned char iv2[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv2) == 0);
    BOOST_REQUIRE(strcmp((char *)iv, (char *)iv2) != 0);

    unsigned char plaintext[] = "lol";
    unsigned char aad[] = "";

    unsigned char ciphertext[128];
    unsigned char decryptedtext[128];

    unsigned char tag[16];

    int decryptedtext_len = 0, ciphertext_len = 0;
    ciphertext_len
        = my::crypto::Encrypt_AES(plaintext, strlen(reinterpret_cast<char *>(plaintext)), aad, strlen(reinterpret_cast<char *>(aad)), key, iv, ciphertext, tag);

    decryptedtext_len = my::crypto::Decrypt_AES(ciphertext, ciphertext_len, aad, strlen(reinterpret_cast<char *>(aad)), tag, key, iv, decryptedtext);

    BOOST_REQUIRE(decryptedtext_len >= 0);
    decryptedtext[decryptedtext_len] = '\0';

    BOOST_REQUIRE(strlen(reinterpret_cast<char *>(decryptedtext)) == strlen(reinterpret_cast<char *>(plaintext)));
    BOOST_REQUIRE(strcmp((char *)decryptedtext, (char *)plaintext) == 0);

    ERR_free_strings();
}

BOOST_AUTO_TEST_CASE(test_crypto_aes_7)
{
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    unsigned char key[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key) == 0);

    unsigned char key2[32];
    BOOST_REQUIRE(my::crypto::Rand_Key_AES(key2) == 0);
    BOOST_REQUIRE(strcmp((char *)key, (char *)key2) != 0);

    unsigned char iv[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv) == 0);

    unsigned char iv2[16];
    BOOST_REQUIRE(my::crypto::Rand_IV_AES(iv2) == 0);
    BOOST_REQUIRE(strcmp((char *)iv, (char *)iv2) != 0);

    unsigned char plaintext[] = "lol";
    unsigned char aad[] = "";

    unsigned char ciphertext[128];
    unsigned char decryptedtext[128];

    unsigned char tag[16];

    int decryptedtext_len = 0, ciphertext_len = 0;
    ciphertext_len
        = my::crypto::Encrypt_AES(plaintext, strlen(reinterpret_cast<char *>(plaintext)), aad, strlen(reinterpret_cast<char *>(aad)), key, iv, ciphertext, tag);

    decryptedtext_len = my::crypto::Decrypt_AES(ciphertext, ciphertext_len, aad, strlen(reinterpret_cast<char *>(aad)), tag, key, iv, decryptedtext);

    BOOST_REQUIRE(decryptedtext_len >= 0);
    decryptedtext[decryptedtext_len] = '\0';

    BOOST_REQUIRE(strlen(reinterpret_cast<char *>(decryptedtext)) == strlen(reinterpret_cast<char *>(plaintext)));
    BOOST_REQUIRE(strcmp((char *)decryptedtext, (char *)plaintext) == 0);

    ERR_free_strings();
}

max_stars_repo_name: Pcornat/BenLib

max_issues_repo_name: Pcornat/BenLib

max_forks_repo_name: Pcornat/BenLib


text:
// Copyright (c) 2018-2019 The Bitcoin Unlimited developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <boost/test/unit_test.hpp>
#include <cassert>
#include <iostream>

#include "hashwrapper.h"
#include "iblt.h"
#include "serialize.h"
#include "test/test_bitcoin.h"
#include "utilstrencodings.h"

const std::vector<uint8_t> IBLT_NULL_VALUE = {};

std::vector<uint8_t> PseudoRandomValue(uint32_t n)
{
    std::vector<uint8_t> result;
    for (int i = 0; i < 4; i++)
    {
        result.push_back(static_cast<uint8_t>(MurmurHash3(n + i, result) & 0xff));
    }
    return result;
}

BOOST_FIXTURE_TEST_SUITE(iblt_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(iblt_variable_checksum_gives_smaller_encoding)
{
    uint64_t version = 2;
    uint32_t salt = 1;
    size_t n = 1;

    CIblt full(n, version);
    full.insert(0, IBLT_NULL_VALUE);
    size_t full_size = ::GetSerializeSize(full, SER_NETWORK, PROTOCOL_VERSION);
    CIblt masked1(n, salt, version, 0x0000ffff);
    masked1.insert(0, IBLT_NULL_VALUE);
    size_t masked1_size = ::GetSerializeSize(masked1, SER_NETWORK, PROTOCOL_VERSION);
    CIblt masked2(n, salt, version, 0x000000ff);
    masked2.insert(0, IBLT_NULL_VALUE);
    size_t masked2_size = ::GetSerializeSize(masked2, SER_NETWORK, PROTOCOL_VERSION);

    BOOST_CHECK(full_size > masked1_size);
    BOOST_CHECK(masked1_size > masked2_size);
}

BOOST_AUTO_TEST_CASE(iblt_handles_small_quantities)
{
    uint64_t versions[2] = {1, 2};
    for (uint64_t version : versions)
    {
        bool allPassed = true;
        for (size_t nItems=1;nItems < 100;nItems++)
        {
            CIblt t(nItems, version);

            for (size_t i=0;i < nItems;i++)
                t.insert(i, IBLT_NULL_VALUE);

            std::set<std::pair<uint64_t, std::vector<uint8_t> > > entries;
            allPassed = allPassed && t.listEntries(entries, entries);
        }

        BOOST_CHECK(allPassed);
    }
}

BOOST_AUTO_TEST_CASE(iblt_arbitrary_salt)
{
    uint32_t salt = 17;
    uint64_t versions[2] = {1, 2};
    for (uint64_t version : versions)
    {
        size_t nItems = 2;
        CIblt t(nItems, salt, version);

        t.insert(0, ParseHex("00000000"));
        t.insert(1, ParseHex("00000001"));
        bool gotResult;
        std::vector<uint8_t> result;

        gotResult = t.get(0, result);
        BOOST_CHECK(gotResult && result == ParseHex("00000000"));

        gotResult = t.get(1, result);
        BOOST_CHECK(gotResult && result == ParseHex("00000001"));
    }
}

BOOST_AUTO_TEST_CASE(iblt_salted_reset)
{
    size_t nHash = 1;
    uint32_t salt = 17;
    uint64_t versions[2] = {1, 2};
    for (uint64_t version : versions)
    {
        bool gotResult;
        std::vector<uint8_t> result;
        CIblt t(nHash, salt, version);

        t.insert(0, ParseHex("00000000"));
        gotResult = t.get(0, result);
        BOOST_CHECK(gotResult && result == ParseHex("00000000"));

        t.reset();
        t.resize(20);
        t.insert(1, ParseHex("00000001"));
        t.insert(11, ParseHex("00000011"));

        gotResult = t.get(1, result);
        BOOST_CHECK(gotResult && result == ParseHex("00000001"));
    }
}

BOOST_AUTO_TEST_CASE(iblt_reset)
{
    uint64_t versions[2] = {1, 2};
    for (uint64_t version : versions)
    {
        CIblt t(version);
        t.insert(0, ParseHex("00000000"));
        bool gotResult;
        std::vector<uint8_t> result;
        gotResult = t.get(21, result);
        BOOST_CHECK(!gotResult);  // anything could have been inserted into a zero length IBLT

        t.reset();
        t.resize(20);
        t.insert(0, ParseHex("00000000"));
        t.insert(1, ParseHex("00000001"));
        t.insert(11, ParseHex("00000011"));

        gotResult = t.get(0, result);
        BOOST_CHECK(gotResult && result == ParseHex("00000000"));

        t.reset();

        gotResult = t.get(0, result);
        BOOST_CHECK(gotResult && (result.size()==0));

        t.resize(40);

        t.insert(0, ParseHex("00000000"));
        t.insert(1, ParseHex("00000001"));
        t.insert(11, ParseHex("00000011"));

        gotResult = t.get(0, result);
        BOOST_CHECK(gotResult && result == ParseHex("00000000"));
    }
}

BOOST_AUTO_TEST_CASE(iblt_erases_properly)
{
    uint64_t versions[2] = {1, 2};
    for (uint64_t version : versions)
    {
        CIblt t(20, version);
        t.insert(0, ParseHex("00000000"));
        t.insert(1, ParseHex("00000001"));
        t.insert(11, ParseHex("00000011"));

        bool gotResult;
        std::vector<uint8_t> result;
        gotResult = t.get(0, result);
        BOOST_CHECK(gotResult && result == ParseHex("00000000"));
        gotResult = t.get(11, result);
        BOOST_CHECK(gotResult && result == ParseHex("00000011"));

        t.erase(0, ParseHex("00000000"));
        t.erase(1, ParseHex("00000001"));
        gotResult = t.get(1, result);
        BOOST_CHECK(gotResult && result.empty());
        t.erase(11, ParseHex("00000011"));
        gotResult = t.get(11, result);
        BOOST_CHECK(gotResult && result.empty());

        t.insert(0, ParseHex("00000000"));
        t.insert(1, ParseHex("00000001"));
        t.insert(11, ParseHex("00000011"));

        for (int i = 100; i < 115; i++)
        {
            t.insert(i, ParseHex("aabbccdd"));
        }

        gotResult = t.get(101, result);
        BOOST_CHECK(gotResult && result == ParseHex("aabbccdd"));
        gotResult = t.get(200, result);
        BOOST_CHECK(gotResult && result.empty());
    }
}

BOOST_AUTO_TEST_CASE(iblt_handles_overload)
{
    uint64_t versions[2] = {1, 2};
    for (uint64_t version : versions)
    {
        CIblt t(20, version);

        // 1,000 values in an IBLT that has room for 20,
        // all lookups should fail.
        for (int i = 0; i < 1000; i++)
        {
            t.insert(i, PseudoRandomValue(i));
        }
        bool gotResult;
        std::vector<uint8_t> result;
        for (int i = 0; i < 1000; i += 97)
        {
            gotResult = t.get(i, result);
            BOOST_CHECK(!gotResult && result.empty());
        }

        // erase all but 20:
        for (int i = 20; i < 1000; i++)
        {
            t.erase(i, PseudoRandomValue(i));
        }
        for (int i = 0; i < 20; i++)
        {
            gotResult = t.get(i, result);
            BOOST_CHECK(gotResult && result == PseudoRandomValue(i));
        }
    }
}

BOOST_AUTO_TEST_CASE(iblt_lists_entries_properly)
{
    uint64_t versions[2] = {1, 2};
    for (uint64_t version : versions)
    {
        std::set<std::pair<uint64_t, std::vector<uint8_t> > > expected;
        CIblt t(20, version);
        for (int i = 0; i < 20; i++)
        {
            t.insert(i, PseudoRandomValue(i * 2));
            expected.insert(std::make_pair(i, PseudoRandomValue(i * 2)));
        }
        std::set<std::pair<uint64_t, std::vector<uint8_t> > > entries;
        bool fAllFound = t.listEntries(entries, entries);
        BOOST_CHECK(fAllFound && entries == expected);
    }
}

BOOST_AUTO_TEST_CASE(iblt_performs_subtraction_properly)
{
    uint64_t versions[2] = {1, 2};
    for (uint64_t version : versions)
    {
        CIblt t1(11, version);
        CIblt t2(11, version);

        for (int i = 0; i < 195; i++)
        {
            t1.insert(i, PseudoRandomValue(i));
        }
        for (int i = 5; i < 200; i++)
        {
            t2.insert(i, PseudoRandomValue(i));
        }

        CIblt diff = t1 - t2;

        // Should end up with 10 differences, 5 positive and 5 negative:
        std::set<std::pair<uint64_t, std::vector<uint8_t> > > expectedPositive;
        std::set<std::pair<uint64_t, std::vector<uint8_t> > > expectedNegative;
        for (int i = 0; i < 5; i++)
        {
            expectedPositive.insert(std::make_pair(i, PseudoRandomValue(i)));
            expectedNegative.insert(std::make_pair(195 + i, PseudoRandomValue(195 + i)));
        }
        std::set<std::pair<uint64_t, std::vector<uint8_t> > > positive;
        std::set<std::pair<uint64_t, std::vector<uint8_t> > > negative;
        bool allDecoded = diff.listEntries(positive, negative);
        BOOST_CHECK(allDecoded);
        BOOST_CHECK(positive == expectedPositive);
        BOOST_CHECK(negative == expectedNegative);

        positive.clear();
        negative.clear();
        allDecoded = (t2 - t1).listEntries(positive, negative);
        BOOST_CHECK(allDecoded);
        BOOST_CHECK(positive == expectedNegative); // Opposite subtraction, opposite results
        BOOST_CHECK(negative == expectedPositive);

        CIblt emptyIBLT(11, version);
        std::set<std::pair<uint64_t, std::vector<uint8_t> > > emptySet;

        // Test edge cases for empty IBLT:
        allDecoded = emptyIBLT.listEntries(emptySet, emptySet);
        BOOST_CHECK(allDecoded);
        BOOST_CHECK(emptySet.empty());

        positive.clear();
        negative.clear();
        allDecoded = (diff - emptyIBLT).listEntries(positive, negative);
        BOOST_CHECK(allDecoded);
        BOOST_CHECK(positive == expectedPositive);
        BOOST_CHECK(negative == expectedNegative);

        positive.clear();
        negative.clear();
        allDecoded = (emptyIBLT - diff).listEntries(positive, negative);
        BOOST_CHECK(allDecoded);
        BOOST_CHECK(positive == expectedNegative); // Opposite subtraction, opposite results
        BOOST_CHECK(negative == expectedPositive);
    }
}

BOOST_AUTO_TEST_SUITE_END()


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

#include <unordered_map>

#include <boost/format.hpp>
#include <boost/pending/disjoint_sets.hpp>

#include "luxrays/core/exttrianglemesh.h"
#include "slg/shapes/islandaovshape.h"
#include "slg/scene/scene.h"

using namespace std;
using namespace luxrays;
using namespace slg;

IslandAOVShape::IslandAOVShape(ExtTriangleMesh *srcMesh, const u_int dataIndex) {
	SDL_LOG("IslandAOV shape " << srcMesh->GetName());

	const double startTime = WallClockTime();

	const u_int vertexCount = srcMesh->GetTotalVertexCount();
	const u_int triCount = srcMesh->GetTotalTriangleCount();
	const Triangle *tris = srcMesh->GetTriangles();
	SDL_LOG("IslandAOV shape vertex count: " << vertexCount);
	SDL_LOG("IslandAOV shape triangle count: " << triCount);

	// Built a mapping to have all very near vertices
	auto compareVerts = [](const TriangleMesh &mesh, const u_int vertIndex1, const u_int vertIndex2) {
		const ExtTriangleMesh *triMesh = dynamic_cast<const ExtTriangleMesh *>(&mesh);
		assert (triMesh);

		const Point v1 = triMesh->GetVertex(Transform::TRANS_IDENTITY, vertIndex1);
		const Point v2 = triMesh->GetVertex(Transform::TRANS_IDENTITY, vertIndex2);

		return (DistanceSquared(v1, v2) < DEFAULT_EPSILON_STATIC);
	};
	vector<u_int> uniqueVertices;
	const u_int uniqueVertCount = srcMesh->GetUniqueVerticesMapping(uniqueVertices, compareVerts);
	SDL_LOG("IslandAOV shape has " << uniqueVertCount << " unique vertices over " << vertexCount);

	vector<u_int> triangleIndices(triCount);
	for (u_int i = 0; i < triCount; ++i)
		triangleIndices[i] = i;

	// Set the group leaders
	vector<u_int> leaderIndices(vertexCount, NULL_INDEX);
	for (u_int i = 0; i < triCount; ++i) {
		const Triangle &tri = tris[i];

		for (u_int j = 0; j < 3; ++j) {
			if (leaderIndices[uniqueVertices[tri.v[j]]] == NULL_INDEX) {
				// I can set this triangle as leader
				leaderIndices[uniqueVertices[tri.v[j]]] = i;
			}
		}
	}

	vector<u_int> rank(triCount);
	vector<u_int> parent(triCount);
	boost::disjoint_sets<u_int *,u_int *> ds(&rank[0], &parent[0]);

	// Create the initial sets with each triangle
	for (u_int i = 0; i < triCount; ++i)
		ds.make_set(triangleIndices[i]);

	// Link each triangle with the group leader
	for (u_int i = 0; i < triCount; ++i) {
		const Triangle &tri = tris[i];

		for (u_int j = 0; j < 3; ++j) {
			ds.union_set(triangleIndices[i], triangleIndices[leaderIndices[uniqueVertices[tri.v[j]]]]);
		}
	}

	// Build the list of islands
	float *triAOV = new float[triCount];
	unordered_map<u_int, u_int> islandIndices;
	u_int islandCount = 0;
	for (u_int i = 0; i < triCount; ++i) {
		const u_int leaderIndex = ds.find_set(triangleIndices[i]);

		// Check if it is a new leader
		u_int islandIndex;
		if (islandIndices.find(leaderIndex) == islandIndices.end()) {
			islandIndex = islandCount;
			islandIndices[leaderIndex] = islandCount++;
		} else
			islandIndex = islandIndices[leaderIndex];

		triAOV[i] = islandIndex;
	}

	SDL_LOG("IslandAOV shape island count: " << islandCount);

	mesh = srcMesh->Copy();
	mesh->SetTriAOV(dataIndex, &triAOV[0]);

	const double endTime = WallClockTime();
	SDL_LOG("IslandAOV time: " << (boost::format("%.3f") % (endTime - startTime)) << "secs");
}

IslandAOVShape::~IslandAOVShape() {
	if (!refined)
		delete mesh;
}

ExtTriangleMesh *IslandAOVShape::RefineImpl(const Scene *scene) {
	return mesh;
}

max_stars_repo_name: mbrukman/LuxCore

max_issues_repo_name: mbrukman/LuxCore

max_forks_repo_name: mbrukman/LuxCore


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

  @copyright 2016 NumScale SAS

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

#include <boost/simd/config.hpp>
#include <boost/simd/detail/dispatch/function/make_callable.hpp>
#include <boost/simd/detail/dispatch/hierarchy/functions.hpp>
#include <boost/simd/detail/dispatch.hpp>

namespace boost { namespace simd
{
  namespace tag
  {
    BOOST_DISPATCH_MAKE_TAG(ext, ifnot_inc_, boost::dispatch::elementwise_<ifnot_inc_>);
  }

  namespace ext
  {
    BOOST_DISPATCH_FUNCTION_DECLARATION(tag, ifnot_inc_);
  }

  BOOST_DISPATCH_CALLABLE_DEFINITION(tag::ifnot_inc_,ifnot_inc);

} }

#endif

max_stars_repo_name: xmar/pythran

max_issues_repo_name: xmar/pythran

max_forks_repo_name: xmar/pythran


text:
/*
 * NetworkClient.cpp
 *
 *  Created on: Apr 23, 2016
 *      Author: James Hong
 */

#include "controller/ControllerClient.h"

#define BOOST_NETWORK_ENABLE_HTTPS

#include <boost/network/protocol/http/client/options.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <cassert>
#include <sstream>
#include <memory>

#include "Beetle.h"
#include "util/file.h"

static const int CLIENT_TIMEOUT = 180;

/* Custom header to identify gateway */
const std::string ControllerClient::SESSION_HEADER = "Beetle-Gateway-Session";

ControllerClient::ControllerClient(Beetle &beetle, std::string host, int apiPort, int ctrlPort,
		bool verifyPeers, std::string clientCert, std::string clientKey, std::string caCert) :
		beetle(beetle), host(host), apiPort(apiPort), ctrlPort(ctrlPort) {
	assert(file_exists(clientCert));
	assert(file_exists(clientKey));
	assert(file_exists(caCert));

	using namespace boost::network;
	http::client::options options;
	options.follow_redirects(false)
		.cache_resolved(true)
		.always_verify_peer(verifyPeers)
		.timeout(CLIENT_TIMEOUT)
		.openssl_certificate(caCert)
		.openssl_certificate_file(clientCert)
		.openssl_private_key_file(clientKey);
	client.reset(new http::client(options));
}

ControllerClient::~ControllerClient() {

}

std::string ControllerClient::getApiUrl(std::string resource) {
	// TODO more robust escaping
	boost::replace_all(resource, " ", "%20");
	std::stringstream ss;
	ss << "https://" << host << ":" << apiPort << "/" << resource;
	return ss.str();
}

std::shared_ptr<boost::network::http::client> ControllerClient::getClient() {
	return client;
}

std::string ControllerClient::getName() {
	return beetle.name;
}

std::string ControllerClient::getHost() {
	return host;
}

int ControllerClient::getApiPort() {
	return apiPort;
}

int ControllerClient::getCtrlPort() {
	return ctrlPort;
}

void ControllerClient::setSessionToken(std::string token) {
	sessionToken = token;
}

std::string ControllerClient::getSessionToken() {
	return sessionToken;
}

max_stars_repo_name: helena-project/beetle

max_issues_repo_name: helena-project/beetle

max_forks_repo_name: helena-project/beetle


text:
#ifndef BOOST_NUMERIC_SAFE_INTEGER_LITERAL_HPP
#define BOOST_NUMERIC_SAFE_INTEGER_LITERAL_HPP

//  Copyright (c) 2012 Robert Ramey
//
// 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 <cstdint> // for intmax_t/uintmax_t
#include <iosfwd>
#include <type_traits> // conditional, enable_if
#include <boost/mp11/utility.hpp>

#include "utility.hpp"
#include "safe_integer.hpp"
#include "checked_integer.hpp"

namespace boost {
namespace safe_numerics {

template<typename T, T N, class P, class E>
class safe_literal_impl;

template<typename T, T N, class P, class E>
struct is_safe<safe_literal_impl<T, N, P, E> > : public std::true_type
{};

template<typename T, T N, class P, class E>
struct get_promotion_policy<safe_literal_impl<T, N, P, E> > {
    using type = P;
};

template<typename T, T N, class P, class E>
struct get_exception_policy<safe_literal_impl<T, N, P, E> > {
    using type = E;
};
template<typename T, T N, class P, class E>
struct base_type<safe_literal_impl<T, N, P, E> > {
    using type = T;
};

template<typename T, T N, class P, class E>
constexpr T base_value(
    const safe_literal_impl<T, N, P, E> &
) {
    return N;
}

template<typename CharT, typename Traits, typename T, T N, class P, class E>
inline std::basic_ostream<CharT, Traits> & operator<<(
    std::basic_ostream<CharT, Traits> & os,
    const safe_literal_impl<T, N, P, E> &
){
    return os << (
        (std::is_same<T, signed char>::value
        || std::is_same<T, unsigned char>::value
        ) ?
            static_cast<int>(N)
        :
            N
    );
}

template<typename T, T N, class P, class E>
class safe_literal_impl {

    template<
        class CharT,
        class Traits
    >
    friend std::basic_ostream<CharT, Traits> & operator<<(
        std::basic_ostream<CharT, Traits> & os,
        const safe_literal_impl &
    ){
        return os << (
            (::std::is_same<T, signed char>::value
            || ::std::is_same<T, unsigned char>::value
            || ::std::is_same<T, wchar_t>::value
            ) ?
                static_cast<int>(N)
            :
                N
        );
    };

public:

    ////////////////////////////////////////////////////////////
    // constructors
    // default constructor
    constexpr safe_literal_impl(){}

    /////////////////////////////////////////////////////////////////
    // casting operators for intrinsic integers
    // convert to any type which is not safe.  safe types need to be
    // excluded to prevent ambiguous function selection which
    // would otherwise occur
    template<
        class R,
        typename std::enable_if<
            ! boost::safe_numerics::is_safe<R>::value,
            int
        >::type = 0
    >
    constexpr operator R () const {
        // if static values don't overlap, the program can never function
        #if 1
        constexpr const interval<R> r_interval;
        static_assert(
            ! r_interval.excludes(N),
            "safe type cannot be constructed with this type"
        );
        #endif

        return validate_detail<
            R,
            std::numeric_limits<R>::min(),
            std::numeric_limits<R>::max(),
            E
        >::return_value(*this);
    }

    // non mutating unary operators
    constexpr safe_literal_impl<T, N, P, E> operator+() const { // unary plus
        return safe_literal_impl<T, N, P, E>();
    }
    // after much consideration, I've permitted the resulting value of a unary
    // - to change the type in accordance with the promotion policy.
    // The C++ standard does invoke integral promotions so it's changing the type as well.

    /*  section 5.3.1 &8 of the C++ standard
    The operand of the unary - operator shall have arithmetic or unscoped
    enumeration type and the result is the negation of its operand. Integral
    promotion is performed on integral or enumeration operands. The negative
    of an unsigned quantity is computed by subtracting its value from 2n,
    where n is the number of bits in the promoted operand. The type of the
    result is the type of the promoted operand.
    */
    template<
        typename Tx, Tx Nx, typename = std::enable_if_t<! checked::minus(Nx).exception()>
    >
    constexpr auto minus_helper() const {
        return safe_literal_impl<Tx, -N, P, E>();
    }

    constexpr auto operator-() const { // unary minus
        return minus_helper<T, N>();
    }

    /*   section 5.3.1 &10 of the C++ standard
    The operand of ~ shall have integral or unscoped enumeration type;
    the result is the ones’ complement of its operand. Integral promotions
    are performed. The type of the result is the type of the promoted operand.
    constexpr safe_literal_impl<T, checked::bitwise_not(N), P, E> operator~() const { // invert bits
        return safe_literal_impl<T, checked::bitwise_not(N), P, E>();
    }
    */
    template<
        typename Tx, Tx Nx, typename = std::enable_if_t<! checked::bitwise_not(Nx).exception()>
    >
    constexpr auto not_helper() const {
        return safe_literal_impl<Tx, ~N, P, E>();
    }

    constexpr auto operator~() const { // unary minus
        return not_helper<T, N>();
    }
};

template<
    std::intmax_t N,
    class P = void,
    class E = void
>
using safe_signed_literal = safe_literal_impl<
    typename utility::signed_stored_type<N, N>,
    N,
    P,
    E
>;

template<
    std::uintmax_t N,
    class P = void,
    class E = void
>
using safe_unsigned_literal = safe_literal_impl<
    typename utility::unsigned_stored_type<N, N>,
    N,
    P,
    E
>;

template<
    class T,
    T N,
    class P = void,
    class E = void,
    typename std::enable_if<
        std::is_signed<T>::value,
        int
    >::type = 0
>
constexpr auto make_safe_literal_impl() {
    return boost::safe_numerics::safe_signed_literal<N, P, E>();
}

template<
    class T,
    T N,
    class P = void,
    class E = void,
    typename std::enable_if<
        ! std::is_signed<T>::value,
        int
    >::type = 0
>
constexpr auto make_safe_literal_impl() {
    return boost::safe_numerics::safe_unsigned_literal<N, P, E>();
}

} // safe_numerics
} // boost

#define make_safe_literal(n, P, E)  \
    boost::safe_numerics::make_safe_literal_impl<decltype(n), n, P, E>()

/////////////////////////////////////////////////////////////////
// numeric limits for safe_literal etc.

#include <limits>

namespace std {

template<
    typename T,
    T N,
    class P,
    class E
>
class numeric_limits<boost::safe_numerics::safe_literal_impl<T, N, P, E> >
    : public std::numeric_limits<T>
{
    using SL = boost::safe_numerics::safe_literal_impl<T, N, P, E>;
public:
    constexpr static SL lowest() noexcept {
        return SL();
    }
    constexpr static SL min() noexcept {
        return SL();
    }
    constexpr static SL max() noexcept {
        return SL();
    }
};

} // std

#endif // BOOST_NUMERIC_SAFE_INTEGER_LITERAL_HPP

max_stars_repo_name: kindlychung/mediasoup-sfu-cpp

max_issues_repo_name: kindlychung/mediasoup-sfu-cpp

max_forks_repo_name: kindlychung/mediasoup-sfu-cpp


text:
/*
 *      Copyright (C) 2013 DataStax Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
#include <map>
#include <sstream>
#include <boost/algorithm/string/join.hpp>
#include "cql/internal/cql_vector_stream.hpp"
#include "cql/internal/cql_serialization.hpp"
#include "cql/internal/cql_defines.hpp"

#include "cql/internal/cql_message_startup_impl.hpp"

cql::cql_message_startup_impl_t::cql_message_startup_impl_t() :
    _buffer(new std::vector<cql_byte_t>()),
    _version(),
    _compression()
{}

cql::cql_message_startup_impl_t::cql_message_startup_impl_t(size_t size) :
    _buffer(new std::vector<cql_byte_t>(size)),
    _version(),
    _compression()
{}

cql::cql_message_buffer_t
cql::cql_message_startup_impl_t::buffer() {
    return _buffer;
}

void
cql::cql_message_startup_impl_t::compression(const std::string& c) {
    _compression = c;
}

const std::string&
cql::cql_message_startup_impl_t::compression() const {
    return _compression;
}

void
cql::cql_message_startup_impl_t::version(const std::string& v) {
    _version = v;
}

const std::string&
cql::cql_message_startup_impl_t::version() const {
    return _version;
}

cql::cql_opcode_enum
cql::cql_message_startup_impl_t::opcode() const {
    return CQL_OPCODE_STARTUP;
}

cql::cql_int_t
cql::cql_message_startup_impl_t::size() const {
    return _buffer->size();
}

std::string
cql::cql_message_startup_impl_t::str() const {
    std::stringstream output;
    output << "{version: " << _version << ", compression: " << _compression << "}";
    return output.str();
}

bool
cql::cql_message_startup_impl_t::consume(cql::cql_error_t*) {
    cql::vector_stream_t buffer(*_buffer);
    std::istream stream(&buffer);

    std::map<std::string, std::string> startup;
    cql::decode_string_map(stream, startup);

    if (startup.find(CQL_VERSION) != startup.end()) {
        _version = startup[CQL_VERSION];
    }

    if (startup.find(CQL_COMPRESSION) != startup.end()) {
        _compression = startup[CQL_COMPRESSION];
    }

    return true;
}

bool
cql::cql_message_startup_impl_t::prepare(cql::cql_error_t*) {
    std::map<std::string, std::string> startup;
    size_t size = sizeof(cql::cql_short_t);

    if (!_version.empty()) {
        startup.insert(std::pair<std::string, std::string>(CQL_VERSION, _version));
        size += strlen(CQL_VERSION) + _version.size() + (2* sizeof(cql::cql_short_t));
    }

    if (!_compression.empty()) {
        startup.insert(std::pair<std::string, std::string>(CQL_COMPRESSION, _compression));
        size += strlen(CQL_COMPRESSION) + _compression.size() + (2* sizeof(cql::cql_short_t));
    }

    _buffer->resize(size);
    cql::vector_stream_t buffer(*_buffer);
    std::ostream stream(&buffer);
    cql::encode_string_map(stream, startup);
    return true;
}

max_stars_repo_name: ncbi/cassandra-cpp-driver

max_issues_repo_name: ncbi/cassandra-cpp-driver

max_forks_repo_name: ncbi/cassandra-cpp-driver


text:
/*
 *          Copyright Andrey Semashev 2007 - 2015.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
/*!
 * \file   bind_output.hpp
 * \author Andrey Semashev
 * \date   30.03.2008
 *
 * This header contains a function object that puts the received value to the
 * bound stream. This is a lightweight alternative to what Boost.Phoenix and
 * Boost.Lambda provides.
 */

#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_BIND_OUTPUT_HPP_INCLUDED_
#define BOOST_LOG_UTILITY_FUNCTIONAL_BIND_OUTPUT_HPP_INCLUDED_

#include <boost/log/detail/config.hpp>
#include <boost/log/detail/header.hpp>
#include <boost/log/utility/functional/bind.hpp>

#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif

namespace boost
{

BOOST_LOG_OPEN_NAMESPACE

//! The function object that outputs its second operand to the first one
struct output_fun
{
    typedef void result_type;

    template <typename StreamT, typename T>
    void operator()(StreamT& strm, T const& val) const
    {
        strm << val;
    }
};

template <typename StreamT>
BOOST_FORCEINLINE binder1st<output_fun, StreamT&> bind_output(StreamT& strm)
{
    return binder1st<output_fun, StreamT&>(output_fun(), strm);
}

BOOST_LOG_CLOSE_NAMESPACE // namespace log

} // namespace boost

#include <boost/log/detail/footer.hpp>

#endif // BOOST_LOG_UTILITY_FUNCTIONAL_BIND_OUTPUT_HPP_INCLUDED_

max_stars_repo_name: sotaoverride/backup

max_issues_repo_name: sotaoverride/backup

max_forks_repo_name: sotaoverride/backup