text:
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).

//------------------------------------------------------------------------------
//
// This example implements interfaces.
//
// Detailed description
// ====================
//
// An interface is a collection of member function prototypes that may be
// implemented by classes. Objects of classes that implement the interface can
// then be assigned to an interface variable through which the interface's
// functions can be called.
//
// Interfaces are a feature of the Java programming language [Gosling] and the
// most obvious way to model interfaces in C++ is (multiple) inheritance.
// Using inheritance for this purpose, however, is neither the most efficient
// nor the most flexible solution, because:
//
//   - all functions must be virtual,
//
//     => a function that calls another function of the interface must do so
//        via virtual dispatch (as opposed to inlining)
//     => a class can not implement an interface's (overloaded) function via
//        a function template
//
//   - inhertitance is intrusive
//
//     => object size increases
//     => client's are always polymorphic
//     => dependencies cause tighter coupling
//
// Fortunately it is possible to eliminate all the drawbacks mentioned above
// based on an alternative implementation proposed by David Abrahams.
// We'll add some detail to the original scheme (see [Abrahams]) such as
// support for overloaded and const qualified functions.
// The implementation in this example uses Boost.FunctionTypes to shift
// metaprogramming code from the preprocessor into templates, to reduce
// preprocessing time and increase maintainability.
//
//
// Limitations
// ===========
//
// There is no lifetime management as implemented by the Boost candidate
// Interfaces library (see [Turkanis]).
//
// This example does not compile with Visual C++. Template argument deduction
// from the result of the address-of operator does not work properly with this
// compiler. It is possible to partially work around the problem, but it isn't
// done here for the sake of readability.
//
//
// Bibliography
// ============
//
// [Gosling]  Gosling, J., Joy, B., Steele, G. The Java Language Specification
//   http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html
//
// [Abrahams] Abrahams, D. Proposal: interfaces, Post to newsgroup comp.std.c++
//   http://groups.google.com/group/comp.std.c++/msg/85af30a61bf677e4
//
// [Turkanis] Turkanis, J., Diggins, C. Boost candidate Interfaces library
//   http://www.kangaroologic.com/interfaces/libs/interfaces/doc/index.html

#include <cstddef>

#include <boost/function_types/function_pointer.hpp>
#include <boost/function_types/member_function_pointer.hpp>

#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>

#include <boost/utility/addressof.hpp>

#include <boost/mpl/at.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/single_view.hpp>
#include <boost/mpl/transform_view.hpp>

#include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <boost/preprocessor/facilities/identity.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>

#include "detail/param_type.hpp"

namespace example
{
  namespace ft = boost::function_types;
  namespace mpl = boost::mpl;
  using namespace mpl::placeholders;

  // join a single type and an MPL-sequence
  // in some ways similar to mpl::push_front (but mpl::push_front requires
  // an MPL Extensible Sequence and this template does not)
  template<typename T, typename Seq>
  struct concat_view
    : mpl::joint_view<mpl::single_view<T>, Seq>
  { };

  // metafunction returning a function pointer type for a vtable entry
  template<typename Inf>
  struct vtable_entry
    : ft::function_pointer
      < concat_view< typename Inf::result, mpl::transform_view<
            typename Inf::params, param_type<_> > > >
  { };

  // the expression '& member<MetaInfo,Tag>::wrap<& Class::Function> ' in an
  // assignment context binds the member function Function of Class with the
  // properties described by MetaInfo and Tag to the corresponding vtable
  // entry
  template<typename Inf, typename Tag>
  struct member
  {
    typedef typename ft::member_function_pointer
      < concat_view<typename Inf::result,typename Inf::params>,Tag
      >::type
    mem_func_ptr;

    typedef typename mpl::at_c<typename Inf::params,0>::type context;

    template<mem_func_ptr MemFuncPtr>
    static typename Inf::result wrap(void* c)
    {
      return (reinterpret_cast<context*>(c)->*MemFuncPtr)();
    }
    template<mem_func_ptr MemFuncPtr, typename T0>
    static typename Inf::result wrap(void* c, T0 a0)
    {
      return (reinterpret_cast<context*>(c)->*MemFuncPtr)(a0);
    }
    template<mem_func_ptr MemFuncPtr, typename T0, typename T1>
    static typename Inf::result wrap(void* c, T0 a0, T1 a1)
    {
      return (reinterpret_cast<context*>(c)->*MemFuncPtr)(a0,a1);
    }
    // continue with the preprocessor (the scheme should be clear, by now)
    #define  BOOST_PP_LOCAL_MACRO(n)                                           \
    template<mem_func_ptr MemFuncPtr, BOOST_PP_ENUM_PARAMS(n,typename T)>      \
    static typename Inf::result wrap(void* c,                                  \
        BOOST_PP_ENUM_BINARY_PARAMS(n,T,a))                                    \
    {                                                                          \
      return (reinterpret_cast<context*>(c)->*MemFuncPtr)(                     \
        BOOST_PP_ENUM_PARAMS(n,a) );                                           \
    }
    #define  BOOST_PP_LOCAL_LIMITS (3,BOOST_FT_MAX_ARITY-1)
    #include BOOST_PP_LOCAL_ITERATE()
  };

  // extract a parameter by index
  template<typename Inf, std::size_t Index>
  struct param
    : param_type< typename mpl::at_c< typename Inf::params,Index>::type >
  { };
}

// the interface definition on the client's side
#define BOOST_EXAMPLE_INTERFACE(name,def)                                      \
    class name                                                                 \
    {                                                                          \
      struct vtable                                                            \
      {                                                                        \
        BOOST_EXAMPLE_INTERFACE__MEMBERS(def,VTABLE)                           \
      };                                                                       \
                                                                               \
      vtable const * ptr_vtable;                                               \
      void * ptr_that;                                                         \
                                                                               \
      template<class T> struct vtable_holder                                   \
      {                                                                        \
        static vtable const val_vtable;                                        \
      };                                                                       \
                                                                               \
    public:                                                                    \
                                                                               \
      template<class T>                                                        \
      inline name (T & that)                                                   \
        : ptr_vtable(& vtable_holder<T>::val_vtable)                           \
        , ptr_that(boost::addressof(that))                                     \
      { }                                                                      \
                                                                               \
      BOOST_EXAMPLE_INTERFACE__MEMBERS(def,FUNCTION)                           \
    };                                                                         \
                                                                               \
    template<typename T>                                                       \
    name ::vtable const name ::vtable_holder<T>::val_vtable                    \
        = { BOOST_EXAMPLE_INTERFACE__MEMBERS(def,INIT_VTABLE) }

#ifdef BOOST_PP_NIL // never defined -- a comment with syntax highlighting

BOOST_EXAMPLE_INTERFACE( interface_x,
  (( a_func, (void)(int), const_qualified ))
  (( another_func, (int), non_const   ))
);

// expands to:
class interface_x
{
  struct vtable
  {
    // meta information for first function
    template<typename T = void*> struct inf0
    {
      typedef void result;
      typedef ::boost::mpl::vector< T, int > params;
    };
    // function pointer with void* context pointer and parameters optimized
    // for forwarding
    ::example::vtable_entry<inf0<> >::type func0;

    // second function
    template<typename T = void*> struct inf1
    {
      typedef int result;
      typedef ::boost::mpl::vector< T > params;
    };
    ::example::vtable_entry<inf1<> >::type func1;
  };

  // data members
  vtable const * ptr_vtable;
  void * ptr_that;

  // this template is instantiated for every class T this interface is created
  // from, causing the compiler to emit an initialized vtable for this type
  // (see aggregate assignment, below)
  template<class T> struct vtable_holder
  {
    static vtable const val_vtable;
  };

public:

  // converting ctor, creates an interface from an arbitrary class
  template<class T>
  inline interface_x (T & that)
    : ptr_vtable(& vtable_holder<T>::val_vtable)
    , ptr_that(boost::addressof(that))
  { }

  // the member functions from the interface definition, parameters are
  // optimized for forwarding

  inline vtable::inf0<> ::result a_func (
      ::example::param<vtable::inf0<>,1>::type p0) const
  {
    return ptr_vtable-> func0(ptr_that , p0);
  }

  inline vtable::inf1<> ::result another_func ()
  {
    return ptr_vtable-> func1(ptr_that );
  }
};

template<typename T>
interface_x ::vtable const interface_x ::vtable_holder<T>::val_vtable =
{
  // instantiate function templates that wrap member function pointers (which
  // are known at compile time) by taking their addresses in assignment to
  // function pointer context
  & ::example::member< vtable::inf0<T>, ::example::ft:: const_qualified >
        ::template wrap < &T:: a_func >
, & ::example::member< vtable::inf1<T>, ::example::ft:: non_const >
        ::template wrap < &T:: another_func >
};
#endif

// preprocessing code details

// iterate all of the interface's members and invoke a macro (prefixed with
// BOOST_EXAMPLE_INTERFACE_)
#define BOOST_EXAMPLE_INTERFACE__MEMBERS(seq,macro)                            \
    BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq),                                    \
        BOOST_EXAMPLE_INTERFACE__ ## macro,seq)

// extract signature sequence from entry
#define BOOST_EXAMPLE_INTERFACE__VTABLE(z,i,seq)                               \
    BOOST_EXAMPLE_INTERFACE__VTABLE_I(z,i,                                     \
        BOOST_PP_TUPLE_ELEM(3,1,BOOST_PP_SEQ_ELEM(i,seq)))

// split the signature sequence result/params and insert T at the beginning of
// the params part
#define BOOST_EXAMPLE_INTERFACE__VTABLE_I(z,i,seq)                             \
    BOOST_EXAMPLE_INTERFACE__VTABLE_II(z,i,                                    \
        BOOST_PP_SEQ_HEAD(seq),(T)BOOST_PP_SEQ_TAIL(seq))

// emit the meta information structure and function pointer declaration
#define BOOST_EXAMPLE_INTERFACE__VTABLE_II(z,i,result_type,param_types)        \
    template<typename T = void*>                                               \
    struct BOOST_PP_CAT(inf,i)                                                 \
    {                                                                          \
      typedef result_type result;                                              \
      typedef ::boost::mpl::vector< BOOST_PP_SEQ_ENUM(param_types) > params;   \
    };                                                                         \
    ::example::vtable_entry<BOOST_PP_CAT(inf,i)<> >::type BOOST_PP_CAT(func,i);

// extract tuple entry from sequence and precalculate the name of the function
// pointer variable
#define BOOST_EXAMPLE_INTERFACE__INIT_VTABLE(z,i,seq)                          \
    BOOST_EXAMPLE_INTERFACE__INIT_VTABLE_I(i,seq,BOOST_PP_CAT(func,i),         \
        BOOST_PP_SEQ_ELEM(i,seq))

// emit a function pointer expression that encapsulates the corresponding
// member function of T
#define BOOST_EXAMPLE_INTERFACE__INIT_VTABLE_I(i,seq,func,desc)                \
    BOOST_PP_COMMA_IF(i) & ::example::member< BOOST_PP_CAT(vtable::inf,i)<T>,  \
        ::example::ft:: BOOST_PP_TUPLE_ELEM(3,2,desc) >::template wrap         \
                                          < &T:: BOOST_PP_TUPLE_ELEM(3,0,desc) >

// extract tuple entry from sequence
#define BOOST_EXAMPLE_INTERFACE__FUNCTION(z,i,seq)                             \
    BOOST_EXAMPLE_INTERFACE__FUNCTION_I(z,i,BOOST_PP_SEQ_ELEM(i,seq))

// precalculate function name, arity, name of meta info structure and cv-
// qualifiers
#define BOOST_EXAMPLE_INTERFACE__FUNCTION_I(z,i,desc)                          \
    BOOST_EXAMPLE_INTERFACE__FUNCTION_II(z,i,                                  \
        BOOST_PP_TUPLE_ELEM(3,0,desc),                                         \
        BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_PP_TUPLE_ELEM(3,1,desc))),        \
        BOOST_PP_CAT(vtable::inf,i)<>,                                         \
        BOOST_PP_CAT(BOOST_EXAMPLE_INTERFACE___,BOOST_PP_TUPLE_ELEM(3,2,desc)) \
    )

// emit the definition for a member function of the interface
#define BOOST_EXAMPLE_INTERFACE__FUNCTION_II(z,i,name,arity,types,cv)          \
    inline types ::result name                                                 \
      (BOOST_PP_ENUM_ ## z (arity,BOOST_EXAMPLE_INTERFACE__PARAM,types)) cv()  \
    {                                                                          \
      return ptr_vtable-> BOOST_PP_CAT(func,i)(ptr_that                        \
          BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,arity,p));                         \
    }

// emit a parameter of the function definition
#define BOOST_EXAMPLE_INTERFACE__PARAM(z,j,types)                              \
    ::example::param<types,BOOST_PP_INC(j)>::type BOOST_PP_CAT(p,j)

// helper macros to map 'const_qualified' to 'const' an 'non_const' to ''
#define BOOST_EXAMPLE_INTERFACE___const_qualified BOOST_PP_IDENTITY(const)
#define BOOST_EXAMPLE_INTERFACE___non_const BOOST_PP_EMPTY

