<commit_before>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_COMMON_FLOAT_CMP_HH
#define DUNE_STUFF_COMMON_FLOAT_CMP_HH

#include <dune/stuff/common/disable_warnings.hh>
# include <dune/common/float_cmp.hh>
# include <dune/common/fvector.hh>
#include <dune/stuff/common/reenable_warnings.hh>
#include <dune/common/dynvector.hh>

#include <dune/stuff/la/container/interfaces.hh>

#include <type_traits>

namespace Dune {
namespace Stuff {
namespace Common {
namespace FloatCmp {

#define DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(id) \
  template< class T, Dune::FloatCmp::CmpStyle style = Dune::FloatCmp::defaultCmpStyle > \
  typename std::enable_if< std::is_arithmetic< T >::value, bool >::type \
    id (const T& first, \
        const T& second, \
        typename Dune::FloatCmp::EpsilonType< T >::Type epsilon = Dune::FloatCmp::DefaultEpsilon< T, style >::value()) \
  { \
    return Dune::FloatCmp:: id < T, style >(first, second, epsilon); \
  } \
 \
  template< class T, Dune::FloatCmp::CmpStyle style = Dune::FloatCmp::defaultCmpStyle > \
  typename std::enable_if< std::is_arithmetic< T >::value, bool >::type \
    id (const std::vector< T >& first, \
        const std::vector< T >& second, \
        typename Dune::FloatCmp::EpsilonType< T >::Type epsilon = Dune::FloatCmp::DefaultEpsilon< T, style >::value()) \
  { \
    assert(first.size() == second.size()); \
    for (size_t ii = 0; ii < first.size(); ++ii) \
      if (!Dune::FloatCmp:: id < T, style >(first[ii], second[ii], epsilon)) \
        return false; \
      return true; \
  } \
 \
  template< class T, Dune::FloatCmp::CmpStyle style = Dune::FloatCmp::defaultCmpStyle > \
  bool id (const Dune::DynamicVector< T >& first, \
           const Dune::DynamicVector< T >& second, \
           typename Dune::FloatCmp::EpsilonType< T >::Type epsilon = Dune::FloatCmp::DefaultEpsilon< T, style >::value()) \
  { \
    assert(first.size() == second.size()); \
    for (size_t ii = 0; ii < first.size(); ++ii) \
      if (!Dune::FloatCmp:: id < T, style >(first[ii], second[ii], epsilon)) \
        return false; \
      return true; \
  } \
 \
  template< class T, int size, Dune::FloatCmp::CmpStyle style = Dune::FloatCmp::defaultCmpStyle > \
  bool id (const Dune::FieldVector< T, size >& first, \
           const Dune::FieldVector< T, size >& second, \
           typename Dune::FloatCmp::EpsilonType< T >::Type epsilon = Dune::FloatCmp::DefaultEpsilon< T, style >::value()) \
  { \
    for (size_t ii = 0; ii < size; ++ii) \
      if (!Dune::FloatCmp:: id < T, style >(first[ii], second[ii], epsilon)) \
        return false; \
    return true; \
  } \
  template< class F, class S, Dune::FloatCmp::CmpStyle style = Dune::FloatCmp::defaultCmpStyle > \
  bool id (const Stuff::LA::VectorInterface< F >& first, \
           const Stuff::LA::VectorInterface< S >& second, \
           typename Dune::FloatCmp::EpsilonType< typename F::ScalarType >::Type epsilon = Dune::FloatCmp::DefaultEpsilon< typename F::ScalarType, style >::value()) \
  { \
    assert(first.size() == second.size()); \
    for (size_t ii = 0; ii < first.size(); ++ii) \
      if (!Dune::FloatCmp:: id < typename F::ScalarType, style >(first[ii], second[ii], epsilon)) \
        return false; \
    return true; \
  }
// DUNE_STUFF_GENERATE_VECTOR_COMPARATOR

DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(eq)
DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(ne)
DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(gt)
DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(lt)
DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(ge)
DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(le)

#undef DUNE_STUFF_GENERATE_VECTOR_COMPARATOR

} // namespace FloatCmp
} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_COMMON_FLOAT_CMP_HH
<commit_msg>[common.float_cmp] implement vec_ne with diff. semantics from ne<commit_after>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_COMMON_FLOAT_CMP_HH
#define DUNE_STUFF_COMMON_FLOAT_CMP_HH

#include <dune/stuff/common/disable_warnings.hh>
# include <dune/common/float_cmp.hh>
# include <dune/common/fvector.hh>
#include <dune/stuff/common/reenable_warnings.hh>
#include <dune/common/dynvector.hh>

#include <dune/stuff/la/container/interfaces.hh>

#include <type_traits>

namespace Dune {
namespace Stuff {
namespace Common {
namespace FloatCmp {

#define DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(id) \
  template< class T, Dune::FloatCmp::CmpStyle style = Dune::FloatCmp::defaultCmpStyle > \
  typename std::enable_if< std::is_arithmetic< T >::value, bool >::type \
    id (const T& first, \
        const T& second, \
        typename Dune::FloatCmp::EpsilonType< T >::Type epsilon = Dune::FloatCmp::DefaultEpsilon< T, style >::value()) \
  { \
    return Dune::FloatCmp:: id < T, style >(first, second, epsilon); \
  } \
 \
  template< class T, Dune::FloatCmp::CmpStyle style = Dune::FloatCmp::defaultCmpStyle > \
  typename std::enable_if< std::is_arithmetic< T >::value, bool >::type \
    id (const std::vector< T >& first, \
        const std::vector< T >& second, \
        typename Dune::FloatCmp::EpsilonType< T >::Type epsilon = Dune::FloatCmp::DefaultEpsilon< T, style >::value()) \
  { \
    assert(first.size() == second.size()); \
    for (size_t ii = 0; ii < first.size(); ++ii) \
      if (!Dune::FloatCmp:: id < T, style >(first[ii], second[ii], epsilon)) \
        return false; \
      return true; \
  } \
 \
  template< class T, Dune::FloatCmp::CmpStyle style = Dune::FloatCmp::defaultCmpStyle > \
  bool id (const Dune::DynamicVector< T >& first, \
           const Dune::DynamicVector< T >& second, \
           typename Dune::FloatCmp::EpsilonType< T >::Type epsilon = Dune::FloatCmp::DefaultEpsilon< T, style >::value()) \
  { \
    assert(first.size() == second.size()); \
    for (size_t ii = 0; ii < first.size(); ++ii) \
      if (!Dune::FloatCmp:: id < T, style >(first[ii], second[ii], epsilon)) \
        return false; \
      return true; \
  } \
 \
  template< class T, int size, Dune::FloatCmp::CmpStyle style = Dune::FloatCmp::defaultCmpStyle > \
  bool id (const Dune::FieldVector< T, size >& first, \
           const Dune::FieldVector< T, size >& second, \
           typename Dune::FloatCmp::EpsilonType< T >::Type epsilon = Dune::FloatCmp::DefaultEpsilon< T, style >::value()) \
  { \
    for (size_t ii = 0; ii < size; ++ii) \
      if (!Dune::FloatCmp:: id < T, style >(first[ii], second[ii], epsilon)) \
        return false; \
    return true; \
  } \
  template< class F, class S, Dune::FloatCmp::CmpStyle style = Dune::FloatCmp::defaultCmpStyle > \
  bool id (const Stuff::LA::VectorInterface< F >& first, \
           const Stuff::LA::VectorInterface< S >& second, \
           typename Dune::FloatCmp::EpsilonType< typename F::ScalarType >::Type epsilon = Dune::FloatCmp::DefaultEpsilon< typename F::ScalarType, style >::value()) \
  { \
    assert(first.size() == second.size()); \
    for (size_t ii = 0; ii < first.size(); ++ii) \
      if (!Dune::FloatCmp:: id < typename F::ScalarType, style >(first[ii], second[ii], epsilon)) \
        return false; \
    return true; \
  }
// DUNE_STUFF_GENERATE_VECTOR_COMPARATOR

DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(eq)
DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(ne)
DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(gt)
DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(lt)
DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(ge)
DUNE_STUFF_GENERATE_VECTOR_COMPARATOR(le)

#undef DUNE_STUFF_GENERATE_VECTOR_COMPARATOR

template< class T, int size, Dune::FloatCmp::CmpStyle style = Dune::FloatCmp::defaultCmpStyle >
bool vec_ne (const Dune::FieldVector< T, size >& first,
         const Dune::FieldVector< T, size >& second,
         typename Dune::FloatCmp::EpsilonType< T >::Type epsilon = Dune::FloatCmp::DefaultEpsilon< T, style >::value())
{
  return !eq(first, second, epsilon);
}

} // namespace FloatCmp
} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_COMMON_FLOAT_CMP_HH
<|endoftext|>


<commit_before>#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "Cow.h"

cCow::cCow(void) :
	super("Cow", 92, "mob.cow.hurt", "mob.cow.hurt", 0.9, 1.3)
{
}

void cCow::GetDrops(cItems & a_Drops, cEntity * a_Killer)
{
	AddRandomDropItem(a_Drops, 0, 2, E_ITEM_LEATHER);
	AddRandomDropItem(a_Drops, 1, 3, IsOnFire() ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
}

void cCow::OnRightClicked(cPlayer & a_Player)
{
	if ((a_Player.GetEquippedItem().m_ItemType == E_ITEM_BUCKET))
	{
		if (!a_Player.IsGameModeCreative())
		{
			a_Player.GetInventory().RemoveOneEquippedItem();
			a_Player.GetInventory().AddItem(E_ITEM_MILK)
		}

	}
}

<commit_msg>Added extra line (yes, again)<commit_after>
#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "Cow.h"

cCow::cCow(void) :
	super("Cow", 92, "mob.cow.hurt", "mob.cow.hurt", 0.9, 1.3)
{
}

void cCow::GetDrops(cItems & a_Drops, cEntity * a_Killer)
{
	AddRandomDropItem(a_Drops, 0, 2, E_ITEM_LEATHER);
	AddRandomDropItem(a_Drops, 1, 3, IsOnFire() ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
}

void cCow::OnRightClicked(cPlayer & a_Player)
{
	if ((a_Player.GetEquippedItem().m_ItemType == E_ITEM_BUCKET))
	{
		if (!a_Player.IsGameModeCreative())
		{
			a_Player.GetInventory().RemoveOneEquippedItem();
			a_Player.GetInventory().AddItem(E_ITEM_MILK)
		}

	}
}

<|endoftext|>


<commit_before>///
/// @file  BitSieve.cpp
/// @brief The BitSieve class is a bit array for use with
///        Eratosthenes-like prime sieving algorithms. BitSieve
///        assigns 64 numbers to the bits of an 8 byte word thus
///        reducing the memory usage by a factor of 8.
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <BitSieve.hpp>
#include <popcnt.hpp>
#include <imath.hpp>

#include <stdint.h>
#include <algorithm>
#include <cassert>
#include <cstring>
#include <vector>

using namespace std;

namespace {

/// 1-indexing: primes[1] = 2, primes[2] = 3, ...
const uint64_t primes[] = { 0, 2, 3, 5, 7, 11, 13, 17, 19, 23 };

/// Bitmasks with multiples of the i-th prime set
const uint64_t masks[] =
{
  0x0000000000000000ull,
  0x5555555555555555ull, // 2
  0x9249249249249249ull, // 3
  0x1084210842108421ull, // 5
  0x8102040810204081ull, // 7
  0x0080100200400801ull, // 11
  0x0010008004002001ull, // 13
  0x0008000400020001ull, // 17
  0x0200004000080001ull, // 19
  0x0000400000800001ull  // 23
};

uint64_t unset_mask(uint64_t mask, uint64_t shift)
{
  return ~(mask << shift);
}

uint64_t fast_modulo(uint64_t x, uint64_t y)
{
  assert(x < y * 2);
  x = (x < y) ? x : x - y;
  return x;
}

} // namespace

namespace primecount {

const uint64_t BitSieve::unset_bit_[64] =
{
  ~(1ull <<  0), ~(1ull <<  1), ~(1ull <<  2), ~(1ull <<  3),
  ~(1ull <<  4), ~(1ull <<  5), ~(1ull <<  6), ~(1ull <<  7),
  ~(1ull <<  8), ~(1ull <<  9), ~(1ull << 10), ~(1ull << 11),
  ~(1ull << 12), ~(1ull << 13), ~(1ull << 14), ~(1ull << 15),
  ~(1ull << 16), ~(1ull << 17), ~(1ull << 18), ~(1ull << 19),
  ~(1ull << 20), ~(1ull << 21), ~(1ull << 22), ~(1ull << 23),
  ~(1ull << 24), ~(1ull << 25), ~(1ull << 26), ~(1ull << 27),
  ~(1ull << 28), ~(1ull << 29), ~(1ull << 30), ~(1ull << 31),
  ~(1ull << 32), ~(1ull << 33), ~(1ull << 34), ~(1ull << 35),
  ~(1ull << 36), ~(1ull << 37), ~(1ull << 38), ~(1ull << 39),
  ~(1ull << 40), ~(1ull << 41), ~(1ull << 42), ~(1ull << 43),
  ~(1ull << 44), ~(1ull << 45), ~(1ull << 46), ~(1ull << 47),
  ~(1ull << 48), ~(1ull << 49), ~(1ull << 50), ~(1ull << 51),
  ~(1ull << 52), ~(1ull << 53), ~(1ull << 54), ~(1ull << 55),
  ~(1ull << 56), ~(1ull << 57), ~(1ull << 58), ~(1ull << 59),
  ~(1ull << 60), ~(1ull << 61), ~(1ull << 62), ~(1ull << 63)
};

BitSieve::BitSieve(std::size_t size) :
  sieve_(ceil_div(size, 64)),
  size_(size)
{ }

/// Pre-sieve the multiples (>= low) of the first c primes.
/// @warning Also removes the first c primes.
/// @pre c < 10
///
void BitSieve::pre_sieve(uint64_t c, uint64_t low)
{
  assert(c < 10);

  if (sieve_.empty())
    return;

  // unset multiples of 2
  sieve_[0] = unset_mask(masks[1], low % 2);

  uint64_t last = 1;
  uint64_t sieved = last;
  uint64_t sieve_size = sieve_.size();

  // pre-sieve multiples of first c primes
  for (uint64_t i = 2; i <= c; i++)
  {
    uint64_t prime = primes[i];
    uint64_t end_copy = min(sieved * prime, sieve_size);

    // pre-sieve multiples of primes < i-th prime
    // by copying a small pre-sieved buffer
    while (last < end_copy)
    {
      uint64_t copy_words = min(sieved, sieve_size - last);
      copy(sieve_.begin(),
           sieve_.begin() + copy_words,
           sieve_.begin() + last);
      last += copy_words;
    }

    // calculate first multiple >= low of prime
    uint64_t multiple = ceil_div(low, prime) * prime;
    uint64_t shift = multiple - low;
    uint64_t next_shift = prime - 64 % prime;
    uint64_t mask = masks[i];

    // pre-sieve multiples of the i-th prime
    for (uint64_t j = 0; j < last; j++)
    {
      sieve_[j] &= unset_mask(mask, shift);
      shift = fast_modulo(shift + next_shift, prime);
    }

    sieved = last;
  }

  // fill up the rest of the sieve
  while (last < sieve_size)
  {
    uint64_t copy_words = min(sieved, sieve_size - last);
    copy(sieve_.begin(),
         sieve_.begin() + copy_words,
         sieve_.begin() + last);
    last += copy_words;
  }
}

/// Count the number of 1 bits inside [start, stop]
uint64_t BitSieve::count(uint64_t start,
                         uint64_t stop) const
{
  if (start > stop)
    return 0;

  assert(stop < size_);

  uint64_t start_idx = start / 64;
  uint64_t stop_idx = stop / 64;
  uint64_t m1 = 0xffffffffffffffffull << (start % 64);
  uint64_t m2 = 0xffffffffffffffffull >> (63 - stop % 64);
  uint64_t bit_count;

  if (start_idx == stop_idx)
    bit_count = popcnt64(sieve_[start_idx] & (m1 & m2));
  else
  {
    bit_count = popcnt64(sieve_[start_idx] & m1);
    bit_count += popcnt(&sieve_[start_idx + 1], stop_idx - (start_idx + 1));
    bit_count += popcnt64(sieve_[stop_idx] & m2);
  }

  return bit_count;
}

} // namespace
<commit_msg>Use std::array instead of C-style arrays<commit_after>///
/// @file  BitSieve.cpp
/// @brief The BitSieve class is a bit array for use with
///        Eratosthenes-like prime sieving algorithms. BitSieve
///        assigns 64 numbers to the bits of an 8 byte word thus
///        reducing the memory usage by a factor of 8.
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <BitSieve.hpp>
#include <popcnt.hpp>
#include <imath.hpp>

#include <stdint.h>
#include <algorithm>
#include <array>
#include <cassert>
#include <cstring>
#include <vector>

using namespace std;

namespace {

/// primes[1] = 2, primes[2] = 3, ...
const array<uint64_t, 10> primes = { 0, 2, 3, 5, 7, 11, 13, 17, 19, 23 };

/// Bitmasks with multiples of the i-th prime set
const array<uint64_t, 10> masks =
{
  0x0000000000000000ull,
  0x5555555555555555ull, // 2
  0x9249249249249249ull, // 3
  0x1084210842108421ull, // 5
  0x8102040810204081ull, // 7
  0x0080100200400801ull, // 11
  0x0010008004002001ull, // 13
  0x0008000400020001ull, // 17
  0x0200004000080001ull, // 19
  0x0000400000800001ull  // 23
};

uint64_t unset_mask(uint64_t mask, uint64_t shift)
{
  return ~(mask << shift);
}

uint64_t fast_modulo(uint64_t x, uint64_t y)
{
  assert(x < y * 2);
  x = (x < y) ? x : x - y;
  return x;
}

} // namespace

namespace primecount {

const uint64_t BitSieve::unset_bit_[64] =
{
  ~(1ull <<  0), ~(1ull <<  1), ~(1ull <<  2), ~(1ull <<  3),
  ~(1ull <<  4), ~(1ull <<  5), ~(1ull <<  6), ~(1ull <<  7),
  ~(1ull <<  8), ~(1ull <<  9), ~(1ull << 10), ~(1ull << 11),
  ~(1ull << 12), ~(1ull << 13), ~(1ull << 14), ~(1ull << 15),
  ~(1ull << 16), ~(1ull << 17), ~(1ull << 18), ~(1ull << 19),
  ~(1ull << 20), ~(1ull << 21), ~(1ull << 22), ~(1ull << 23),
  ~(1ull << 24), ~(1ull << 25), ~(1ull << 26), ~(1ull << 27),
  ~(1ull << 28), ~(1ull << 29), ~(1ull << 30), ~(1ull << 31),
  ~(1ull << 32), ~(1ull << 33), ~(1ull << 34), ~(1ull << 35),
  ~(1ull << 36), ~(1ull << 37), ~(1ull << 38), ~(1ull << 39),
  ~(1ull << 40), ~(1ull << 41), ~(1ull << 42), ~(1ull << 43),
  ~(1ull << 44), ~(1ull << 45), ~(1ull << 46), ~(1ull << 47),
  ~(1ull << 48), ~(1ull << 49), ~(1ull << 50), ~(1ull << 51),
  ~(1ull << 52), ~(1ull << 53), ~(1ull << 54), ~(1ull << 55),
  ~(1ull << 56), ~(1ull << 57), ~(1ull << 58), ~(1ull << 59),
  ~(1ull << 60), ~(1ull << 61), ~(1ull << 62), ~(1ull << 63)
};

BitSieve::BitSieve(std::size_t size) :
  sieve_(ceil_div(size, 64)),
  size_(size)
{ }

/// Pre-sieve the multiples (>= low) of the first c primes.
/// @warning Also removes the first c primes.
/// @pre c < 10
///
void BitSieve::pre_sieve(uint64_t c, uint64_t low)
{
  assert(c < primes.size());

  if (sieve_.empty())
    return;

  // unset multiples of 2
  sieve_[0] = unset_mask(masks[1], low % 2);

  uint64_t last = 1;
  uint64_t sieved = last;
  uint64_t sieve_size = sieve_.size();

  // pre-sieve multiples of first c primes
  for (uint64_t i = 2; i <= c; i++)
  {
    uint64_t prime = primes[i];
    uint64_t end_copy = min(sieved * prime, sieve_size);

    // pre-sieve multiples of primes < i-th prime
    // by copying a small pre-sieved buffer
    while (last < end_copy)
    {
      uint64_t copy_words = min(sieved, sieve_size - last);
      copy(sieve_.begin(),
           sieve_.begin() + copy_words,
           sieve_.begin() + last);
      last += copy_words;
    }

    // calculate first multiple >= low of prime
    uint64_t multiple = ceil_div(low, prime) * prime;
    uint64_t shift = multiple - low;
    uint64_t next_shift = prime - 64 % prime;
    uint64_t mask = masks[i];

    // pre-sieve multiples of the i-th prime
    for (uint64_t j = 0; j < last; j++)
    {
      sieve_[j] &= unset_mask(mask, shift);
      shift = fast_modulo(shift + next_shift, prime);
    }

    sieved = last;
  }

  // fill up the rest of the sieve
  while (last < sieve_size)
  {
    uint64_t copy_words = min(sieved, sieve_size - last);
    copy(sieve_.begin(),
         sieve_.begin() + copy_words,
         sieve_.begin() + last);
    last += copy_words;
  }
}

/// Count the number of 1 bits inside [start, stop]
uint64_t BitSieve::count(uint64_t start,
                         uint64_t stop) const
{
  if (start > stop)
    return 0;

  assert(stop < size_);

  uint64_t start_idx = start / 64;
  uint64_t stop_idx = stop / 64;
  uint64_t m1 = 0xffffffffffffffffull << (start % 64);
  uint64_t m2 = 0xffffffffffffffffull >> (63 - stop % 64);
  uint64_t bit_count;

  if (start_idx == stop_idx)
    bit_count = popcnt64(sieve_[start_idx] & (m1 & m2));
  else
  {
    bit_count = popcnt64(sieve_[start_idx] & m1);
    bit_count += popcnt(&sieve_[start_idx + 1], stop_idx - (start_idx + 1));
    bit_count += popcnt64(sieve_[stop_idx] & m2);
  }

  return bit_count;
}

} // namespace
<|endoftext|>


<commit_before>// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/compiler/runtime_api.h"

#if !defined(DART_PRECOMPILED_RUNTIME)

#include "vm/longjump.h"
#include "vm/object.h"

namespace dart {
namespace compiler {

bool IsSameObject(const Object& a, const Object& b) {
  return a.raw() == b.raw();
}

bool IsNotTemporaryScopedHandle(const Object& obj) {
  return obj.IsNotTemporaryScopedHandle();
}

bool IsInOldSpace(const Object& obj) {
  return obj.IsOld();
}

intptr_t ObjectHash(const Object& obj) {
  if (obj.IsNull()) {
    return 2011;
  }
  if (obj.IsString() || obj.IsNumber()) {
    return Instance::Cast(obj).CanonicalizeHash();
  }
  if (obj.IsCode()) {
    // Instructions don't move during compaction.
    return Code::Cast(obj).PayloadStart();
  }
  if (obj.IsFunction()) {
    return Function::Cast(obj).Hash();
  }
  if (obj.IsField()) {
    return dart::String::HashRawSymbol(Field::Cast(obj).name());
  }
  // Unlikely.
  return obj.GetClassId();
}

void SetToNull(Object* obj) {
  *obj = Object::null();
}

Object& NewZoneHandle(Zone* zone) {
  return Object::ZoneHandle(zone, Object::null());
}

Object& NewZoneHandle(Zone* zone, const Object& obj) {
  return Object::ZoneHandle(zone, obj.raw());
}

bool IsOriginalObject(const Object& object) {
  if (object.IsICData()) {
    return ICData::Cast(object).IsOriginal();
  } else if (object.IsField()) {
    return Field::Cast(object).IsOriginal();
  }
  return true;
}

const String& AllocateString(const char* buffer) {
  return String::ZoneHandle(String::New(buffer));
}

bool HasIntegerValue(const dart::Object& object, int64_t* value) {
  if (object.IsInteger()) {
    *value = Integer::Cast(object).AsInt64Value();
    return true;
  }
  return false;
}

int32_t CreateJitCookie() {
  return static_cast<int32_t>(Isolate::Current()->random()->NextUInt32());
}

void BailoutWithBranchOffsetError() {
  Thread::Current()->long_jump_base()->Jump(1, Object::branch_offset_error());
}

namespace target {

uint32_t MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size) {
  return dart::RawObject::SizeTag::encode(instance_size) |
         dart::RawObject::ClassIdTag::encode(cid) |
         dart::RawObject::NewBit::encode(true);
}

word Object::tags_offset() {
  return dart::Object::tags_offset();
}

const word RawObject::kClassIdTagPos = dart::RawObject::kClassIdTagPos;

const word RawObject::kClassIdTagSize = dart::RawObject::kClassIdTagSize;

const word RawObject::kBarrierOverlapShift =
    dart::RawObject::kBarrierOverlapShift;

intptr_t ObjectPool::element_offset(intptr_t index) {
  return dart::ObjectPool::element_offset(index);
}

classid_t Class::GetId(const dart::Class& handle) {
  return handle.id();
}

uword Class::GetInstanceSize(const dart::Class& handle) {
  return handle.instance_size();
}

word Instance::DataOffsetFor(intptr_t cid) {
  return dart::Instance::DataOffsetFor(cid);
}

bool Heap::IsAllocatableInNewSpace(intptr_t instance_size) {
  return dart::Heap::IsAllocatableInNewSpace(instance_size);
}

word Thread::top_offset() {
  return dart::Thread::top_offset();
}

word Thread::end_offset() {
  return dart::Thread::end_offset();
}

word Thread::isolate_offset() {
  return dart::Thread::isolate_offset();
}

#if !defined(TARGET_ARCH_DBC)
word Thread::call_to_runtime_entry_point_offset() {
  return dart::Thread::call_to_runtime_entry_point_offset();
}

word Thread::null_error_shared_with_fpu_regs_entry_point_offset() {
  return dart::Thread::null_error_shared_with_fpu_regs_entry_point_offset();
}

word Thread::null_error_shared_without_fpu_regs_entry_point_offset() {
  return dart::Thread::null_error_shared_without_fpu_regs_entry_point_offset();
}

word Thread::monomorphic_miss_entry_offset() {
  return dart::Thread::monomorphic_miss_entry_offset();
}

word Thread::write_barrier_mask_offset() {
  return dart::Thread::write_barrier_mask_offset();
}

word Thread::write_barrier_entry_point_offset() {
  return dart::Thread::write_barrier_entry_point_offset();
}

word Thread::array_write_barrier_entry_point_offset() {
  return dart::Thread::array_write_barrier_entry_point_offset();
}
#endif  // !defined(TARGET_ARCH_DBC)

#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) ||                  \
    defined(TARGET_ARCH_X64)
word Thread::write_barrier_wrappers_thread_offset(intptr_t regno) {
  return dart::Thread::write_barrier_wrappers_thread_offset(
      static_cast<Register>(regno));
}
#endif

word Thread::vm_tag_offset() {
  return dart::Thread::vm_tag_offset();
}

#define DECLARE_CONSTANT_OFFSET_GETTER(name)                                   \
  word Thread::name##_address_offset() {                                       \
    return dart::Thread::name##_address_offset();                              \
  }
THREAD_XMM_CONSTANT_LIST(DECLARE_CONSTANT_OFFSET_GETTER)
#undef DECLARE_CONSTANT_OFFSET_GETTER

word Isolate::class_table_offset() {
  return dart::Isolate::class_table_offset();
}

word ClassTable::table_offset() {
  return dart::ClassTable::table_offset();
}

#if !defined(PRODUCT)
word ClassTable::ClassOffsetFor(intptr_t cid) {
  return dart::ClassTable::ClassOffsetFor(cid);
}

word ClassTable::StateOffsetFor(intptr_t cid) {
  return dart::ClassTable::StateOffsetFor(cid);
}

word ClassTable::TableOffsetFor(intptr_t cid) {
  return dart::ClassTable::TableOffsetFor(cid);
}

word ClassTable::CounterOffsetFor(intptr_t cid, bool is_new) {
  return dart::ClassTable::CounterOffsetFor(cid, is_new);
}

word ClassTable::SizeOffsetFor(intptr_t cid, bool is_new) {
  return dart::ClassTable::SizeOffsetFor(cid, is_new);
}
#endif  // !defined(PRODUCT)

const word ClassTable::kSizeOfClassPairLog2 = dart::kSizeOfClassPairLog2;

const intptr_t Instructions::kPolymorphicEntryOffset =
    dart::Instructions::kPolymorphicEntryOffset;

const intptr_t Instructions::kMonomorphicEntryOffset =
    dart::Instructions::kMonomorphicEntryOffset;

intptr_t Instructions::HeaderSize() {
  return dart::Instructions::HeaderSize();
}

intptr_t Code::object_pool_offset() {
  return dart::Code::object_pool_offset();
}

intptr_t Code::saved_instructions_offset() {
  return dart::Code::saved_instructions_offset();
}

intptr_t Code::entry_point_offset(CodeEntryKind kind) {
  return dart::Code::entry_point_offset(kind);
}

#if !defined(PRODUCT)
word ClassHeapStats::TraceAllocationMask() {
  return dart::ClassHeapStats::TraceAllocationMask();
}

word ClassHeapStats::state_offset() {
  return dart::ClassHeapStats::state_offset();
}

word ClassHeapStats::allocated_since_gc_new_space_offset() {
  return dart::ClassHeapStats::allocated_since_gc_new_space_offset();
}

word ClassHeapStats::allocated_size_since_gc_new_space_offset() {
  return dart::ClassHeapStats::allocated_size_since_gc_new_space_offset();
}
#endif  // !defined(PRODUCT)

word Double::value_offset() {
  return dart::Double::value_offset();
}

word Float32x4::value_offset() {
  return dart::Float32x4::value_offset();
}

word Float64x2::value_offset() {
  return dart::Float64x2::value_offset();
}

bool IsSmi(const dart::Object& a) {
  return a.IsSmi();
}

word ToRawSmi(const dart::Object& a) {
  ASSERT(a.IsSmi());
  return reinterpret_cast<word>(a.raw());
}

word ToRawSmi(intptr_t value) {
  return dart::Smi::RawValue(value);
}

bool CanLoadFromThread(const dart::Object& object,
                       word* offset /* = nullptr */) {
  if (dart::Thread::CanLoadFromThread(object)) {
    if (offset != nullptr) {
      *offset = dart::Thread::OffsetFromThread(object);
    }
    return true;
  }
  return false;
}

#if defined(TARGET_ARCH_IA32)
uword Code::EntryPointOf(const dart::Code& code) {
  static_assert(kHostWordSize == kWordSize,
                "Can't embed raw pointers to runtime objects when host and "
                "target word sizes are different");
  return code.EntryPoint();
}

bool CanEmbedAsRawPointerInGeneratedCode(const dart::Object& obj) {
  return obj.IsSmi() || obj.InVMHeap();
}

word ToRawPointer(const dart::Object& a) {
  static_assert(kHostWordSize == kWordSize,
                "Can't embed raw pointers to runtime objects when host and "
                "target word sizes are different");
  return reinterpret_cast<word>(a.raw());
}
#endif  // defined(TARGET_ARCH_IA32)

}  // namespace target
}  // namespace compiler
}  // namespace dart

#endif  // !defined(DART_PRECOMPILED_RUNTIME)
<commit_msg>[vm] Fix disassembler test after f496e538f4587f29562e161ca6b06f169396f499<commit_after>// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/compiler/runtime_api.h"

#if !defined(DART_PRECOMPILED_RUNTIME)

#include "vm/longjump.h"
#include "vm/object.h"

namespace dart {
namespace compiler {

bool IsSameObject(const Object& a, const Object& b) {
  return a.raw() == b.raw();
}

bool IsNotTemporaryScopedHandle(const Object& obj) {
  return obj.IsNotTemporaryScopedHandle();
}

bool IsInOldSpace(const Object& obj) {
  return obj.IsOld();
}

intptr_t ObjectHash(const Object& obj) {
  if (obj.IsNull()) {
    return 2011;
  }
  if (obj.IsString() || obj.IsNumber()) {
    return Instance::Cast(obj).CanonicalizeHash();
  }
  if (obj.IsCode()) {
    // Instructions don't move during compaction.
    return Code::Cast(obj).PayloadStart();
  }
  if (obj.IsFunction()) {
    return Function::Cast(obj).Hash();
  }
  if (obj.IsField()) {
    return dart::String::HashRawSymbol(Field::Cast(obj).name());
  }
  // Unlikely.
  return obj.GetClassId();
}

void SetToNull(Object* obj) {
  *obj = Object::null();
}

Object& NewZoneHandle(Zone* zone) {
  return Object::ZoneHandle(zone, Object::null());
}

Object& NewZoneHandle(Zone* zone, const Object& obj) {
  return Object::ZoneHandle(zone, obj.raw());
}

bool IsOriginalObject(const Object& object) {
  if (object.IsICData()) {
    return ICData::Cast(object).IsOriginal();
  } else if (object.IsField()) {
    return Field::Cast(object).IsOriginal();
  }
  return true;
}

const String& AllocateString(const char* buffer) {
  return String::ZoneHandle(String::New(buffer, dart::Heap::kOld));
}

bool HasIntegerValue(const dart::Object& object, int64_t* value) {
  if (object.IsInteger()) {
    *value = Integer::Cast(object).AsInt64Value();
    return true;
  }
  return false;
}

int32_t CreateJitCookie() {
  return static_cast<int32_t>(Isolate::Current()->random()->NextUInt32());
}

void BailoutWithBranchOffsetError() {
  Thread::Current()->long_jump_base()->Jump(1, Object::branch_offset_error());
}

namespace target {

uint32_t MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size) {
  return dart::RawObject::SizeTag::encode(instance_size) |
         dart::RawObject::ClassIdTag::encode(cid) |
         dart::RawObject::NewBit::encode(true);
}

word Object::tags_offset() {
  return dart::Object::tags_offset();
}

const word RawObject::kClassIdTagPos = dart::RawObject::kClassIdTagPos;

const word RawObject::kClassIdTagSize = dart::RawObject::kClassIdTagSize;

const word RawObject::kBarrierOverlapShift =
    dart::RawObject::kBarrierOverlapShift;

intptr_t ObjectPool::element_offset(intptr_t index) {
  return dart::ObjectPool::element_offset(index);
}

classid_t Class::GetId(const dart::Class& handle) {
  return handle.id();
}

uword Class::GetInstanceSize(const dart::Class& handle) {
  return handle.instance_size();
}

word Instance::DataOffsetFor(intptr_t cid) {
  return dart::Instance::DataOffsetFor(cid);
}

bool Heap::IsAllocatableInNewSpace(intptr_t instance_size) {
  return dart::Heap::IsAllocatableInNewSpace(instance_size);
}

word Thread::top_offset() {
  return dart::Thread::top_offset();
}

word Thread::end_offset() {
  return dart::Thread::end_offset();
}

word Thread::isolate_offset() {
  return dart::Thread::isolate_offset();
}

#if !defined(TARGET_ARCH_DBC)
word Thread::call_to_runtime_entry_point_offset() {
  return dart::Thread::call_to_runtime_entry_point_offset();
}

word Thread::null_error_shared_with_fpu_regs_entry_point_offset() {
  return dart::Thread::null_error_shared_with_fpu_regs_entry_point_offset();
}

word Thread::null_error_shared_without_fpu_regs_entry_point_offset() {
  return dart::Thread::null_error_shared_without_fpu_regs_entry_point_offset();
}

word Thread::monomorphic_miss_entry_offset() {
  return dart::Thread::monomorphic_miss_entry_offset();
}

word Thread::write_barrier_mask_offset() {
  return dart::Thread::write_barrier_mask_offset();
}

word Thread::write_barrier_entry_point_offset() {
  return dart::Thread::write_barrier_entry_point_offset();
}

word Thread::array_write_barrier_entry_point_offset() {
  return dart::Thread::array_write_barrier_entry_point_offset();
}
#endif  // !defined(TARGET_ARCH_DBC)

#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) ||                  \
    defined(TARGET_ARCH_X64)
word Thread::write_barrier_wrappers_thread_offset(intptr_t regno) {
  return dart::Thread::write_barrier_wrappers_thread_offset(
      static_cast<Register>(regno));
}
#endif

word Thread::vm_tag_offset() {
  return dart::Thread::vm_tag_offset();
}

#define DECLARE_CONSTANT_OFFSET_GETTER(name)                                   \
  word Thread::name##_address_offset() {                                       \
    return dart::Thread::name##_address_offset();                              \
  }
THREAD_XMM_CONSTANT_LIST(DECLARE_CONSTANT_OFFSET_GETTER)
#undef DECLARE_CONSTANT_OFFSET_GETTER

word Isolate::class_table_offset() {
  return dart::Isolate::class_table_offset();
}

word ClassTable::table_offset() {
  return dart::ClassTable::table_offset();
}

#if !defined(PRODUCT)
word ClassTable::ClassOffsetFor(intptr_t cid) {
  return dart::ClassTable::ClassOffsetFor(cid);
}

word ClassTable::StateOffsetFor(intptr_t cid) {
  return dart::ClassTable::StateOffsetFor(cid);
}

word ClassTable::TableOffsetFor(intptr_t cid) {
  return dart::ClassTable::TableOffsetFor(cid);
}

word ClassTable::CounterOffsetFor(intptr_t cid, bool is_new) {
  return dart::ClassTable::CounterOffsetFor(cid, is_new);
}

word ClassTable::SizeOffsetFor(intptr_t cid, bool is_new) {
  return dart::ClassTable::SizeOffsetFor(cid, is_new);
}
#endif  // !defined(PRODUCT)

const word ClassTable::kSizeOfClassPairLog2 = dart::kSizeOfClassPairLog2;

const intptr_t Instructions::kPolymorphicEntryOffset =
    dart::Instructions::kPolymorphicEntryOffset;

const intptr_t Instructions::kMonomorphicEntryOffset =
    dart::Instructions::kMonomorphicEntryOffset;

intptr_t Instructions::HeaderSize() {
  return dart::Instructions::HeaderSize();
}

intptr_t Code::object_pool_offset() {
  return dart::Code::object_pool_offset();
}

intptr_t Code::saved_instructions_offset() {
  return dart::Code::saved_instructions_offset();
}

intptr_t Code::entry_point_offset(CodeEntryKind kind) {
  return dart::Code::entry_point_offset(kind);
}

#if !defined(PRODUCT)
word ClassHeapStats::TraceAllocationMask() {
  return dart::ClassHeapStats::TraceAllocationMask();
}

word ClassHeapStats::state_offset() {
  return dart::ClassHeapStats::state_offset();
}

word ClassHeapStats::allocated_since_gc_new_space_offset() {
  return dart::ClassHeapStats::allocated_since_gc_new_space_offset();
}

word ClassHeapStats::allocated_size_since_gc_new_space_offset() {
  return dart::ClassHeapStats::allocated_size_since_gc_new_space_offset();
}
#endif  // !defined(PRODUCT)

word Double::value_offset() {
  return dart::Double::value_offset();
}

word Float32x4::value_offset() {
  return dart::Float32x4::value_offset();
}

word Float64x2::value_offset() {
  return dart::Float64x2::value_offset();
}

bool IsSmi(const dart::Object& a) {
  return a.IsSmi();
}

word ToRawSmi(const dart::Object& a) {
  ASSERT(a.IsSmi());
  return reinterpret_cast<word>(a.raw());
}

word ToRawSmi(intptr_t value) {
  return dart::Smi::RawValue(value);
}

bool CanLoadFromThread(const dart::Object& object,
                       word* offset /* = nullptr */) {
  if (dart::Thread::CanLoadFromThread(object)) {
    if (offset != nullptr) {
      *offset = dart::Thread::OffsetFromThread(object);
    }
    return true;
  }
  return false;
}

#if defined(TARGET_ARCH_IA32)
uword Code::EntryPointOf(const dart::Code& code) {
  static_assert(kHostWordSize == kWordSize,
                "Can't embed raw pointers to runtime objects when host and "
                "target word sizes are different");
  return code.EntryPoint();
}

bool CanEmbedAsRawPointerInGeneratedCode(const dart::Object& obj) {
  return obj.IsSmi() || obj.InVMHeap();
}

word ToRawPointer(const dart::Object& a) {
  static_assert(kHostWordSize == kWordSize,
                "Can't embed raw pointers to runtime objects when host and "
                "target word sizes are different");
  return reinterpret_cast<word>(a.raw());
}
#endif  // defined(TARGET_ARCH_IA32)

}  // namespace target
}  // namespace compiler
}  // namespace dart

#endif  // !defined(DART_PRECOMPILED_RUNTIME)
<|endoftext|>


<commit_before>#include "dspSmoothers.h"
#include <apf.h>

namespace dsp {

Smoother::~Smoother()
{
}

class LaplacianSmoother : public Smoother {
  public:
    void smooth(apf::Field* df, Boundary& fixed, Boundary& moving)
    {
      apf::Mesh* m = apf::getMesh(df);
      /* start Fan's code */
      apf::MeshIterator* it;
      apf::MeshEntity* v;
      apf::ModelEntity* me;
      apf::Vector3 p;

      //---------------------------------------------------------
      int n_mb = 0; int n_in = 0; int n_fb = 0;

      //iterate vertex to count the number of each type of vertex
      it = m->begin(0);
      while ((v = m->iterate(it))) {
        me = m->toModel(v);
        if (moving.count(me)) n_mb++;
        else if (fixed.count(me)) n_fb++;
        else n_in++;
      }
      m->end(it);

      //----------------------------------------------------------
      int MB_begin = 0;            int MB_end = n_mb - 1;
      int IN_begin = n_mb;         int IN_end = n_mb + n_in - 1;
      int FB_begin = n_mb + n_in;  int FB_end = n_mb + n_in + n_fb - 1;
      int ithMB = 0; int ithIN =0; int ithFB = 0;

      vector < apf::MeshEntity* > V_total(n_mb + n_in + n_fb);
      vector < apf::Vector3 > P_total(n_mb + n_in + n_fb);
      apf::Numbering* numbers = numberOwnedDimension(m, "my_numbering", 0);

      //iterate to store vertices and points
      it = m->begin(0);
      while ((v = m->iterate(it))) {
        m->getPoint(v, 0, p);
        me = m->toModel(v);
        if (moving.count(me)) {
          V_total[MB_begin + ithMB] = v;
          P_total[MB_begin + ithMB] = p;
          apf::number(numbers, v, 0, 0, MB_begin + ithMB);
          ithMB++;
        }
        else if (fixed.count(me)) {
          V_total[FB_begin + ithFB] = v;
          P_total[FB_begin + ithFB] = p;
          apf::number(numbers, v, 0, 0, FB_begin + ithFB);
          ithFB++;
        }
        else {
          V_total[IN_begin + ithIN] = v;
          P_total[IN_begin + ithIN] = p;
          // apf::number(numbers, v, 0, 0, IN_begin + ithIN);
          ithIN++;
        }
      }
      m->end(it);

      //----------------------------------------------------------
      ithIN = 0;
      apf::Adjacent adj;

      //make a queue and put all MB vertex in it
      std::queue < apf::MeshEntity* > q;
      for (int i = MB_begin ; i < MB_end + 1 ; i++) {
        q.push(V_total[i]);
      }

      //tag = 1, indicates this is in queue before AND this is a interior vertex
      apf::MeshTag* in_queue_tag = m->createIntTag("In_Queue_Tag", 1);
      it = m->begin(0);
      while ((v = m->iterate(it))) {
        m->setIntTag(v, in_queue_tag, 0);
      }
      m->end(it);

      //find its adj, if it is never in queue, put it in queue
      while (!q.empty()) {
        v = q.front();
        me = m->toModel(v);
        m->getPoint(v, 0, p);
        m->getAdjacent(v, 1, adj);
        int num_adj = adj.getSize();
        for (int i = 0 ; i < num_adj ; i++) {
          apf::MeshEntity* adj_v = apf::getEdgeVertOppositeVert(m, adj[i], v);
          apf::ModelEntity* adj_me = m->toModel(adj_v);
          if ((!moving.count(adj_me)) & (!fixed.count(adj_me))) {
            int tag;
            m->getIntTag(adj_v, in_queue_tag, tag);
            if (tag = 0) {
              q.push(adj_v);
              m->setIntTag(adj_v, in_queue_tag, 1);
            }
          }
        }
        if ((!moving.count(me)) & (!fixed.count(me))) {
          V_total[IN_start + ithIN] = v;
          P_total[IN_start + ithIN] = p;
          apf::number(numbers, v, 0, 0, IN_begin + ithIN);
          ithIN++;
        }
        q.pop();
      }

      //----------------------------------------------------------
      double tol = 1.0E-5; //tolerance
      vector < apf::Vector3 > delta_P(n_mb + n_in + n_fb);
      apf::Vector3 P_sum = apf::Vector3(0, 0, 0);

      for (int i = 0 ; i < n_mb + n_in + n_fb ; i++) {
        delta_P[i] = apf::Vector3(0, 0, 0);
      }

      // average nodal position = sum(all adj_V's position)/num of adj_V
      // check max, stop until it is less the tolerance
      double max = 1.0;
      while (max > tol) {
        max = 0.0;
        for (int i = IN_begin ; i < IN_end + 1 ; i++) {
          m->getAdjacent(V_total[i], 1, adj);
          int num_adj = adj.getSize();
          for (int j = 0 ; j < num_adj ; j++) {
            apf::MeshEntity* adj_V = apf::getEdgeVertOppositeVert(m, adj[j], V_total[i]);
            int adj_V_id = apf::getNumber(v_n, adj_V, 0, 0);
            P_sum = P_sum + P_total[adj_V_id];
          }
          delta_P_sum[0] = delta_P_sum[0]/num_adj;
          delta_P_sum[1] = delta_P_sum[1]/num_adj;
          delta_P_sum[2] = delta_P_sum[2]/num_adj;
          delta_P[i] = delta_P_sum;

          double temp_max = sqrt(pow(delta_P_sum[0], 2) + pow(delta_P_sum[1], 2) + pow(delta_P_sum[2], 2));
                if (max < temp_max) {
                    max = temp_max;
                }
                //update IN
                P_total[i] = P_total[i] + delta_P[i];
                calc_times++;
            }
            if (notZero_check) {
                for (int i = MB_start ; i < MB_end + 1 ; i++) {
                    delta_P[i] = apf::Vector3(0, 0, 0);
                    notZero_check = 0;
                }
            }
        }

        /*------------------ update and print mesh -----------------*/
        for (int i = 0 ; i < n_mb + n_in + n_fb ; i++) {
            mesh->setPoint(V_total[i], 0, P_total[i]);
        }

      /* end Fan's code */
      (void)m;
      (void)df;
      (void)fixed;
      (void)moving;
    }
};

class EmptySmoother : public Smoother {
  public:
    void smooth(apf::Field* df, Boundary& fixed, Boundary& moving)
    {
      (void)df;
      (void)fixed;
      (void)moving;
    }
};

Smoother* Smoother::makeLaplacian()
{
  return new LaplacianSmoother();
}

Smoother* Smoother::makeEmpty()
{
  return new EmptySmoother();
}

}
<commit_msg>update<commit_after>#include "dspSmoothers.h"
#include <math.h>
#include <apf.h>

namespace dsp {

Smoother::~Smoother()
{
}

class LaplacianSmoother : public Smoother {
  public:
    void smooth(apf::Field* df, Boundary& fixed, Boundary& moving)
    {
      apf::Mesh* m = apf::getMesh(df);
      /* start Fan's code */
      apf::MeshIterator* it;
      apf::MeshEntity* v;
      apf::ModelEntity* me;
      apf::Vector3 p;

      //---------------------------------------------------------
      int n_mb = 0; int n_in = 0; int n_fb = 0;

      //iterate vertex to count the number of each type of vertex
      it = m->begin(0);
      while ((v = m->iterate(it))) {
        me = m->toModel(v);
        if (moving.count(me)) n_mb++;
        else if (fixed.count(me)) n_fb++;
        else n_in++;
      }
      m->end(it);

      //----------------------------------------------------------
      int MB_begin = 0;            int MB_end = n_mb - 1;
      int IN_begin = n_mb;         int IN_end = n_mb + n_in - 1;
      int FB_begin = n_mb + n_in;  int FB_end = n_mb + n_in + n_fb - 1;
      int ithMB = 0; int ithIN =0; int ithFB = 0;

      vector < apf::MeshEntity* > V_total(n_mb + n_in + n_fb);
      vector < apf::Vector3 > P_total(n_mb + n_in + n_fb);
      apf::Numbering* numbers = numberOwnedDimension(m, "my_numbering", 0);

      //iterate to store vertices and points
      it = m->begin(0);
      while ((v = m->iterate(it))) {
        m->getPoint(v, 0, p);
        me = m->toModel(v);
        if (moving.count(me)) {
          V_total[MB_begin + ithMB] = v;
          P_total[MB_begin + ithMB] = p;
          apf::number(numbers, v, 0, 0, MB_begin + ithMB);
          ithMB++;
        }
        else if (fixed.count(me)) {
          V_total[FB_begin + ithFB] = v;
          P_total[FB_begin + ithFB] = p;
          apf::number(numbers, v, 0, 0, FB_begin + ithFB);
          ithFB++;
        }
        else {
          V_total[IN_begin + ithIN] = v;
          P_total[IN_begin + ithIN] = p;
          // apf::number(numbers, v, 0, 0, IN_begin + ithIN);
          ithIN++;
        }
      }
      m->end(it);

      //----------------------------------------------------------
      ithIN = 0;
      apf::Adjacent adj;

      //make a queue and put all MB vertex in it
      std::queue < apf::MeshEntity* > q;
      for (int i = MB_begin ; i < MB_end + 1 ; i++) {
        q.push(V_total[i]);
      }

      //tag = 1, indicates this is in queue before AND this is a interior vertex
      apf::MeshTag* in_queue_tag = m->createIntTag("In_Queue_Tag", 1);
      it = m->begin(0);
      while ((v = m->iterate(it))) {
        m->setIntTag(v, in_queue_tag, 0);
      }
      m->end(it);

      //find its adj, if it is never in queue, put it in queue
      while (!q.empty()) {
        v = q.front();
        me = m->toModel(v);
        m->getPoint(v, 0, p);
        m->getAdjacent(v, 1, adj);
        int num_adj = adj.getSize();
        for (int i = 0 ; i < num_adj ; i++) {
          apf::MeshEntity* adj_v = apf::getEdgeVertOppositeVert(m, adj[i], v);
          apf::ModelEntity* adj_me = m->toModel(adj_v);
          if ((!moving.count(adj_me)) & (!fixed.count(adj_me))) {
            int tag;
            m->getIntTag(adj_v, in_queue_tag, tag);
            if (tag = 0) {
              q.push(adj_v);
              m->setIntTag(adj_v, in_queue_tag, 1);
            }
          }
        }
        if ((!moving.count(me)) & (!fixed.count(me))) {
          V_total[IN_start + ithIN] = v;
          P_total[IN_start + ithIN] = p;
          apf::number(numbers, v, 0, 0, IN_begin + ithIN);
          ithIN++;
        }
        q.pop();
      }

      //----------------------------------------------------------
      double tol = 1.0E-5; //tolerance
      vector < apf::Vector3 > delta_P(n_mb + n_in + n_fb);
      apf::Vector3 P_sum = apf::Vector3(0, 0, 0);

      for (int i = 0 ; i < n_mb + n_in + n_fb ; i++) {
        delta_P[i] = apf::Vector3(0, 0, 0);
      }

      // average nodal position = sum(all adj_V's position)/num of adj_V
      // check max, stop until it is less the tolerance
      double max = 1.0;
      while (max > tol) {
        max = 0.0;
        for (int i = IN_begin ; i < IN_end + 1 ; i++) {
          m->getAdjacent(V_total[i], 1, adj);
          int num_adj = adj.getSize();
          for (int j = 0 ; j < num_adj ; j++) {
            apf::MeshEntity* adj_V = apf::getEdgeVertOppositeVert(m, adj[j], V_total[i]);
            int adj_V_id = apf::getNumber(v_n, adj_V, 0, 0);
            P_sum = P_sum + P_total[adj_V_id];
          }
          P_sum[0] = P_sum[0]/num_adj;
          P_sum[1] = P_sum[1]/num_adj;
          P_sum[2] = P_sum[2]/num_adj;
          delta_P[i] = delta_P_sum;

          double temp_max = sqrt(pow(delta_P_sum[0], 2) + pow(delta_P_sum[1], 2) + pow(delta_P_sum[2], 2));
                if (max < temp_max) {
                    max = temp_max;
                }
                //update IN
                P_total[i] = P_total[i] + delta_P[i];
                calc_times++;
            }
            if (notZero_check) {
                for (int i = MB_start ; i < MB_end + 1 ; i++) {
                    delta_P[i] = apf::Vector3(0, 0, 0);
                    notZero_check = 0;
                }
            }
        }

        /*------------------ update and print mesh -----------------*/
        for (int i = 0 ; i < n_mb + n_in + n_fb ; i++) {
            mesh->setPoint(V_total[i], 0, P_total[i]);
        }

      /* end Fan's code */
      (void)m;
      (void)df;
      (void)fixed;
      (void)moving;
    }
};

class EmptySmoother : public Smoother {
  public:
    void smooth(apf::Field* df, Boundary& fixed, Boundary& moving)
    {
      (void)df;
      (void)fixed;
      (void)moving;
    }
};

Smoother* Smoother::makeLaplacian()
{
  return new LaplacianSmoother();
}

Smoother* Smoother::makeEmpty()
{
  return new EmptySmoother();
}

}
<|endoftext|>


<commit_before>#include <cstdio>
#include <string>

#include "board.hpp"
#include "config.hpp"

namespace roadagain
{

Config::Config() : color_(true), automatic_(false), player_(BLACK)
{
}

Config& Config::instance()
{
    static Config instance_;
    return (instance_);
}

bool Config::init(int argc, char** argv)
{
    for (int i = 1; i < argc; i++){
        std::string argument(argv[i]);

        if (argument == BLACK_STR){
            player_ = BLACK;
        }
        else if (argument == WHITE_STR){
            player_ = WHITE;
        }
        else if (argument == AUTOMATIC_STR){
            automatic_ = true;
        }
        else if (argument == COLOR_STR){
            color_ = true;
        }
        else if (argument == NO_COLOR_STR){
            color_ = false;
        }
        else if (argument == HELP_STR){
            help();
            return (false);
        }
        else {
            std::printf("invalid argument: %s\n", argv[i]);
            return (false);
        }
    }

    return (true);
}

void Config::help()
{
    std::puts("Usage: reversi [options] [color]");
    std::puts("Reversi game for one person's play.");
    std::puts("Options:");
    std::puts("  --automatic Play automatically.");
    std::puts("  --color     Use colors when printing something.");
    std::puts("  --help      Print this help and exit successfully.");
    std::puts("  --nocolor   Don't use colors when printing something.");
    std::puts("");
    std::puts("color must be 'black' or 'white'.");
}

bool Config::color() const
{
    return (color_);
}

bool Config::automatic() const
{
    return (automatic_);
}

BoardState Config::player() const
{
    if (automatic_){
        return (EMPTY);
    }
    else {
        return (player_);
    }
}

const std::string Config::BLACK_STR("black");
const std::string Config::WHITE_STR("white");
const std::string Config::AUTOMATIC_STR("--automatic");
const std::string Config::COLOR_STR("--color");
const std::string Config::NO_COLOR_STR("--nocolor");
const std::string Config::HELP_STR("--help");

}
<commit_msg>Adde default color description to help message<commit_after>#include <cstdio>
#include <string>

#include "board.hpp"
#include "config.hpp"

namespace roadagain
{

Config::Config() : color_(true), automatic_(false), player_(BLACK)
{
}

Config& Config::instance()
{
    static Config instance_;
    return (instance_);
}

bool Config::init(int argc, char** argv)
{
    for (int i = 1; i < argc; i++){
        std::string argument(argv[i]);

        if (argument == BLACK_STR){
            player_ = BLACK;
        }
        else if (argument == WHITE_STR){
            player_ = WHITE;
        }
        else if (argument == AUTOMATIC_STR){
            automatic_ = true;
        }
        else if (argument == COLOR_STR){
            color_ = true;
        }
        else if (argument == NO_COLOR_STR){
            color_ = false;
        }
        else if (argument == HELP_STR){
            help();
            return (false);
        }
        else {
            std::printf("invalid argument: %s\n", argv[i]);
            return (false);
        }
    }

    return (true);
}

void Config::help()
{
    std::puts("Usage: reversi [options] [color]");
    std::puts("Reversi game for one person's play.");
    std::puts("Options:");
    std::puts("  --automatic Play automatically.");
    std::puts("  --color     Use colors when printing something.");
    std::puts("  --help      Print this help and exit successfully.");
    std::puts("  --nocolor   Don't use colors when printing something.");
    std::puts("");
    std::puts("Color must be 'black' or 'white'.");
    std::puts("Default color is black.");
}

bool Config::color() const
{
    return (color_);
}

bool Config::automatic() const
{
    return (automatic_);
}

BoardState Config::player() const
{
    if (automatic_){
        return (EMPTY);
    }
    else {
        return (player_);
    }
}

const std::string Config::BLACK_STR("black");
const std::string Config::WHITE_STR("white");
const std::string Config::AUTOMATIC_STR("--automatic");
const std::string Config::COLOR_STR("--color");
const std::string Config::NO_COLOR_STR("--nocolor");
const std::string Config::HELP_STR("--help");

}
<|endoftext|>


<commit_before>/**
@file StateStore.hpp
@brief StateStore class.

@author Tim Howard
@copyright 2013 Tim Howard under the MIT license;
see @ref index or the accompanying LICENSE file for full text.
*/

#ifndef DUCT_STATESTORE_HPP_
#define DUCT_STATESTORE_HPP_

#include "./config.hpp"
#include "./utility.hpp"

#include <type_traits>

/*
FIXME: constexpr implies const on non-static member functions in
C++11, but many member functions here can and should be constexpr in
C++1y.

TODO: When constexpr doesn't imply const, operations should have
parameter pack variants.
*/

namespace duct {

// Forward declarations
template<
	typename S,
	typename V
>
class StateStore;

/**
	@addtogroup utils
	@{
*/

/**
	Typesafe state storage for bitflags.

	@note Both @a S and @a V must be plain non-const, non-volatile,
	non-reference, and non-pointer types.

	@tparam S State type. This type must be an enum or non-boolean
	integral type.

	@tparam V Value type. Defaults to the underlying type of @a S
	if @a S is an enum, or @a S otherwise. This type must be a non-
	boolean integral type to which @a S is @c static_cast-able.
*/
template<
	typename S,
	typename V
	= typename std::conditional<
		std::is_enum<S>::value,
		typename std::underlying_type<S>::type,
		S
	>::type
>
class StateStore {
	static_assert(
		std::is_same<typename std::decay<S>::type, S>::value &&
		(
			std::is_enum<S>::value ||
			(
				std::is_integral<S>::value &&
				!std::is_same<typename std::decay<S>::type, bool>::value
			)
		),
		"state type must be a non-reference, non-cv enum "
		"or non-boolean integral type"
	);
	static_assert(
		std::is_same<typename std::decay<S>::type, S>::value &&
		(
			std::is_integral<V>::value &&
			!std::is_same<typename std::remove_cv<V>::type, bool>::value
		),
		"value type must be a non-reference, non-cv, non-boolean "
		"integral type"
	);

public:
	/**
		State type.
	*/
	using state_type = S;
	/**
		Value type.
	*/
	using value_type = V;

private:
	value_type m_value;

public:
/** @name Constructors and destructor */ /// @{
	/**
		Constructor with states.

		@tparam Rest Rest types. See enum_bitor().
		@param first First state to enable.
		@param rest Rest of states to enable.
	*/
	template<
		typename... Rest
	>
	constexpr
	StateStore(
		state_type const first,
		Rest const... rest
	) noexcept
		: m_value(
			enum_bitor<state_type, value_type>(first, rest...)
		)
	{}

