<commit_before>/// Causal Dynamical Triangulations in C++ using CGAL
///
/// Copyright (c) 2016 Adam Getchell
///
/// Checks that the MoveManager RAII class handles resources properly.

/// @file MoveManagerTest.cpp
/// @brief Tests for the MoveManager RAII class
/// @author Adam Getchell

#include <tuple>
#include <vector>
#include <utility>
#include <algorithm>

#include "gmock/gmock.h"
#include "MoveManager.h"
#include "S3ErgodicMoves.h"

using namespace testing;  // NOLINT

class MoveManagerTest : public Test {
 public:
  MoveManagerTest() : universe_(std::move(make_triangulation(6400, 17))),
                      movable_simplex_types_(classify_simplices(universe_)),
                      movable_edge_types_(classify_edges(universe_)),
                      attempted_moves_(std::make_tuple(0, 0, 0, 0, 0)),
                      number_of_vertices_(universe_->number_of_vertices()) {}

  virtual void SetUp() {
    // Print ctor-initialized values
    std::cout << "(3,1) simplices: "
              << std::get<0>(movable_simplex_types_).size() << std::endl;
    std::cout << "(2,2) simplices: "
              << std::get<1>(movable_simplex_types_).size() << std::endl;
    std::cout << "(1,3) simplices: "
              << std::get<2>(movable_simplex_types_).size() << std::endl;
    std::cout << "Timelike edges: "
              << movable_edge_types_.first.size() << std::endl;
    std::cout << "Spacelike edges: "
              << movable_edge_types_.second << std::endl;
    std::cout << "Vertices: "
              << number_of_vertices_ << std::endl;
  }

  std::unique_ptr<Delaunay> universe_;
  ///< Unique pointer to the Delaunay triangulation
  std::tuple<std::vector<Cell_handle>,
             std::vector<Cell_handle>,
             std::vector<Cell_handle>> movable_simplex_types_;
  ///< Movable (3,1), (2,2) and (1,3) simplices.
  std::pair<std::vector<Edge_tuple>, uintmax_t> movable_edge_types_;
  ///< Movable timelike and spacelike edges.
  Move_tuple attempted_moves_;
  ///< A count of all attempted moves
  std::uintmax_t number_of_vertices_;
  ///< Vertices in Delaunay triangulation
};

TEST_F(MoveManagerTest, DelaunayDeepCopyCtor) {
  // Print info on move/copy operation exception safety
  std::cout << std::boolalpha
    << "Delaunay alias is copy-assignable? "
    << std::is_copy_assignable<Delaunay>::value << '\n'
    << "Delaunay alias is nothrow copy-assignable? "
    << std::is_nothrow_copy_assignable<Delaunay>::value << '\n'
    << "Delaunay alias is nothrow move-assignable? "
    << std::is_nothrow_move_assignable<Delaunay>::value << '\n'
    << "unique_ptr<Delaunay> is nothrow move-assignable? "
    << std::is_nothrow_move_assignable<std::unique_ptr<Delaunay>>::value
    << std::endl;

  EXPECT_TRUE(this->universe_->tds().is_valid())
    << "Constructed universe is invalid.";

  // Make a copy using Delaunay copy-ctor
  auto tempDT = Delaunay(*this->universe_);
  auto tempDT_ptr = std::make_unique<Delaunay>(tempDT);

  EXPECT_TRUE(tempDT_ptr->tds().is_valid())
    << "Delaunay copy is invalid.";

  EXPECT_THAT(number_of_vertices_, Eq(tempDT_ptr->number_of_vertices()))
    << "Delaunay copy doesn't have the same number of vertices.";

  EXPECT_THAT(this->universe_->number_of_finite_edges(),
    Eq(tempDT_ptr->number_of_finite_edges()))
    << "Delaunay copy doesn't have the same number of edges.";

  EXPECT_THAT(this->universe_->number_of_finite_facets(),
    Eq(tempDT_ptr->number_of_finite_facets()))
    << "Delaunay copy doesn't have the same number of facets.";

  EXPECT_THAT(this->universe_->number_of_finite_cells(),
    Eq(tempDT_ptr->number_of_finite_cells()))
    << "Delaunay copy doesn't have the same number of cells.";

  // Calculate copied simplex types
  auto tempDT_simplex_types = classify_simplices(tempDT_ptr);

  EXPECT_THAT(std::get<0>(this->movable_simplex_types_).size(),
    Eq(std::get<0>(tempDT_simplex_types).size()))
    << "Delaunay copy doesn't have the same number of (3,1) simplices.";

  EXPECT_THAT(std::get<1>(this->movable_simplex_types_).size(),
    Eq(std::get<1>(tempDT_simplex_types).size()))
    << "Delaunay copy doesn't have the same number of (2,2) simplices.";

  EXPECT_THAT(std::get<2>(this->movable_simplex_types_).size(),
    Eq(std::get<2>(tempDT_simplex_types).size()))
    << "Delaunay copy doesn't have the same number of (1,3) simplices.";

  // Calculate copied edge types
  auto tempDT_edge_types = classify_edges(tempDT_ptr);

  EXPECT_THAT(this->movable_edge_types_.first.size(),
    Eq(tempDT_edge_types.first.size()))
    << "Delaunay copy doesn't have the same number of timelike edges.";

  EXPECT_THAT(this->movable_edge_types_.second, Eq(tempDT_edge_types.second))
    << "Delaunay copy doesn't have the same number of spacelike edges.";
}

TEST_F(MoveManagerTest, MakeA23MoveOnACopyAndSwap) {
  EXPECT_TRUE(this->universe_->tds().is_valid())
    << "Constructed universe_ is invalid.";

  // Make a copy using Delaunay copy-ctor
  auto tempDT = Delaunay(*this->universe_);
  auto tempDT_ptr = std::make_unique<Delaunay>(tempDT);

  EXPECT_TRUE(tempDT_ptr->tds().is_valid())
    << "Copied universe is invalid.";

  auto simplex_types = classify_simplices(tempDT_ptr);

  tempDT_ptr = std::move(make_23_move(tempDT_ptr,
                                      simplex_types,
                                      attempted_moves_));

  std::cout << "Attempted (2,3) moves = " << std::get<0>(attempted_moves_)
            << std::endl;

  EXPECT_TRUE(tempDT_ptr->tds().is_valid())
    << "Copied universe invalid after make_23_move().";

  std::swap(this->universe_, tempDT_ptr);

  EXPECT_TRUE(this->universe_->tds().is_valid())
    << "universe_ invalid after swap with copied universe.";

  // Re-populate with current data
  auto new_movable_simplex_types = classify_simplices(this->universe_);
  auto new_movable_edge_types = classify_edges(this->universe_);

  // Print new values
  std::cout << "New values: " << std::endl;
  std::cout << "(3,1) simplices: "
            << std::get<0>(new_movable_simplex_types).size() << std::endl;
  std::cout << "(2,2) simplices: "
            << std::get<1>(new_movable_simplex_types).size() << std::endl;
  std::cout << "(1,3) simplices: "
            << std::get<2>(new_movable_simplex_types).size() << std::endl;
  std::cout << "Timelike edges: "
            << new_movable_edge_types.first.size() << std::endl;
  std::cout << "Spacelike edges: "
            << new_movable_edge_types.second << std::endl;
  std::cout << "Vertices: "
            << this->universe_->number_of_vertices() << std::endl;

  EXPECT_THAT(std::get<0>(attempted_moves_), Ge(1))
    << "make_23_move() didn't record an attempted move.";

  EXPECT_THAT(std::get<1>(new_movable_simplex_types).size(),
    Eq(std::get<1>(movable_simplex_types_).size()+1))
    << "make_23_move() didn't add one and only one (2,2) simplex.";

  EXPECT_THAT(std::get<0>(new_movable_simplex_types).size(),
    Eq(std::get<0>(movable_simplex_types_).size()))
    << "make_23_move() changed (3,1) simplices.";

  EXPECT_THAT(std::get<2>(new_movable_simplex_types).size(),
    Eq(std::get<2>(movable_simplex_types_).size()))
    << "make_23_move() changed (1,3) simplices.";

  EXPECT_THAT(new_movable_edge_types.first.size(),
    Eq(movable_edge_types_.first.size()+1))
    << "make_23_move() didn't add one and only one timelike edge.";

  EXPECT_THAT(new_movable_edge_types.second, Eq(movable_edge_types_.second))
    << "make_23_move() changed the number of spacelike edges.";

  EXPECT_THAT(this->universe_->number_of_vertices(),
    Eq(number_of_vertices_))
    << "make_23_move() changed the number of vertices.";
}

TEST_F(MoveManagerTest, DISABLED_MakeA23MoveManager) {
  EXPECT_TRUE(this->universe_->tds().is_valid())
    << "Constructed universe_ is invalid.";

  PachnerMove p(universe_,
                move_type::TWO_THREE,
                movable_simplex_types_,
                movable_edge_types_);

  std::cout << "Attempted (2,3) moves = " << std::get<0>(p.attempted_moves_)
            << std::endl;

  // Move info from MoveManager
  universe_ = std::move(p.universe_);
  std::get<0>(attempted_moves_) += std::get<0>(p.attempted_moves_);

  EXPECT_TRUE(this->universe_->tds().is_valid())
    << "MoveManager(TWO_THREE) invalidated universe_.";

  // Re-populate with current data
  auto new_movable_simplex_types = classify_simplices(this->universe_);
  auto new_movable_edge_types = classify_edges(this->universe_);

  // Print new values
  std::cout << "New values: " << std::endl;
  std::cout << "(3,1) simplices: "
            << std::get<0>(new_movable_simplex_types).size() << std::endl;
  std::cout << "(2,2) simplices: "
            << std::get<1>(new_movable_simplex_types).size() << std::endl;
  std::cout << "(1,3) simplices: "
            << std::get<2>(new_movable_simplex_types).size() << std::endl;
  std::cout << "Timelike edges: "
            << new_movable_edge_types.first.size() << std::endl;
  std::cout << "Spacelike edges: "
            << new_movable_edge_types.second << std::endl;
  std::cout << "Vertices: "
            << this->universe_->number_of_vertices() << std::endl;

EXPECT_THAT(std::get<0>(attempted_moves_), Ge(1))
  << "MoveManager(TWO_THREE) didn't record an attempted move.";

EXPECT_THAT(std::get<1>(new_movable_simplex_types).size(),
  Eq(std::get<1>(movable_simplex_types_).size()+1))
  << "MoveManager(TWO_THREE) didn't add one and only one (2,2) simplex.";

EXPECT_THAT(std::get<0>(new_movable_simplex_types).size(),
  Eq(std::get<0>(movable_simplex_types_).size()))
  << "MoveManager(TWO_THREE) changed (3,1) simplices.";

EXPECT_THAT(std::get<2>(new_movable_simplex_types).size(),
  Eq(std::get<2>(movable_simplex_types_).size()))
  << "MoveManager(TWO_THREE) changed (1,3) simplices.";

EXPECT_THAT(new_movable_edge_types.first.size(),
  Eq(movable_edge_types_.first.size()+1))
  << "MoveManager(TWO_THREE) didn't add one and only one timelike edge.";

EXPECT_THAT(new_movable_edge_types.second, Eq(movable_edge_types_.second))
  << "MoveManager(TWO_THREE) changed the number of spacelike edges.";

EXPECT_THAT(this->universe_->number_of_vertices(),
  Eq(number_of_vertices_))
  << "MoveManager(TWO_THREE) changed the number of vertices.";
}
<commit_msg>Ensure correct initialization of MoveManagerTest class<commit_after>/// Causal Dynamical Triangulations in C++ using CGAL
///
/// Copyright (c) 2016 Adam Getchell
///
/// Checks that the MoveManager RAII class handles resources properly.

/// @file MoveManagerTest.cpp
/// @brief Tests for the MoveManager RAII class
/// @author Adam Getchell

#include <tuple>
#include <vector>
#include <utility>
#include <algorithm>

#include "gmock/gmock.h"
#include "MoveManager.h"
#include "S3ErgodicMoves.h"

using namespace testing;  // NOLINT

class MoveManagerTest : public Test {
 public:
  MoveManagerTest() : universe_(std::move(make_triangulation(6400, 17))),
                      movable_simplex_types_(classify_simplices(universe_)),
                      movable_edge_types_(classify_edges(universe_)),
                      attempted_moves_(std::make_tuple(0, 0, 0, 0, 0)),
                      number_of_vertices_(universe_->number_of_vertices()) {}

