text:
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2014 MaidSafe.net Limited
//
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)
//
///////////////////////////////////////////////////////////////////////////////

#ifndef MAIDSAFE_CRUX_DETAIL_CUMULATIVE_SET_HPP
#define MAIDSAFE_CRUX_DETAIL_CUMULATIVE_SET_HPP

#include <set>
#include <utility>
#include <type_traits>
#include <boost/optional.hpp>

namespace maidsafe
{
namespace crux
{
namespace detail
{

template <typename SequenceType,
          typename FieldType>
class cumulative_set
{
    static_assert(std::is_integral<FieldType>::value && std::is_unsigned<FieldType>::value,
                  "Field type must be an unsigned integral");

    using container_type = std::set<SequenceType>;

public:
    using value_type = typename container_type::value_type;
    using field_type = FieldType;
    using composite_type = value_type;

    bool empty() const;

    boost::optional<composite_type> front();

    void insert(const value_type&);

private:
    void prune();

private:
    container_type container;
};

} // namespace detail
} // namespace crux
} // namespace maidsafe

#include <algorithm>

namespace maidsafe
{
namespace crux
{
namespace detail
{

template <typename SequenceType, typename FieldType>
bool cumulative_set<SequenceType, FieldType>::empty() const
{
    return container.empty();
}

template <typename SequenceType, typename FieldType>
boost::optional<typename cumulative_set<SequenceType, FieldType>::composite_type>
cumulative_set<SequenceType, FieldType>::front()
{
    if (container.empty())
        return boost::none;

    auto cumulative = container.begin();
    return *cumulative;
}

template <typename SequenceType, typename FieldType>
void cumulative_set<SequenceType, FieldType>::insert(const value_type& item)
{
    container.insert(item);
    prune();
    assert(!container.empty());
}

template <typename SequenceType, typename FieldType>
void cumulative_set<SequenceType, FieldType>::prune()
{
    // Skip contiguous sequence numbers to find most recent cumulative entry.

    // This algorithm works almost like std::adjacent_find but we always want
    // the last tie instead of the first.
    auto current = container.begin();
    if (current != container.end()) {
        auto next = current;
        ++next;
        for (; next != container.end(); ++next, ++current)
        {
            if (next == container.end())
                break;
            if (current->distance(*next) > 1)
                return;
        }
        // Prune all entries before the cumulative value
        container.erase(container.begin(), current);
    }
}

} // namespace detail
} // namespace crux
} // namespace maidsafe

#endif // MAIDSAFE_CRUX_DETAIL_CUMULATIVE_SET_HPP

ext: hpp

max_stars_repo_name: maidsafe-archive/MaidSafe-CRUX

max_issues_repo_name: inetic/MaidSafe-CRUX

max_forks_repo_name: inetic/MaidSafe-CRUX


text:
// Boost.Range library
//
//  Copyright Thorsten Ottosen 2003-2004. 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)
//
// For more information, see http://www.boost.org/libs/range/
//

#ifndef BOOST_RANGE_DETAIL_VALUE_TYPE_HPP
#define BOOST_RANGE_DETAIL_VALUE_TYPE_HPP

#include <boost/range/detail/common.hpp>
#include <boost/range/detail/remove_extent.hpp>
#include <boost/iterator/iterator_traits.hpp>

//////////////////////////////////////////////////////////////////////////////
// missing partial specialization  workaround.
//////////////////////////////////////////////////////////////////////////////

namespace mars_boost {}
namespace boost = mars_boost;
namespace mars_boost {
namespace range_detail {
template<typename T>
struct range_value_type_;

template<>
struct range_value_type_<std_container_> {
  template<typename C>
  struct pts {
    typedef BOOST_RANGE_DEDUCED_TYPENAME C::value_type type;
  };
};

template<>
struct range_value_type_<std_pair_> {
  template<typename P>
  struct pts {
    typedef BOOST_RANGE_DEDUCED_TYPENAME mars_boost::iterator_value<BOOST_RANGE_DEDUCED_TYPENAME P::first_type>::type type;
  };
};

template<>
struct range_value_type_<array_> {
  template<typename T>
  struct pts {
    typedef BOOST_DEDUCED_TYPENAME remove_extent<T>::type type;
  };
};

}

template<typename C>
class range_value {
  typedef BOOST_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
public:
  typedef BOOST_DEDUCED_TYPENAME range_detail::range_value_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type;
};

}

#endif

max_stars_repo_name: habbyge/mars

max_issues_repo_name: habbyge/mars

max_forks_repo_name: habbyge/mars


text:
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "assert.h"

#include "chainparams.h"
#include "main.h"
#include "util.h"

#include <boost/assign/list_of.hpp>

using namespace boost::assign;

struct SeedSpec6 {
    uint8_t addr[16];
    uint16_t port;
};

#include "chainparamsseeds.h"

#ifndef GENESIS_MINE
#define GENESIS_MINE false
#endif
//
// Main network
//

// Convert the pnSeeds6 array into usable address objects.
static void convertSeed6(std::vector<CAddress> &vSeedsOut, const SeedSpec6 *data, unsigned int count)
{
    // It'll only connect to one or two seed nodes because once it connects,
    // it'll get a pile of addresses with newer timestamps.
    // Seed nodes are given a random 'last seen time' of between one and two
    // weeks ago.
    const int64_t nOneWeek = 7*24*60*60;
    for (unsigned int i = 0; i < count; i++)
    {
        struct in6_addr ip;
        memcpy(&ip, data[i].addr, sizeof(ip));
        CAddress addr(CService(ip, data[i].port));
        addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
        vSeedsOut.push_back(addr);
    }
}

class CMainParams : public CChainParams {
public:
    void Mine(CBlock *pBlock) {

      CBlock block=*pBlock;
      cout<<block.ToString();

      // start with this nonce
      block.nNonce   =  0;

      //cout<<block.ToString();
      printf("Figure out valid hash and nonce for block\n");
      printf("block.GetHash() == %s\n", block.GetHash().ToString().c_str());
      printf("block.hashMerkleRoot == %s\n", block.hashMerkleRoot.ToString().c_str());
      printf("block.nTime = %u \n", block.nTime);
      printf("block.nNonce = %u \n", block.nNonce);

      // This will figure out a valid hash and Nonce if you're
      // creating a different genesis block:
      uint256 hashTarget = CBigNum().SetCompact(block.nBits).getuint256();
      printf("* Mining block...\n");
      printf("    Target %s\n", hashTarget.ToString().c_str());

      uint64_t nStart = GetTimeMillis();

      while (block.GetHash() > hashTarget)
         {
             if ((block.nNonce & 0xFFF) == 0)
             {
                 printf("nonce= %08X hash= %s\n",
                      block.nNonce, block.GetHash().ToString().c_str());
             }

             ++block.nNonce;
             if (block.nNonce == 0)
             {
                 printf("NONCE WRAPPED, incrementing time");
                 ++block.nTime;
             }
         }

     cout<<"Mining target met!!!\n";
     cout<<block.ToString();

      if (CheckProofOfWork(block.GetHash(), block.nBits)) {
         printf("* Solved block nonce %u hash 0x%s time %u\n",
           block.nNonce, block.GetHash().ToString().c_str(), block.nTime);
         printf("* Mining took %llu minutes\n", (unsigned long long) (GetTimeMillis() - nStart)/60000);
      }
      //cout<<block.ToString();
    }

    CMainParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.

        pchMessageStart[0] = 0xcf;
        pchMessageStart[1] = 0xd1;
        pchMessageStart[2] = 0xe8;
        pchMessageStart[3] = 0xea;
        vAlertPubKey = ParseHex("04894885B16E72DA9E2A56FC5B6BE4B1EBB9F3FE96B58A43EF8013EAEC246C2E3D01AC4317EFBCFFC0E8FE36E4D525DD7C7F6664AED00288D234686AF3D9F37180"); //1VALabNVujcHnWis49uQWFnWhQe4btyCX

        nDefaultPort = 8338;
        nRPCPort = 8339;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20);
        nLastPOWBlock = BLOCKS_PER_DAY * DAYS_PER_YEAR * 128;

        static const char* hash160SeedAddress = "0553721f7507c9d43b618656b52918aa503b7f67"; // 1VALsigUQFqRAh8jBd1Q4K4n2kWq6PtSM

        static const uint256 _hashGenesisBlockMerkleRoot("0x0538153e4c67a03c7ba7e588354bbdc0f8031a60d87556ae1979f8e6b5a0938f");
        static const uint256 _hashGenesisBlock("0x00000b5e18c0bcce94a9f88751b9fafd18b4dc11f351539cc1da6fbba04cb0df");

        // Build the genesis block. Note that the output of the genesis coinbase cannot
        // be spent as it did not originally exist in the database.
        //
        const char* pszTimestamp = "Valorbit http://www.wired.com/2015/11/connecting-worlds-poorest-the-best-hope-for-ending-poverty/";
        std::vector<CTxIn> vin;
        vin.resize(1);
        vin[0].scriptSig = CScript() << 0 << CBigNum(42) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
        std::vector<CTxOut> vout;
        vout.resize(1);
        vout[0].SetEmpty();

        CTransaction txNew(1, 0, vin, vout, 0);
        txNew.nTime = 1446501600;

        genesis.vtx.push_back(txNew);
        genesis.hashPrevBlock = 0;
        genesis.hashMerkleRoot = genesis.BuildMerkleTree();
        genesis.nVersion = 1;
        genesis.nTime    = txNew.nTime;
        genesis.nBits    = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce   = 2469539;

        if (genesis.hashMerkleRoot != _hashGenesisBlockMerkleRoot)
        {
           cout<<"GENESIS block:\n"<<genesis.ToString();
        }

        assert(genesis.hashMerkleRoot == _hashGenesisBlockMerkleRoot);

        hashGenesisBlock = genesis.GetHash();
        if (GENESIS_MINE  && (hashGenesisBlock != _hashGenesisBlock )) {
                cout<<"Mining GENESIS block ...............\n";
                Mine(&genesis);
            }

        assert(hashGenesisBlock == _hashGenesisBlock);

        CTransaction txSeed;
        const char* pszTimestampSeed = "2015-11-02@valorbit.com";
        txSeed.nTime = genesis.nTime + 1;
        static const uint256 _hashSeedBlockMerkleRoot("0x1016a3b0898340769914d906d4edde0bf5c5a7da177bc83254bb5478ec78938a");
        static const uint256 _hashSeedBlock("0x000007e37b0e556cf82169d6485df7fe3c1a07214a4108a9e3da575a83a2668e");
        seed.nNonce   = 247609;
        txSeed.vin.resize(1);
        txSeed.vout.resize(1);
        txSeed.vin[0].scriptSig = CScript() << 486604799 << CBigNum(9999) << vector<unsigned char>((const unsigned char*)pszTimestampSeed, (const unsigned char*)pszTimestampSeed + strlen(pszTimestampSeed));
        txSeed.vout[0].SetEmpty();
        txSeed.vout[0].nValue= SEED_MONEY;
        txSeed.vout[0].scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ParseHex(hash160SeedAddress) << OP_EQUALVERIFY << OP_CHECKSIG;

        seed.vtx.push_back(txSeed);
        seed.hashPrevBlock = genesis.GetHash();
        seed.hashMerkleRoot = seed.BuildMerkleTree();
        seed.nVersion = 1;
        seed.nTime    = txSeed.nTime;
        seed.nBits    = bnProofOfWorkLimit.GetCompact();

        if (seed.hashMerkleRoot != _hashSeedBlockMerkleRoot)
        {
           cout<<"SEED block:\n"<<seed.ToString();
        }

        assert(seed.hashMerkleRoot == _hashSeedBlockMerkleRoot);

        hashSeedBlock = seed.GetHash();
        if (GENESIS_MINE  && (hashSeedBlock != _hashSeedBlock )) {
           cout<<"Mining SEED block ...............\n";
           Mine(&seed);
        }

        assert(hashSeedBlock == _hashSeedBlock);

        vSeeds.push_back(CDNSSeedData("seed.valorbit.com", "seed.valorbit.com"));
        vSeeds.push_back(CDNSSeedData("seed2.valorbit.com", "seed2.valorbit.com"));
        vSeeds.push_back(CDNSSeedData("seed3.valorbit.com", "seed3.valorbit.com"));

        base58Prefixes[PUBKEY_ADDRESS] = list_of(0);
        base58Prefixes[SCRIPT_ADDRESS] = list_of(5);
        base58Prefixes[SECRET_KEY] =     list_of(128);
        base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x88)(0xB2)(0x1E);
        base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x88)(0xAD)(0xE4);

        convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));

    }

    virtual const CBlock& GenesisBlock() const { return genesis; }
    virtual const CBlock& SeedBlock() const { return seed; }
    virtual Network NetworkID() const { return CChainParams::MAIN; }

    virtual const vector<CAddress>& FixedSeeds() const {
        return vFixedSeeds;
    }
