text:
#include <list>

#include "cppunit/TestCase.h"
#include "rutil/BaseException.hxx"
#include "rutil/Logger.hxx"
#include "tfm/Sequence.hxx"
#include "tfm/SequenceSet.hxx"

#include <boost/version.hpp>

using namespace resip;
using namespace std;
using namespace boost;

#define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST

boost::shared_ptr<SequenceSet> SequenceClass::CPUSequenceSet;
bool SequenceClass::CPUSequenceSetCleanup = true;

void SequenceClass::CPUSequenceSetup()
{
   if (SequenceClass::CPUSequenceSetCleanup)
   {
      // get rid of the old SequenceSet
      if (SequenceClass::CPUSequenceSet)
      {
         //.dcm. -- should rationalize clear and release
         SequenceClass::CPUSequenceSet->clear();
         SequenceClass::CPUSequenceSet->release();
      }
      SequenceSet* sset = new SequenceSet();
      SequenceClass::CPUSequenceSet = sset->getHandle();
      // reuse this SequenceSet until executed
      SequenceClass::CPUSequenceSetCleanup = false;
   }
}

int
SequenceClass::size()
{
   return mExpects.size();
}

bool
SequenceClass::isFailed() const
{
   return mFailed || !mExpects.empty();
}

void
SequenceClass::setParent(SequenceClass* parent)
{
   mParent = parent;
}

SequenceClass*
SequenceClass::getParent() const
{
   return mParent;
}

const SequenceClass&
SequenceClass::getRoot() const
{
   if (this->getParent() == 0)
   {
      return *this;
   }
   return this->getParent()->getRoot();
}

void
SequenceClass::setBranchCount(unsigned int count)
{
   assert(count);
   assert(mBranchCount == 0);

   mBranchCount = count;
   removeFromActiveSet();
}

void
SequenceClass::setAfterAction(ActionBase* action)
{
   delete mAfterAction;
   mAfterAction = action;
}

bool
SequenceClass::decrementBranches()
{
   assert(mBranchCount);
   if (!(--mBranchCount))
   {
      if (mAfterAction)
      {
         InfoLog(<< "All branches satisfied: triggering after action");
         // .dlb. what if this throws?
         mAfterAction->exec();
      }
      return true;
   }
   else
   {
      return false;
   }
}

void
SequenceClass::fail(const resip::Data& message)
{
   // keep first fail info
   if (!getSequenceSet()->mFailed)
   {
      getSequenceSet()->mFailed = true;
      Data errorMessage;
      {
         DataStream str(errorMessage);
         str << message << endl << "Sequence state:" << endl;
         str << "     ";
         bool previousActive = false;
         this->getRoot().prettyPrint(str, previousActive);
         str << endl;
      }
      getSequenceSet()->mExplanation = errorMessage;
      getSequenceSet()->mLineNumber = mLineNumber;
   }
   mFailed = true;
}

void
SequenceClass::prettyPrint(EncodeStream& str, bool& previousActive, int ind) const
{
   if (find(getSequenceSet()->mSequences.begin(),
            getSequenceSet()->mSequences.end(), this) != getSequenceSet()->mSequences.end())
   {
      str << "Seq(";
      str << mAction->toString() << ", ";
   }
   else
   {
      str << "Sub(";
   }

   bool first = true;
   ind += 4;
   for (list<TestEndPoint::ExpectBase*>::const_iterator i = mUsedExpects.begin();
        i != mUsedExpects.end(); i++)
   {
      if (!first)
      {
         str << ", ";
      }
      str << endl;
      str << indent(ind);
      (*i)->prettyPrint(str, previousActive, ind);
   }

   if (!mUsedExpects.empty() && !mExpects.empty())
   {
      str << ", " << endl;
   }

   first = true;
   for (list<TestEndPoint::ExpectBase*>::const_iterator i = mExpects.begin();
        i != mExpects.end(); i++)
   {
      if (!first)
      {
         str << ",";
      }
      str << endl;

      if (!previousActive)
      {
         str << "===> " << indent(ind - 5);
         (*i)->prettyPrint(str, previousActive, ind);
      }
      else
      {
         str << indent(ind);
         (*i)->prettyPrint(str, previousActive, ind);
      }
      first = false;
      previousActive = true;
   }
   str << ")";
   str.flush();
}

bool
SequenceClass::isMatch(boost::shared_ptr<Event> event) const
{
#if BOOST_VERSION >= 103500
   boost::shared_ptr<OptionalTimeoutEvent> to = dynamic_pointer_cast<OptionalTimeoutEvent>(event);
#else
   boost::shared_ptr<OptionalTimeoutEvent> to = shared_dynamic_cast<OptionalTimeoutEvent>(event);
#endif
   for (std::list<TestEndPoint::ExpectBase*>::const_iterator i = mExpects.begin();
        i != mExpects.end(); i++)
   {
      DebugLog(<< "expect matching: " << **i);
      if (to)
      {
         if (to->getExpect() == *i)
         {
            return true;
         }
         else
         {
            continue;
         }
      }
      if ((*i)->isMatch(event))
      {
         return true;
      }
      else if (!(*i)->isOptional())
      {
         return false;
      }
   }
   return false;
}

void
SequenceClass::handleEvent(boost::shared_ptr<Event> event)
{
   TestEndPoint* user = event->getEndPoint();

   InfoLog(<< "inner handleEvent: " << " to " << user << " " << *this << endl << event);
  next:
   if (!mExpects.empty())
   {
      TestEndPoint::ExpectBase* expect = mExpects.front();

      mUsedExpects.push_back(mExpects.front());
      mExpects.pop_front();

#if BOOST_VERSION >= 103500
      boost::shared_ptr<OptionalTimeoutEvent> ot = dynamic_pointer_cast<OptionalTimeoutEvent>(event);
#else
      boost::shared_ptr<OptionalTimeoutEvent> ot = shared_dynamic_cast<OptionalTimeoutEvent>(event);
#endif
      if (ot && ot->getExpect() == expect)
      {
         mTimerId=-7;
         scheduleTimeout();
         return;
      }

      if (!expect->isMatch(event))
      {
         if (expect->isOptional())
         {
            //DebugLog("handleEvent -- skipping optional: " << *expect);
            cancelTimeout();
            scheduleTimeout();
            goto next;
         }
         else
         {
            DebugLog(<< "Failed expect: " << expect->explainMismatch(event));

            fail("Received " + event->briefString() + " expected " + expect->getMsgTypeString());
            return;
         }
      }
      DebugLog(<< "Matched");

      cancelTimeout();
      scheduleTimeout();
      try
      {
         if(user)
         {
            expect->onEvent(*user, event);
         }
         else
         {
            assert(0);
         }
      }
      catch (BaseException& e)
      {
         InfoLog(<< "Failed expect action with: " << e << " for " << event->briefString());
         Data errorMessage;
         {
            DataStream str(errorMessage);
            str << "Failed expect action: " << e << ",  Event: " << event->toString();
         }
         fail(errorMessage);
      }
      catch (std::exception& e)
      {
         InfoLog (<< "Failed expect action with: " << e.what() << " for " << event->briefString());
         Data errorMessage;
         {
            DataStream str(errorMessage);
            str << "Failed expect action: " << e.what() << ",  Event: " << event->toString();
         }
         fail(errorMessage);
      }
      catch (...)
      {
         InfoLog(<< "Failed expect action with an unknown exception, Event: " << event->briefString());
         fail("Failed expect action with an unknown exception, Event: " + event->toString());
      }
   }
   else
   {
      InfoLog(<< "Failed expect: received " << event->briefString() << " expected no more messages");
      fail("Unexpected " + event->toString());
   }
}

void
SequenceClass::addToActiveSet()
{
   //DebugLog( << "Adding sequence: " << this << " to activeSet");
   getSequenceSet()->mActiveSet.insert(this);
   scheduleTimeout();
}

bool
SequenceClass::removeFromActiveSet()
{
   //DebugLog(<< "removeFromActiveSet: " << *this);
   set<SequenceClass*>::iterator i = getSequenceSet()->mActiveSet.find(this);
   if (i != getSequenceSet()->mActiveSet.end())
   {
      getSequenceSet()->mActiveSet.erase(i);
      cancelTimeout();
      return true;
   }
   else
   {
      return false;
   }
}

void SequenceClass::cancelTimeout()
{
   if (mTimerId != -7)
   {
      InfoLog(<< "SequenceClass::cancelTimeout(" << mTimerId << ") " << this);
      if(!getSequenceSet()->mEventFifo.cancel(mTimerId))
      {
         // Race condition; it is likely that the timer is sitting, unprocessed,
         // in our message queue, right as we satisfy the expect that the timer
         // was waiting for. It would be nice to figure out a way to fix this.
         assert(0);
      }
      mTimerId = -7;
   }
}

void SequenceClass::scheduleTimeout()
{
   if (mExpects.empty())
   {
      // schedule sequence done event
      InfoLog(<< "Queuing Sequence done: hangAroundTime: " <<mHangAroundTimeMs);
      mTimingOut = true;
      getSequenceSet()->enqueue(boost::shared_ptr<Event>(new SequenceDoneEvent(this)), mHangAroundTimeMs);
   }
   else
   {
      TestEndPoint::ExpectBase* f = mExpects.front();
      if (f->isOptional())
      {
         mTimerId = getSequenceSet()->enqueue(boost::shared_ptr<Event>(new OptionalTimeoutEvent(*this, f)),
                                              f->getTimeout());
         InfoLog(<< "SequenceClass::scheduleTimeout(" << mTimerId << ") optional");
      }
      else
      {
         mTimerId = getSequenceSet()->enqueue(boost::shared_ptr<Event>(new TimeoutEvent(*this)),
                                              f->getTimeout());
         InfoLog(<< "SequenceClass::scheduleTimeout(" << mTimerId << ") for " << *f << " with timeout "<< f->getTimeout());
      }
   }
}

// execute the starting Action
// (called only from Execute)
void
SequenceClass::start()
{
   mTimerId = -7;
   addToActiveSet();
   mAction->exec();
}

bool
SequenceClass::queue()
{
   if (!mExpects.empty() && mExpects.front()->queue(this))
   {
      mUsedExpects.push_back(mExpects.front());
      mExpects.pop_front();
      return true;
   }
   return false;
}

void
SequenceClass::addExpect(TestEndPoint::ExpectBase* expect)
{
   //DebugLog(<< "addExpect " << expect);

   mExpects.push_back(expect);
}

#include "SequenceClassConstructorDefns.hxx"

SequenceClass::~SequenceClass()
{
   delete mAction;
   for (list<TestEndPoint::ExpectBase*>::const_iterator i = mExpects.begin();
        i != mExpects.end(); i++)
   {
      delete *i;
   }

   for (list<TestEndPoint::ExpectBase*>::const_iterator i = mUsedExpects.begin();
        i != mUsedExpects.end(); i++)
   {
      delete *i;
   }

   delete mAfterAction;

   mSet.reset();
}

EncodeStream&
operator<<(EncodeStream& s, const SequenceClass& sequence)
{
   s << "Sequence(" << &sequence << ", line: " << sequence.mLineNumber << ")[";
   for (list<TestEndPoint::ExpectBase*>::const_iterator i = sequence.mExpects.begin();
        i != sequence.mExpects.end(); i++)
   {
      s << **i << ", ";
   }
   s << "]";
   s.flush();
   return s;
}

bool
operator<(const SequenceClass& lhs, const SequenceClass& rhs)
{
   return &lhs < &rhs;
}

Box
SequenceClass::layout() const
{
   //InfoLog(<< "SequenceClass::layout");

   for (list<TestEndPoint::ExpectBase*>::const_iterator i = mExpects.begin();
        i != mExpects.end(); i++)
   {
      // layout alone (0,0) corner
      Box sub = (*i)->layout();

      // push down to position in sequence
      sub = (*i)->displaceDown(mBox);
      //InfoLog(<< "after displace down: " << sub);
      mBox.boxUnion(sub);
   }

   // center each in the widest
   for (list<TestEndPoint::ExpectBase*>::const_iterator i = mExpects.begin();
        i != mExpects.end(); i++)
   {
      unsigned displace = mBox.mWidth/2 - (*i)->mBox.mWidth/2;
      //InfoLog(<< "displace: " << displace);
      (*i)->displaceRight(Box(0, 0, displace, 0));
   }

   //InfoLog(<< "SequenceClass::layout: " << mBox);

   return mBox;
}

void
SequenceClass::render(CharRaster& out) const
{
   //InfoLog(<< "SequenceClass::render");
   for (list<TestEndPoint::ExpectBase*>::const_iterator i = mExpects.begin();
        i != mExpects.end(); i++)
   {
      (*i)->render(out);
   }

   // pad the | after the sequence
   for (unsigned int i = mBox.mY +mBox.mHeight; i < mContainerBottom; i++)
   {
      out[i][mBox.mX + mBox.mWidth/2+1] = '|';
   }
}