  virtual void SetUp() {
    // Print ctor-initialized values
    std::cout << "(3,1) simplices: "
              << std::get<0>(movable_simplex_types_).size() << std::endl;
    std::cout << "(2,2) simplices: "
              << std::get<1>(movable_simplex_types_).size() << std::endl;
    std::cout << "(1,3) simplices: "
              << std::get<2>(movable_simplex_types_).size() << std::endl;
    std::cout << "Timelike edges: "
              << movable_edge_types_.first.size() << std::endl;
    std::cout << "Spacelike edges: "
              << movable_edge_types_.second << std::endl;
    std::cout << "Vertices: "
              << number_of_vertices_ << std::endl;
  }

  Delaunay triangulation;
  ///< Delaunay triangulation
  std::unique_ptr<Delaunay>
    universe_ = std::make_unique<Delaunay>(triangulation);
  ///< Unique pointer to the Delaunay triangulation
  std::tuple<std::vector<Cell_handle>,
             std::vector<Cell_handle>,
             std::vector<Cell_handle>> movable_simplex_types_;
  ///< Movable (3,1), (2,2) and (1,3) simplices.
  std::pair<std::vector<Edge_tuple>, uintmax_t> movable_edge_types_;
  ///< Movable timelike and spacelike edges.
  Move_tuple attempted_moves_;
  ///< A count of all attempted moves
  std::uintmax_t number_of_vertices_;
  ///< Vertices in Delaunay triangulation
};

TEST_F(MoveManagerTest, DelaunayDeepCopyCtor) {
  // Print info on move/copy operation exception safety
  std::cout << std::boolalpha
    << "Delaunay alias is copy-assignable? "
    << std::is_copy_assignable<Delaunay>::value << '\n'
    << "Delaunay alias is nothrow copy-assignable? "
    << std::is_nothrow_copy_assignable<Delaunay>::value << '\n'
    << "Delaunay alias is nothrow move-assignable? "
    << std::is_nothrow_move_assignable<Delaunay>::value << '\n'
    << "unique_ptr<Delaunay> is nothrow move-assignable? "
    << std::is_nothrow_move_assignable<std::unique_ptr<Delaunay>>::value
    << std::endl;

  EXPECT_TRUE(this->universe_->tds().is_valid())
    << "Constructed universe is invalid.";

  // Make a copy using Delaunay copy-ctor
  auto tempDT = Delaunay(*this->universe_);
  auto tempDT_ptr = std::make_unique<Delaunay>(tempDT);

  EXPECT_TRUE(tempDT_ptr->tds().is_valid())
    << "Delaunay copy is invalid.";

  EXPECT_THAT(number_of_vertices_, Eq(tempDT_ptr->number_of_vertices()))
    << "Delaunay copy doesn't have the same number of vertices.";

  EXPECT_THAT(this->universe_->number_of_finite_edges(),
    Eq(tempDT_ptr->number_of_finite_edges()))
    << "Delaunay copy doesn't have the same number of edges.";

  EXPECT_THAT(this->universe_->number_of_finite_facets(),
    Eq(tempDT_ptr->number_of_finite_facets()))
    << "Delaunay copy doesn't have the same number of facets.";

  EXPECT_THAT(this->universe_->number_of_finite_cells(),
    Eq(tempDT_ptr->number_of_finite_cells()))
    << "Delaunay copy doesn't have the same number of cells.";

  // Calculate copied simplex types
  auto tempDT_simplex_types = classify_simplices(tempDT_ptr);

  EXPECT_THAT(std::get<0>(this->movable_simplex_types_).size(),
    Eq(std::get<0>(tempDT_simplex_types).size()))
    << "Delaunay copy doesn't have the same number of (3,1) simplices.";

  EXPECT_THAT(std::get<1>(this->movable_simplex_types_).size(),
    Eq(std::get<1>(tempDT_simplex_types).size()))
    << "Delaunay copy doesn't have the same number of (2,2) simplices.";

  EXPECT_THAT(std::get<2>(this->movable_simplex_types_).size(),
    Eq(std::get<2>(tempDT_simplex_types).size()))
    << "Delaunay copy doesn't have the same number of (1,3) simplices.";

  // Calculate copied edge types
  auto tempDT_edge_types = classify_edges(tempDT_ptr);

  EXPECT_THAT(this->movable_edge_types_.first.size(),
    Eq(tempDT_edge_types.first.size()))
    << "Delaunay copy doesn't have the same number of timelike edges.";

  EXPECT_THAT(this->movable_edge_types_.second, Eq(tempDT_edge_types.second))
    << "Delaunay copy doesn't have the same number of spacelike edges.";
}

TEST_F(MoveManagerTest, MakeA23MoveOnACopyAndSwap) {
  EXPECT_TRUE(this->universe_->tds().is_valid())
    << "Constructed universe_ is invalid.";

  // Make a copy using Delaunay copy-ctor
  auto tempDT = Delaunay(*this->universe_);
  auto tempDT_ptr = std::make_unique<Delaunay>(tempDT);

  EXPECT_TRUE(tempDT_ptr->tds().is_valid())
    << "Copied universe is invalid.";

  auto simplex_types = classify_simplices(tempDT_ptr);

  tempDT_ptr = std::move(make_23_move(tempDT_ptr,
                                      simplex_types,
                                      attempted_moves_));

  std::cout << "Attempted (2,3) moves = " << std::get<0>(attempted_moves_)
            << std::endl;

  EXPECT_TRUE(tempDT_ptr->tds().is_valid())
    << "Copied universe invalid after make_23_move().";

  std::swap(this->universe_, tempDT_ptr);

  EXPECT_TRUE(this->universe_->tds().is_valid())
    << "universe_ invalid after swap with copied universe.";

  // Re-populate with current data
  auto new_movable_simplex_types = classify_simplices(this->universe_);
  auto new_movable_edge_types = classify_edges(this->universe_);

  // Print new values
  std::cout << "New values: " << std::endl;
  std::cout << "(3,1) simplices: "
            << std::get<0>(new_movable_simplex_types).size() << std::endl;
  std::cout << "(2,2) simplices: "
            << std::get<1>(new_movable_simplex_types).size() << std::endl;
  std::cout << "(1,3) simplices: "
            << std::get<2>(new_movable_simplex_types).size() << std::endl;
  std::cout << "Timelike edges: "
            << new_movable_edge_types.first.size() << std::endl;
  std::cout << "Spacelike edges: "
            << new_movable_edge_types.second << std::endl;
  std::cout << "Vertices: "
            << this->universe_->number_of_vertices() << std::endl;

  EXPECT_THAT(std::get<0>(attempted_moves_), Ge(1))
    << "make_23_move() didn't record an attempted move.";

  EXPECT_THAT(std::get<1>(new_movable_simplex_types).size(),
    Eq(std::get<1>(movable_simplex_types_).size()+1))
    << "make_23_move() didn't add one and only one (2,2) simplex.";

  EXPECT_THAT(std::get<0>(new_movable_simplex_types).size(),
    Eq(std::get<0>(movable_simplex_types_).size()))
    << "make_23_move() changed (3,1) simplices.";

  EXPECT_THAT(std::get<2>(new_movable_simplex_types).size(),
    Eq(std::get<2>(movable_simplex_types_).size()))
    << "make_23_move() changed (1,3) simplices.";

  EXPECT_THAT(new_movable_edge_types.first.size(),
    Eq(movable_edge_types_.first.size()+1))
    << "make_23_move() didn't add one and only one timelike edge.";

  EXPECT_THAT(new_movable_edge_types.second, Eq(movable_edge_types_.second))
    << "make_23_move() changed the number of spacelike edges.";

  EXPECT_THAT(this->universe_->number_of_vertices(),
    Eq(number_of_vertices_))
    << "make_23_move() changed the number of vertices.";
}

TEST_F(MoveManagerTest, DISABLED_MakeA23MoveManager) {
  EXPECT_TRUE(this->universe_->tds().is_valid())
    << "Constructed universe_ is invalid.";

  PachnerMove p(universe_,
                move_type::TWO_THREE,
                movable_simplex_types_,
                movable_edge_types_);

  std::cout << "Attempted (2,3) moves = " << std::get<0>(p.attempted_moves_)
            << std::endl;

  // Move info from MoveManager
  universe_ = std::move(p.universe_);
  std::get<0>(attempted_moves_) += std::get<0>(p.attempted_moves_);

  EXPECT_TRUE(this->universe_->tds().is_valid())
    << "MoveManager(TWO_THREE) invalidated universe_.";

  // Re-populate with current data
  auto new_movable_simplex_types = classify_simplices(this->universe_);
  auto new_movable_edge_types = classify_edges(this->universe_);

  // Print new values
  std::cout << "New values: " << std::endl;
  std::cout << "(3,1) simplices: "
            << std::get<0>(new_movable_simplex_types).size() << std::endl;
  std::cout << "(2,2) simplices: "
            << std::get<1>(new_movable_simplex_types).size() << std::endl;
  std::cout << "(1,3) simplices: "
            << std::get<2>(new_movable_simplex_types).size() << std::endl;
  std::cout << "Timelike edges: "
            << new_movable_edge_types.first.size() << std::endl;
  std::cout << "Spacelike edges: "
            << new_movable_edge_types.second << std::endl;
  std::cout << "Vertices: "
            << this->universe_->number_of_vertices() << std::endl;

EXPECT_THAT(std::get<0>(attempted_moves_), Ge(1))
  << "MoveManager(TWO_THREE) didn't record an attempted move.";

EXPECT_THAT(std::get<1>(new_movable_simplex_types).size(),
  Eq(std::get<1>(movable_simplex_types_).size()+1))
  << "MoveManager(TWO_THREE) didn't add one and only one (2,2) simplex.";

EXPECT_THAT(std::get<0>(new_movable_simplex_types).size(),
  Eq(std::get<0>(movable_simplex_types_).size()))
  << "MoveManager(TWO_THREE) changed (3,1) simplices.";

EXPECT_THAT(std::get<2>(new_movable_simplex_types).size(),
  Eq(std::get<2>(movable_simplex_types_).size()))
  << "MoveManager(TWO_THREE) changed (1,3) simplices.";

EXPECT_THAT(new_movable_edge_types.first.size(),
  Eq(movable_edge_types_.first.size()+1))
  << "MoveManager(TWO_THREE) didn't add one and only one timelike edge.";

EXPECT_THAT(new_movable_edge_types.second, Eq(movable_edge_types_.second))
  << "MoveManager(TWO_THREE) changed the number of spacelike edges.";

EXPECT_THAT(this->universe_->number_of_vertices(),
  Eq(number_of_vertices_))
  << "MoveManager(TWO_THREE) changed the number of vertices.";
}
<|endoftext|>


<commit_before>/// Causal Dynamical Triangulations in C++ using CGAL
///
/// Copyright (c) 2016 Adam Getchell
///
/// Checks that the PachnerMove RAII class handles resources properly.

/// @file PachnerMoveTest.cpp
/// @brief Tests for the PachnerMove RAII class
/// @author Adam Getchell

#include "gmock/gmock.h"
#include "PachnerMove.h"
#include "S3Triangulation.h"

using namespace testing;  // NOLINT