protected:
    CBlock genesis;
    CBlock seed;
    vector<CAddress> vFixedSeeds;
};
static CMainParams mainParams;

//
// Testnet
//

class CTestNetParams : public CMainParams {
public:
    CTestNetParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0xe2;
        pchMessageStart[1] = 0xbf;
        pchMessageStart[2] = 0xd8;
        pchMessageStart[3] = 0xc7;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 16);
        vAlertPubKey = ParseHex("04f84f9a4d41d3009d0ad1f9b30e234e8da2663631daa3ead20b6d761bd2e202725358400421d028e664990cafb53df80e890d3a40a23aed828ee1675bc2c1a644");
        nDefaultPort = 18338;
        nRPCPort = 18339;
        strDataDir = "testnet";
        nLastPOWBlock = 0x7fffffff;

        static const uint256 _hashGenesisBlock("0x00008d18e582741232b7dd943061dec5c8a53b7a5a62497a56d3bf65702c0a18");

        // Modify the testnet genesis block so the timestamp is valid for a later start.
        genesis.nBits  = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce = 54984;
        hashGenesisBlock = genesis.GetHash();
        //cout<<genesis.ToString();
        if (GENESIS_MINE  && (hashGenesisBlock != _hashGenesisBlock )) {
                printf("Mining GENESIS block on testnet ...............\n");
                Mine(&genesis);
        }

        assert(hashGenesisBlock == _hashGenesisBlock);

        vFixedSeeds.clear();
        vSeeds.clear();

        base58Prefixes[PUBKEY_ADDRESS] = list_of(111);
        base58Prefixes[SCRIPT_ADDRESS] = list_of(196);
        base58Prefixes[SECRET_KEY]     = list_of(239);
        base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x35)(0x87)(0xCF);
        base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x35)(0x83)(0x94);

        convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));

        nLastPOWBlock = 0x7fffffff;
    }
    virtual Network NetworkID() const { return CChainParams::TESTNET; }
};
static CTestNetParams testNetParams;

//
// Regression test
//
class CRegTestParams : public CTestNetParams {
public:
    CRegTestParams() {
        pchMessageStart[0] = 0xe2;
        pchMessageStart[1] = 0xbf;
        pchMessageStart[2] = 0xd9;
        pchMessageStart[3] = 0xc8;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 1);
        //genesis.nTime = 1411111111;
        genesis.nBits  = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce = 3;
        nDefaultPort = 28338;
        strDataDir = "regtest";
        static const uint256 _hashGenesisBlock("0x0b687e82b23d3f22665adfc7895ac125218f504177f5735bebfd735a3c1a5df5");

        hashGenesisBlock = genesis.GetHash();
        //cout<<genesis.ToString();
        if (GENESIS_MINE && (hashGenesisBlock != _hashGenesisBlock )) {
                printf("Mining GENESIS block on regtest ...............\n");
                Mine(&genesis);
        }

        assert(hashGenesisBlock == _hashGenesisBlock);

        vSeeds.clear();  // Regtest mode doesn't have any DNS seeds.
    }

    virtual bool RequireRPCPassword() const { return false; }
    virtual Network NetworkID() const { return CChainParams::REGTEST; }
};
static CRegTestParams regTestParams;

static CChainParams *pCurrentParams = &mainParams;

const CChainParams &Params() {
    return *pCurrentParams;
}

void SelectParams(CChainParams::Network network) {
    switch (network) {
        case CChainParams::MAIN:
            pCurrentParams = &mainParams;
            break;
        case CChainParams::TESTNET:
            pCurrentParams = &testNetParams;
            break;
        case CChainParams::REGTEST:
            pCurrentParams = &regTestParams;
            break;
        default:
            assert(false && "Unimplemented network");
            return;
    }
}

bool SelectParamsFromCommandLine() {
    bool fRegTest = GetBoolArg("-regtest", false);
    bool fTestNet = GetBoolArg("-testnet", false);

    if (fTestNet && fRegTest) {
        return false;
    }

    if (fRegTest) {
        SelectParams(CChainParams::REGTEST);
    } else if (fTestNet) {
        SelectParams(CChainParams::TESTNET);
    } else {
        SelectParams(CChainParams::MAIN);
    }
    return true;
}

ext: cpp

max_stars_repo_name: valorbit/valorbitlegacy

max_issues_repo_name: valorbit/valorbitlegacy

max_forks_repo_name: valorbit/valorbitlegacy


text:
#pragma once
/*
**  Copyright (C) 2013 Aldebaran Robotics
**  See COPYING for the license
*/

#ifndef _QI_SIGNATURE_HPP_
#define _QI_SIGNATURE_HPP_

#include <qi/api.hpp>
#include <ka/macro.hpp>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <sstream>
#include <boost/shared_ptr.hpp>

KA_WARNING_PUSH()
KA_WARNING_DISABLE(4251, )

namespace qi {

  QI_API std::vector<std::string> signatureSplit(const std::string &fullSignature);

  class SignaturePrivate;

  class AnyReference;
  class AnyValue;
  class TypeInterface;
  class Signature;
  QI_API qi::Signature makeTupleSignature(const std::vector<qi::AnyReference>& vgv,
                                              bool resolveDynamic = false,
                                              const std::string &name = std::string(),
                                              const std::vector<std::string>& names = std::vector<std::string>());
  QI_API qi::Signature makeTupleSignature(const std::vector<TypeInterface*>& vgv,
                                              const std::string &name = std::string(),
                                              const std::vector<std::string>& names = std::vector<std::string>());

  QI_API qi::Signature makeTupleSignature(const qi::Signature &element);
  QI_API qi::Signature makeListSignature(const qi::Signature &element);
  QI_API qi::Signature makeVarArgsSignature(const qi::Signature &element);
  QI_API qi::Signature makeKwArgsSignature(const qi::Signature &element);
  QI_API qi::Signature makeMapSignature(const qi::Signature &key, const qi::Signature &value);
  QI_API qi::Signature makeOptionalSignature(const qi::Signature& value);

  /* Represent the serialisation signature of a Type.
  * pseudo-grammar:
  * root: element
  * element: signature annotation.opt
  * sinature:
  *   | primitive  // in bcCwWiIlLfdsmro, see Type
  *   | [element]
  *   | {elementelement}
  *   | (elementsequence)
  * elementsequence: a list of 1 or more elements
  * annotation.opt: empty or <annotation>
  * annotation: may contain arbitrary content except \0
      and must balance all (), {}, [] and <> within
  * for tuple annotation has the following form: "<TupleName,elementName0,...,elementName1>"
  */
  class Signature;
  using SignatureVector = std::vector<Signature>;

  class QI_API Signature {
  protected:
    Signature(const std::string &signature, size_t begin, size_t end);
    friend class SignaturePrivate;

  public:
    Signature();
    Signature(const char *signature);
    Signature(const std::string &signature);

    bool isValid() const;

    bool hasChildren() const;

    const SignatureVector& children() const;

    //TODO use the type than "network type"
    enum Type {
      // Used only for empty containers when Dynamic resolution is used.
      Type_None     = '_',
      Type_Bool     = 'b',

      Type_Int8     = 'c',
      Type_UInt8    = 'C',

      Type_Void     = 'v',

      Type_Int16    = 'w',
      Type_UInt16   = 'W',

      Type_Int32    = 'i',
      Type_UInt32   = 'I',

      Type_Int64    = 'l',
      Type_UInt64   = 'L',

      Type_Float    = 'f',
      Type_Double   = 'd',

      Type_String   = 's',
      Type_List     = '[',
      Type_List_End = ']',

      Type_Map      = '{',
      Type_Map_End  = '}',

      Type_Tuple    = '(',
      Type_Tuple_End= ')',

      Type_Dynamic  = 'm',

      Type_Raw      = 'r',

      //This type should not be used, it's will be removed when we get ride of legacy void *.
      Type_Pointer  = '*',

      Type_Object   = 'o',
      Type_VarArgs  = '#',
      Type_KwArgs   = '~',

      Type_Optional = '+',

      Type_Unknown  = 'X',
    };

    Type type() const;
    std::string annotation() const;

    /** Encode the signature in a plain struct,
    * suitable for further serialization.
    * [typeString, childrenList, annotationString ]
    */
    AnyValue toData() const;
    std::string toPrettySignature() const;
    const std::string& toString() const;

    /** Tell if arguments with this signature can be converted to \p b.
     * @return 0 if conversion is impossible, or a score in ]0,1] indicating
     * the amount of type mismatch (the closer signatures are the bigger)
     */
    float isConvertibleTo(const Signature& b) const;

    static Signature fromType(Type t);
  protected:
    // C4251
    boost::shared_ptr<SignaturePrivate> _p;

    friend QI_API bool operator==(const Signature &lhs, const Signature &rhs);
  };

  inline std::ostream& operator<<(std::ostream& os, const Signature& s)
  {
    return os << s.toString();
  }

  inline bool operator!=(const Signature &lhs, const Signature &rhs)
  { return !(lhs == rhs); }
  QI_API bool operator==(const Signature &lhs, const Signature &rhs);

}

extern "C" QI_API char* signature_to_json(const char* sig);

KA_WARNING_POP()

#endif  // _QITYPE_SIGNATURE_HPP_

max_stars_repo_name: arntanguy/libqi

max_issues_repo_name: arntanguy/libqi

max_forks_repo_name: arntanguy/libqi


text:
#ifndef __STOUT_PROTOBUF_HPP__
#define __STOUT_PROTOBUF_HPP__

#include <errno.h>
#include <unistd.h>

#include <sys/types.h>

#include <glog/logging.h>

#include <google/protobuf/message.h>

#include <google/protobuf/io/zero_copy_stream_impl.h>

#include <string>

#include <boost/lexical_cast.hpp>

#include "os.hpp"
#include "result.hpp"
#include "try.hpp"

