<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// bwtree_index.cpp
//
// Identification: src/backend/index/bwtree_index.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "common/logger.h"
#include "index/bwtree_index.h"
#include "index/index_key.h"
#include "storage/tuple.h"

namespace peloton {
namespace index {

BWTREE_TEMPLATE_ARGUMENTS
BWTREE_INDEX_TYPE::BWTreeIndex(IndexMetadata *metadata) :
      // Base class
      Index{metadata},
      // Key "less than" relation comparator
      comparator{},
      // Key equality checker
      equals{},
      // Key hash function
      hash_func{},
      // NOTE: These two arguments need to be constructed in advance
      // and do not have trivial constructor
      container{comparator,
                equals,
                hash_func} {
  return;
}

BWTREE_TEMPLATE_ARGUMENTS
BWTREE_INDEX_TYPE::~BWTreeIndex() {
  return;
}

/*
 * InsertEntry() - insert a key-value pair into the map
 *
 * If the key value pair already exists in the map, just return false
 */
BWTREE_TEMPLATE_ARGUMENTS
bool
BWTREE_INDEX_TYPE::InsertEntry(const storage::Tuple *key,
                               const ItemPointer &location) {
  KeyType index_key;
  index_key.SetFromKey(key);

  ItemPointer *item_p = new ItemPointer{location};

  bool ret = container.Insert(index_key, item_p);
  // If insertion fails we just delete the new value and return false
  // to notify the caller
  if(ret == false) {
    delete item_p;
  }

  return ret;
}

/*
 * DeleteEntry() - Removes a key-value pair
 *
 * If the key-value pair does not exists yet in the map return false
 */
BWTREE_TEMPLATE_ARGUMENTS
bool
BWTREE_INDEX_TYPE::DeleteEntry(const storage::Tuple *key,
                               const ItemPointer &location) {
  KeyType index_key;
  index_key.SetFromKey(key);

  // Must allocate new memory here
  ItemPointer *ip_p = new ItemPointer{location};

  // In Delete() since we just use the value for comparison (i.e. read-only)
  // it is unnecessary for us to allocate memory
  bool ret = container.DeleteExchange(index_key, &ip_p);

  // IF delete succeeds then DeleteExchange() will exchange the deleted
  // value into this variable
  if(ret == true) {
    //delete ip_p;
  } else {
    // This will delete the unused memory
    delete ip_p;
  }

  return ret;
}

BWTREE_TEMPLATE_ARGUMENTS
bool
BWTREE_INDEX_TYPE::CondInsertEntry(const storage::Tuple *key,
                                   const ItemPointer &location,
                                   std::function<bool(const ItemPointer &)> predicate) {
  KeyType index_key;
  index_key.SetFromKey(key);

  ItemPointer *item_p = new ItemPointer{location};
  bool predicate_satisfied = false;

  // This function will complete them in one step
  // predicate will be set to nullptr if the predicate
  // returns true for some value
  bool ret = container.ConditionalInsert(index_key,
                                         item_p,
                                         predicate,
                                         &predicate_satisfied);

  // If predicate is not satisfied then we know insertion successes
  if(predicate_satisfied == false) {
    // So it should always succeed?
    assert(ret == true);
  } else {
    assert(ret == false);

    delete item_p;
  }

  return ret;
}

BWTREE_TEMPLATE_ARGUMENTS
void
BWTREE_INDEX_TYPE::Scan(const std::vector<Value> &values,
                        const std::vector<oid_t> &key_column_ids,
                        const std::vector<ExpressionType> &expr_types,
                        const ScanDirectionType &scan_direction,
                        std::vector<ItemPointer *> &result) {
  KeyType index_key;

  // Checkif we have leading (leftmost) column equality
  // refer : http://www.postgresql.org/docs/8.2/static/indexes-multicolumn.html
  oid_t leading_column_id = 0;
  auto key_column_ids_itr = std::find(key_column_ids.begin(),
                                      key_column_ids.end(), leading_column_id);

  // SPECIAL CASE : leading column id is one of the key column ids
  // and is involved in a equality constraint
  bool special_case = false;
  if (key_column_ids_itr != key_column_ids.end()) {
    auto offset = std::distance(key_column_ids.begin(), key_column_ids_itr);
    if (expr_types[offset] == EXPRESSION_TYPE_COMPARE_EQUAL) {
      special_case = true;
    }
  }

  LOG_TRACE("Special case : %d ", special_case);

  // This is only a placeholder that cannot be moved but can be assigned to
  auto scan_begin_itr = container.NullIterator();

  std::unique_ptr<storage::Tuple> start_key;
  bool all_constraints_are_equal = false;

  // If it is a special case, we can figure out the range to scan in the index
  if (special_case == true) {
    start_key.reset(new storage::Tuple(metadata->GetKeySchema(), true));

    // Construct the lower bound key tuple
    all_constraints_are_equal = ConstructLowerBoundTuple(
        start_key.get(), values, key_column_ids, expr_types);

    LOG_TRACE("All constraints are equal : %d ", all_constraints_are_equal);

    index_key.SetFromKey(start_key.get());
/*
    // If it is point query then we just do a GetValue() since GetValue()
    // is way more faster than scanning using iterator
    if(all_constraints_are_equal == true) {
      //printf("All constraints are equal\n");

      // This retrieves a list of ItemPointer *
      container.GetValue(index_key, result);

      return;
    }
*/
    //printf("Non special case\n");

    // This returns an iterator pointing to index_key's values
    scan_begin_itr = container.Begin(index_key);
  } else {
    scan_begin_itr = container.Begin();
  }

  switch (scan_direction) {
    case SCAN_DIRECTION_TYPE_FORWARD:
    case SCAN_DIRECTION_TYPE_BACKWARD: {
      // Scan the index entries in forward direction
      for (auto scan_itr = scan_begin_itr;
           scan_itr.IsEnd() == false;
           scan_itr++) {
        KeyType &scan_current_key = const_cast<KeyType &>(scan_itr->first);

        auto tuple =
            scan_current_key.GetTupleForComparison(metadata->GetKeySchema());

        // Compare the current key in the scan with "values" based on
        // "expression types"
        // For instance, "5" EXPR_GREATER_THAN "2" is true
        if (Compare(tuple, key_column_ids, expr_types, values) == true) {
          result.push_back(scan_itr->second);
        } else {
          // We can stop scanning if we know that all constraints are equal
          if (all_constraints_are_equal == true) {
            break;
          }
        }
      }

    } break;

    case SCAN_DIRECTION_TYPE_INVALID:
    default:
      throw Exception("Invalid scan direction \n");
      break;
  }

  return;
}

BWTREE_TEMPLATE_ARGUMENTS
void
BWTREE_INDEX_TYPE::ScanAllKeys(std::vector<ItemPointer *> &result) {
  auto it = container.Begin();

  // scan all entries
  while (it.IsEnd() == false) {
    result.push_back(it->second);
    it++;
  }

  return;
}

BWTREE_TEMPLATE_ARGUMENTS
void
BWTREE_INDEX_TYPE::ScanKey(const storage::Tuple *key,
                           std::vector<ItemPointer *> &result) {
  KeyType index_key;
  index_key.SetFromKey(key);

  // This function in BwTree fills a given vector
  container.GetValue(index_key, result);

  return;
}

BWTREE_TEMPLATE_ARGUMENTS
std::string
BWTREE_INDEX_TYPE::GetTypeName() const {
  return "BWTree";
}

// NOTE: If ints key is used as an optimization just uncommend
// the following in order to instanciation the template before it is
// linked in linking stage

/*
template class BWTreeIndex<IntsKey<1>,
                           ItemPointer *,
                           IntsComparator<1>,
                           IntsEqualityChecker<1>,
                           IntsHasher<1>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<IntsKey<2>,
                           ItemPointer *,
                           IntsComparator<2>,
                           IntsEqualityChecker<2>,
                           IntsHasher<2>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<IntsKey<3>,
                           ItemPointer *,
                           IntsComparator<3>,
                           IntsEqualityChecker<3>,
                           IntsHasher<3>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<IntsKey<4>,
                           ItemPointer *,
                           IntsComparator<4>,
                           IntsEqualityChecker<4>,
                           IntsHasher<4>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
*/

// Generic key
template class BWTreeIndex<GenericKey<4>,
                           ItemPointer *,
                           GenericComparator<4>,
                           GenericEqualityChecker<4>,
                           GenericHasher<4>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<GenericKey<8>,
                           ItemPointer *,
                           GenericComparator<8>,
                           GenericEqualityChecker<8>,
                           GenericHasher<8>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<GenericKey<16>,
                           ItemPointer *,
                           GenericComparator<16>,
                           GenericEqualityChecker<16>,
                           GenericHasher<16>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<GenericKey<64>,
                           ItemPointer *,
                           GenericComparator<64>,
                           GenericEqualityChecker<64>,
                           GenericHasher<64>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<GenericKey<256>,
                           ItemPointer *,
                           GenericComparator<256>,
                           GenericEqualityChecker<256>,
                           GenericHasher<256>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;

// Tuple key
template class BWTreeIndex<TupleKey,
                           ItemPointer *,
                           TupleKeyComparator,
                           TupleKeyEqualityChecker,
                           TupleKeyHasher,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;

}  // End index namespace
}  // End peloton namespace
<commit_msg>Change constructor such that GC Thread is not started automatically<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// bwtree_index.cpp
//
// Identification: src/backend/index/bwtree_index.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "common/logger.h"
#include "index/bwtree_index.h"
#include "index/index_key.h"
#include "storage/tuple.h"