TEST(PachnerMoveTest, DeepCopyCtor) {
  // This is a std::unique_ptr<Delaunay>
  auto universe = std::move(make_triangulation(6400, 17));
  auto tempDT = Delaunay(*universe);
  auto tempDT_ptr = std::make_unique<Delaunay>(tempDT);

  // Print info on move/copy operation exception safety
  std::cout << std::boolalpha
    << "Delaunay alias is copy-assignable? "
    << std::is_copy_assignable<Delaunay>::value << '\n'
    << "Delaunay alias is nothrow copy-assignable? "
    << std::is_nothrow_copy_assignable<Delaunay>::value << '\n'
    << "Delaunay alias is nothrow move-assignable? "
    << std::is_nothrow_move_assignable<Delaunay>::value << '\n'
    << "unique_ptr<Delaunay> is nothrow move-assignable? "
    << std::is_nothrow_move_assignable<std::unique_ptr<Delaunay>>::value
    << std::endl;

  EXPECT_THAT(universe->number_of_vertices(),
    Eq(tempDT_ptr->number_of_vertices()))
    << "Delaunay copy doesn't have the same number of vertices.";

  EXPECT_THAT(universe->number_of_finite_edges(),
    Eq(tempDT_ptr->number_of_finite_edges()))
    << "Delaunay copy doesn't have the same number of edges.";

  EXPECT_THAT(universe->number_of_finite_facets(),
    Eq(tempDT_ptr->number_of_finite_facets()))
    << "Delaunay copy doesn't have the same number of facets.";

  EXPECT_THAT(universe->number_of_finite_cells(),
    Eq(tempDT_ptr->number_of_finite_cells()))
    << "Delaunay copy doesn't have the same number of cells.";

  auto simplex_types = classify_simplices(universe);
  auto tempDT_simplex_types = classify_simplices(tempDT_ptr);

  EXPECT_THAT(std::get<0>(simplex_types).size(),
    Eq(std::get<0>(tempDT_simplex_types).size()))
    << "Delaunay copy doesn't have the same number of (3,1) simplices.";

  EXPECT_THAT(std::get<1>(simplex_types).size(),
    Eq(std::get<1>(tempDT_simplex_types).size()))
    << "Delaunay copy doesn't have the same number of (2,2) simplices.";

  EXPECT_THAT(std::get<2>(simplex_types).size(),
    Eq(std::get<2>(tempDT_simplex_types).size()))
    << "Delaunay copy doesn't have the same number of (1,3) simplices.";

  auto edge_types = classify_edges(universe);
  auto tempDT_edge_types = classify_edges(tempDT_ptr);

  EXPECT_THAT(edge_types.first.size(), Eq(tempDT_edge_types.first.size()))
    << "Delaunay copy doesn't have the same number of timelike edges.";

  EXPECT_THAT(edge_types.second, Eq(tempDT_edge_types.second))
    << "Delaunay copy doesn't have the same number of spacelike edges.";
}

TEST(PachnerMoveTest, MakeA23Move) {
  // Make a foliated triangulation
  auto universe = std::move(make_triangulation(6400, 17));
  auto simplex_types = classify_simplices(universe);
  auto edge_types = classify_edges(universe);
  auto number_of_vertices_before = universe->number_of_vertices();
  auto N3_31_before = std::get<0>(simplex_types).size();
  auto N3_22_before = std::get<1>(simplex_types).size();
  auto N3_13_before = std::get<2>(simplex_types).size();
  auto V2_before = edge_types.first.size();

  // Print initial values
  std::cout << "Number of vertices before = " << number_of_vertices_before
              << std::endl;
    std::cout << "Number of (3,1) simplices before = " << N3_31_before
              << std::endl;
    std::cout << "Number of (2,2) simplices before = " << N3_22_before
              << std::endl;
    std::cout << "Number of (1,3) simplices before = " << N3_13_before
              << std::endl;
    std::cout << "Number of timelike edges before = " << V2_before
              << std::endl;

  // Make move using PachnerMove
  PachnerMove p(universe, move_type::TWO_THREE, simplex_types, edge_types);

  std::cout << "Attempted (2,3) moves = " << std::get<0>(p.attempted_moves_)
            << std::endl;

  // Did we remove a (2,2) Cell_handle?
  EXPECT_THAT(std::get<1>(p.movable_simplex_types_).size(), Le(N3_22_before-1))
    << "make_23_move didn't remove a (2,2) simplex vector element.";

  EXPECT_THAT(std::get<0>(p.movable_simplex_types_).size(), Eq(N3_31_before))
    << "make_23_move removed a (3,1) simplex vector element.";

  EXPECT_THAT(std::get<2>(p.movable_simplex_types_).size(), Eq(N3_13_before))
    << "make_23_move removed a (1,3) simplex vector element.";

  // Now look at changes
  simplex_types = classify_simplices(p.universe_);
  auto N3_31_after = std::get<0>(simplex_types).size();
  auto N3_22_after = std::get<1>(simplex_types).size();
  auto N3_13_after = std::get<2>(simplex_types).size();

  // We expect the triangulation to be valid, but not necessarily Delaunay
  EXPECT_TRUE(p.universe_->tds().is_valid())
    << "Triangulation is invalid.";

  EXPECT_THAT(p.universe_->dimension(), Eq(3))
    << "Triangulation has wrong dimensionality.";

  EXPECT_TRUE(fix_timeslices(p.universe_))
    << "Some simplices do not span exactly 1 timeslice.";

  EXPECT_THAT(p.universe_->number_of_vertices(), Eq(number_of_vertices_before))
    << "The number of vertices changed.";

  EXPECT_THAT(N3_31_after, Eq(N3_31_before))
    << "(3,1) simplices changed.";

  EXPECT_THAT(N3_22_after, Eq(N3_22_before+1))
    << "(2,2) simplices did not increase by 1.";

  EXPECT_THAT(N3_13_after, Eq(N3_13_before))
    << "(1,3) simplices changed.";
}
<commit_msg>Test copy, move & swap<commit_after>/// Causal Dynamical Triangulations in C++ using CGAL
///
/// Copyright (c) 2016 Adam Getchell
///
/// Checks that the PachnerMove RAII class handles resources properly.

/// @file PachnerMoveTest.cpp
/// @brief Tests for the PachnerMove RAII class
/// @author Adam Getchell

#include <tuple>
#include <vector>
#include <utility>
#include <algorithm>

#include "gmock/gmock.h"
#include "PachnerMove.h"
#include "S3ErgodicMoves.h"

using namespace testing;  // NOLINT

class PachnerMoveTest : public Test {
 public:
  PachnerMoveTest() : universe_(std::move(make_triangulation(6400, 17))),
                      movable_simplex_types_(classify_simplices(universe_)),
                      movable_edge_types_(classify_edges(universe_)),
                      attempted_moves_(std::make_tuple(0, 0, 0, 0, 0)) {
    // Print ctor-initialized values
    std::cout << "(3,1) simplices: "
              << std::get<0>(movable_simplex_types_).size() << std::endl;
    std::cout << "(2,2) simplices: "
              << std::get<1>(movable_simplex_types_).size() << std::endl;
    std::cout << "(1,3) simplices: "
              << std::get<2>(movable_simplex_types_).size() << std::endl;
    std::cout << "Timelike edges: "
              << movable_edge_types_.first.size() << std::endl;
    std::cout << "Spacelike edges: "
              << movable_edge_types_.second << std::endl;
    std::cout << "Vertices: "
              << this->universe_->number_of_vertices() << std::endl;
  }  // Ctor

  std::unique_ptr<Delaunay> universe_;
  ///< Unique pointer to the Delaunay triangulation
  move_tuple attempted_moves_;
  ///< A count of all attempted moves
  std::tuple<std::vector<Cell_handle>,
             std::vector<Cell_handle>,
             std::vector<Cell_handle>> movable_simplex_types_;
  ///< Movable (3,1), (2,2) and (1,3) simplices.
  std::pair<std::vector<Edge_tuple>, unsigned> movable_edge_types_;
  ///< Movable timelike and spacelike edges.
};

TEST_F(PachnerMoveTest, DeepCopyCtor) {
  // Print info on move/copy operation exception safety
  std::cout << std::boolalpha
    << "Delaunay alias is copy-assignable? "
    << std::is_copy_assignable<Delaunay>::value << '\n'
    << "Delaunay alias is nothrow copy-assignable? "
    << std::is_nothrow_copy_assignable<Delaunay>::value << '\n'
    << "Delaunay alias is nothrow move-assignable? "
    << std::is_nothrow_move_assignable<Delaunay>::value << '\n'
    << "unique_ptr<Delaunay> is nothrow move-assignable? "
    << std::is_nothrow_move_assignable<std::unique_ptr<Delaunay>>::value
    << std::endl;

  EXPECT_TRUE(this->universe_->tds().is_valid())
    << "Constructed universe is invalid.";

  // Make a copy using Delaunay copy-ctor
  auto tempDT = Delaunay(*this->universe_);
  auto tempDT_ptr = std::make_unique<Delaunay>(tempDT);

  EXPECT_TRUE(tempDT_ptr->tds().is_valid())
    << "Delaunay copy is invalid.";

  EXPECT_THAT(this->universe_->number_of_vertices(),
    Eq(tempDT_ptr->number_of_vertices()))
    << "Delaunay copy doesn't have the same number of vertices.";

  EXPECT_THAT(this->universe_->number_of_finite_edges(),
    Eq(tempDT_ptr->number_of_finite_edges()))
    << "Delaunay copy doesn't have the same number of edges.";

  EXPECT_THAT(this->universe_->number_of_finite_facets(),
    Eq(tempDT_ptr->number_of_finite_facets()))
    << "Delaunay copy doesn't have the same number of facets.";

  EXPECT_THAT(this->universe_->number_of_finite_cells(),
    Eq(tempDT_ptr->number_of_finite_cells()))
    << "Delaunay copy doesn't have the same number of cells.";

  // Calculate copied simplex types
  auto tempDT_simplex_types = classify_simplices(tempDT_ptr);

  EXPECT_THAT(std::get<0>(this->movable_simplex_types_).size(),
    Eq(std::get<0>(tempDT_simplex_types).size()))
    << "Delaunay copy doesn't have the same number of (3,1) simplices.";

  EXPECT_THAT(std::get<1>(this->movable_simplex_types_).size(),
    Eq(std::get<1>(tempDT_simplex_types).size()))
    << "Delaunay copy doesn't have the same number of (2,2) simplices.";

  EXPECT_THAT(std::get<2>(this->movable_simplex_types_).size(),
    Eq(std::get<2>(tempDT_simplex_types).size()))
    << "Delaunay copy doesn't have the same number of (1,3) simplices.";

  // Calculate copied edge types
  auto tempDT_edge_types = classify_edges(tempDT_ptr);

  EXPECT_THAT(this->movable_edge_types_.first.size(),
    Eq(tempDT_edge_types.first.size()))
    << "Delaunay copy doesn't have the same number of timelike edges.";

  EXPECT_THAT(this->movable_edge_types_.second, Eq(tempDT_edge_types.second))
    << "Delaunay copy doesn't have the same number of spacelike edges.";
}