	// FIXME: Defect in GCC 4.7.3: compiler trips itself by
	// not initializing m_value in its own generated ctor.
	/** Default constructor. */
	StateStore() noexcept = default;
	/** Copy constructor. */
	StateStore(StateStore const&) noexcept = default;
	/** Move constructor. */
	StateStore(StateStore&&) noexcept = default;
	/** Destructor. */
	~StateStore() noexcept = default;
/// @}

/** @name Operators */ /// @{
	/** Copy-assignment operator. */
	StateStore& operator=(StateStore const&) noexcept = default;
	/** Move-assignment operator. */
	StateStore& operator=(StateStore&&) noexcept = default;
/// @}

/** @name Properties */ /// @{
	/**
		Get value.

		@returns Value.
	*/
	constexpr value_type
	get_value() const noexcept {
		return m_value;
	}

	/**
		Get states by mask.

		@param mask Mask.
	*/
	constexpr state_type
	get_states(
		state_type const mask
	) const noexcept {
		return static_cast<state_type>(
			m_value & static_cast<value_type const>(mask)
		);
	}

	/**
		Test value of state.

		@returns
		- @c true if the state is enabled;
		- @c false if the state is disabled.
		@param state State to test.
	*/
	constexpr bool
	test(
		state_type const state
	) const noexcept {
		return m_value & static_cast<value_type const>(state);
	}
/// @}

/** @name Operations */ /// @{
	/**
		Enable state.

		@param state State to enable.
	*/
	/*constexpr*/ void
	enable(
		state_type const state
	) noexcept {
		m_value |= static_cast<value_type const>(state);
	}