namespace protobuf {

// Write out the given protobuf to the specified file descriptor by
// first writing out the length of the protobuf followed by the
// contents.
inline Try<bool> write(int fd, const google::protobuf::Message& message)
{
  if (!message.IsInitialized()) {
    LOG(ERROR) << "Failed to write protocol buffer to file, "
               << "protocol buffer is not initialized!";
    return false;
  }

  uint32_t size = message.ByteSize();

  ssize_t length = ::write(fd, (void*) &size, sizeof(size));

  if (length == -1) {
    std::string error = strerror(errno);
    error = error + " (" + __FILE__ + ":" + stringify(__LINE__) + ")";
    return Try<bool>::error(error);
  }

  CHECK(length != 0);
  CHECK(length == sizeof(size)); // TODO(benh): Handle a non-blocking fd?

  return message.SerializeToFileDescriptor(fd);
}

// A wrapper function that wraps the above write() with
// open and closing the file.
inline Try<bool> write(const std::string& path,
                       const google::protobuf::Message& message)
{
  Try<int> fd = os::open(path, O_WRONLY | O_CREAT | O_TRUNC,
                         S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);
  if (fd.isError()) {
    return Try<bool>::error("Failed to open file " + path);
  }

  Try<bool> result = write(fd.get(), message);

  // NOTE: We ignore the return value of close(). This is because users calling
  // this function are interested in the return value of write(). Also an
  // unsuccessful close() doesn't affect the write.
  os::close(fd.get());

  return result;
}

// Read the next protobuf from the file by first reading the "size"
// followed by the contents (as written by 'write' above).
inline Result<bool> read(int fd, google::protobuf::Message* message)
{
  CHECK(message != NULL);

  message->Clear();

  // Save the offset so we can re-adjust if something goes wrong.
  off_t offset = lseek(fd, 0, SEEK_CUR);

  if (offset < 0) {
    std::string error = strerror(errno);
    error = error + " (" + __FILE__ + ":" + stringify(__LINE__) + ")";
    return Result<bool>::error(error);
  }

  uint32_t size;
  ssize_t length = ::read(fd, (void*) &size, sizeof(size));

  if (length == 0) {
    return Result<bool>::none();
  } else if (length == -1) {
    // Save the error, reset the file offset, and return the error.
    std::string error = strerror(errno);
    error = error + " (" + __FILE__ + ":" + stringify(__LINE__) + ")";
    lseek(fd, offset, SEEK_SET);
    return Result<bool>::error(error);
  } else if (length != sizeof(size)) {
    return false;
  }

  // TODO(benh): Use a different format for writing a protobuf to disk
  // so that we don't need to have broken heuristics like this!
  if (size > 10 * 1024 * 1024) { // 10 MB
    // Save the error, reset the file offset, and return the error.
    std::string error = "Size > 10 MB, possible corruption detected";
    error = error + " (" + __FILE__ + ":" + stringify(__LINE__) + ")";
    lseek(fd, offset, SEEK_SET);
    return Result<bool>::error(error);;
  }

  char* temp = new char[size];

  length = ::read(fd, temp, size);

  if (length == 0) {
    delete[] temp;
    return Result<bool>::none();
  } else if (length == -1) {
    // Save the error, reset the file offset, and return the error.
    std::string error = strerror(errno);
    error = error + " (" + __FILE__ + ":" + stringify(__LINE__) + ")";
    lseek(fd, offset, SEEK_SET);
    delete[] temp;
    return Result<bool>::error(error);
  } else if (length != size) {
    delete[] temp;
    return false;
  }

  google::protobuf::io::ArrayInputStream stream(temp, length);
  bool parsed = message->ParseFromZeroCopyStream(&stream);

  delete[] temp;

  if (!parsed) {
    // Save the error, reset the file offset, and return the error.
    std::string error = "Failed to parse protobuf";
    error = error + " (" + __FILE__ + ":" + stringify(__LINE__) + ")";
    lseek(fd, offset, SEEK_SET);
    return Result<bool>::error(error);;
  }

  return true;
}

// A wrapper function that wraps the above read() with
// open and closing the file.
inline Result<bool> read(const std::string& path,
                         google::protobuf::Message* message)
{
  Try<int> fd = os::open(path, O_RDONLY,
                         S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);

  if (fd.isError()) {
    return Result<bool>::error("Failed to open file " + path);
  }

  Result<bool> result = read(fd.get(), message);

  // NOTE: We ignore the return value of close(). This is because users calling
  // this function are interested in the return value of read(). Also an
  // unsuccessful close() doesn't affect the read.
  os::close(fd.get());

  return result;
}

} // namespace protobuf {

#endif // __STOUT_PROTOBUF_HPP__

max_stars_repo_name: clearstorydata/mesos

max_issues_repo_name: clearstorydata/mesos

max_forks_repo_name: clearstorydata/mesos


text: #include <boost/metaparse/v1/nth_of.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include <boost/test/unit_test.hpp>
#include "ParserFlatbuffersFixture.hpp"
#include "../TfLiteParser.hpp"

BOOST_AUTO_TEST_SUITE(TensorflowLiteParser)

struct TransposeConvFixture : public ParserFlatbuffersFixture
{
    explicit TransposeConvFixture(const std::string& inputShape,
                                  const std::string& outputShape,
                                  const std::string& filterShape,
                                  const std::string& filterData,
                                  const std::string& strideX,
                                  const std::string& strideY,
                                  const std::string& dataType)
    {
        m_JsonString = R"(
            {
                "version": 3,
                "operator_codes": [ { "builtin_code": "TRANSPOSE_CONV" } ],
                "subgraphs": [ {
                    "tensors": [
                        {
                            "shape": [ 4 ],
                            "type": "UINT8",
                            "buffer": 0,
                            "name": "outputShapeTensor",
                            "quantization": {
                                "min": [ 0.0 ],
                                "max": [ 255.0 ],
                                "scale": [ 1.0 ],
                                "zero_point": [ 0 ],
                            }
                        },
                        {
                            "shape": )" + filterShape + R"(,
                            "type": ")" + dataType + R"(",
                            "buffer": 1,
                            "name": "filterTensor",
                            "quantization": {
                                "min": [ 0.0 ],
                                "max": [ 255.0 ],
                                "scale": [ 1.0 ],
                                "zero_point": [ 0 ],
                            }
                        },
                        {
                            "shape": )" + inputShape + R"(,
                            "type": ")" + dataType + R"(",
                            "buffer": 2,
                            "name": "inputTensor",
                            "quantization": {
                                "min": [ 0.0 ],
                                "max": [ 255.0 ],
                                "scale": [ 1.0 ],
                                "zero_point": [ 0 ],
                            }
                        },
                        {
                            "shape": )" + outputShape + R"(,
                            "type": ")" + dataType + R"(",
                            "buffer": 3,
                            "name": "outputTensor",
                            "quantization": {
                                "min": [ 0.0 ],
                                "max": [ 255.0 ],
                                "scale": [ 1.0 ],
                                "zero_point": [ 0 ],
                            }
                        }
                    ],
                    "inputs": [ 2 ],
                    "outputs": [ 3 ],
                    "operators": [
                        {
                            "opcode_index": 0,
                            "inputs": [ 0, 1, 2 ],
                            "outputs": [ 3 ],
                            "builtin_options_type": "TransposeConvOptions",
                            "builtin_options": {
                                "padding": "VALID",
                                "stride_w": )" + strideX + R"(,
                                "stride_h": )" + strideY + R"(
                            },
                            "custom_options_format": "FLEXBUFFERS"
                        }
                    ],
                } ],
                "buffers" : [
                    { "data": )" + outputShape + R"( },
                    { "data": )" + filterData + R"( },
                    { },
                    { }
                ]
            }
        )";
        SetupSingleInputSingleOutput("inputTensor", "outputTensor");
    }
};

struct SimpleTransposeConvFixture : TransposeConvFixture
{
    SimpleTransposeConvFixture()
    : TransposeConvFixture("[ 1, 2, 2, 1 ]",  // inputShape
                           "[ 1, 3, 3, 1 ]",  // outputShape
                           "[ 1, 2, 2, 1 ]",  // filterShape
                           "[ 0, 1, 2, 4 ]",  // filterData
                           "1",               // strideX
                           "1",               // strideY
                           "UINT8")           // dataType
    {}
};

BOOST_FIXTURE_TEST_CASE( ParseSimpleTransposeConv, SimpleTransposeConvFixture )
{
    RunTest<4, armnn::DataType::QAsymmU8>(
        0,
        {
            1, 2,
            3, 4
        },
        {
            0, 1,  2,
            2, 11, 12,
            6, 20, 16
        });
}

BOOST_AUTO_TEST_SUITE_END()


text:
#include "version.h"
#include "ZipWriter.h"
#include "DslWriter.h"
#include "dictlsd/lsd.h"
#include "dictlsd/tools.h"
#include "dictlsd/LSAReader.h"

#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>
#include <boost/format.hpp>

#include <iostream>
#include <string>
#include <vector>
#include <tuple>
#include <map>

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

struct Entry {
    std::u16string heading;
    std::u16string article;
};

template <typename T>
std::vector<T>& append(std::vector<T>& vec, std::vector<T> const& rhs) {
    std::copy(rhs.begin(), rhs.end(), std::back_inserter(vec));
    return vec;
}

int parseLSD(fs::path lsdPath,
             fs::path outputPath,
             int sourceFilter,
             int targetFilter,
             bool dumb,
             std::ostream& log)
{
    FileStream ras(lsdPath.string());
    BitStreamAdapter bstr(&ras);
    LSDDictionary reader(&bstr);
    LSDHeader header = reader.header();
    log << "Header:";
    log << "\n  Version:  " << std::hex << header.version << std::dec;
    log << "\n  Headings: " << header.entriesCount;
    log << "\n  Source:   " << header.sourceLanguage
        << " (" << toUtf8(langFromCode(header.sourceLanguage)) << ")";
    log << "\n  Target:   " << header.targetLanguage
        << " (" << toUtf8(langFromCode(header.targetLanguage)) << ")";
    log << "\n  Name:     " << toUtf8(reader.name()) << std::endl;

    if (!reader.supported()) {
        log << "Unsupported dictionary version\n"
            "Only the following versions are implemented\n"
            "  Lingvo x6: 151005, 152001, 155001\n"
            "  Lingvo x5: 141004, 142001, 145001\n"
            "  Lingvo x3: 131001, 132001\n"
            "  Lingvo 12: 120001\n"
            "  Lingvo 11: 110001\n";
        return 1;
    }

    if ((sourceFilter != -1 && sourceFilter != header.sourceLanguage) ||
        (targetFilter != -1 && targetFilter != header.targetLanguage))
    {
        log << "ignoring\n";
        return 0;
    }

    if (!outputPath.empty()) {
        writeDSL(&reader, lsdPath.filename().string(), outputPath.string(),
                 dumb, [&](int, std::string s) { log << s << std::endl; });
    }

    return 0;
}

int main(int argc, char* argv[]) {
    std::string lsdPath, lsaPath, outputPath;
    int sourceFilter = -1, targetFilter = -1;
    bool isDumb;
    po::options_description console_desc("Allowed options");
    try {
        console_desc.add_options()
            ("help", "produce help message")
            ("lsd", po::value<std::string>(&lsdPath), "LSD dictionary to decode")
            ("lsa", po::value<std::string>(&lsaPath), "LSA sound archive to decode")
            ("source-filter", po::value<int>(&sourceFilter),
                "ignore dictionaries with source language != source-filter")
            ("target-filter", po::value<int>(&targetFilter),
                "ignore dictionaries with target language != target-filter")
            ("codes", "print supported languages and their codes")
            ("out", po::value<std::string>(&outputPath), "output directory")
            ("dumb", "don't combine variant headings and headings "
                     "referencing the same article")
            ("version", "print version")
            ;
        po::variables_map console_vm;
        po::store(po::parse_command_line(argc, argv, console_desc), console_vm);
        if (console_vm.count("help")) {
            std::cout << console_desc;
            return 0;
        }
        if (console_vm.count("codes")) {
            printLanguages(std::cout);
            return 0;
        }
        if (console_vm.count("version")) {
            std::cout << "lsd2dsl version " << g_version << std::endl;
            return 0;
        }
        isDumb = console_vm.count("dumb");
        po::notify(console_vm);
    } catch(std::exception& e) {
        std::cout << "can't parse program options:\n";
        std::cout << e.what() << "\n\n";
        std::cout << console_desc;
        return 1;
    }

    if (lsdPath.empty() && lsaPath.empty()) {
        std::cout << console_desc;
        return 0;
    }

    try {
        if (!outputPath.empty()) {
            fs::create_directories(outputPath);
            outputPath = fs::canonical(outputPath).string();
        }
        if (!lsdPath.empty()) {
            parseLSD(lsdPath,
                     outputPath,
                     sourceFilter,
                     targetFilter,
                     isDumb,
                     std::cout);
        }
        if (!lsaPath.empty()) {
            decodeLSA(lsaPath, outputPath, [](int i) { std::cout << i << std::endl; });
        }
    } catch (std::exception& exc) {
        std::cout << "an error occured while processing dictionary: " << exc.what() << std::endl;
        return 1;
    }

    return 0;
}


text:
#include <boost/test/unit_test.hpp>
#include "CheckedAllocator.h"
#include "L4/HashTable/ReadWrite/HashTable.h"
#include "L4/Log/PerfCounter.h"
#include "Mocks.h"
#include "Utils.h"

namespace L4 {
namespace UnitTests {

using namespace HashTable::ReadWrite;

class ReadWriteHashTableTestFixture {
 protected:
  using Allocator = CheckedAllocator<>;
  using HashTable = WritableHashTable<Allocator>::HashTable;

  ReadWriteHashTableTestFixture() : m_allocator{}, m_epochManager{} {}