Box&
SequenceClass::displaceDown(const Box& box)
{
   for (list<TestEndPoint::ExpectBase*>::iterator i = mExpects.begin();
        i != mExpects.end(); i++)
   {
      (*i)->displaceDown(box);
   }

   AsciiGraphic::displaceDown(box);
   mContainerBottom += box.mY + box.mHeight;
   return mBox;
}

Box&
SequenceClass::displaceRight(const Box& box)
{
   for (list<TestEndPoint::ExpectBase*>::iterator i = mExpects.begin();
        i != mExpects.end(); i++)
   {
      (*i)->displaceRight(box);
   }

   AsciiGraphic::displaceRight(box);
   return mBox;
}

TimeoutEvent::TimeoutEvent(SequenceClass& sequence)
   : Event(0),
     mSequence(sequence)
{
}

TimeoutEvent::~TimeoutEvent()
{
}

SequenceClass&
TimeoutEvent::getSequence()
{
   return mSequence;
}

resip::Data
TimeoutEvent::toString() const
{
   Data s;
   {
      DataStream str(s);
      str << "<TimeoutEvent> " << mSequence;
   }
   return s;
}

resip::Data
TimeoutEvent::briefString() const
{
   Data s;
   {
      DataStream str(s);
      str << "<TimeoutEvent> " << &mSequence;
   }
   return s;
}

OptionalTimeoutEvent::OptionalTimeoutEvent(SequenceClass& sequence,
                                           TestEndPoint::ExpectBase* expect)
   : Event(0),
     mSequence(sequence),
     mExpect(expect)
{
}

OptionalTimeoutEvent::~OptionalTimeoutEvent()
{
}

SequenceClass&
OptionalTimeoutEvent::getSequence() const
{
   return mSequence;
}

TestEndPoint::ExpectBase*
OptionalTimeoutEvent::getExpect() const
{
   return mExpect;
}

resip::Data
OptionalTimeoutEvent::toString() const
{
   Data s;
   {
      DataStream str(s);
      str << "<OptionalTimeoutEvent> " << mSequence;
   }
   return s;
}

resip::Data
OptionalTimeoutEvent::briefString() const
{
   Data s;
   {
      DataStream str(s);
      str << "<OptionalTimeoutEvent> " << &mSequence;
   }
   return s;
}

SequenceDoneEvent::SequenceDoneEvent(SequenceClass* sequence)
   : Event(0),
     mSequence(sequence)
{
}

SequenceClass*
SequenceDoneEvent::getSequence()
{
   return mSequence;
}

resip::Data
SequenceDoneEvent::toString() const
{
   Data s;
   {
      DataStream str(s);
      str << "<SequenceDoneEvent> " << mSequence;
   }
   return s;
}

resip::Data
SequenceDoneEvent::briefString() const
{
   Data s;
   {
      DataStream str(s);
      str << "<SequenceDoneEvent> " << &mSequence;
   }
   return s;
}

void
SequenceClass::setSequenceSet(boost::shared_ptr<SequenceSet> set)
{
   mSet = set;
   for (list<TestEndPoint::ExpectBase*>::const_iterator i = mExpects.begin();
        i != mExpects.end(); i++)
   {
      (*i)->setSequenceSet(set);
   }

   for (list<TestEndPoint::ExpectBase*>::const_iterator i = mUsedExpects.begin();
        i != mUsedExpects.end(); i++)
   {
      (*i)->setSequenceSet(set);
   }
}

#include "SeqDefns.hxx"
#include "SubDefns.hxx"

// Copyright 2005 Purplecomm, Inc.
/*
  Copyright (c) 2005, PurpleComm, Inc.
  All rights reserved.

  Redistribution and use in source and binary forms, with or without modification,
  are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.
  * Neither the name of PurpleComm, Inc. nor the names of its contributors may
    be used to endorse or promote products derived from this software without
    specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

ext: cxx

max_stars_repo_name: dulton/reSipServer

max_issues_repo_name: dulton/reSipServer

max_forks_repo_name: dulton/reSipServer


text:
// -*- coding: utf-16 -*-
#pragma once

/*! @file include/fractions.hpp
 *  This is a C++ Library header.
 */

#include <boost/operators.hpp>
// #include <cmath>
#include "common_concepts.h"
#include <numeric>
#include <type_traits>
#include <utility>

namespace fun
{

/**
 * @brief absolute (for unsigned)
 *
 * @tparam T
 * @param a
 * @return T
 */
template <typename T>
requires std::is_unsigned_v<T>
inline constexpr auto abs(const T& a) -> T
{
    return a;
}

/**
 * @brief absolute
 *
 * @tparam T
 */
template <typename T>
requires (!std::is_unsigned_v<T> && ordered_ring<T>)
inline constexpr auto abs(const T& a) -> T
{
    return (a < T(0)) ? -a : a;
}

/*!
 * @brief Greatest common divider
 *
 * @tparam _Mn
 * @param[in] __m
 * @param[in] __n
 * @return _Mn
 */
template <Integral _Mn>
inline constexpr auto gcd_recur(_Mn __m, _Mn __n) -> _Mn
{
    if (__n == 0)
    {
        return abs(__m);
    }
    return gcd_recur(__n, __m % __n);
}

/*!
 * @brief Greatest common divider
 *
 * @tparam _Mn
 * @param[in] __m
 * @param[in] __n
 * @return _Mn
 */
template <Integral _Mn>
inline constexpr auto gcd(_Mn __m, _Mn __n) -> _Mn
{
    if (__m == 0)
    {
        return abs(__n);
    }
    return gcd_recur(__m, __n);
}

/*!
 * @brief Least common multiple
 *
 * @tparam _Mn
 * @param[in] __m
 * @param[in] __n
 * @return _Mn
 */
template <Integral _Mn>
inline constexpr auto lcm(_Mn __m, _Mn __n) -> _Mn
{
    if (__m == 0 || __n == 0)
    {
        return 0;
    }
    return (abs(__m) / gcd(__m, __n)) * abs(__n);
}

template <Integral Z>
struct Fraction : boost::totally_ordered<Fraction<Z>,
                      boost::totally_ordered2<Fraction<Z>, Z,
                          boost::multipliable2<Fraction<Z>, Z,
                              boost::dividable2<Fraction<Z>, Z>>>>
{
    Z _num;
    Z _den;

    /*!
     * @brief Construct a new Fraction object
     *
     * @param[in] num
     * @param[in] den
     */
    constexpr Fraction(Z num, Z den)
        : _num {std::move(num)}
        , _den {std::move(den)}
    {
        this->normalize();
    }

    constexpr void normalize()
    {
        Z common = gcd(this->_num, this->_den);
        if (common == Z(1) || common == Z(0))
        {
            return;
        }
        if (this->_den < Z(0))
        {
            common = -common;
        }
        this->_num /= common;
        this->_den /= common;
    }

    /*!
     * @brief Construct a new Fraction object
     *
     * @param[in] num
     */
    constexpr explicit Fraction(Z&& num)
        : _num {std::move(num)}
        , _den(Z(1))
    {
    }

    /*!
     * @brief Construct a new Fraction object
     *
     * @param[in] num
     */
    constexpr explicit Fraction(const Z& num)
        : _num {num}
        , _den(1)
    {
    }

    /*!
     * @brief Construct a new Fraction object
     *
     * @param[in] num
     */
    constexpr Fraction()
        : _num(0)
        , _den(1)
    {
    }

    /*!
     * @brief
     *
     * @return const Z&
     */
    [[nodiscard]] constexpr auto num() const noexcept -> const Z&
    {
        return _num;
    }

    /*!
     * @brief
     *
     * @return const Z&
     */
    [[nodiscard]] constexpr auto den() const noexcept -> const Z&
    {
        return _den;
    }

    /*!
     * @brief
     *
     * @return Fraction
     */
    [[nodiscard]] constexpr auto abs() const -> Fraction
    {
        return Fraction(abs(this->_num), abs(this->_den));
    }

    /*!
     * @brief
     *
     */
    constexpr void reciprocal() noexcept(std::is_nothrow_swappable_v<Z>)
    {
        std::swap(this->_num, this->_den);
    }

    /*!
     * @brief
     *
     * @return Fraction
     */
    constexpr auto operator-() const -> Fraction
    {
        auto res = Fraction(*this);
        res._num = -res._num;
        return res;
    }

    /*!
     * @brief
     *
     * @param[in] frac
     * @return Fraction
     */
    constexpr auto operator+(const Fraction& frac) const -> Fraction
    {
        if (this->_den == frac._den)
        {
            return Fraction(this->_num + frac._num, this->_den);
        }
        auto d = this->_den * frac._den;
        auto n = frac._den * this->_num + this->_den * frac._num;
        return Fraction(n, d);
    }

    /*!
     * @brief
     *
     * @param[in] frac
     * @return Fraction
     */
    constexpr auto operator-(const Fraction& frac) const -> Fraction
    {
        return *this + (-frac);
    }

    /*!
     * @brief
     *
     * @param[in] frac
     * @return Fraction
     */
    constexpr auto operator*(const Fraction& frac) const -> Fraction
    {
        auto n = this->_num * frac._num;
        auto d = this->_den * frac._den;
        return Fraction(std::move(n), std::move(d));
    }

    /*!
     * @brief
     *
     * @param[in] frac
     * @return Fraction
     */
    constexpr auto operator/(Fraction frac) const -> Fraction
    {
        frac.reciprocal();
        return *this * frac;
    }

    /*!
     * @brief
     *
     * @param[in] i
     * @return Fraction
     */
    constexpr auto operator+(const Z& i) const -> Fraction
    {
        auto n = this->_num + this->_den * i;
        return Fraction(std::move(n), this->_den);
    }

    /*!
     * @brief
     *
     * @param[in] i
     * @return Fraction
     */
    constexpr auto operator-(const Z& i) const -> Fraction
    {
        return *this + (-i);
    }

    // /*!
    //  * @brief
    //  *
    //  * @param[in] i
    //  * @return Fraction
    //  */
    // constexpr Fraction operator*(const Z& i) const noexcept
    // {
    //     auto n = _num * i;
    //     return Fraction(n, _den);
    // }

    // /*!
    //  * @brief
    //  *
    //  * @param[in] i
    //  * @return Fraction
    //  */
    // constexpr Fraction operator/(const Z& i) const noexcept
    // {
    //     auto d = _den * i;
    //     return Fraction(_num, d);
    // }

    /*!
     * @brief
     *
     * @param[in] frac
     * @return Fraction
     */
    constexpr auto operator+=(const Fraction& frac) -> Fraction&
    {
        return *this = *this + frac;
    }

    /*!
     * @brief
     *
     * @param[in] frac
     * @return Fraction
     */
    constexpr auto operator-=(const Fraction& frac) -> Fraction&
    {
        return *this = *this - frac;
    }

    /*!
     * @brief
     *
     * @param[in] frac
     * @return Fraction
     */
    constexpr auto operator*=(const Fraction& frac) -> Fraction&
    {
        return *this = *this * frac;
    }

    /*!
     * @brief
     *
     * @param[in] frac
     * @return Fraction
     */
    constexpr auto operator/=(const Fraction& frac) -> Fraction&
    {
        return *this = *this / frac;
    }

    /*!
     * @brief
     *
     * @param[in] i
     * @return Fraction
     */
    constexpr auto operator+=(const Z& i) -> Fraction&
    {
        return *this = *this + i;
    }

    /*!
     * @brief
     *
     * @param[in] i
     * @return Fraction
     */
    constexpr auto operator-=(const Z& i) -> Fraction&
    {
        return *this = *this - i;
    }

    /*!
     * @brief
     *
     * @param[in] i
     * @return Fraction
     */
    constexpr auto operator*=(const Z& i) -> Fraction&
    {
        const auto common = gcd(i, this->_den);
        if (common == Z(1))
        {
            this->_num *= i;
        }
        // else if (common == Z(0)) [[unlikely]] // both i and den are zero
        // {
        //     this->_num = Z(0);
        // }
        else
        {
            this->_num *= (i / common);
            this->_den /= common;
        }
        return *this;
    }

    /*!
     * @brief
     *
     * @param[in] i
     * @return Fraction
     */
    constexpr auto operator/=(const Z& i) -> Fraction&
    {
        const auto common = gcd(this->_num, i);
        if (common == Z(1))
        {
            this->_den *= i;
        }
        // else if (common == Z(0)) [[unlikely]] // both i and num are zero
        // {
        //     this->_den = Z(0);
        // }
        else
        {
            this->_den *= (i / common);
            this->_num /= common;
        }
        return *this;
    }

    /*!
     * @brief Three way comparison
     *
     * @param[in] frac
     * @return auto
     */
    template <typename U>
    constexpr auto cmp(const Fraction<U>& frac) const -> Fraction&
    {
        if (this->_den == frac._den)
        {
            return (this->_num - frac._num) * this->_den;
        }
        return this->_num * frac._den - this->_den * frac._num;
    }

    template <typename U>
    constexpr auto operator==(const Fraction<U>& rhs) const -> bool
    {
        if (this->_den == rhs._den)
        {
            return this->_num == rhs._num;
        }

        return this->_num * rhs._den == this->_den * rhs._num;
    }

    template <typename U>
    constexpr auto operator<(const Fraction<U>& rhs) const -> bool
    {
        if (this->_den == rhs._den)
        {
            return this->_num < rhs._num;
        }

        return this->_num * rhs._den < this->_den * rhs._num;
    }

    /**
     * @brief
     *
     */
    constexpr auto operator==(const Z& rhs) const -> bool
    {
        return this->_den == Z(1) && this->_num == rhs;
    }

    /**
     * @brief
     *
     */
    constexpr auto operator<(const Z& rhs) const -> bool
    {
        return this->_num < this->_den * rhs;
    }

    /**
     * @brief
     *
     */
    constexpr auto operator>(const Z& rhs) const -> bool
    {
        return this->_num > this->_den * rhs;
    }

    // /*!
    //  * @brief
    //  *
    //  * @return double
    //  */
    // constexpr explicit operator double())
    // {
    //     return double(_num) / _den;
    // }

    // /**
    //  * @brief
    //  *
    //  */
    // friend constexpr bool operator<(const Z& lhs, const Fraction<Z>& rhs))
    // {
    //     return lhs * rhs.den() < rhs.num();
    // }
};

/*!
 * @brief
 *
 * @param[in] c
 * @param[in] frac
 * @return Fraction<Z>
 */
template <typename Z>
constexpr auto operator+(const Z& c, const Fraction<Z>& frac) -> Fraction<Z>
{
    return frac + c;
}

/*!
 * @brief
 *
 * @param[in] c
 * @param[in] frac
 * @return Fraction<Z>
 */
template <typename Z>
constexpr auto operator-(const Z& c, const Fraction<Z>& frac) -> Fraction<Z>
{
    return c + (-frac);
}

// /*!
//  * @brief
//  *
//  * @param[in] c
//  * @param[in] frac
//  * @return Fraction<Z>
//  */
// template <typename Z>
// constexpr Fraction<Z> operator*(const Z& c, const Fraction<Z>& frac)
// {
//     return frac * c;
// }

/*!
 * @brief
 *
 * @param[in] c
 * @param[in] frac
 * @return Fraction<Z>
 */
template <typename Z>
constexpr auto operator+(int&& c, const Fraction<Z>& frac) -> Fraction<Z>
{
    return frac + c;
}

/*!
 * @brief
 *
 * @param[in] c
 * @param[in] frac
 * @return Fraction<Z>
 */
template <typename Z>
constexpr auto operator-(int&& c, const Fraction<Z>& frac) -> Fraction<Z>
{
    return (-frac) + c;
}

/*!
 * @brief
 *
 * @param[in] c
 * @param[in] frac
 * @return Fraction<Z>
 */
template <typename Z>
constexpr auto operator*(int&& c, const Fraction<Z>& frac) -> Fraction<Z>
{
    return frac * c;
}

/*!
 * @brief
 *
 * @tparam _Stream
 * @tparam Z
 * @param[in] os
 * @param[in] frac
 * @return _Stream&
 */
template <typename _Stream, typename Z>
auto operator<<(_Stream& os, const Fraction<Z>& frac) -> _Stream&
{
    os << frac.num() << "/" << frac.den();
    return os;
}

// For template deduction
// Integral{Z} Fraction(const Z &, const Z &) noexcept -> Fraction<Z>;

} // namespace fun