	/**
		Disable state.

		@param state State to disable.
	*/
	/*constexpr*/ void
	disable(
		state_type const state
	) noexcept {
		m_value &= ~static_cast<value_type const>(state);
	}

	/**
		Enable or disable state.

		@param state State to enable or disable.
		@param enable Whether to enable or disable the state.
	*/
	/*constexpr*/ void
	set(
		state_type const state,
		bool const enable
	) noexcept {
		enable
			? this->enable(state)
			: this->disable(state)
		;
	}

	/**
		Remove states by mask and set states.

		@param mask State mask.
		@param states States to set.
	*/
	/*constexpr*/ void
	set_masked(
		state_type const mask,
		state_type const states
	) noexcept {
		m_value
			= (m_value & ~static_cast<value_type const>(mask))
			| static_cast<value_type const>(states)
		;
	}

	/**
		Remove states by mask.

		Removes states by ANDing @c ~mask.

		@param mask State mask.
	*/
	/*constexpr*/ void
	remove(
		state_type const mask
	) noexcept {
		m_value &= ~static_cast<value_type const>(mask);
	}

	/**
		Clear all states.
	*/
	/*constexpr*/ void
	clear() noexcept {
		m_value = value_type(0);
	}
/// @}
};

/** @} */ // end of doc-group utils

} // namespace duct

#endif // DUCT_STATESTORE_HPP_
<commit_msg>StateStore: corrected GCC "defect" by explicitly default-initializing m_value.¹<commit_after>/**
@file StateStore.hpp
@brief StateStore class.

@author Tim Howard
@copyright 2013 Tim Howard under the MIT license;
see @ref index or the accompanying LICENSE file for full text.
*/

#ifndef DUCT_STATESTORE_HPP_
#define DUCT_STATESTORE_HPP_

#include "./config.hpp"
#include "./utility.hpp"

#include <type_traits>

/*
FIXME: constexpr implies const on non-static member functions in
C++11, but many member functions here can and should be constexpr in
C++1y.

TODO: When constexpr doesn't imply const, operations should have
parameter pack variants.
*/

namespace duct {

// Forward declarations
template<
	typename S,
	typename V
>
class StateStore;

/**
	@addtogroup utils
	@{
*/

/**
	Typesafe state storage for bitflags.

	@note Both @a S and @a V must be plain non-const, non-volatile,
	non-reference, and non-pointer types.

	@tparam S State type. This type must be an enum or non-boolean
	integral type.

	@tparam V Value type. Defaults to the underlying type of @a S
	if @a S is an enum, or @a S otherwise. This type must be a non-
	boolean integral type to which @a S is @c static_cast-able.
*/
template<
	typename S,
	typename V
	= typename std::conditional<
		std::is_enum<S>::value,
		typename std::underlying_type<S>::type,
		S
	>::type
>
class StateStore {
	static_assert(
		std::is_same<typename std::decay<S>::type, S>::value &&
		(
			std::is_enum<S>::value ||
			(
				std::is_integral<S>::value &&
				!std::is_same<typename std::decay<S>::type, bool>::value
			)
		),
		"state type must be a non-reference, non-cv enum "
		"or non-boolean integral type"
	);
	static_assert(
		std::is_same<typename std::decay<S>::type, S>::value &&
		(
			std::is_integral<V>::value &&
			!std::is_same<typename std::remove_cv<V>::type, bool>::value
		),
		"value type must be a non-reference, non-cv, non-boolean "
		"integral type"
	);

public:
	/**
		State type.
	*/
	using state_type = S;
	/**
		Value type.
	*/
	using value_type = V;

private:
	value_type m_value{};

public:
/** @name Constructors and destructor */ /// @{
	/**
		Constructor with states.

		@tparam Rest Rest types. See enum_bitor().
		@param first First state to enable.
		@param rest Rest of states to enable.
	*/
	template<
		typename... Rest
	>
	constexpr
	StateStore(
		state_type const first,
		Rest const... rest
	) noexcept
		: m_value(
			enum_bitor<state_type, value_type>(first, rest...)
		)
	{}