  Allocator m_allocator;
  MockEpochManager m_epochManager;
};

BOOST_FIXTURE_TEST_SUITE(ReadWriteHashTableTests, ReadWriteHashTableTestFixture)

BOOST_AUTO_TEST_CASE(HashTableTest) {
  HashTable hashTable{HashTable::Setting{100, 5}, m_allocator};
  WritableHashTable<Allocator> writableHashTable(hashTable, m_epochManager);
  ReadOnlyHashTable<Allocator> readOnlyHashTable(hashTable);

  const auto& perfData = writableHashTable.GetPerfData();

  {
    // Check empty data.

    std::string keyStr = "hello";
    auto key =
        Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str());

    IReadOnlyHashTable::Value data;
    BOOST_CHECK(!readOnlyHashTable.Get(key, data));

    const auto c_counterMaxValue =
        (std::numeric_limits<HashTablePerfData::TValue>::max)();
    Utils::ValidateCounters(
        perfData, {{HashTablePerfCounter::RecordsCount, 0},
                   {HashTablePerfCounter::BucketsCount, 100},
                   {HashTablePerfCounter::ChainingEntriesCount, 0},
                   {HashTablePerfCounter::TotalKeySize, 0},
                   {HashTablePerfCounter::TotalValueSize, 0},
                   {HashTablePerfCounter::MinKeySize, c_counterMaxValue},
                   {HashTablePerfCounter::MaxKeySize, 0},
                   {HashTablePerfCounter::MinValueSize, c_counterMaxValue},
                   {HashTablePerfCounter::MaxValueSize, 0}});
  }

  {
    // First record added.
    std::string keyStr = "hello";
    std::string valStr = "world";

    auto key =
        Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str());
    auto val =
        Utils::ConvertFromString<IReadOnlyHashTable::Value>(valStr.c_str());

    writableHashTable.Add(key, val);

    IReadOnlyHashTable::Value value;
    BOOST_CHECK(readOnlyHashTable.Get(key, value));
    BOOST_CHECK(value.m_size == valStr.size());
    BOOST_CHECK(!memcmp(value.m_data, valStr.c_str(), valStr.size()));

    Utils::ValidateCounters(perfData,
                            {{HashTablePerfCounter::RecordsCount, 1},
                             {HashTablePerfCounter::BucketsCount, 100},
                             {HashTablePerfCounter::ChainingEntriesCount, 0},
                             {HashTablePerfCounter::TotalKeySize, 5},
                             {HashTablePerfCounter::TotalValueSize, 5},
                             {HashTablePerfCounter::MinKeySize, 5},
                             {HashTablePerfCounter::MaxKeySize, 5},
                             {HashTablePerfCounter::MinValueSize, 5},
                             {HashTablePerfCounter::MaxValueSize, 5}});
  }

  {
    // Second record added.
    std::string keyStr = "hello2";
    std::string valStr = "world2";

    auto key =
        Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str());
    auto val =
        Utils::ConvertFromString<IReadOnlyHashTable::Value>(valStr.c_str());

    writableHashTable.Add(key, val);

    IReadOnlyHashTable::Value value;
    BOOST_CHECK(readOnlyHashTable.Get(key, value));
    BOOST_CHECK(value.m_size == valStr.size());
    BOOST_CHECK(!memcmp(value.m_data, valStr.c_str(), valStr.size()));

    Utils::ValidateCounters(perfData,
                            {{HashTablePerfCounter::RecordsCount, 2},
                             {HashTablePerfCounter::BucketsCount, 100},
                             {HashTablePerfCounter::ChainingEntriesCount, 0},
                             {HashTablePerfCounter::TotalKeySize, 11},
                             {HashTablePerfCounter::TotalValueSize, 11},
                             {HashTablePerfCounter::MinKeySize, 5},
                             {HashTablePerfCounter::MaxKeySize, 6},
                             {HashTablePerfCounter::MinValueSize, 5},
                             {HashTablePerfCounter::MaxValueSize, 6}});
  }

  {
    // Update the key with value bigger than the existing values.
    std::string keyStr = "hello";
    std::string valStr = "world long string";

    auto key =
        Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str());
    auto val =
        Utils::ConvertFromString<IReadOnlyHashTable::Value>(valStr.c_str());

    writableHashTable.Add(key, val);

    IReadOnlyHashTable::Value value;
    BOOST_CHECK(readOnlyHashTable.Get(key, value));
    BOOST_CHECK(value.m_size == valStr.size());
    BOOST_CHECK(!memcmp(value.m_data, valStr.c_str(), valStr.size()));
    BOOST_CHECK(m_epochManager.m_numRegisterActionsCalled == 1);

    Utils::ValidateCounters(perfData,
                            {{HashTablePerfCounter::RecordsCount, 2},
                             {HashTablePerfCounter::BucketsCount, 100},
                             {HashTablePerfCounter::ChainingEntriesCount, 0},
                             {HashTablePerfCounter::TotalKeySize, 11},
                             {HashTablePerfCounter::TotalValueSize, 23},
                             {HashTablePerfCounter::MinKeySize, 5},
                             {HashTablePerfCounter::MaxKeySize, 6},
                             {HashTablePerfCounter::MinValueSize, 5},
                             {HashTablePerfCounter::MaxValueSize, 17}});
  }

  {
    // Update the key with value smaller than the existing values.
    std::string keyStr = "hello2";
    std::string valStr = "wo";

    auto key =
        Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str());
    auto val =
        Utils::ConvertFromString<IReadOnlyHashTable::Value>(valStr.c_str());

    writableHashTable.Add(key, val);

    IReadOnlyHashTable::Value value;
    BOOST_CHECK(readOnlyHashTable.Get(key, value));
    BOOST_CHECK(value.m_size == valStr.size());
    BOOST_CHECK(!memcmp(value.m_data, valStr.c_str(), valStr.size()));
    BOOST_CHECK(m_epochManager.m_numRegisterActionsCalled == 2);

    Utils::ValidateCounters(perfData,
                            {{HashTablePerfCounter::RecordsCount, 2},
                             {HashTablePerfCounter::BucketsCount, 100},
                             {HashTablePerfCounter::ChainingEntriesCount, 0},
                             {HashTablePerfCounter::TotalKeySize, 11},
                             {HashTablePerfCounter::TotalValueSize, 19},
                             {HashTablePerfCounter::MinKeySize, 5},
                             {HashTablePerfCounter::MaxKeySize, 6},
                             {HashTablePerfCounter::MinValueSize, 2},
                             {HashTablePerfCounter::MaxValueSize, 17}});
  }

  {
    // Remove the first key.
    std::string keyStr = "hello";
    std::string valStr = "";

    auto key =
        Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str());
    auto val =
        Utils::ConvertFromString<IReadOnlyHashTable::Value>(valStr.c_str());

    BOOST_CHECK(writableHashTable.Remove(key));
    BOOST_CHECK(m_epochManager.m_numRegisterActionsCalled == 3);

    // Note that the Remove() doesn't change Min/Max counters by design.
    Utils::ValidateCounters(perfData,
                            {{HashTablePerfCounter::RecordsCount, 1},
                             {HashTablePerfCounter::BucketsCount, 100},
                             {HashTablePerfCounter::ChainingEntriesCount, 0},
                             {HashTablePerfCounter::TotalKeySize, 6},
                             {HashTablePerfCounter::TotalValueSize, 2},
                             {HashTablePerfCounter::MinKeySize, 5},
                             {HashTablePerfCounter::MaxKeySize, 6},
                             {HashTablePerfCounter::MinValueSize, 2},
                             {HashTablePerfCounter::MaxValueSize, 17}});

    // Remove the second key.
    keyStr = "hello2";
    key = Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str());

    BOOST_CHECK(writableHashTable.Remove(key));
    BOOST_CHECK(m_epochManager.m_numRegisterActionsCalled == 4);

    Utils::ValidateCounters(perfData,
                            {{HashTablePerfCounter::RecordsCount, 0},
                             {HashTablePerfCounter::BucketsCount, 100},
                             {HashTablePerfCounter::ChainingEntriesCount, 0},
                             {HashTablePerfCounter::TotalKeySize, 0},
                             {HashTablePerfCounter::TotalValueSize, 0},
                             {HashTablePerfCounter::MinKeySize, 5},
                             {HashTablePerfCounter::MaxKeySize, 6},
                             {HashTablePerfCounter::MinValueSize, 2},
                             {HashTablePerfCounter::MaxValueSize, 17}});

    // Removing the key that doesn't exist.
    BOOST_CHECK(!writableHashTable.Remove(key));
    Utils::ValidateCounters(perfData,
                            {{HashTablePerfCounter::RecordsCount, 0},
                             {HashTablePerfCounter::BucketsCount, 100},
                             {HashTablePerfCounter::ChainingEntriesCount, 0},
                             {HashTablePerfCounter::TotalKeySize, 0},
                             {HashTablePerfCounter::TotalValueSize, 0},
                             {HashTablePerfCounter::MinKeySize, 5},
                             {HashTablePerfCounter::MaxKeySize, 6},
                             {HashTablePerfCounter::MinValueSize, 2},
                             {HashTablePerfCounter::MaxValueSize, 17}});
  }
}

BOOST_AUTO_TEST_CASE(HashTableWithOneBucketTest) {
  Allocator allocator;
  HashTable hashTable{HashTable::Setting{1}, allocator};
  WritableHashTable<Allocator> writableHashTable(hashTable, m_epochManager);
  ReadOnlyHashTable<Allocator> readOnlyHashTable(hashTable);

  const auto& perfData = writableHashTable.GetPerfData();

  Utils::ValidateCounters(perfData,
                          {{HashTablePerfCounter::ChainingEntriesCount, 0}});

  const auto initialTotalIndexSize =
      perfData.Get(HashTablePerfCounter::TotalIndexSize);
  const std::size_t c_dataSetSize = HashTable::Entry::c_numDataPerEntry + 5U;

  std::size_t expectedTotalKeySize = 0U;
  std::size_t expectedTotalValueSize = 0U;

  for (auto i = 0U; i < c_dataSetSize; ++i) {
    std::stringstream keyStream;
    keyStream << "key" << i;

    std::stringstream valStream;
    valStream << "value" << i;

    std::string keyStr = keyStream.str();
    std::string valStr = valStream.str();

    auto key =
        Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str());
    auto val =
        Utils::ConvertFromString<IReadOnlyHashTable::Value>(valStr.c_str());

    expectedTotalKeySize += key.m_size;
    expectedTotalValueSize += val.m_size;

    writableHashTable.Add(key, val);

    IReadOnlyHashTable::Value value;
    BOOST_CHECK(readOnlyHashTable.Get(key, value));
    BOOST_CHECK(value.m_size == valStr.size());
    BOOST_CHECK(!memcmp(value.m_data, valStr.c_str(), valStr.size()));
  }

  using L4::HashTable::RecordSerializer;

  // Variable key/value sizes.
  const auto recordOverhead =
      RecordSerializer{0U, 0U}.CalculateRecordOverhead();

  Utils::ValidateCounters(
      perfData, {{HashTablePerfCounter::RecordsCount, c_dataSetSize},
                 {HashTablePerfCounter::BucketsCount, 1},
                 {HashTablePerfCounter::MaxBucketChainLength, 2},
                 {HashTablePerfCounter::ChainingEntriesCount, 1},
                 {HashTablePerfCounter::TotalKeySize, expectedTotalKeySize},
                 {HashTablePerfCounter::TotalValueSize, expectedTotalValueSize},
                 {HashTablePerfCounter::TotalIndexSize,
                  initialTotalIndexSize + sizeof(HashTable::Entry) +
                      (c_dataSetSize * recordOverhead)}});

  // Now replace with new values.
  expectedTotalValueSize = 0U;

  for (auto i = 0U; i < c_dataSetSize; ++i) {
    std::stringstream keyStream;
    keyStream << "key" << i;

    std::stringstream valStream;
    valStream << "val" << i;

    std::string keyStr = keyStream.str();
    std::string valStr = valStream.str();

    auto key =
        Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str());
    auto val =
        Utils::ConvertFromString<IReadOnlyHashTable::Value>(valStr.c_str());

    expectedTotalValueSize += val.m_size;

    writableHashTable.Add(key, val);

    IReadOnlyHashTable::Value value;
    BOOST_CHECK(readOnlyHashTable.Get(key, value));
    BOOST_CHECK(value.m_size == valStr.size());
    BOOST_CHECK(!memcmp(value.m_data, valStr.c_str(), valStr.size()));
  }

  Utils::ValidateCounters(
      perfData, {{HashTablePerfCounter::RecordsCount, c_dataSetSize},
                 {HashTablePerfCounter::BucketsCount, 1},
                 {HashTablePerfCounter::MaxBucketChainLength, 2},
                 {HashTablePerfCounter::ChainingEntriesCount, 1},
                 {HashTablePerfCounter::TotalKeySize, expectedTotalKeySize},
                 {HashTablePerfCounter::TotalValueSize, expectedTotalValueSize},
                 {HashTablePerfCounter::TotalIndexSize,
                  initialTotalIndexSize + sizeof(HashTable::Entry) +
                      (c_dataSetSize * recordOverhead)}});

  // Now remove all key-value.
  for (auto i = 0U; i < c_dataSetSize; ++i) {
    std::stringstream keyStream;
    keyStream << "key" << i;

    std::string keyStr = keyStream.str();
    auto key =
        Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str());

    BOOST_CHECK(writableHashTable.Remove(key));

    IReadOnlyHashTable::Value value;
    BOOST_CHECK(!readOnlyHashTable.Get(key, value));
  }

  Utils::ValidateCounters(perfData,
                          {{HashTablePerfCounter::RecordsCount, 0},
                           {HashTablePerfCounter::BucketsCount, 1},
                           {HashTablePerfCounter::MaxBucketChainLength, 2},
                           {HashTablePerfCounter::ChainingEntriesCount, 1},
                           {HashTablePerfCounter::TotalKeySize, 0},
                           {HashTablePerfCounter::TotalValueSize, 0},
                           {HashTablePerfCounter::TotalIndexSize,
                            initialTotalIndexSize + sizeof(HashTable::Entry)}});

  // Try to add back to the same bucket (reusing existing entries)
  expectedTotalKeySize = 0U;
  expectedTotalValueSize = 0U;

  for (auto i = 0U; i < c_dataSetSize; ++i) {
    std::stringstream keyStream;
    keyStream << "key" << i;

    std::stringstream valStream;
    valStream << "value" << i;

    std::string keyStr = keyStream.str();
    std::string valStr = valStream.str();

    auto key =
        Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str());
    auto val =
        Utils::ConvertFromString<IReadOnlyHashTable::Value>(valStr.c_str());

    expectedTotalKeySize += key.m_size;
    expectedTotalValueSize += val.m_size;

    writableHashTable.Add(key, val);

    IReadOnlyHashTable::Value value;
    BOOST_CHECK(readOnlyHashTable.Get(key, value));
    BOOST_CHECK(value.m_size == valStr.size());
    BOOST_CHECK(!memcmp(value.m_data, valStr.c_str(), valStr.size()));
  }

  Utils::ValidateCounters(
      perfData, {{HashTablePerfCounter::RecordsCount, c_dataSetSize},
                 {HashTablePerfCounter::BucketsCount, 1},
                 {HashTablePerfCounter::MaxBucketChainLength, 2},
                 {HashTablePerfCounter::ChainingEntriesCount, 1},
                 {HashTablePerfCounter::TotalKeySize, expectedTotalKeySize},
                 {HashTablePerfCounter::TotalValueSize, expectedTotalValueSize},
                 {HashTablePerfCounter::TotalIndexSize,
                  initialTotalIndexSize + sizeof(HashTable::Entry) +
                      (c_dataSetSize * recordOverhead)}});
}