ext: hpp


text:
/** sys_mmap_test.cc                                 -*- C++ -*-
    Rémi Attab, 05 Nov 2012
    Copyright (c) 2012 Datacratic.  All rights reserved.

    Tests for the mmap syscall to test various things.

*/

#define BOOST_TEST_MAIN
#define BOOST_TEST_DYN_LINK

#include "mmap_test.h"
#include "mmap/mmap_const.h"
#include "jml/utils/exc_assert.h"
#include "jml/utils/guard.h"

#include <boost/test/unit_test.hpp>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <algorithm>
#include <string>

using namespace std;
using namespace ML;
using namespace Datacratic::MMap;

struct SysMMapFixture : public TestFolderFixture {
    SysMMapFixture() : TestFolderFixture("sys_mmap_test") {}
    virtual ~SysMMapFixture () {}
};

/** Tests whether we can remap an VMA by specifying only the last page in a
    range. Turns out that we can! This makes it much easier to resize the region
    while there's an ongoing snapshot because it doesn't matter if the VMA is
    fragmented.

 */
BOOST_FIXTURE_TEST_CASE( test_remap, SysMMapFixture )
{
    int fd = open("test_file.bin", O_RDWR | O_CREAT | O_TRUNC, 0660);
    ExcCheckErrno(fd != -1, "open failed");

    {
        int ret = ftruncate(fd, page_size * 2);
        ExcCheckErrno(ret != -1, "truncate failed");
    }

    uint8_t* addr = (uint8_t*) mmap(
            nullptr, page_size * 2, PROT_READ | PROT_WRITE,
            MAP_SHARED, fd, 0);
    ExcCheckErrno(addr != MAP_FAILED, "mmap failed");

    fill(addr, addr + page_size * 2, 0xA5);

    {
        int ret = ftruncate(fd, page_size * 4);
        ExcCheckErrno(ret != -1, "expand truncate failed");
    }

    uint8_t* new_addr = (uint8_t*) mremap(
            addr + page_size, page_size, page_size * 3, 0, 0);
    ExcCheckErrno(new_addr != MAP_FAILED, "mremap failed");
    ExcCheckEqual(new_addr, addr + page_size, "mmap moved");

    fill(addr + page_size * 2, addr + page_size * 4, 0xA5);

    bool eq = all_of(addr, addr + page_size * 4, [](uint8_t v) {
                return v == 0xA5; });
    ExcCheck(eq, "check failed");
}

ext: cc

max_stars_repo_name: datacratic/DasDB

max_issues_repo_name: datacratic/DasDB

max_forks_repo_name: datacratic/DasDB


text:
#include "network_input/networking/network_client.h"

#include <boost/bind.hpp>

#include "util/constants.h"
#include "util/logger/init.h"
#include "util/ros_messages.h"

NetworkClient::NetworkClient(ros::NodeHandle& node_handle) : backend(), io_service()
{
    // Set up publishers
    world_publisher = node_handle.advertise<thunderbots_msgs::World>(
        Util::Constants::NETWORK_INPUT_WORLD_TOPIC, 1);
    gamecontroller_publisher = node_handle.advertise<thunderbots_msgs::RefboxData>(
        Util::Constants::NETWORK_INPUT_GAMECONTROLLER_TOPIC, 1);

    // Set up our connection over udp to receive vision packets
    try
    {
        ssl_vision_client = std::make_unique<SSLVisionClient>(
            io_service, Util::Constants::SSL_VISION_MULTICAST_ADDRESS,
            Util::Constants::SSL_VISION_MULTICAST_PORT,
            boost::bind(&NetworkClient::filterAndPublishVisionData, this, _1));
    }
    catch (const boost::exception& ex)
    {
        // LOG(FATAL) will terminate the network_input process
        LOG(FATAL) << "An error occured while setting up the SSL Vision Client:"
                   << std::endl
                   << boost::diagnostic_information(ex) << std::endl;
    }

    // Set up our connection over udp to receive gamecontroller packets
    try
    {
        ssl_gamecontroller_client = std::make_unique<SSLGameControllerClient>(
            io_service, Util::Constants::SSL_GAMECONTROLLER_MULTICAST_ADDRESS,
            Util::Constants::SSL_GAMECONTROLLER_MULTICAST_PORT,
            boost::bind(&NetworkClient::filterAndPublishGameControllerData, this, _1));
    }
    catch (const boost::exception& ex)
    {
        // LOG(FATAL) will terminate the network_input process
        LOG(FATAL) << "An error occured while setting up the SSL GameController Client:"
                   << std::endl
                   << boost::diagnostic_information(ex) << std::endl;
    }

    // Start the thread to run the io_service in the background
    io_service_thread = std::thread([this]() { io_service.run(); });
}

NetworkClient::~NetworkClient()
{
    // Stop the io_service. This is safe to call from another thread.
    // https://stackoverflow.com/questions/4808848/boost-asio-stopping-io-service
    // This MUST be done before attempting to join the thread because otherwise the
    // io_service will not stop and the thread will not join
    io_service.stop();

    // Join the io_service_thread so that we wait for it to exit before destructing the
    // thread object. If we do not wait for the thread to finish executing, it will call
    // `std::terminate` when we deallocate the thread object and kill our whole program
    io_service_thread.join();
}

void NetworkClient::filterAndPublishVisionData(SSL_WrapperPacket packet)
{
    if (packet.has_geometry())
    {
        const auto& latest_geometry_data = packet.geometry();
        Field field                      = backend.getFieldData(latest_geometry_data);
        thunderbots_msgs::Field field_msg =
            Util::ROSMessages::convertFieldToROSMessage(field);
        world_msg.field = field_msg;
    }

    if (packet.has_detection())
    {
        auto detection = packet.detection();
        // add the detection to the map, replacing any existing values
        auto ret = latest_detection_data.insert(
            std::make_pair(detection.camera_id(), detection));
        // check if we inserted successfully. if not, modify the existing
        // entry to be our new value
        if (!ret.second)
        {
            ret.first->second = detection;
        }

        // Create a vector of the latest detection data for each camera
        std::vector<SSL_DetectionFrame> latest_detections;
        for (auto it = latest_detection_data.begin(); it != latest_detection_data.end();
             it++)
        {
            latest_detections.push_back(it->second);
        }

        Ball ball = backend.getFilteredBallData(latest_detections);
        thunderbots_msgs::Ball ball_msg =
            Util::ROSMessages::convertBallToROSMessage(ball);
        world_msg.ball = ball_msg;

        Team friendly_team = backend.getFilteredFriendlyTeamData(latest_detections);
        thunderbots_msgs::Team friendly_team_msg =
            Util::ROSMessages::convertTeamToROSMessage(friendly_team);
        world_msg.friendly_team = friendly_team_msg;

        Team enemy_team = backend.getFilteredEnemyTeamData(latest_detections);
        thunderbots_msgs::Team enemy_team_msg =
            Util::ROSMessages::convertTeamToROSMessage(enemy_team);
        world_msg.enemy_team = enemy_team_msg;
    }

    world_publisher.publish(world_msg);
}

void NetworkClient::filterAndPublishGameControllerData(Referee packet)
{
    auto gamecontroller_data_msg = backend.getRefboxDataMsg(packet);
    world_msg.refbox_data        = gamecontroller_data_msg;
    world_publisher.publish(world_msg);
}

ext: cpp

max_stars_repo_name: FSXAC/Software

max_issues_repo_name: FSXAC/Software

max_forks_repo_name: FSXAC/Software


text:
// Copyright (c) 2015-2020 Daniel Cooke
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

#ifndef variant_hpp
#define variant_hpp

#include <string>
#include <functional>
#include <algorithm>
#include <iterator>
#include <utility>
#include <iosfwd>
#include <stdexcept>

#include <boost/functional/hash.hpp>

#include "basics/genomic_region.hpp"
#include "concepts/comparable.hpp"
#include "concepts/mappable.hpp"
#include "allele.hpp"

namespace octopus {

class ReferenceGenome;

/*
 A variant is a combination of a reference allele and an alternative allele.
 */
class Variant : public Comparable<Variant>, public Mappable<Variant>
{
public:
    using MappingDomain      = Allele::MappingDomain;
    using NucleotideSequence = Allele::NucleotideSequence;

    Variant() = default;

    template <typename R, typename A>
    Variant(R&& reference, A&& alternative);

    template <typename GenomicRegion_, typename Sequence1, typename Sequence2>
    Variant(GenomicRegion_&& reference_allele_region,
            Sequence1&& reference_allele, Sequence2&& alternative_allele);

    template <typename String, typename Sequence1, typename Sequence2>
    Variant(String&& reference_contig_name, MappingDomain::Position reference_begin,
            Sequence1&& reference_allele, Sequence2&& alternative_allele);

    Variant(const Variant&)            = default;
    Variant& operator=(const Variant&) = default;
    Variant(Variant&&)                 = default;
    Variant& operator=(Variant&&)      = default;

    ~Variant() = default;

    const GenomicRegion& mapped_region() const noexcept;