	/** Default constructor. */
	StateStore() noexcept = default;
	/** Copy constructor. */
	StateStore(StateStore const&) noexcept = default;
	/** Move constructor. */
	StateStore(StateStore&&) noexcept = default;
	/** Destructor. */
	~StateStore() noexcept = default;
/// @}

/** @name Operators */ /// @{
	/** Copy-assignment operator. */
	StateStore& operator=(StateStore const&) noexcept = default;
	/** Move-assignment operator. */
	StateStore& operator=(StateStore&&) noexcept = default;
/// @}

/** @name Properties */ /// @{
	/**
		Get value.

		@returns Value.
	*/
	constexpr value_type
	get_value() const noexcept {
		return m_value;
	}

	/**
		Get states by mask.

		@param mask Mask.
	*/
	constexpr state_type
	get_states(
		state_type const mask
	) const noexcept {
		return static_cast<state_type>(
			m_value & static_cast<value_type const>(mask)
		);
	}

	/**
		Test value of state.

		@returns
		- @c true if the state is enabled;
		- @c false if the state is disabled.
		@param state State to test.
	*/
	constexpr bool
	test(
		state_type const state
	) const noexcept {
		return m_value & static_cast<value_type const>(state);
	}
/// @}

/** @name Operations */ /// @{
	/**
		Enable state.

		@param state State to enable.
	*/
	/*constexpr*/ void
	enable(
		state_type const state
	) noexcept {
		m_value |= static_cast<value_type const>(state);
	}