BOOST_AUTO_TEST_CASE(AddRemoveSameKeyTest) {
  HashTable hashTable{HashTable::Setting{100, 5}, m_allocator};
  WritableHashTable<Allocator> writableHashTable(hashTable, m_epochManager);
  ReadOnlyHashTable<Allocator> readOnlyHashTable(hashTable);

  // Add two key/value pairs.
  auto key1 = Utils::ConvertFromString<IReadOnlyHashTable::Key>("key1");
  auto val1 = Utils::ConvertFromString<IReadOnlyHashTable::Value>("val1");
  writableHashTable.Add(key1, val1);

  IReadOnlyHashTable::Value valueRetrieved;
  BOOST_CHECK(readOnlyHashTable.Get(key1, valueRetrieved));
  BOOST_CHECK(valueRetrieved.m_size == val1.m_size);
  BOOST_CHECK(!memcmp(valueRetrieved.m_data, val1.m_data, val1.m_size));

  auto key2 = Utils::ConvertFromString<IReadOnlyHashTable::Key>("key2");
  auto val2 = Utils::ConvertFromString<IReadOnlyHashTable::Value>("val2");
  writableHashTable.Add(key2, val2);

  BOOST_CHECK(readOnlyHashTable.Get(key2, valueRetrieved));
  BOOST_CHECK(valueRetrieved.m_size == val2.m_size);
  BOOST_CHECK(!memcmp(valueRetrieved.m_data, val2.m_data, val2.m_size));

  const auto& perfData = writableHashTable.GetPerfData();

  // Now remove the first record with key = "key1", which is at the head of the
  // chain.
  BOOST_CHECK(writableHashTable.Remove(key1));
  BOOST_CHECK(!readOnlyHashTable.Get(key1, valueRetrieved));
  Utils::ValidateCounter(perfData, HashTablePerfCounter::RecordsCount, 1);

  // Now try update the record with key = "key2". This should correctly update
  // the existing record instead of using the empty slot created by removing the
  // record with key = "key1".
  auto newVal2 = Utils::ConvertFromString<IReadOnlyHashTable::Value>("newVal2");
  writableHashTable.Add(key2, newVal2);

  BOOST_CHECK(readOnlyHashTable.Get(key2, valueRetrieved));
  BOOST_CHECK(valueRetrieved.m_size == newVal2.m_size);
  BOOST_CHECK(!memcmp(valueRetrieved.m_data, newVal2.m_data, newVal2.m_size));
  Utils::ValidateCounter(perfData, HashTablePerfCounter::RecordsCount, 1);

  // Remove the record with key = "key2".
  BOOST_CHECK(writableHashTable.Remove(key2));
  BOOST_CHECK(!writableHashTable.Remove(key2));
  Utils::ValidateCounter(perfData, HashTablePerfCounter::RecordsCount, 0);
}

BOOST_AUTO_TEST_CASE(FixedKeyValueHashTableTest) {
  // Fixed 4 byte keys and 6 byte values.
  std::vector<HashTable::Setting> settings = {
      HashTable::Setting{100, 200, 4, 0}, HashTable::Setting{100, 200, 0, 6},
      HashTable::Setting{100, 200, 4, 6}};

  for (const auto& setting : settings) {
    HashTable hashTable{setting, m_allocator};
    WritableHashTable<Allocator> writableHashTable(hashTable, m_epochManager);
    ReadOnlyHashTable<Allocator> readOnlyHashTable(hashTable);

    constexpr std::uint8_t c_numRecords = 10;

    for (std::uint8_t i = 0; i < c_numRecords; ++i) {
      const std::string keyStr = "key" + std::to_string(i);
      const std::string valueStr = "value" + std::to_string(i);

      writableHashTable.Add(
          Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str()),
          Utils::ConvertFromString<IReadOnlyHashTable::Value>(
              valueStr.c_str()));
    }

    Utils::ValidateCounters(writableHashTable.GetPerfData(),
                            {{HashTablePerfCounter::RecordsCount, 10},
                             {HashTablePerfCounter::BucketsCount, 100},
                             {HashTablePerfCounter::TotalKeySize, 40},
                             {HashTablePerfCounter::TotalValueSize, 60},
                             {HashTablePerfCounter::MinKeySize, 4},
                             {HashTablePerfCounter::MaxKeySize, 4},
                             {HashTablePerfCounter::MinValueSize, 6},
                             {HashTablePerfCounter::MaxValueSize, 6}});

    for (std::uint8_t i = 0; i < c_numRecords; ++i) {
      const std::string keyStr = "key" + std::to_string(i);
      const std::string valueStr = "value" + std::to_string(i);
      const auto expectedValue =
          Utils::ConvertFromString<IReadOnlyHashTable::Value>(valueStr.c_str());

      IReadOnlyHashTable::Value actualValue;
      BOOST_CHECK(readOnlyHashTable.Get(
          Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str()),
          actualValue));
      BOOST_CHECK(expectedValue == actualValue);
    }

    for (std::uint8_t i = 0; i < c_numRecords; ++i) {
      const std::string keyStr = "key" + std::to_string(i);
      writableHashTable.Remove(
          Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str()));
    }

    Utils::ValidateCounters(writableHashTable.GetPerfData(),
                            {{HashTablePerfCounter::RecordsCount, 0},
                             {HashTablePerfCounter::BucketsCount, 100},
                             {HashTablePerfCounter::TotalKeySize, 0},
                             {HashTablePerfCounter::TotalValueSize, 0}});
  }
}

BOOST_AUTO_TEST_CASE(HashTableIteratorTest) {
  Allocator allocator;
  constexpr std::uint32_t c_numBuckets = 10;
  HashTable hashTable{HashTable::Setting{c_numBuckets}, allocator};
  WritableHashTable<Allocator> writableHashTable(hashTable, m_epochManager);

  {
    // Empty data set, thus iterator cannot move.
    auto iter = writableHashTable.GetIterator();
    BOOST_CHECK(!iter->MoveNext());

    CHECK_EXCEPTION_THROWN_WITH_MESSAGE(
        iter->GetKey(), "HashTableIterator is not correctly used.");

    CHECK_EXCEPTION_THROWN_WITH_MESSAGE(
        iter->GetValue(), "HashTableIterator is not correctly used.");
  }

  using Buffer = std::vector<std::uint8_t>;
  using BufferMap = std::map<Buffer, Buffer>;

  BufferMap keyValueMap;

  // The number of records should be such that it will create chained entries
  // for at least one bucket. So it should be greater than
  // HashTable::Entry::c_numDataPerEntry * number of buckets.
  constexpr std::uint32_t c_numRecords =
      (HashTable::Entry::c_numDataPerEntry * c_numBuckets) + 1;

  for (auto i = 0U; i < c_numRecords; ++i) {
    std::stringstream keyStream;
    keyStream << "key" << i;

    std::stringstream valStream;
    valStream << "value" << i;

    std::string keyStr = keyStream.str();
    std::string valStr = valStream.str();

    auto key =
        Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str());
    auto val =
        Utils::ConvertFromString<IReadOnlyHashTable::Value>(valStr.c_str());

    writableHashTable.Add(key, val);

    keyValueMap[Buffer(key.m_data, key.m_data + key.m_size)] =
        Buffer(val.m_data, val.m_data + val.m_size);
  }

  BOOST_REQUIRE(writableHashTable.GetPerfData().Get(
                    HashTablePerfCounter::MaxBucketChainLength) >= 2);
  BOOST_CHECK_EQUAL(keyValueMap.size(), c_numRecords);

  {
    BufferMap keyValueMapFromIterator;

    // Validate the data using the iterator.
    auto iter = writableHashTable.GetIterator();
    for (auto i = 0U; i < c_numRecords; ++i) {
      BOOST_CHECK(iter->MoveNext());

      const auto& key = iter->GetKey();
      const auto& val = iter->GetValue();

      keyValueMapFromIterator[Buffer(key.m_data, key.m_data + key.m_size)] =
          Buffer(val.m_data, val.m_data + val.m_size);
    }
    BOOST_CHECK(!iter->MoveNext());
    BOOST_CHECK(keyValueMap == keyValueMapFromIterator);

    // Reset should move the iterator to the beginning.
    iter->Reset();
    for (auto i = 0U; i < c_numRecords; ++i) {
      BOOST_CHECK(iter->MoveNext());
    }
    BOOST_CHECK(!iter->MoveNext());
  }

  // Remove half of the key.
  for (auto i = 0U; i < c_numRecords; ++i) {
    if (i % 2 == 0U) {
      std::stringstream keyStream;
      keyStream << "key" << i;

      std::string keyStr = keyStream.str();
      auto key =
          Utils::ConvertFromString<IReadOnlyHashTable::Key>(keyStr.c_str());

      BOOST_CHECK(writableHashTable.Remove(key));

      keyValueMap.erase(Buffer(key.m_data, key.m_data + key.m_size));
    }
  }

  BOOST_CHECK_EQUAL(keyValueMap.size(), c_numRecords / 2U);

  // Validate only the existing keys are iterated.
  {
    BufferMap keyValueMapFromIterator;
    auto iter = writableHashTable.GetIterator();
    for (auto i = 0U; i < c_numRecords / 2U; ++i) {
      BOOST_CHECK(iter->MoveNext());

      const auto& key = iter->GetKey();
      const auto& val = iter->GetValue();

      keyValueMapFromIterator[Buffer(key.m_data, key.m_data + key.m_size)] =
          Buffer(val.m_data, val.m_data + val.m_size);
    }
    BOOST_CHECK(!iter->MoveNext());
    BOOST_CHECK(keyValueMap == keyValueMapFromIterator);
  }
}