max_stars_repo_name: randolphwong/mcsema

max_issues_repo_name: randolphwong/mcsema

max_forks_repo_name: randolphwong/mcsema


text:
//            Copyright (c) Glyn Matthews 2011.
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)

#include <iostream>
#include <boost/network/uri.hpp>
#include <boost/network/uri/uri_io.hpp>

using namespace boost::network;

int main(int argc, char *argv[]) {

  uri::uri url;
  url << uri::scheme("http") << uri::host("www.github.com")
      << uri::path("/cpp-netlib");
  std::cout << url << std::endl;

  return 0;
}

ext: cpp

max_stars_repo_name: yhager/cpp-netlib

max_issues_repo_name: yhager/cpp-netlib

max_forks_repo_name: yhager/cpp-netlib


text:
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#include "util/runtime_profile.h"

#include <gtest/gtest.h>
#include <stdio.h>
#include <stdlib.h>

#include <boost/bind.hpp>
#include <iostream>

#include "common/object_pool.h"
#include "util/cpu_info.h"

using namespace std;
using namespace boost;

namespace impala {

TEST(CountersTest, Basic) {
    ObjectPool pool;
    RuntimeProfile profile_a(&pool, "ProfileA");
    RuntimeProfile profile_a1(&pool, "ProfileA1");
    RuntimeProfile profile_a2(&pool, "ProfileAb");

    TRuntimeProfileTree thrift_profile;

    profile_a.AddChild(&profile_a1);
    profile_a.AddChild(&profile_a2);

    // Test Empty
    profile_a.ToThrift(&thrift_profile.nodes);
    EXPECT_EQ(thrift_profile.nodes.size(), 3);
    thrift_profile.nodes.clear();

    RuntimeProfile::Counter* counter_a;
    RuntimeProfile::Counter* counter_b;
    RuntimeProfile::Counter* counter_merged;

    // Updating/setting counter
    counter_a = profile_a.AddCounter("A", TCounterType::UNIT);
    EXPECT_TRUE(counter_a != NULL);
    counter_a->Update(10);
    counter_a->Update(-5);
    EXPECT_EQ(counter_a->value(), 5);
    counter_a->Set(1L);
    EXPECT_EQ(counter_a->value(), 1);

    counter_b = profile_a2.AddCounter("B", TCounterType::BYTES);
    EXPECT_TRUE(counter_b != NULL);

    // Serialize/deserialize
    profile_a.ToThrift(&thrift_profile.nodes);
    RuntimeProfile* from_thrift = RuntimeProfile::CreateFromThrift(&pool, thrift_profile);
    counter_merged = from_thrift->GetCounter("A");
    EXPECT_EQ(counter_merged->value(), 1);
    EXPECT_TRUE(from_thrift->GetCounter("Not there") == NULL);

    // Merge
    RuntimeProfile merged_profile(&pool, "Merged");
    merged_profile.Merge(from_thrift);
    counter_merged = merged_profile.GetCounter("A");
    EXPECT_EQ(counter_merged->value(), 1);

    // Merge 2 more times, counters should get aggregated
    merged_profile.Merge(from_thrift);
    merged_profile.Merge(from_thrift);
    EXPECT_EQ(counter_merged->value(), 3);

    // Update
    RuntimeProfile updated_profile(&pool, "Updated");
    updated_profile.Update(thrift_profile);
    RuntimeProfile::Counter* counter_updated = updated_profile.GetCounter("A");
    EXPECT_EQ(counter_updated->value(), 1);

    // Update 2 more times, counters should stay the same
    updated_profile.Update(thrift_profile);
    updated_profile.Update(thrift_profile);
    EXPECT_EQ(counter_updated->value(), 1);
}

void ValidateCounter(RuntimeProfile* profile, const string& name, int64_t value) {
    RuntimeProfile::Counter* counter = profile->GetCounter(name);
    EXPECT_TRUE(counter != NULL);
    EXPECT_EQ(counter->value(), value);
}

TEST(CountersTest, MergeAndUpdate) {
    // Create two trees.  Each tree has two children, one of which has the
    // same name in both trees.  Merging the two trees should result in 3
    // children, with the counters from the shared child aggregated.

    ObjectPool pool;
    RuntimeProfile profile1(&pool, "Parent1");
    RuntimeProfile p1_child1(&pool, "Child1");
    RuntimeProfile p1_child2(&pool, "Child2");
    profile1.AddChild(&p1_child1);
    profile1.AddChild(&p1_child2);

    RuntimeProfile profile2(&pool, "Parent2");
    RuntimeProfile p2_child1(&pool, "Child1");
    RuntimeProfile p2_child3(&pool, "Child3");
    profile2.AddChild(&p2_child1);
    profile2.AddChild(&p2_child3);

    // Create parent level counters
    RuntimeProfile::Counter* parent1_shared =
            profile1.AddCounter("Parent Shared", TCounterType::UNIT);
    RuntimeProfile::Counter* parent2_shared =
            profile2.AddCounter("Parent Shared", TCounterType::UNIT);
    RuntimeProfile::Counter* parent1_only =
            profile1.AddCounter("Parent 1 Only", TCounterType::UNIT);
    RuntimeProfile::Counter* parent2_only =
            profile2.AddCounter("Parent 2 Only", TCounterType::UNIT);
    parent1_shared->Update(1);
    parent2_shared->Update(3);
    parent1_only->Update(2);
    parent2_only->Update(5);

    // Create child level counters
    RuntimeProfile::Counter* p1_c1_shared =
            p1_child1.AddCounter("Child1 Shared", TCounterType::UNIT);
    RuntimeProfile::Counter* p1_c1_only =
            p1_child1.AddCounter("Child1 Parent 1 Only", TCounterType::UNIT);
    RuntimeProfile::Counter* p1_c2 = p1_child2.AddCounter("Child2", TCounterType::UNIT);
    RuntimeProfile::Counter* p2_c1_shared =
            p2_child1.AddCounter("Child1 Shared", TCounterType::UNIT);
    RuntimeProfile::Counter* p2_c1_only =
            p1_child1.AddCounter("Child1 Parent 2 Only", TCounterType::UNIT);
    RuntimeProfile::Counter* p2_c3 = p2_child3.AddCounter("Child3", TCounterType::UNIT);
    p1_c1_shared->Update(10);
    p1_c1_only->Update(50);
    p2_c1_shared->Update(20);
    p2_c1_only->Update(100);
    p2_c3->Update(30);
    p1_c2->Update(40);

    // Merge the two and validate
    TRuntimeProfileTree tprofile1;
    profile1.ToThrift(&tprofile1);
    RuntimeProfile* merged_profile = RuntimeProfile::CreateFromThrift(&pool, tprofile1);
    merged_profile->Merge(&profile2);
    EXPECT_EQ(4, merged_profile->num_counters());
    ValidateCounter(merged_profile, "Parent Shared", 4);
    ValidateCounter(merged_profile, "Parent 1 Only", 2);
    ValidateCounter(merged_profile, "Parent 2 Only", 5);

    std::vector<RuntimeProfile*> children;
    merged_profile->GetChildren(&children);
    EXPECT_EQ(children.size(), 3);

    for (int i = 0; i < 3; ++i) {
        RuntimeProfile* profile = children[i];

        if (profile->name().compare("Child1") == 0) {
            EXPECT_EQ(4, profile->num_counters());
            ValidateCounter(profile, "Child1 Shared", 30);
            ValidateCounter(profile, "Child1 Parent 1 Only", 50);
            ValidateCounter(profile, "Child1 Parent 2 Only", 100);
        } else if (profile->name().compare("Child2") == 0) {
            EXPECT_EQ(2, profile->num_counters());
            ValidateCounter(profile, "Child2", 40);
        } else if (profile->name().compare("Child3") == 0) {
            EXPECT_EQ(2, profile->num_counters());
            ValidateCounter(profile, "Child3", 30);
        } else {
            EXPECT_TRUE(false);
        }
    }

    // make sure we can print
    std::stringstream dummy;
    merged_profile->PrettyPrint(&dummy);

    // Update profile2 w/ profile1 and validate
    profile2.Update(tprofile1);
    EXPECT_EQ(4, profile2.num_counters());
    ValidateCounter(&profile2, "Parent Shared", 1);
    ValidateCounter(&profile2, "Parent 1 Only", 2);
    ValidateCounter(&profile2, "Parent 2 Only", 5);

    profile2.GetChildren(&children);
    EXPECT_EQ(children.size(), 3);

    for (int i = 0; i < 3; ++i) {
        RuntimeProfile* profile = children[i];

        if (profile->name().compare("Child1") == 0) {
            EXPECT_EQ(4, profile->num_counters());
            ValidateCounter(profile, "Child1 Shared", 10);
            ValidateCounter(profile, "Child1 Parent 1 Only", 50);
            ValidateCounter(profile, "Child1 Parent 2 Only", 100);
        } else if (profile->name().compare("Child2") == 0) {
            EXPECT_EQ(2, profile->num_counters());
            ValidateCounter(profile, "Child2", 40);
        } else if (profile->name().compare("Child3") == 0) {
            EXPECT_EQ(2, profile->num_counters());
            ValidateCounter(profile, "Child3", 30);
        } else {
            EXPECT_TRUE(false);
        }
    }

    // make sure we can print
    profile2.PrettyPrint(&dummy);
}

TEST(CountersTest, DerivedCounters) {
    ObjectPool pool;
    RuntimeProfile profile(&pool, "Profile");
    RuntimeProfile::Counter* bytes_counter = profile.AddCounter("bytes", TCounterType::BYTES);
    RuntimeProfile::Counter* ticks_counter = profile.AddCounter("ticks", TCounterType::TIME_NS);
    // set to 1 sec
    ticks_counter->Set(1000L * 1000L * 1000L);

    RuntimeProfile::DerivedCounter* throughput_counter = profile.AddDerivedCounter(
            "throughput", TCounterType::BYTES,
            bind<int64_t>(&RuntimeProfile::UnitsPerSecond, bytes_counter, ticks_counter));

    bytes_counter->Set(10L);
    EXPECT_EQ(throughput_counter->value(), 10);
    bytes_counter->Set(20L);
    EXPECT_EQ(throughput_counter->value(), 20);
    ticks_counter->Set(ticks_counter->value() / 2);
    EXPECT_EQ(throughput_counter->value(), 40);
}

TEST(CountersTest, InfoStringTest) {
    ObjectPool pool;
    RuntimeProfile profile(&pool, "Profile");
    EXPECT_TRUE(profile.GetInfoString("Key") == NULL);

    profile.AddInfoString("Key", "Value");
    const string* value = profile.GetInfoString("Key");
    EXPECT_TRUE(value != NULL);
    EXPECT_EQ(*value, "Value");

    // Convert it to thrift
    TRuntimeProfileTree tprofile;
    profile.ToThrift(&tprofile);

    // Convert it back
    RuntimeProfile* from_thrift = RuntimeProfile::CreateFromThrift(&pool, tprofile);
    value = from_thrift->GetInfoString("Key");
    EXPECT_TRUE(value != NULL);
    EXPECT_EQ(*value, "Value");

    // Test update.
    RuntimeProfile update_dst_profile(&pool, "Profile2");
    update_dst_profile.Update(tprofile);
    value = update_dst_profile.GetInfoString("Key");
    EXPECT_TRUE(value != NULL);
    EXPECT_EQ(*value, "Value");

    // Update the original profile, convert it to thrift and update from the dst
    // profile
    profile.AddInfoString("Key", "NewValue");
    profile.AddInfoString("Foo", "Bar");
    EXPECT_EQ(*profile.GetInfoString("Key"), "NewValue");
    EXPECT_EQ(*profile.GetInfoString("Foo"), "Bar");
    profile.ToThrift(&tprofile);

    update_dst_profile.Update(tprofile);
    EXPECT_EQ(*update_dst_profile.GetInfoString("Key"), "NewValue");
    EXPECT_EQ(*update_dst_profile.GetInfoString("Foo"), "Bar");
}

TEST(CountersTest, RateCounters) {
    ObjectPool pool;
    RuntimeProfile profile(&pool, "Profile");

    RuntimeProfile::Counter* bytes_counter = profile.AddCounter("bytes", TCounterType::BYTES);

    RuntimeProfile::Counter* rate_counter = profile.AddRateCounter("RateCounter", bytes_counter);
    EXPECT_TRUE(rate_counter->type() == TCounterType::BYTES_PER_SECOND);

    EXPECT_EQ(rate_counter->value(), 0);
    // set to 100MB.  Use bigger units to avoid truncating to 0 after divides.
    bytes_counter->Set(100L * 1024L * 1024L);

    // Wait one second.
    sleep(1);

    int64_t rate = rate_counter->value();

    // Remove the counter so it no longer gets updates
    profile.StopRateCounterUpdates(rate_counter);

    // The rate counter is not perfectly accurate.  Currently updated at 500ms intervals,
    // we should have seen somewhere between 1 and 3 updates (33 - 200 MB/s)
    EXPECT_GT(rate, 66 * 1024 * 1024);
    EXPECT_LE(rate, 200 * 1024 * 1024);

    // Wait another second.  The counter has been removed. So the value should not be
    // changed (much).
    sleep(2);

    rate = rate_counter->value();
    EXPECT_GT(rate, 66 * 1024 * 1024);
    EXPECT_LE(rate, 200 * 1024 * 1024);
}

TEST(CountersTest, BucketCounters) {
    ObjectPool pool;
    RuntimeProfile profile(&pool, "Profile");

    RuntimeProfile::Counter* unit_counter = profile.AddCounter("unit", TCounterType::UNIT);

    // Set the unit to 1 before sampling
    unit_counter->Set(1L);

    // Create the bucket counters and start sampling
    std::vector<RuntimeProfile::Counter*> buckets;
    profile.AddBucketingCounters("BucketCounters", "", unit_counter, 2, &buckets);

    // Wait two seconds.
    sleep(2);

    // Stop sampling
    profile.StopBucketingCountersUpdates(&buckets, true);

    // TODO: change the value to double
    // The value of buckets[0] should be zero and buckets[1] should be 1.
    double val0 = buckets[0]->double_value();
    double val1 = buckets[1]->double_value();
    EXPECT_EQ(0, val0);
    EXPECT_EQ(100, val1);

    // Wait another second.  The counter has been removed. So the value should not be
    // changed (much).
    sleep(2);
    EXPECT_EQ(val0, buckets[0]->double_value());
    EXPECT_EQ(val1, buckets[1]->double_value());
}
} // namespace impala