TEST_F(PachnerMoveTest, MakeA23MoveOnACopy) {
  EXPECT_TRUE(this->universe_->tds().is_valid())
    << "Constructed universe_ is invalid.";

  // Make a copy using Delaunay copy-ctor
  auto tempDT = Delaunay(*this->universe_);
  auto tempDT_ptr = std::make_unique<Delaunay>(tempDT);

  EXPECT_TRUE(tempDT_ptr->tds().is_valid())
    << "Copied universe is invalid.";

  auto simplex_types = classify_simplices(tempDT_ptr);

  tempDT_ptr = std::move(make_23_move(tempDT_ptr,
                                      simplex_types,
                                      attempted_moves_));

  std::cout << "Attempted (2,3) moves = " << std::get<0>(attempted_moves_)
            << std::endl;

  EXPECT_TRUE(tempDT_ptr->tds().is_valid())
    << "Copied universe invalid after make_23_move().";

  std::swap(this->universe_, tempDT_ptr);

  EXPECT_TRUE(this->universe_->tds().is_valid())
    << "universe_ invalid after swap with copied universe.";

  // Re-populate with current data
  auto new_movable_simplex_types = classify_simplices(this->universe_);
  auto new_movable_edge_types = classify_edges(this->universe_);

  // Print new values
  std::cout << "(3,1) simplices: "
            << std::get<0>(new_movable_simplex_types).size() << std::endl;
  std::cout << "(2,2) simplices: "
            << std::get<1>(new_movable_simplex_types).size() << std::endl;
  std::cout << "(1,3) simplices: "
            << std::get<2>(new_movable_simplex_types).size() << std::endl;
  std::cout << "Timelike edges: "
            << new_movable_edge_types.first.size() << std::endl;
  std::cout << "Spacelike edges: "
            << new_movable_edge_types.second << std::endl;
  std::cout << "Vertices: "
            << this->universe_->number_of_vertices() << std::endl;

  // Did we add a (2,2) Cell_handle?
  EXPECT_THAT(std::get<1>(new_movable_simplex_types).size(),
    Eq(std::get<1>(movable_simplex_types_).size()+1))
    << "make_23_move didn't add a (2,2) simplex vector element.";

  // Did we add a Timelike edge?
  EXPECT_THAT(new_movable_edge_types.first.size(),
    Eq(movable_edge_types_.first.size()+1))
    << "make_23_move didn't add a timelike edge.";

    // // Did we record an attempted move?
    // EXPECT_THAT(std::get<0>(attempted_moves) +
    //             std::get<1>(simplex_types).size(), Eq(N3_22_before))
    //   << "Attempted (2,3) moves not recorded correctly.";
    //
    // EXPECT_THAT(std::get<0>(simplex_types).size(), Eq(N3_31_before))
    //   << "make_23_move removed a (3,1) simplex vector element.";
    //
    // EXPECT_THAT(std::get<2>(simplex_types).size(), Eq(N3_13_before))
    //   << "make_23_move removed a (1,3) simplex vector element.";
}
// TEST(PachnerMoveTest, MakeA23Move) {
//   // Make a foliated triangulation
//   auto universe = std::move(make_triangulation(6400, 17));
//   auto simplex_types = classify_simplices(universe);
//   auto edge_types = classify_edges(universe);
//   auto number_of_vertices_before = universe->number_of_vertices();
//   auto N3_31_before = std::get<0>(simplex_types).size();
//   auto N3_22_before = std::get<1>(simplex_types).size();
//   auto N3_13_before = std::get<2>(simplex_types).size();
//   auto V2_before = edge_types.first.size();
//
//   // Print initial values
//   std::cout << "Number of vertices before = " << number_of_vertices_before
//               << std::endl;
//     std::cout << "Number of (3,1) simplices before = " << N3_31_before
//               << std::endl;
//     std::cout << "Number of (2,2) simplices before = " << N3_22_before
//               << std::endl;
//     std::cout << "Number of (1,3) simplices before = " << N3_13_before
//               << std::endl;
//     std::cout << "Number of timelike edges before = " << V2_before
//               << std::endl;
//
//   // Make move using PachnerMove
//   PachnerMove p(universe, move_type::TWO_THREE, simplex_types, edge_types);
//
//   std::cout << "Attempted (2,3) moves = " << std::get<0>(p.attempted_moves_)
//             << std::endl;
//
//   // Did we remove a (2,2) Cell_handle?
//   EXPECT_THAT(std::get<1>(p.movable_simplex_types_).size(), Le(N3_22_before-1))
//     << "make_23_move didn't remove a (2,2) simplex vector element.";
//
//   EXPECT_THAT(std::get<0>(p.movable_simplex_types_).size(), Eq(N3_31_before))
//     << "make_23_move removed a (3,1) simplex vector element.";
//
//   EXPECT_THAT(std::get<2>(p.movable_simplex_types_).size(), Eq(N3_13_before))
//     << "make_23_move removed a (1,3) simplex vector element.";
//
//   // Now look at changes
//   simplex_types = classify_simplices(p.universe_);
//   auto N3_31_after = std::get<0>(simplex_types).size();
//   auto N3_22_after = std::get<1>(simplex_types).size();
//   auto N3_13_after = std::get<2>(simplex_types).size();
//
//   // We expect the triangulation to be valid, but not necessarily Delaunay
//   EXPECT_TRUE(p.universe_->tds().is_valid())
//     << "Triangulation is invalid.";
//
//   EXPECT_THAT(p.universe_->dimension(), Eq(3))
//     << "Triangulation has wrong dimensionality.";
//
//   EXPECT_TRUE(fix_timeslices(p.universe_))
//     << "Some simplices do not span exactly 1 timeslice.";
//
//   EXPECT_THAT(p.universe_->number_of_vertices(), Eq(number_of_vertices_before))
//     << "The number of vertices changed.";
//
//   EXPECT_THAT(N3_31_after, Eq(N3_31_before))
//     << "(3,1) simplices changed.";
//
//   EXPECT_THAT(N3_22_after, Eq(N3_22_before+1))
//     << "(2,2) simplices did not increase by 1.";
//
//   EXPECT_THAT(N3_13_after, Eq(N3_13_before))
//     << "(1,3) simplices changed.";
// }
<|endoftext|>


<commit_before>//===---------- llvm/unittest/Support/Casting.cpp - Casting tests --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Debug.h"
//#define DEBUG_CAST_OPERATORS
#include "llvm/Support/Casting.h"

#include "gtest/gtest.h"
#include <cstdlib>

namespace llvm {

// set up two example classes
// with conversion facility
//
struct bar {
  bar() {}
  //struct foo *baz();
private:
  bar(const bar &);
};
struct foo {
  void ext() const;
  /*  static bool classof(const bar *X) {
    cerr << "Classof: " << X << "\n";
    return true;
    }*/
};

template <> struct isa_impl<foo,bar> {
  static inline bool doit(const bar &Val) {
    dbgs() << "Classof: " << &Val << "\n";
    return true;
  }
};

/*foo *bar::baz() {
    return cast<foo>(this);
}*/

bar *fub();
} // End llvm namespace

using namespace llvm;

namespace {

const foo *null_foo = NULL;

extern bar &B1;
extern const bar *B2;
// test various configurations of const
const bar &B3 = B1;
const bar *const B4 = B2;

TEST(CastingTest, isa) {
  EXPECT_TRUE(isa<foo>(B1));
  EXPECT_TRUE(isa<foo>(B2));
  EXPECT_TRUE(isa<foo>(B3));
  EXPECT_TRUE(isa<foo>(B4));
}

TEST(CastingTest, cast) {
  foo &F1 = cast<foo>(B1);
  EXPECT_NE(&F1, null_foo);
  const foo *F3 = cast<foo>(B2);
  EXPECT_NE(F3, null_foo);
  const foo *F4 = cast<foo>(B2);
  EXPECT_NE(F4, null_foo);
  const foo &F5 = cast<foo>(B3);
  EXPECT_NE(&F5, null_foo);
  const foo *F6 = cast<foo>(B4);
  EXPECT_NE(F6, null_foo);
  foo *F7 = cast<foo>(fub());
  EXPECT_EQ(F7, null_foo);

/*  foo *F8 = B1.baz();
  EXPECT_NE(F8, null_foo);*/
}

TEST(CastingTest, cast_or_null) {
  const foo *F11 = cast_or_null<foo>(B2);
  EXPECT_NE(F11, null_foo);
  const foo *F12 = cast_or_null<foo>(B2);
  EXPECT_NE(F12, null_foo);
  const foo *F13 = cast_or_null<foo>(B4);
  EXPECT_NE(F13, null_foo);
  const foo *F14 = cast_or_null<foo>(fub());  // Shouldn't print.
  EXPECT_EQ(F14, null_foo);
}

// These lines are errors...
//foo *F20 = cast<foo>(B2);  // Yields const foo*
//foo &F21 = cast<foo>(B3);  // Yields const foo&
//foo *F22 = cast<foo>(B4);  // Yields const foo*
//foo &F23 = cast_or_null<foo>(B1);
//const foo &F24 = cast_or_null<foo>(B3);

bar B;
bar &B1 = B;
const bar *B2 = &B;
}  // anonymous namespace

bar *llvm::fub() { return 0; }
<commit_msg>tidy up<commit_after>//===---------- llvm/unittest/Support/Casting.cpp - Casting tests ---------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

#include "gtest/gtest.h"
#include <cstdlib>

namespace llvm {

// set up two example classes
// with conversion facility
//
struct bar {
  bar() {}
  //struct foo *baz();
private:
  bar(const bar &);
};
struct foo {
  void ext() const;
  /*  static bool classof(const bar *X) {
    cerr << "Classof: " << X << "\n";
    return true;
    }*/
};

template <> struct isa_impl<foo,bar> {
  static inline bool doit(const bar &Val) {
    dbgs() << "Classof: " << &Val << "\n";
    return true;
  }
};

/*foo *bar::baz() {
    return cast<foo>(this);
}*/

bar *fub();
} // End llvm namespace

using namespace llvm;

namespace {

const foo *null_foo = NULL;

extern bar &B1;
extern const bar *B2;
// test various configurations of const
const bar &B3 = B1;
const bar *const B4 = B2;

TEST(CastingTest, isa) {
  EXPECT_TRUE(isa<foo>(B1));
  EXPECT_TRUE(isa<foo>(B2));
  EXPECT_TRUE(isa<foo>(B3));
  EXPECT_TRUE(isa<foo>(B4));
}

TEST(CastingTest, cast) {
  foo &F1 = cast<foo>(B1);
  EXPECT_NE(&F1, null_foo);
  const foo *F3 = cast<foo>(B2);
  EXPECT_NE(F3, null_foo);
  const foo *F4 = cast<foo>(B2);
  EXPECT_NE(F4, null_foo);
  const foo &F5 = cast<foo>(B3);
  EXPECT_NE(&F5, null_foo);
  const foo *F6 = cast<foo>(B4);
  EXPECT_NE(F6, null_foo);
  foo *F7 = cast<foo>(fub());
  EXPECT_EQ(F7, null_foo);

/*  foo *F8 = B1.baz();
  EXPECT_NE(F8, null_foo);*/
}

TEST(CastingTest, cast_or_null) {
  const foo *F11 = cast_or_null<foo>(B2);
  EXPECT_NE(F11, null_foo);
  const foo *F12 = cast_or_null<foo>(B2);
  EXPECT_NE(F12, null_foo);
  const foo *F13 = cast_or_null<foo>(B4);
  EXPECT_NE(F13, null_foo);
  const foo *F14 = cast_or_null<foo>(fub());  // Shouldn't print.
  EXPECT_EQ(F14, null_foo);
}

// These lines are errors...
//foo *F20 = cast<foo>(B2);  // Yields const foo*
//foo &F21 = cast<foo>(B3);  // Yields const foo&
//foo *F22 = cast<foo>(B4);  // Yields const foo*
//foo &F23 = cast_or_null<foo>(B1);
//const foo &F24 = cast_or_null<foo>(B3);

bar B;
bar &B1 = B;
const bar *B2 = &B;
}  // anonymous namespace

bar *llvm::fub() { return 0; }
<|endoftext|>


<commit_before>/* FREEVERB - a reverberator

   This reverb instrument is based on Freeverb, by Jezar
   (http://www.dreampoint.co.uk/~jzracc/freeverb.htm).

   p0  = output start time
   p1  = input start time
   p2  = input duration
   p3  = amplitude multiplier
   p4  = room size (0-1.07143 ... don't ask)
   p5  = pre-delay time (time between dry signal and onset of reverb)
   p6  = ring-down duration
   p7  = damp (0-100%)
   p8  = dry signal level (0-100%)
   p9  = wet signal level (0-100%)
   p10 = stereo width of reverb (0-100%)

   p3 (amplitude), p4 (room size), p5 (pre-delay), p7 (damp), p8 (dry),
   p9 (wet) and p10 (stereo width) can receive dynamic updates from a table
   or real-time control source.

   If an old-style gen table 1 is present, its values will be multiplied
   by the p3 amplitude multiplier, even if the latter is dynamic.

   The amplitude multiplier is applied to the input sound *before*
   it enters the reverberator.

   If you enter a room size greater than the maximum, you'll get the
   maximum amount -- which is probably an infinite reverb time.

   Input can be mono or stereo; output can be mono or stereo.

   Be careful with the dry and wet levels -- it's easy to get extreme
   clipping!

   John Gibson <johngibson@virginia.edu>, 2 Feb 2001; rev for v4, 7/11/04
*/
#include <stdio.h>
#include <stdlib.h>
#include <ugens.h>
#include <math.h>
#include <Instrument.h>
#include "FREEVERB.h"
#include <rt.h>
#include <rtdefs.h>

FREEVERB :: FREEVERB() : Instrument()
{
   in = NULL;
   branch = 0;
   warn_roomsize = true;
   warn_predelay = true;
   warn_damp = true;
   warn_dry = true;
   warn_wet = true;
   warn_width = true;
}

FREEVERB :: ~FREEVERB()
{
   delete [] in;
   delete rvb;
}

int FREEVERB :: init(double p[], int n_args)
{
   float outskip = p[0];
   float inskip = p[1];
   float dur = p[2];
   roomsize = p[4];
   predelay_time = p[5];
   ringdur = p[6];
   damp = p[7];
   dry = p[8];
   wet = p[9];
   width = p[10];

   // Keep reverb comb feedback <= 1.0
   max_roomsize = (1.0 - offsetroom) / scaleroom;
   if (roomsize < 0.0)
      return die("FREEVERB", "Room size must be between 0 and %g.",
                                                               max_roomsize);
   if (roomsize > max_roomsize) {
      roomsize = max_roomsize;
      advise("FREEVERB", "Room size cannot be greater than %g. Adjusting...",
             max_roomsize);
   }
   int predelay_samps = (int) ((predelay_time * SR) + 0.5);
   if (predelay_samps > max_predelay_samps)
      return die("FREEVERB", "Pre-delay must be between 0 and %g seconds.",
                                             (float) max_predelay_samps / SR);
   if (damp < 0.0 || damp > 100.0)
      return die("FREEVERB", "Damp must be between 0 and 100%%.");
   if (dry < 0.0 || dry > 100.0)
      return die("FREEVERB", "Dry signal level must be between 0 and 100%%.");
   if (wet < 0.0 || wet > 100.0)
      return die("FREEVERB", "Wet signal level must be between 0 and 100%%.");
   if (width < 0.0 || width > 100.0)
      return die("FREEVERB", "Width must be between 0 and 100%%.");

   if (rtsetinput(inskip, this) == -1)
      return DONT_SCHEDULE;
   if (rtsetoutput(outskip, dur + ringdur, this) == -1)
      return DONT_SCHEDULE;
   insamps = (int) (dur * SR);

   if (inputChannels() > 2)
      return die("FREEVERB", "Can't have more than 2 input channels.");
   if (outputChannels() > 2)
      return die("FREEVERB", "Can't have more than 2 output channels.");

   rvb = new revmodel();

   rvb->setroomsize(roomsize);
   rvb->setpredelay(predelay_samps);
   rvb->setdamp(damp * 0.01);
   rvb->setdry(dry * 0.01);
   rvb->setwet(wet * 0.01);
   rvb->setwidth(width * 0.01);

   amparray = floc(1);
   if (amparray) {
      int lenamp = fsize(1);
      tableset(SR, dur, lenamp, amptabs);
   }

   return nSamps();
}