BOOST_AUTO_TEST_SUITE_END()

}  // namespace UnitTests
}  // namespace L4


text:
/******************************************************************
*
* Round for C++
*
* Copyright (C) Satoshi Konno 2015
*
* This is licensed under BSD-style license, see file COPYING.
*
******************************************************************/

#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>

#include <round/Round.h>
#include <round/core/LocalNode.h>
#include <round/core/RemoteNode.h>
#include <round/core/local/method/SystemMethod.h>

////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////

Round::LocalNode::LocalNode() {
  init();
}

Round::LocalNode::~LocalNode() {
}

void Round::LocalNode::init() {
  this->nodeReg.setNode(this);
  this->scriptMgr.setNode(this);
  setState(NodeStatus::STOP);
}

////////////////////////////////////////////////
// Config
////////////////////////////////////////////////

bool Round::LocalNode::loadConfigFromString(const std::string &string, Error *error) {
  if (this->nodeConfig.loadFromString(string, error) == false)
    return false;
  return true;
}

bool Round::LocalNode::loadConfigFromFile(const std::string &filename, Error *error) {
  if (this->nodeConfig.loadFromFile(filename, error) == false)
    return false;
  return true;
}

bool Round::LocalNode::isConfigValid(Error *error) {
  return this->nodeConfig.isValid(error);
}

bool Round::LocalNode::getClusterName(std::string *name, Error *error) {
  return this->nodeConfig.getCluster(name, error);
}

bool Round::LocalNode::getConfig(JSONDictionary *jsonDict, Error *error) {
  std::string value;
  int ivalue;

  // bind_addr
  if (this->nodeConfig.getBindAddress(&value, error)) {
    jsonDict->set(LocalConfig::BIND_ADDR, value);
 }

  // bind_port
  if (this->nodeConfig.getBindPort(&ivalue, error)) {
    jsonDict->set(LocalConfig::BIND_PORT, ivalue);
  }

  // cluster
  if (getClusterName(&value, error)) {
    jsonDict->set(LocalConfig::CLUSTER, value);
  }

  // log_file
  if (this->nodeConfig.getLogFilename(&value, error)) {
    jsonDict->set(LocalConfig::LOG_FILE, value);
  }

  // methods
  JSONArray *methods = new JSONArray();
  if (methods) {
    if (this->scriptMgr.toJSONArray(methods, error)) {
      jsonDict->set(LocalConfig::METHODS, methods);
    }
    else {
      delete methods;
    }
  }

  return true;
}

////////////////////////////////////////////////
// Thread
////////////////////////////////////////////////

bool Round::LocalNode::start(Error *error) {
  stop(error);

  bool areAllOperationSucess = true;

  setState(NodeStatus::ACTIVATING);

  nodeWorker.setObject(this);
  if (nodeWorker.start()) {
    if (!this->nodeGraph.addNode(this)) {
      areAllOperationSucess = false;
    }
  }
  else {
    areAllOperationSucess = false;
  }

  if (!this->triggerMgr.start()) {
    areAllOperationSucess = false;
  }

  if (!areAllOperationSucess) {
    stop(error);
    return false;
  }

  setState(NodeStatus::ACTIVE);

  return true;
}

bool Round::LocalNode::stop(Error *error) {
  bool areAllOperationSucess = true;

  if (!nodeWorker.stop()) {
    areAllOperationSucess = false;
    return false;
  }

  NodeGraph *nodeGraph = getNodeGraph();
  if (!nodeGraph->clear()) {
    areAllOperationSucess = false;
  }

  if (!this->triggerMgr.stop()) {
    areAllOperationSucess = false;
  }

  if (areAllOperationSucess == true) {
    setState(NodeStatus::STOP);
  }

  return areAllOperationSucess;
}

bool Round::LocalNode::restart(Error *error) {
  if (stop(error) == false)
    return false;
  return start(error);
}

////////////////////////////////////////////////
// Notification
////////////////////////////////////////////////

bool Round::LocalNode::nodeAdded(Round::Node *notifyNode)  {
  Error error;

  std::string notifyNodeCluster;
  if (!notifyNode->getClusterName(&notifyNodeCluster, &error))
    return false;

  std::string thisNodeCluster;
  if (!getClusterName(&thisNodeCluster, &error))
    return false;

  if (thisNodeCluster.compare(notifyNodeCluster) != 0)
    return false;

  if (this->nodeGraph.hasNode(notifyNode))
    return true;

  if (!this->nodeGraph.addNode(notifyNode))
    return true;

  if (equals(notifyNode))
    return true;

  return true;
}

bool Round::LocalNode::nodeRemoved(Round::Node *notifyNode)  {
  if (!this->nodeGraph.hasNode(notifyNode))
    return true;

  if (equals(notifyNode)) {
    this->nodeGraph.removeNode(notifyNode);
    return true;
  }

  ssize_t notifyNodeIndex = this->nodeGraph.getNodeIndex(notifyNode);
  if (notifyNodeIndex < 0)
    return false;

  Node *failedNode = this->nodeGraph.getNode(notifyNodeIndex);
  if (!failedNode)
    return false;

  return true;
}

////////////////////////////////////////////////
// Method
////////////////////////////////////////////////

bool Round::LocalNode::addMethod(Method *method) {
  return this->sysMethodMgr.addMethod(method);
}

bool Round::LocalNode::setScript(const std::string &method, const std::string &lang, const std::string &code, int encodeType, Error *error) {
  return this->scriptMgr.setScript(method, lang, code, encodeType, error);
}

bool Round::LocalNode::removeScript(const std::string &method, Error *error) {
  return this->scriptMgr.removeScript(method, error);
}

bool Round::LocalNode::execJob(const std::string &lang, const std::string &script, int encodeType, std::string *result, Error *error) {
  return this->scriptMgr.execScript(lang, script, encodeType, result, error);
}

////////////////////////////////////////////////
// Alias
////////////////////////////////////////////////

bool Round::LocalNode::setAlias(Alias *alias) {
  this->aliasMgr.lock();
  bool isSuccess = this->aliasMgr.setAlias(alias);
  this->aliasMgr.unlock();
  return isSuccess;
}

bool Round::LocalNode::removeAliasByName(const std::string &name) {
  this->aliasMgr.lock();
  bool isSuccess = this->aliasMgr.removeAliasByName(name);
  this->aliasMgr.unlock();
  return isSuccess;
}

////////////////////////////////////////////////
// Trigger
////////////////////////////////////////////////

bool Round::LocalNode::setTrigger(Trigger *trigger) {
  this->triggerMgr.lock();
  bool isSuccess = this->triggerMgr.setTrigger(trigger);
  this->triggerMgr.unlock();
  return isSuccess;
}

bool Round::LocalNode::removeTriggerByName(const std::string &name) {
  this->triggerMgr.lock();
  bool isSuccess = this->triggerMgr.removeTriggerByName(name);
  this->triggerMgr.unlock();
  return isSuccess;
}

bool Round::LocalNode::execTrigger(const std::string &name) {
  Error err;
  return execTrigger(name, &err);
}

////////////////////////////////////////////////
// Registry
////////////////////////////////////////////////

bool Round::LocalNode::setRegistry(const std::string &key, const std::string &value) {
  return this->nodeReg.set(key, value);
}

bool Round::LocalNode::getRegistry(const std::string &key, std::string *value) const {
  return this->nodeReg.get(key, value);
}

bool Round::LocalNode::setRegistry(const Registry reg) {
  return this->nodeReg.set(reg);
}

bool Round::LocalNode::getRegistry(const std::string &key, Registry *reg) const {
  return this->nodeReg.get(key, reg);
}

bool Round::LocalNode::removeRegistry(const std::string &key) {
  return this->nodeReg.remove(key);
}

////////////////////////////////////////////////
// Message
////////////////////////////////////////////////

bool Round::LocalNode::postMessage(const NodeRequest *nodeReq, NodeResponse *nodeRes, Error *error) {
  // Set id and ts parameter
  (const_cast<NodeRequest *>(nodeReq))->setSourceNodeParameters(this);

  // Post RPC message
  return execMessage(nodeReq, nodeRes, error);
}

bool Round::LocalNode::postMessage(const NodeBatchRequest *nodeBatchReq, NodeBatchResponse *nodeBatchRes, Error *error) {
  return execMessage(nodeBatchReq, nodeBatchRes, error);
}

bool Round::LocalNode::pushMessage(const Message *nodeReq) {
  return this->nodeMsgMgr.pushMessage(nodeReq);
}

bool Round::LocalNode::waitMessage(const Message **nodeReq) {
  if (!this->nodeMsgMgr.waitMessage(nodeReq))
    return false;
  return true;
}

////////////////////////////////////////////////
// Route
////////////////////////////////////////////////

bool Round::LocalNode::setRoute(Route *route) {
  this->routeMgr.lock();

  bool isSuccess = this->routeMgr.setRoute(route);

  this->routeMgr.unlock();

  return isSuccess;
}

bool Round::LocalNode::removeSameRoute(const Route *route) {
  this->routeMgr.lock();

  bool isSuccess = this->routeMgr.removeSameRoute(route);

  this->routeMgr.unlock();

  return isSuccess;
}

bool Round::LocalNode::removeRouteByName(const std::string &name) {
  this->routeMgr.lock();

  bool isSuccess = this->routeMgr.removeRouteByName(name);

  this->routeMgr.unlock();

  return isSuccess;
}

////////////////////////////////////////////////
// get*Nodes
////////////////////////////////////////////////

bool Round::LocalNode::getQuorumNodes(NodeList *nodes, size_t quorum) {
  NodeGraph *nodeGraph = getNodeGraph();
  if (!nodeGraph)
    return false;

  for (size_t n=1; n<=quorum; n++) {
    Node *node = nodeGraph->getOffsetNode(this, n);
    if (!node)
      continue;
    if (node->equals(this))
      continue;
    RemoteNode *remoteNode = new RemoteNode(node);
    remoteNode->setWeakFlag(false);
    nodes->addNode(remoteNode);
  }

  return true;
}

bool Round::LocalNode::getAllOtherNodes(NodeList *nodes) {
  NodeGraph *nodeGraph = getNodeGraph();
  if (!nodeGraph)
    return false;

  nodeGraph->lock();

  for (NodeGraph::iterator nodeIt = nodeGraph->begin(); nodeIt != nodeGraph->end(); nodeIt++) {
    Node *node = dynamic_cast<Node *>(*nodeIt);
    if (!node)
      continue;
    if (node->equals(this))
      continue;
    RemoteNode *remoteNode = new RemoteNode(node);
    remoteNode->setWeakFlag(false);
    nodes->addNode(remoteNode);
  }

  nodeGraph->unlock();

  return true;
}

////////////////////////////////////////////////
// Execution
////////////////////////////////////////////////

bool Round::LocalNode::setError(int rpcErrorCode, Error *err) {
  if (!err)
    return false;
  RPC::JSON::ErrorCodeToError(rpcErrorCode, err);
  return true;
}