int main(int argc, char** argv) {
    std::string conffile = std::string(getenv("DORIS_HOME")) + "/conf/be.conf";
    if (!doris::config::init(conffile.c_str(), false)) {
        fprintf(stderr, "error read config file. \n");
        return -1;
    }
    init_glog("be-test");
    ::testing::InitGoogleTest(&argc, argv);
    impala::CpuInfo::Init();
    return RUN_ALL_TESTS();
}


text:
#include <iostream>
#include <list>
#include <algorithm>
#include <boost/foreach.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace std;
using namespace boost::property_tree;

struct IntVec {
  int x, y;
  IntVec operator+(IntVec &another);
  bool operator==(const IntVec &another) const;
  IntVec(int x = 0, int y = 0): x(x), y(y) {};
};

typedef IntVec Position;

struct Movement {
  Position from, to;
  bool intersects(const Movement &m) const;
  list <Position> touchedSquares() const;
  Movement() {};
  Movement(Position from, Position to): from(from), to(to) {};
};

const string CourseDataFileType = "race course 2018";

struct RaceCourse {
  ptree courseTree;
  int width, length;
  int vision;
  int64_t thinkTime;
  int stepLimit;
  int startX[2];
  char **squares;
  RaceCourse(istream &in);
};

ostream & operator <<(ostream &out, const IntVec &v);
ostream & operator <<(ostream &out, const RaceCourse &c);

ext: hpp


text:
// Copyright (c) 2011-2013, Pacific Biosciences of California, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted (subject to the limitations in the
// disclaimer below) provided that the following conditions are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above
//    copyright notice, this list of conditions and the following
//    disclaimer in the documentation and/or other materials provided
//    with the distribution.
//
//  * Neither the name of Pacific Biosciences nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
// GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY PACIFIC
// BIOSCIENCES AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL PACIFIC BIOSCIENCES OR ITS
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.

// Author: David Alexander

#include <ConsensusCore/Checksum.hpp>
#include <ConsensusCore/Features.hpp>
#include <ConsensusCore/Types.hpp>
#include <ConsensusCore/Read.hpp>

#include <string>
#include <sstream>
#include <boost/format.hpp>

namespace ConsensusCore {

    template<typename FeaturesType>
    Read<FeaturesType>::Read(FeaturesType features,
                             std::string name,
                             std::string chemistry)
        : Features(features)
        , Name(name)
        , Chemistry(chemistry)
    {}

    template<typename FeaturesType>
    Read<FeaturesType>::Read(const Read& other)
        : Features(other.Features)
        , Name(other.Name)
        , Chemistry(other.Chemistry)
    {}

    template<typename FeaturesType>
    int Read<FeaturesType>::Length() const
    {
        return Features.Length();
    }

    template<typename FeaturesType>
    std::string Read<FeaturesType>::ToString() const
    {
        return (boost::format("%s (%s) Length=%d Data=%s")
                % Name % Chemistry % Length() % Checksum::Of(Features)).str();
    }

    template<typename FeaturesType>
    Read<FeaturesType> Read<FeaturesType>::Null()
    {
        return Read(FeaturesType(""), "", "");
    }

    template<typename FeaturesType>
    MappedRead<FeaturesType>::MappedRead(const Read<FeaturesType>& read,
                           StrandEnum strand,
                           int templateStart,
                           int templateEnd,
                           bool pinStart,
                           bool pinEnd)
        : Read<FeaturesType>(read),
          Strand(strand),
          TemplateStart(templateStart),
          TemplateEnd(templateEnd),
          PinStart(pinStart),
          PinEnd(pinEnd)
    {}

    template<typename FeaturesType>
    MappedRead<FeaturesType>::MappedRead(const MappedRead& other)
        : Read<FeaturesType>(other),
          Strand(other.Strand),
          TemplateStart(other.TemplateStart),
          TemplateEnd(other.TemplateEnd),
          PinStart(other.PinStart),
          PinEnd(other.PinEnd)
    {}

    template<typename FeaturesType>
    std::string MappedRead<FeaturesType>::ToString() const
    {
        std::stringstream ss;
        ss << (PinStart ? "[" : "(");
        ss << TemplateStart << "," << TemplateEnd;
        ss << (PinEnd   ? "]" : ")");
        return Read<FeaturesType>::ToString() + " @ " + ss.str();
    }

    template struct Read<QvSequenceFeatures>;
    template struct Read<ArrowSequenceFeatures>;

    template struct MappedRead<QvSequenceFeatures>;
    template struct MappedRead<ArrowSequenceFeatures>;
}

max_stars_repo_name: pb-cdunn/pbccs

max_issues_repo_name: pb-cdunn/pbccs

max_forks_repo_name: pb-cdunn/pbccs


text:
/*************************************************************************
 > File Name: mutex.cpp
 > Author: Mengxing Liu
 ************************************************************************/

#include <iostream>
#include <mutex>
#include <boost/coroutine/coroutine.hpp>
#include <map>
#include <set>

typedef boost::coroutines::coroutine< void(void *)> coro_t;

int count;
std::mutex mtx;

class event{
	coro_t* coro;
public:
	event(coro_t* c):coro(c){

	}
	void trigger(){
		(*coro)(NULL);
	}
};

std::map<std::mutex*, std::set<event*> > event_map;

event* mkevent(coro_t* cur_coro){
	return new event(cur_coro);
}

bool trylock(){
	if(count < 1){
		return false;
	}else{
		mtx.try_lock();
		count--;
		return true;
	}
}
void unlock(){
	if (count == 0){
		count++;
		mtx.unlock();
		if (event_map[&mtx].size()>0){
			event* ev = (event*)*(event_map[&mtx].begin());
			event_map[&mtx].erase(ev);

			ev->trigger();
		}
	}
}

void txn2(coro_t::caller_type& ca){
	ca.get();
	ca();

	coro_t* cur_coro = (coro_t*)(ca.get());
	event* lock_ev = mkevent(cur_coro);

	while(trylock() == false){
		event_map[&mtx].insert(lock_ev);
		cur_coro = NULL;
		ca();
	}

	std::cout << "task2 is doing stuff\n";

	// do something else

	std::cout << "task2 unlock\n";
	unlock();
}

void txn1(coro_t::caller_type& ca){
	ca.get();
	ca();

	coro_t* cur_coro = (coro_t*)(ca.get());
	event* lock_ev = mkevent(cur_coro);

	while(trylock() == false){
		event_map[&mtx].insert(lock_ev);
		cur_coro = NULL;
		ca();
	}
	std::cout << "task1 is doing stuff\n";

	// may yield because of waiting for I/O or Internet message
	ca();

	std::cout << "task1 unlock\n";
	unlock();
}

int main(){
	count = 1;

	coro_t c1(txn1, NULL);
	c1((void*) &c1);

	coro_t c2(txn2, NULL);
	c2((void*) &c2);

	// txn1 waiting condition is trigger
	c1(NULL);
}

max_stars_repo_name: SJTU-IPADS/dst

max_issues_repo_name: SJTU-IPADS/dst

max_forks_repo_name: SJTU-IPADS/dst


text:
#include <iostream>
#include <sstream>

#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>

#include "simple_wml.hpp"

#include "../log.hpp"

#ifdef __PLAYBOOK__
using ::std::atoi;
using ::std::sprintf;
#endif

static lg::log_domain log_config("config");
#define ERR_SWML LOG_STREAM(err, log_config)

namespace simple_wml {

namespace {

void debug_delete(node* n) {
	delete n;
}

char* uncompress_buffer(const string_span& input, string_span* span)
{
	int nalloc = input.size();
	int state = 0;
	try {
		std::istringstream stream(std::string(input.begin(), input.end()));
		state = 1;
		boost::iostreams::filtering_stream<boost::iostreams::input> filter;
		state = 2;
		filter.push(boost::iostreams::gzip_decompressor());
		filter.push(stream);
		state = 3;

		const size_t chunk_size = input.size() * 10;
		nalloc = chunk_size;
		std::vector<char> buf(chunk_size);
		state = 4;
		size_t len = 0;
		size_t pos = 0;
		while(filter.good() && (len = filter.read(&buf[pos], chunk_size).gcount()) == chunk_size) {
			if(pos + chunk_size > 40000000) {
				throw error("WML document exceeds 40MB limit");
			}

			pos += len;
			buf.resize(pos + chunk_size);
			len = 0;
		}

		if(!filter.eof() && !filter.good()) {
			throw error("failed to uncompress");
		}

		pos += len;
		state = 5;
		nalloc = pos;

		buf.resize(pos);
		state = 6;

		char* small_out = new char[pos+1];
		memcpy(small_out, &buf[0], pos);
		state = 7;

		small_out[pos] = 0;

		*span = string_span(small_out, pos);
		state = 8;
		return small_out;
	} catch (std::bad_alloc& e) {
		ERR_SWML << "ERROR: bad_alloc caught in uncompress_buffer() state "
		<< state << " alloc bytes " << nalloc << " with input: '"
		<< input << "' " << e.what() << std::endl;
		throw error("Bad allocation request in uncompress_buffer().");
	}
}

char* compress_buffer(const char* input, string_span* span)
{
	int nalloc = strlen(input);
	int state = 0;
	try {
		std::string in(input);
		state = 1;
		std::istringstream stream(in);
		state = 2;
		boost::iostreams::filtering_stream<boost::iostreams::input> filter;
		state = 3;
		filter.push(boost::iostreams::gzip_compressor());
		filter.push(stream);
		state = 4;
		nalloc = in.size()*2 + 80;

		std::vector<char> buf(in.size()*2 + 80);
		state = 5;
		const int len = filter.read(&buf[0], buf.size()).gcount();
		assert(len < 128*1024*1024);
		if((!filter.eof() && !filter.good()) || len == static_cast<int>(buf.size())) {
			throw error("failed to compress");
		}
		state = 6;
		nalloc = len;

		buf.resize(len);
		state = 7;

		char* small_out = new char[len];
		memcpy(small_out, &buf[0], len);
		state = 8;

		*span = string_span(small_out, len);
		assert(*small_out == 31);
		state = 9;
		return small_out;
	} catch (std::bad_alloc& e) {
		ERR_SWML << "ERROR: bad_alloc caught in compress_buffer() state "
		<< state << " alloc bytes " << nalloc << " with input: '"
		<< input << "' " << e.what() << std::endl;
		throw error("Bad allocation request in compress_buffer().");
	}
}

}  // namespace

bool string_span::to_bool(bool default_value) const
{
	if(empty()) {
		return default_value;
	}

	if (operator==("no") || operator==("off") || operator==("false") || operator==("0") || operator==("0.0"))
		return false;

	return true;
}

int string_span::to_int() const
{
	const int buf_size = 64;
	if(size() >= buf_size) {
		return 0;
	}
	char buf[64];
	memcpy(buf, begin(), size());
	buf[size()] = 0;
	return atoi(buf);
}

std::string string_span::to_string() const
{
	return std::string(begin(), end());
}

char* string_span::duplicate() const
{
	char* buf = new char[size() + 1];
	memcpy(buf, begin(), size());
	buf[size()] = 0;
	return buf;
}

error::error(const char* msg)
  : game::error(msg)
{
	ERR_SWML << "ERROR: '" << msg << "'\n";
}

std::ostream& operator<<(std::ostream& o, const string_span& s)
{
	o << std::string(s.begin(), s.end());
	return o;
}

node::node(document& doc, node* parent) :
	doc_(&doc),
	attr_(),
	parent_(parent),
	children_(),
	ordered_children_(),
	output_cache_()
{
}

node::node(document& doc, node* parent, const char** str, int depth) :
	doc_(&doc),
	attr_(),
	parent_(parent),
	children_(),
	ordered_children_(),
	output_cache_()
{
	if(depth >= 1000) {
		throw error("elements nested too deep");
	}

	const char*& s = *str;

	const char* const begin = s;
	while(*s) {
		switch(*s) {
		case '[': {
			if(s[1] == '/') {
				output_cache_ = string_span(begin, s - begin);
				s = strchr(s, ']');
				if(s == NULL) {
					throw error("end element unterminated");
				}

				++s;
				return;
			}

			++s;
			const char* end = strchr(s, ']');
			if(end == NULL) {
				throw error("unterminated element");
			}

			const int list_index = get_children(string_span(s, end - s));
			check_ordered_children();

			s = end + 1;

			children_[list_index].second.push_back(new node(doc, this, str, depth+1));
			ordered_children_.push_back(node_pos(list_index, children_[list_index].second.size() - 1));
			check_ordered_children();

			break;
		}
		case ' ':
		case '\t':
		case '\n':
			++s;
			break;
		case '#':
			s = strchr(s, '\n');
			if(s == NULL) {
				throw error("did not find newline after '#'");
			}
			break;
		default: {
			const char* end = strchr(s, '=');
			if(end == NULL) {
				ERR_SWML << "attribute: " << s << "\n";
				throw error("did not find '=' after attribute");
			}

			string_span name(s, end - s);
			s = end + 1;
			if(*s == '_') {
				s = strchr(s, '"');
				if(s == NULL) {
					throw error("did not find '\"' after '_'");
				}
			}

			if (*s != '"') {
				end = strchr(s, '\n');
				if (!end) {
					ERR_SWML << "ATTR: '" << name << "' (((" << s << ")))\n";
					throw error("did not find end of attribute");
				}
				if (memchr(s, '"', end - s))
					throw error("found stray quotes in unquoted value");
				goto read_attribute;
			}

			end = s;

			for(;;)
			{
				// Read until the first single double quote.
				while((end = strchr(end+1, '"')) && end[1] == '"') {
					++end;
				}
				if(end == NULL)
					throw error("did not find end of attribute");

				// Stop if newline.
				const char *endline = end + 1;
				while (*endline == ' ') ++endline;
				if (*endline == '\n') break;

				// Read concatenation marker.
				if (*(endline++) != '+')
					throw error("did not find newline after end of attribute");
				if (*(endline++) != '\n')
					throw error("did not find newline after '+'");

				// Read textdomain marker.
				if (*endline == '#') {
					endline = strchr(endline + 1, '\n');
					if (!endline)
						throw error("did not find newline after '#'");
					++endline;
				}

				// Read indentation and start of string.
				while (*endline == '\t') ++endline;
				if (*endline == '_') ++endline;
				if (*endline != '"')
					throw error("did not find quotes after '+'");
				end = endline;
			}

			++s;

			read_attribute:
			string_span value(s, end - s);
			if(attr_.empty() == false && !(attr_.back().first < name)) {
				ERR_SWML << "attributes: '" << attr_.back().first << "' < '" << name << "'\n";
				throw error("attributes not in order");
			}

			s = end + 1;

			attr_.push_back(attribute(name, value));
		}
		}
	}

	output_cache_ = string_span(begin, s - begin);
	check_ordered_children();
}

node::~node()
{
	for(child_map::iterator i = children_.begin(); i != children_.end(); ++i) {
		for(child_list::iterator j = i->second.begin(); j != i->second.end(); ++j) {
			debug_delete(*j);
		}
	}
}

namespace {
struct string_span_pair_comparer
{
	bool operator()(const string_span& a, const node::attribute& b) const {
		return a < b.first;
	}