int FREEVERB :: configure()
{
   in = new float [RTBUFSAMPS * inputChannels()];
   return in ? 0 : -1;
}

inline void FREEVERB :: updateRvb(double p[])
{
   if (p[4] != roomsize) {
      roomsize = p[4];
      if (roomsize < 0.0 || roomsize > max_roomsize) {
         if (warn_roomsize) {
            warn("FREEVERB", "Room size must be between 0 and %g. Adjusting...",
                                                                  max_roomsize);
            warn_roomsize = false;
         }
         roomsize = roomsize < 0.0 ? 0.0 : max_roomsize;
      }
      rvb->setroomsize(roomsize);
   }
   if (p[5] != predelay_time) {
      predelay_time = p[5];
      int predelay_samps = (int) ((predelay_time * SR) + 0.5);
      if (predelay_samps > max_predelay_samps) {
         if (warn_predelay) {
            warn("FREEVERB", "Pre-delay must be between 0 and %g seconds. "
                             "Adjusting...", (float) max_predelay_samps / SR);
            warn_predelay = false;
         }
         predelay_samps = max_predelay_samps;
      }
      rvb->setpredelay(predelay_samps);
   }
   if (p[7] != damp) {
      damp = p[7];
      if (damp < 0.0 || damp > 100.0) {
         if (warn_damp) {
            warn("FREEVERB", "Damp must be between 0 and 100%%. Adjusting...");
            warn_damp = false;
         }
         damp = damp < 0.0 ? 0.0 : 100.0;
      }
      rvb->setdamp(damp * 0.01);
   }
   if (p[8] != dry) {
      dry = p[8];
      if (dry < 0.0 || dry > 100.0) {
         if (warn_dry) {
            warn("FREEVERB", "Dry signal level must be between 0 and 100%%. "
                                                               "Adjusting...");
            warn_dry = false;
         }
         dry = dry < 0.0 ? 0.0 : 100.0;
      }
      rvb->setdry(dry * 0.01);
   }
   if (p[9] != wet) {
      wet = p[9];
      if (wet < 0.0 || wet > 100.0) {
         if (warn_wet) {
            warn("FREEVERB", "Wet signal level must be between 0 and 100%%. "
                                                               "Adjusting...");
            warn_wet = false;
         }
         wet = wet < 0.0 ? 0.0 : 100.0;
      }
      rvb->setwet(wet * 0.01);
   }
   if (p[10] != width) {
      width = p[10];
      if (width < 0.0 || width > 100.0) {
         if (warn_width) {
            warn("FREEVERB", "Width must be between 0 and 100%%. Adjusting...");
            warn_width = false;
         }
         width = width < 0.0 ? 0.0 : 100.0;
      }
      rvb->setwidth(width * 0.01);
   }
// printf("rmsz=%f, predel=%f, damp=%f, dry=%f, wet=%f, width=%f\n", roomsize, predelay_time, damp, dry, wet, width);
}

int FREEVERB :: run()
{
   float *inL, *inR, *outL, *outR;

   inL = in;
   inR = inputChannels() > 1 ? in + 1 : in;
   outL = outbuf;
   outR = outputChannels() > 1 ? outbuf + 1 : outbuf;

   int samps = framesToRun() * inputChannels();

   if (currentFrame() < insamps)
      rtgetin(in, this, samps);

   // Scale input signal by amplitude multiplier and setline curve.
   for (int i = 0; i < samps; i += inputChannels()) {
      if (--branch <= 0) {
         double p[11];
         update(p, 11, kRoomSize | kPreDelay | kDamp | kDry | kWet | kWidth);
         if (currentFrame() < insamps) {  // amp is pre-effect
            amp = update(3, insamps);
            if (amparray)
               amp *= tablei(currentFrame(), amparray, amptabs);
         }
         updateRvb(p);
         branch = getSkip();
      }
      if (currentFrame() < insamps) {     // still taking input from file
         in[i] *= amp;
         if (inputChannels() == 2)
            in[i + 1] *= amp;
      }
      else {                              // in ringdown phase
         in[i] = 0.0;
         if (inputChannels() == 2)
            in[i + 1] = 0.0;
      }
      increment();
   }

   // Hand off to Freeverb to do the actual work.
   rvb->processreplace(inL, inR, outL, outR, chunksamps, inputChannels(),
                                                         outputChannels());

   return framesToRun();
}

Instrument *makeFREEVERB()
{
   FREEVERB *inst;

   inst = new FREEVERB();
   inst->set_bus_config("FREEVERB");

   return inst;
}

void rtprofile()
{
   RT_INTRO("FREEVERB", makeFREEVERB);
}

<commit_msg>Removed all direct uses of 'chunksamps' member from derived Instrument classes.<commit_after>/* FREEVERB - a reverberator

   This reverb instrument is based on Freeverb, by Jezar
   (http://www.dreampoint.co.uk/~jzracc/freeverb.htm).

   p0  = output start time
   p1  = input start time
   p2  = input duration
   p3  = amplitude multiplier
   p4  = room size (0-1.07143 ... don't ask)
   p5  = pre-delay time (time between dry signal and onset of reverb)
   p6  = ring-down duration
   p7  = damp (0-100%)
   p8  = dry signal level (0-100%)
   p9  = wet signal level (0-100%)
   p10 = stereo width of reverb (0-100%)

   p3 (amplitude), p4 (room size), p5 (pre-delay), p7 (damp), p8 (dry),
   p9 (wet) and p10 (stereo width) can receive dynamic updates from a table
   or real-time control source.

   If an old-style gen table 1 is present, its values will be multiplied
   by the p3 amplitude multiplier, even if the latter is dynamic.

   The amplitude multiplier is applied to the input sound *before*
   it enters the reverberator.

   If you enter a room size greater than the maximum, you'll get the
   maximum amount -- which is probably an infinite reverb time.

   Input can be mono or stereo; output can be mono or stereo.

   Be careful with the dry and wet levels -- it's easy to get extreme
   clipping!

   John Gibson <johngibson@virginia.edu>, 2 Feb 2001; rev for v4, 7/11/04
*/
#include <stdio.h>
#include <stdlib.h>
#include <ugens.h>
#include <math.h>
#include <Instrument.h>
#include "FREEVERB.h"
#include <rt.h>
#include <rtdefs.h>

FREEVERB :: FREEVERB() : Instrument()
{
   in = NULL;
   branch = 0;
   warn_roomsize = true;
   warn_predelay = true;
   warn_damp = true;
   warn_dry = true;
   warn_wet = true;
   warn_width = true;
}

FREEVERB :: ~FREEVERB()
{
   delete [] in;
   delete rvb;
}

int FREEVERB :: init(double p[], int n_args)
{
   float outskip = p[0];
   float inskip = p[1];
   float dur = p[2];
   roomsize = p[4];
   predelay_time = p[5];
   ringdur = p[6];
   damp = p[7];
   dry = p[8];
   wet = p[9];
   width = p[10];

   // Keep reverb comb feedback <= 1.0
   max_roomsize = (1.0 - offsetroom) / scaleroom;
   if (roomsize < 0.0)
      return die("FREEVERB", "Room size must be between 0 and %g.",
                                                               max_roomsize);
   if (roomsize > max_roomsize) {
      roomsize = max_roomsize;
      advise("FREEVERB", "Room size cannot be greater than %g. Adjusting...",
             max_roomsize);
   }
   int predelay_samps = (int) ((predelay_time * SR) + 0.5);
   if (predelay_samps > max_predelay_samps)
      return die("FREEVERB", "Pre-delay must be between 0 and %g seconds.",
                                             (float) max_predelay_samps / SR);
   if (damp < 0.0 || damp > 100.0)
      return die("FREEVERB", "Damp must be between 0 and 100%%.");
   if (dry < 0.0 || dry > 100.0)
      return die("FREEVERB", "Dry signal level must be between 0 and 100%%.");
   if (wet < 0.0 || wet > 100.0)
      return die("FREEVERB", "Wet signal level must be between 0 and 100%%.");
   if (width < 0.0 || width > 100.0)
      return die("FREEVERB", "Width must be between 0 and 100%%.");

   if (rtsetinput(inskip, this) == -1)
      return DONT_SCHEDULE;
   if (rtsetoutput(outskip, dur + ringdur, this) == -1)
      return DONT_SCHEDULE;
   insamps = (int) (dur * SR);

   if (inputChannels() > 2)
      return die("FREEVERB", "Can't have more than 2 input channels.");
   if (outputChannels() > 2)
      return die("FREEVERB", "Can't have more than 2 output channels.");

   rvb = new revmodel();

   rvb->setroomsize(roomsize);
   rvb->setpredelay(predelay_samps);
   rvb->setdamp(damp * 0.01);
   rvb->setdry(dry * 0.01);
   rvb->setwet(wet * 0.01);
   rvb->setwidth(width * 0.01);

   amparray = floc(1);
   if (amparray) {
      int lenamp = fsize(1);
      tableset(SR, dur, lenamp, amptabs);
   }

   return nSamps();
}

int FREEVERB :: configure()
{
   in = new float [RTBUFSAMPS * inputChannels()];
   return in ? 0 : -1;
}

inline void FREEVERB :: updateRvb(double p[])
{
   if (p[4] != roomsize) {
      roomsize = p[4];
      if (roomsize < 0.0 || roomsize > max_roomsize) {
         if (warn_roomsize) {
            warn("FREEVERB", "Room size must be between 0 and %g. Adjusting...",
                                                                  max_roomsize);
            warn_roomsize = false;
         }
         roomsize = roomsize < 0.0 ? 0.0 : max_roomsize;
      }
      rvb->setroomsize(roomsize);
   }
   if (p[5] != predelay_time) {
      predelay_time = p[5];
      int predelay_samps = (int) ((predelay_time * SR) + 0.5);
      if (predelay_samps > max_predelay_samps) {
         if (warn_predelay) {
            warn("FREEVERB", "Pre-delay must be between 0 and %g seconds. "
                             "Adjusting...", (float) max_predelay_samps / SR);
            warn_predelay = false;
         }
         predelay_samps = max_predelay_samps;
      }
      rvb->setpredelay(predelay_samps);
   }
   if (p[7] != damp) {
      damp = p[7];
      if (damp < 0.0 || damp > 100.0) {
         if (warn_damp) {
            warn("FREEVERB", "Damp must be between 0 and 100%%. Adjusting...");
            warn_damp = false;
         }
         damp = damp < 0.0 ? 0.0 : 100.0;
      }
      rvb->setdamp(damp * 0.01);
   }
   if (p[8] != dry) {
      dry = p[8];
      if (dry < 0.0 || dry > 100.0) {
         if (warn_dry) {
            warn("FREEVERB", "Dry signal level must be between 0 and 100%%. "
                                                               "Adjusting...");
            warn_dry = false;
         }
         dry = dry < 0.0 ? 0.0 : 100.0;
      }
      rvb->setdry(dry * 0.01);
   }
   if (p[9] != wet) {
      wet = p[9];
      if (wet < 0.0 || wet > 100.0) {
         if (warn_wet) {
            warn("FREEVERB", "Wet signal level must be between 0 and 100%%. "
                                                               "Adjusting...");
            warn_wet = false;
         }
         wet = wet < 0.0 ? 0.0 : 100.0;
      }
      rvb->setwet(wet * 0.01);
   }
   if (p[10] != width) {
      width = p[10];
      if (width < 0.0 || width > 100.0) {
         if (warn_width) {
            warn("FREEVERB", "Width must be between 0 and 100%%. Adjusting...");
            warn_width = false;
         }
         width = width < 0.0 ? 0.0 : 100.0;
      }
      rvb->setwidth(width * 0.01);
   }
// printf("rmsz=%f, predel=%f, damp=%f, dry=%f, wet=%f, width=%f\n", roomsize, predelay_time, damp, dry, wet, width);
}