bool Round::LocalNode::execMessage(const NodeRequest *nodeReq, NodeResponse *nodeRes, Error *error) {
  if (!nodeReq || !nodeRes || !error)
    return false;

  // Check dest

  if (!nodeReq->isDestValid()) {
    setError(RPC::JSON::ErrorCodeInvalidParams, error);
    return false;
  }

  bool isDestHash = nodeReq->isDestHash();
  if (isDestHash) {
    std::string nodeHash;
    if (nodeReq->getDest(&nodeHash)) {
      NodeGraph *nodeGraph = getNodeGraph();
      if (!nodeGraph->isHandleNode(this, nodeHash)) {
        setError(RPC::JSON::ErrorCodeMovedPermanently, error);
        return false;
      }
    }
  }

  // Update local clock

  clock_t remoteTs;
  if (nodeRes->getTimestamp(&remoteTs)) {
    setRemoteClock(remoteTs);
  }
  else {
    incrementLocalClock();
  }

  // Exec Method (One node)

  bool isDestOne = nodeReq->isDestOne();
  if (isDestOne) {
    return execMethod(nodeReq, nodeRes, error);
  }

  // Exec Method (Multi node)

  JSONArray *batchArray = new JSONArray();
  nodeRes->setResult(batchArray);

  Error thisNodeError;
  NodeResponse *thisNodeRes = new NodeResponse();
  execMethod(nodeReq, thisNodeRes, &thisNodeError);
  thisNodeRes->setDest(this);
  batchArray->add(thisNodeRes);

  NodeList otherNodes;
  if (nodeReq->isDestAll()) {
    getAllOtherNodes(&otherNodes);
  }
  else if (nodeReq->hasQuorum()) {
    size_t quorum;
    if (nodeReq->getQuorum(&quorum)) {
      getQuorumNodes(&otherNodes, quorum);
    }
  }
  for (NodeList::iterator node = otherNodes.begin(); node != otherNodes.end(); node++) {
    Error otherNodeError;
    NodeResponse *otherNodeRes = new NodeResponse();
    (*node)->postMessage(nodeReq, otherNodeRes, &otherNodeError);
    otherNodeRes->setDest((*node));
    batchArray->add(otherNodeRes);
  }

  return true;
}

bool Round::LocalNode::execMessage(const NodeBatchRequest *nodeBatchReq, NodeBatchResponse *nodeBatchRes, Error *error) {
  for (NodeBatchRequest::const_iterator jsonObj = nodeBatchReq->begin(); jsonObj != nodeBatchReq->end(); jsonObj++) {
    const NodeRequest *nodeReq = (dynamic_cast<NodeRequest *>(*jsonObj));
    if (!nodeReq)
      continue;
    NodeResponse *nodeRes = new NodeResponse();
    execMessage(nodeReq, nodeRes, error);
    nodeBatchRes->add(nodeRes);
  }
  return true;
}

////////////////////////////////////////////////
// Dynamic Method
////////////////////////////////////////////////

bool Round::LocalNode::isDynamicMethod(const std::string &method) {
  return this->scriptMgr.hasScript(method);
}

bool Round::LocalNode::execDynamicMethod(const NodeRequest *nodeReq, NodeResponse *nodeRes, Error *error) {
  std::string method;
  nodeReq->getMethod(&method);

  if (!this->scriptMgr.hasScript(method)) {
    RPC::JSON::ErrorCodeToError(RPC::JSON::ErrorCodeMethodNotFound, error);
    return false;
  }

  std::string params;
  nodeReq->getParams(&params);

  std::string result;
  bool isSuccess = this->scriptMgr.execMethod(method, params, &result, error);
  if (isSuccess) {
    nodeRes->setResult(result);
  }
  else {
    nodeRes->setError(error);
  }

  return isSuccess;
}

////////////////////////////////////////////////
// Static Method
////////////////////////////////////////////////

bool Round::LocalNode::isStaticMethod(const std::string &method) {
  return this->staticMethodMgr.hasMethod(method);
}

bool Round::LocalNode::execStaticMethod(const NodeRequest *nodeReq, NodeResponse *nodeRes, Error *error) {
  std::string reqMethod;
  nodeReq->getMethod(&reqMethod);

  if (!this->staticMethodMgr.hasMethod(reqMethod)) {
    RPC::JSON::ErrorCodeToError(RPC::JSON::ErrorCodeMethodNotFound, error);
    return false;
  }

  bool isSuccess = this->staticMethodMgr.exec(reqMethod, this, nodeReq, nodeRes);
  if (!isSuccess) {
    setError(RPC::JSON::ErrorCodeInvalidParams, error);
  }

  return isSuccess;
}

////////////////////////////////////////////////
// Native Method
////////////////////////////////////////////////

bool Round::LocalNode::isNativeMethod(const std::string &method) {
  return this->sysMethodMgr.hasMethod(method);
}

bool Round::LocalNode::execNativeMethod(const NodeRequest *nodeReq, NodeResponse *nodeRes, Error *error) {
  std::string reqMethod;
  nodeReq->getMethod(&reqMethod);

  if (!this->sysMethodMgr.hasMethod(reqMethod)) {
    RPC::JSON::ErrorCodeToError(RPC::JSON::ErrorCodeMethodNotFound, error);
    return false;
  }

  bool isSuccess = this->sysMethodMgr.exec(reqMethod, this, nodeReq, nodeRes);
  if (!isSuccess) {
    setError(RPC::JSON::ErrorCodeInvalidParams, error);
  }

  return isSuccess;
}

////////////////////////////////////////////////
// Alias Method
////////////////////////////////////////////////

bool Round::LocalNode::isAliasMethod(const std::string &method) {
  this->aliasMgr.lock();
  bool isAlias = this->aliasMgr.hasAlias(method);
  this->aliasMgr.unlock();
  return isAlias;
}

bool Round::LocalNode::execAliasMethod(const NodeRequest *aliasReq, NodeResponse *nodeRes, Error *error) {
  std::string reqMethod;
  aliasReq->getMethod(&reqMethod);

  this->aliasMgr.lock();

  Alias *alias = this->aliasMgr.findAlias(reqMethod);
  if (!alias) {
    this->aliasMgr.unlock();
    return false;
  }

  std::string sourceMethod;
  if (!alias->getObject(&sourceMethod)) {
    this->aliasMgr.unlock();
    return false;
  }

  std::string defaultParams;
  if (!alias->getDefaults(&defaultParams)) {
    this->aliasMgr.unlock();
    return false;
  }

  this->aliasMgr.unlock();

  NodeRequest nodeReq;
  nodeReq.setParamsWithDefault(aliasReq, defaultParams);
  nodeReq.setMethod(sourceMethod);

  return execMethod(&nodeReq, nodeRes, error);
}

////////////////////////////////////////////////
// Exce Method
////////////////////////////////////////////////

bool Round::LocalNode::execMethod(const NodeRequest *nodeReq, NodeResponse *nodeRes, Error *error) {
  // Set id and ts parameter

  size_t msgId;
  if (nodeReq->getId(&msgId)) {
    nodeRes->setId(msgId);
  }
  nodeRes->setTimestamp(getLocalClock());

  // Exec Message

  std::string name;
  if (!nodeReq->getMethod(&name) || (name.length() <= 0)) {
    setError(RPC::JSON::ErrorCodeMethodNotFound, error);
    return false;
  }

  bool isMethodExecuted = false;
  bool isMethodSuccess = false;

  if (isStaticMethod(name)) {
    isMethodExecuted = true;
    isMethodSuccess = execStaticMethod(nodeReq, nodeRes, error);
  }
  else if (isDynamicMethod(name)) {
    isMethodExecuted = true;
    isMethodSuccess = execDynamicMethod(nodeReq, nodeRes, error);
  }
  else if (isNativeMethod(name)) {
    isMethodExecuted = true;
    isMethodSuccess = execNativeMethod(nodeReq, nodeRes, error);
  }
  else if (isAliasMethod(name)) {
    isMethodExecuted = true;
    isMethodSuccess = execAliasMethod(nodeReq, nodeRes, error);
  }

  if (!isMethodExecuted) {
    setError(RPC::JSON::ErrorCodeMethodNotFound, error);
    return false;
  }

  if (!isMethodSuccess)
    return false;

  if (!hasRoute(name)) {
    return true;
  }

  NodeResponse routeNodeRes;
  if (!execRoute(name, nodeRes, &routeNodeRes, error)) {
    return false;
  }

  nodeRes->set(&routeNodeRes);

  return true;
}

////////////////////////////////////////////////
// Exec Route
////////////////////////////////////////////////

bool Round::LocalNode::hasRoute(const std::string &name) {
  bool hasRoute = this->routeMgr.hasRoute(name);
  return hasRoute;
}

bool Round::LocalNode::execRoute(const std::string &name, const NodeResponse *prevNodeRes, NodeResponse *nodeRes, Error *error) {
  RouteList *routeList = this->routeMgr.getRouteList(name);
  if (!routeList) {
    return false;
  }

  std::string params;
  prevNodeRes->getResult(&params);

  // Set prev response if all route types are event.
  nodeRes->setResult(params);

  bool isSuccess = true;

  for (RouteList::const_iterator routeIt = routeList->begin(); routeIt != routeList->end(); routeIt++) {
    Route *route = *routeIt;

    // TODO Check cluser.node too.
    std::string target;
    if (!route->getDestinationTarget(&target))
      continue;

    NodeRequest nodeReq;
    nodeReq.setMethod(target);
    nodeReq.setParams(params);

    if (route->isEvent()) {
      NodeResponse eventRes;
      if (!execMethod(&nodeReq, &eventRes, error)) {
        isSuccess = false;
      }
    }
    else if (route->isPipe()) {
      if (!execMethod(&nodeReq, nodeRes, error)) {
        isSuccess = false;
      }
    }
  }

  return isSuccess;
}

////////////////////////////////////////////////
// Exec Trigger
////////////////////////////////////////////////

bool Round::LocalNode::execTrigger(const std::string &name, Error *error) {
  return false;
}

max_stars_repo_name: cybergarage/round-cc

max_issues_repo_name: cybergarage/round-cc

max_forks_repo_name: cybergarage/round-cc


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

// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.

// 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)

#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_VINCENTY_HPP
#define BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_VINCENTY_HPP

#include <boost/math/constants/constants.hpp>

#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/math.hpp>

#include <boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp>

namespace boost { namespace geometry
{

namespace strategy { namespace distance
{

/*!
\brief Distance calculation formulae on latlong coordinates, after Vincenty, 1975
\ingroup distance
\tparam Point1 \tparam_first_point
\tparam Point2 \tparam_second_point
\tparam CalculationType \tparam_calculation
\author See http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
\author Adapted from various implementations to get it close to the original document
    - http://www.movable-type.co.uk/scripts/LatLongVincenty.html
    - http://exogen.case.edu/projects/geopy/source/geopy.distance.html
    - http://futureboy.homeip.net/fsp/colorize.fsp?fileName=navigation.frink

*/
template
<
    typename RadiusType,
    typename CalculationType = void
>
class vincenty
{
public :
    template <typename Point1, typename Point2>
    struct calculation_type
        : promote_floating_point
          <
              typename select_calculation_type
                  <
                      Point1,
                      Point2,
                      CalculationType
                  >::type
          >
    {};

    typedef RadiusType radius_type;

    inline vincenty()
    {}

    explicit inline vincenty(geometry::detail::ellipsoid<RadiusType> const& e)
        : m_ellipsoid(e)
    {}

    template <typename Point1, typename Point2>
    inline typename calculation_type<Point1, Point2>::type
    apply(Point1 const& point1, Point2 const& point2) const
    {
        return calculate<typename calculation_type<Point1, Point2>::type>
            (
                get_as_radian<0>(point1), get_as_radian<1>(point1),
                get_as_radian<0>(point2), get_as_radian<1>(point2)
            );
    }

    inline geometry::detail::ellipsoid<RadiusType> ellipsoid() const
    {
        return m_ellipsoid;
    }

    inline RadiusType radius() const
    {
        // For now return the major axis. It is used in distance_cross_track, from point-to-line
        return m_ellipsoid.a();
    }

private :
    geometry::detail::ellipsoid<RadiusType> m_ellipsoid;