	bool operator()(const node::attribute& a, const string_span& b) const {
		return a.first < b;
	}

	bool operator()(const node::attribute& a,
	                const node::attribute& b) const {
		return a.first < b.first;
	}
};
}

const string_span& node::operator[](const char* key) const
{
	static string_span empty("");
	string_span span(key);
	std::pair<attribute_list::const_iterator,
	          attribute_list::const_iterator> range = std::equal_range(attr_.begin(), attr_.end(), span, string_span_pair_comparer());
	if(range.first != range.second) {
		return range.first->second;
	}

	return empty;
}

bool node::has_attr(const char* key) const
{
	string_span span(key);
	std::pair<attribute_list::const_iterator,
	          attribute_list::const_iterator> range = std::equal_range(attr_.begin(), attr_.end(), span, string_span_pair_comparer());
	return range.first != range.second;
}

node& node::set_attr(const char* key, const char* value)
{
	set_dirty();

	string_span span(key);
	std::pair<attribute_list::iterator,
	          attribute_list::iterator> range = std::equal_range(attr_.begin(), attr_.end(), span, string_span_pair_comparer());
	if(range.first != range.second) {
		range.first->second = string_span(value);
	} else {
		attr_.insert(range.first, attribute(span, string_span(value)));
	}

	return *this;
}

node& node::set_attr_dup(const char* key, const char* value)
{
	return set_attr(key, doc_->dup_string(value));
}

node& node::set_attr_dup(const char* key, const string_span& value)
{
	char* buf = value.duplicate();
	doc_->take_ownership_of_buffer(buf);
	return set_attr(key, buf);
}

node& node::set_attr_int(const char* key, int value)
{
	char buf[64];
	sprintf(buf, "%d", value);
	return set_attr_dup(key, buf);
}

node& node::add_child_at(const char* name, size_t index)
{
	set_dirty();

	const int list_index = get_children(name);
	child_list& list = children_[list_index].second;
	if(index > list.size()) {
		index = list.size();
	}

	check_ordered_children();
	list.insert(list.begin() + index, new node(*doc_, this));
	insert_ordered_child(list_index, index);

	check_ordered_children();
	return *list[index];
}

node& node::add_child(const char* name)
{
	set_dirty();

	const int list_index = get_children(name);
	check_ordered_children();
	child_list& list = children_[list_index].second;
	list.push_back(new node(*doc_, this));
	ordered_children_.push_back(node_pos(list_index, list.size() - 1));
	check_ordered_children();
	return *list.back();
}

void node::remove_child(const string_span& name, size_t index)
{
	set_dirty();

	//if we don't already have a vector for this item we don't want to add one.
	child_map::iterator itor = find_in_map(children_, name);
	if(itor == children_.end()) {
		return;
	}

	child_list& list = itor->second;
	if(index >= list.size()) {
		return;
	}

	remove_ordered_child(itor - children_.begin(), index);

	debug_delete(list[index]);
	list.erase(list.begin() + index);

	if(list.empty()) {
		remove_ordered_child_list(itor - children_.begin());
		children_.erase(itor);
	}
}

void node::insert_ordered_child(int child_map_index, int child_list_index)
{
	bool inserted = false;
	std::vector<node_pos>::iterator i = ordered_children_.begin();
	while(i != ordered_children_.end()) {
		if(i->child_map_index == child_map_index && i->child_list_index > child_list_index) {
			i->child_list_index++;
		} else if(i->child_map_index == child_map_index && i->child_list_index == child_list_index) {
			inserted = true;
			i->child_list_index++;
			i = ordered_children_.insert(i, node_pos(child_map_index, child_list_index));
			++i;
		}

		++i;
	}

	if(!inserted) {
		ordered_children_.push_back(node_pos(child_map_index, child_list_index));
	}
}

void node::remove_ordered_child(int child_map_index, int child_list_index)
{
	int erase_count = 0;
	std::vector<node_pos>::iterator i = ordered_children_.begin();
	while(i != ordered_children_.end()) {
		if(i->child_map_index == child_map_index && i->child_list_index == child_list_index) {
			i = ordered_children_.erase(i);
			++erase_count;
		} else {
			if(i->child_map_index == child_map_index && i->child_list_index > child_list_index) {
				i->child_list_index--;
			}
			++i;
		}
	}

	assert(erase_count == 1);
}

void node::insert_ordered_child_list(int child_map_index)
{
	std::vector<node_pos>::iterator i = ordered_children_.begin();
	while(i != ordered_children_.end()) {
		if(i->child_map_index >= child_map_index) {
			i->child_map_index++;
		}
	}
}

void node::remove_ordered_child_list(int child_map_index)
{
	std::vector<node_pos>::iterator i = ordered_children_.begin();
	while(i != ordered_children_.end()) {
		if(i->child_map_index == child_map_index) {
			assert(false);
			i = ordered_children_.erase(i);
		} else {
			if(i->child_map_index > child_map_index) {
				i->child_map_index--;
			}

			++i;
		}
	}
}

void node::check_ordered_children() const
{
// only define this symbol in debug mode to work out child ordering.
#ifdef CHECK_ORDERED_CHILDREN
	std::vector<node_pos>::const_iterator i = ordered_children_.begin();
	while(i != ordered_children_.end()) {
		assert(i->child_map_index < children_.size());
		assert(i->child_list_index < children_[i->child_map_index].second.size());
		++i;
	}

	for(child_map::const_iterator j = children_.begin(); j != children_.end(); ++j) {
		const unsigned short child_map_index = j - children_.begin();
		for(child_list::const_iterator k = j->second.begin(); k != j->second.end(); ++k) {
			const unsigned short child_list_index = k - j->second.begin();
			bool found = false;
			for(int n = 0; n != ordered_children_.size(); ++n) {
				if(ordered_children_[n].child_map_index == child_map_index &&
				   ordered_children_[n].child_list_index == child_list_index) {
					found = true;
					break;
				}
			}

			assert(found);
		}
	}
#endif // CHECK_ORDERED_CHILDREN
}

void node::remove_child(const char* name, size_t index)
{
	remove_child(string_span(name), index);
}

node* node::child(const char* name)
{
	for(child_map::iterator i = children_.begin(); i != children_.end(); ++i) {
		if(i->first == name) {
			assert(i->second.empty() == false);
			return i->second.front();
		}
	}

	return NULL;
}

const node* node::child(const char* name) const
{
	for(child_map::const_iterator i = children_.begin(); i != children_.end(); ++i) {
		if(i->first == name) {
			if(i->second.empty()) {
				return NULL;
			} else {
				return i->second.front();
			}
		}
	}

	return NULL;
}

const node::child_list& node::children(const char* name) const
{
	for(child_map::const_iterator i = children_.begin(); i != children_.end(); ++i) {
		if(i->first == name) {
			return i->second;
		}
	}

	static const node::child_list empty;
	return empty;
}

int node::get_children(const char* name)
{
	return get_children(string_span(name));
}

int node::get_children(const string_span& name)
{
	for(child_map::iterator i = children_.begin(); i != children_.end(); ++i) {
		if(i->first == name) {
			return i - children_.begin();
		}
	}

	children_.push_back(child_pair(string_span(name), child_list()));
	return children_.size() - 1;
}

node::child_map::const_iterator node::find_in_map(const child_map& m, const string_span& attr)
{
	child_map::const_iterator i = m.begin();
	for(; i != m.end(); ++i) {
		if(i->first == attr) {
			break;
		}
	}

	return i;
}

node::child_map::iterator node::find_in_map(child_map& m, const string_span& attr)
{
	child_map::iterator i = m.begin();
	for(; i != m.end(); ++i) {
		if(i->first == attr) {
			break;
		}
	}

	return i;
}

const string_span& node::first_child() const
{
	if(children_.empty()) {
		static const string_span empty;
		return empty;
	}

	return children_.begin()->first;
}

int node::output_size() const
{
	check_ordered_children();
	if(output_cache_.empty() == false) {
		return output_cache_.size();
	}

	int res = 0;
	for(attribute_list::const_iterator i = attr_.begin(); i != attr_.end(); ++i) {
		res += i->first.size() + i->second.size() + 4;
	}

	size_t count_children = 0;
	for(child_map::const_iterator i = children_.begin(); i != children_.end(); ++i) {
		for(child_list::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
			res += i->first.size()*2 + 7;
			res += (*j)->output_size();
			++count_children;
		}
	}

	assert(count_children == ordered_children_.size());

	return res;
}

void node::shift_buffers(ptrdiff_t offset)
{
	if(!output_cache_.empty()) {
		output_cache_ = string_span(output_cache_.begin() + offset, output_cache_.size());
	}

	for(std::vector<attribute>::iterator i = attr_.begin(); i != attr_.end(); ++i) {
		i->first = string_span(i->first.begin() + offset, i->first.size());
		i->second = string_span(i->second.begin() + offset, i->second.size());
	}

	for(child_map::iterator i = children_.begin(); i != children_.end(); ++i) {
		string_span& key = i->first;
		key = string_span(key.begin() + offset, key.size());
		for(child_list::iterator j = i->second.begin(); j != i->second.end(); ++j) {
			(*j)->shift_buffers(offset);
		}
	}
}

void node::output(char*& buf, CACHE_STATUS cache_status)
{
	if(output_cache_.empty() == false) {
		memcpy(buf, output_cache_.begin(), output_cache_.size());
		if(cache_status == REFRESH_CACHE) {
			shift_buffers(buf - output_cache_.begin());
		}
		buf += output_cache_.size();
		return;
	}

	char* begin = buf;

	for(std::vector<attribute>::iterator i = attr_.begin(); i != attr_.end(); ++i) {
		memcpy(buf, i->first.begin(), i->first.size());
		i->first = string_span(buf, i->first.size());
		buf += i->first.size();
		*buf++ = '=';
		*buf++ = '"';
		memcpy(buf, i->second.begin(), i->second.size());
		i->second = string_span(buf, i->second.size());
		buf += i->second.size();
		*buf++ = '"';
		*buf++ = '\n';
	}

	for(std::vector<node_pos>::const_iterator i = ordered_children_.begin();
	    i != ordered_children_.end(); ++i) {
		assert(i->child_map_index < children_.size());
		assert(i->child_list_index < children_[i->child_map_index].second.size());
		string_span& attr = children_[i->child_map_index].first;
		*buf++ = '[';
		memcpy(buf, attr.begin(), attr.size());
		attr = string_span(buf, attr.size());
		buf += attr.size();
		*buf++ = ']';
		*buf++ = '\n';
		children_[i->child_map_index].second[i->child_list_index]->output(buf, cache_status);
		*buf++ = '[';
		*buf++ = '/';
		memcpy(buf, attr.begin(), attr.size());
		buf += attr.size();
		*buf++ = ']';
		*buf++ = '\n';
	}

	if(cache_status == REFRESH_CACHE) {
		output_cache_ = string_span(begin, buf - begin);
	}
}

std::string node_to_string(const node& n)
{
	//calling output with status=DO_NOT_MODIFY_CACHE really doesn't modify the
	//node, so we can do it safely
	node& mutable_node = const_cast<node&>(n);
	std::vector<char> v(mutable_node.output_size());
	char* ptr = &v[0];
	mutable_node.output(ptr, node::DO_NOT_MODIFY_CACHE);
	assert(ptr == &v[0] + v.size());
	return std::string(v.begin(), v.end());
}

void node::copy_into(node& n) const
{
	n.set_dirty();
	for(attribute_list::const_iterator i = attr_.begin(); i != attr_.end(); ++i) {
		char* key = i->first.duplicate();
		char* value = i->second.duplicate();
		n.doc_->take_ownership_of_buffer(key);
		n.doc_->take_ownership_of_buffer(value);
		n.set_attr(key, value);
	}

	for(std::vector<node_pos>::const_iterator i = ordered_children_.begin();
	    i != ordered_children_.end(); ++i) {
		assert(i->child_map_index < children_.size());
		assert(i->child_list_index < children_[i->child_map_index].second.size());
		char* buf = children_[i->child_map_index].first.duplicate();
		n.doc_->take_ownership_of_buffer(buf);
		children_[i->child_map_index].second[i->child_list_index]->copy_into(n.add_child(buf));
	}
}

void node::apply_diff(const node& diff)
{
	set_dirty();
	const node* inserts = diff.child("insert");
	if(inserts != NULL) {
		for(attribute_list::const_iterator i = inserts->attr_.begin(); i != inserts->attr_.end(); ++i) {
			char* name = i->first.duplicate();
			char* value = i->second.duplicate();
			set_attr(name, value);
			doc_->take_ownership_of_buffer(name);
			doc_->take_ownership_of_buffer(value);
		}
	}

	const node* deletes = diff.child("delete");
	if(deletes != NULL) {
		for(attribute_list::const_iterator i = deletes->attr_.begin(); i != deletes->attr_.end(); ++i) {
			std::pair<attribute_list::iterator,
	                  attribute_list::iterator> range = std::equal_range(attr_.begin(), attr_.end(), i->first, string_span_pair_comparer());
			if(range.first != range.second) {
				attr_.erase(range.first);
			}
		}
	}

	const child_list& child_changes = diff.children("change_child");
	for(child_list::const_iterator i = child_changes.begin(); i != child_changes.end(); ++i) {
		const size_t index = (**i)["index"].to_int();
		for(child_map::const_iterator j = (*i)->children_.begin(); j != (*i)->children_.end(); ++j) {
			const string_span& name = j->first;
			for(child_list::const_iterator k = j->second.begin(); k != j->second.end(); ++k) {
				child_map::iterator itor = find_in_map(children_, name);
				if(itor != children_.end()) {
					if(index < itor->second.size()) {
						itor->second[index]->apply_diff(**k);
					}
				}
			}
		}
	}

	const child_list& child_inserts = diff.children("insert_child");
	for(child_list::const_iterator i = child_inserts.begin(); i != child_inserts.end(); ++i) {
		const size_t index = (**i)["index"].to_int();
		for(child_map::const_iterator j = (*i)->children_.begin(); j != (*i)->children_.end(); ++j) {
			const string_span& name = j->first;
			for(child_list::const_iterator k = j->second.begin(); k != j->second.end(); ++k) {
				char* buf = name.duplicate();
				doc_->take_ownership_of_buffer(buf);
				(*k)->copy_into(add_child_at(buf, index));
			}
		}
	}

	const child_list& child_deletes = diff.children("delete_child");
	for(child_list::const_iterator i = child_deletes.begin(); i != child_deletes.end(); ++i) {
		const size_t index = (**i)["index"].to_int();
		for(child_map::const_iterator j = (*i)->children_.begin(); j != (*i)->children_.end(); ++j) {
			if(j->second.empty()) {
				continue;
			}

			const string_span& name = j->first;
			remove_child(name, index);
		}
	}
}

void node::set_doc(document* doc)
{
	doc_ = doc;

	for(child_map::iterator i = children_.begin(); i != children_.end(); ++i) {
		for(child_list::iterator j = i->second.begin(); j != i->second.end(); ++j) {
			(*j)->set_doc(doc);
		}
	}
}

int node::nchildren() const
{
	int res = 0;
	for(child_map::const_iterator i = children_.begin(); i != children_.end(); ++i) {
		for(child_list::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
			++res;
			res += (*j)->nchildren();
		}
	}

	return res;
}

int node::nattributes_recursive() const
{
	int res = attr_.capacity();
	for(child_map::const_iterator i = children_.begin(); i != children_.end(); ++i) {
		for(child_list::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
			res += (*j)->nattributes_recursive();
		}
	}

	return res;
}

void node::set_dirty()
{
	for(node* n = this; n != NULL && n->output_cache_.is_null() == false; n = n->parent_) {
		n->output_cache_ = string_span();
	}
}

document::document() :
	compressed_buf_(),
	output_(NULL),
	buffers_(),
	root_(new node(*this, NULL)),
	prev_(NULL),
	next_(NULL)
{
	attach_list();
}

document::document(char* buf, INIT_BUFFER_CONTROL control) :
	compressed_buf_(),
	output_(buf),
	buffers_(),
	root_(NULL),
	prev_(NULL),
	next_(NULL)
{
	if(control == INIT_TAKE_OWNERSHIP) {
		buffers_.push_back(buf);
	}
	const char* cbuf = buf;
	root_ = new node(*this, NULL, &cbuf);

	attach_list();
}

document::document(const char* buf, INIT_STATE state) :
	compressed_buf_(),
	output_(buf),
	buffers_(),
	root_(NULL),
	prev_(NULL),
	next_(NULL)
{
	if(state == INIT_COMPRESSED) {
		output_compressed();
		output_ = NULL;
	} else {
		root_ = new node(*this, NULL, &buf);
	}

	attach_list();
}

document::document(string_span compressed_buf) :
	compressed_buf_(compressed_buf),
	output_(NULL),
	buffers_(),
	root_(NULL),
	prev_(NULL),
	next_(NULL)
{
	string_span uncompressed_buf;
	buffers_.push_back(uncompress_buffer(compressed_buf, &uncompressed_buf));
	output_ = uncompressed_buf.begin();
	const char* cbuf = output_;
	try {
		root_ = new node(*this, NULL, &cbuf);
	} catch(...) {
		delete [] buffers_.front();
		buffers_.clear();
		throw;
	}

	attach_list();
}

document::~document()
{
	for(std::vector<char*>::iterator i = buffers_.begin(); i != buffers_.end(); ++i) {
		delete [] *i;
	}

	buffers_.clear();
	debug_delete(root_);

	detach_list();
}

const char* document::dup_string(const char* str)
{
	const int len = strlen(str);
	char* res = new char[len+1];
	memcpy(res, str, len + 1);
	buffers_.push_back(res);
	return res;
}

const char* document::output()
{
	if(output_ && (!root_ || root_->is_dirty() == false)) {
		return output_;
	}
	if(!root_) {
		assert(compressed_buf_.empty() == false);
		string_span uncompressed_buf;
		buffers_.push_back(uncompress_buffer(compressed_buf_, &uncompressed_buf));
		output_ = uncompressed_buf.begin();
		return output_;
	}

	//we're dirty, so the compressed buf must also be dirty; clear it.
	compressed_buf_ = string_span();

	std::vector<char*> bufs;
	bufs.swap(buffers_);

	const int buf_size = root_->output_size() + 1;
	char* buf;
	try {
		buf = new char[buf_size];
	} catch (std::bad_alloc& e) {
		ERR_SWML << "ERROR: Trying to allocate " << buf_size << " bytes. "
		<< e.what() << std::endl;
		throw error("Bad allocation request in output().");
	}
	buffers_.push_back(buf);
	output_ = buf;

	root_->output(buf, node::REFRESH_CACHE);
	*buf++ = 0;
	assert(buf == output_ + buf_size);

	for(std::vector<char*>::iterator i = bufs.begin(); i != bufs.end(); ++i) {
		delete [] *i;
	}

	bufs.clear();

	return output_;
}

string_span document::output_compressed()
{
	if(compressed_buf_.empty() == false &&
	   (root_ == NULL || root_->is_dirty() == false)) {
		assert(*compressed_buf_.begin() == 31);
		return compressed_buf_;
	}

	buffers_.push_back(compress_buffer(output(), &compressed_buf_));
	assert(*compressed_buf_.begin() == 31);

	return compressed_buf_;
}

void document::compress()
{
	output_compressed();
	debug_delete(root_);
	root_ = NULL;
	output_ = NULL;
	std::vector<char*> new_buffers;
	for(std::vector<char*>::iterator i = buffers_.begin(); i != buffers_.end(); ++i) {
		if(*i != compressed_buf_.begin()) {
			delete [] *i;
		} else {
			new_buffers.push_back(*i);
		}
	}

	buffers_.swap(new_buffers);
	assert(buffers_.size() == 1);
}

void document::generate_root()
{
	if(output_ == NULL) {
		assert(compressed_buf_.empty() == false);
		string_span uncompressed_buf;
		buffers_.push_back(uncompress_buffer(compressed_buf_, &uncompressed_buf));
		output_ = uncompressed_buf.begin();
	}

	assert(root_ == NULL);
	const char* cbuf = output_;
	root_ = new node(*this, NULL, &cbuf);
}

document* document::clone()
{
	char* buf = new char[strlen(output())+1];
	strcpy(buf, output());
	return new document(buf);
}

void document::swap(document& o)
{
	std::swap(compressed_buf_, o.compressed_buf_);
	std::swap(output_, o.output_);
	buffers_.swap(o.buffers_);
	std::swap(root_, o.root_);

	root_->set_doc(this);
	o.root_->set_doc(&o);
}

void document::clear()
{
	compressed_buf_ = string_span();
	output_ = NULL;
	debug_delete(root_);
	root_ = new node(*this, NULL);
	for(std::vector<char*>::iterator i = buffers_.begin(); i != buffers_.end(); ++i) {
		delete [] *i;
	}

	buffers_.clear();
}

namespace {
document* head_doc = NULL;
}

void document::attach_list()
{
	prev_ = NULL;
	next_ = head_doc;

	if(next_) {
		next_->prev_ = this;
	}
	head_doc = this;
}

void document::detach_list()
{
	if(head_doc == this) {
		head_doc = next_;
	}

	if(next_) {
		next_->prev_ = prev_;
	}

	if(prev_) {
		prev_->next_ = next_;
	}
	next_ = prev_ = NULL;
}

std::string document::stats()
{
	std::ostringstream s;
	int ndocs = 0;
	int ncompressed = 0;
	int compressed_size = 0;
	int ntext = 0;
	int text_size = 0;
	int nbuffers = 0;
	int nnodes = 0;
	int ndirty = 0;
	int nattributes = 0;
	for(document* d = head_doc; d != NULL; d = d->next_) {
		ndocs++;
		nbuffers += d->buffers_.size();

		if(d->compressed_buf_.is_null() == false) {
			++ncompressed;
			compressed_size += d->compressed_buf_.size();
		}

		if(d->output_) {
			++ntext;
			text_size += strlen(d->output_);
		}

		if(d->root_) {
			nnodes += 1 + d->root_->nchildren();
			nattributes += d->root_->nattributes_recursive();
		}

		if(d->root_ && d->root_->is_dirty()) {
			++ndirty;
		}
	}

	const int nodes_alloc = nnodes*(sizeof(node) + 12);
	const int attr_alloc = nattributes*(sizeof(string_span)*2);
	const int total_alloc = compressed_size + text_size + nodes_alloc + attr_alloc;

	s << "WML documents: " << ndocs << "\n"
	  << "Dirty: " << ndirty << "\n"
	  << "With compression: " << ncompressed << " (" << compressed_size
	  << " bytes)\n"
	  << "With text: " << ntext << " (" << text_size
	  << " bytes)\n"
	  << "Nodes: " << nnodes << " (" << nodes_alloc << " bytes)\n"
	  << "Attr: " << nattributes << " (" << attr_alloc << " bytes)\n"
	  << "Buffers: " << nbuffers << "\n"
	  << "Total allocation: " << total_alloc << " bytes\n";

	return s.str();
}

}