	/**
		Disable state.

		@param state State to disable.
	*/
	/*constexpr*/ void
	disable(
		state_type const state
	) noexcept {
		m_value &= ~static_cast<value_type const>(state);
	}

	/**
		Enable or disable state.

		@param state State to enable or disable.
		@param enable Whether to enable or disable the state.
	*/
	/*constexpr*/ void
	set(
		state_type const state,
		bool const enable
	) noexcept {
		enable
			? this->enable(state)
			: this->disable(state)
		;
	}

	/**
		Remove states by mask and set states.

		@param mask State mask.
		@param states States to set.
	*/
	/*constexpr*/ void
	set_masked(
		state_type const mask,
		state_type const states
	) noexcept {
		m_value
			= (m_value & ~static_cast<value_type const>(mask))
			| static_cast<value_type const>(states)
		;
	}

	/**
		Remove states by mask.

		Removes states by ANDing @c ~mask.

		@param mask State mask.
	*/
	/*constexpr*/ void
	remove(
		state_type const mask
	) noexcept {
		m_value &= ~static_cast<value_type const>(mask);
	}

	/**
		Clear all states.
	*/
	/*constexpr*/ void
	clear() noexcept {
		m_value = value_type(0);
	}
/// @}
};

/** @} */ // end of doc-group utils

} // namespace duct

#endif // DUCT_STATESTORE_HPP_
<|endoftext|>


<commit_before>#include "CNetwork.hpp"
#include "CLog.hpp"

#include <beast/core/to_string.hpp>

#include <unordered_map>

void CNetwork::Initialize(std::string &&token)
{
	m_Token = std::move(token);
	m_HttpsStream.set_verify_mode(asio::ssl::verify_none);

	// connect to REST API
	asio::ip::tcp::resolver r{ m_IoService };
	boost::system::error_code error;
	auto target = r.resolve({ "discordapp.com", "https" }, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't resolve Discord API URL: {} ({})",
			error.message(), error.value());
		CSingleton::Destroy();
		return;
	}