    template <typename CT, typename T>
    inline CT calculate(T const& lon1,
                T const& lat1,
                T const& lon2,
                T const& lat2) const
    {
        CT const c2 = 2;
        CT const pi = geometry::math::pi<CT>();
        CT const two_pi = c2 * pi;

        // lambda: difference in longitude on an auxiliary sphere
        CT L = lon2 - lon1;
        CT lambda = L;

        if (L < -pi) L += two_pi;
        if (L > pi) L -= two_pi;

        if (math::equals(lat1, lat2) && math::equals(lon1, lon2))
        {
            return CT(0);
        }

        // U: reduced latitude, defined by tan U = (1-f) tan phi
        CT const c1 = 1;
        CT const one_min_f = c1 - m_ellipsoid.f();

        CT const U1 = atan(one_min_f * tan(lat1)); // above (1)
        CT const U2 = atan(one_min_f * tan(lat2)); // above (1)

        CT const cos_U1 = cos(U1);
        CT const cos_U2 = cos(U2);
        CT const sin_U1 = sin(U1);
        CT const sin_U2 = sin(U2);

        // alpha: azimuth of the geodesic at the equator
        CT cos2_alpha;
        CT sin_alpha;

        // sigma: angular distance p1,p2 on the sphere
        // sigma1: angular distance on the sphere from the equator to p1
        // sigma_m: angular distance on the sphere from the equator to the midpoint of the line
        CT sigma;
        CT sin_sigma;
        CT cos2_sigma_m;

        CT previous_lambda;

        CT const c3 = 3;
        CT const c4 = 4;
        CT const c6 = 6;
        CT const c16 = 16;

        CT const c_e_12 = 1e-12;

        do
        {
            previous_lambda = lambda; // (13)
            CT sin_lambda = sin(lambda);
            CT cos_lambda = cos(lambda);
            sin_sigma = sqrt(math::sqr(cos_U2 * sin_lambda) + math::sqr(cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda)); // (14)
            CT cos_sigma = sin_U1 * sin_U2 + cos_U1 * cos_U2 * cos_lambda; // (15)
            sin_alpha = cos_U1 * cos_U2 * sin_lambda / sin_sigma; // (17)
            cos2_alpha = c1 - math::sqr(sin_alpha);
            cos2_sigma_m = math::equals(cos2_alpha, 0) ? 0 : cos_sigma - c2 * sin_U1 * sin_U2 / cos2_alpha; // (18)

            CT C = m_ellipsoid.f()/c16 * cos2_alpha * (c4 + m_ellipsoid.f() * (c4 - c3 * cos2_alpha)); // (10)
            sigma = atan2(sin_sigma, cos_sigma); // (16)
            lambda = L + (c1 - C) * m_ellipsoid.f() * sin_alpha *
                (sigma + C * sin_sigma * ( cos2_sigma_m + C * cos_sigma * (-c1 + c2 * math::sqr(cos2_sigma_m)))); // (11)

        } while (geometry::math::abs(previous_lambda - lambda) > c_e_12
                && geometry::math::abs(lambda) < pi);

        CT sqr_u = cos2_alpha * (math::sqr(m_ellipsoid.a()) - math::sqr(m_ellipsoid.b())) / math::sqr(m_ellipsoid.b()); // above (1)

        // Oops getting hard here
        // (again, problem is that ttmath cannot divide by doubles, which is OK)
        CT const c47 = 47;
        CT const c74 = 74;
        CT const c128 = 128;
        CT const c256 = 256;
        CT const c175 = 175;
        CT const c320 = 320;
        CT const c768 = 768;
        CT const c1024 = 1024;
        CT const c4096 = 4096;
        CT const c16384 = 16384;

        CT A = c1 + sqr_u/c16384 * (c4096 + sqr_u * (-c768 + sqr_u * (c320 - c175 * sqr_u))); // (3)
        CT B = sqr_u/c1024 * (c256 + sqr_u * ( -c128 + sqr_u * (c74 - c47 * sqr_u))); // (4)
        CT delta_sigma = B * sin_sigma * ( cos2_sigma_m + (B/c4) * (cos(sigma)* (-c1 + c2 * cos2_sigma_m)
                - (B/c6) * cos2_sigma_m * (-c3 + c4 * math::sqr(sin_sigma)) * (-c3 + c4 * cos2_sigma_m))); // (6)

        return m_ellipsoid.b() * A * (sigma - delta_sigma); // (19)
    }
};

#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{

template <typename RadiusType, typename CalculationType>
struct tag<vincenty<RadiusType, CalculationType> >
{
    typedef strategy_tag_distance_point_point type;
};

template <typename RadiusType, typename CalculationType, typename P1, typename P2>
struct return_type<vincenty<RadiusType, CalculationType>, P1, P2>
    : vincenty<RadiusType, CalculationType>::template calculation_type<P1, P2>
{};

template <typename RadiusType, typename CalculationType>
struct comparable_type<vincenty<RadiusType, CalculationType> >
{
    typedef vincenty<RadiusType, CalculationType> type;
};

template <typename RadiusType, typename CalculationType>
struct get_comparable<vincenty<RadiusType, CalculationType> >
{
    static inline vincenty<RadiusType, CalculationType> apply(vincenty<RadiusType, CalculationType> const& input)
    {
        return input;
    }
};

template <typename RadiusType, typename CalculationType, typename P1, typename P2>
struct result_from_distance<vincenty<RadiusType, CalculationType>, P1, P2 >
{
    template <typename T>
    static inline typename return_type<vincenty<RadiusType, CalculationType>, P1, P2>::type
        apply(vincenty<RadiusType, CalculationType> const& , T const& value)
    {
        return value;
    }
};

} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS

// We might add a vincenty-like strategy also for point-segment distance, but to calculate the projected point is not trivial

}} // namespace strategy::distance

}} // namespace boost::geometry

#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_VINCENTY_HPP

max_stars_repo_name: ballisticwhisper/boost

max_issues_repo_name: ballisticwhisper/boost

max_forks_repo_name: ballisticwhisper/boost


text:
#pragma once

//#include <ADEKF/ceres/jet.h>
#include "ADEKFUtils.h"
#include "ADEKF.h"

#include <iostream>
#include <Eigen/Core>
#include <vector>

namespace adekf
{

    //using namespace Eigen;
    //using namespace std::placeholders;

    /**
     * An RTS Smoother Implementation based on the ADEKF
     * @tparam Filter The Filter to be used for estimation
     */
    template <typename State>
    class Naive_RTS_Smoother : public ADEKF<State>
    {

    public:
        using Covariance = typename ADEKF<State>::Covariance;
        using ScalarType = typename ADEKF<State>::ScalarType;
        static constexpr size_t DOF = DOFOf<State>;
        static constexpr double weighted_mean_epsilon = 1e-8;
        aligned_vector<State> old_mus,smoothed_mus, predicted_mus;
        aligned_vector<Covariance> old_sigmas,smoothed_sigmas,predicted_sigmas;

        Naive_RTS_Smoother(const State &_mu, const Covariance &_sigma) : ADEKF<State>(_mu, _sigma) { storeEstimation(); storePredictedEstimation(); }
        Naive_RTS_Smoother(const ADEKF<State> &filter) : ADEKF<State>(filter) { storeEstimation();storePredictedEstimation(); }
        /**
         * Stores the current mean and covariance of the filter
         */
        void storeEstimation()
        {
            old_mus.push_back(this->mu);
            smoothed_mus.push_back(this->mu);
            old_sigmas.push_back(this->sigma);
            smoothed_sigmas.push_back(this->sigma);
        }

         void storePredictedEstimation()
        {
            predicted_mus.push_back(this->mu);
            predicted_sigmas.push_back(this->sigma);
        }
        template <typename Head, typename... Tail>
        std::tuple<Tail...> tuple_tail(const std::tuple<Head, Tail...> &tuple)
        {
            return apply([](auto head, auto... tail) {
                return std::make_tuple(tail...);
            },
                         tuple);
        }

        template <typename DynamicModel, typename tstate, typename NoiseVector, typename... Controls, typename... ExpandedControls>
        void applyDynamicModel(DynamicModel dynamicModel, tstate &input, const NoiseVector &noise, const std::tuple<Controls...> &controls, const ExpandedControls& ...  expanded_controls)
        {
             if constexpr(std::tuple_size<std::tuple<Controls ...>>::value > 0)
            {
                applyDynamicModel(dynamicModel, input, noise, tuple_tail(controls), expanded_controls..., std::get<0>(controls));
            }
            else
            {
                dynamicModel(input, noise, expanded_controls...);
            }
        }

        template <int NoiseDim, typename DynamicModel, typename... Controls>
        Covariance getNonAdditiveDynamicNoise(const State &smoothed, DynamicModel dynamicModel, const SquareMatrixType<double,NoiseDim> &Q, const std::tuple<Controls...> &controls)
        {
            auto derivator = adekf::getDerivator<DOF + NoiseDim>();
            auto input = eval(smoothed + derivator.template head<DOF>());
            //Todo u vernünftig machen
            applyDynamicModel(dynamicModel, input, derivator.template tail<NoiseDim>(), controls);
            auto result = (input - smoothed);
            //std::cout << result << std::endl;
            MatrixType<double, DOF, DOF + NoiseDim> F(DOF, DOF + NoiseDim);
            //Eigen::Matrix<double,DOF,1> diff;
            for (size_t j = 0; j < DOF; ++j)
            {
                F.row(j) = result(j).v;
                //diff(j)=result(j).a;
            }
            return eval(F.template rightCols<NoiseDim>() * Q * F.template rightCols<NoiseDim>().transpose());
        }

static inline size_t indefinite_counter=0;
        template <int NoiseDim, typename DynamicModel, typename... Controls>
        void smoothSingleStep(size_t k, DynamicModel & dynamicModel, const Eigen::Matrix<double,NoiseDim,NoiseDim> &Q,const std::tuple<Controls ...> & controls,const State & smoothed_mu_kplus,const Covariance & smoothed_sigma_kplus){
                MatrixType<ScalarType,DOF, DOF> Fk(DOF, DOF);
                Covariance SmootherGain;

                auto derivator = adekf::getDerivator<DOF>();
                auto input = eval(old_mus[k] + derivator);
                applyDynamicModel(dynamicModel,input,MatrixType<ScalarType,NoiseDim, 1>::Zero(), controls);
                auto result1 = eval(input - predicted_mus[k+1]);
                MatrixType<ScalarOf(this->mu),DOF, 1> diff1;

                for (size_t j = 0; j < DOF; ++j)
                {
                    Fk.row(j) = result1(j).v;
                    diff1(j) = result1(j).a;
                }

                SmootherGain = old_sigmas[k] * Fk.transpose() * (predicted_sigmas[k+1].inverse());
                smoothed_mus[k] = old_mus[k] + (SmootherGain * (smoothed_mu_kplus- predicted_mus[k+1]));
                smoothed_sigmas[k] = (old_sigmas[k] + SmootherGain *(smoothed_sigma_kplus- predicted_sigmas[k+1]) * SmootherGain.transpose());
                if(!isPositiveDefinite(smoothed_sigmas[k]))
                indefinite_counter++;
                assurePositiveDefinite(smoothed_sigmas[k]);
        }

        template <int NoiseDim, typename DynamicModel, typename... Controls>
        void smoothIntervalWithNonAdditiveNoise(size_t steps, int start, DynamicModel & dynamicModel, const Eigen::Matrix<double,NoiseDim,NoiseDim> &Q, const std::vector<std::tuple<Controls...>> &all_controls)
        {
            if (start < 0)
            {
                start = old_mus.size() - 1 + start;
            }
            assert(start - steps >= 0 && "Can not smooth more estimates than available");
            assert(start < old_mus.size() - 1 && "Can not smooth a state which belongs to future");
            assert(all_controls.size() == old_mus.size() - 1 && "Requires all control inputs for the dynamic model.");
            for (size_t k = start; k >= old_mus.size() - steps - 1; k--)
            {
                //std::cout << "At iteration: " << k << std::endl;
                smoothSingleStep(k,dynamicModel,Q,all_controls[k],smoothed_mus[k+1], smoothed_sigmas[k+1]);

            }
        }

        template <int NoiseDim, typename DynamicModel, typename... Controls>
        void smoothAllWithNonAdditiveNoise(DynamicModel & dynamicModel, const Eigen::Matrix<double,NoiseDim,NoiseDim> &Q, const std::vector<std::tuple<Controls...>> &all_controls)
        {
            smoothIntervalWithNonAdditiveNoise(old_mus.size() - 2, -1, dynamicModel, Q, all_controls);
        }
    };

    /**
     * General Deduction Template for the Naive_RTS_Smoother based on StateRetriever.
     * This is needed so you can type Naive_RTS_Smoother smoother(Filter{...}) without template arguments
     */
    /*template <typename State>
    Naive_RTS_Smoother(ADEKF<State> &&) -> Naive_RTS_Smoother<State>;
    template <typename State>
    Naive_RTS_Smoother(ADEKF<State> ) -> Naive_RTS_Smoother<State>;
*/

} // namespace adekf

max_stars_repo_name: TomLKoller/Manifold-RTS-Smoother

max_issues_repo_name: TomLKoller/Manifold-RTS-Smoother

max_forks_repo_name: TomLKoller/Manifold-RTS-Smoother