int FREEVERB :: run()
{
   float *inL, *inR, *outL, *outR;

   inL = in;
   inR = inputChannels() > 1 ? in + 1 : in;
   outL = outbuf;
   outR = outputChannels() > 1 ? outbuf + 1 : outbuf;

   int samps = framesToRun() * inputChannels();

   if (currentFrame() < insamps)
      rtgetin(in, this, samps);

   // Scale input signal by amplitude multiplier and setline curve.
   for (int i = 0; i < samps; i += inputChannels()) {
      if (--branch <= 0) {
         double p[11];
         update(p, 11, kRoomSize | kPreDelay | kDamp | kDry | kWet | kWidth);
         if (currentFrame() < insamps) {  // amp is pre-effect
            amp = update(3, insamps);
            if (amparray)
               amp *= tablei(currentFrame(), amparray, amptabs);
         }
         updateRvb(p);
         branch = getSkip();
      }
      if (currentFrame() < insamps) {     // still taking input from file
         in[i] *= amp;
         if (inputChannels() == 2)
            in[i + 1] *= amp;
      }
      else {                              // in ringdown phase
         in[i] = 0.0;
         if (inputChannels() == 2)
            in[i + 1] = 0.0;
      }
      increment();
   }

   // Hand off to Freeverb to do the actual work.
   rvb->processreplace(inL, inR, outL, outR, framesToRun(), inputChannels(),
                                                         outputChannels());

   return framesToRun();
}

Instrument *makeFREEVERB()
{
   FREEVERB *inst;

   inst = new FREEVERB();
   inst->set_bus_config("FREEVERB");

   return inst;
}

void rtprofile()
{
   RT_INTRO("FREEVERB", makeFREEVERB);
}

<|endoftext|>


<commit_before>// This file is part of the dune-hdd project:
//   http://users.dune-project.org/projects/dune-hdd
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_HDD_EXAMPLES_LINEARELLIPTIC_SWIPDG_HH
#define DUNE_HDD_EXAMPLES_LINEARELLIPTIC_SWIPDG_HH

#include "config.h"

#include <memory>

#include <dune/stuff/common/memory.hh>

#include <dune/hdd/playground/linearelliptic/discreteproblem.hh>
#include <dune/hdd/playground/linearelliptic/discretizations/swipdg.hh>

template< class GridImp >
class LinearellipticExampleSWIPDG
{
public:
  typedef GridImp GridType;
  typedef Dune::HDD::LinearElliptic::DiscreteProblem< GridType > DiscreteProblemType;
  typedef typename DiscreteProblemType::RangeFieldType RangeFieldType;
  static const unsigned int dimRange = DiscreteProblemType::dimRange;
  typedef Dune::HDD::LinearElliptic::Discretizations::SWIPDG< GridType, Dune::Stuff::Grid::ChooseLayer::leaf,
                                                              RangeFieldType, dimRange, 1 > DiscretizationType;

  static std::string static_id()
  {
    return "linearelliptic.swipdg";
  }

  static void write_config_file(const std::string filename = static_id() + ".cfg")
  {
    DiscreteProblemType::write_config(filename, static_id());
  }

  void initialize(const std::vector< std::string > arguments)
  {
    using namespace Dune;
    if (!discrete_problem_) {
      discrete_problem_ = Stuff::Common::make_unique< DiscreteProblemType >(static_id(), arguments);
      const bool debug_logging = discrete_problem_->debug_logging();
      auto& info = DSC_LOG_INFO;
      auto& debug = DSC_LOG_DEBUG;
      discretization_ = Stuff::Common::make_unique< DiscretizationType >(discrete_problem_->grid_provider(),
                                                                         discrete_problem_->boundary_info(),
                                                                         discrete_problem_->problem());
      info << "initializing discretization";
      if (debug_logging)
        info << ":" << std::endl;
      else
        info << "... " << std::flush;
      Dune::Timer timer;
      discretization_->init(debug, "  ");
      if (!debug_logging)
        info << "done (took " << timer.elapsed() << "s)" << std::endl;
    } else
      DSC_LOG_INFO << "initialize has already been called" << std::endl;
  } // ... initialize(...)

  const DiscreteProblemType& discrete_problem() const
  {
    return *discrete_problem_;
  }

  const DiscretizationType& discretization() const
  {
    return *discretization_;
  }

  DiscretizationType* discretization_and_return_ptr() const
  {
    return new DiscretizationType(*discretization_);
  }

private:
  std::unique_ptr< DiscreteProblemType > discrete_problem_;
  std::unique_ptr< DiscretizationType > discretization_;
}; // class LinearellipticExampleSWIPDG

namespace Dune {

// forward grid declaratios
template< int dim, int dimworld, typename _ctype >
class SGrid;

template< int dim >
class YaspGrid;

} // namespace Dune

extern template class LinearellipticExampleSWIPDG< Dune::SGrid< 1, 1 > >;
extern template class LinearellipticExampleSWIPDG< Dune::SGrid< 2, 2 > >;
extern template class LinearellipticExampleSWIPDG< Dune::SGrid< 3, 3 > >;

extern template class LinearellipticExampleSWIPDG< Dune::YaspGrid< 1 > >;
extern template class LinearellipticExampleSWIPDG< Dune::YaspGrid< 2 > >;
extern template class LinearellipticExampleSWIPDG< Dune::YaspGrid< 3 > >;

#endif // DUNE_HDD_EXAMPLES_LINEARELLIPTIC_SWIPDG_HH
<commit_msg>[examples.linearelliptic.swipdg] removed config.h include<commit_after>// This file is part of the dune-hdd project:
//   http://users.dune-project.org/projects/dune-hdd
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_HDD_EXAMPLES_LINEARELLIPTIC_SWIPDG_HH
#define DUNE_HDD_EXAMPLES_LINEARELLIPTIC_SWIPDG_HH

#include <memory>

#include <dune/stuff/common/memory.hh>

#include <dune/hdd/playground/linearelliptic/discreteproblem.hh>
#include <dune/hdd/playground/linearelliptic/discretizations/swipdg.hh>

template< class GridImp >
class LinearellipticExampleSWIPDG
{
public:
  typedef GridImp GridType;
  typedef Dune::HDD::LinearElliptic::DiscreteProblem< GridType > DiscreteProblemType;
  typedef typename DiscreteProblemType::RangeFieldType RangeFieldType;
  static const unsigned int dimRange = DiscreteProblemType::dimRange;
  typedef Dune::HDD::LinearElliptic::Discretizations::SWIPDG< GridType, Dune::Stuff::Grid::ChooseLayer::leaf,
                                                              RangeFieldType, dimRange, 1 > DiscretizationType;

  static std::string static_id()
  {
    return "linearelliptic.swipdg";
  }

  static void write_config_file(const std::string filename = static_id() + ".cfg")
  {
    DiscreteProblemType::write_config(filename, static_id());
  }

  void initialize(const std::vector< std::string > arguments)
  {
    using namespace Dune;
    if (!discrete_problem_) {
      discrete_problem_ = Stuff::Common::make_unique< DiscreteProblemType >(static_id(), arguments);
      const bool debug_logging = discrete_problem_->debug_logging();
      auto& info = DSC_LOG_INFO;
      auto& debug = DSC_LOG_DEBUG;
      discretization_ = Stuff::Common::make_unique< DiscretizationType >(discrete_problem_->grid_provider(),
                                                                         discrete_problem_->boundary_info(),
                                                                         discrete_problem_->problem());
      info << "initializing discretization";
      if (debug_logging)
        info << ":" << std::endl;
      else
        info << "... " << std::flush;
      Dune::Timer timer;
      discretization_->init(debug, "  ");
      if (!debug_logging)
        info << "done (took " << timer.elapsed() << "s)" << std::endl;
    } else
      DSC_LOG_INFO << "initialize has already been called" << std::endl;
  } // ... initialize(...)

  const DiscreteProblemType& discrete_problem() const
  {
    return *discrete_problem_;
  }

  const DiscretizationType& discretization() const
  {
    return *discretization_;
  }

  DiscretizationType* discretization_and_return_ptr() const
  {
    return new DiscretizationType(*discretization_);
  }

private:
  std::unique_ptr< DiscreteProblemType > discrete_problem_;
  std::unique_ptr< DiscretizationType > discretization_;
}; // class LinearellipticExampleSWIPDG

namespace Dune {

// forward grid declaratios
template< int dim, int dimworld, typename _ctype >
class SGrid;

template< int dim >
class YaspGrid;

} // namespace Dune

extern template class LinearellipticExampleSWIPDG< Dune::SGrid< 1, 1 > >;
extern template class LinearellipticExampleSWIPDG< Dune::SGrid< 2, 2 > >;
extern template class LinearellipticExampleSWIPDG< Dune::SGrid< 3, 3 > >;

extern template class LinearellipticExampleSWIPDG< Dune::YaspGrid< 1 > >;
extern template class LinearellipticExampleSWIPDG< Dune::YaspGrid< 2 > >;
extern template class LinearellipticExampleSWIPDG< Dune::YaspGrid< 3 > >;

#endif // DUNE_HDD_EXAMPLES_LINEARELLIPTIC_SWIPDG_HH
<|endoftext|>


<commit_before>/*******************************************************************************
 *  Code contributed to the webinos project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Copyright 2012 Torsec -Computer and network security group-
 * Politecnico di Torino
 *
 ******************************************************************************/

#include "AuthorizationsSet.h"
#include "../../debug.h"

string ontology_vector[PURPOSES_NUMBER] = {
	"http://www.w3.org/2002/01/P3Pv1/current",
	"http://www.w3.org/2002/01/P3Pv1/admin",
	"http://www.w3.org/2002/01/P3Pv1/develop",
	"http://www.w3.org/2002/01/P3Pv1/tailoring",
	"http://www.w3.org/2002/01/P3Pv1/pseudo-analysis",
	"http://www.w3.org/2002/01/P3Pv1/pseudo-decision",
	"http://www.w3.org/2002/01/P3Pv1/individual-analysis",
	"http://www.w3.org/2002/01/P3Pv1/individual-decision",
	"http://www.w3.org/2002/01/P3Pv1/contact",
	"http://www.w3.org/2002/01/P3Pv1/historical",
	"http://www.w3.org/2002/01/P3Pv1/telemarketing",
	"http://www.w3.org/2002/01/P3Pv11/account",
	"http://www.w3.org/2002/01/P3Pv11/arts",
	"http://www.w3.org/2002/01/P3Pv11/browsing",
	"http://www.w3.org/2002/01/P3Pv11/charity",
	"http://www.w3.org/2002/01/P3Pv11/communicate",
	"http://www.w3.org/2002/01/P3Pv11/custom",
	"http://www.w3.org/2002/01/P3Pv11/delivery",
	"http://www.w3.org/2002/01/P3Pv11/downloads",
	"http://www.w3.org/2002/01/P3Pv11/education",
	"http://www.w3.org/2002/01/P3Pv11/feedback",
	"http://www.w3.org/2002/01/P3Pv11/finmgt",
	"http://www.w3.org/2002/01/P3Pv11/gambling",
	"http://www.w3.org/2002/01/P3Pv11/gaming",
	"http://www.w3.org/2002/01/P3Pv11/government",
	"http://www.w3.org/2002/01/P3Pv11/health",
	"http://www.w3.org/2002/01/P3Pv11/login",
	"http://www.w3.org/2002/01/P3Pv11/marketing",
	"http://www.w3.org/2002/01/P3Pv11/news",
	"http://www.w3.org/2002/01/P3Pv11/payment",
	"http://www.w3.org/2002/01/P3Pv11/sales",
	"http://www.w3.org/2002/01/P3Pv11/search",
	"http://www.w3.org/2002/01/P3Pv11/state",
	"http://www.w3.org/2002/01/P3Pv11/surveys",
	"http://www.primelife.eu/purposes/unspecified"
};