	error.clear();
	asio::connect(m_HttpsStream.lowest_layer(), target, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't connect to Discord API: {} ({})",
			error.message(), error.value());
		CSingleton::Destroy();
		return;
	}

	// SSL handshake
	error.clear();
	m_HttpsStream.handshake(asio::ssl::stream_base::client, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't establish secured connection to Discord API: {} ({})",
			error.message(), error.value());
		CSingleton::Destroy();
		return;
	}

	// retrieve WebSocket host URL
	HttpGet("/gateway", [this](HttpGetResponse res)
	{
		if (res.status != 200)
		{
			CLog::Get()->Log(LogLevel::ERROR, "Can't retrieve Discord gateway URL: {} ({})",
				res.reason, res.status);
			return;
		}
		auto gateway_res = json::parse(res.body);
		m_GatewayUrl = gateway_res["url"];

		// get rid of protocol
		size_t protocol_pos = m_GatewayUrl.find("wss://");
		if (protocol_pos != std::string::npos)
			m_GatewayUrl.erase(protocol_pos, 6); // 6 = length of "wss://"

		m_WssStream.set_verify_mode(asio::ssl::verify_none);

		if (!WsConnect())
			return;

		WsRead();
		WsIdentify();
	});

	m_IoThread = new std::thread([this]()
	{
		m_IoService.run();
	});
}

CNetwork::~CNetwork()
{
	WsDisconnect();
	if (m_IoThread)
	{
		m_IoThread->join();
		delete m_IoThread;
		m_IoThread = nullptr;
	}
}