#ifdef UNIT_TEST_SIMPLE_WML

int main(int argc, char** argv)
{
	char* doctext = strdup(
"[test]\n"
"a=\"blah\"\n"
"b=\"blah\"\n"
"c=\"\\\\\"\n"
"d=\"\\\"\"\n"
"[/test]");
	std::cerr << doctext << "\n";
	simple_wml::document doc(doctext);

	simple_wml::node& node = doc.root();
	simple_wml::node* test_node = node.child("test");
	assert(test_node);
	assert((*test_node)["a"] == "blah");
	assert((*test_node)["b"] == "blah");
	assert((*test_node)["c"] == "\\\\");
	assert((*test_node)["d"] == "\\\"");

	node.set_attr("blah", "blah");
	test_node->set_attr("e", "f");
	std::cerr << doc.output();
}

#endif

max_stars_repo_name: blackberry/Wesnoth

max_issues_repo_name: blackberry/Wesnoth

max_forks_repo_name: blackberry/Wesnoth


text:
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE expected

#include <coco/combix/iterator_stream.hpp>
#include <coco/combix/primitives.hpp>
#include <coco/combix/combinators/choice.hpp>
#include <coco/combix/combinators/map.hpp>
#include <coco/combix/combinators/seq.hpp>
#include <coco/combix/combinators/many.hpp>
#include <coco/combix/combinators/chainl.hpp>
#include <coco/combix/combinators/between.hpp>
#include <coco/combix/combinators/expected.hpp>
#include <coco/combix/combinators/skip.hpp>
#include <coco/combix/combinators/skip_seq.hpp>
#include <coco/combix/combinators/sep_by.hpp>
#include <coco/combix/combinators/try_.hpp>
#include <coco/combix/combinators/option.hpp>
#include <coco/combix/combinators/not_followed_by.hpp>
#include <coco/combix/combinators/end_by.hpp>