    const Allele& ref_allele() const noexcept;
    const Allele& alt_allele() const noexcept;

private:
    Allele reference_, alternative_;
};

template <typename R, typename A>
Variant::Variant(R&& reference, A&& alternative)
: reference_ {std::forward<R>(reference)}
, alternative_ {std::forward<A>(alternative)}
{
    if (!is_same_region(reference_, alternative_)) {
        throw std::logic_error {"Variant: reference & alternative alleles must define the same region"};
    }
}

template <typename GenomicRegion_, typename Sequence1, typename Sequence2>
Variant::Variant(GenomicRegion_&& ref_region, Sequence1&& ref_sequence, Sequence2&& alt_sequence)
: reference_ {ref_region, std::forward<Sequence1>(ref_sequence)}
, alternative_ {std::forward<GenomicRegion_>(ref_region), std::forward<Sequence2>(alt_sequence)}
{}

template <typename String, typename Sequence1, typename Sequence2>
Variant::Variant(String&& ref_contig_name, const MappingDomain::Position ref_begin,
                 Sequence1&& ref_sequence, Sequence2&& alt_sequence)
: reference_ {std::forward<String>(ref_contig_name), ref_begin, std::forward<Sequence1>(ref_sequence)}
, alternative_ {reference_.mapped_region(), std::forward<Sequence2>(alt_sequence)}
{}

// non-member methods

Variant make_variant(const Allele& alt_allele, const ReferenceGenome& reference);

const Variant::NucleotideSequence& ref_sequence(const Variant& variant);
const Variant::NucleotideSequence& alt_sequence(const Variant& variant);

Variant::NucleotideSequence::size_type ref_sequence_size(const Variant& variant);
Variant::NucleotideSequence::size_type alt_sequence_size(const Variant& variant);

bool operator==(const Variant& lhs, const Variant& rhs);
bool operator<(const Variant& lhs, const Variant& rhs);

void remove_duplicates(std::vector<Variant>& variants);

std::vector<Variant> split_mnv(const Variant& variant);

/*
 Decomposes a list of variants into unique alleles in the same order as the given variants.
 The reference allele for each unique GenomicRegion will appear first in the sub-list.
 */
std::vector<Allele> decompose(const std::vector<Variant>& variants);
std::vector<std::reference_wrapper<const Allele>> decompose_ref(const std::vector<Variant>& variants);

std::vector<Allele> extract_intervening_reference_alleles(const std::vector<Variant>& variants,
                                                          const ReferenceGenome& reference);

bool can_trim(const Variant& v);

Variant trim(const Variant& v);

/*
 A variant is parsimonious if and only if it is represented in as few nucleotides as possible
 without an allele of length 0.
 */
bool is_parsimonious(const Variant& variant) noexcept;

/*
 See http://genome.sph.umich.edu/wiki/Variant_Normalization for details on variant parsimony.
 The requirement of the template type R is a SequenceType sequence(const GenomicRegion&)
 method.

 G is a functor which must return a char of the given GenomicRegion position.
 */
template <typename G>
Variant make_parsimonious(const Variant& variant, G generator)
{
    using std::move; using std::cbegin; using std::cend; using std::crbegin; using std::crend;

    using NucleotideSequence = Variant::NucleotideSequence;

    const auto& old_ref_region   = mapped_region(variant);
    const auto& old_ref_sequence = ref_sequence(variant);
    const auto& old_alt_sequence = alt_sequence(variant);

    if (old_ref_sequence.empty() || old_alt_sequence.empty()) {
        if (old_ref_region.begin() > 0) {
            auto new_ref_region = expand_lhs(old_ref_region, 1);

            const char new_base = generator(head_position(new_ref_region));

            NucleotideSequence new_ref_allele(old_ref_sequence.size() + 1, new_base);
            std::copy(cbegin(old_ref_sequence), cend(old_ref_sequence),
                      std::next(begin(new_ref_allele)));

            NucleotideSequence new_alt_allele(old_alt_sequence.size() + 1, new_base);
            std::copy(cbegin(old_alt_sequence), cend(old_alt_sequence),
                      std::next(begin(new_alt_allele)));

            return Variant {move(new_ref_region), move(new_ref_allele), move(new_alt_allele)};
        } else {
            // In this rare case the only option is to pad to the right.
            auto new_ref_region = expand_rhs(old_ref_region, 1);

            const char new_base = generator(tail_position(new_ref_region));

            NucleotideSequence new_ref_allele(old_ref_sequence.size() + 1, new_base);
            std::copy(cbegin(old_ref_sequence), cend(old_ref_sequence), begin(new_ref_allele));

            NucleotideSequence new_alt_allele(old_alt_sequence.size() + 1, new_base);
            std::copy(cbegin(old_alt_sequence), cend(old_alt_sequence), begin(new_alt_allele));

            return Variant {move(new_ref_region), move(new_ref_allele), move(new_alt_allele)};
        }
    }

    const auto& alleles = std::minmax(old_ref_sequence, old_alt_sequence,
                                      [] (const auto& lhs, const auto& rhs) {
                                          return lhs.size() < rhs.size();
                                      });
    const auto& small_allele = alleles.first;
    const auto& big_allele   = alleles.second;

    auto pf = std::mismatch(cbegin(small_allele), cend(small_allele), cbegin(big_allele));

    if (pf.first == cbegin(small_allele) && small_allele.size() == 1) {
        return variant;
    }

    const auto pb = std::mismatch(crbegin(small_allele), std::make_reverse_iterator(pf.first),
                                  crbegin(big_allele));

    if (pf.first == cbegin(small_allele) && pb.first == crbegin(small_allele)) {
        return variant;
    }

    if (pf.first == std::cend(small_allele)) {
        --pf.first;
        --pf.second;
    }

    NucleotideSequence new_big_allele   {pf.second, pb.second.base()};
    NucleotideSequence new_small_allele {pf.first, pb.first.base()};

    using S = GenomicRegion::Position;
    GenomicRegion new_ref_region {
        old_ref_region.contig_name(),
        old_ref_region.begin() + static_cast<S>(std::distance(cbegin(small_allele), pf.first)),
        old_ref_region.end()   - static_cast<S>(std::distance(crbegin(small_allele), pb.first))
    };

    if (old_ref_sequence.size() > old_alt_sequence.size()) {
        return Variant {move(new_ref_region), move(new_big_allele), move(new_small_allele)};
    } else {
        return Variant {move(new_ref_region), move(new_small_allele), move(new_big_allele)};
    }
}

Variant make_parsimonious(const Variant& variant, const ReferenceGenome& reference);

bool is_left_alignable(const Variant& variant) noexcept;

// Note there are no 'is_left_aligned' or 'is_normalised' methods because they
// would take as much work as calling 'left_align'.

/*
 A variant is left aligned if and only if it is no longer possible to shift its position
 to the left while keeping the length of all its alleles constant.
 */
Variant left_align(const Variant& variant, const ReferenceGenome& reference,
                   GenomicRegion::Size extension_size = 30);

/*
 A variant is normalised if and only if it is parsimonious and left aligned.
 */
Variant normalise(const Variant& variant, const ReferenceGenome& reference,
                  unsigned extension_size = 30);

Variant pad_left(const Variant& variant, const Variant::NucleotideSequence& sequence);
Variant pad_right(const Variant& variant, const Variant::NucleotideSequence& sequence);
Variant pad_right(const Variant& variant, const ReferenceGenome& reference, unsigned n);
Variant pad_left(const Variant& variant, const ReferenceGenome& reference, unsigned n);
Variant pad_right(const Variant& variant, const ReferenceGenome& reference, unsigned n);

/*
 Left aligns all input Variants and removes any resulting duplicates. The returned variants are sorted.
 */
std::vector<Variant> unique_left_align(const std::vector<Variant>& variants,
                                       const ReferenceGenome& reference);
std::vector<Variant> unique_left_align(std::vector<Variant>&& variants,
                                       const ReferenceGenome& reference);

std::vector<Variant> parsimonise_each(const std::vector<Variant>& variants,
                                      const ReferenceGenome& reference);
std::vector<Variant> parsimonise_each(std::vector<Variant>&& variants,
                                      const ReferenceGenome& reference);

std::vector<Variant> parsimonise_together(const std::vector<Variant>& variants,
                                          const ReferenceGenome& reference);

bool is_snv(const Variant& variant) noexcept;
bool is_mnv(const Variant& variant) noexcept;
bool is_insertion(const Variant& variant) noexcept;
bool is_deletion(const Variant& variant) noexcept;
bool is_indel(const Variant& variant) noexcept;
bool is_simple_insertion(const Variant& variant) noexcept;
bool is_simple_deletion(const Variant& variant) noexcept;
bool is_simple_indel(const Variant& variant) noexcept;
bool are_same_type(const Variant& lhs, const Variant& rhs) noexcept;
bool is_transition(const Variant& variant) noexcept;
bool is_transversion(const Variant& variant) noexcept;
Variant::NucleotideSequence::size_type indel_size(const Variant& variant) noexcept;

std::vector<Allele::NucleotideSequence> extract_alt_allele_sequences(const std::vector<Variant>& variants);

std::ostream& operator<<(std::ostream& os, const Variant& variant);

struct VariantHash
{
    std::size_t operator()(const Variant& variant) const
    {
        using boost::hash_combine;
        size_t result {};
        hash_combine(result, std::hash<GenomicRegion>()(variant.mapped_region()));
        hash_combine(result, std::hash<Allele::NucleotideSequence>()(ref_sequence(variant)));
        hash_combine(result, std::hash<Allele::NucleotideSequence>()(alt_sequence(variant)));
        return result;
    }
};

} // namespace octopus

namespace std {
    template <> struct hash<octopus::Variant>
    {
        size_t operator()(const octopus::Variant& variant) const
        {
            return octopus::VariantHash()(variant);
        }
    };
} // namespace std

#endif

max_stars_repo_name: roryk/octopus

max_issues_repo_name: roryk/octopus

max_forks_repo_name: roryk/octopus


text:
#ifndef BOOST_NETWORK_INCLUDE_HTTP_CLIENT_HPP_
#define BOOST_NETWORK_INCLUDE_HTTP_CLIENT_HPP_

// Copyright 2009 Dean Michael Berris
// 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)
//
// This is the modular include file for using the HTTP Client

#include <boost/network/protocol/http/client.hpp>

#endif  // BOOST_NETWORK_INCLUDE_HTTP_CLIENT_HPP_

max_stars_repo_name: ccnyou/cpp-netlib-stable


text:
/**
 * BlockchainInterface.cpp
 *
 * @author Krzysztof Okupski
 * @version 1.0
 */

#define BOOST_TEST_DYN_LINK

#include <boost/test/unit_test.hpp>
#include "Main.cpp"

#include "BlockchainInterface.h"
#include "DataInterface.h"

using namespace BlockchainInterface;

BOOST_AUTO_TEST_SUITE(BlockchainInterfaceTests)

BOOST_AUTO_TEST_CASE(SelectInput_Test)
{
	uint64_t minBudget = 1;
	InitInputs inputs;

	inputs = SelectInputs(minBudget);

	BOOST_REQUIRE(inputs.utxo.size() >= 1);
	BOOST_REQUIRE(inputs.budget >= minBudget);
}

BOOST_AUTO_TEST_CASE(PackIntoSequenceNr_Test)
{
	for(int i = 0; i < 1000; i++)
	{
		DataBits bits = Utilities::GenerateRandomBits(i % 100);
		DataBits copy = DataBits(bits);

		DataBits slice = SliceBits(bits, std::min(32, i % 100));
		PadBits(slice, 32 - slice.size());

		CTxIn input = CTxIn();
		PackDataIntoSeqNr(copy, input);

		BOOST_REQUIRE(slice == UnpackDataFromSeqNr(input));
		BOOST_REQUIRE(bits == copy);
	}
}

BOOST_AUTO_TEST_CASE(PackIntoNulldata_Test)
{
	for(int i = 0; i < 1000; i++)
	{
		DataBits bits = Utilities::GenerateRandomBits(i % 500);
		DataBits copy = DataBits(bits);

		DataBits slice = SliceBits(bits, std::min(320, i % 500));
		PadBits(slice, 320 - slice.size());

		CTxOut output = CTxOut();
		PackDataIntoNulldata(copy, output);

		BOOST_REQUIRE(slice == UnpackDataFromNulldata(output));
		BOOST_REQUIRE(bits == copy);
	}
}

BOOST_AUTO_TEST_CASE(PackIntoBudgetSplit_Test)
{
	for(int i = 0; i < 1000; i++)
	{
		DataBits bits = Utilities::GenerateRandomBits(i % 500);
		DataBits copy = DataBits(bits);

		uint64_t budget = pow(10,7);
		uint64_t lbound = 546;
		int nOuts = 2 + (i%19);
		int nBits = DataInterface::EmbeddableBitsInValues(budget-(nOuts*lbound), nOuts);

		DataBits slice = SliceBits(bits, std::min(nBits, i % 500));
		PadBits(slice, nBits - slice.size());

		std::vector<CTxOut> txOuts(nOuts);
		PackDataIntoBudgetSplit(copy, txOuts, budget, lbound);

		BOOST_REQUIRE(slice == UnpackDataFromBudgetSplit(txOuts, lbound));
		BOOST_REQUIRE(bits == copy);
	}
}