AuthorizationsSet::AuthorizationsSet(TiXmlElement* authorizationsset){

	// AuthzUseForPurpose Tags
	for(TiXmlElement * child = (TiXmlElement*)authorizationsset->FirstChild("AuthzUseForPurpose"); child;
			child = (TiXmlElement*)child->NextSibling("AuthzUseForPurpose")) {
		LOGD("AuthorizationsSet constructor, AuthzUseForPurpose %s found", ((TiXmlElement*)child->FirstChild("Purpose"))->GetText());
		authzuseforpurpose.push_back(((TiXmlElement*)child->FirstChild("Purpose"))->GetText());
	}
}

AuthorizationsSet::~AuthorizationsSet(){
}

bool AuthorizationsSet::evaluate(Request * req){
	LOGD("Evaluating AuthorizationsSet");

	bool purpose_satisfied[PURPOSES_NUMBER];
	vector<bool> purpose = req->getPurposeAttrs();
	unsigned int i = 0;

	for(vector<bool>::iterator it = purpose.begin(); it!= purpose.end(); it++){
		// Purpose requested
		if (*it == true){
			purpose_satisfied[i] = false;
			LOGD("AuthorizationsSet: purpose %d is true", i);
			for(unsigned int j=0; j<authzuseforpurpose.size(); j++){
				LOGD("AuthorizationsSet: checking authzuseforpurpose %d, %s", j, authzuseforpurpose[j].c_str());
				if (ontology_vector[i].compare(authzuseforpurpose[j]) == 0){
					// Purpose requested and satisfied
					purpose_satisfied[i] = true;
					break;
				}
			}
		}
		// Purpose not requested
		else {
			LOGD("AuthorizationsSet: purpose %d is false", i);
			purpose_satisfied[i] = true;
		}
		i++;
	}

	for (i=0; i < PURPOSES_NUMBER; i++){
		if (purpose_satisfied[i] == false)
			// A purpose is not satisfied
			return false;
	}
	// All purposes are satisfied
	return true;
}
<commit_msg>Fixed AuthzUseForPurpose parsing<commit_after>/*******************************************************************************
 *  Code contributed to the webinos project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Copyright 2012 Torsec -Computer and network security group-
 * Politecnico di Torino
 *
 ******************************************************************************/

#include "AuthorizationsSet.h"
#include "../../debug.h"

string ontology_vector[PURPOSES_NUMBER] = {
	"http://www.w3.org/2002/01/P3Pv1/current",
	"http://www.w3.org/2002/01/P3Pv1/admin",
	"http://www.w3.org/2002/01/P3Pv1/develop",
	"http://www.w3.org/2002/01/P3Pv1/tailoring",
	"http://www.w3.org/2002/01/P3Pv1/pseudo-analysis",
	"http://www.w3.org/2002/01/P3Pv1/pseudo-decision",
	"http://www.w3.org/2002/01/P3Pv1/individual-analysis",
	"http://www.w3.org/2002/01/P3Pv1/individual-decision",
	"http://www.w3.org/2002/01/P3Pv1/contact",
	"http://www.w3.org/2002/01/P3Pv1/historical",
	"http://www.w3.org/2002/01/P3Pv1/telemarketing",
	"http://www.w3.org/2002/01/P3Pv11/account",
	"http://www.w3.org/2002/01/P3Pv11/arts",
	"http://www.w3.org/2002/01/P3Pv11/browsing",
	"http://www.w3.org/2002/01/P3Pv11/charity",
	"http://www.w3.org/2002/01/P3Pv11/communicate",
	"http://www.w3.org/2002/01/P3Pv11/custom",
	"http://www.w3.org/2002/01/P3Pv11/delivery",
	"http://www.w3.org/2002/01/P3Pv11/downloads",
	"http://www.w3.org/2002/01/P3Pv11/education",
	"http://www.w3.org/2002/01/P3Pv11/feedback",
	"http://www.w3.org/2002/01/P3Pv11/finmgt",
	"http://www.w3.org/2002/01/P3Pv11/gambling",
	"http://www.w3.org/2002/01/P3Pv11/gaming",
	"http://www.w3.org/2002/01/P3Pv11/government",
	"http://www.w3.org/2002/01/P3Pv11/health",
	"http://www.w3.org/2002/01/P3Pv11/login",
	"http://www.w3.org/2002/01/P3Pv11/marketing",
	"http://www.w3.org/2002/01/P3Pv11/news",
	"http://www.w3.org/2002/01/P3Pv11/payment",
	"http://www.w3.org/2002/01/P3Pv11/sales",
	"http://www.w3.org/2002/01/P3Pv11/search",
	"http://www.w3.org/2002/01/P3Pv11/state",
	"http://www.w3.org/2002/01/P3Pv11/surveys",
	"http://www.primelife.eu/purposes/unspecified"
};

AuthorizationsSet::AuthorizationsSet(TiXmlElement* authorizationsset){

	TiXmlElement * child;

	// AuthzUseForPurpose Tag
	if (authorizationsset->FirstChild("AuthzUseForPurpose")) {
		LOGD("AuthorizationsSet constructor, AuthzUseForPurpose found");
		child = (TiXmlElement*)authorizationsset->FirstChild("AuthzUseForPurpose");
		for(child = (TiXmlElement*)child->FirstChild("Purpose"); child;
				child = (TiXmlElement*)child->NextSibling("Purpose")) {
			LOGD("Purpose %s found", child->GetText());
			authzuseforpurpose.push_back(child->GetText());
		}
	}
	else{
		LOGD("AuthorizationsSet constructor, AuthzUseForPurpose not found");
	}
}

AuthorizationsSet::~AuthorizationsSet(){
}

bool AuthorizationsSet::evaluate(Request * req){
	LOGD("Evaluating AuthorizationsSet");

	bool purpose_satisfied[PURPOSES_NUMBER];
	vector<bool> purpose = req->getPurposeAttrs();
	unsigned int i = 0;

	for(vector<bool>::iterator it = purpose.begin(); it!= purpose.end(); it++){
		// Purpose requested
		if (*it == true){
			purpose_satisfied[i] = false;
			LOGD("AuthorizationsSet: purpose %d is true", i);
			for(unsigned int j=0; j<authzuseforpurpose.size(); j++){
				LOGD("AuthorizationsSet: checking authzuseforpurpose %d, %s", j, authzuseforpurpose[j].c_str());
				if (ontology_vector[i].compare(authzuseforpurpose[j]) == 0){
					// Purpose requested and satisfied
					purpose_satisfied[i] = true;
					break;
				}
			}
		}
		// Purpose not requested
		else {
			LOGD("AuthorizationsSet: purpose %d is false", i);
			purpose_satisfied[i] = true;
		}
		i++;
	}

	for (i=0; i < PURPOSES_NUMBER; i++){
		if (purpose_satisfied[i] == false)
			// A purpose is not satisfied
			return false;
	}
	// All purposes are satisfied
	return true;
}
<|endoftext|>


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

#include "OpenwireStringSupport.h"

#include <decaf/lang/Integer.h>
#include <activemq/exceptions/ActiveMQException.h>

using namespace activemq;
using namespace activemq::exceptions;
using namespace activemq::wireformat;
using namespace activemq::wireformat::openwire;
using namespace activemq::wireformat::openwire::utils;
using namespace decaf::io;
using namespace decaf::lang;

////////////////////////////////////////////////////////////////////////////////
std::string OpenwireStringSupport::readString( decaf::io::DataInputStream& dataIn )
    throw ( decaf::io::IOException ) {

    try {

        short utflen = dataIn.readShort();

        if( utflen > -1 ) {

            // Let the stream get us all that data.
            std::vector<unsigned char> value;
            value.resize( utflen );
            dataIn.readFully( value );

            std::vector<unsigned char> byteArr;
            byteArr.resize( utflen );

            int count = 0;
            for( unsigned int i = 0; i < value.size(); ++i ) {

                unsigned int z = (unsigned char) value[i];

                if( (z >= 0x0001) && (z <= 0x007F) )  {
                    byteArr[count++] = (unsigned char)z;
                } else if( (z >= 0x00C0) && (z <= 0x00DF) ) {
                    unsigned int y = (unsigned char) value[++i];
                    byteArr[count++] = (unsigned char)((z-192)*64 + (y-128));
                } else if ((z >= 0x00E0) && (z <= 0x00EF) ) {
                    unsigned int y = (unsigned char) value[++i];
                    unsigned int x = (unsigned char) value[++i];
                    byteArr[count++] = (unsigned char)((z-224)*4096 + (y-128)*64 + (x-128));
                } else if( (z >= 0x00F0) && (z <= 0x00F7) ) {
                    unsigned int y = (unsigned char) value[++i];
                    unsigned int x = (unsigned char) value[++i];
                    unsigned int w = (unsigned char) value[++i];
                    byteArr[count++] = (unsigned char)((z-240)*262144 + (y-128)*4096 + (x-128)*64 + (w-128));
                } else if( (z >= 0x00F8) && (z <= 0x00FB) ) {
                    unsigned int y = (unsigned char) value[++i];
                    unsigned int x = (unsigned char) value[++i];
                    unsigned int w = (unsigned char) value[++i];
                    unsigned int v = (unsigned char) value[++i];
                    byteArr[count++] = (unsigned char)((z-248)*16777216 + (y-128)*262144 + (x-128)*4096 + (w-128)*64 + (v-128));
                } else if( (z >= 0x00FC) && (z <= 0x00FD) ) {
                    unsigned int y = (unsigned char) value[++i];
                    unsigned int x = (unsigned char) value[++i];
                    unsigned int w = (unsigned char) value[++i];
                    unsigned int v = (unsigned char) value[++i];
                    unsigned int u = (unsigned char) value[++i];
                    byteArr[count++] = (unsigned char)((z-252)*1073741824 + (y-128)*16777216 + (x-128)*262144 + (w-128)*4096 + (v-128)*64 + (u-128));
                }
            }

            // C++ strings need a NULL terminator
            byteArr.push_back( '\0' );

            // Let the Compiler give us a string.
            return reinterpret_cast<const char*>( &byteArr[0] );
        }

        return "";
    }
    AMQ_CATCH_RETHROW( decaf::io::IOException )
    AMQ_CATCH_EXCEPTION_CONVERT( Exception, decaf::io::IOException )
    AMQ_CATCHALL_THROW( decaf::io::IOException )
}

////////////////////////////////////////////////////////////////////////////////
void OpenwireStringSupport::writeString( decaf::io::DataOutputStream& dataOut,
                                         const std::string* str )
                                            throw ( decaf::io::IOException ) {

    try {

        if( str != NULL ) {

            if( str->size() > 65536 ) {

                throw IOException(
                    __FILE__,
                    __LINE__,
                    ( std::string( "OpenwireStringSupport::writeString - Cannot marshall " ) +
                    "string longer than: 65536 characters, supplied string was: " +
                    Integer::toString( (int)str->size() ) + " characters long." ).c_str() );
            }

            unsigned short utflen = 0;
            unsigned int c, count = 0;

            std::string::const_iterator iter = str->begin();

            for(; iter != str->end(); ++iter ) {
                c = (unsigned char) *iter;
                if( (c >= 0x0001) && (c <= 0x007F) ) {
                    utflen++;
                } else if( c > 0x07FF ) {
                    utflen += 3;
                } else {
                    utflen += 2;
                }
            }

            dataOut.writeUnsignedShort( utflen );
            std::vector<unsigned char> byteArr;
            byteArr.resize( utflen );

            for( iter = str->begin(); iter != str->end(); ++iter ) {

                c = (unsigned char) *iter;
                if( (c >= 0x0001) && (c <= 0x007F) ) {
                    byteArr[count++] = (unsigned char)c;
                } else if( c <= 0x07FF ) {
                    byteArr[count++] = (unsigned char)( 192 + (c / 64));
                    byteArr[count++] = (unsigned char)( 128 + (c % 64));
                } else {
                    byteArr[count++] = (unsigned char)( 224 + (c / 4096));
                    byteArr[count++] = (unsigned char)( 192 + ((c / 64) % 64));
                    byteArr[count++] = (unsigned char)( 128 + (c % 64));
                }
            }

            dataOut.write( byteArr );

        } else {
            dataOut.writeShort( (short)-1 );
        }
    }
    AMQ_CATCH_RETHROW( decaf::io::IOException )
    AMQ_CATCH_EXCEPTION_CONVERT( Exception, decaf::io::IOException )
    AMQ_CATCHALL_THROW( decaf::io::IOException )
}
<commit_msg>https://issues.apache.org/activemq/browse/AMQCPP-232<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "OpenwireStringSupport.h"

#include <decaf/lang/Integer.h>
#include <activemq/exceptions/ActiveMQException.h>