namespace peloton {
namespace index {

BWTREE_TEMPLATE_ARGUMENTS
BWTREE_INDEX_TYPE::BWTreeIndex(IndexMetadata *metadata) :
      // Base class
      Index{metadata},
      // Key "less than" relation comparator
      comparator{},
      // Key equality checker
      equals{},
      // Key hash function
      hash_func{},
      // NOTE: These two arguments need to be constructed in advance
      // and do not have trivial constructor
      //
      // NOTE 2: We set the first parameter to false to disable automatic GC
      //
      container{false,
                comparator,
                equals,
                hash_func} {

  return;
}

BWTREE_TEMPLATE_ARGUMENTS
BWTREE_INDEX_TYPE::~BWTreeIndex() {
  return;
}

/*
 * InsertEntry() - insert a key-value pair into the map
 *
 * If the key value pair already exists in the map, just return false
 */
BWTREE_TEMPLATE_ARGUMENTS
bool
BWTREE_INDEX_TYPE::InsertEntry(const storage::Tuple *key,
                               const ItemPointer &location) {
  KeyType index_key;
  index_key.SetFromKey(key);

  ItemPointer *item_p = new ItemPointer{location};

  bool ret = container.Insert(index_key, item_p);
  // If insertion fails we just delete the new value and return false
  // to notify the caller
  if(ret == false) {
    delete item_p;
  }

  return ret;
}

/*
 * DeleteEntry() - Removes a key-value pair
 *
 * If the key-value pair does not exists yet in the map return false
 */
BWTREE_TEMPLATE_ARGUMENTS
bool
BWTREE_INDEX_TYPE::DeleteEntry(const storage::Tuple *key,
                               const ItemPointer &location) {
  KeyType index_key;
  index_key.SetFromKey(key);

  // Must allocate new memory here
  ItemPointer *ip_p = new ItemPointer{location};

  // In Delete() since we just use the value for comparison (i.e. read-only)
  // it is unnecessary for us to allocate memory
  bool ret = container.DeleteExchange(index_key, &ip_p);

  // IF delete succeeds then DeleteExchange() will exchange the deleted
  // value into this variable
  if(ret == true) {
    //delete ip_p;
  } else {
    // This will delete the unused memory
    delete ip_p;
  }

  return ret;
}

BWTREE_TEMPLATE_ARGUMENTS
bool
BWTREE_INDEX_TYPE::CondInsertEntry(const storage::Tuple *key,
                                   const ItemPointer &location,
                                   std::function<bool(const ItemPointer &)> predicate) {
  KeyType index_key;
  index_key.SetFromKey(key);

  ItemPointer *item_p = new ItemPointer{location};
  bool predicate_satisfied = false;

  // This function will complete them in one step
  // predicate will be set to nullptr if the predicate
  // returns true for some value
  bool ret = container.ConditionalInsert(index_key,
                                         item_p,
                                         predicate,
                                         &predicate_satisfied);

  // If predicate is not satisfied then we know insertion successes
  if(predicate_satisfied == false) {
    // So it should always succeed?
    assert(ret == true);
  } else {
    assert(ret == false);

    delete item_p;
  }

  return ret;
}

BWTREE_TEMPLATE_ARGUMENTS
void
BWTREE_INDEX_TYPE::Scan(const std::vector<Value> &values,
                        const std::vector<oid_t> &key_column_ids,
                        const std::vector<ExpressionType> &expr_types,
                        const ScanDirectionType &scan_direction,
                        std::vector<ItemPointer *> &result) {
  KeyType index_key;

  // Checkif we have leading (leftmost) column equality
  // refer : http://www.postgresql.org/docs/8.2/static/indexes-multicolumn.html
  oid_t leading_column_id = 0;
  auto key_column_ids_itr = std::find(key_column_ids.begin(),
                                      key_column_ids.end(), leading_column_id);

  // SPECIAL CASE : leading column id is one of the key column ids
  // and is involved in a equality constraint
  bool special_case = false;
  if (key_column_ids_itr != key_column_ids.end()) {
    auto offset = std::distance(key_column_ids.begin(), key_column_ids_itr);
    if (expr_types[offset] == EXPRESSION_TYPE_COMPARE_EQUAL) {
      special_case = true;
    }
  }

  LOG_TRACE("Special case : %d ", special_case);

  // This is only a placeholder that cannot be moved but can be assigned to
  auto scan_begin_itr = container.NullIterator();

  std::unique_ptr<storage::Tuple> start_key;
  bool all_constraints_are_equal = false;

  // If it is a special case, we can figure out the range to scan in the index
  if (special_case == true) {
    start_key.reset(new storage::Tuple(metadata->GetKeySchema(), true));

    // Construct the lower bound key tuple
    all_constraints_are_equal = ConstructLowerBoundTuple(
        start_key.get(), values, key_column_ids, expr_types);

    LOG_TRACE("All constraints are equal : %d ", all_constraints_are_equal);

    index_key.SetFromKey(start_key.get());
/*
    // If it is point query then we just do a GetValue() since GetValue()
    // is way more faster than scanning using iterator
    if(all_constraints_are_equal == true) {
      //printf("All constraints are equal\n");

      // This retrieves a list of ItemPointer *
      container.GetValue(index_key, result);

      return;
    }
*/
    //printf("Non special case\n");

    // This returns an iterator pointing to index_key's values
    scan_begin_itr = container.Begin(index_key);
  } else {
    scan_begin_itr = container.Begin();
  }

  switch (scan_direction) {
    case SCAN_DIRECTION_TYPE_FORWARD:
    case SCAN_DIRECTION_TYPE_BACKWARD: {
      // Scan the index entries in forward direction
      for (auto scan_itr = scan_begin_itr;
           scan_itr.IsEnd() == false;
           scan_itr++) {
        KeyType &scan_current_key = const_cast<KeyType &>(scan_itr->first);

        auto tuple =
            scan_current_key.GetTupleForComparison(metadata->GetKeySchema());

        // Compare the current key in the scan with "values" based on
        // "expression types"
        // For instance, "5" EXPR_GREATER_THAN "2" is true
        if (Compare(tuple, key_column_ids, expr_types, values) == true) {
          result.push_back(scan_itr->second);
        } else {
          // We can stop scanning if we know that all constraints are equal
          if (all_constraints_are_equal == true) {
            break;
          }
        }
      }

    } break;

    case SCAN_DIRECTION_TYPE_INVALID:
    default:
      throw Exception("Invalid scan direction \n");
      break;
  }

  return;
}

BWTREE_TEMPLATE_ARGUMENTS
void
BWTREE_INDEX_TYPE::ScanAllKeys(std::vector<ItemPointer *> &result) {
  auto it = container.Begin();

  // scan all entries
  while (it.IsEnd() == false) {
    result.push_back(it->second);
    it++;
  }

  return;
}

BWTREE_TEMPLATE_ARGUMENTS
void
BWTREE_INDEX_TYPE::ScanKey(const storage::Tuple *key,
                           std::vector<ItemPointer *> &result) {
  KeyType index_key;
  index_key.SetFromKey(key);

  // This function in BwTree fills a given vector
  container.GetValue(index_key, result);

  return;
}

BWTREE_TEMPLATE_ARGUMENTS
std::string
BWTREE_INDEX_TYPE::GetTypeName() const {
  return "BWTree";
}

// NOTE: If ints key is used as an optimization just uncommend
// the following in order to instanciation the template before it is
// linked in linking stage

/*
template class BWTreeIndex<IntsKey<1>,
                           ItemPointer *,
                           IntsComparator<1>,
                           IntsEqualityChecker<1>,
                           IntsHasher<1>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<IntsKey<2>,
                           ItemPointer *,
                           IntsComparator<2>,
                           IntsEqualityChecker<2>,
                           IntsHasher<2>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<IntsKey<3>,
                           ItemPointer *,
                           IntsComparator<3>,
                           IntsEqualityChecker<3>,
                           IntsHasher<3>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<IntsKey<4>,
                           ItemPointer *,
                           IntsComparator<4>,
                           IntsEqualityChecker<4>,
                           IntsHasher<4>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
*/

// Generic key
template class BWTreeIndex<GenericKey<4>,
                           ItemPointer *,
                           GenericComparator<4>,
                           GenericEqualityChecker<4>,
                           GenericHasher<4>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<GenericKey<8>,
                           ItemPointer *,
                           GenericComparator<8>,
                           GenericEqualityChecker<8>,
                           GenericHasher<8>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<GenericKey<16>,
                           ItemPointer *,
                           GenericComparator<16>,
                           GenericEqualityChecker<16>,
                           GenericHasher<16>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<GenericKey<64>,
                           ItemPointer *,
                           GenericComparator<64>,
                           GenericEqualityChecker<64>,
                           GenericHasher<64>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;
template class BWTreeIndex<GenericKey<256>,
                           ItemPointer *,
                           GenericComparator<256>,
                           GenericEqualityChecker<256>,
                           GenericHasher<256>,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;

// Tuple key
template class BWTreeIndex<TupleKey,
                           ItemPointer *,
                           TupleKeyComparator,
                           TupleKeyEqualityChecker,
                           TupleKeyHasher,
                           ItemPointerComparator,
                           ItemPointerHashFunc>;

}  // End index namespace
}  // End peloton namespace
<|endoftext|>


<commit_before>
#include "lib/safeint3.hpp"
#include "intrinsic_overflow.hpp"
#include "vmachine.hpp"

using namespace usagi;

// VMにライブラリを登録する。
void IntrinsicOverflow::regist(VMachine& vm) {
  vm.regist_intrinsic_func("llvm.sadd.with.overflow.i16", IntrinsicOverflow::sadd, 16);
  vm.regist_intrinsic_func("llvm.sadd.with.overflow.i32", IntrinsicOverflow::sadd, 32);
  vm.regist_intrinsic_func("llvm.sadd.with.overflow.i64", IntrinsicOverflow::sadd, 64);

  vm.regist_intrinsic_func("llvm.smul.with.overflow.i16", IntrinsicOverflow::smul, 16);
  vm.regist_intrinsic_func("llvm.smul.with.overflow.i32", IntrinsicOverflow::smul, 32);
  vm.regist_intrinsic_func("llvm.smul.with.overflow.i64", IntrinsicOverflow::smul, 64);

  vm.regist_intrinsic_func("llvm.ssub.with.overflow.i16", IntrinsicOverflow::ssub, 16);
  vm.regist_intrinsic_func("llvm.ssub.with.overflow.i32", IntrinsicOverflow::ssub, 32);
  vm.regist_intrinsic_func("llvm.ssub.with.overflow.i64", IntrinsicOverflow::ssub, 64);

  vm.regist_intrinsic_func("llvm.uadd.with.overflow.i16", IntrinsicOverflow::uadd, 16);
  vm.regist_intrinsic_func("llvm.uadd.with.overflow.i32", IntrinsicOverflow::uadd, 32);
  vm.regist_intrinsic_func("llvm.uadd.with.overflow.i64", IntrinsicOverflow::uadd, 64);

  vm.regist_intrinsic_func("llvm.umul.with.overflow.i16", IntrinsicOverflow::umul, 16);
  vm.regist_intrinsic_func("llvm.umul.with.overflow.i32", IntrinsicOverflow::umul, 32);
  vm.regist_intrinsic_func("llvm.umul.with.overflow.i64", IntrinsicOverflow::umul, 64);

  vm.regist_intrinsic_func("llvm.usub.with.overflow.i16", IntrinsicOverflow::usub, 16);
  vm.regist_intrinsic_func("llvm.usub.with.overflow.i32", IntrinsicOverflow::usub, 32);
  vm.regist_intrinsic_func("llvm.usub.with.overflow.i64", IntrinsicOverflow::usub, 64);
}

/**
 * @param SFUNC SafeIntの演算関数
 * @param INT_T 計算のベースになる整数型
 * @param WIDTH 整数のビット幅
 */