#include <boost/test/unit_test.hpp>

#include <string>

namespace cbx = coco::combix;

auto digit() {
  return cbx::satisfy([](auto&& c) { return '0' <= c && c <= '9'; });
}
auto alpha() {
  return cbx::satisfy([](auto&& c) { return 'a' <= c && c <= 'z'; });
}

BOOST_AUTO_TEST_SUITE(combix)
BOOST_AUTO_TEST_SUITE(combinators)

  BOOST_AUTO_TEST_CASE(choice) {
    auto src = std::string{"a1B"};
    auto s = cbx::iter_stream(std::begin(src), std::end(src));
    auto const alpha =
        cbx::satisfy([](auto&& c) { return 'a' <= c && c <= 'z'; });
    auto const num =
        cbx::satisfy([](auto&& c) { return '0' <= c && c <= '9'; });
    auto const p = cbx::choice(
        alpha,
        num);

    BOOST_TEST(parse(p, s).unwrap() == 'a');
    BOOST_TEST(parse(p, s).unwrap() == '1');
    BOOST_TEST(parse(p, s).is_error());
  }

  BOOST_AUTO_TEST_CASE(map) {
    auto src = std::string{"1"};
    auto s = cbx::iter_stream(std::begin(src), std::end(src));
    auto const p = cbx::map(
        cbx::satisfy([](auto&& c) { return '0' <= c && c <= '9'; }),
        [](auto&& c) { return static_cast<int>(c) - '0'; });

    BOOST_TEST(parse(p, s).unwrap() == 1);
    BOOST_TEST(parse(p, s).is_error());
  }

  BOOST_AUTO_TEST_CASE(seq) {
    auto src = std::string{"123"};
    auto s = cbx::iter_stream(std::begin(src), std::end(src));
    auto const digit = cbx::map(
        cbx::satisfy([](auto&& c) { return '0' <= c && c <= '9'; }),
        [](auto&& c) { return static_cast<int>(c) - '0'; });
    auto const p = cbx::seq(digit, digit, digit);

    BOOST_ASSERT(parse(p, s).unwrap() == std::make_tuple(1, 2, 3));
    BOOST_TEST(std::string(s.begin(), s.end()) == "");
    BOOST_TEST(parse(p, s).is_error());
  }

  BOOST_AUTO_TEST_CASE(many) {
    auto src = std::string{"123"};
    auto s = cbx::iter_stream(std::begin(src), std::end(src));
    auto const digit = cbx::map(
        cbx::satisfy([](auto&& c) { return '0' <= c && c <= '9'; }),
        [](auto&& c) { return static_cast<int>(c) - '0'; });
    auto const p = cbx::many(digit);

    BOOST_TEST((parse(p, s).unwrap() == std::deque<int>{1, 2, 3}));
  }

  BOOST_AUTO_TEST_CASE(many_with_zero_input) {
    auto src = std::string{"abc"};
    auto s = cbx::iter_stream(std::begin(src), std::end(src));
    auto const digit = cbx::map(
        cbx::satisfy([](auto&& c) { return '0' <= c && c <= '9'; }),
        [](auto&& c) { return static_cast<int>(c) - '0'; });
    auto const p = cbx::many(digit);

    BOOST_TEST((parse(p, s).unwrap() == std::deque<int>{}));
  }

  BOOST_AUTO_TEST_CASE(many1) {
    auto src = std::string{"123"};
    auto s = cbx::iter_stream(std::begin(src), std::end(src));
    auto const digit = cbx::map(
        cbx::satisfy([](auto&& c) { return '0' <= c && c <= '9'; }),
        [](auto&& c) { return static_cast<int>(c) - '0'; });
    auto const p = cbx::many1(digit);

    BOOST_TEST((parse(p, s).unwrap() == std::deque<int>{1, 2, 3}));
  }

  BOOST_AUTO_TEST_CASE(many1_with_zero_input) {
    auto src = std::string{"abc"};
    auto s = cbx::iter_stream(std::begin(src), std::end(src));
    auto const digit = cbx::map(
        cbx::satisfy([](auto&& c) { return '0' <= c && c <= '9'; }),
        [](auto&& c) { return static_cast<int>(c) - '0'; });
    auto const p = cbx::many1(digit);

    BOOST_TEST(parse(p, s).is_error());
  }

  BOOST_AUTO_TEST_CASE(chainl1) {
    auto src = std::string{"1+2+3"};
    auto s = cbx::range_stream(src);
    auto const digit = cbx::map(
        cbx::satisfy([](auto&& c) { return '1' <= c && c <= '9'; }),
        [](auto&& c) { return static_cast<int>(c) - '0'; });
    auto const add = cbx::map(cbx::token('+'), [](auto&&) {
      return std::plus<int>();
    });
    auto const expr = cbx::chainl1(digit, add);

    BOOST_TEST(parse(expr, s).unwrap() == 6);
    BOOST_TEST(std::string(s.begin(), s.end()) == "");
  }

  BOOST_AUTO_TEST_CASE(between) {
    auto src = std::string{"(a)"};
    auto s = cbx::range_stream(src);
    auto const alpha =
        cbx::satisfy([](auto&& c) { return 'a' <= c && c <= 'z'; });
    auto const p = cbx::between(cbx::token('('),
                                         cbx::token(')'), alpha);

    BOOST_TEST(parse(p, s).unwrap() == 'a');
    BOOST_TEST(std::string(s.begin(), s.end()) == "");
  }

  BOOST_AUTO_TEST_CASE(expected) {
    auto src = std::string("hoge");
    auto s = cbx::range_stream(src);
    auto const lower = cbx::expected(
        cbx::satisfy([](auto&& c) { return 'a' <= c && c <= 'z'; }),
        "lower");

    BOOST_TEST(parse(lower, s).unwrap() == 'h');

    auto src2 = std::string{"2"};
    auto s2 = cbx::range_stream(src2);
    auto err = parse(lower, s2).unwrap_error();
    std::stringstream ss;
    ss << err;
    BOOST_TEST(ss.str() == "Unexpected \"2\"\nExpected lower\n");
  }

  BOOST_AUTO_TEST_CASE(skip) {
    auto src = std::string("1 2 3");
    auto s = cbx::range_stream(src);

    auto const digit =
        cbx::satisfy([](auto c) { return '0' <= c && c <= '9'; });
    auto const spaces = cbx::many(cbx::token(' '));
    auto const p = cbx::many(cbx::skip(digit, spaces));

    BOOST_TEST((parse(p, s).unwrap() == std::deque<char>{'1', '2', '3'}));
  }

  BOOST_AUTO_TEST_CASE(skip_seq) {
    auto src = std::string{"1   2 3"};
    auto s = cbx::range_stream(src);

    auto const digit =
        cbx::satisfy([](auto c) { return '0' <= c && c <= '9'; });
    auto const spaces = cbx::many(cbx::token(' '));
    auto const p =
        cbx::skip_seq(spaces)(digit, digit, digit);

    BOOST_TEST((parse(p, s).unwrap() == std::make_tuple('1', '2', '3')));
  }

  BOOST_AUTO_TEST_CASE(sep_by) {
    auto src = std::string("1,2,3");
    auto s = cbx::range_stream(src);

    auto const digit =
        cbx::satisfy([](auto c) { return '0' <= c && c <= '9'; });
    auto const p = cbx::sep_by(digit, cbx::token(','));

    BOOST_TEST((parse(p, s).unwrap() == std::deque<char>{'1', '2', '3'}));

    {
      auto src = std::string("1,2,3,");
      auto s = cbx::range_stream(src);

      auto const digit =
          cbx::satisfy([](auto c) { return '0' <= c && c <= '9'; });
      auto const p = cbx::sep_by(digit, cbx::token(','));

      BOOST_TEST(parse(p, s).is_error());
    }
  }

  BOOST_AUTO_TEST_CASE(end_by) {
    auto const p = cbx::end_by(digit(), cbx::token(','));

    {
      auto src = std::string("1,2,3,");
      auto s = cbx::range_stream(src);

      BOOST_TEST((parse(p, s).unwrap() == std::deque<char>{'1', '2', '3'}));
    }

    {
      auto src = std::string("1,2,3");
      auto s = cbx::range_stream(src);

      BOOST_TEST(parse(p, s).is_error());
    }

    {
      auto src = std::string("");
      auto s = cbx::range_stream(src);

      BOOST_TEST((parse(p, s).unwrap() == std::deque<char>{}));
    }
  }

  BOOST_AUTO_TEST_CASE(end_by1) {
    auto const p = cbx::end_by1(digit(), cbx::token(','));

    {
      auto src = std::string("1,2,3,");
      auto s = cbx::range_stream(src);

      BOOST_TEST((parse(p, s).unwrap() == std::deque<char>{'1', '2', '3'}));
    }

    {
      auto src = std::string("1,2,3");
      auto s = cbx::range_stream(src);

      BOOST_TEST(parse(p, s).is_error());
    }

    {
      auto src = std::string("");
      auto s = cbx::range_stream(src);

      BOOST_TEST(parse(p, s).is_error());
    }
  }

  BOOST_AUTO_TEST_CASE(try_) {
    auto src = std::string{"1a"};
    auto s = cbx::range_stream(src);

    auto const p = cbx::seq(digit(), digit());
    auto const try_p = cbx::try_(p);

    BOOST_TEST(parse(try_p, s).is_error());
    BOOST_TEST(std::string(s.begin(), s.end()) == "1a");

    BOOST_TEST(parse(p, s).is_error());
    BOOST_TEST(std::string(s.begin(), s.end()) == "a");
  }

  BOOST_AUTO_TEST_CASE(option) {
    auto const p = cbx::between(cbx::token('('), cbx::token(')'),
                                cbx::option(digit()));
    auto src = std::string{"()"};
    auto s = cbx::range_stream(src);
    BOOST_ASSERT(parse(p, s).unwrap() == boost::none);

    auto src2 = std::string{"(1)"};
    auto s2 = cbx::range_stream(src2);
    BOOST_TEST(*(parse(p, s2).unwrap()) == '1');
  }

  BOOST_AUTO_TEST_CASE(not_followed_by) {
    auto non_keyword = std::string{"key"};
    auto non_keyword_s = cbx::range_stream(non_keyword);
    auto keyword = std::string{"k ()"};
    auto keyword_s = cbx::range_stream(keyword);

    auto const p =
        cbx::skip(cbx::token('k'), cbx::not_followed_by(alpha()));

    BOOST_TEST(parse(p, non_keyword_s).is_error());
    BOOST_TEST(std::string(non_keyword_s.begin(), non_keyword_s.end()) ==
               "ey");

    BOOST_TEST(parse(p, keyword_s).unwrap() == 'k');
    BOOST_TEST(std::string(keyword_s.begin(), keyword_s.end()) == " ()");
  }

BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: agatan/coco

max_issues_repo_name: agatan/coco

max_forks_repo_name: agatan/coco


text:
#include <array>
#include <future>
#include <iostream>
#include <thread>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/udp.hpp>
#include <boost/asio/use_future.hpp>

using boost::asio::ip::udp;

void get_daytime(boost::asio::io_context& io_context,const char* hostname)
{
    try
    {
        udp::resolver resolver(io_context);

        std::future<udp::resolver::results_type> endpoints =
            resolver.async_resolve(
                udp::v4(),hostname,"daytime",
                boost::asio::use_future);

        // The async_resolve operation above returns the endpoints as a future
        // value that is not retrieved ...

        udp::socket socket(io_context,udp::v4());

        std::array<char,1> send_buf = {{ 0 }};
        std::future<std::size_t> send_length =
            socket.async_send_to(boost::asio::buffer(send_buf),
                *endpoints.get().begin(),     // ... until here. This call may block.
                boost::asio::use_future);

        // Do other things here while the send completes.
        send_length.get();          // Blocks until the send is complete. Throws any errors.

        std::array<char,128> recv_buf;
        udp::endpoint send_endpoint;
        std::future<std::size_t> recv_length =
            socket.async_receive_from(
                boost::asio::buffer(recv_buf),
                send_endpoint,
                boost::asio::use_future
            );

        // Do other things here while the receive completes.
        std::cout.write(
            recv_buf.data(),
            recv_length.get()
        );      // Blocks until receive is complete.

    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << '\n';
    }

}

int main(int argc, char const *argv[])
{
    try
    {
        if(argc != 2)
        {
            std::cerr << "Usage: daytime_client <host>" << std::endl;
            return 1;
        }

        // We run the io_context off in its own thread so that it operates
        // completely asynchronously with respect to the rest of the program.
        boost::asio::io_context io_context;
        auto work = boost::asio::make_work_guard(io_context);
        std::thread thread([&io_context](){ io_context.run(); });

        get_daytime(io_context,argv[1]);

        io_context.stop();
        thread.join();
    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << '\n';
    }

    return 0;
}


text: #include <boost/units/base_units/us/mil.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#include <sec/ShortestEdgeCollapse.h>

#include <wmtk/utils/Logger.hpp>
#include <wmtk/utils/ManifoldUtils.hpp>

#include <igl/Timer.h>
#include <igl/is_edge_manifold.h>
#include <igl/is_vertex_manifold.h>
#include <igl/read_triangle_mesh.h>

#include <Eigen/Core>
#include <catch2/catch.hpp>

using namespace sec;
using namespace wmtk;

TEST_CASE("separate-manifold-patch", "[test_sec]")
{
    std::vector<Eigen::Vector3d> v = {
        {Eigen::Vector3d(0, 0, 0),
         Eigen::Vector3d(1, 0, 0),
         Eigen::Vector3d(0, 1, 0),
         Eigen::Vector3d(0, 0, 1),
         Eigen::Vector3d(0, -1, 0)}};
    std::vector<std::array<size_t, 3>> tris = {{
        {{0, 1, 2}},
        {{0, 1, 3}},
        {{0, 1, 4}},
    }};

    std::vector<Eigen::Vector3d> out_v;
    std::vector<std::array<size_t, 3>> out_f;
    std::vector<size_t> freeze_v;
    wmtk::separate_to_manifold(v, tris, out_v, out_f, freeze_v);
    REQUIRE(out_v.size() == 9);
    REQUIRE(out_f.size() == 3);

    // after extraction the output should be manifold
    Eigen::VectorXi dummy;
    Eigen::MatrixXd F(out_f.size(), 3);
    for (int i = 0; i < out_f.size(); i++) {
        F.row(i) << out_f[i][0], out_f[i][1], out_f[i][2];
    }
    REQUIRE(igl::is_edge_manifold(F));

    ShortestEdgeCollapse m(out_v);
    m.create_mesh(out_v.size(), out_f, freeze_v, 0);
    m.collapse_shortest(-1);
    Eigen::MatrixXi Fafter = Eigen::MatrixXi::Constant(m.tri_capacity(), 3, -1);
    for (auto& t : m.get_faces()) {
        auto i = t.fid(m);
        auto vs = m.oriented_tri_vertices(t);
        Fafter.row(i) << vs[0].vid(m), vs[1].vid(m), vs[2].vid(m);
    }
    // after operations the mesh is manifold
    REQUIRE(igl::is_edge_manifold(Fafter));
    REQUIRE(igl::is_vertex_manifold(Fafter, dummy));
}

TEST_CASE("manifold-separate-test-37989", "[test_sec]")
{
    std::string filename = WMT_DATA_DIR "/37989_sf.obj";
    wmtk::manifold_internal::Vertices V;
    wmtk::manifold_internal::Facets F;
    igl::read_triangle_mesh(filename, V, F);
    REQUIRE_FALSE(igl::is_edge_manifold(F));
    std::vector<size_t> modified_vertices;
    wmtk::manifold_internal::resolve_nonmanifoldness(V, F, modified_vertices);
    REQUIRE(modified_vertices.size() > 0);
    REQUIRE(igl::is_edge_manifold(F));
    Eigen::VectorXi VI;
    REQUIRE(igl::is_vertex_manifold(F, VI));
}

TEST_CASE("shortest_edge_collapse", "[test_sec]")
{
    // 0___1___2                *
    // \  /\  /                 *
    // 3\/__\/4  ==>    __      *
    //   \  /          \  /     *
    //    \/5           \/5     *
    // 3-4 is shortest

    std::vector<Eigen::Vector3d> v_positions(6);
    v_positions[0] = Eigen::Vector3d(-3, 3, 0);
    v_positions[1] = Eigen::Vector3d(0, 3, 0);
    v_positions[2] = Eigen::Vector3d(3, 3, 0);
    v_positions[3] = Eigen::Vector3d(0, 0, 0);
    v_positions[4] = Eigen::Vector3d(0.5, 0, 0);
    v_positions[5] = Eigen::Vector3d(0, -3, 0);
    ShortestEdgeCollapse m(v_positions);
    std::vector<std::array<size_t, 3>> tris = {{{0, 1, 3}}, {{1, 2, 4}}, {{1, 4, 3}}, {{3, 4, 5}}};
    m.create_mesh_nofreeze(6, tris);
    std::vector<TriMesh::Tuple> edges = m.get_edges();
    // find the shortest edge
    double shortest = std::numeric_limits<double>::max();
    TriMesh::Tuple shortest_edge;
    for (TriMesh::Tuple t : edges) {
        size_t v1 = t.vid(m);
        size_t v2 = m.switch_vertex(t).vid(m);
        if ((v_positions[v1] - v_positions[v2]).squaredNorm() < shortest) {
            shortest = (v_positions[v1] - v_positions[v2]).squaredNorm();
            shortest_edge = t;
        }
    }

    REQUIRE_FALSE(m.check_link_condition(shortest_edge));
    m.collapse_shortest(-1);

    REQUIRE_FALSE(shortest_edge.is_valid(m));

    REQUIRE(m.get_vertices().size() == 3);
    REQUIRE(m.get_faces().size() == 1);
}

TEST_CASE("shortest_edge_collapse_boundary_edge", "[test_sec]")
{
    // 0___1___2    0 __1___2      0 __1
    // \  /\  /      \  |  /         \ |
    // 3\/__\/4  ==>  \ | / ==>        6
    //                 \|/5
    //

    std::vector<Eigen::Vector3d> v_positions(6);
    v_positions[0] = Eigen::Vector3d(-3, 3, 0);
    v_positions[1] = Eigen::Vector3d(0, 3, 0);
    v_positions[2] = Eigen::Vector3d(3, 3, 0);
    v_positions[3] = Eigen::Vector3d(0, 0, 0);
    v_positions[4] = Eigen::Vector3d(0.5, 0, 0);
    ShortestEdgeCollapse m(v_positions);
    std::vector<std::array<size_t, 3>> tris = {{{0, 1, 3}}, {{1, 2, 4}}, {{3, 1, 4}}};
    m.create_mesh_nofreeze(5, tris);
    std::vector<TriMesh::Tuple> edges = m.get_edges();
    // find the shortest edge
    double shortest = std::numeric_limits<double>::max();
    TriMesh::Tuple shortest_edge;
    for (TriMesh::Tuple t : edges) {
        size_t v1 = t.vid(m);
        size_t v2 = m.switch_vertex(t).vid(m);
        if ((v_positions[v1] - v_positions[v2]).squaredNorm() < shortest) {
            shortest = (v_positions[v1] - v_positions[v2]).squaredNorm();
            shortest_edge = t;
        }
    }
    m.collapse_shortest(100);
    // the collapsed edge tuple is not valid anymore
    REQUIRE_FALSE(shortest_edge.is_valid(m));

    m.write_triangle_mesh("collapsed.obj");
    REQUIRE(m.get_vertices().size() == 3);
    REQUIRE(m.get_faces().size() == 1);
}

TEST_CASE("shortest_edge_collapse_closed_mesh", "[test_sec]")
{
    SECTION("test on tet")
    {
        // create a tet and collapse can't happen
        std::vector<Eigen::Vector3d> v_positions(6);
        v_positions[0] = Eigen::Vector3d(-3, 3, 0);
        v_positions[1] = Eigen::Vector3d(0, 3, 0);
        v_positions[2] = Eigen::Vector3d(0, 0, 2);
        v_positions[3] = Eigen::Vector3d(0, 0, 0);

        ShortestEdgeCollapse m(v_positions);
        std::vector<std::array<size_t, 3>> tris = {
            {{0, 1, 3}},
            {{1, 2, 3}},
            {{0, 3, 2}},
            {{0, 1, 2}}};
        m.create_mesh_nofreeze(4, tris);
        m.collapse_shortest(100);
        REQUIRE(m.vert_capacity() == 4);

        REQUIRE(m.tri_capacity() == 4);
    }
    SECTION("test on cube, end with tet")
    {
        // then test on a cube
        // will have a tet in the end
        const std::string root(WMT_DATA_DIR);
        const std::string path = root + "/piece_0.obj";

        Eigen::MatrixXd V;
        Eigen::MatrixXi F;
        bool ok = igl::read_triangle_mesh(path, V, F);

        REQUIRE(ok);

        REQUIRE(V.rows() == 8);
        REQUIRE(F.rows() == 12);

        std::vector<Eigen::Vector3d> v(V.rows());
        std::vector<std::array<size_t, 3>> tri(F.rows());
        for (int i = 0; i < V.rows(); i++) {
            v[i] = V.row(i);
        }
        for (int i = 0; i < F.rows(); i++) {
            for (int j = 0; j < 3; j++) tri[i][j] = (size_t)F(i, j);
        }
        ShortestEdgeCollapse m(v);
        m.create_mesh(V.rows(), tri);
        REQUIRE(m.check_mesh_connectivity_validity());
        REQUIRE(m.collapse_shortest(100));

        std::vector<TriMesh::Tuple> edges = m.get_edges();
        REQUIRE(m.get_vertices().size() == 4);

        REQUIRE(m.get_faces().size() == 4);
    }
}

TEST_CASE("shortest_edge_collapse_octocat", "[test_sec][.slow]")
{
    const std::string root(WMT_DATA_DIR);
    const std::string path = root + "/Octocat.obj";

    Eigen::MatrixXd V;
    Eigen::MatrixXi F;
    bool ok = igl::read_triangle_mesh(path, V, F);

    REQUIRE(ok);

    std::vector<Eigen::Vector3d> v(V.rows());
    std::vector<std::array<size_t, 3>> tri(F.rows());
    for (int i = 0; i < V.rows(); i++) {
        v[i] = V.row(i);
    }
    for (int i = 0; i < F.rows(); i++) {
        for (int j = 0; j < 3; j++) tri[i][j] = (size_t)F(i, j);
    }
    ShortestEdgeCollapse m(v);
    m.create_mesh(V.rows(), tri);
    REQUIRE(m.collapse_shortest(2000));
    REQUIRE(m.check_mesh_connectivity_validity());
}

TEST_CASE("edge_manifold", "[test_sec]")
{
    const std::string root(WMT_DATA_DIR);
    const std::string path = root + "/circle.obj";

    Eigen::MatrixXd V;
    Eigen::MatrixXi F;
    bool ok = igl::read_triangle_mesh(path, V, F);

    REQUIRE(ok);

    std::vector<Eigen::Vector3d> v(V.rows());
    std::vector<std::array<size_t, 3>> tri(F.rows());
    for (int i = 0; i < V.rows(); i++) {
        v[i] = V.row(i);
    }
    for (int i = 0; i < F.rows(); i++) {
        for (int j = 0; j < 3; j++) tri[i][j] = (size_t)F(i, j);
    }
    ShortestEdgeCollapse m(v);
    m.create_mesh(V.rows(), tri);
    REQUIRE(m.check_mesh_connectivity_validity());
    REQUIRE(igl::is_edge_manifold(F) == m.check_edge_manifold());
}