bool CNetwork::WsConnect()
{
	asio::ip::tcp::resolver r{ m_IoService };
	boost::system::error_code error;
	auto target = r.resolve({ m_GatewayUrl, "https" }, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't resolve Discord gateway URL '{}': {} ({})",
			m_GatewayUrl, error.message(), error.value());
		return false;
	}

	error.clear();
	asio::connect(m_WssStream.lowest_layer(), target, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't connect to Discord gateway: {} ({})",
			error.message(), error.value());
		return false;
	}

	error.clear();
	m_WssStream.handshake(asio::ssl::stream_base::client, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't establish secured connection to Discord gateway: {} ({})",
			error.message(), error.value());
		return false;
	}

	error.clear();
	m_WebSocket.handshake(m_GatewayUrl, "/", error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't upgrade to WSS protocol: {} ({})",
			error.message(), error.value());
		return false;
	}

	return true;
}

void CNetwork::WsDisconnect()
{
	boost::system::error_code error;
	m_WebSocket.close(beast::websocket::close_code::normal, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::WARNING, "Error while sending WS close frame: {} ({})",
			error.message(), error.value());
	}

	error.clear();
	m_WssStream.lowest_layer().shutdown(asio::ip::tcp::socket::shutdown_both, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::WARNING, "Error while shutting down WS connection: {} ({})",
			error.message(), error.value());
	}

	error.clear();
	m_WssStream.lowest_layer().close(error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::WARNING, "Error while closing WS connection: {} ({})",
			error.message(), error.value());
	}

	m_HeartbeatTimer.cancel();
}

void CNetwork::WsIdentify()
{
#ifdef WIN32
	std::string os_name = "Windows";
#else
	std::string os_name = "Linux";
#endif

	json identify_payload = {
		{ "op", 2 },
		{ "d",{
			{ "token", m_Token },
			{ "v", 5 },
			{ "compress", false },
			{ "large_threshold", 100 },
			{ "properties",{
				{ "$os", os_name },
				{ "$browser", "boost::asio" },
				{ "$device", "SA-MP DCC plugin" },
				{ "$referrer", "" },
				{ "$referring_domain", "" }
			} }
		} }
	};

	m_WebSocket.write(asio::buffer(identify_payload.dump()));
}

void CNetwork::WsSendResumePayload()
{
	if (!WsConnect())
		return;

	WsRead();

	json resume_payload = {
		{ "op", 6 },
		{ "d", {
			{ "token", m_Token },
			{ "session_id", m_SessionId },
			{ "seq", m_SequenceNumber }
		}}
	};
	m_WebSocket.write(asio::buffer(resume_payload.dump()));
}

void CNetwork::WsRead()
{
	m_WebSocket.async_read(m_WebSocketOpcode, m_WebSocketBuffer,
		std::bind(&CNetwork::OnWsRead, this, std::placeholders::_1));
}

void CNetwork::OnWsRead(boost::system::error_code ec)
{
	if (ec)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't read from Discord websocket gateway: {} ({})",
			ec.message(), ec.value());

		return;
	}

	json result = json::parse(beast::to_string(m_WebSocketBuffer.data()));
	m_WebSocketBuffer.consume(m_WebSocketBuffer.size());

	int payload_opcode = result["op"].get<int>();
	switch (payload_opcode)
	{
		case 0:
		{
			m_SequenceNumber = result["s"];

			static const std::unordered_map<std::string, WsEvent> events_map{
				{ "READY", WsEvent::READY },
				{ "RESUMED", WsEvent::RESUMED },
				{ "CHANNEL_CREATE", WsEvent::CHANNEL_CREATE },
				{ "CHANNEL_UPDATE", WsEvent::CHANNEL_UPDATE },
				{ "CHANNEL_DELETE", WsEvent::CHANNEL_DELETE },
				{ "GUILD_CREATE", WsEvent::GUILD_CREATE },
				{ "GUILD_UPDATE", WsEvent::GUILD_UPDATE },
				{ "GUILD_DELETE", WsEvent::GUILD_DELETE },
				{ "GUILD_BAN_ADD", WsEvent::GUILD_BAN_ADD },
				{ "GUILD_BAN_REMOVE", WsEvent::GUILD_BAN_REMOVE },
				{ "GUILD_EMOJIS_UPDATE", WsEvent::GUILD_EMOJIS_UPDATE },
				{ "GUILD_INTEGRATIONS_UPDATE", WsEvent::GUILD_INTEGRATIONS_UPDATE },
				{ "GUILD_MEMBER_ADD", WsEvent::GUILD_MEMBER_ADD },
				{ "GUILD_MEMBER_REMOVE", WsEvent::GUILD_MEMBER_REMOVE },
				{ "GUILD_MEMBER_UPDATE", WsEvent::GUILD_MEMBER_UPDATE },
				{ "GUILD_MEMBERS_CHUNK", WsEvent::GUILD_MEMBERS_CHUNK },
				{ "GUILD_ROLE_CREATE", WsEvent::GUILD_ROLE_CREATE },
				{ "GUILD_ROLE_UPDATE", WsEvent::GUILD_ROLE_UPDATE },
				{ "GUILD_ROLE_DELETE", WsEvent::GUILD_ROLE_DELETE },
				{ "MESSAGE_CREATE", WsEvent::MESSAGE_CREATE },
				{ "MESSAGE_UPDATE", WsEvent::MESSAGE_UPDATE },
				{ "MESSAGE_DELETE", WsEvent::MESSAGE_DELETE },
				{ "MESSAGE_DELETE_BULK", WsEvent::MESSAGE_DELETE_BULK },
				{ "PRESENCE_UPDATE", WsEvent::PRESENCE_UPDATE },
				{ "TYPING_START", WsEvent::TYPING_START },
				{ "USER_SETTINGS_UPDATE", WsEvent::USER_SETTINGS_UPDATE },
				{ "USER_UPDATE", WsEvent::USER_UPDATE },
				{ "VOICE_STATE_UPDATE", WsEvent::VOICE_STATE_UPDATE },
				{ "VOICE_SERVER_UPDATE", WsEvent::VOICE_SERVER_UPDATE }
			};

			auto it = events_map.find(result["t"].get<std::string>());
			if (it != events_map.end())
			{
				json &data = result["d"];
				WsEvent event = it->second;
				switch (event)
				{
					case WsEvent::READY:
						m_HeartbeatInterval = std::chrono::milliseconds(data["heartbeat_interval"]);
						m_SessionId = data["session_id"];

						// start heartbeat
						DoHeartbeat({ });
						break;
				}

				auto ev_it = m_EventMap.find(event);
				if (ev_it != m_EventMap.end())
					ev_it->second(data);
			}
			else
			{
				CLog::Get()->Log(LogLevel::WARNING, "Unknown gateway event '{}'", result["t"].get<std::string>());
				CLog::Get()->Log(LogLevel::DEBUG, "UGE res: {}", result.dump(4));
			}
		} break;
		case 7: // reconnect
			WsDisconnect();
			WsConnect();
			WsSendResumePayload();
			DoHeartbeat({ });
			break;
		case 9: // invalid session
			WsIdentify();
			break;
		default:
			CLog::Get()->Log(LogLevel::WARNING, "Unhandled payload opcode '{}'", payload_opcode);
			CLog::Get()->Log(LogLevel::DEBUG, "UPO res: {}", result.dump(4));
	}

	WsRead();
}

void CNetwork::DoHeartbeat(boost::system::error_code ec)
{
	if (ec)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Heartbeat error: {} ({})",
			ec.message(), ec.value());
		return;
	}

	json heartbeat_payload = {
		{ "op", 1 },
		{ "d", m_SequenceNumber }
	};
	m_WebSocket.write(asio::buffer(heartbeat_payload.dump()));

	m_HeartbeatTimer.expires_from_now(m_HeartbeatInterval);
	m_HeartbeatTimer.async_wait(std::bind(&CNetwork::DoHeartbeat, this, std::placeholders::_1));
}

void CNetwork::HttpWriteRequest(std::string const &method,
	std::string const &url, std::string const &content, std::function<void()> &&callback)
{
	beast::http::request<beast::http::string_body> req;
	req.method = method;
	req.url = "/api" + url;
	req.version = 11;
	req.headers.replace("Host", "discordapp.com");
	if (!token.empty())
		req.headers.replace("Authorization", "Bot " + token);
	req.body = content;

	beast::http::prepare(req);

	beast::http::async_write(
		m_HttpsStream,
		req,
		[url, method, callback](boost::system::error_code ec)
		{
			if (ec)
			{
				CLog::Get()->Log(LogLevel::ERROR, "Error while sending HTTP {} request to '{}': {}",
					method, url, ec.message());
				return;
			}

			if (callback)
				callback();
		}
	);
}

void CNetwork::HttpReadResponse(HttpReadResponseCallback_t &&callback)
{
	auto sb = std::make_shared<beast::streambuf>();
	auto response = std::make_shared<beast::http::response<beast::http::streambuf_body>>();
	beast::http::async_read(
		m_HttpsStream,
		*sb,
		*response,
		[callback, sb, response](boost::system::error_code ec)
		{
			if (ec)
			{
				CLog::Get()->Log(LogLevel::ERROR, "Error while retrieving HTTP response: {}",
					ec.message());
				return;
			}

			callback(sb, response);
		}
	);
}

void CNetwork::HttpGet(std::string const &url, HttpGetCallback_t &&callback)
{
	HttpWriteRequest("GET", url, "", [this, callback]()
	{
		HttpReadResponse([callback](SharedStreambuf_t sb, SharedResponse_t resp)
		{
			callback({ resp->status, resp->reason, beast::to_string(resp->body.data()),
				beast::to_string(sb->data()) });
		});
	});
}

void CNetwork::HttpPost(std::string const &url, std::string const &content)
{
	HttpWriteRequest("POST", url, content, nullptr);
}
<commit_msg>bug-fix: buffer got invalid while being sent<commit_after>#include "CNetwork.hpp"
#include "CLog.hpp"

#include <beast/core/to_string.hpp>

#include <unordered_map>

void CNetwork::Initialize(std::string &&token)
{
	m_Token = std::move(token);
	m_HttpsStream.set_verify_mode(asio::ssl::verify_none);

	// connect to REST API
	asio::ip::tcp::resolver r{ m_IoService };
	boost::system::error_code error;
	auto target = r.resolve({ "discordapp.com", "https" }, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't resolve Discord API URL: {} ({})",
			error.message(), error.value());
		CSingleton::Destroy();
		return;
	}

	error.clear();
	asio::connect(m_HttpsStream.lowest_layer(), target, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't connect to Discord API: {} ({})",
			error.message(), error.value());
		CSingleton::Destroy();
		return;
	}

	// SSL handshake
	error.clear();
	m_HttpsStream.handshake(asio::ssl::stream_base::client, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't establish secured connection to Discord API: {} ({})",
			error.message(), error.value());
		CSingleton::Destroy();
		return;
	}

	// retrieve WebSocket host URL
	HttpGet("/gateway", [this](HttpGetResponse res)
	{
		if (res.status != 200)
		{
			CLog::Get()->Log(LogLevel::ERROR, "Can't retrieve Discord gateway URL: {} ({})",
				res.reason, res.status);
			return;
		}
		auto gateway_res = json::parse(res.body);
		m_GatewayUrl = gateway_res["url"];

		// get rid of protocol
		size_t protocol_pos = m_GatewayUrl.find("wss://");
		if (protocol_pos != std::string::npos)
			m_GatewayUrl.erase(protocol_pos, 6); // 6 = length of "wss://"

		m_WssStream.set_verify_mode(asio::ssl::verify_none);

		if (!WsConnect())
			return;

		WsRead();
		WsIdentify();
	});

	m_IoThread = new std::thread([this]()
	{
		m_IoService.run();
	});
}

CNetwork::~CNetwork()
{
	WsDisconnect();
	if (m_IoThread)
	{
		m_IoThread->join();
		delete m_IoThread;
		m_IoThread = nullptr;
	}
}