#define M_CASE_PER_WIDTH(SFUNC, INT_T, WIDTH)				\
  case WIDTH: {								\
  INT_T a = static_cast<INT_T>(VMachine::read_intrinsic_param_i##WIDTH(src, &seek)); \
  INT_T b = static_cast<INT_T>(VMachine::read_intrinsic_param_i##WIDTH(src, &seek)); \
  INT_T res;								\
  bool flg = SFUNC<INT_T, INT_T>(a, b, res);				\
  *reinterpret_cast<INT_T*>(vm.get_raw_addr(dst)) = res;		\
  *reinterpret_cast<uint8_t*>(vm.get_raw_addr(dst) + sizeof(INT_T)) = (flg ? 0x00 : 0xff); \
  } break

/**
 * @param FNAME 作成する関数名
 * @param SFUNC SafeIntの演算関数
 * @param I16 16bit幅の計算のベースになる整数型
 * @param I32 32bit幅の計算のベースになる整数型
 * @param I64 64bit幅の計算のベースになる整数型
 */
#define M_FUNC_PER_METHOD(FNAME, SFUNC, I16, I32, I64) \
  bool IntrinsicOverflow::FNAME(VMachine& vm, Thread& th, IntrinsicFuncParam p, \
				vaddr_t dst, std::vector<uint8_t>& src) { \
    int seek = 0;							\
    switch (p.i64) {							\
      M_CASE_PER_WIDTH(SFUNC, I16, 16);					\
      M_CASE_PER_WIDTH(SFUNC, I32, 32);					\
      M_CASE_PER_WIDTH(SFUNC, I64, 64);					\
    default: assert(false); break;					\
    }									\
    return false;							\
  }

M_FUNC_PER_METHOD(sadd, SafeAdd,      int16_t, int32_t, int64_t)
M_FUNC_PER_METHOD(smul, SafeMultiply, int16_t, int32_t, int64_t)
M_FUNC_PER_METHOD(ssub, SafeSubtract, int16_t, int32_t, int64_t)
M_FUNC_PER_METHOD(uadd, SafeAdd,      uint16_t, uint32_t, uint64_t)
M_FUNC_PER_METHOD(umul, SafeMultiply, uint16_t, uint32_t, uint64_t)
M_FUNC_PER_METHOD(usub, SafeSubtract, uint16_t, uint32_t, uint64_t)

#undef M_FUNC_PER_METHOD
#undef M_CASE_PER_WIDTH
<commit_msg>Fix fault of compile on linux. refs #41<commit_after>
#include "intrinsic_overflow.hpp"
#include "vmachine.hpp"
#include "lib/safeint3.hpp"

using namespace usagi;

// VMにライブラリを登録する。
void IntrinsicOverflow::regist(VMachine& vm) {
  vm.regist_intrinsic_func("llvm.sadd.with.overflow.i16", IntrinsicOverflow::sadd, 16);
  vm.regist_intrinsic_func("llvm.sadd.with.overflow.i32", IntrinsicOverflow::sadd, 32);
  vm.regist_intrinsic_func("llvm.sadd.with.overflow.i64", IntrinsicOverflow::sadd, 64);

  vm.regist_intrinsic_func("llvm.smul.with.overflow.i16", IntrinsicOverflow::smul, 16);
  vm.regist_intrinsic_func("llvm.smul.with.overflow.i32", IntrinsicOverflow::smul, 32);
  vm.regist_intrinsic_func("llvm.smul.with.overflow.i64", IntrinsicOverflow::smul, 64);

  vm.regist_intrinsic_func("llvm.ssub.with.overflow.i16", IntrinsicOverflow::ssub, 16);
  vm.regist_intrinsic_func("llvm.ssub.with.overflow.i32", IntrinsicOverflow::ssub, 32);
  vm.regist_intrinsic_func("llvm.ssub.with.overflow.i64", IntrinsicOverflow::ssub, 64);

  vm.regist_intrinsic_func("llvm.uadd.with.overflow.i16", IntrinsicOverflow::uadd, 16);
  vm.regist_intrinsic_func("llvm.uadd.with.overflow.i32", IntrinsicOverflow::uadd, 32);
  vm.regist_intrinsic_func("llvm.uadd.with.overflow.i64", IntrinsicOverflow::uadd, 64);

  vm.regist_intrinsic_func("llvm.umul.with.overflow.i16", IntrinsicOverflow::umul, 16);
  vm.regist_intrinsic_func("llvm.umul.with.overflow.i32", IntrinsicOverflow::umul, 32);
  vm.regist_intrinsic_func("llvm.umul.with.overflow.i64", IntrinsicOverflow::umul, 64);

  vm.regist_intrinsic_func("llvm.usub.with.overflow.i16", IntrinsicOverflow::usub, 16);
  vm.regist_intrinsic_func("llvm.usub.with.overflow.i32", IntrinsicOverflow::usub, 32);
  vm.regist_intrinsic_func("llvm.usub.with.overflow.i64", IntrinsicOverflow::usub, 64);
}

/**
 * @param SFUNC SafeIntの演算関数
 * @param INT_T 計算のベースになる整数型
 * @param WIDTH 整数のビット幅
 */
#define M_CASE_PER_WIDTH(SFUNC, INT_T, WIDTH)				\
  case WIDTH: {								\
  INT_T a = static_cast<INT_T>(VMachine::read_intrinsic_param_i##WIDTH(src, &seek)); \
  INT_T b = static_cast<INT_T>(VMachine::read_intrinsic_param_i##WIDTH(src, &seek)); \
  INT_T res;								\
  bool flg = SFUNC<INT_T, INT_T>(a, b, res);				\
  *reinterpret_cast<INT_T*>(vm.get_raw_addr(dst)) = res;		\
  *reinterpret_cast<uint8_t*>(vm.get_raw_addr(dst) + sizeof(INT_T)) = (flg ? 0x00 : 0xff); \
  } break

/**
 * @param FNAME 作成する関数名
 * @param SFUNC SafeIntの演算関数
 * @param I16 16bit幅の計算のベースになる整数型
 * @param I32 32bit幅の計算のベースになる整数型
 * @param I64 64bit幅の計算のベースになる整数型
 */
#define M_FUNC_PER_METHOD(FNAME, SFUNC, I16, I32, I64) \
  bool IntrinsicOverflow::FNAME(VMachine& vm, Thread& th, IntrinsicFuncParam p, \
				vaddr_t dst, std::vector<uint8_t>& src) { \
    int seek = 0;							\
    switch (p.i64) {							\
      M_CASE_PER_WIDTH(SFUNC, I16, 16);					\
      M_CASE_PER_WIDTH(SFUNC, I32, 32);					\
      M_CASE_PER_WIDTH(SFUNC, I64, 64);					\
    default: assert(false); break;					\
    }									\
    return false;							\
  }

M_FUNC_PER_METHOD(sadd, SafeAdd,      int16_t, int32_t, int64_t)
M_FUNC_PER_METHOD(smul, SafeMultiply, int16_t, int32_t, int64_t)
M_FUNC_PER_METHOD(ssub, SafeSubtract, int16_t, int32_t, int64_t)
M_FUNC_PER_METHOD(uadd, SafeAdd,      uint16_t, uint32_t, uint64_t)
M_FUNC_PER_METHOD(umul, SafeMultiply, uint16_t, uint32_t, uint64_t)
M_FUNC_PER_METHOD(usub, SafeSubtract, uint16_t, uint32_t, uint64_t)

#undef M_FUNC_PER_METHOD
#undef M_CASE_PER_WIDTH
<|endoftext|>


<commit_before>/*-
 * Copyright (c) 2015 Alexander Nasonov.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

 #include <assert.h>
 #include <stddef.h>

/*
 * The algorithm below is based on paper
 * Cache-Oblivious Peeling of Random Hypergraphs by Djamal Belazzougui,
 * Paolo Boldi, Giuseppe Ottaviano, Rossano Venturini, and Sebastiano
 * Vigna.
 * http://zola.di.unipi.it/rossano/wp-content/papercite-data/pdf/dcc14.pdf
 */
namespace {

template<class T, int R>
struct edge {
	T verts[R];
	T idx; // XXX
};

/*
 * Data type for a valid oriented edge (v0, v1, v2), v1 < v2.
 * The first vertex v0 is implicit and is determined by an index
 * of the corresponding element in the oedges array.
 * If the degree of v0 is greater than 1, other members don't make
 * sense because they're a result of XORing multiple random values.
 */
template<class T, int R>
struct oedge {
	T verts[R-1]; // v1 (and v2, if R==3).
	T degree;     // Degree of v0.
	T edge;
};

template<class T>
inline void
add_remove_oedge(oedge<T,2> *oedges, int delta, T e, T v0, T v1)
{

	oedges[v0].verts[0] ^= v1;
	oedges[v0].degree += delta;
	oedges[v0].edge ^= e;
}

template<class T>
inline void
remove_edge(oedge<T,2> *oedges, T e, T v0, T v1)
{

	return add_remove_oedge(oedges, -1, e, v0, v1);
}

template<class T>
inline void
add_remove_oedge(oedge<T,3> *oedges, int delta, T e, T v0, T v1, T v2)
{

	oedges[v0].verts[v1 < v2 ? 0 : 1] ^= v1;
	oedges[v0].verts[v1 < v2 ? 1 : 0] ^= v2;
	oedges[v0].degree += delta;
	oedges[v0].edge ^= e;
}

template<class T>
inline void
remove_oedge(oedge<T,3> *oedges, T e, T v0, T v1, T v2)
{

	return add_remove_oedge(oedges, -1, e, v0, v1, v2);
}

template<class T>
inline void
add_edge(oedge<T,2> *oedges, T e, const T *verts)
{

	add_remove_oedge(oedges, 1, e, verts[0], verts[1]);
	add_remove_oedge(oedges, 1, e, verts[1], verts[0]);
}

template<class T>
inline void
add_edge(oedge<T,3> *oedges, T e, const T *verts)
{

	add_remove_oedge(oedges, 1, e, verts[0], verts[1], verts[2]);
	add_remove_oedge(oedges, 1, e, verts[1], verts[0], verts[2]);
	add_remove_oedge(oedges, 1, e, verts[2], verts[0], verts[1]);
}

template<class T>
inline size_t
remove_vertex(oedge<T,2> *oedges, T v0, T *order, size_t end)
{

	if (oedges[v0].degree == 1) {
		const T e = oedges[v0].edge;
		const T v1 = oedges[v0].verts[0];
		oedges[v0].degree = 0;
		remove_oedge(oedges, e, v1, v0);
		order[--end] = e;
	}

	return end;
}

template<class T>
inline size_t
remove_vertex(oedge<T,3> *oedges, T v0, T *order, size_t end)
{

	if (oedges[v0].degree == 1) {
		const T e = oedges[v0].edge;
		const T v1 = oedges[v0].verts[0];
		const T v2 = oedges[v0].verts[1];
		oedges[v0].degree = 0;
		remove_oedge(oedges, e, v1, v0, v2);
		remove_oedge(oedges, e, v2, v0, v1);
		order[--end] = e;
	}

	return end;
}

template<class Iter, class Hash, class T, int R>
void
build_graph(Iter keys, size_t nkeys, Hash hash, size_t nverts,
    edge<T,R> *edges, oedge<T,R> *oedges)
{
	// Partition size of an R-partite R-graph.
	const T partsz = nverts / R;
	assert(partsz > 1 && (nverts % R) == 0);

	for (size_t i = 0; i < nkeys; ++i, ++keys) {
		const T *verts = hash(keys->key, keys->keylen);
		for (size_t r = 0; r < R; ++r)
			edges[i].verts[r] = (verts[r] % partsz) + r * partsz;
		add_edge(oedges, i, edges[i].verts);
	}
}

template<class T, int R>
size_t
peel_graph(edge<T,R> *edges, size_t nkeys,
    oedge<T,R> *oedges, size_t nverts, T *order)
{
	size_t end = nkeys;

	for (size_t i = 0; i < nkeys; ++i)
		end = remove_vertex(oedges, i, order, end);

	for (size_t i = nkeys; i > 0 && i > end; --i) {
		const edge<T,R> *e = edges[order[i-1]];
		for (size_t r = 0; r < R; ++r)
			end = remove_vertex(oedges, e->verts[r], order, end);
	}

	return end;
}

} // namespace
<commit_msg>verts -> overts in struct oedge<T,R>.<commit_after>/*-
 * Copyright (c) 2015 Alexander Nasonov.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

 #include <assert.h>
 #include <stddef.h>

/*
 * The algorithm below is based on paper
 * Cache-Oblivious Peeling of Random Hypergraphs by Djamal Belazzougui,
 * Paolo Boldi, Giuseppe Ottaviano, Rossano Venturini, and Sebastiano
 * Vigna.
 * http://zola.di.unipi.it/rossano/wp-content/papercite-data/pdf/dcc14.pdf
 */
namespace {

template<class T, int R>
struct edge {
	T verts[R]; // v0, v1 (and v2, if R==3).
	T idx; // XXX
};

/*
 * Data type for a valid oriented edge (v0, v1, v2), v1 < v2.
 * The first vertex v0 is implicit and is determined by an index
 * of the corresponding element in the oedges array.
 * If the degree of v0 is greater than 1, other members don't make
 * sense because they're a result of XORing multiple random values.
 */
template<class T, int R>
struct oedge {
	T overts[R-1]; // v1 (and v2, if R==3).
	T degree;     // Degree of v0.
	T edge;
};

template<class T>
inline void
add_remove_oedge(oedge<T,2> *oedges, int delta, T e, T v0, T v1)
{

	oedges[v0].overts[0] ^= v1;
	oedges[v0].degree += delta;
	oedges[v0].edge ^= e;
}

template<class T>
inline void
remove_edge(oedge<T,2> *oedges, T e, T v0, T v1)
{

	return add_remove_oedge(oedges, -1, e, v0, v1);
}

template<class T>
inline void
add_remove_oedge(oedge<T,3> *oedges, int delta, T e, T v0, T v1, T v2)
{

	oedges[v0].overts[v1 < v2 ? 0 : 1] ^= v1;
	oedges[v0].overts[v1 < v2 ? 1 : 0] ^= v2;
	oedges[v0].degree += delta;
	oedges[v0].edge ^= e;
}

template<class T>
inline void
remove_oedge(oedge<T,3> *oedges, T e, T v0, T v1, T v2)
{

	return add_remove_oedge(oedges, -1, e, v0, v1, v2);
}

template<class T>
inline void
add_edge(oedge<T,2> *oedges, T e, const T *verts)
{

	add_remove_oedge(oedges, 1, e, verts[0], verts[1]);
	add_remove_oedge(oedges, 1, e, verts[1], verts[0]);
}

template<class T>
inline void
add_edge(oedge<T,3> *oedges, T e, const T *verts)
{

	add_remove_oedge(oedges, 1, e, verts[0], verts[1], verts[2]);
	add_remove_oedge(oedges, 1, e, verts[1], verts[0], verts[2]);
	add_remove_oedge(oedges, 1, e, verts[2], verts[0], verts[1]);
}

template<class T>
inline size_t
remove_vertex(oedge<T,2> *oedges, T v0, T *order, size_t end)
{

	if (oedges[v0].degree == 1) {
		const T e = oedges[v0].edge;
		const T v1 = oedges[v0].overts[0];
		oedges[v0].degree = 0;
		remove_oedge(oedges, e, v1, v0);
		order[--end] = e;
	}

	return end;
}

template<class T>
inline size_t
remove_vertex(oedge<T,3> *oedges, T v0, T *order, size_t end)
{

	if (oedges[v0].degree == 1) {
		const T e = oedges[v0].edge;
		const T v1 = oedges[v0].overts[0];
		const T v2 = oedges[v0].overts[1];
		oedges[v0].degree = 0;
		remove_oedge(oedges, e, v1, v0, v2);
		remove_oedge(oedges, e, v2, v0, v1);
		order[--end] = e;
	}

	return end;
}

template<class Iter, class Hash, class T, int R>
void
build_graph(Iter keys, size_t nkeys, Hash hash, size_t nverts,
    edge<T,R> *edges, oedge<T,R> *oedges)
{
	// Partition size of an R-partite R-graph.
	const T partsz = nverts / R;
	assert(partsz > 1 && (nverts % R) == 0);

	for (size_t i = 0; i < nkeys; ++i, ++keys) {
		const T *verts = hash(keys->key, keys->keylen);
		for (size_t r = 0; r < R; ++r)
			edges[i].verts[r] = (verts[r] % partsz) + r * partsz;
		add_edge(oedges, i, edges[i].verts);
	}
}

template<class T, int R>
size_t
peel_graph(edge<T,R> *edges, size_t nkeys,
    oedge<T,R> *oedges, size_t nverts, T *order)
{
	size_t end = nkeys;

	for (size_t i = 0; i < nkeys; ++i)
		end = remove_vertex(oedges, i, order, end);

	for (size_t i = nkeys; i > 0 && i > end; --i) {
		const edge<T,R> *e = edges[order[i-1]];
		for (size_t r = 0; r < R; ++r)
			end = remove_vertex(oedges, e->verts[r], order, end);
	}

	return end;
}

} // namespace
<|endoftext|>


<commit_before><commit_msg>a few minor cleanups<commit_after><|endoftext|>


<commit_before><commit_msg>push latest barnes-hut<commit_after><|endoftext|>


<commit_before>#include "stack.hpp"
#include <catch.hpp>
SCENARIO("Stack: init", "[init]") {
	stack<int> a;
	REQUIRE(sizeof(a) != 0);
	REQUIRE(a.count() == 0);
}
SCENARIO("Stack: operator==", "[op==]") {
	stack<int> a, b;
	a.push(5);
	a.push(3);
	a.push(5);
	b.push(5);
	b.push(3);
	b.push(5);
	REQUIRE(a == b);
}
SCENARIO("Stack: operator=", "[op=]") {
	stack<int> a;
	a.push(1);
	stack<int> b;
	b = a;
	REQUIRE(b == a);
}
SCENARIO("Stack: count", "[op=]") {
	stack<int> a;
	a.push(7);
	a.push(6);
	a.push(8);
	a.push(9);
	REQUIRE(a.count() == 4);
}
SCENARIO("Stack: pop", "[op=]") {
	stack<int> a;
	a.push(7);
	a.push(6);
	a.push(8);
	a.push(9);
	a.pop();
	REQUIRE(a.count() == 3);
}
<commit_msg>Update init.cpp<commit_after>#include "stack.hpp"
#include <catch.hpp>
SCENARIO("stack: init", "[init]") {
	stack<int> a;
	REQUIRE(sizeof(a) != 0);
	REQUIRE(a.count() == 0);
}
SCENARIO("stack: operator==", "[op==]") {
	stack<int> a, b;
	a.push(5);
	a.push(3);
	a.push(5);
	b.push(5);
	b.push(3);
	b.push(5);
	REQUIRE(a == b);
}
SCENARIO("stack: operator=", "[op=]") {
	stack<int> a;
	a.push(1);
	stack<int> b;
	b = a;
	REQUIRE(b == a);
}
SCENARIO("stack: count", "[op=]") {
	stack<int> a;
	a.push(7);
	a.push(6);
	a.push(8);
	a.push(9);
	REQUIRE(a.count() == 4);
}
SCENARIO("stack: pop", "[op=]") {
	stack<int> a;
	a.push(7);
	a.push(6);
	a.push(8);
	a.push(9);
	a.pop();
	REQUIRE(a.count() == 3);
}
<|endoftext|>


<commit_before>#include <Stack.h>
//#include <Node.hpp>
#include <catch.hpp>

SCENARIO("Stack init", "[init"){
	bool mark=false;
	stack<int> st;
	st.push(1);
	st.push(2);
	if (st.count()!=0)
	{
		mark=true;
	}
	REQUIRE(mark);
}

/*
SCENARIO("Tree init", "[init]") {
         Tree<int> inttree;
         bool mark=false;
         mark=inttree.input("in.txt");

	 REQUIRE(mark);
}

SCENARIO("doubleTree init", "[init]") {
	Tree<double> dtree;
	bool mark=false;
        mark=dtree.input("indouble.txt");
        REQUIRE(mark);
}
SCENARIO("Insert node","[insert]") {
	Tree<int> inttree;
	bool mark=false;
	mark=inttree.insert_node(125);
	REQUIRE(mark);
}

SCENARIO("Output tree","[output]") {
	Tree<int> inttree;
	bool mark=false;
	inttree.input("in.txt");
	mark=inttree.output(inttree.get_root());
	REQUIRE(mark);
}

SCENARIO("inorder walk","[inorder]") {
	Tree<int> inttree;
	bool mark=false;
	inttree.input("in.txt");
	mark=inttree.inorder_walk(inttree.get_root());
	REQUIRE(mark);
}

SCENARIO("inorder walkd","[inotderd]") {
	Tree<double> dtree;
	bool mark=false;
	dtree.input("indouble.txt");
	mark=dtree.inorder_walk(dtree.get_root());
	REQUIRE(mark);
}

SCENARIO("out<<","[out]") {
	bool mark;
	Tree<int> inttree;
	inttree.input("in.txt");
	TreeNode<int>* n=inttree.get_root();
	mark=true;
	try
	{
		cout<<n;
	}
	catch (Empty_tree & e)
	{
		mark=false;
	}
	REQUIRE(mark);
}

SCENARIO("Exception input","[exceptinput]") {
	bool marker=false;
	Tree<int> inttree;
	try
	{
		inttree.input("aavavasvas.txt");
	}
	catch (File_Not_Open & e)
	{
	    marker=true;
	}
	REQUIRE(marker);
}

SCENARIO("Exception out","[exceptout]") {
        bool marker=false;
	Tree<int> inttree;
	try
	{
	    inttree.output(inttree.get_root());
	}
	catch (Empty_tree & e)
	{
	    marker=true;
	}
	REQUIRE(marker);
}

SCENARIO("Delete root","[delete r ]") {
	 Tree<int> inttree;
	 inttree.input("in.txt");
	 //удаление корня
	 inttree.delete_node(inttree.get_root());
	 REQUIRE(!inttree.search(inttree.get_root(),5));
	 REQUIRE(inttree.search(inttree.get_root(),4));
	 REQUIRE(inttree.search(inttree.get_root(),2));
	 REQUIRE(inttree.search(inttree.get_root(),3));
}

SCENARIO("Delete node","[delete n]") {
	 Tree<int> inttree;
	 inttree.input("in.txt");
	 //удаление узла с левым дочерним узлом
	 TreeNode<int>* node;
	 node=inttree.find_node(inttree.get_root(),4);
	 inttree.delete_node(node);
	 REQUIRE(!inttree.search(inttree.get_root(),4));
	 REQUIRE(inttree.search(inttree.get_root(),5));
	 REQUIRE(inttree.search(inttree.get_root(),2));
	 REQUIRE(inttree.search(inttree.get_root(),3));
}

*/
<commit_msg>Update init.cpp<commit_after>#include <Stack.h>
#include <catch.hpp>

SCENARIO("Stack init", "[init"){
	bool mark=false;
	stack<int> st;
	if ((st.count()==0))
	{
		mark=true;
	}
	REQUIRE(mark);
}

SCENARIO("Stack push", "[push]"){
	bool mark=false;
	stack<int> st;
	st.push(1);
	st.push(2);
	if ((st.count()==2)&&(st.pop()==2)&&(st.pop()==1))
	{
		mark=true;
	}
	REQUIRE(mark);
}

SCENARIO("Stack pop", "[pop]"){
	bool mark=false;
	stack<int> st;
	st.push(123);
	if (st.pop()==123)
	{
		mark=true;
	}
}
<|endoftext|>


<commit_before>#include <catch/catch.hpp>

#include <vili/parser/parser.hpp>

TEST_CASE("Inline object")
{
    SECTION("Simple object")
    {
        vili::node root
            = vili::parser::from_string("object: {a: 15, b: [16, 17], c: \"18\"}");
        REQUIRE(root["object"]["a"].as<vili::integer>() == 15);
        REQUIRE(root["object"]["b"].as<vili::array>() == vili::array { 16, 17 });
        REQUIRE(root["object"]["c"].as<vili::string>() == "18");
    }
}

TEST_CASE("Multiline object")
{
    SECTION("Comma separator")
    {
        vili::node root = vili::parser::from_string(
            "object: { a: 15, b: [16, 17], c: \"18\"}");
        REQUIRE(root["object"]["a"].as<vili::integer>() == 15);
        REQUIRE(root["object"]["b"].as<vili::array>() == vili::array{ 16, 17 });
        REQUIRE(root["object"]["c"].as<vili::string>() == "18");
    }

    SECTION("Newline separator")
    {
        vili::node root = vili::parser::from_string(
            "object: {\n"
            "a: 15\n"
            "b: [16, 17]\n"
            "c: \"18\"\n"
            "}");
        REQUIRE(root["object"]["a"].as<vili::integer>() == 15);
        REQUIRE(root["object"]["b"].as<vili::array>() == vili::array{ 16, 17 });
        REQUIRE(root["object"]["c"].as<vili::string>() == "18");
    }

    SECTION("Mixed separator")
    {
        vili::node root = vili::parser::from_string(
            "object: {\n"
            "a: 15,\n"
            "b: [16, 17]\n"
            "c: \"18\"\n"
            "}");
        REQUIRE(root["object"]["a"].as<vili::integer>() == 15);
        REQUIRE(root["object"]["b"].as<vili::array>() == vili::array{ 16, 17 });
        REQUIRE(root["object"]["c"].as<vili::string>() == "18");
    }

    SECTION("Eol and spaces")
    {
        vili::node root = vili::parser::from_string(
            "object:     {  \n"
            "    a: 15  \n"
            "        ,    \n"
            "b: [16, 17]  \n"
            "\n"
            "   c: \"18\"       \n"
            "}");
        REQUIRE(root["object"]["a"].as<vili::integer>() == 15);
        REQUIRE(root["object"]["b"].as<vili::array>() == vili::array{ 16, 17 });
        REQUIRE(root["object"]["c"].as<vili::string>() == "18");
    }

}

TEST_CASE("Nested objects")
{
    SECTION("One object inside object")
    {
        vili::node root = vili::parser::from_string(
            "object: {\n"
            "a: 15,\n"
            "b: {\n"
            "a: 16, b: 17},\n"
            "c: \"18\"\n"
            "}");
        REQUIRE(root["object"]["a"].as<vili::integer>() == 15);
        REQUIRE(root["object"]["b"]["a"].as<vili::integer>() == 16);
        REQUIRE(root["object"]["b"]["b"].as<vili::integer>() == 17);
        REQUIRE(root["object"]["c"].as<vili::string>() == "18");
    }
}

TEST_CASE("Incorrect object")
{
    SECTION("Missing closing bracket")
    {
        REQUIRE_THROWS_AS(vili::parser::from_string(
            "object: {\n"
            "a: 15,\n"
            "b: [16, 17]\n"
            "c: \"18\"\n"),
        vili::exceptions::parsing_error);
    }

    SECTION("Missing opening bracket")
    {
        REQUIRE_THROWS_AS(vili::parser::from_string(
            "object: \n"
            "a: 15,\n"
            "b: [16, 17]\n"
            "c: \"18\"\n"
            "}"),
        vili::exceptions::parsing_error);
    }

    SECTION("Comma after last element")
    {
        REQUIRE_THROWS_AS(vili::parser::from_string(
            "object: {\n"
            "a: 15,\n"
            "b: [16, 17]\n"
            "c: \"18\",\n"
            "}"),
        vili::exceptions::parsing_error);
    }

    SECTION("Missing comma")
    {
        REQUIRE_THROWS_AS(vili::parser::from_string(
            "object: {\n"
            "a: 15,\n"
            "b: [16, 17] c: \"18\",\n"
            "}"),
        vili::exceptions::parsing_error);
    }

    SECTION("Newline after opening bracket")
    {
        REQUIRE_THROWS_AS(vili::parser::from_string(
            "object: \n"
            "{\n"
            "a: 15,\n"
            "b: [16, 17] c: \"18\",\n"
            "}"),
        vili::exceptions::parsing_error);
    }
}<commit_msg>Added empty object tests<commit_after>#include <catch/catch.hpp>

#include <vili/parser/parser.hpp>

TEST_CASE("Inline object")
{
    SECTION("Simple object")
    {
        vili::node root
            = vili::parser::from_string("object: {a: 15, b: [16, 17], c: \"18\"}");
        REQUIRE(root["object"]["a"].as<vili::integer>() == 15);
        REQUIRE(root["object"]["b"].as<vili::array>() == vili::array { 16, 17 });
        REQUIRE(root["object"]["c"].as<vili::string>() == "18");
    }

    SECTION("Empty object")
    {
        vili::node root
            = vili::parser::from_string("object: {}");
        REQUIRE(root["object"].empty());
    }
}

TEST_CASE("Multiline object")
{
    SECTION("Empty object")
    {
        vili::node root = vili::parser::from_string(
            "object: {\n"
            "   \n"
            "  }");
        REQUIRE(root["object"].empty());
    }

    SECTION("Comma separator")
    {
        vili::node root = vili::parser::from_string(
            "object: { a: 15, b: [16, 17], c: \"18\"}");
        REQUIRE(root["object"]["a"].as<vili::integer>() == 15);
        REQUIRE(root["object"]["b"].as<vili::array>() == vili::array{ 16, 17 });
        REQUIRE(root["object"]["c"].as<vili::string>() == "18");
    }

    SECTION("Newline separator")
    {
        vili::node root = vili::parser::from_string(
            "object: {\n"
            "a: 15\n"
            "b: [16, 17]\n"
            "c: \"18\"\n"
            "}");
        REQUIRE(root["object"]["a"].as<vili::integer>() == 15);
        REQUIRE(root["object"]["b"].as<vili::array>() == vili::array{ 16, 17 });
        REQUIRE(root["object"]["c"].as<vili::string>() == "18");
    }

    SECTION("Mixed separator")
    {
        vili::node root = vili::parser::from_string(
            "object: {\n"
            "a: 15,\n"
            "b: [16, 17]\n"
            "c: \"18\"\n"
            "}");
        REQUIRE(root["object"]["a"].as<vili::integer>() == 15);
        REQUIRE(root["object"]["b"].as<vili::array>() == vili::array{ 16, 17 });
        REQUIRE(root["object"]["c"].as<vili::string>() == "18");
    }

    SECTION("Eol and spaces")
    {
        vili::node root = vili::parser::from_string(
            "object:     {  \n"
            "    a: 15  \n"
            "        ,    \n"
            "b: [16, 17]  \n"
            "\n"
            "   c: \"18\"       \n"
            "}");
        REQUIRE(root["object"]["a"].as<vili::integer>() == 15);
        REQUIRE(root["object"]["b"].as<vili::array>() == vili::array{ 16, 17 });
        REQUIRE(root["object"]["c"].as<vili::string>() == "18");
    }

}

TEST_CASE("Nested objects")
{
    SECTION("One object inside object")
    {
        vili::node root = vili::parser::from_string(
            "object: {\n"
            "a: 15,\n"
            "b: {\n"
            "a: 16, b: 17},\n"
            "c: \"18\"\n"
            "}");
        REQUIRE(root["object"]["a"].as<vili::integer>() == 15);
        REQUIRE(root["object"]["b"]["a"].as<vili::integer>() == 16);
        REQUIRE(root["object"]["b"]["b"].as<vili::integer>() == 17);
        REQUIRE(root["object"]["c"].as<vili::string>() == "18");
    }
}

TEST_CASE("Incorrect object")
{
    SECTION("Missing closing bracket")
    {
        REQUIRE_THROWS_AS(vili::parser::from_string(
            "object: {\n"
            "a: 15,\n"
            "b: [16, 17]\n"
            "c: \"18\"\n"),
        vili::exceptions::parsing_error);
    }

    SECTION("Missing opening bracket")
    {
        REQUIRE_THROWS_AS(vili::parser::from_string(
            "object: \n"
            "a: 15,\n"
            "b: [16, 17]\n"
            "c: \"18\"\n"
            "}"),
        vili::exceptions::parsing_error);
    }

    SECTION("Comma after last element")
    {
        REQUIRE_THROWS_AS(vili::parser::from_string(
            "object: {\n"
            "a: 15,\n"
            "b: [16, 17]\n"
            "c: \"18\",\n"
            "}"),
        vili::exceptions::parsing_error);
    }

    SECTION("Missing comma")
    {
        REQUIRE_THROWS_AS(vili::parser::from_string(
            "object: {\n"
            "a: 15,\n"
            "b: [16, 17] c: \"18\",\n"
            "}"),
        vili::exceptions::parsing_error);
    }

    SECTION("Newline after opening bracket")
    {
        REQUIRE_THROWS_AS(vili::parser::from_string(
            "object: \n"
            "{\n"
            "a: 15,\n"
            "b: [16, 17] c: \"18\",\n"
            "}"),
        vili::exceptions::parsing_error);
    }
}<|endoftext|>


<commit_before>#include "CppUTest/TestHarness.h"

#include <string>

#include "vrp.h"

TEST_GROUP(ReadVrpFile)
{
    Vrp *vrp;

    void setup(void)
    {
        vrp = new Vrp("Vrp-All/E/E-n13-k4.vrp");
    }

    void teardown(void)
    {
        delete vrp;
    }
};

TEST(ReadVrpFile, name)
{
    std::string name = vrp->name();

    CHECK_EQUAL("E-n13-k4", name);
}

TEST(ReadVrpFile, demension)
{
    LONGS_EQUAL(13, vrp->demension());
}

TEST(ReadVrpFile, edge_weight_type)
{
    CHECK_EQUAL("EXPLICIT", vrp->edge_weight_type());
}
<commit_msg>不要な中間変数を削除<commit_after>#include "CppUTest/TestHarness.h"

#include <string>

#include "vrp.h"

TEST_GROUP(ReadVrpFile)
{
    Vrp *vrp;

    void setup(void)
    {
        vrp = new Vrp("Vrp-All/E/E-n13-k4.vrp");
    }

    void teardown(void)
    {
        delete vrp;
    }
};

TEST(ReadVrpFile, name)
{
    CHECK_EQUAL("E-n13-k4", vrp->name());
}

TEST(ReadVrpFile, demension)
{
    LONGS_EQUAL(13, vrp->demension());
}

TEST(ReadVrpFile, edge_weight_type)
{
    CHECK_EQUAL("EXPLICIT", vrp->edge_weight_type());
}
<|endoftext|>


<commit_before>//
//  main2.cpp
//  test_SCUD
//
//  Created by Boris Vigman on 08/07/2017.
//  Copyright © 2017-2019 Boris Vigman. All rights reserved.
//

#include "scud.h"

using namespace SCUD;

#include <iostream>
#include <thread>
#include <chrono>
#include "vector"

template<typename TSchedulable,typename Tid> class Queue1:public LinkableQueue<int,void*>{

};
template<typename TSchedulable,typename Tid> class Dropper1:public LinkableDropper<int,void*>{
public:

    void processOnPush(TSchedulable sch, long long schedulingParam){
        int x=0;
    }
    void processOnPull(TSchedulable sch, long long schedulingParam){
        int x=0;
    }
    void processOnPullPush(TSchedulable sch, long long schedulingParam){
        int x=0;
    }
};
class Source{
    char priority;
    float weight;
    int label;
    long long delay;
    Queue1<int,void*> queue0;
    LinkableQueue<int,void*> queue1;
    Dropper1<int,void*> drop0;
    LinkableDropper<int,void*> drop1;
    LinkablePass<int, void*> pass1,pass2;
    //LinkablePass<int,void*> pass;
    void run(){
        SCUD_RC r0;
        drop1.unlink(&r0);
        drop0.setPriority(7);
        drop1.setPriority(priority);
        SCUD_RC rc= queue0.setPriority(priority);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        //rc=queue0.setWeight(weight);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        rc=queue0.setLowThreshold(1);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        rc=queue0.setHighThreshold(100);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        rc=queue0.setDRRQuantum(200);
        rc=queue1.setDRRQuantum(1);
        //rc=queue1.setWeight(5);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        rc=queue1.setLowThreshold(1);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        rc=queue1.setHighThreshold(1030);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        rc= queue1.setPriority(priority);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        int count=10;

        //while(count>0){
        SCUD_RC status=SCUD_RC_OK;
        //queue.unlink(&status);
        //std::cout<<"loop: source"<<std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(delay));
        queue1.linkSuccessor(&drop1);
        queue0.linkSuccessor(&drop0);

        drop0.linkSuccessor(&queue0);
        //status=next->linkPredecessor(&drop1);

        //}
        while(1){
            std::this_thread::sleep_for(std::chrono::milliseconds(delay));

            //buildCompound();
            auto start= std::chrono::high_resolution_clock::now() ;
            //drop0.push(label, label*10);
            queue0.push(label, 100);
            queue0.push(label, 100);
            queue0.push(label, 100);
            queue0.push(label, 100);
            auto end= std::chrono::high_resolution_clock::now() ;
            auto diff = end - start;
            //std::cout<<"Push delay="<<std::chrono::duration <double, std::micro>(diff).count()<<std::endl;
            //std::cout<<"Queue1 ["<<label<<"] has "<<queue1.size()<<" objects"<<std::endl;
            start= std::chrono::high_resolution_clock::now() ;
            pass1.pullAndPush();
            end= std::chrono::high_resolution_clock::now() ;
            diff = end - start;
            //std::cout<<"Pull/Push delay="<<std::chrono::duration <double, std::micro>(diff).count()<<std::endl;
            //std::cout<<"Queue0 ["<<label<<"] has "<<queue0.size()<<" objects;"<<"Queue1 ["<<label<<"] has "<<queue1.size()<<" objects"<<std::endl;
            //breakCompound();
            /*
             count--;
             if(count<0){
             count=100;
             std::this_thread::sleep_for(std::chrono::milliseconds(delay*100));
             }
             */
        }
    }
public:
    Source(){weight=-1;priority=-1;label=-1;delay=100;}
    Source(int lbl, char p,float w,long long delayMilli){
        priority=p;
        weight=w;
        label=lbl;
        delay=delayMilli;
    }
    std::thread start() {
        return std::thread([=] { run(); });
    }
    void buildCompound(){
        //drop0.linkSuccessor(&queue0);
        //queue0.linkSuccessor(&pass1);
        //pass1.linkSuccessor(&queue1);
        //queue1.linkSuccessor(&pass2);
        //pass2.linkSuccessor(&drop1);

    }
    void breakCompound(){
        SCUD_RC status=SCUD_RC_OK;
        Linkable<int,void*>::LinkedObjectsTuple lot1=drop1.unlink(&status);
        if(status!=SCUD_RC_OK){
            std::cout<<SCHelper::convertReturnCodeToString(status)<<std::endl;
        }
        Linkable<int,void*>::LinkedObjectsTuple lot2=queue0.unlink(&status);
        if(status!=SCUD_RC_OK){
            std::cout<<SCHelper::convertReturnCodeToString(status)<<std::endl;
        }
        Linkable<int,void*>::LinkedObjectsTuple lot3=queue1.unlink(&status);
        if(status!=SCUD_RC_OK){
            std::cout<<SCHelper::convertReturnCodeToString(status)<<std::endl;
        }
    }
    Linkable<int,void*>* compoundBegin(){
        //return &drop0;
        return &queue0;
    }
    Linkable<int,void*>* compoundEnd(){
        //return &drop1;
        //return &pass2;
        return &queue0;
    }
};

class Sink{
    LinkableSchedulerPriority<int, void*> scheduler;
    //LinkableSchedulerNaiveRR<int, void*> scheduler;
    //LinkableSchedulerDRR<int, void*> scheduler;
    //LinkableSchedulerWFQ<int, void*> scheduler;
    LinkableNull<int, void*> null;
    void run(){
        scheduler.setPriority(9);
        //scheduler.setWeight(1);

        //        while(1){
        //            //std::cout<<"loop: sink"<<std::endl;
        //            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        //            SCUD_RC rc=SCUD_RC_OK;
        //            struct Linkable<int,void*>::Queueable res;
        ////            rc=next->pull(res);
        ////            if(rc==SCUD_RC_OK){
        ////                std::cout<<"Sink: Pulled object "<<res.scheduled<<" "<<std::endl;
        ////            }else{
        ////                std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        ////            }
        ////            if(res.scheduled>100000){
        ////                int x=0;
        ////            }
        //        }
    }
public:
    Sink(Linkable<int, void*>* l){

    }
    std::thread start() {
        return std::thread([=] { run(); });
    }

    void buildCompound(){
        scheduler.linkSuccessor(&null);
    };
    void breakCompound(){
        SCUD_RC status=SCUD_RC_OK;
        null.unlink(&status);
    };
    Linkable<int,void*>* compoundBegin(){
        return &scheduler;
    }
    Linkable<int,void*>* compoundEnd(){
        return &null;
    }

};
class Mixer{
    std::vector<Source*> v;
    Sink* sink;
    std::vector<int> output;
    void runlego(){
        while (1) {
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            sink->breakCompound();
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            sink->buildCompound();

            //std::cout<<"loop: mixer"<<std::endl;
            int s=v.size();
            //std::cout<<"loop: mixer 1"<<std::endl;
            for(int i=0;i<s;i++){
                std::this_thread::sleep_for(std::chrono::milliseconds(1000));
                v[i]->breakCompound();
            }

            for(int i=0;i<s;i++){
                v[i]->buildCompound();
                std::this_thread::sleep_for(std::chrono::milliseconds(1000));
                sink->compoundBegin()->linkPredecessor(v[i]->compoundEnd());
            }
        }

    }
    void run()
    {
        SCUD_RC rc=SCUD_RC_OK;
        int s=v.size();
        sink->buildCompound();
        for(long i=s-1;i>-1;i--){
            v[i]->buildCompound();
            //std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            sink->compoundBegin()->linkPredecessor(v[i]->compoundEnd());
        }
        for(int i=0;i<s;i++){
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            v[i]->breakCompound();
        }

        for(int i=0;i<s;i++){
            v[i]->buildCompound();
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            sink->compoundBegin()->linkPredecessor(v[i]->compoundEnd());
        }
        while (1) {
            //std::cout<<"loop: mixer 0"<<std::endl;
            std::this_thread::sleep_for(std::chrono::milliseconds(500));
            std::cout<<"** ROUND **"<<std::endl;
            for(int j=0;j<100;++j)
            {

                pull();

            }
        }
    }

public:
    void addSource(Source* s){
        v.push_back(s);
    }
    void addSink(Sink* s){
        sink=s;
    }
    void addNull(){

    };
    void pull(){
        SCUD_RC rc=SCUD_RC_OK;
        struct Linkable<int,void*>::Queueable res;
        res.scheduled=-1;
        auto start= std::chrono::high_resolution_clock::now() ;
        rc=sink->compoundEnd()->pull(res);
        auto end= std::chrono::high_resolution_clock::now() ;
        auto diff = end - start;
        //std::cout<<"Pull delay="<<std::chrono::duration <double, std::micro>(diff).count()<<std::endl;
        output.push_back(res.scheduled);
        if(rc==SCUD_RC_OK){
            std::cout<<"---Mixer: Pulled object "<<res.scheduled<<" "<<std::endl;
        }else if(rc==SCUD_RC_FAIL_LINK_NO_PACKET_AVAILABLE){
            //std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        }
    }
    std::thread start() {
        return std::thread([=] { run(); });
    }
    std::thread startlego() {
        return std::thread([=] { runlego(); });
    }
};
int main()
{
    Source s1(1,10,1,250);
    Source s2(2,20,1,2000);
    Source s3(3,30,1,1000);
    Source s4(4,50,1,5000);

    Mixer m;
    m.addSource(&s1);
    m.addSource(&s2);
    m.addSource(&s3);
    m.addSource(&s4);

    std::cout<<"SW version is: "<<SCHelper::version()<<std::endl;
    LinkableNull<int, void*> null;
    Sink si0(0);

    m.addSink(&si0);

    std::thread t1=s1.start();
    std::thread t2=s2.start();
    std::thread t3=s3.start();
    std::thread t4=s4.start();
    std::thread ti0=si0.start();

    std::thread m0=m.start();
    //std::thread mlego=m.startlego();

    t1.join();
    t2.join();
    t3.join();
    t4.join();
    ti0.join();
    m0.join();
    //mlego.join();

    std::cout << "done!\n";
}

<commit_msg>Update main.cpp<commit_after>//
//  main2.cpp
//  test_SCUD
//
//  Created by Boris Vigman on 08/07/2017.
//  Copyright © 2017-2019 Boris Vigman. All rights reserved.
//

/*
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as
 published by the Free Software Foundation, either version 3 of the
 License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "scud.h"

using namespace SCUD;

#include <iostream>
#include <thread>
#include <chrono>
#include "vector"

template<typename TSchedulable,typename Tid> class Queue1:public LinkableQueue<int,void*>{

};
template<typename TSchedulable,typename Tid> class Dropper1:public LinkableDropper<int,void*>{
public:

    void processOnPush(TSchedulable sch, long long schedulingParam){
        int x=0;
    }
    void processOnPull(TSchedulable sch, long long schedulingParam){
        int x=0;
    }
    void processOnPullPush(TSchedulable sch, long long schedulingParam){
        int x=0;
    }
};
class Source{
    char priority;
    float weight;
    int label;
    long long delay;
    Queue1<int,void*> queue0;
    LinkableQueue<int,void*> queue1;
    Dropper1<int,void*> drop0;
    LinkableDropper<int,void*> drop1;
    LinkablePass<int, void*> pass1,pass2;
    //LinkablePass<int,void*> pass;
    void run(){
        SCUD_RC r0;
        drop1.unlink(&r0);
        drop0.setPriority(7);
        drop1.setPriority(priority);
        SCUD_RC rc= queue0.setPriority(priority);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        //rc=queue0.setWeight(weight);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        rc=queue0.setLowThreshold(1);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        rc=queue0.setHighThreshold(100);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        rc=queue0.setDRRQuantum(200);
        rc=queue1.setDRRQuantum(1);
        //rc=queue1.setWeight(5);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        rc=queue1.setLowThreshold(1);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        rc=queue1.setHighThreshold(1030);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        rc= queue1.setPriority(priority);std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        int count=10;

        //while(count>0){
        SCUD_RC status=SCUD_RC_OK;
        //queue.unlink(&status);
        //std::cout<<"loop: source"<<std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(delay));
        queue1.linkSuccessor(&drop1);
        queue0.linkSuccessor(&drop0);

        drop0.linkSuccessor(&queue0);
        //status=next->linkPredecessor(&drop1);

        //}
        while(1){
            std::this_thread::sleep_for(std::chrono::milliseconds(delay));

            //buildCompound();
            auto start= std::chrono::high_resolution_clock::now() ;
            //drop0.push(label, label*10);
            queue0.push(label, 100);
            queue0.push(label, 100);
            queue0.push(label, 100);
            queue0.push(label, 100);
            auto end= std::chrono::high_resolution_clock::now() ;
            auto diff = end - start;
            //std::cout<<"Push delay="<<std::chrono::duration <double, std::micro>(diff).count()<<std::endl;
            //std::cout<<"Queue1 ["<<label<<"] has "<<queue1.size()<<" objects"<<std::endl;
            start= std::chrono::high_resolution_clock::now() ;
            pass1.pullAndPush();
            end= std::chrono::high_resolution_clock::now() ;
            diff = end - start;
            //std::cout<<"Pull/Push delay="<<std::chrono::duration <double, std::micro>(diff).count()<<std::endl;
            //std::cout<<"Queue0 ["<<label<<"] has "<<queue0.size()<<" objects;"<<"Queue1 ["<<label<<"] has "<<queue1.size()<<" objects"<<std::endl;
            //breakCompound();
            /*
             count--;
             if(count<0){
             count=100;
             std::this_thread::sleep_for(std::chrono::milliseconds(delay*100));
             }
             */
        }
    }
public:
    Source(){weight=-1;priority=-1;label=-1;delay=100;}
    Source(int lbl, char p,float w,long long delayMilli){
        priority=p;
        weight=w;
        label=lbl;
        delay=delayMilli;
    }
    std::thread start() {
        return std::thread([=] { run(); });
    }
    void buildCompound(){
        //drop0.linkSuccessor(&queue0);
        //queue0.linkSuccessor(&pass1);
        //pass1.linkSuccessor(&queue1);
        //queue1.linkSuccessor(&pass2);
        //pass2.linkSuccessor(&drop1);

    }
    void breakCompound(){
        SCUD_RC status=SCUD_RC_OK;
        Linkable<int,void*>::LinkedObjectsTuple lot1=drop1.unlink(&status);
        if(status!=SCUD_RC_OK){
            std::cout<<SCHelper::convertReturnCodeToString(status)<<std::endl;
        }
        Linkable<int,void*>::LinkedObjectsTuple lot2=queue0.unlink(&status);
        if(status!=SCUD_RC_OK){
            std::cout<<SCHelper::convertReturnCodeToString(status)<<std::endl;
        }
        Linkable<int,void*>::LinkedObjectsTuple lot3=queue1.unlink(&status);
        if(status!=SCUD_RC_OK){
            std::cout<<SCHelper::convertReturnCodeToString(status)<<std::endl;
        }
    }
    Linkable<int,void*>* compoundBegin(){
        //return &drop0;
        return &queue0;
    }
    Linkable<int,void*>* compoundEnd(){
        //return &drop1;
        //return &pass2;
        return &queue0;
    }
};

class Sink{
    LinkableSchedulerPriority<int, void*> scheduler;
    //LinkableSchedulerNaiveRR<int, void*> scheduler;
    //LinkableSchedulerDRR<int, void*> scheduler;
    //LinkableSchedulerWFQ<int, void*> scheduler;
    LinkableNull<int, void*> null;
    void run(){
        scheduler.setPriority(9);
        //scheduler.setWeight(1);

        //        while(1){
        //            //std::cout<<"loop: sink"<<std::endl;
        //            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        //            SCUD_RC rc=SCUD_RC_OK;
        //            struct Linkable<int,void*>::Queueable res;
        ////            rc=next->pull(res);
        ////            if(rc==SCUD_RC_OK){
        ////                std::cout<<"Sink: Pulled object "<<res.scheduled<<" "<<std::endl;
        ////            }else{
        ////                std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        ////            }
        ////            if(res.scheduled>100000){
        ////                int x=0;
        ////            }
        //        }
    }
public:
    Sink(Linkable<int, void*>* l){

    }
    std::thread start() {
        return std::thread([=] { run(); });
    }

    void buildCompound(){
        scheduler.linkSuccessor(&null);
    };
    void breakCompound(){
        SCUD_RC status=SCUD_RC_OK;
        null.unlink(&status);
    };
    Linkable<int,void*>* compoundBegin(){
        return &scheduler;
    }
    Linkable<int,void*>* compoundEnd(){
        return &null;
    }

};
class Mixer{
    std::vector<Source*> v;
    Sink* sink;
    std::vector<int> output;
    void runlego(){
        while (1) {
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            sink->breakCompound();
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            sink->buildCompound();

            //std::cout<<"loop: mixer"<<std::endl;
            int s=v.size();
            //std::cout<<"loop: mixer 1"<<std::endl;
            for(int i=0;i<s;i++){
                std::this_thread::sleep_for(std::chrono::milliseconds(1000));
                v[i]->breakCompound();
            }

            for(int i=0;i<s;i++){
                v[i]->buildCompound();
                std::this_thread::sleep_for(std::chrono::milliseconds(1000));
                sink->compoundBegin()->linkPredecessor(v[i]->compoundEnd());
            }
        }

    }
    void run()
    {
        SCUD_RC rc=SCUD_RC_OK;
        int s=v.size();
        sink->buildCompound();
        for(long i=s-1;i>-1;i--){
            v[i]->buildCompound();
            //std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            sink->compoundBegin()->linkPredecessor(v[i]->compoundEnd());
        }
        for(int i=0;i<s;i++){
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            v[i]->breakCompound();
        }

        for(int i=0;i<s;i++){
            v[i]->buildCompound();
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            sink->compoundBegin()->linkPredecessor(v[i]->compoundEnd());
        }
        while (1) {
            //std::cout<<"loop: mixer 0"<<std::endl;
            std::this_thread::sleep_for(std::chrono::milliseconds(500));
            std::cout<<"** ROUND **"<<std::endl;
            for(int j=0;j<100;++j)
            {

                pull();

            }
        }
    }

public:
    void addSource(Source* s){
        v.push_back(s);
    }
    void addSink(Sink* s){
        sink=s;
    }
    void addNull(){

    };
    void pull(){
        SCUD_RC rc=SCUD_RC_OK;
        struct Linkable<int,void*>::Queueable res;
        res.scheduled=-1;
        auto start= std::chrono::high_resolution_clock::now() ;
        rc=sink->compoundEnd()->pull(res);
        auto end= std::chrono::high_resolution_clock::now() ;
        auto diff = end - start;
        //std::cout<<"Pull delay="<<std::chrono::duration <double, std::micro>(diff).count()<<std::endl;
        output.push_back(res.scheduled);
        if(rc==SCUD_RC_OK){
            std::cout<<"---Mixer: Pulled object "<<res.scheduled<<" "<<std::endl;
        }else if(rc==SCUD_RC_FAIL_LINK_NO_PACKET_AVAILABLE){
            //std::cout<<SCHelper::convertReturnCodeToString(rc)<<std::endl;
        }
    }
    std::thread start() {
        return std::thread([=] { run(); });
    }
    std::thread startlego() {
        return std::thread([=] { runlego(); });
    }
};
int main()
{
    Source s1(1,10,1,250);
    Source s2(2,20,1,2000);
    Source s3(3,30,1,1000);
    Source s4(4,50,1,5000);

    Mixer m;
    m.addSource(&s1);
    m.addSource(&s2);
    m.addSource(&s3);
    m.addSource(&s4);

    std::cout<<"SW version is: "<<SCHelper::version()<<std::endl;
    LinkableNull<int, void*> null;
    Sink si0(0);

    m.addSink(&si0);

    std::thread t1=s1.start();
    std::thread t2=s2.start();
    std::thread t3=s3.start();
    std::thread t4=s4.start();
    std::thread ti0=si0.start();

    std::thread m0=m.start();
    //std::thread mlego=m.startlego();

    t1.join();
    t2.join();
    t3.join();
    t4.join();
    ti0.join();
    m0.join();
    //mlego.join();

    std::cout << "done!\n";
}

<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS res32bit (1.3.10); FILE MERGED 2004/10/27 17:50:54 pl 1.3.10.3: minor updates 2004/10/22 15:10:23 pl 1.3.10.2: removed a warning 2004/10/22 13:54:35 pl 1.3.10.1: #i34513# free rsc of 32 bit constraints<commit_after><|endoftext|>


<commit_before>//=================================================================================================
// Copyright (c) 2011, Johannes Meyer, TU Darmstadt
// All rights reserved.

// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the Flight Systems and Automatic Control group,
//       TU Darmstadt, nor the names of its contributors may be used to
//       endorse or promote products derived from this software without
//       specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
//=================================================================================================

#include <hector_quadrotor_pose_estimation/pose_estimation_node.h>
#include <hector_pose_estimation/measurements/baro.h>

namespace hector_quadrotor_pose_estimation {

QuadrotorPoseEstimationNode::QuadrotorPoseEstimationNode(const SystemPtr& system, const StatePtr& state)
  : PoseEstimationNode(system, state)
{
  pose_estimation_->addMeasurement(new Baro("baro"));
}

QuadrotorPoseEstimationNode::~QuadrotorPoseEstimationNode()
{
}

bool QuadrotorPoseEstimationNode::init() {
  if (!PoseEstimationNode::init()) return false;
  baro_subscriber_ = getNodeHandle().subscribe("altimeter", 10, &QuadrotorPoseEstimationNode::baroCallback, this);
  height_subscriber_.shutdown();
  return true;
}

void QuadrotorPoseEstimationNode::baroCallback(const hector_uav_msgs::AltimeterConstPtr& altimeter) {
  pose_estimation_->getMeasurement("baro")->add(Baro::Update(altimeter->pressure, altimeter->qnh));
}

} // namespace hector_quadrotor_pose_estimation
<commit_msg>hector_pose_estimation_core: update raw baro height as position.z component in sensor pose<commit_after>//=================================================================================================
// Copyright (c) 2011, Johannes Meyer, TU Darmstadt
// All rights reserved.

// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the Flight Systems and Automatic Control group,
//       TU Darmstadt, nor the names of its contributors may be used to
//       endorse or promote products derived from this software without
//       specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
//=================================================================================================

#include <hector_quadrotor_pose_estimation/pose_estimation_node.h>
#include <hector_pose_estimation/measurements/baro.h>

namespace hector_quadrotor_pose_estimation {

QuadrotorPoseEstimationNode::QuadrotorPoseEstimationNode(const SystemPtr& system, const StatePtr& state)
  : PoseEstimationNode(system, state)
{
  pose_estimation_->addMeasurement(new Baro("baro"));
}

QuadrotorPoseEstimationNode::~QuadrotorPoseEstimationNode()
{
}

bool QuadrotorPoseEstimationNode::init() {
  if (!PoseEstimationNode::init()) return false;
  baro_subscriber_ = getNodeHandle().subscribe("altimeter", 10, &QuadrotorPoseEstimationNode::baroCallback, this);
  height_subscriber_.shutdown();
  return true;
}

void QuadrotorPoseEstimationNode::baroCallback(const hector_uav_msgs::AltimeterConstPtr& altimeter) {
  pose_estimation_->getMeasurement("baro")->add(Baro::Update(altimeter->pressure, altimeter->qnh));

  if (sensor_pose_publisher_) {
    boost::shared_ptr<Baro> baro = boost::static_pointer_cast<Baro>(pose_estimation_->getMeasurement("baro"));
    sensor_pose_.pose.position.z = baro->getModel()->getAltitude(Baro::Update(altimeter->pressure, altimeter->qnh)) - baro->getElevation();
  }
}

} // namespace hector_quadrotor_pose_estimation
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2014 Max-Planck-Institute for Intelligent Systems,
 *                     University of Southern California
 *    Jan Issac (jan.issac@gmail.com)
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

/**
 * @date 05/25/2014
 * @author Jan Issac (jan.issac@gmail.com)
 * @author Manuel Wuthrich (manuel.wuthrich@gmail.com)
 * Max-Planck-Institute for Intelligent Systems, University of Southern California (USC)
 */

#ifndef STATE_FILTERING_DISTRIBUTION_FEATURES_SAMPLEBALE_HPP
#define STATE_FILTERING_DISTRIBUTION_FEATURES_SAMPLEBALE_HPP

#include <state_filtering/distributions/distribution.hpp>

namespace distributions
{

template <typename ScalarType_, typename VectorType_>
class Sampleable: public Distribution<ScalarType_, VectorType_>
{
public:
    typedef Distribution<ScalarType_, VectorType_>  BaseType;
    typedef typename BaseType::ScalarType           ScalarType;
    typedef typename BaseType::VectorType           VectorType;

public:
    virtual ~Sampleable() { }

    virtual VectorType Sample() = 0;
};

}

#endif
<commit_msg>- Uses ::sf namespace & removed distribution namespace. - Unified template parameters <ScalarType, VectorType, OperatorType> to <Vector, Operator>. - Omitted suffix "Type" since it does not provide any further meaning.<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2014 Max-Planck-Institute for Intelligent Systems,
 *                     University of Southern California
 *    Jan Issac (jan.issac@gmail.com)
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

/**
 * @date 05/25/2014
 * @author Jan Issac (jan.issac@gmail.com)
 * @author Manuel Wuthrich (manuel.wuthrich@gmail.com)
 * Max-Planck-Institute for Intelligent Systems,
 *  University of Southern California (USC)
 */

#ifndef STATE_FILTERING_DISTRIBUTION_FEATURES_SAMPLEBALE_HPP
#define STATE_FILTERING_DISTRIBUTION_FEATURES_SAMPLEBALE_HPP

namespace sf
{

template <typename Vector>
class Sampleable
{
public:
    virtual Vector Sample() = 0;
};

}

#endif
<|endoftext|>


<commit_before>/*
 * File:   Audio.h
 * Author: morgan
 *
 * Created on May 7, 2014, 9:41 PM
 */

#ifndef MO_AUDIO_H
#define	MO_AUDIO_H

#include <AL/al.h>
#include <AL/alc.h>
#include <unordered_map>
#include <memory>
#include <thread>

#include "streamsource.hpp"
#include "soundsource.hpp"

namespace mo {

    /*!
     * Audio player class. Uses OpenAL for Windows/Linux/OSX.
     */
    class Audio {
    public:
        Audio();
        virtual ~Audio();

        /**
         * Play audio from a SoundSource object. A sound source contains one sound.
         *
         * @param source
         */
        void init(const SoundSource & source);

        /**
         * Plays audio from a StreamSource. Which streams content from a file. This
         * method starts a new thread for each source playing.
         *
         * @brief play
         * @param stream_source
         */
        void init(const StreamSource & stream_source);

        /**
         * Updates the internal source representation with data. Data
         * such as position, velocity, pitch and gain.
         *
         * @brief update
         * @param stream_source
         */
        void update(SoundSource & source);

		/**
		* Updates the internal source representation with data. Data
		* such as position, velocity, pitch and gain.
		*
		* @brief update
		* @param stream_source
		*/
        void update(StreamSource & source);

		/**
		* Updates the internal source representation with data. Data
		* such as position, velocity, pitch and gain.
		*
		* @brief update
		* @param stream_source
		*/
        glm::vec3 listener_position();

		/**
		* Set the listener position.
		*
		* @brief listener_position
		* @param position
		*/
        void listener_position(const glm::vec3 position);

		/**
		* Get the listener position
		*
		* @brief listener_position
		*/
        glm::vec3 listener_orientation();

		/**
		* Set the listener orientation.
		*
		* @brief listener_orientation
		* @param orientation, up
		*/
        void listener_orientation(const glm::vec3 orientation, const glm::vec3 up = glm::vec3(0.0f, 0.0f, 1.0f));

		/**
		* Get the listener velocity.
		*
		* @brief listener_velocity
		*/
		glm::vec3 listener_velocity();

		/**
		* Set the listener velocity.
		*
		* @brief listener_velocity
		* @param velocity
		*/
        void listener_velocity(const glm::vec3 velocity);
    private:
		struct StreamThread {
			std::shared_ptr<std::thread> thread;
			bool running;
		};

        ALCdevice * device_;
        ALCcontext * context_;

        using SourcePair = std::pair<unsigned int, ALuint>;
        using BufferPair = std::pair<unsigned int, ALuint>;
        using Sources = std::unordered_map<unsigned int, ALuint>;
        using Buffers = std::unordered_map<unsigned int, ALuint>;

        Sources sources_;
        Buffers buffers_;

        std::unordered_map<unsigned int, StreamThread> stream_threads;
    };
}

#endif	/* MO_AUDIO_H */

<commit_msg>Batch update init.<commit_after>/*
 * File:   Audio.h
 * Author: morgan
 *
 * Created on May 7, 2014, 9:41 PM
 */

#ifndef MO_AUDIO_H
#define	MO_AUDIO_H

#include <AL/al.h>
#include <AL/alc.h>
#include <unordered_map>
#include <memory>
#include <thread>

#include "streamsource.hpp"
#include "soundsource.hpp"

namespace mo {

    /*!
     * Audio player class. Uses OpenAL for Windows/Linux/OSX.
     */
    class Audio {
    public:
        Audio();
        virtual ~Audio();

        template<class It>
        /*!
         * A generalized init method
         *
         * @brief init
         * @param begin
         * @param end
         */
        void init(It begin, It end) {
            for (auto it = begin; it != end; it++){
                init(*it);
            }
        }

        /**
         * Play audio from a SoundSource object. A sound source contains one sound.
         *
         * @param source
         */
        void init(const SoundSource & source);

        /**
         * Plays audio from a StreamSource. Which streams content from a file. This
         * method starts a new thread for each source playing.
         *
         * @brief play
         * @param stream_source
         */
        void init(const StreamSource & stream_source);

        template<class It>
        /*!
         * A generalized update method
         *
         * @brief init
         * @param begin iterator
         * @param end iterator
         */
        void update(It begin, It end) {
            for (auto it = begin; it != end; it++){
                update(*it);
            }
        }

        /**
         * Updates the internal source representation with data. Data
         * such as position, velocity, pitch and gain.
         *
         * @brief update
         * @param stream_source
         */
        void update(SoundSource & source);

		/**
		* Updates the internal source representation with data. Data
		* such as position, velocity, pitch and gain.
		*
		* @brief update
		* @param stream_source
		*/
        void update(StreamSource & source);

		/**
		* Updates the internal source representation with data. Data
		* such as position, velocity, pitch and gain.
		*
		* @brief update
		* @param stream_source
		*/
        glm::vec3 listener_position();

		/**
		* Set the listener position.
		*
		* @brief listener_position
		* @param position
		*/
        void listener_position(const glm::vec3 position);

		/**
		* Get the listener position
		*
		* @brief listener_position
		*/
        glm::vec3 listener_orientation();

		/**
		* Set the listener orientation.
		*
		* @brief listener_orientation
		* @param orientation, up
		*/
        void listener_orientation(const glm::vec3 orientation, const glm::vec3 up = glm::vec3(0.0f, 0.0f, 1.0f));

		/**
		* Get the listener velocity.
		*
		* @brief listener_velocity
		*/
		glm::vec3 listener_velocity();

		/**
		* Set the listener velocity.
		*
		* @brief listener_velocity
		* @param velocity
		*/
        void listener_velocity(const glm::vec3 velocity);
    private:
		struct StreamThread {
			std::shared_ptr<std::thread> thread;
			bool running;
		};

        ALCdevice * device_;
        ALCcontext * context_;

        using SourcePair = std::pair<unsigned int, ALuint>;
        using BufferPair = std::pair<unsigned int, ALuint>;
        using Sources = std::unordered_map<unsigned int, ALuint>;
        using Buffers = std::unordered_map<unsigned int, ALuint>;

        Sources sources_;
        Buffers buffers_;

        std::unordered_map<unsigned int, StreamThread> stream_threads;
    };
}

#endif	/* MO_AUDIO_H */

<|endoftext|>