TEST_CASE("shortest_edge_collapse_circle", "[test_sec]")
{
    const std::string root(WMT_DATA_DIR);
    const std::string path = root + "/circle.obj";

    Eigen::MatrixXd V;
    Eigen::MatrixXi F;
    bool ok = igl::read_triangle_mesh(path, V, F);

    REQUIRE(ok);

    std::vector<Eigen::Vector3d> v(V.rows());
    std::vector<std::array<size_t, 3>> tri(F.rows());
    for (int i = 0; i < V.rows(); i++) {
        v[i] = V.row(i);
    }
    for (int i = 0; i < F.rows(); i++) {
        for (int j = 0; j < 3; j++) tri[i][j] = (size_t)F(i, j);
    }
    ShortestEdgeCollapse m(v);
    m.create_mesh(V.rows(), tri);
    REQUIRE(m.check_mesh_connectivity_validity());
    REQUIRE(igl::is_edge_manifold(F));
    REQUIRE(m.check_edge_manifold());
    REQUIRE(m.collapse_shortest(100));
    m.consolidate_mesh();
    m.write_triangle_mesh("collapsed.obj");
}

TEST_CASE("metis_test_bigmesh", "[test_sec][.slow]")
{
    const std::string root(WMT_DATA_DIR);
    const std::string path = root + "/circle.obj";

    Eigen::MatrixXd V;
    Eigen::MatrixXi F;
    bool ok = igl::read_triangle_mesh(path, V, F);
    REQUIRE(ok);

    // change this for max concurrency
    int max_num_threads = 8;

    std::vector<double> timecost;

    for (int thread = 1; thread <= max_num_threads; thread *= 2) {
        std::vector<Eigen::Vector3d> v(V.rows());
        std::vector<std::array<size_t, 3>> tri(F.rows());
        for (int i = 0; i < V.rows(); i++) {
            v[i] = V.row(i);
        }
        for (int i = 0; i < F.rows(); i++) {
            for (int j = 0; j < 3; j++) tri[i][j] = (size_t)F(i, j);
        }

        ShortestEdgeCollapse m(v, thread);
        // m.print_num_attributes();
        m.create_mesh(V.rows(), tri);
        REQUIRE(m.check_mesh_connectivity_validity());
        igl::Timer timer;
        double time;
        timer.start();

        // change this for num of operations
        m.collapse_shortest(20);
        time = timer.getElapsedTimeInMilliSec();
        timecost.push_back(time);
    }
}

max_stars_repo_name: wildmeshing/wildmeshing-toolkit

max_issues_repo_name: wildmeshing/wildmeshing-toolkit

max_forks_repo_name: wildmeshing/wildmeshing-toolkit


text:
#include <vector>
#include <cmath>
#include <Eigen/Core>
#include <Eigen/Cholesky>
#include <unsupported/Eigen/MatrixFunctions>

#include "ihgp/InfiniteHorizonGP.hpp"

const double InfiniteHorizonGP::DARE_EPS = 1e-10;
const int InfiniteHorizonGP::DARE_MAXIT = 100;

InfiniteHorizonGP::InfiniteHorizonGP(const double dt, const Eigen::MatrixXd &F, const Eigen::MatrixXd &HH, const Eigen::MatrixXd &Pinf, const double &R, const std::vector<Eigen::MatrixXd> &dF, const std::vector<Eigen::MatrixXd> &dPinf, const std::vector<double> &dR)
{
    // Solve A and Q (stationary systems)
    A = (F*dt).exp();
    Q = Pinf - A*Pinf*A.transpose();
    Rc = R;

    // Assign measurement model
    H = HH;

    // Solve the discrete algebraic Riccati equation
    Eigen::MatrixXd PP = InfiniteHorizonGP::DARE(A,H,Q,R);
    PP_update = PP;

    // Stationary innovation variance
    S = (H*PP*H.transpose())(0) + R;

    // Stationary gain
    K = PP*H.transpose()/S;

    // State covariance
    PF = PP - K*H*PP;

    // Pre-calculate
    HA = (H*A).transpose();
    AKHA = A-K*H*A;

    // Number of parameters
    nparam = (int)dF.size();

    // State dimensionality
    int dim = (int)F.rows();

    // Initialize mean and helpers
    m.setZero(dim);

    // Prepare
    Eigen::MatrixXd AK = A*K;
    Eigen::MatrixXd FF(2*dim,2*dim);
    FF.setZero();
    FF.topLeftCorner(dim,dim) = F;
    FF.bottomRightCorner(dim,dim) = F;

    // Allocate the arrays
    HdA  = new Eigen::VectorXd[nparam];
    dK = new Eigen::VectorXd[nparam];
    dAKHA = new Eigen::MatrixXd[nparam];
    dS = new double[nparam];
    dm = new Eigen::VectorXd[nparam];

    // Pre-calculate the needed derivative matrices
    for (int j=0; j<nparam; j++)
    {
        // Assign derivative of drift model matrix
        FF.bottomLeftCorner(dim,dim) = dF[j];

        // Solve the matrix exponential (see ...)
        Eigen::MatrixXd AA = (FF*dt).exp();

        // Extract the derivative of the discrete-time dynamic model
        Eigen::MatrixXd dA = AA.bottomLeftCorner(dim,dim);
        Eigen::MatrixXd dQ = dPinf[j] - dA*Pinf*A.transpose() - A*dPinf[j]*A.transpose() - A*Pinf*dA.transpose();
        dQ = .5*(dQ+dQ.transpose()).eval();

        // Precalculate C
        Eigen::MatrixXd C = dA*PP*A.transpose() + A*PP*dA.transpose() - dA*PP*H.transpose()*AK.transpose() - AK*H*PP*dA.transpose() + AK*dR[j]*AK.transpose() + dQ;
        C = .5*(C+C.transpose()).eval();

        // Solve DARE
        Eigen::MatrixXd dPP = InfiniteHorizonGP::DARE(A-AK*H,Eigen::MatrixXd::Zero(dim,dim),C,0.0);

        // Evaluate dS and dK
        dS[j] = (H*dPP*H.transpose())(0) + dR[j];
        dK[j] = dPP*H.transpose()/S - PP*H.transpose()*(((H*dPP*H.transpose())(0)+dR[j])/S/S);
        dAKHA[j] = dA - dK[j]*H*A - K*H*dA;
        HdA[j] = (H*dA).transpose();

        // Initial dm
        dm[j] = Eigen::VectorXd::Zero(dim);

    }

    // Initialize log likelihood and its gradient
    edata = 0;
    gdata = Eigen::VectorXd::Zero(nparam);
}

InfiniteHorizonGP::~InfiniteHorizonGP()
{
    delete[] HdA;
    delete[] dK;
    delete[] dAKHA;
    delete[] dS;
    delete[] dm;
}

void InfiniteHorizonGP::init_step()
{
    // Initialize log likelihood and its gradient
    edata = 0;
    gdata = Eigen::VectorXd::Zero(nparam);

    // Update
    // Stationary innovation variance
    S = (H*PP_update*H.transpose())(0) + Rc;

    // Stationary gain
    K = PP_update*H.transpose()/S;

    // State covariance
    PF = PP_update - K*H*PP_update;

    // Pre-calculate
    HA = (H*A).transpose();
    AKHA = A-K*H*A;

    //
    MF.clear();
}

void InfiniteHorizonGP::update(const double &y)
{
    // Define constants
    const double PI = 3.141592654;

    // Innovation mean
    double v = y - HA.dot(m);

    // Update marginal likelihood
    edata += .5*v*v/S + .5*log(2*PI) + .5*log(S);

    // Update derivatives
    for (int j=0; j<nparam; j++)
    {
        // Derivatives of innovation mean
        double dv = -HdA[j].dot(m) - HA.dot(dm[j]);

        // Derivatives of marginal likelihood
        gdata(j) += v*dv/S - .5*v*v*dS[j]/S/S + .5*dS[j]/S;

        // Derivatives of state mean
        dm[j] = dAKHA[j]*m + AKHA*dm[j] + dK[j]*y;
    }

    // Recursion for the state mean
    m = AKHA*m + K*y;

    // Store state mean for possible backward pass
    MF.push_back(m);

}

std::vector<double> InfiniteHorizonGP::getEft()
{
    // Solve backward smoother gain
    int dim = (int)A.rows();
    Eigen::MatrixXd PP = A*PF*A.transpose()+Q;
    Eigen::LDLT<Eigen::MatrixXd> PPldl = PP.ldlt();
    Eigen::MatrixXd G = PPldl.solve(A*PF).transpose();

    // Solve smoother state covariance
    // Eigen::MatrixXd QQ = PF-G*PP*G.transpose();
    // QQ = .5*(QQ+QQ.transpose()).eval();
    // P = InfiniteHorizonGP::DARE(G,Eigen::MatrixXd::Zero(dim,dim),QQ,0.0);

    // Output vector
    std::vector<double> Eft;

    // Initialize with last element
    m = MF[MF.size()-1];
    Eft.push_back((H*m)(0));

    // Run backward pass
    for (int k=(int)MF.size()-2; k>=0; k--)
    {
        m = MF[k] + G*(m-A*MF[k]);
        Eft.push_back((H*m)(0));
    }

    // Reverse
    std::reverse(Eft.begin(),Eft.end());

    return Eft;

}

double InfiniteHorizonGP::getVarft()
{
    return (H*P*H.transpose())(0);
}

double InfiniteHorizonGP::getLik()
{
    return edata;
}

Eigen::VectorXd InfiniteHorizonGP::getLikDeriv()
{
    return gdata;
}

Eigen::MatrixXd InfiniteHorizonGP::DARE(const Eigen::MatrixXd &A, const Eigen::MatrixXd &B, const Eigen::MatrixXd &Q, const double &R)
{

    // Initial guess
    int dim = (int)A.rows();
    Eigen::MatrixXd X(dim,dim);
    Eigen::MatrixXd X_prev(dim,dim);
    Eigen::MatrixXd K(dim,B.rows());
    X.setIdentity();

    // Number of loops
    int n = 0;

    // Iterate a maximum of 100 iterations
    while (n < DARE_MAXIT)
    {
        // Step
        n++;
        X_prev = X;

        // Gain (NB: Does not work in the general case, but for scalar R and possibly zero B)
        if (abs(R) < 1e-15)
        {
            K.setZero();
        } else {
            K = A*(X*B.transpose() / ((B*X*B.transpose())(0)+R));
        }

        // Recursion
        X = (A - K*B)*X*(A - K*B).transpose() + K*R*K.transpose() + Q;

        // Check if we should break (use the Frobenius norm)
        if ((X-X_prev).norm() < DARE_EPS)
        {
            break;
        }
    }

    return X;
}


text:
#include <iostream>
#include <boost/thread.hpp>

#include <ros/ros.h>
#include <std_msgs/Bool.h>
#include <sensor_msgs/Range.h>
#include <random_numbers/random_numbers.h>

using namespace std;

int main(int argc, char** argv){

	ros::init(argc, argv, "fsm_roomba_events");

	ros::NodeHandle node;
	random_numbers::RandomNumberGenerator randomizer;

	ros::Publisher leftBumperPub = node.advertise<std_msgs::Bool>("/roomba/left_bumper", 1, false);
	ros::Publisher rightBumperPub = node.advertise<std_msgs::Bool>("/roomba/right_bumper", 1, false);
	ros::Publisher wallSensorPub = node.advertise<sensor_msgs::Range>("/roomba/wall_sensor", 1, false);

	ROS_INFO("Starting roomba event publisher...");

	while (ros::ok()) {
	    std_msgs::Bool leftBumper, rightBumper;
	    sensor_msgs::Range wallSensor;

	    wallSensor.range = randomizer.uniformReal(0.2, 3);
	    leftBumper.data = randomizer.uniformInteger(1, 5) == 1;
	    rightBumper.data = randomizer.uniformInteger(1, 5) == 1;

	    leftBumperPub.publish(leftBumper);
	    rightBumperPub.publish(rightBumper);
	    wallSensorPub.publish(wallSensor);

	    boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
	}

	return 0;
}


text:
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<ctime>
#include <boost/random.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/variate_generator.hpp>
#include<fstream>
#include<string>
#include <numeric>
using namespace std;
// Function to print the vector
void PrintData(vector<double>& data);
// Function to print the matrix
void PrintData(vector< vector<double> >& data);

// Function to do Cholesky decomposition
vector< vector<double> > Cholesky(vector< vector<double> >& data);

//Function to write matrix into csv file
void WriteToCsv(string CsvFile, vector< vector<double> >& data);

//Function to write vector into csv file
void WriteToCsv(string CsvFile, vector<double>& data);

// Function to calculate standard deviation
double CaclVariance(vector<double>& data);

max_stars_repo_name: icezerowjj/Monte-Carlo-Simulation

max_issues_repo_name: icezerowjj/Monte-Carlo-Option-Pricing

max_forks_repo_name: icezerowjj/Monte-Carlo-Option-Pricing