using namespace activemq;
using namespace activemq::exceptions;
using namespace activemq::wireformat;
using namespace activemq::wireformat::openwire;
using namespace activemq::wireformat::openwire::utils;
using namespace decaf::io;
using namespace decaf::lang;

////////////////////////////////////////////////////////////////////////////////
std::string OpenwireStringSupport::readString( decaf::io::DataInputStream& dataIn )
    throw ( decaf::io::IOException ) {

    try {

        short utflen = dataIn.readShort();

        if( utflen > -1 )
        {
            // Let the stream get us all that data.
            std::vector<unsigned char> value;
            value.resize( utflen );
            dataIn.readFully( value );

            unsigned char c = 0;
            int count = 0;

            // x counts the number of 2-byte UTF8 sequences decoded
            int x = 0;

            while( count+x < utflen )
            {
                c = value[count+x];
                switch( c >> 4 )
                {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                        // 1-byte UTF8 encoding: 0xxxxxxx
                        value[count] = c;
                        count++;
                        break;
                    case 12:
                    case 13:
                        // 2-byte UTF8 encoding: 110X XXxx 10xx xxxx
                        // Bits set at 'X' means we have encountered a UTF8 encoded value
                        // greater than 255, which is not supported.
                        if( c & 0x1C ) {
                            throw IOException(
                                __FILE__,
                                __LINE__,
                                "OpenwireStringSupport::readString - Encoding not supported" );
                        }
                        // Place the decoded UTF8 character back into the value array
                        value[count] = ((c & 0x1F) << 6) | (value[count+x+1] & 0x3F);
                        count++;
                        x++;
                        break;
                    case 14:
                    default:
                    {
                        // 3-byte UTF8 encoding: 1110 xxxx  10xx xxxx  10xx xxxx
                        throw IOException(
                            __FILE__,
                            __LINE__,
                            "OpenwireStringSupport::readString - Encoding not supported" );
                    }
                }
            }

            // Let the Compiler give us a string.
            return std::string(reinterpret_cast<const char*>(&value[0]), count);
        }

        return "";
    }
    AMQ_CATCH_RETHROW( decaf::io::IOException )
    AMQ_CATCH_EXCEPTION_CONVERT( Exception, decaf::io::IOException )
    AMQ_CATCHALL_THROW( decaf::io::IOException )
}

////////////////////////////////////////////////////////////////////////////////
void OpenwireStringSupport::writeString( decaf::io::DataOutputStream& dataOut,
                                         const std::string* str )
                                         throw ( decaf::io::IOException ) {

    try {

        if( str != NULL ) {

            if( str->size() > 65536 ) {

                throw IOException(
                    __FILE__,
                    __LINE__,
                    ( std::string( "OpenwireStringSupport::writeString - Cannot marshall " ) +
                    "string longer than: 65536 characters, supplied string was: " +
                    Integer::toString( (int)str->size() ) + " characters long." ).c_str() );
            }

            unsigned short utflen = 0;
            int count = 0;
            unsigned char c;

            std::string::const_iterator iter = str->begin();

            for(; iter != str->end(); ++iter ) {
                c = *iter;
                if( c < 0x80 ) {
                    utflen++;
                } else {
                    utflen += 2;
                }
            }

            dataOut.writeUnsignedShort( utflen );
            std::vector<unsigned char> byteArr;
            byteArr.resize( utflen );

            for( iter = str->begin(); iter != str->end(); ++iter ) {

                c = *iter;
                if( c < 0x80 ) {
                    byteArr[count++] = (unsigned char)c;
                } else {
                    byteArr[count++] = (unsigned char)( 0xC0 | ( (c >> 6) & 0x1F) );
                    byteArr[count++] = (unsigned char)( 0x80 | ( (c >> 0) & 0x3F) );
                }
            }

            dataOut.write( byteArr );

        } else {
            dataOut.writeShort( (short)-1 );
        }
    }
    AMQ_CATCH_RETHROW( decaf::io::IOException )
    AMQ_CATCH_EXCEPTION_CONVERT( Exception, decaf::io::IOException )
    AMQ_CATCHALL_THROW( decaf::io::IOException )
}
<|endoftext|>


<commit_before>#include "wide_graph_with_pool.h"
#include "../src/transwarp.h"
#include <iostream>
#include <fstream>
#include <random>
#include <numeric>
#include <stack>
#include <list>
namespace tw = transwarp;

namespace {

using data_t = std::shared_ptr<std::vector<double>>;

data_t transform(data_t data) {
    std::uniform_real_distribution<double> dist(0.5, 1.5);
    std::mt19937 gen{static_cast<unsigned int>((*data)[0] * 1000.)};
    for (auto& v : *data) {
        v *= dist(gen);
    }
    return data;
}

data_t copy_transform(data_t data) {
    std::uniform_real_distribution<double> dist(0.5, 1.5);
    auto copy = std::make_shared<std::vector<double>>(*data);
    std::mt19937 gen{static_cast<unsigned int>((*data)[0] * 1000.)};
    for (auto& v : *copy) {
        v *= dist(gen);
    }
    return copy;
}

double mean(data_t data) {
    return std::accumulate(data->begin(), data->end(), 0.) / static_cast<double>(data->size());
}

struct graph {
    std::shared_ptr<tw::task<data_t>> input;
    std::shared_ptr<tw::task<double>> final;
};

std::shared_ptr<graph> make_graph() {
    auto input = tw::make_value_task(std::make_shared<std::vector<double>>());
    std::vector<std::shared_ptr<tw::task<data_t>>> parents;
    for (int i=0; i<8; ++i) {
        auto t = tw::make_task(tw::consume, copy_transform, input)->then(tw::consume, transform);
        parents.emplace_back(t);
    }
    auto final = tw::make_task(tw::consume, [](const std::vector<data_t>& parents) {
                                                double res = 0;
                                                for (const auto p : parents) {
                                                    res += mean(p);
                                                }
                                                return res / static_cast<double>(parents.size());
                                            }, parents);
    return std::make_shared<graph>(graph{input, final});
}

// One possible implementation of a graph pool
class graph_pool {
public:

    explicit
    graph_pool(std::size_t initial_size) {
        for (std::size_t i=0; i<initial_size; ++i) {
            ready_.push(make_graph());
        }
    }

    std::shared_ptr<graph> next_graph() {
        reclaim_finished_graphs();
        double_pool_size();
        auto g = ready_.top(); ready_.pop();
        running_.push_back(g);
        return g;
    }

private:

    void reclaim_finished_graphs() {
        if (ready_.empty()) {
            for (auto it = running_.begin(); it != running_.end();) {
                if ((*it)->final->has_result()) {
                    ready_.push(*it);
                    it = running_.erase(it);
                } else {
                    ++it;
                }
            }
        }
    }

    void double_pool_size() {
        if (ready_.empty()) {
            const auto pool_size = running_.size() + ready_.size();
            for (std::size_t i=0; i<pool_size; ++i) {
                ready_.push(make_graph());
            }
        }
    }

    std::stack<std::shared_ptr<graph>> ready_;
    std::list<std::shared_ptr<graph>> running_;
};

}

namespace examples {

// This example demonstrates the scheduling of an extra wide graph.
// Increase iterations and size and observe your CPU load.
// New data is scheduled as soon as possible by virtue of a graph pool.
void wide_graph_with_pool(std::ostream& os, std::size_t iterations, std::size_t size) {
    tw::parallel exec{8}; // thread pool with 8 threads

    // Output graph for visualization
    const auto graph = make_graph()->final->get_graph();
    std::ofstream("wide_graph_with_pool.dot") << tw::to_string(graph);

    // This is to generate random data
    std::uniform_int_distribution<std::size_t> dist(size, size * 10);
    std::mt19937 gen{1};

    // Pool of graphs with 16 initial graphs
    graph_pool pool{16};

    std::vector<std::shared_future<double>> futures;
    for (std::size_t i=0; i<iterations; ++i) {
        auto data = std::make_shared<std::vector<double>>(dist(gen), 1); // New data arrive
        auto g = pool.next_graph(); // Get the next available graph
        g->input->set_value(data);
        g->final->schedule_all(exec); // Schedule the graph
        futures.push_back(g->final->get_future()); // Collect the future
    }

    // Wait and print results
    for (auto& future : futures) {
        os << future.get() << std::endl;
    }
}

}

#ifndef UNITTEST
int main() {
    std::cout << "Running example: wide_graph_with_pool ..." << std::endl;
    examples::wide_graph_with_pool(std::cout);
}
#endif
<commit_msg>reuse transform function<commit_after>#include "wide_graph_with_pool.h"
#include "../src/transwarp.h"
#include <iostream>
#include <fstream>
#include <random>
#include <numeric>
#include <stack>
#include <list>
namespace tw = transwarp;

namespace {

using data_t = std::shared_ptr<std::vector<double>>;

data_t transform(data_t data) {
    std::uniform_real_distribution<double> dist(0.5, 1.5);
    std::mt19937 gen{static_cast<unsigned int>((*data)[0] * 1000.)};
    for (auto& v : *data) {
        v *= dist(gen);
    }
    return data;
}

data_t copy_transform(data_t data) {
    auto copy = std::make_shared<std::vector<double>>(*data);
    return transform(copy);
}

double mean(data_t data) {
    return std::accumulate(data->begin(), data->end(), 0.) / static_cast<double>(data->size());
}

struct graph {
    std::shared_ptr<tw::task<data_t>> input;
    std::shared_ptr<tw::task<double>> final;
};

std::shared_ptr<graph> make_graph() {
    auto input = tw::make_value_task(std::make_shared<std::vector<double>>());
    std::vector<std::shared_ptr<tw::task<data_t>>> parents;
    for (int i=0; i<8; ++i) {
        auto t = tw::make_task(tw::consume, copy_transform, input)->then(tw::consume, transform);
        parents.emplace_back(t);
    }
    auto final = tw::make_task(tw::consume, [](const std::vector<data_t>& parents) {
                                                double res = 0;
                                                for (const auto p : parents) {
                                                    res += mean(p);
                                                }
                                                return res / static_cast<double>(parents.size());
                                            }, parents);
    return std::make_shared<graph>(graph{input, final});
}

// One possible implementation of a graph pool
class graph_pool {
public:

    explicit
    graph_pool(std::size_t initial_size) {
        for (std::size_t i=0; i<initial_size; ++i) {
            ready_.push(make_graph());
        }
    }

    std::shared_ptr<graph> next_graph() {
        reclaim_finished_graphs();
        double_pool_size();
        auto g = ready_.top(); ready_.pop();
        running_.push_back(g);
        return g;
    }

private:

    void reclaim_finished_graphs() {
        if (ready_.empty()) {
            for (auto it = running_.begin(); it != running_.end();) {
                if ((*it)->final->has_result()) {
                    ready_.push(*it);
                    it = running_.erase(it);
                } else {
                    ++it;
                }
            }
        }
    }

    void double_pool_size() {
        if (ready_.empty()) {
            const auto pool_size = running_.size() + ready_.size();
            for (std::size_t i=0; i<pool_size; ++i) {
                ready_.push(make_graph());
            }
        }
    }

    std::stack<std::shared_ptr<graph>> ready_;
    std::list<std::shared_ptr<graph>> running_;
};

}

namespace examples {

// This example demonstrates the scheduling of an extra wide graph.
// Increase iterations and size and observe your CPU load.
// New data is scheduled as soon as possible by virtue of a graph pool.
void wide_graph_with_pool(std::ostream& os, std::size_t iterations, std::size_t size) {
    tw::parallel exec{8}; // thread pool with 8 threads

    // Output graph for visualization
    const auto graph = make_graph()->final->get_graph();
    std::ofstream("wide_graph_with_pool.dot") << tw::to_string(graph);

    // This is to generate random data
    std::uniform_int_distribution<std::size_t> dist(size, size * 10);
    std::mt19937 gen{1};

    // Pool of graphs with 16 initial graphs
    graph_pool pool{16};

    std::vector<std::shared_future<double>> futures;
    for (std::size_t i=0; i<iterations; ++i) {
        auto data = std::make_shared<std::vector<double>>(dist(gen), 1); // New data arrive
        auto g = pool.next_graph(); // Get the next available graph
        g->input->set_value(data);
        g->final->schedule_all(exec); // Schedule the graph
        futures.push_back(g->final->get_future()); // Collect the future
    }

    // Wait and print results
    for (auto& future : futures) {
        os << future.get() << std::endl;
    }
}

}

#ifndef UNITTEST
int main() {
    std::cout << "Running example: wide_graph_with_pool ..." << std::endl;
    examples::wide_graph_with_pool(std::cout);
}
#endif
<|endoftext|>