BOOST_AUTO_TEST_CASE(PackIntoBudgetClaim_Test)
{
	for(int i = 0; i < 1000; i++)
	{
		DataBits bits = Utilities::GenerateRandomBits(i % 500);
		DataBits copy = DataBits(bits);

		uint16_t nIns = 2 + (i%19);
		std::vector<CTxIn> inputs(nIns);
		int nBits = DataInterface::EmbeddableBitsInPermutation(nIns);

		DataBits slice = SliceBits(bits, std::min(nBits, i % 500));
		PadBits(slice, nBits - slice.size());

		PackDataIntoBudgetClaim(copy, inputs);

		BOOST_REQUIRE(slice == UnpackDataFromBudgetClaim(inputs));
		BOOST_REQUIRE(bits == copy);
	}
}

BOOST_AUTO_TEST_CASE(PackIntoP2SH_Test)
{
	for(int i = 0; i < 1000; i++)
	{
		DataBits bits = Utilities::GenerateRandomBits(i % 500);
		DataBits copy = DataBits(bits);

		const int nKeys = std::min(11, (int)ceil((bits.size()-8)/250.0));
		const int MaxBits = 8 + nKeys * 250;

		CTransaction tx = CTransaction();
		CTxIn txIn = CTxIn();
		tx.vin.push_back(txIn);
		CTxOut txOut = CTxOut();

		DataBits slice = SliceBits(bits, std::min(MaxBits, (int)bits.size()));
		PadBits(slice, MaxBits - slice.size());

		PackDataIntoP2SH(copy, txOut, tx, 0);

		BOOST_REQUIRE(slice == UnpackDataFromP2SH(tx.vin[0]));
		BOOST_REQUIRE(bits == copy);
	}
}

//BOOST_AUTO_TEST_CASE(OptimalTxOutputCount_Test)
//{
//	for(int i = 0; i < 20; i++)
//	{
//		DataBits bits = Utilities::GenerateRandomBits(i*1000);
//
//		CTransaction tx = CTransaction();
//		tx.vin.push_back(CTxIn());
//		tx.vout.push_back(CTxOut());
//
//		BlockchainInterface::Parameters params;
//		BlockchainInterface::OptimizeParams(tx, bits, pow(10,7), params);
//	}
//}

BOOST_AUTO_TEST_CASE(EmbeddingInTransactions_Test)
{
	for(int i = 0; i < 40; i++)
	{
		DataBits originalData = Utilities::GenerateRandomBits(8*i*250);
		DataBits recoveredData;

		std::vector<COutPoint> prevOut;
		CBitcoinAddress addr;

		std::vector<CTransaction> txs = EmbedData(originalData, pow(10,7), prevOut, addr);
		recoveredData = BlockchainInterface::ExtractData(txs);

		int padding = recoveredData.size() - originalData.size();
		recoveredData.erase(recoveredData.end() - padding, recoveredData.end());

		BOOST_REQUIRE(originalData == recoveredData);
	}
}

BOOST_AUTO_TEST_CASE(ExtractingFromTransactionsI_Test)
{
	uint256 TxBegin = uint256("ca0bc0e7d422a71e016d757ecdba8ee801791b5ece529cb5fbcb3cc04bcb102e");
	uint256 TxEnd = uint256("b12d1d539f84a16a98baf1e7f77ed30559785e9e51228a59d0af0dbe127d38d2");
	std::vector<TransactionChain> chains;

	chains = ReadTransactions(TxBegin, TxEnd);
	DataBits bits = ExtractData(chains.front());

	int padding = 8 - (bits.size() % 8);
	PadBits(bits, padding);

	Data data = BitsToData(bits);
	std::string str = std::string(data.begin(), data.end());

	BOOST_REQUIRE(str.size() == 5761);
}

BOOST_AUTO_TEST_CASE(ExtractingFromTransactionsII_Test)
{
	uint256 TxBegin = uint256("ca0bc0e7d422a71e016d757ecdba8ee801791b5ece529cb5fbcb3cc04bcb102e");
	std::vector<TransactionChain> chains;

	chains = ReadTransactions(TxBegin);
	DataBits bits = ExtractData(chains.front());

	int padding = 8 - (bits.size() % 8);
	PadBits(bits, padding);

	Data data = BitsToData(bits);
	std::string str = std::string(data.begin(), data.end());

	BOOST_REQUIRE(str.size() == 5761);
}