bool CNetwork::WsConnect()
{
	asio::ip::tcp::resolver r{ m_IoService };
	boost::system::error_code error;
	auto target = r.resolve({ m_GatewayUrl, "https" }, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't resolve Discord gateway URL '{}': {} ({})",
			m_GatewayUrl, error.message(), error.value());
		return false;
	}

	error.clear();
	asio::connect(m_WssStream.lowest_layer(), target, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't connect to Discord gateway: {} ({})",
			error.message(), error.value());
		return false;
	}

	error.clear();
	m_WssStream.handshake(asio::ssl::stream_base::client, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't establish secured connection to Discord gateway: {} ({})",
			error.message(), error.value());
		return false;
	}

	error.clear();
	m_WebSocket.handshake(m_GatewayUrl, "/", error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't upgrade to WSS protocol: {} ({})",
			error.message(), error.value());
		return false;
	}

	return true;
}

void CNetwork::WsDisconnect()
{
	boost::system::error_code error;
	m_WebSocket.close(beast::websocket::close_code::normal, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::WARNING, "Error while sending WS close frame: {} ({})",
			error.message(), error.value());
	}

	error.clear();
	m_WssStream.lowest_layer().shutdown(asio::ip::tcp::socket::shutdown_both, error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::WARNING, "Error while shutting down WS connection: {} ({})",
			error.message(), error.value());
	}

	error.clear();
	m_WssStream.lowest_layer().close(error);
	if (error)
	{
		CLog::Get()->Log(LogLevel::WARNING, "Error while closing WS connection: {} ({})",
			error.message(), error.value());
	}

	m_HeartbeatTimer.cancel();
}

void CNetwork::WsIdentify()
{
#ifdef WIN32
	std::string os_name = "Windows";
#else
	std::string os_name = "Linux";
#endif

	json identify_payload = {
		{ "op", 2 },
		{ "d",{
			{ "token", m_Token },
			{ "v", 5 },
			{ "compress", false },
			{ "large_threshold", 100 },
			{ "properties",{
				{ "$os", os_name },
				{ "$browser", "boost::asio" },
				{ "$device", "SA-MP DCC plugin" },
				{ "$referrer", "" },
				{ "$referring_domain", "" }
			} }
		} }
	};

	m_WebSocket.write(asio::buffer(identify_payload.dump()));
}

void CNetwork::WsSendResumePayload()
{
	if (!WsConnect())
		return;

	WsRead();

	json resume_payload = {
		{ "op", 6 },
		{ "d", {
			{ "token", m_Token },
			{ "session_id", m_SessionId },
			{ "seq", m_SequenceNumber }
		}}
	};
	m_WebSocket.write(asio::buffer(resume_payload.dump()));
}

void CNetwork::WsRead()
{
	m_WebSocket.async_read(m_WebSocketOpcode, m_WebSocketBuffer,
		std::bind(&CNetwork::OnWsRead, this, std::placeholders::_1));
}

void CNetwork::OnWsRead(boost::system::error_code ec)
{
	if (ec)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Can't read from Discord websocket gateway: {} ({})",
			ec.message(), ec.value());

		return;
	}

	json result = json::parse(beast::to_string(m_WebSocketBuffer.data()));
	m_WebSocketBuffer.consume(m_WebSocketBuffer.size());

	int payload_opcode = result["op"].get<int>();
	switch (payload_opcode)
	{
		case 0:
		{
			m_SequenceNumber = result["s"];

			static const std::unordered_map<std::string, WsEvent> events_map{
				{ "READY", WsEvent::READY },
				{ "RESUMED", WsEvent::RESUMED },
				{ "CHANNEL_CREATE", WsEvent::CHANNEL_CREATE },
				{ "CHANNEL_UPDATE", WsEvent::CHANNEL_UPDATE },
				{ "CHANNEL_DELETE", WsEvent::CHANNEL_DELETE },
				{ "GUILD_CREATE", WsEvent::GUILD_CREATE },
				{ "GUILD_UPDATE", WsEvent::GUILD_UPDATE },
				{ "GUILD_DELETE", WsEvent::GUILD_DELETE },
				{ "GUILD_BAN_ADD", WsEvent::GUILD_BAN_ADD },
				{ "GUILD_BAN_REMOVE", WsEvent::GUILD_BAN_REMOVE },
				{ "GUILD_EMOJIS_UPDATE", WsEvent::GUILD_EMOJIS_UPDATE },
				{ "GUILD_INTEGRATIONS_UPDATE", WsEvent::GUILD_INTEGRATIONS_UPDATE },
				{ "GUILD_MEMBER_ADD", WsEvent::GUILD_MEMBER_ADD },
				{ "GUILD_MEMBER_REMOVE", WsEvent::GUILD_MEMBER_REMOVE },
				{ "GUILD_MEMBER_UPDATE", WsEvent::GUILD_MEMBER_UPDATE },
				{ "GUILD_MEMBERS_CHUNK", WsEvent::GUILD_MEMBERS_CHUNK },
				{ "GUILD_ROLE_CREATE", WsEvent::GUILD_ROLE_CREATE },
				{ "GUILD_ROLE_UPDATE", WsEvent::GUILD_ROLE_UPDATE },
				{ "GUILD_ROLE_DELETE", WsEvent::GUILD_ROLE_DELETE },
				{ "MESSAGE_CREATE", WsEvent::MESSAGE_CREATE },
				{ "MESSAGE_UPDATE", WsEvent::MESSAGE_UPDATE },
				{ "MESSAGE_DELETE", WsEvent::MESSAGE_DELETE },
				{ "MESSAGE_DELETE_BULK", WsEvent::MESSAGE_DELETE_BULK },
				{ "PRESENCE_UPDATE", WsEvent::PRESENCE_UPDATE },
				{ "TYPING_START", WsEvent::TYPING_START },
				{ "USER_SETTINGS_UPDATE", WsEvent::USER_SETTINGS_UPDATE },
				{ "USER_UPDATE", WsEvent::USER_UPDATE },
				{ "VOICE_STATE_UPDATE", WsEvent::VOICE_STATE_UPDATE },
				{ "VOICE_SERVER_UPDATE", WsEvent::VOICE_SERVER_UPDATE }
			};

			auto it = events_map.find(result["t"].get<std::string>());
			if (it != events_map.end())
			{
				json &data = result["d"];
				WsEvent event = it->second;
				switch (event)
				{
					case WsEvent::READY:
						m_HeartbeatInterval = std::chrono::milliseconds(data["heartbeat_interval"]);
						m_SessionId = data["session_id"];

						// start heartbeat
						DoHeartbeat({ });
						break;
				}

				auto ev_it = m_EventMap.find(event);
				if (ev_it != m_EventMap.end())
					ev_it->second(data);
			}
			else
			{
				CLog::Get()->Log(LogLevel::WARNING, "Unknown gateway event '{}'", result["t"].get<std::string>());
				CLog::Get()->Log(LogLevel::DEBUG, "UGE res: {}", result.dump(4));
			}
		} break;
		case 7: // reconnect
			WsDisconnect();
			WsConnect();
			WsSendResumePayload();
			DoHeartbeat({ });
			break;
		case 9: // invalid session
			WsIdentify();
			break;
		default:
			CLog::Get()->Log(LogLevel::WARNING, "Unhandled payload opcode '{}'", payload_opcode);
			CLog::Get()->Log(LogLevel::DEBUG, "UPO res: {}", result.dump(4));
	}

	WsRead();
}

void CNetwork::DoHeartbeat(boost::system::error_code ec)
{
	if (ec)
	{
		CLog::Get()->Log(LogLevel::ERROR, "Heartbeat error: {} ({})",
			ec.message(), ec.value());
		return;
	}

	json heartbeat_payload = {
		{ "op", 1 },
		{ "d", m_SequenceNumber }
	};
	m_WebSocket.write(asio::buffer(heartbeat_payload.dump()));

	m_HeartbeatTimer.expires_from_now(m_HeartbeatInterval);
	m_HeartbeatTimer.async_wait(std::bind(&CNetwork::DoHeartbeat, this, std::placeholders::_1));
}

void CNetwork::HttpWriteRequest(std::string const &method,
	std::string const &url, std::string const &content, std::function<void()> &&callback)
{
	auto req = std::make_shared<beast::http::request<beast::http::string_body>>();
	req->method = method;
	req->url = "/api" + url;
	req->version = 11;
	req->headers.replace("Host", "discordapp.com");
	if (!content.empty())
		req->headers.replace("Content-Type", "application/json");
	req->headers.replace("Authorization", "Bot " + m_Token);
	req->body = content;

	beast::http::prepare(*req);

	beast::http::async_write(
		m_HttpsStream,
		*req,
		[req, url, method, callback](boost::system::error_code ec)
		{
			if (ec)
			{
				CLog::Get()->Log(LogLevel::ERROR, "Error while sending HTTP {} request to '{}': {}",
					method, url, ec.message());
				return;
			}

			if (callback)
				callback();
		}
	);
}

void CNetwork::HttpReadResponse(HttpReadResponseCallback_t &&callback)
{
	auto sb = std::make_shared<beast::streambuf>();
	auto response = std::make_shared<beast::http::response<beast::http::streambuf_body>>();
	beast::http::async_read(
		m_HttpsStream,
		*sb,
		*response,
		[callback, sb, response](boost::system::error_code ec)
		{
			if (ec)
			{
				CLog::Get()->Log(LogLevel::ERROR, "Error while retrieving HTTP response: {}",
					ec.message());
				return;
			}

			callback(sb, response);
		}
	);
}

void CNetwork::HttpGet(std::string const &url, HttpGetCallback_t &&callback)
{
	HttpWriteRequest("GET", url, "", [this, callback]()
	{
		HttpReadResponse([callback](SharedStreambuf_t sb, SharedResponse_t resp)
		{
			callback({ resp->status, resp->reason, beast::to_string(resp->body.data()),
				beast::to_string(sb->data()) });
		});
	});
}

void CNetwork::HttpPost(std::string const &url, std::string const &content)
{
	HttpWriteRequest("POST", url, content, nullptr);
}
<|endoftext|>


<commit_before>#include <scheduler/scheduler.hh>
#include <scheduler/tag.hh>

namespace scheduler
{
  Tag::Tag(const rTag& parent, libport::Symbol name)
    : parent_(parent)
    , blocked_(false)
    , frozen_(false)
    , prio_(parent->prio_)
    , flow_control_(false)
  {
    if (parent)
      name_ = libport::Symbol::Symbol
	(parent->name_get().name_get() + "." + name.name_get());
    else
      name_ = name;
  }

  void
  Tag::stop(Scheduler& sched, const boost::any& payload) const
  {
    sched.signal_stop(*this, payload);
  }

  const boost::any&
  Tag::payload_get() const
  {
    if (blocked_)
      return payload_;
    else if (parent_)
      return parent_->payload_get();
    else
      throw object::SchedulingError
	("attempt to retrieve payload of an unblocked tag");
  }

  void
  Tag::apply_tag(tags_type& tags, libport::Finally* finally)
  {
    tags.push_back(this);
    if (finally)
      *finally << boost::bind(&tags_type::pop_back, boost::ref(tags));
  }

} // namespace scheduler
<commit_msg>Do not raise an exception for an impossible condition.<commit_after>#include <scheduler/scheduler.hh>
#include <scheduler/tag.hh>

namespace scheduler
{
  Tag::Tag(const rTag& parent, libport::Symbol name)
    : parent_(parent)
    , blocked_(false)
    , frozen_(false)
    , prio_(parent->prio_)
    , flow_control_(false)
  {
    if (parent)
      name_ = libport::Symbol::Symbol
	(parent->name_get().name_get() + "." + name.name_get());
    else
      name_ = name;
  }

  void
  Tag::stop(Scheduler& sched, const boost::any& payload) const
  {
    sched.signal_stop(*this, payload);
  }

  const boost::any&
  Tag::payload_get() const
  {
    if (blocked_)
      return payload_;
    else if (parent_)
      return parent_->payload_get();
    // This is an internal error and can never happen.
    abort();
  }

  void
  Tag::apply_tag(tags_type& tags, libport::Finally* finally)
  {
    tags.push_back(this);
    if (finally)
      *finally << boost::bind(&tags_type::pop_back, boost::ref(tags));
  }

} // namespace scheduler
<|endoftext|>