BOOST_AUTO_TEST_CASE(DryRun)
{
	for(int i = 0; i < 50; i++)
	{
		Data originalData = BitsToData(Utilities::GenerateRandomBits(8*i*250));
		std::string str(originalData.begin(), originalData.end());

		HuffmanCoding::TransformCharDomain(str);
		originalData = Data(str.begin(), str.end());

		DataBits compressedData = HuffmanCoding::Compress(originalData, Utilities::HuffCode);
		Data recoveredData;

		InitInputs params = SelectInputs(Utilities::MinimumBudget(originalData.size()));
		CBitcoinAddress addr = SelectAddress();
		TransactionChain chain = EmbedData(compressedData, params.budget, params.utxo, addr);

		Utilities::Wallet.walletpassphrase("123456", 10);
		BOOST_REQUIRE_NO_THROW(AuthorizeTransactions(chain));

		compressedData = ExtractData(chain);
		recoveredData = HuffmanCoding::Decompress(compressedData, Utilities::HuffCode);

		BOOST_REQUIRE(originalData == recoveredData);
	}
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: minium/bitcoin-messaging

max_stars_repo_licenses: Unlicense MIT

max_issues_repo_name: minium/bitcoin-messaging

max_issues_repo_licenses: Unlicense MIT

max_forks_repo_name: minium/bitcoin-messaging

max_forks_repo_licenses: Unlicense MIT


text:
#include <iostream>
#include <fstream>
#include <Eigen/Eigen>
//include the bie header files
#include "material.hh"
#include "precomputed_kernel.hh"
#include "bimat_interface.hh"
#include "infinite_boundary.hh"
//include the fem header files
//#include "mesh_Abaqus_multi_faults_withAB.hpp"
#include "mesh_Abaqus_multi_faults.hpp"
#include "bcdof.hpp"
#include "bcdof_ptr.hpp"
#include "cal_ke.hpp"
#include "cal_fe_global_vary_ke.hpp"
#include "cal_ab_force.hpp"
#include "mapglobal.hpp"
#include "maplocal.hpp"
#include "cal_M.hpp"
#include "cal_T_abc.hpp"
#include "cal_Bmat.hpp"
#include "Slip_Weakening_lumpM_with_buffer.hpp"
#include "Rate_and_State_Aging.hpp"
#include "cal_slip_sliprate_angle.hpp"
#include "time_advance.hpp"
#include "BIE_correct.hpp"
#include "cal_fe_global_plastic_vary.cpp"
#include "update_disp_velocity.hpp"
#include <math.h>
using namespace Eigen;
using namespace std;

typedef Eigen::Matrix<int, -1, -1,RowMajor> MatrixXi_rm;

double time_fem=0;
double time_bie;
int main() {

    std::string filename = "wedge_50m.inp";

    std::cout<<filename<<std::endl;
   // double fault_angle  = 0/180.0*M_PI;
    int dim = 2.0;
    double x_max = 10.0e3;
    double x_min = -10.0e3;
    double dx = 50.0;
    double dy = 50.0;
    std::vector<int> BIE_top, BIE_bot;
    //std::vector<int> AB_left, AB_right;
    MatrixXd Node;
    MatrixXi_rm Element;
    // Total number of faults icluding the main fault
    // number of secondary faults + 1
    int num_faults = 1;
    std::vector<std::vector<int>> fault_nodes(2*num_faults);
    mesh_Abaqus_multi_faults(filename, Node, Element, BIE_top, BIE_bot,fault_nodes,num_faults);

    int nx_BIE = BIE_top.size();
    std::cout<<"nx_BIE="<<nx_BIE;
    int n_nodes = Node.rows();
    int n_el = Element.rows();
    int Ndofn = 2;
    int Nnel = Element.cols();
    Node = Node*1e3;
    // Material
    double density = 2670.0;
    double v_s =3.464e3;
    double v_p = 6.0e3;
    double G= pow(v_s,2)*density;
    double Lambda = pow(v_p,2)*density-2.0*G;
    double E  = G*(3.0*Lambda+2.0*G)/(Lambda+G);
    double nu = Lambda/(2.0*(Lambda+G));
    //std::cout<<nu<<std::endl;
    // Slip weakening friction parameters
    double Dc = 0.2;
    double mu_d= 0.3;
    //double mu_s = 0.677;
    // Intialization
    // disp velocity current and next time step (new)
    VectorXd u_n = VectorXd::Zero(n_nodes*Ndofn,1);
    VectorXd v_n = VectorXd::Zero(n_nodes*Ndofn,1);
    VectorXd u_new = VectorXd::Zero(n_nodes*Ndofn,1);
    VectorXd v_new = VectorXd::Zero(n_nodes*Ndofn,1);
    VectorXd a_n = VectorXd::Zero(n_nodes*Ndofn,1);
    // slip and slip-rate
    std::vector<Eigen::Array<double, -1, 1> > delt_u_n(num_faults);
    std::vector<Eigen::Array<double, -1, 1> > delt_v_n(num_faults);
    std::vector<Eigen::Array<double, -1, 1> > T_c(num_faults);
    std::vector<Eigen::Array<double, -1, 1> > T_0(num_faults);
    std::vector<Eigen::Array<double, -1, 1> > tau_s(num_faults);
    std::vector<Eigen::Array<double, -1, 1> > mu_s(num_faults);

    // Vector containing number of elements on each faults (nx)
    std::vector<int> nx_faults(num_faults);
    for (int i=0;i<num_faults;i++)
    {
        nx_faults[i] =fault_nodes[2*i].size();
    }

    for (int i=0;i<num_faults;i++)
    {
        delt_u_n[i] = ArrayXd::Zero(Ndofn*(nx_faults[i]),1);
        delt_v_n[i] = ArrayXd::Zero(Ndofn*(nx_faults[i]),1);
        T_c[i] = ArrayXd::Zero(Ndofn*(nx_faults[i]),1);
        T_0[i] = ArrayXd::Zero(Ndofn*(nx_faults[i]),1);
        tau_s[i] = ArrayXd::Zero(Ndofn*(nx_faults[i]),1);
        mu_s[i] = ArrayXd::Zero(nx_faults[i], 1);
    }
    // Making a copy of delt_u and delt_v to calculate the frictional disspation
    std::vector<Eigen::Array<double, -1, 1> > delt_u_n_copy(num_faults);
    std::vector<Eigen::Array<double, -1, 1> > delt_v_n_copy(num_faults);
    for (int i=0;i<num_faults;i++)
    {
        delt_u_n_copy[i] = ArrayXd::Zero(Ndofn*(nx_faults[i]),1);
        delt_v_n_copy[i] = ArrayXd::Zero(Ndofn*(nx_faults[i]),1);
    }

    VectorXd F_ext_global = VectorXd::Zero(n_nodes*Ndofn,1);
    // Write the x coordiantes for each fault
    std::vector<double> fault_angle(num_faults);
    double x1 = 0.0;
    double x2 = 0.0;
    double y1 = 0.0;
    double y2 = 0.0;
    for (int j=0;j<num_faults; j++)
    {
        VectorXd x = VectorXd::Zero(nx_faults[j], 1);
        VectorXd y = VectorXd::Zero(nx_faults[j], 1);

        for (int i=0; i<x.size(); i++)
        {
            x(i) = Node(fault_nodes[2*j][i],0);
            y(i) = Node(fault_nodes[2*j][i],1);
        }

        //std::ofstream x_output("results/fault_x_coord.txt");
        std::string  x_fault= "results/x_fault_"+std::to_string(j)+".txt";
        std::ofstream x_output(x_fault);
        x_output<<x;

        x1 = Node(fault_nodes[2*j][0],0);
        x2 = Node(fault_nodes[2*j][nx_faults[j]-1],0);
        y1 = Node(fault_nodes[2*j][0],1);
        y2 = Node(fault_nodes[2*j][nx_faults[j]-1],1);
        fault_angle[j]=std::atan2(y2-y1,x2-x1);
        //std::cout<<x1/1e3<<" "<<x2/1e3<<" "<<y1/1e3<<" "<<y2/1e3<<std::endl;
      }

    //Adding pertubation to the main fault 0
    VectorXd x_main = VectorXd::Zero(nx_faults[0], 1);

    for (int i=0; i<x_main.size(); i++)
    {
        x_main(i) = Node(fault_nodes[0][i],0);
    }

    // Get the index degree of freedome for each element
    VectorXi index_el = VectorXi::Zero(Ndofn*Nnel,1);
    MatrixXi index_store = MatrixXi::Zero(Nnel*Ndofn,n_el);
    for (int i=0;i<n_el;i++)
    {
        bcdof(Element.row(i),dim,index_el);
        index_store.col(i) = index_el;
    }
  //  VectorXi BIE_top_surf_index = VectorXi::Zero(Ndofn*(BIE_top_surf_nodes.size()),1);
   // VectorXi BIE_bot_surf_index = VectorXi::Zero(Ndofn*(BIE_bot_surf_nodes.size()),1);
    VectorXi BIE_top_surf_index = VectorXi::Zero(Ndofn*(BIE_top.size()),1);
    VectorXi BIE_bot_surf_index = VectorXi::Zero(Ndofn*(BIE_bot.size()),1);
    std::vector<Eigen::ArrayXi> Fault_surf_index(num_faults*2);
    for (int i=0; i <num_faults*2; i++)
    {
        Fault_surf_index[i] = ArrayXi::Zero(Ndofn*(fault_nodes[i].size()),1);
    }

//    VectorXi AB_left_surf_index = VectorXi::Zero(Ndofn*(AB_left.size()),1);
//    VectorXi AB_right_surf_index = VectorXi::Zero(Ndofn*(AB_right.size()),1);
//
//    bcdof_ptr(AB_left,dim,AB_left_surf_index.data());
//    bcdof_ptr(AB_right,dim,AB_right_surf_index.data());

    // Getting the faults DOF index
    for (int i=0; i<num_faults*2;i++)
    {
        bcdof_ptr(fault_nodes[i], dim, Fault_surf_index[i].data());
    }
    bcdof_ptr(BIE_top,dim,BIE_top_surf_index.data());
    bcdof_ptr(BIE_bot,dim,BIE_bot_surf_index.data());
    // Calculating the Global Mass Vector (lumped mass)
    // Element stiffness matrix,Element mass
    std::vector<MatrixXd> ke_store(n_el);
    MatrixXd M_el = MatrixXd::Zero(Nnel*Ndofn,Nnel*Ndofn);
    VectorXd M_el_vec = VectorXd::Zero(Nnel*Ndofn,1);
    VectorXd M_global_vec=VectorXd::Zero(n_nodes*Ndofn,1);
    std::vector<double> dx_min_store;
    std::vector<double> detJ(n_el);
  //  std::vector<Eigen::MatrixXd> B_mat(4);
    std::vector<Eigen::MatrixXd> B_mat_temp(4);

    std::vector<std::vector<Eigen::MatrixXd>> B_mat;
    //B_mat[0][0] = MatrixXd::Zero(3, 8);
    for (int i=0; i<n_el;i++)
    {
        MatrixXd coord = MatrixXd::Zero(4,2);
        VectorXi Element_0= Element.row(i);
        coord.row(0) = Node.row(Element_0(0));
        coord.row(1) = Node.row(Element_0(1));
        coord.row(2) = Node.row(Element_0(2));
        coord.row(3) = Node.row(Element_0(3));
        VectorXd dx_cal = VectorXd::Zero(4,1);
        dx_cal(0)=std::sqrt(pow(std::abs(coord(0,0)-coord(1,0)),2)+pow(std::abs(coord(0,1)-coord(1,1)),2));
        dx_cal(1)=std::sqrt(pow(std::abs(coord(1,0)-coord(2,0)),2)+pow(std::abs(coord(1,1)-coord(2,1)),2));
        dx_cal(2)=std::sqrt(pow(std::abs(coord(2,0)-coord(3,0)),2)+pow(std::abs(coord(2,1)-coord(3,1)),2));
        dx_cal(3)=std::sqrt(pow(std::abs(coord(3,0)-coord(0,0)),2)+pow(std::abs(coord(3,1)-coord(0,1)),2));
        double dx_min = dx_cal.minCoeff();
        dx_min_store.push_back(dx_min);
       // std::cout<<dx_cal<<std::endl;
        cal_Bmat(coord, E, nu, B_mat_temp, detJ[i]);
        B_mat.push_back(B_mat_temp);
        cal_ke (coord,E,nu,ke_store[i]);
        cal_M(coord, density,M_el);
        M_el_vec = M_el.rowwise().sum();
        index_el = index_store.col(i);
        mapglobal(index_el,M_global_vec,M_el_vec);

    }
    //
    double dx_min = *std::min_element(std::begin(dx_min_store), std::end(dx_min_store));
    // Time
    double alpha = 0.1;
    //dx_min = 100;
    double dt = alpha*dx_min/v_p;
    std::cout<<"dt="<<dt<<std::endl;
    //dt = 0.001;
    // dt = 5.0e-4;
    // Reyleigh Damping
    double beta =0.1;
    double q = beta*dt;
    double time_run = 6.0;
    int numt = time_run/dt;
    // numt= 1 ;
    //
    std::ofstream time_output("results/time.txt");
    time_output<<time_run<<"\n";
    time_output<<dt<<"\n";
    time_output<<numt<<std::endl;

    //numt = 1;
    VectorXd time = dt*VectorXd::LinSpaced(numt,1,numt);
    // BIE part initiation
    // Setting up the material property for the BIE code
    Material BIE_top_mat = Material(E,nu,density);
    Material BIE_bot_mat = Material(E,nu,density);
    double length = x_max- x_min;
    // infinte bc BIE call infinite_boundary.cc
    PrecomputedKernel h11("kernels/nu_.25_h11.dat");
    PrecomputedKernel h12("kernels/nu_.25_k12.dat");
    PrecomputedKernel h22("kernels/nu_.25_h22.dat");
    InfiniteBoundary BIE_inf_top(length,nx_BIE,1.0,&BIE_top_mat,&h11,&h12,&h22);
    InfiniteBoundary BIE_inf_bot(length,nx_BIE,-1.0,&BIE_bot_mat,&h11,&h12,&h22);
    // BIE setting time step
    BIE_inf_top.setTimeStep(dt);
    BIE_inf_bot.setTimeStep(dt);
    // BIE initialization
    BIE_inf_top.init();
    BIE_inf_bot.init();
    printf("ready to start\n");
    // Output
    ofstream file;
    file.open("results/num_nodes_fault.bin",ios::binary);
    file.write((char*)(nx_faults.data()),nx_faults.size()*sizeof(int));
    file.close();

    file.open("results/u_n.bin",ios::binary);
   // file.write((char*)(u_n.data()),u_n.size()*sizeof(double));
    file.close();
    file.open("results/v_n.bin",ios::binary);
    // file.write((char*)(u_n.data()),u_n.size()*sizeof(double));
    file.close();
    file.open("results/eq_ep_n.bin",ios::binary | ios::app);
    // file.write((char*)(u_n.data()),u_n.size()*sizeof(double));
    file.close();
    file.open("results/E_p.bin",ios::binary | ios::app);
    file.close();

    for (int i=0;i<num_faults;i++)
    {
        std::string slip = "results/slip_"+std::to_string(i)+".bin";
        file.open(slip);
        file.close();
        std::string slip_rate = "results/slip_rate_"+std::to_string(i)+".bin";
        file.open(slip_rate);
        file.close();
        std::string shear = "results/shear_"+std::to_string(i)+".bin";
        file.open(shear);
        file.close();
    }
    // output BIE boundary u_n v_n
    VectorXd BIE_top_u_n = VectorXd::Zero(Ndofn*(nx_faults[0]),1);
    VectorXd BIE_bot_u_n = VectorXd::Zero(Ndofn*(nx_faults[0]),1);
    VectorXd BIE_top_v_n = VectorXd::Zero(Ndofn*(nx_faults[0]),1);
    VectorXd BIE_bot_v_n = VectorXd::Zero(Ndofn*(nx_faults[0]),1);
    // Add output files BIE_top BIE_bot u_n v_n
    file.open("results/BIE_top_u_n.bin",ios::binary | ios::app);
    file.close();
    file.open("results/BIE_top_v_n.bin",ios::binary | ios::app);
    file.close();
    file.open("results/BIE_bot_u_n.bin",ios::binary | ios::app);
    file.close();
    file.open("results/BIE_bot_u_n.bin",ios::binary | ios::app);
    file.close();

    std::ofstream Element_output("results/Element.txt");
    std::ofstream Node_output("results/Node.txt");
    Node_output<<Node;
    Element_output<<Element;

    double a = 0.008;
    double b = 0.012;
    double V_0 = 1e-6;
    double f_0 = 0.6;
    double L = 0.02;
    double tau_ini = 75e6;
    double sigma_ini = 120e6;
    double V_ini  = 1e-12;
    VectorXd a_array = a*VectorXd::Zero(nx_faults[0],1);
    VectorXd b_array = b*VectorXd::Zero(nx_faults[0],1);
    VectorXd theta_ini = b*VectorXd::Zero(nx_faults[0],1);
    VectorXd theta_n = VectorXd::Zero(nx_faults[0],1);
    VectorXd theta_dot_n = VectorXd::Zero(nx_faults[0],1);

    double Vw_width = 5.0e3;
    for (int i =0; i<nx_faults[0]; i++){
        if (abs(x_main(i))<Vw_width/2.0)
        {
            a_array(i) = 0.008;
            b_array(i) = 0.012;
            theta_ini(i) = L/V_0*exp((a_array(i)*log(2*sinh(tau_ini/(a_array(i)*sigma_ini)))-f_0-a_array(i)*log(V_ini/V_0))/b_array(i));
        }
        else
        {
            b_array(i) = 0.012;
            a_array(i) = 0.008;
            theta_ini(i) = L/V_0*exp((a_array(i)*log(2*sinh(tau_ini/(a_array(i)*sigma_ini)))-f_0-a_array(i)*log(V_ini/V_0))/b_array(i));
        }
    }
    theta_n = theta_ini;
    double M = density*dx*dy*1.0;

    // Rate and state initlaized v_n delt_v_n
    for (int i=0;i<nx_faults[0];i++)
    {
        delt_v_n[0](2*i)= V_ini;

        v_n(Fault_surf_index[0](2*i))= V_ini/2.0;

        v_n(Fault_surf_index[1](2*i))= -V_ini/2.0;
    }

    // Setting intial stress on the fault
    for (int i=0; i<T_0[0].size()/2; i++)
    {
        T_0[0](2*i) = tau_ini;
        T_0[0](2*i+1) = -sigma_ini;
    }
    VectorXd x = VectorXd::LinSpaced(nx_faults[0],x_min,x_max);
    double d_tau_0 = 25e6;
    double R = 2.5e3;
    VectorXd F_r = VectorXd::Zero(nx_faults[0],1);
    for (int i=0; i<nx_faults[0]; i++)
    {
        if (fabs(x(i))<R)
        {
            F_r(i) = exp(pow(x(i),2)/( pow(x(i),2)-pow(R,2)));
        }
        else
        {
            F_r(i) = 0.0;
        }
    }
    VectorXd G_t = VectorXd::Zero(numt,1);
    double T_ramp = 1.0;
    for (int i=0; i<numt;i++)
    {
        if(time(i)<T_ramp)
        {
            G_t(i) = exp(pow((time(i)-T_ramp),2)/(time(i)*(time(i)-2*T_ramp)));
        }
        else
        {
            G_t(i) = 1.0;
        }
    }

    MatrixXd d_tau = MatrixXd::Zero(nx_faults[0],numt);
    for (int i=0;i<numt;i++)
    {
        d_tau.col(i)=75e6*VectorXd::Ones(nx_faults[0],1)+d_tau_0*F_r*(G_t(i));
        // d_tau.col(i)=75e6*VectorXd::Ones(nx_el+1,1)+3.75e6*F_r+dt*0.3125e7*i*VectorXd::Ones(nx_el+1,1);
    }

   // time_output<<time_run<<"\n";
   // time_output<<dt<<"\n";
    // Main time loop
    for (int j=0;j<numt;j++)
    {
        // Compute the global internal force
        VectorXd fe_global= VectorXd::Zero(n_nodes*Ndofn,1);
        cal_fe_global_vary_ke(n_nodes, n_el, index_store, q, u_n, v_n, Ndofn, ke_store, fe_global);
      //  cal_fe_global_plastic_vary(n_el, index_store, ke_store, B_mat, detJ, E, nu, q, u_n, v_n, Ndofn, fe_global, strain_n_store,stress_n_store, sxx_initial, syy_initial, sxy_initial, cohes, blkfric,eq_ep_out,E_p_out);
        // Friction subroutine
        VectorXd F_total = F_ext_global-fe_global;
        for (int i=0 ; i<num_faults; i++)
        {
            VectorXd F_fault = VectorXd::Zero(Ndofn*(nx_faults[i]),1);
            VectorXd M_pos = VectorXd::Zero(Ndofn*nx_faults[i], 1);
            VectorXd M_neg = VectorXd::Zero(Ndofn*nx_faults[i],1);

            maplocal(Fault_surf_index[2*i], M_global_vec, M_pos);
            maplocal(Fault_surf_index[2*i+1], M_global_vec, M_neg);

           // Slip_Weakening_lumpM_with_buffer(M_global_vec, Fault_surf_index[2*i], Fault_surf_index[2*i+1], fe_global, dt, dx, dy, nx_faults[i]-1, delt_v_n[i], delt_u_n[i], T_0[i], tau_s[i], mu_s[i], mu_d, Dc, Ndofn, M_pos, M_neg , F_fault, T_c[i], fault_angle[i]);

            for (int i=0;i<nx_faults[0];i++)
            {
                T_0[0](2*i) = d_tau(i,j);
            }

            Rate_and_State_Aging(M_global_vec, Fault_surf_index[0], Fault_surf_index[1], fe_global, dt, dx, dy, nx_faults[i]-1, delt_u_n[0], delt_v_n[0], T_0[i], tau_s[i], a_array, b_array , L, V_0, f_0, Ndofn, M, F_fault, T_c[i], theta_n, theta_dot_n);

            mapglobal(Fault_surf_index[2*i],F_total,-F_fault);
            mapglobal(Fault_surf_index[2*i+1],F_total,F_fault);
        }

        // Calculate Absorbing force
      //  cal_ab_force(T_abc, F_total, AB_left_surf_index, v_n, Ndofn);
      //  cal_ab_force(T_abc, F_total, AB_right_surf_index, v_n, Ndofn);
       // Central Difference Time integration
        time_advance(u_n, v_n, F_total, M_global_vec, dt);

        update_disp_velocity(u_n, v_n, Fault_surf_index[0], Fault_surf_index[1], Ndofn, nx_faults[0]-1, delt_u_n[0], delt_v_n[0]);

        delt_v_n[0](0)=0;
        delt_v_n[0](2*nx_faults[0]-2)=0;
        delt_u_n[0](0)=0;
        delt_u_n[0](2*nx_faults[0]-2)=0;
        // Correct the BIE surf nodes solutions from FEM with the BIE solution
        BIE_correct(BIE_top_surf_index, BIE_bot_surf_index, fe_global, Ndofn, nx_BIE-1, dx, BIE_inf_top, BIE_inf_bot, u_n, v_n);

        for (int i=0;i<1;i++)
        {
            std::string slip = "results/slip_"+std::to_string(i)+".bin";
            file.open(slip,ios::binary | ios::app);
            file.write((char*)(delt_u_n[i].data()),delt_u_n[i].size()*sizeof(double));
            file.close();

            std::string slip_rate = "results/slip_rate_"+std::to_string(i)+".bin";
            file.open(slip_rate,ios::binary | ios::app);
            file.write((char*)(delt_v_n[i].data()),delt_v_n[i].size()*sizeof(double));
            file.close();

            std::string shear = "results/shear_"+std::to_string(i)+".bin";
            file.open(shear,ios::binary | ios::app);
            file.write((char*)(T_c[i].data()),T_c[i].size()*sizeof(double));
            file.close();
        }
//
        if (j%100==1)
        {
            file.open("results/u_n.bin",ios::binary | ios::app);
            file.write((char*)(u_n.data()),u_n.size()*sizeof(double));
            file.close();
            file.open("results/v_n.bin",ios::binary | ios::app);
            file.write((char*)(v_n.data()),v_n.size()*sizeof(double));
            file.close();
        }

//  Adding virtual boundary information
        maplocal(BIE_top_surf_index,u_n,BIE_top_u_n);
        maplocal(BIE_top_surf_index,v_n,BIE_top_v_n);
        maplocal(BIE_bot_surf_index,u_n,BIE_bot_u_n);
        maplocal(BIE_bot_surf_index,v_n,BIE_bot_v_n);

        file.open("results/BIE_top_u_n.bin",ios::binary | ios::app);
        file.write((char*)(BIE_top_u_n.data()),BIE_top_u_n.size()*sizeof(double));
        file.close();
        file.open("results/BIE_top_v_n.bin",ios::binary | ios::app);
        file.write((char*)(BIE_top_v_n.data()),BIE_top_v_n.size()*sizeof(double));
        file.close();
        file.open("results/BIE_bot_u_n.bin",ios::binary | ios::app);
        file.write((char*)(BIE_bot_u_n.data()),BIE_bot_u_n.size()*sizeof(double));
        file.close();
        file.open("results/BIE_bot_v_n.bin",ios::binary | ios::app);
        file.write((char*)(BIE_bot_v_n.data()),BIE_bot_v_n.size()*sizeof(double));
        file.close();
//
        printf("Simulation time = %f\n",time(j));
    }
    return 0;
}


text:
//
// get_pointer_test.cpp
//
// Copyright 2014 Peter Dimov
//
// 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 <boost/get_pointer.hpp>
#include <boost/core/lightweight_test.hpp>
#include <memory>

struct X
{
};

int main()
{
    using boost::get_pointer;

    {
        X * p = new X;
        BOOST_TEST( get_pointer( p ) == p );

        delete p;
    }

    {
        std::auto_ptr< X > p( new X );
        BOOST_TEST( get_pointer( p ) == p.get() );
    }

#if !defined( BOOST_NO_CXX11_SMART_PTR )

    {
        std::unique_ptr< X > p( new X );
        BOOST_TEST( get_pointer( p ) == p.get() );
    }

    {
        std::shared_ptr< X > p( new X );
        BOOST_TEST( get_pointer( p ) == p.get() );
    }

#endif

    return boost::report_errors();
}

max_issues_repo_name: lipper/arangodb

max_forks_repo_name: lipper/arangodb


text:
// Copyright (c) 2012 Christopher Lux <christopherlux@gmail.com>
// Distributed under the Modified BSD License, see license.txt.

#include "volume_loader.h"

#include <vector>
#include <memory.h>
#include <sstream>

#include <FreeImagePlus.h>

#include <scm/core/math.h>
#include <scm/core/memory.h>

#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/numeric/conversion/bounds.hpp>

#include <scm/log.h>
#include <scm/core/log/logger_state.h>
#include <scm/core/math.h>
#include <scm/core/memory.h>
#include <scm/core/numeric_types.h>
#include <scm/core/time/high_res_timer.h>

#include <scm/gl_util/data/analysis/transfer_function/build_lookup_table.h>

#include <scm/gl_core/data_formats.h>
#include <scm/gl_core/math.h>
#include <scm/gl_core/render_device.h>
#include <scm/gl_core/state_objects.h>
#include <scm/gl_core/texture_objects.h>
#include <scm/gl_core/buffer_objects/scoped_buffer_map.h>

#include <scm/gl_util/data/imaging/texture_data_util.h>
#include <scm/gl_util/primitives/box.h>
#include <scm/gl_util/primitives/box_volume.h>
#include <scm/gl_util/viewer/camera.h>
#include <scm/gl_util/data/volume/volume_reader_raw.h>
#include <scm/gl_util/data/volume/volume_reader_segy.h>
#include <scm/gl_util/data/volume/volume_reader_vgeo.h>

#include <scm/gl_util/data/imaging/texture_image_data.h>

namespace scm {
namespace gl {

texture_3d_ptr
volume_loader::load_texture_3d(render_device&       in_device,
                                const std::string&   in_image_path,
                                bool                 in_create_mips,
                                bool                 in_color_mips,
                                const data_format    in_force_internal_format)
{

    using namespace scm;
    using namespace scm::gl;
    using namespace scm::math;
    using namespace boost::filesystem;

    scoped_ptr<gl::volume_reader> vol_reader;
    path                    file_path(in_image_path);
    std::string             file_name       = file_path.filename().string();
    std::string             file_extension  = file_path.extension().string();

    data_format volume_data_format     = FORMAT_NULL;

    boost::algorithm::to_lower(file_extension);

    if (file_extension == ".raw") {
        vol_reader.reset(new scm::gl::volume_reader_raw(file_path.string(), false));
    }
    else if (file_extension == ".vol") {
        vol_reader.reset(new scm::gl::volume_reader_vgeo(file_path.string(), true));
    }
    else {
        err() << log::error
              << "volume_loader::load_texture_3d(): unsupported volume file format ('" << file_extension << "')." << log::end;
        return (texture_3d_ptr());
    }

    if (!(*vol_reader)) {
        std::cout << "volume_loader::load_texture_3d(): unable to open file ('" << in_image_path << "')." << log::end;
        return (texture_3d_ptr());
    }

    int    max_volume_dim  = in_device.capabilities()._max_texture_3d_size;
    vec3ui data_offset = vec3ui(0);
    vec3ui data_dimensions = vol_reader->dimensions();
    volume_data_format     = vol_reader->format();

    if (max(max(data_dimensions.x, data_dimensions.y), data_dimensions.z) > static_cast<unsigned>(max_volume_dim)) {
        err() << log::error
              << "volume_loader::load_texture_3d(): volume too large to load as single texture ('" << data_dimensions << "')." << log::end;
        return (texture_3d_ptr());
    }

    scm::shared_array<unsigned char>    read_buffer;
    scm::size_t                         read_buffer_size =   data_dimensions.x * data_dimensions.y * data_dimensions.z
                                                           * size_of_format(volume_data_format);

    read_buffer.reset(new unsigned char[read_buffer_size]);

    if (!vol_reader->read(data_offset, data_dimensions, read_buffer.get())) {
        err() << log::error
              << "volume_loader::load_texture_3d(): unable to read data from file ('" << in_image_path << "')." << log::end;
        return (texture_3d_ptr());
    }

    if (volume_data_format == FORMAT_NULL) {
        err() << log::error
              << "volume_loader::load_texture_3d(): unable to determine volume data format ('" << in_image_path << "')." << log::end;
        return (texture_3d_ptr());
    }

    std::vector<void*> in_data;
    in_data.push_back(read_buffer.get());
    texture_3d_ptr new_volume_tex =
        in_device.create_texture_3d(data_dimensions, volume_data_format, 1, volume_data_format, in_data);

    return (new_volume_tex);
}

texture_3d_ptr
volume_loader::load_volume_data(render_device&      in_device,
								const std::string&  in_image_path)
{
    using namespace scm::gl;
    using namespace scm::math;
    using namespace boost::filesystem;

    path                    file_path(in_image_path);
    std::string             file_name       = file_path.filename().string();
    std::string             file_extension  = file_path.extension().string();

    boost::algorithm::to_lower(file_extension);

    vec3ui      data_dimensions = vec3ui(0u);
    data_format data_format     = FORMAT_NULL;
    scm::shared_array<unsigned char> read_buffer;
    scm::size_t                      read_buffer_size = 0;

    scoped_ptr<gl::volume_reader> vol_reader;

    out() << log::indent;
    time::high_res_timer timer;

    if (file_extension == ".raw") {
        vol_reader.reset(new volume_reader_raw(file_path.string(), false));
    }
    else if (file_extension == ".vol") {
        vol_reader.reset(new volume_reader_vgeo(file_path.string(), true));
    }
    else if (file_extension == ".segy" || file_extension == ".sgy") {
        vol_reader.reset(new volume_reader_segy(file_path.string(), true));
    }
    else {
        err() << log::error
              << "volume_data::load_volume(): unable to open file ('" << in_image_path << "')." << log::end;
        return texture_3d_ptr();
    }

    if (!(*vol_reader)) {
        err() << log::error
                << "volume_data::load_volume(): unable to open file ('" << in_image_path << "')." << log::end;
        return texture_3d_ptr();
    }
    out() << "source data dimensions: " << vol_reader->dimensions() << log::end;

    vec3ui data_offset = vec3ui(0);
    data_dimensions    = vol_reader->dimensions();
    data_format        = vol_reader->format();

    read_buffer_size =   static_cast<scm::size_t>(data_dimensions.x) * data_dimensions.y * data_dimensions.z
                        * size_of_format(data_format);

    read_buffer.reset(new unsigned char[read_buffer_size]);

    out() << "reading volume data "
          << "(dimensions: " << data_dimensions
          << ", size : " << std::fixed << std::setprecision(3) << static_cast<double>(read_buffer_size) / (1024.0*1024.0) << "MiB)..."
          << log::end;
    timer.start();
    if (!vol_reader->read(data_offset, data_dimensions, read_buffer.get())) {
        err() << log::error
                << "volume_data::load_volume(): unable to read data from file ('" << in_image_path << "')." << log::end;
        return texture_3d_ptr();
    }
    timer.stop();
    out() << "reading volume data done"
          << " (elapsed time: " << std::fixed << std::setprecision(3)
          << time::to_seconds(timer.get_time()) << "s, "
          << (static_cast<double>(read_buffer_size) / (1024.0*1024.0)) / time::to_seconds(timer.get_time()) << "MiB/s)" << log::end;

    //_min_value = 0.0f;
    //_max_value = 1.0f;
    //if (is_float_type(data_format)) {
    //    out() << "determining floating point value range..." << log::end;
    //    timer.start();

    //    float* fp_data = reinterpret_cast<float*>(read_buffer.get());
    //    size_t dcount  = static_cast<scm::size_t>(data_dimensions.x) * data_dimensions.y * data_dimensions.z * channel_count(data_format);
    //    _min_value = boost::numeric::bounds<float>::highest();//(std::numeric_limits<float>::max)();
    //    _max_value = boost::numeric::bounds<float>::lowest();//(std::numeric_limits<float>::min)();

    //    for (size_t i = 0; i < dcount; ++i) {
    //        _min_value = min(_min_value, fp_data[i]);
    //        _max_value = max(_max_value, fp_data[i]);
    //    }

    //    if (abs(_min_value) > abs(_max_value)) {
    //        _max_value = abs(_min_value);
    //    }
    //    else {
    //        _min_value = -abs(_max_value);
    //    }

    //    timer.stop();
    //    out() << "etermining floating point value range"
    //          << " (elapsed time: " << std::fixed << std::setprecision(3)
    //          << time::to_seconds(timer.get_time()) << "s)" << log::end;

    //}
    //out() << "min_value: " << _min_value << ", max_value: " << _max_value << log::end;

    std::vector<uint8*> mip_data;
    std::vector<void*>  mip_init_data;

    out() << "generating mip map hierarchy..." << log::end;
    timer.start();
    gl::util::generate_mipmaps(data_dimensions, data_format, read_buffer.get(), mip_data);
    timer.stop();
    out() << "generating mip map hierarchy done"
          << " (elapsed time: " << std::fixed << std::setprecision(3)
          << time::to_seconds(timer.get_time()) << "s)" << log::end;

    std::for_each(mip_data.begin(), mip_data.end(), [&mip_init_data](uint8* v) {mip_init_data.push_back(v);});
    //for (std::vector<uint8*>::iterator v = mip_data.begin(); v != mip_data.end(); ++v) {
    //    mip_init_data.push_back(*v);
    //}

    unsigned mip_count = gl::util::max_mip_levels(data_dimensions);

    assert(mip_count == mip_init_data.size());

    out() << "allocating texture storage ("
          << "dimensions: " << data_dimensions << ", format: " << format_string(data_format)
          << ", mip-level: " << mip_count
          << ", size : " << std::fixed << std::setprecision(3) << static_cast<double>(read_buffer_size) / (1024.0*1024.0) << "MiB)..."
          << log::end;
    timer.start();
    texture_3d_ptr new_volume_tex = in_device.create_texture_3d(data_dimensions, data_format, mip_count, data_format, mip_init_data);
    timer.stop();
    out() << "allocating texture storage done."
          << " (elapsed time: " << std::fixed << std::setprecision(3)
          << time::to_seconds(timer.get_time()) << "s)" << log::end;

    std::for_each(mip_data.begin() + 1, mip_data.end(), [&mip_init_data](uint8* v) {delete [] v; });

    out() << log::outdent;

    return new_volume_tex;
}

scm::math::vec3ui
volume_loader::read_dimensions(const std::string&  in_image_path)
{
	using namespace scm::gl;
	using namespace scm::math;
	using namespace boost::filesystem;

	path                    file_path(in_image_path);
	std::string             file_name = file_path.filename().string();
	std::string             file_extension = file_path.extension().string();

	boost::algorithm::to_lower(file_extension);

	vec3ui      data_dimensions = vec3ui(0u);
	data_format data_format = FORMAT_NULL;
	scm::shared_array<unsigned char> read_buffer;
	scm::size_t                      read_buffer_size = 0;

	scoped_ptr<gl::volume_reader> vol_reader;

	out() << log::indent;
	time::high_res_timer timer;

	if (file_extension == ".raw") {
		vol_reader.reset(new volume_reader_raw(file_path.string(), false));
	}
	else if (file_extension == ".vol") {
		vol_reader.reset(new volume_reader_vgeo(file_path.string(), true));
	}
	else if (file_extension == ".segy" || file_extension == ".sgy") {
		vol_reader.reset(new volume_reader_segy(file_path.string(), true));
	}
	else {
		err() << log::error
			<< "volume_data::load_volume(): unable to open file ('" << in_image_path << "')." << log::end;
		return scm::math::vec3ui::zero();
	}

	if (!(*vol_reader)) {
		err() << log::error
			<< "volume_data::load_volume(): unable to open file ('" << in_image_path << "')." << log::end;
		return scm::math::vec3ui::zero();
	}
	//out() << "source data dimensions: " << vol_reader->dimensions() << log::end;

	data_dimensions = vol_reader->dimensions();
	data_format = vol_reader->format();

	return data_dimensions;
}

} // namespace gl
} // namespace scm

max_stars_repo_name: Nyran/schism

max_issues_repo_name: Nyran/schism

max_forks_repo_name: Nyran/schism


text:
// Copyright (C) 2005-2006 Douglas Gregor <doug.gregor@gmail.com>.
// Copyright (C) 2004 The Trustees of Indiana University

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

//   Authors: Douglas Gregor
//            Andrew Lumsdaine

// Message Passing Interface 1.1 -- Section 4.9.1. Scan
#ifndef BOOST_MPI_SCAN_HPP
#define BOOST_MPI_SCAN_HPP

#include <boost/mpi/exception.hpp>
#include <boost/mpi/datatype.hpp>

// For (de-)serializing sends and receives
#include <boost/mpi/packed_oarchive.hpp>
#include <boost/mpi/packed_iarchive.hpp>

// For packed_[io]archive sends and receives
#include <boost/mpi/detail/point_to_point.hpp>

#include <boost/mpi/communicator.hpp>
#include <boost/mpi/environment.hpp>
#include <boost/mpi/detail/computation_tree.hpp>
#include <boost/mpi/operations.hpp>
#include <algorithm>
#include <exception>
#include <boost/assert.hpp>

namespace boost { namespace mpi {

/************************************************************************
 * Implementation details                                               *
 ************************************************************************/
namespace detail {
  /**********************************************************************
   * Simple prefix reduction with MPI_Scan                              *
   **********************************************************************/

  // We are performing prefix reduction for a type that has an
  // associated MPI datatype and operation, so we'll use MPI_Scan
  // directly.
  template<typename T, typename Op>
  void
  scan_impl(const communicator& comm, const T* in_values, int n, T* out_values,
            Op op, mpl::true_ /*is_mpi_op*/, mpl::true_ /*is_mpi_datatype*/)
  {
    BOOST_MPI_CHECK_RESULT(MPI_Scan,
                           (const_cast<T*>(in_values), out_values, n,
                            boost::mpi::get_mpi_datatype<T>(*in_values),
                            (is_mpi_op<Op, T>::op()), comm));
  }

  /**********************************************************************
   * User-defined prefix reduction with MPI_Scan                        *
   **********************************************************************/

  // We are performing prefix reduction for a type that has an
  // associated MPI datatype but with a custom operation. We'll use
  // MPI_Scan directly, but we'll need to create an MPI_Op manually.
  template<typename T, typename Op>
  void
  scan_impl(const communicator& comm, const T* in_values, int n, T* out_values,
            Op op, mpl::false_ /*is_mpi_op*/, mpl::true_ /*is_mpi_datatype*/)
  {
    user_op<Op, T> mpi_op(op);
    BOOST_MPI_CHECK_RESULT(MPI_Scan,
                           (const_cast<T*>(in_values), out_values, n,
                            boost::mpi::get_mpi_datatype<T>(*in_values),
                            mpi_op.get_mpi_op(), comm));
  }

  /**********************************************************************
   * User-defined, tree-based reduction for non-MPI data types          *
   **********************************************************************/

  template<typename T, typename Op>
  void
  upper_lower_scan(const communicator& comm, const T* in_values, int n,
                   T* out_values, Op& op, int lower, int upper)
  {
    int tag = environment::collectives_tag();
    int rank = comm.rank();

    if (lower + 1 == upper) {
      std::copy(in_values, in_values + n, out_values);
    } else {
      int middle = (lower + upper) / 2;

      if (rank < middle) {
        // Lower half
        upper_lower_scan(comm, in_values, n, out_values, op, lower, middle);

        // If we're the last process in the lower half, send our values
        // to everyone in the upper half.
        if (rank == middle - 1) {
          packed_oarchive oa(comm);
          for (int i = 0; i < n; ++i)
            oa << out_values[i];

          for (int p = middle; p < upper; ++p)
            comm.send(p, tag, oa);
        }
      } else {
        // Upper half
        upper_lower_scan(comm, in_values, n, out_values, op, middle, upper);

        // Receive value from the last process in the lower half.
        packed_iarchive ia(comm);
        comm.recv(middle - 1, tag, ia);

        // Combine value that came from the left with our value
        T left_value;
        for (int i = 0; i < n; ++i)
          {
            ia >> left_value;
            out_values[i] = op(left_value, out_values[i]);
          }
      }
    }
  }

  // We are performing prefix reduction for a type that has no
  // associated MPI datatype and operation, so we'll use a simple
  // upper/lower algorithm.
  template<typename T, typename Op>
  inline void
  scan_impl(const communicator& comm, const T* in_values, int n, T* out_values,
            Op op, mpl::false_ /*is_mpi_op*/, mpl::false_/*is_mpi_datatype*/)
  {
    upper_lower_scan(comm, in_values, n, out_values, op, 0, comm.size());
  }
} // end namespace detail

template<typename T, typename Op>
inline void
scan(const communicator& comm, const T& in_value, T& out_value, Op op)
{
  detail::scan_impl(comm, &in_value, 1, &out_value, op,
                    is_mpi_op<Op, T>(), is_mpi_datatype<T>());
}

template<typename T, typename Op>
inline void
scan(const communicator& comm, const T* in_values, int n, T* out_values, Op op)
{
  detail::scan_impl(comm, in_values, n, out_values, op,
                    is_mpi_op<Op, T>(), is_mpi_datatype<T>());
}

template<typename T, typename Op>
inline T
scan(const communicator& comm, const T& in_value, Op op)
{
  T out_value;
  detail::scan_impl(comm, &in_value, 1, &out_value, op,
                    is_mpi_op<Op, T>(), is_mpi_datatype<T>());
  return out_value;
}

} } // end namespace boost::mpi

#endif // BOOST_MPI_SCAN_HPP


text:
#ifndef BOOST_EXTENDED_TYPE_INFO_HPP
#define BOOST_EXTENDED_TYPE_INFO_HPP

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

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// extended_type_info.hpp: interface for portable version of type_info

// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

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

#include <boost/config.hpp>
#include <boost/noncopyable.hpp>

#define BOOST_SERIALIZATION_MAX_KEY_SIZE 128

namespace boost {
namespace serialization {

class extended_type_info : public boost::noncopyable
{
private:
    friend bool
    operator<(const extended_type_info &lhs, const extended_type_info &rhs);
    friend bool
    operator==(const extended_type_info &lhs, const extended_type_info &rhs);
    friend bool
    operator!=(const extended_type_info &lhs, const extended_type_info &rhs);
    virtual bool
    less_than(const extended_type_info &rhs) const = 0;
    virtual bool
    equal_to(const extended_type_info &rhs) const = 0;
    virtual bool
    not_equal_to(const extended_type_info &rhs) const = 0;
protected:
    void self_register();
    extended_type_info(const char * type_info_key_) :
        type_info_key(type_info_key_),
        key(NULL)
    {}
    virtual ~extended_type_info(){};
    int type_info_key_cmp(const extended_type_info & rhs) const;
public:
    // used to uniquely identify the type of class derived from this one
    // so that different derivations of this class can be simultaneously
    // included in implementation of sets and maps.
    const char * type_info_key;
    // text string used as key for exporting serialized classes
    const char * key;
    static const extended_type_info * find(const char *key);
    static const extended_type_info * find(const extended_type_info * t);
    void key_register(const char *key);
};

bool
operator<(const extended_type_info &lhs, const extended_type_info &rhs);
bool
operator==(const extended_type_info &lhs, const extended_type_info &rhs);
bool
operator!=(const extended_type_info &lhs, const extended_type_info &rhs);

} // namespace serialization
} // namespace boost

#endif // BOOST_EXTENDED_TYPE_INFO_HPP

max_stars_repo_name: macaurther/DOCUSA

max_issues_repo_name: macaurther/DOCUSA

max_forks_repo_name: dguenms/Dawn-of-Civilization