<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// packet_manager_test.cpp
//
// Identification: test/wire/packet_manager_test.cpp
//
// Copyright (c) 2016-17, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "common/harness.h"
#include "gtest/gtest.h"
#include "common/logger.h"
#include "wire/libevent_server.h"
#include <pqxx/pqxx> /* libpqxx is used to instantiate C++ client */

#define NUM_THREADS 1

namespace peloton {
namespace test {

//===--------------------------------------------------------------------===//
// Packet Manager Tests
//===--------------------------------------------------------------------===//

class PacketManagerTests : public PelotonTest {};

static void *LaunchServer(peloton::wire::LibeventServer libeventserver) {
  try {
    libeventserver.StartServer();
  } catch (peloton::ConnectionException exception) {
    LOG_INFO("[LaunchServer] exception in thread");
  }
  return NULL;
}

/**
 * Simple select query test
 */
static void *SimpleQueryTest(void *) {
  try {
    pqxx::connection C(
        "host=127.0.0.1 port=15721 user=postgres sslmode=disable");
    LOG_INFO("[SimpleQueryTest] Connected to %s", C.dbname());
    pqxx::work W(C);

    peloton::wire::LibeventSocket *conn =
        peloton::wire::LibeventServer::GetConn(
            peloton::wire::LibeventServer::recent_connfd);

    EXPECT_EQ(conn->pkt_manager.is_started, true);
    EXPECT_EQ(conn->state, peloton::wire::CONN_READ);
    // create table and insert some data
    W.exec("DROP TABLE IF EXISTS employee;");
    W.exec("CREATE TABLE employee(id INT, name VARCHAR(100));");
    W.exec("INSERT INTO employee VALUES (1, 'Han LI');");
    W.exec("INSERT INTO employee VALUES (2, 'Shaokun ZOU');");
    W.exec("INSERT INTO employee VALUES (3, 'Yilei CHU');");

    pqxx::result R = W.exec("SELECT name FROM employee where id=1;");

    EXPECT_EQ(R.size(), 1);
    LOG_INFO("[SimpleQueryTest] Found %lu employees", R.size());
    W.commit();
  } catch (const std::exception &e) {
    LOG_INFO("[SimpleQueryTest] Exception occurred");
  }

  LOG_INFO("[SimpleQueryTest] Client has closed");
  return NULL;
}

/**
 * named prepare statement without parameters
 * TODO: add prepare's parameters when parser team fix the bug
 */

static void *PrepareStatementTest(void *) {
  try {
    pqxx::connection C(
        "host=127.0.0.1 port=15721 user=postgres sslmode=disable");
    LOG_INFO("[PrepareStatementTest] Connected to %s", C.dbname());
    pqxx::work W(C);

    peloton::wire::LibeventSocket *conn =
        peloton::wire::LibeventServer::GetConn(
            peloton::wire::LibeventServer::recent_connfd);

    // create table and insert some data
    W.exec("DROP TABLE IF EXISTS employee;");
    W.exec("CREATE TABLE employee(id INT, name VARCHAR(100));");
    W.exec("INSERT INTO employee VALUES (1, 'Han LI');");
    W.exec("INSERT INTO employee VALUES (2, 'Shaokun ZOU');");
    W.exec("INSERT INTO employee VALUES (3, 'Yilei CHU');");

    // test prepare statement
    C.prepare("searchstmt","SELECT name FROM employee WHERE id=1;");
    // invocation as in variable binding
    pqxx::result R = W.prepared("searchstmt").exec();
    W.commit();

    // test prepared statement already in statement cache
//    LOG_INFO("[Prepare statement cache] %d",conn->pkt_manager.ExistCachedStatement("searchstmt"));
    EXPECT_TRUE(conn->pkt_manager.ExistCachedStatement("searchstmt"));

    LOG_INFO("Prepare statement search result:%lu",R.size());
  } catch (const std::exception &e) {
    LOG_INFO("[PrepareStatementTest] Exception occurred");
  }

  LOG_INFO("[PrepareStatementTest] Client has closed");
  return NULL;
}

/**
 * rollback test
 */
static void *RollbackTest(void *) {
  try {
    pqxx::connection C(
        "host=127.0.0.1 port=15721 user=postgres sslmode=disable");
    LOG_INFO("[RollbackTest] Connected to %s", C.dbname());
    pqxx::work W(C);

    peloton::wire::LibeventSocket *conn =
        peloton::wire::LibeventServer::GetConn(
            peloton::wire::LibeventServer::recent_connfd);

    EXPECT_EQ(conn->pkt_manager.is_started, true);
    EXPECT_EQ(conn->state, peloton::wire::CONN_READ);
    // create table and insert some data
    W.exec("DROP TABLE IF EXISTS employee;");
    W.exec("CREATE TABLE employee(id INT, name VARCHAR(100));");
    W.abort();

    // W.exec("INSERT INTO employee VALUES (1, 'Han LI');");
    // W.exec("INSERT INTO employee VALUES (2, 'Shaokun ZOU');");
    // W.exec("INSERT INTO employee VALUES (3, 'Yilei CHU');");

    pqxx::result R = W.exec("SELECT name FROM employee where id=1;");

    EXPECT_EQ(R.size(), 1);
    LOG_INFO("[RollbackTest] Found %lu employees", R.size());
    W.commit();
  } catch (const std::exception &e) {
    LOG_INFO("[RollbackTest] Exception occurred");
  }

  LOG_INFO("[RollbackTest] Client has closed");
  return NULL;
}

// /**
//  * Use std::thread to initiate peloton server and pqxx client in separate
//  * threads
//  * Simple query test to guarantee both sides run correctly
//  * Callback method to close server after client finishes
//  */
// TEST_F(PacketManagerTests, SimpleQueryTest) {
//   peloton::PelotonInit::Initialize();
//   LOG_INFO("Server initialized");
//   peloton::wire::LibeventServer libeventserver;
//   std::thread serverThread(LaunchServer, libeventserver);
//   while (!libeventserver.is_started) {
//     sleep(1);
//   }

//   /* server & client running correctly */
//   SimpleQueryTest(NULL);

//   /* TODO: monitor packet_manager's status when receiving prepare statement from
//    * client */
//   // PrepareStatementTest(NULL);

//   libeventserver.CloseServer();
//   serverThread.join();
//   LOG_INFO("Thread has joined");
//   peloton::PelotonInit::Shutdown();
//   LOG_INFO("Peloton has shut down\n");
// }

// TEST_F(PacketManagerTests, PrepareStatementTest) {
//   peloton::PelotonInit::Initialize();
//   LOG_INFO("Server initialized");
//   peloton::wire::LibeventServer libeventserver;
//   std::thread serverThread(LaunchServer, libeventserver);
//   while (!libeventserver.is_started) {
//     sleep(1);
//   }

//   PrepareStatementTest(NULL);

//   libeventserver.CloseServer();
//   serverThread.join();
//   LOG_INFO("Thread has joined");
//   peloton::PelotonInit::Shutdown();
//   LOG_INFO("Peloton has shut down\n");
// }

TEST_F(PacketManagerTests, RollbackTest) {
  peloton::PelotonInit::Initialize();
  LOG_INFO("Server initialized");
  peloton::wire::LibeventServer libeventserver;
  std::thread serverThread(LaunchServer, libeventserver);
  while (!libeventserver.is_started) {
    sleep(1);
  }

  RollbackTest(NULL);

  libeventserver.CloseServer();
  serverThread.join();
  LOG_INFO("Thread has joined");
  peloton::PelotonInit::Shutdown();
  LOG_INFO("Peloton has shut down\n");
}

}  // End test namespace
}  // End peloton namespace
<commit_msg>tweak rollback test<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// packet_manager_test.cpp
//
// Identification: test/wire/packet_manager_test.cpp
//
// Copyright (c) 2016-17, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "common/harness.h"
#include "gtest/gtest.h"
#include "common/logger.h"
#include "wire/libevent_server.h"
#include <pqxx/pqxx> /* libpqxx is used to instantiate C++ client */

#define NUM_THREADS 1

namespace peloton {
namespace test {

//===--------------------------------------------------------------------===//
// Packet Manager Tests
//===--------------------------------------------------------------------===//

class PacketManagerTests : public PelotonTest {};

static void *LaunchServer(peloton::wire::LibeventServer libeventserver) {
  try {
    libeventserver.StartServer();
  } catch (peloton::ConnectionException exception) {
    LOG_INFO("[LaunchServer] exception in thread");
  }
  return NULL;
}

/**
 * Simple select query test
 */
void *SimpleQueryTest(void *) {
  try {
    pqxx::connection C(
        "host=127.0.0.1 port=15721 user=postgres sslmode=disable");
    LOG_INFO("[SimpleQueryTest] Connected to %s", C.dbname());
    pqxx::work W(C);

    peloton::wire::LibeventSocket *conn =
        peloton::wire::LibeventServer::GetConn(
            peloton::wire::LibeventServer::recent_connfd);

    EXPECT_EQ(conn->pkt_manager.is_started, true);
    EXPECT_EQ(conn->state, peloton::wire::CONN_READ);
    // create table and insert some data
    W.exec("DROP TABLE IF EXISTS employee;");
    W.exec("CREATE TABLE employee(id INT, name VARCHAR(100));");
    W.exec("INSERT INTO employee VALUES (1, 'Han LI');");
    W.exec("INSERT INTO employee VALUES (2, 'Shaokun ZOU');");
    W.exec("INSERT INTO employee VALUES (3, 'Yilei CHU');");

    pqxx::result R = W.exec("SELECT name FROM employee where id=1;");

    EXPECT_EQ(R.size(), 1);
    LOG_INFO("[SimpleQueryTest] Found %lu employees", R.size());
    W.commit();
  } catch (const std::exception &e) {
    LOG_INFO("[SimpleQueryTest] Exception occurred");
  }

  LOG_INFO("[SimpleQueryTest] Client has closed");
  return NULL;
}

/**
 * named prepare statement without parameters
 * TODO: add prepare's parameters when parser team fix the bug
 */

void *PrepareStatementTest(void *) {
  try {
    pqxx::connection C(
        "host=127.0.0.1 port=15721 user=postgres sslmode=disable");
    LOG_INFO("[PrepareStatementTest] Connected to %s", C.dbname());
    pqxx::work W(C);

    peloton::wire::LibeventSocket *conn =
        peloton::wire::LibeventServer::GetConn(
            peloton::wire::LibeventServer::recent_connfd);

    // create table and insert some data
    W.exec("DROP TABLE IF EXISTS employee;");
    W.exec("CREATE TABLE employee(id INT, name VARCHAR(100));");
    W.exec("INSERT INTO employee VALUES (1, 'Han LI');");
    W.exec("INSERT INTO employee VALUES (2, 'Shaokun ZOU');");
    W.exec("INSERT INTO employee VALUES (3, 'Yilei CHU');");

    // test prepare statement
    C.prepare("searchstmt","SELECT name FROM employee WHERE id=1;");
    // invocation as in variable binding
    pqxx::result R = W.prepared("searchstmt").exec();
    W.commit();

    // test prepared statement already in statement cache
//    LOG_INFO("[Prepare statement cache] %d",conn->pkt_manager.ExistCachedStatement("searchstmt"));
    EXPECT_TRUE(conn->pkt_manager.ExistCachedStatement("searchstmt"));

    LOG_INFO("Prepare statement search result:%lu",R.size());
  } catch (const std::exception &e) {
    LOG_INFO("[PrepareStatementTest] Exception occurred");
  }

  LOG_INFO("[PrepareStatementTest] Client has closed");
  return NULL;
}

/**
 * rollback test
 * YINGJUN: rewrite wanted.
 */
void *RollbackTest(void *) {
  try {
    pqxx::connection C(
        "host=127.0.0.1 port=15721 user=postgres sslmode=disable");
    LOG_INFO("[RollbackTest] Connected to %s", C.dbname());
    pqxx::work W(C);

    peloton::wire::LibeventSocket *conn =
        peloton::wire::LibeventServer::GetConn(
            peloton::wire::LibeventServer::recent_connfd);

    EXPECT_EQ(conn->pkt_manager.is_started, true);
    EXPECT_EQ(conn->state, peloton::wire::CONN_READ);
    // create table and insert some data
    W.exec("DROP TABLE IF EXISTS employee;");
    W.exec("CREATE TABLE employee(id INT, name VARCHAR(100));");
    W.exec("INSERT INTO employee VALUES (1, 'Han LI');");

    W.abort();

    W.exec("INSERT INTO employee VALUES (2, 'Shaokun ZOU');");
    W.exec("INSERT INTO employee VALUES (3, 'Yilei CHU');");

    W.commit();

    // pqxx::result R = W.exec("SELECT name FROM employee where id=1;");

    // EXPECT_EQ(R.size(), 1);

    // LOG_INFO("[RollbackTest] Found %lu employees", R.size());
    // W.commit();

  } catch (const std::exception &e) {
    LOG_INFO("[RollbackTest] Exception occurred");
  }

  LOG_INFO("[RollbackTest] Client has closed");
  return NULL;
}

/**
 * Use std::thread to initiate peloton server and pqxx client in separate
 * threads
 * Simple query test to guarantee both sides run correctly
 * Callback method to close server after client finishes
 */
TEST_F(PacketManagerTests, SimpleQueryTest) {
  peloton::PelotonInit::Initialize();
  LOG_INFO("Server initialized");
  peloton::wire::LibeventServer libeventserver;
  std::thread serverThread(LaunchServer, libeventserver);
  while (!libeventserver.is_started) {
    sleep(1);
  }

  /* server & client running correctly */
  SimpleQueryTest(NULL);

  /* TODO: monitor packet_manager's status when receiving prepare statement from
   * client */
  // PrepareStatementTest(NULL);

  libeventserver.CloseServer();
  serverThread.join();
  LOG_INFO("Thread has joined");
  peloton::PelotonInit::Shutdown();
  LOG_INFO("Peloton has shut down\n");
}

TEST_F(PacketManagerTests, PrepareStatementTest) {
  peloton::PelotonInit::Initialize();
  LOG_INFO("Server initialized");
  peloton::wire::LibeventServer libeventserver;
  std::thread serverThread(LaunchServer, libeventserver);
  while (!libeventserver.is_started) {
    sleep(1);
  }

  PrepareStatementTest(NULL);

  libeventserver.CloseServer();
  serverThread.join();
  LOG_INFO("Thread has joined");
  peloton::PelotonInit::Shutdown();
  LOG_INFO("Peloton has shut down\n");
}

TEST_F(PacketManagerTests, RollbackTest) {
  peloton::PelotonInit::Initialize();
  LOG_INFO("Server initialized");
  peloton::wire::LibeventServer libeventserver;
  std::thread serverThread(LaunchServer, libeventserver);
  while (!libeventserver.is_started) {
    sleep(1);
  }

  RollbackTest(NULL);

  libeventserver.CloseServer();
  serverThread.join();
  LOG_INFO("Thread has joined");
  peloton::PelotonInit::Shutdown();
  LOG_INFO("Peloton has shut down\n");
}

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


<commit_before>/*
 * This file is part of the CN24 semantic segmentation software,
 * copyright (C) 2015 Clemens-Alexander Brust (ikosa dot de at gmail dot com).
 *
 * For licensing information, see the LICENSE file included with this project.
 */

#include <cn24.h>

#include <vector>
#include <string>
#include <cmath>

std::vector<std::string> test_layers = {
  "convolution(size=3x3 kernels=3 seed=5)",
  "convolution(size=3x3 stride=2x2 kernels=3 seed=5)",
  "convolution(size=3x3 group=3 kernels=9 seed=5)",
  "tanh","sigm","relu"
};

Conv::datum SimpleSumLoss(const Conv::Tensor& tensor) {
  Conv::datum sum = 0;

  for (unsigned int e = 0; e < tensor.elements(); e++) {
    const Conv::datum element = tensor.data_ptr_const()[e];
    sum += fabs(element);
  }

  return sum;
}

Conv::datum SimpleSumLoss(const std::vector<Conv::CombinedTensor*>& outputs) {
  Conv::datum sum = 0;

  for (unsigned int o = 0; o < outputs.size(); o++) {
    sum += SimpleSumLoss(outputs[o]->data);
  }

  return sum;
}

void SimpleSumLossGradient(const std::vector<Conv::CombinedTensor*>& outputs) {
  for (unsigned int o = 0; o < outputs.size(); o++) {
    Conv::Tensor& tensor = outputs[o]->data;
    Conv::Tensor& delta_tensor = outputs[o]->delta;
    for (unsigned int e = 0; e < tensor.elements(); e++) {
      const Conv::datum element = tensor.data_ptr_const()[e];
      const Conv::datum gradient = element > 0.0 ? 1.0 : -1.0;
      delta_tensor.data_ptr()[e] = gradient;
    }
  }
}

namespace Conv {
  bool DoGradientTest(Conv::Layer* layer, Conv::Tensor& data, Conv::Tensor& delta, std::vector<Conv::CombinedTensor*>& outputs, Conv::datum epsilon) {
    layer->FeedForward();
    SimpleSumLossGradient(outputs);
    layer->BackPropagate();

    unsigned int elements = data.elements();
    unsigned int okay = 0;

    // Weight gradient test
    for (unsigned int w = 0; w < data.elements(); w++) {
      const Conv::datum weight = data.data_ptr_const()[w];
      const Conv::datum gradient = delta.data_ptr_const()[w];

      // Using central diff
      data.data_ptr()[w] = weight + epsilon;
      layer->FeedForward();
      const Conv::datum forward_loss = SimpleSumLoss(outputs);

      data.data_ptr()[w] = weight - epsilon;
      layer->FeedForward();
      const Conv::datum backward_loss = SimpleSumLoss(outputs);

      const Conv::datum fd_gradient = (forward_loss - backward_loss) / (2.0 * epsilon);
      data.data_ptr()[w] = weight;

      const Conv::datum ratio = fd_gradient / gradient;
      if(ratio > 1.2 || ratio < 0.8) {
        LOGDEBUG << "Expected: " << gradient << ", FD Grad : " << fd_gradient;
        LOGDEBUG << "Ratio: " << ratio;
      } else {
        okay++;
      }
    }
    if(okay != elements) {
      LOGDEBUG << okay << " of " << elements << " gradients okay - " << std::setprecision(3) << 100.0 * (double)okay/(double)elements << "%";
      double success_rate = (double)okay/(double)elements;
      if(success_rate > 0.95)
        return true;
      else
        return false;
    } else {
      return true;
    }
  }
}

int main(int argc, char* argv[]) {
  Conv::System::Init();

  Conv::NetStatus net_status;
  net_status.SetIsTesting(true);

  unsigned int SAMPLES = 2, WIDTH = 7, HEIGHT = 7, MAPS = 3;
  Conv::datum epsilon = 0.005;

  bool test_failed = false;

  Conv::CombinedTensor input_data(SAMPLES, WIDTH, HEIGHT, MAPS);

  for (std::string& layer_descriptor : test_layers) {
    input_data.data.Clear(2.0);
    input_data.delta.Clear(0.0);

    LOGINFO << "Testing layer: " << layer_descriptor;
    Conv::Layer* layer = Conv::LayerFactory::ConstructLayer(layer_descriptor);
    if(layer == nullptr) {
      test_failed = true;
      LOGERROR << "        FAILED";
      continue;
    }

    LOGINFO << "    Description: " << layer->GetLayerDescription();

    LOGINFO << "    Creating outputs...";
    std::vector<Conv::CombinedTensor*> outputs;
    bool createoutputs_success = layer->CreateOutputs({&input_data}, outputs);
    if(!createoutputs_success) {
      test_failed = true;
      LOGERROR << "       FAILED";
      continue;
    }

    for(Conv::CombinedTensor* output : outputs) {
      LOGINFO << "        " << output->data;
    }

    LOGINFO << "    Connecting...";
    bool connect_success = layer->Connect({&input_data}, outputs, &net_status);
    if(!connect_success) {
      test_failed = true;
      LOGERROR << "        FAILED";
      continue;
    }

    layer->OnLayerConnect({});

    LOGINFO << "    Gradient test (weights)...";
    for(Conv::CombinedTensor* weights : layer->parameters()) {
      bool gradient_success = Conv::DoGradientTest(layer, weights->data, weights->delta, outputs, epsilon);
      if(!gradient_success) {
        test_failed = true;
        LOGERROR << "        FAILED";
        continue;
      }
    }

    LOGINFO << "    Gradient test (inputs)...";
    bool gradient_success = Conv::DoGradientTest(layer, input_data.data, input_data.delta, outputs, epsilon);
    if(!gradient_success) {
      test_failed = true;
      LOGERROR << "        FAILED";
      continue;
    }
  }

  LOGEND;
  return test_failed ? -1 : 0;
}<commit_msg>SingleLayerGradientTest: Added more random initializations for input data tests<commit_after>/*
 * This file is part of the CN24 semantic segmentation software,
 * copyright (C) 2015 Clemens-Alexander Brust (ikosa dot de at gmail dot com).
 *
 * For licensing information, see the LICENSE file included with this project.
 */

#include <cn24.h>

#include <vector>
#include <string>
#include <cmath>
#include <random>

// TEST SETUP
std::vector<std::string> test_layers_noseed = {
  "convolution(size=3x3 kernels=3)",
  "convolution(size=3x3 stride=2x2 kernels=3)",
  "convolution(size=3x3 group=3 kernels=9)",
  "tanh","sigm","relu"
};

unsigned int SAMPLES = 2, WIDTH = 8, HEIGHT = 7, MAPS = 3;
unsigned int SEEDS = 3;
Conv::datum epsilon = 0.005;

// UTILITIES
Conv::datum SimpleSumLoss(const Conv::Tensor& tensor) {
  Conv::datum sum = 0;

  for (unsigned int e = 0; e < tensor.elements(); e++) {
    const Conv::datum element = tensor.data_ptr_const()[e];
    sum += fabs(element);
  }

  return sum;
}

Conv::datum SimpleSumLoss(const std::vector<Conv::CombinedTensor*>& outputs) {
  Conv::datum sum = 0;

  for (unsigned int o = 0; o < outputs.size(); o++) {
    sum += SimpleSumLoss(outputs[o]->data);
  }

  return sum;
}

void SimpleSumLossGradient(const std::vector<Conv::CombinedTensor*>& outputs) {
  for (unsigned int o = 0; o < outputs.size(); o++) {
    Conv::Tensor& tensor = outputs[o]->data;
    Conv::Tensor& delta_tensor = outputs[o]->delta;
    for (unsigned int e = 0; e < tensor.elements(); e++) {
      const Conv::datum element = tensor.data_ptr_const()[e];
      const Conv::datum gradient = element > 0.0 ? 1.0 : -1.0;
      delta_tensor.data_ptr()[e] = gradient;
    }
  }
}

namespace Conv {
  bool DoGradientTest(Conv::Layer* layer, Conv::Tensor& data, Conv::Tensor& delta, std::vector<Conv::CombinedTensor*>& outputs, Conv::datum epsilon) {
    layer->FeedForward();
    SimpleSumLossGradient(outputs);
    layer->BackPropagate();

    unsigned int elements = data.elements();
    unsigned int okay = 0;

    // Weight gradient test
    for (unsigned int w = 0; w < data.elements(); w++) {
      const Conv::datum weight = data.data_ptr_const()[w];
      const Conv::datum gradient = delta.data_ptr_const()[w];

      // Using central diff
      data.data_ptr()[w] = weight + epsilon;
      layer->FeedForward();
      const Conv::datum forward_loss = SimpleSumLoss(outputs);

      data.data_ptr()[w] = weight - epsilon;
      layer->FeedForward();
      const Conv::datum backward_loss = SimpleSumLoss(outputs);

      const Conv::datum fd_gradient = (forward_loss - backward_loss) / (2.0 * epsilon);
      data.data_ptr()[w] = weight;

      const Conv::datum ratio = fd_gradient / gradient;
      if(ratio > 1.2 || ratio < 0.8) {
        LOGDEBUG << "Expected: " << gradient << ", FD Grad : " << fd_gradient;
        LOGDEBUG << "Ratio: " << ratio;
      } else {
        okay++;
      }
    }
    if(okay != elements) {
      LOGDEBUG << okay << " of " << elements << " gradients okay - " << std::setprecision(3) << 100.0 * (double)okay/(double)elements << "%";
      double success_rate = (double)okay/(double)elements;
      if(success_rate > 0.95)
        return true;
      else
        return false;
    } else {
      return true;
    }
  }
}

int main(int argc, char* argv[]) {
  Conv::System::Init();

  std::mt19937 seed_generator(93023);
  std::uniform_real_distribution<Conv::datum> dist(-1.0, 1.0);

  Conv::NetStatus net_status;
  net_status.SetIsTesting(true);

  bool test_failed = false;

  Conv::CombinedTensor input_data(SAMPLES, WIDTH, HEIGHT, MAPS);

  std::vector<std::string> test_layers;

  // Inject random seeds
  for (std::string& layer_descriptor : test_layers_noseed) {
    for(unsigned int i = 0; i < SEEDS; i++) {
      std::string injected_descriptor = Conv::LayerFactory::InjectSeed(layer_descriptor, seed_generator());
      test_layers.push_back(injected_descriptor);
    }
  }

  for (std::string& layer_descriptor : test_layers) {
    for(unsigned int e = 0; e < input_data.data.elements(); e++) {
      input_data.data.data_ptr()[e] = dist(seed_generator);
    }
    input_data.data.Clear(2.0);
    input_data.delta.Clear(0.0);

    LOGINFO << "Testing layer: " << layer_descriptor;
    Conv::Layer* layer = Conv::LayerFactory::ConstructLayer(layer_descriptor);
    if(layer == nullptr) {
      test_failed = true;
      LOGERROR << "        FAILED";
      continue;
    }

    LOGINFO << "    Description: " << layer->GetLayerDescription();

    LOGINFO << "    Creating outputs...";
    std::vector<Conv::CombinedTensor*> outputs;
    bool createoutputs_success = layer->CreateOutputs({&input_data}, outputs);
    if(!createoutputs_success) {
      test_failed = true;
      LOGERROR << "       FAILED";
      continue;
    }

    for(Conv::CombinedTensor* output : outputs) {
      LOGINFO << "        " << output->data;
    }

    LOGINFO << "    Connecting...";
    bool connect_success = layer->Connect({&input_data}, outputs, &net_status);
    if(!connect_success) {
      test_failed = true;
      LOGERROR << "        FAILED";
      continue;
    }

    layer->OnLayerConnect({});

    LOGINFO << "    Gradient test (weights)...";
    for(Conv::CombinedTensor* weights : layer->parameters()) {
      bool gradient_success = Conv::DoGradientTest(layer, weights->data, weights->delta, outputs, epsilon);
      if(!gradient_success) {
        test_failed = true;
        LOGERROR << "        FAILED";
        continue;
      }
    }

    LOGINFO << "    Gradient test (inputs)...";
    bool gradient_success = Conv::DoGradientTest(layer, input_data.data, input_data.delta, outputs, epsilon);
    if(!gradient_success) {
      test_failed = true;
      LOGERROR << "        FAILED";
      continue;
    }
  }

  LOGEND;
  return test_failed ? -1 : 0;
}<|endoftext|>


<commit_before>// ---------------------------------------------------------------------
//
// Copyright (C) 2015 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, redistribute
// it, and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE at
// the top level of the deal.II distribution.
//
// ---------------------------------------------------------------------

// check Table<2,double> with elements numbers::signaling_nan<double>
//
// the test only checks that the function can be called. It would have
// been nicer to output the tensors (which would also verify the
// correct output type, as well as that indeed *each* element is
// correctly filled), but outputting a sNaN triggers a floating point
// exception as well

#include "../tests.h"
#include <deal.II/base/logstream.h>
#include <deal.II/base/signaling_nan.h>
#include <deal.II/base/table.h>
#include <fstream>
#include <iomanip>
#include <limits>
#include <fenv.h>

template <typename T>
void check ()
{
  Table<2,T> t;
  const T x = numbers::signaling_nan<double>();
  const T array[6] = { x,x,x,x,x,x };

  t.reinit (2,3, &x);

  deallog << "OK" << std::endl;
}

int main ()
{
  std::ofstream logfile("output");
  deallog << std::setprecision(3);
  deallog.attach(logfile);
  deallog.depth_console(0);
  deallog.threshold_double(1.e-10);

  check<float> ();
  check<double> ();

  return 0;
}

<commit_msg>Fix wrong reference to variable in test.<commit_after>// ---------------------------------------------------------------------
//
// Copyright (C) 2015 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, redistribute
// it, and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE at
// the top level of the deal.II distribution.
//
// ---------------------------------------------------------------------

// check Table<2,double> with elements numbers::signaling_nan<double>
//
// the test only checks that the function can be called. It would have
// been nicer to output the tensors (which would also verify the
// correct output type, as well as that indeed *each* element is
// correctly filled), but outputting a sNaN triggers a floating point
// exception as well

#include "../tests.h"
#include <deal.II/base/logstream.h>
#include <deal.II/base/signaling_nan.h>
#include <deal.II/base/table.h>
#include <fstream>
#include <iomanip>
#include <limits>
#include <fenv.h>

template <typename T>
void check ()
{
  Table<2,T> t;

  t.reinit (2,3);
  t.fill (numbers::signaling_nan<T>());

  deallog << "OK" << std::endl;
}

int main ()
{
  std::ofstream logfile("output");
  deallog << std::setprecision(3);
  deallog.attach(logfile);
  deallog.depth_console(0);
  deallog.threshold_double(1.e-10);

  check<float> ();
  check<double> ();

  return 0;
}

<|endoftext|>


<commit_before>#include <QtCore/QDebug>
#include <QtCore/QTimer>

#include <QtDBus/QtDBus>

#include <QtTest/QtTest>

#include <TelepathyQt4/Connection>
#include <TelepathyQt4/Contact>
#include <TelepathyQt4/ContactManager>
#include <TelepathyQt4/PendingReady>
#include <TelepathyQt4/Debug>

#include <telepathy-glib/debug.h>

#include <tests/lib/contactlist/conn.h>
#include <tests/lib/test.h>

using namespace Tp;

class TestConnRosterGroups : public Test
{
    Q_OBJECT

public:
    TestConnRosterGroups(QObject *parent = 0)
        : Test(parent), mConnService(0), mContactsAddedToGroup(0)
    { }

protected Q_SLOTS:
    void onGroupAdded(const QString &group);
    void onContactAddedToGroup(const QString &group);
    void expectConnInvalidated();

private Q_SLOTS:
    void initTestCase();
    void init();

    void testRosterGroups();

    void cleanup();
    void cleanupTestCase();

private:
    QString mConnName, mConnPath;
    ExampleContactListConnection *mConnService;
    ConnectionPtr mConn;

    QString mGroupAdded;
    int mContactsAddedToGroup;
};

void TestConnRosterGroups::onGroupAdded(const QString &group)
{
    mGroupAdded = group;
    mLoop->exit(0);
}

void TestConnRosterGroups::onContactAddedToGroup(const QString &group)
{
    mContactsAddedToGroup++;
    mLoop->exit(0);
}

void TestConnRosterGroups::expectConnInvalidated()
{
    mLoop->exit(0);
}

void TestConnRosterGroups::initTestCase()
{
    initTestCaseImpl();

    g_type_init();
    g_set_prgname("conn-basics");
    tp_debug_set_flags("all");
    dbus_g_bus_get(DBUS_BUS_STARTER, 0);

    gchar *name;
    gchar *connPath;
    GError *error = 0;

    mConnService = EXAMPLE_CONTACT_LIST_CONNECTION(g_object_new(
            EXAMPLE_TYPE_CONTACT_LIST_CONNECTION,
            "account", "me@example.com",
            "protocol", "contactlist",
            0));
    QVERIFY(mConnService != 0);
    QVERIFY(tp_base_connection_register(TP_BASE_CONNECTION(mConnService),
                "contacts", &name, &connPath, &error));
    QVERIFY(error == 0);

    QVERIFY(name != 0);
    QVERIFY(connPath != 0);

    mConnName = name;
    mConnPath = connPath;

    g_free(name);
    g_free(connPath);
}

void TestConnRosterGroups::init()
{
    initImpl();

    mConn = Connection::create(mConnName, mConnPath);

    QVERIFY(connect(mConn->requestConnect(),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mConn->isReady(), true);
    QCOMPARE(mConn->status(), static_cast<uint>(Connection::StatusConnected));

}

void TestConnRosterGroups::testRosterGroups()
{
    Features features = Features() << Connection::FeatureRoster << Connection::FeatureRosterGroups;
    QVERIFY(connect(mConn->becomeReady(features),
            SIGNAL(finished(Tp::PendingOperation*)),
            SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mConn->isReady(features), true);

    ContactManager *contactManager = mConn->contactManager();

    QStringList expectedGroups;
    expectedGroups << "Cambridge" << "Francophones" << "Montreal";
    expectedGroups.sort();
    QStringList groups = contactManager->allKnownGroups();
    groups.sort();
    QCOMPARE(groups, expectedGroups);

    // Cambridge
    {
        QStringList expectedContacts;
        expectedContacts << "geraldine@example.com" << "helen@example.com"
            << "guillaume@example.com" << "sjoerd@example.com";
        expectedContacts.sort();
        QStringList contacts;
        foreach (const ContactPtr &contact, contactManager->groupContacts("Cambridge")) {
            contacts << contact->id();
        }
        contacts.sort();
        QCOMPARE(contacts, expectedContacts);
    }

    // Francophones
    {
        QStringList expectedContacts;
        expectedContacts << "olivier@example.com" << "geraldine@example.com"
            << "guillaume@example.com";
        expectedContacts.sort();
        QStringList contacts;
        foreach (const ContactPtr &contact, contactManager->groupContacts("Francophones")) {
            contacts << contact->id();
        }
        contacts.sort();
        QCOMPARE(contacts, expectedContacts);
    }

    // Montreal
    {
        QStringList expectedContacts;
        expectedContacts << "olivier@example.com";
        expectedContacts.sort();
        QStringList contacts;
        foreach (const ContactPtr &contact, contactManager->groupContacts("Montreal")) {
            contacts << contact->id();
        }
        contacts.sort();
        QCOMPARE(contacts, expectedContacts);
    }

    QString group("foo");
    QVERIFY(contactManager->groupContacts(group).isEmpty());

    // add group foo
    QVERIFY(connect(contactManager,
                    SIGNAL(groupAdded(const QString&)),
                    SLOT(onGroupAdded(const QString&))));
    QVERIFY(connect(contactManager->addGroup(group),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    while (mGroupAdded.isEmpty()) {
        QCOMPARE(mLoop->exec(), 0);
    }
    QCOMPARE(mGroupAdded, group);

    expectedGroups << group;
    expectedGroups.sort();
    groups = contactManager->allKnownGroups();
    groups.sort();
    QCOMPARE(groups, expectedGroups);

    // add Montreal contacts to group foo
    Contacts contacts = contactManager->groupContacts("Montreal");
    foreach (const ContactPtr &contact, contacts) {
        QVERIFY(connect(contact.data(),
                        SIGNAL(addedToGroup(const QString&)),
                        SLOT(onContactAddedToGroup(const QString&))));
    }
    QVERIFY(connect(contactManager->groupAddContacts(group, contacts.toList()),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    while (mContactsAddedToGroup != contacts.size()) {
        QCOMPARE(mLoop->exec(), 0);
    }
    foreach (const ContactPtr &contact, contacts) {
        QVERIFY(contact->groups().contains(group));
    }
}

void TestConnRosterGroups::cleanup()
{
    if (mConn) {
        // Disconnect and wait for the readiness change
        QVERIFY(connect(mConn->requestDisconnect(),
                        SIGNAL(finished(Tp::PendingOperation*)),
                        SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
        QCOMPARE(mLoop->exec(), 0);

        if (mConn->isValid()) {
            QVERIFY(connect(mConn.data(),
                            SIGNAL(invalidated(Tp::DBusProxy *,
                                               const QString &, const QString &)),
                            SLOT(expectConnInvalidated())));
            QCOMPARE(mLoop->exec(), 0);
        }
    }

    cleanupImpl();
}

void TestConnRosterGroups::cleanupTestCase()
{
    if (mConnService != 0) {
        g_object_unref(mConnService);
        mConnService = 0;
    }

    cleanupTestCaseImpl();
}

QTEST_MAIN(TestConnRosterGroups)
#include "_gen/conn-roster-groups.cpp.moc.hpp"
<commit_msg>roster-groups example: Added tests for removing contacts from a contact list group.<commit_after>#include <QtCore/QDebug>
#include <QtCore/QTimer>

#include <QtDBus/QtDBus>

#include <QtTest/QtTest>

#include <TelepathyQt4/Connection>
#include <TelepathyQt4/Contact>
#include <TelepathyQt4/ContactManager>
#include <TelepathyQt4/PendingReady>
#include <TelepathyQt4/Debug>

#include <telepathy-glib/debug.h>

#include <tests/lib/contactlist/conn.h>
#include <tests/lib/test.h>

using namespace Tp;

class TestConnRosterGroups : public Test
{
    Q_OBJECT

public:
    TestConnRosterGroups(QObject *parent = 0)
        : Test(parent), mConnService(0),
          mContactsAddedToGroup(0), mContactsRemovedFromGroup(0)
    { }

protected Q_SLOTS:
    void onGroupAdded(const QString &group);
    void onContactAddedToGroup(const QString &group);
    void onContactRemovedFromGroup(const QString &group);
    void expectConnInvalidated();

private Q_SLOTS:
    void initTestCase();
    void init();

    void testRosterGroups();

    void cleanup();
    void cleanupTestCase();

private:
    QString mConnName, mConnPath;
    ExampleContactListConnection *mConnService;
    ConnectionPtr mConn;

    QString mGroupAdded;
    int mContactsAddedToGroup;
    int mContactsRemovedFromGroup;
};

void TestConnRosterGroups::onGroupAdded(const QString &group)
{
    mGroupAdded = group;
    mLoop->exit(0);
}

void TestConnRosterGroups::onContactAddedToGroup(const QString &group)
{
    mContactsAddedToGroup++;
    mLoop->exit(0);
}

void TestConnRosterGroups::onContactRemovedFromGroup(const QString &group)
{
    mContactsRemovedFromGroup++;
    mLoop->exit(0);
}

void TestConnRosterGroups::expectConnInvalidated()
{
    mLoop->exit(0);
}

void TestConnRosterGroups::initTestCase()
{
    initTestCaseImpl();

    g_type_init();
    g_set_prgname("conn-basics");
    tp_debug_set_flags("all");
    dbus_g_bus_get(DBUS_BUS_STARTER, 0);

    gchar *name;
    gchar *connPath;
    GError *error = 0;

    mConnService = EXAMPLE_CONTACT_LIST_CONNECTION(g_object_new(
            EXAMPLE_TYPE_CONTACT_LIST_CONNECTION,
            "account", "me@example.com",
            "protocol", "contactlist",
            0));
    QVERIFY(mConnService != 0);
    QVERIFY(tp_base_connection_register(TP_BASE_CONNECTION(mConnService),
                "contacts", &name, &connPath, &error));
    QVERIFY(error == 0);

    QVERIFY(name != 0);
    QVERIFY(connPath != 0);

    mConnName = name;
    mConnPath = connPath;

    g_free(name);
    g_free(connPath);
}

void TestConnRosterGroups::init()
{
    initImpl();

    mConn = Connection::create(mConnName, mConnPath);

    QVERIFY(connect(mConn->requestConnect(),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mConn->isReady(), true);
    QCOMPARE(mConn->status(), static_cast<uint>(Connection::StatusConnected));

}

void TestConnRosterGroups::testRosterGroups()
{
    Features features = Features() << Connection::FeatureRoster << Connection::FeatureRosterGroups;
    QVERIFY(connect(mConn->becomeReady(features),
            SIGNAL(finished(Tp::PendingOperation*)),
            SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    QCOMPARE(mConn->isReady(features), true);

    ContactManager *contactManager = mConn->contactManager();

    QStringList expectedGroups;
    expectedGroups << "Cambridge" << "Francophones" << "Montreal";
    expectedGroups.sort();
    QStringList groups = contactManager->allKnownGroups();
    groups.sort();
    QCOMPARE(groups, expectedGroups);

    // Cambridge
    {
        QStringList expectedContacts;
        expectedContacts << "geraldine@example.com" << "helen@example.com"
            << "guillaume@example.com" << "sjoerd@example.com";
        expectedContacts.sort();
        QStringList contacts;
        foreach (const ContactPtr &contact, contactManager->groupContacts("Cambridge")) {
            contacts << contact->id();
        }
        contacts.sort();
        QCOMPARE(contacts, expectedContacts);
    }

    // Francophones
    {
        QStringList expectedContacts;
        expectedContacts << "olivier@example.com" << "geraldine@example.com"
            << "guillaume@example.com";
        expectedContacts.sort();
        QStringList contacts;
        foreach (const ContactPtr &contact, contactManager->groupContacts("Francophones")) {
            contacts << contact->id();
        }
        contacts.sort();
        QCOMPARE(contacts, expectedContacts);
    }

    // Montreal
    {
        QStringList expectedContacts;
        expectedContacts << "olivier@example.com";
        expectedContacts.sort();
        QStringList contacts;
        foreach (const ContactPtr &contact, contactManager->groupContacts("Montreal")) {
            contacts << contact->id();
        }
        contacts.sort();
        QCOMPARE(contacts, expectedContacts);
    }

    QString group("foo");
    QVERIFY(contactManager->groupContacts(group).isEmpty());

    // add group foo
    QVERIFY(connect(contactManager,
                    SIGNAL(groupAdded(const QString&)),
                    SLOT(onGroupAdded(const QString&))));
    QVERIFY(connect(contactManager->addGroup(group),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    while (mGroupAdded.isEmpty()) {
        QCOMPARE(mLoop->exec(), 0);
    }
    QCOMPARE(mGroupAdded, group);

    expectedGroups << group;
    expectedGroups.sort();
    groups = contactManager->allKnownGroups();
    groups.sort();
    QCOMPARE(groups, expectedGroups);

    // add Montreal contacts to group foo
    Contacts contacts = contactManager->groupContacts("Montreal");
    foreach (const ContactPtr &contact, contacts) {
        QVERIFY(connect(contact.data(),
                        SIGNAL(addedToGroup(const QString&)),
                        SLOT(onContactAddedToGroup(const QString&))));
    }
    QVERIFY(connect(contactManager->groupAddContacts(group, contacts.toList()),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    while (mContactsAddedToGroup != contacts.size()) {
        QCOMPARE(mLoop->exec(), 0);
    }
    foreach (const ContactPtr &contact, contacts) {
        QVERIFY(contact->groups().contains(group));
    }

    // remove all contacts from group foo
    contacts = contactManager->groupContacts(group);
    foreach (const ContactPtr &contact, contacts) {
        QVERIFY(connect(contact.data(),
                        SIGNAL(removedFromGroup(const QString&)),
                        SLOT(onContactRemovedFromGroup(const QString&))));
    }
    QVERIFY(connect(contactManager->groupRemoveContacts(group, contacts.toList()),
                    SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
    QCOMPARE(mLoop->exec(), 0);
    while (mContactsRemovedFromGroup != contacts.size()) {
        QCOMPARE(mLoop->exec(), 0);
    }
    foreach (const ContactPtr &contact, contacts) {
        QVERIFY(!contact->groups().contains(group));
    }
}

void TestConnRosterGroups::cleanup()
{
    if (mConn) {
        // Disconnect and wait for the readiness change
        QVERIFY(connect(mConn->requestDisconnect(),
                        SIGNAL(finished(Tp::PendingOperation*)),
                        SLOT(expectSuccessfulCall(Tp::PendingOperation*))));
        QCOMPARE(mLoop->exec(), 0);

        if (mConn->isValid()) {
            QVERIFY(connect(mConn.data(),
                            SIGNAL(invalidated(Tp::DBusProxy *,
                                               const QString &, const QString &)),
                            SLOT(expectConnInvalidated())));
            QCOMPARE(mLoop->exec(), 0);
        }
    }

    cleanupImpl();
}

void TestConnRosterGroups::cleanupTestCase()
{
    if (mConnService != 0) {
        g_object_unref(mConnService);
        mConnService = 0;
    }

    cleanupTestCaseImpl();
}

QTEST_MAIN(TestConnRosterGroups)
#include "_gen/conn-roster-groups.cpp.moc.hpp"
<|endoftext|>


<commit_before>/* Rapicorn
 * Copyright (C) 2005 Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * A copy of the GNU Lesser General Public License should ship along
 * with this library; if not, see http://www.gnu.org/copyleft/.
 */
#include "image.hh"
#include "painter.hh"
#include "factory.hh"
#include <errno.h>

namespace Rapicorn {

const PropertyList&
Image::list_properties()
{
  static Property *properties[] = {
    MakeProperty (Image, image_file, _("Image Filename"), _("Load an image from a file, only PNG images can be loaded."), "w"),
    MakeProperty (Image, stock_pixmap, _("Stock Image"), _("Load an image from stock, providing a stock name."), "w"),
  };
  static const PropertyList property_list (properties, ItemImpl::list_properties());
  return property_list;
}

static const uint8* get_broken16_pixdata (void);

static cairo_surface_t*
cairo_surface_from_pixmap (Pixmap &pixmap)
{
  int stride = 0;
  uint32 *data = pixmap.data (&stride);
  cairo_surface_t *isurface =
    cairo_image_surface_create_for_data ((unsigned char*) data,
                                         CAIRO_FORMAT_ARGB32,
                                         pixmap.width(),
                                         pixmap.height(),
                                         stride);
  return_val_if_fail (CAIRO_STATUS_SUCCESS == cairo_surface_status (isurface), NULL);
  return isurface;
}

class ImageImpl : public virtual ItemImpl, public virtual Image {
  Pixmap           *m_pixmap;
  int               m_xoffset, m_yoffset;
public:
  explicit ImageImpl() :
    m_pixmap (NULL),
    m_xoffset (0),
    m_yoffset (0)
  {}
  void
  reset ()
  {
    m_xoffset = m_yoffset = 0;
    if (m_pixmap)
      {
        Pixmap *op = m_pixmap;
        m_pixmap = NULL;
        unref (op);
      }
    invalidate();
  }
  ~ImageImpl()
  {}
  virtual void
  pixmap (Pixmap *pixmap)
  {
    if (pixmap)
      ref_sink (pixmap);
    reset();
    m_pixmap = pixmap;
  }
  virtual Pixmap*
  pixmap (void)
  {
    return m_pixmap;
  }
  virtual void
  stock_pixmap (const String &stock_name)
  {
    Pixmap *pixmap = Pixmap::stock (stock_name);
    int saved = errno;
    if (!pixmap)
      {
        pixmap = Pixmap::pixstream (get_broken16_pixdata());
        assert (pixmap);
      }
    ref_sink (pixmap);
    this->pixmap (pixmap);
    unref (pixmap);
    errno = saved;
  }
  virtual void
  image_file (const String &filename)
  {
    Pixmap *pixmap = Pixmap::load_png (filename, true);
    int saved = errno;
    if (!pixmap)
      {
        pixmap = Pixmap::pixstream (get_broken16_pixdata());
        assert (pixmap);
      }
    ref_sink (pixmap);
    this->pixmap (pixmap);
    unref (pixmap);
    errno = saved;
  }
protected:
  virtual void
  size_request (Requisition &requisition)
  {
    if (m_pixmap)
      {
        requisition.width += m_pixmap->width();
        requisition.height += m_pixmap->height();
      }
  }
  virtual void
  size_allocate (Allocation area, bool changed)
  {
    if (m_pixmap)
      {
        m_xoffset = iround (0.5 * (area.width - m_pixmap->width()));
        m_yoffset = iround (0.5 * (area.height - m_pixmap->height()));
      }
    else
      m_xoffset = m_yoffset = 0;
  }
public:
  virtual void
  render (RenderContext &rcontext, const Rect &rect)
  {
    if (m_pixmap)
      {
        const Allocation &area = allocation();
        int ix = iround (area.x + m_xoffset), iy = iround (area.y + m_yoffset);
        int ih = m_pixmap->height();
        Rect erect = Rect (ix, iy, m_pixmap->width(), ih);
        erect.intersect (rect);
        cairo_t *cr = cairo_context (rcontext, erect);
        cairo_surface_t *isurface = cairo_surface_from_pixmap (*m_pixmap);
        cairo_set_source_surface (cr, isurface, 0, 0); // (ix,iy) are set in the matrix below
        cairo_matrix_t matrix;
        cairo_matrix_init_identity (&matrix);
        cairo_matrix_translate (&matrix, -ix, iy + m_pixmap->height());
        cairo_matrix_scale (&matrix, 1, -1);
        cairo_pattern_set_matrix (cairo_get_source (cr), &matrix);
        cairo_paint (cr);
        cairo_surface_destroy (isurface);
      }
  }
};
static const ItemFactory<ImageImpl> image_factory ("Rapicorn::Factory::Image");

static const uint8*
get_broken16_pixdata (void)
{
  /* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
#ifdef __SUNPRO_C
#pragma align 4 (broken16_pixdata)
#endif
#ifdef __GNUC__
  static const uint8 broken16_pixdata[] __attribute__ ((__aligned__ (4))) =
#else
    static const uint8 broken16_pixdata[] =
#endif
    { ""
      /* Pixbuf magic (0x47646b50) */
      "GdkP"
      /* length: header (24) + pixel_data (485) */
      "\0\0\1\375"
      /* pixdata_type (0x2010002) */
      "\2\1\0\2"
      /* rowstride (64) */
      "\0\0\0@"
      /* width (16) */
      "\0\0\0\20"
      /* height (16) */
      "\0\0\0\20"
      /* pixel_data: */
      "\221\0\0\0\0\203\0\0\0\377\2>\0\10\377\0\0\0\377\202\0\0\0\0\1\253\0"
      "\30\\\203\0\0\0\377\2\0\0\0\177\0\0\0\77\203\0\0\0\0\1\0\0\0\377\202"
      "\377\377\377\377\2\377r\205\377\377Jc\262\202\0\0\0\0\7\377D_\301\377"
      "\201\222\377\377\377\377\377\0\0\0\377\300\300\300\377\0\0\0\177\0\0"
      "\0\77\202\0\0\0\0\1\0\0\0\377\202\377\377\377\377\2\377\"A\377\377Kd"
      "D\202\0\0\0\0\7\377\32;\367\377\317\325\377\377\377\377\377\0\0\0\377"
      "\377\377\377\377\300\300\300\377\0\0\0\177\202\0\0\0\0\4\0\0\0\377\377"
      "\377\377\377\377\324\332\377\377\25""6\371\202\0\0\0\0\2\377Kd=\377\33"
      ";\377\202\377\377\377\377\204\0\0\0\377\202\0\0\0\0\4\0\0\0\377\377\377"
      "\377\377\377\206\227\377\377A\\\307\202\0\0\0\0\2\377.K\224\377k\177"
      "\377\205\377\377\377\377\1\0\0\0\377\202\0\0\0\0\11\0\0\0\377\377\377"
      "\377\377\377\257\272\377\377\5(\363\377\0$8\0\0\0\0\377\0$P\377\5(\363"
      "\377\305\315\370\204\377\377\377\377\1\0\0\0\377\202\0\0\0\0\1\0\0\0"
      "\377\202\377\377\377\377\7\377\273\305\366\377\4'\366\377\0$R\0\0\0\0"
      "\377\0$A\377\2%\364\377\247\264\360\203\377\377\377\377\1\0\0\0\377\202"
      "\0\0\0\0\1\0\0\0\377\203\377\377\377\377\7\377\325\333\376\377\12,\365"
      "\377\0$w\0\0\0\0\377\0$)\377\2%\355\377|\216\350\202\377\377\377\377"
      "\1\0\0\0\377\202\0\0\0\0\1\0\0\0\377\204\377\377\377\377\11\377\366\367"
      "\377\377(F\352\377\1%\251\377\0$\10\377\0$\11\377\3'\310\377F`\350\377"
      "\367\370\377\0\0\0\377\202\0\0\0\0\1\0\0\0\377\204\377\377\377\377\11"
      "\377\365\366\377\3777S\361\377\4'\256\377\0$\6\377\0$\12\377\5(\301\377"
      "F`\354\377\371\371\377\0\0\0\377\202\0\0\0\0\1\0\0\0\377\203\377\377"
      "\377\377\12\377\356\360\377\377+H\355\377\1%\252\377\0$\2\377\0$\21\377"
      "\6)\312\377Jd\357\377\375\375\377\377\377\377\377\0\0\0\377\202\0\0\0"
      "\0\1\0\0\0\377\202\377\377\377\377\10\377\356\360\377\377\35=\360\377"
      "\1%\216\377\0$\1\377\0$\21\377\3'\327\377h}\357\377\376\376\377\202\377"
      "\377\377\377\1\0\0\0\377\202\0\0\0\0\11\0\0\0\377\377\377\377\377\377"
      "\340\344\377\377\15/\365\377\2%z\0\0\0\0\377\0$\37\377\3&\353\377\200"
      "\222\364\204\377\377\377\377\1\0\0\0\377\202\0\0\0\0\7\0\0\0\377&\0\5"
      "\377\0\0\0\377\326\0\36p\0\0\0\0\377\0$&\370\0#\351\207\0\0\0\377\221"
      "\0\0\0\0"
    };
  return broken16_pixdata;
}

} // Rapicorn
<commit_msg>UI: fixed image rendering to match screen coordinates<commit_after>/* Rapicorn
 * Copyright (C) 2005 Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * A copy of the GNU Lesser General Public License should ship along
 * with this library; if not, see http://www.gnu.org/copyleft/.
 */
#include "image.hh"
#include "painter.hh"
#include "factory.hh"
#include <errno.h>

namespace Rapicorn {

const PropertyList&
Image::list_properties()
{
  static Property *properties[] = {
    MakeProperty (Image, image_file, _("Image Filename"), _("Load an image from a file, only PNG images can be loaded."), "w"),
    MakeProperty (Image, stock_pixmap, _("Stock Image"), _("Load an image from stock, providing a stock name."), "w"),
  };
  static const PropertyList property_list (properties, ItemImpl::list_properties());
  return property_list;
}

static const uint8* get_broken16_pixdata (void);

static cairo_surface_t*
cairo_surface_from_pixmap (Pixmap &pixmap)
{
  int stride = 0;
  uint32 *data = pixmap.data (&stride);
  cairo_surface_t *isurface =
    cairo_image_surface_create_for_data ((unsigned char*) data,
                                         CAIRO_FORMAT_ARGB32,
                                         pixmap.width(),
                                         pixmap.height(),
                                         stride);
  return_val_if_fail (CAIRO_STATUS_SUCCESS == cairo_surface_status (isurface), NULL);
  return isurface;
}

class ImageImpl : public virtual ItemImpl, public virtual Image {
  Pixmap           *m_pixmap;
  int               m_xoffset, m_yoffset;
public:
  explicit ImageImpl() :
    m_pixmap (NULL),
    m_xoffset (0),
    m_yoffset (0)
  {}
  void
  reset ()
  {
    m_xoffset = m_yoffset = 0;
    if (m_pixmap)
      {
        Pixmap *op = m_pixmap;
        m_pixmap = NULL;
        unref (op);
      }
    invalidate();
  }
  ~ImageImpl()
  {}
  virtual void
  pixmap (Pixmap *pixmap)
  {
    if (pixmap)
      ref_sink (pixmap);
    reset();
    m_pixmap = pixmap;
  }
  virtual Pixmap*
  pixmap (void)
  {
    return m_pixmap;
  }
  virtual void
  stock_pixmap (const String &stock_name)
  {
    Pixmap *pixmap = Pixmap::stock (stock_name);
    int saved = errno;
    if (!pixmap)
      {
        pixmap = Pixmap::pixstream (get_broken16_pixdata());
        assert (pixmap);
      }
    ref_sink (pixmap);
    this->pixmap (pixmap);
    unref (pixmap);
    errno = saved;
  }
  virtual void
  image_file (const String &filename)
  {
    Pixmap *pixmap = Pixmap::load_png (filename, true);
    int saved = errno;
    if (!pixmap)
      {
        pixmap = Pixmap::pixstream (get_broken16_pixdata());
        assert (pixmap);
      }
    ref_sink (pixmap);
    this->pixmap (pixmap);
    unref (pixmap);
    errno = saved;
  }
protected:
  virtual void
  size_request (Requisition &requisition)
  {
    if (m_pixmap)
      {
        requisition.width += m_pixmap->width();
        requisition.height += m_pixmap->height();
      }
  }
  virtual void
  size_allocate (Allocation area, bool changed)
  {
    if (m_pixmap)
      {
        m_xoffset = iround (0.5 * (area.width - m_pixmap->width()));
        m_yoffset = iround (0.5 * (area.height - m_pixmap->height()));
      }
    else
      m_xoffset = m_yoffset = 0;
  }
public:
  virtual void
  render (RenderContext &rcontext, const Rect &rect)
  {
    if (m_pixmap)
      {
        const Allocation &area = allocation();
        int ix = iround (area.x + m_xoffset), iy = iround (area.y + m_yoffset);
        int ih = m_pixmap->height();
        Rect erect = Rect (ix, iy, m_pixmap->width(), ih);
        erect.intersect (rect);
        cairo_t *cr = cairo_context (rcontext, erect);
        cairo_surface_t *isurface = cairo_surface_from_pixmap (*m_pixmap);
        cairo_set_source_surface (cr, isurface, 0, 0); // (ix,iy) are set in the matrix below
        cairo_matrix_t matrix;
        cairo_matrix_init_identity (&matrix);
        cairo_matrix_translate (&matrix, -ix, -iy);
        cairo_pattern_set_matrix (cairo_get_source (cr), &matrix);
        cairo_paint (cr);
        cairo_surface_destroy (isurface);
      }
  }
};
static const ItemFactory<ImageImpl> image_factory ("Rapicorn::Factory::Image");

static const uint8*
get_broken16_pixdata (void)
{
  /* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
#ifdef __SUNPRO_C
#pragma align 4 (broken16_pixdata)
#endif
#ifdef __GNUC__
  static const uint8 broken16_pixdata[] __attribute__ ((__aligned__ (4))) =
#else
    static const uint8 broken16_pixdata[] =
#endif
    { ""
      /* Pixbuf magic (0x47646b50) */
      "GdkP"
      /* length: header (24) + pixel_data (485) */
      "\0\0\1\375"
      /* pixdata_type (0x2010002) */
      "\2\1\0\2"
      /* rowstride (64) */
      "\0\0\0@"
      /* width (16) */
      "\0\0\0\20"
      /* height (16) */
      "\0\0\0\20"
      /* pixel_data: */
      "\221\0\0\0\0\203\0\0\0\377\2>\0\10\377\0\0\0\377\202\0\0\0\0\1\253\0"
      "\30\\\203\0\0\0\377\2\0\0\0\177\0\0\0\77\203\0\0\0\0\1\0\0\0\377\202"
      "\377\377\377\377\2\377r\205\377\377Jc\262\202\0\0\0\0\7\377D_\301\377"
      "\201\222\377\377\377\377\377\0\0\0\377\300\300\300\377\0\0\0\177\0\0"
      "\0\77\202\0\0\0\0\1\0\0\0\377\202\377\377\377\377\2\377\"A\377\377Kd"
      "D\202\0\0\0\0\7\377\32;\367\377\317\325\377\377\377\377\377\0\0\0\377"
      "\377\377\377\377\300\300\300\377\0\0\0\177\202\0\0\0\0\4\0\0\0\377\377"
      "\377\377\377\377\324\332\377\377\25""6\371\202\0\0\0\0\2\377Kd=\377\33"
      ";\377\202\377\377\377\377\204\0\0\0\377\202\0\0\0\0\4\0\0\0\377\377\377"
      "\377\377\377\206\227\377\377A\\\307\202\0\0\0\0\2\377.K\224\377k\177"
      "\377\205\377\377\377\377\1\0\0\0\377\202\0\0\0\0\11\0\0\0\377\377\377"
      "\377\377\377\257\272\377\377\5(\363\377\0$8\0\0\0\0\377\0$P\377\5(\363"
      "\377\305\315\370\204\377\377\377\377\1\0\0\0\377\202\0\0\0\0\1\0\0\0"
      "\377\202\377\377\377\377\7\377\273\305\366\377\4'\366\377\0$R\0\0\0\0"
      "\377\0$A\377\2%\364\377\247\264\360\203\377\377\377\377\1\0\0\0\377\202"
      "\0\0\0\0\1\0\0\0\377\203\377\377\377\377\7\377\325\333\376\377\12,\365"
      "\377\0$w\0\0\0\0\377\0$)\377\2%\355\377|\216\350\202\377\377\377\377"
      "\1\0\0\0\377\202\0\0\0\0\1\0\0\0\377\204\377\377\377\377\11\377\366\367"
      "\377\377(F\352\377\1%\251\377\0$\10\377\0$\11\377\3'\310\377F`\350\377"
      "\367\370\377\0\0\0\377\202\0\0\0\0\1\0\0\0\377\204\377\377\377\377\11"
      "\377\365\366\377\3777S\361\377\4'\256\377\0$\6\377\0$\12\377\5(\301\377"
      "F`\354\377\371\371\377\0\0\0\377\202\0\0\0\0\1\0\0\0\377\203\377\377"
      "\377\377\12\377\356\360\377\377+H\355\377\1%\252\377\0$\2\377\0$\21\377"
      "\6)\312\377Jd\357\377\375\375\377\377\377\377\377\0\0\0\377\202\0\0\0"
      "\0\1\0\0\0\377\202\377\377\377\377\10\377\356\360\377\377\35=\360\377"
      "\1%\216\377\0$\1\377\0$\21\377\3'\327\377h}\357\377\376\376\377\202\377"
      "\377\377\377\1\0\0\0\377\202\0\0\0\0\11\0\0\0\377\377\377\377\377\377"
      "\340\344\377\377\15/\365\377\2%z\0\0\0\0\377\0$\37\377\3&\353\377\200"
      "\222\364\204\377\377\377\377\1\0\0\0\377\202\0\0\0\0\7\0\0\0\377&\0\5"
      "\377\0\0\0\377\326\0\36p\0\0\0\0\377\0$&\370\0#\351\207\0\0\0\377\221"
      "\0\0\0\0"
    };
  return broken16_pixdata;
}

} // Rapicorn
<|endoftext|>


<commit_before>//     Copyright Toru Niina 2017.
// Distributed under the MIT License.
#ifndef TOML11_TRAITS_HPP
#define TOML11_TRAITS_HPP
#include <chrono>
#include <forward_list>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>

#if __cplusplus >= 201703L
#if __has_include(<string_view>)
#include <string_view>
#endif // has_include(<string_view>)
#endif // cplusplus   >= C++17

namespace toml
{
template<typename C, template<typename ...> class T, template<typename ...> class A>
class basic_value;

namespace detail
{
// ---------------------------------------------------------------------------
// check whether type T is a kind of container/map class

struct has_iterator_impl
{
    template<typename T> static std::true_type  check(typename T::iterator*);
    template<typename T> static std::false_type check(...);
};
struct has_value_type_impl
{
    template<typename T> static std::true_type  check(typename T::value_type*);
    template<typename T> static std::false_type check(...);
};
struct has_key_type_impl
{
    template<typename T> static std::true_type  check(typename T::key_type*);
    template<typename T> static std::false_type check(...);
};
struct has_mapped_type_impl
{
    template<typename T> static std::true_type  check(typename T::mapped_type*);
    template<typename T> static std::false_type check(...);
};
struct has_reserve_method_impl
{
    template<typename T> static std::false_type check(...);
    template<typename T> static std::true_type  check(
        decltype(std::declval<T>().reserve(std::declval<std::size_t>()))*);
};
struct has_push_back_method_impl
{
    template<typename T> static std::false_type check(...);
    template<typename T> static std::true_type  check(
        decltype(std::declval<T>().push_back(std::declval<typename T::value_type>()))*);
};
struct is_comparable_impl
{
    template<typename T> static std::false_type check(...);
    template<typename T> static std::true_type  check(
        decltype(std::declval<T>() < std::declval<T>())*);
};

struct has_from_toml_method_impl
{
    template<typename T, typename C,
             template<typename ...> class Tb, template<typename ...> class A>
    static std::true_type  check(
        decltype(std::declval<T>().from_toml(
                std::declval<::toml::basic_value<C, Tb, A>>()))*);

    template<typename T, typename C,
             template<typename ...> class Tb, template<typename ...> class A>
    static std::false_type check(...);
};
struct has_into_toml_method_impl
{
    template<typename T>
    static std::true_type  check(decltype(std::declval<T>().into_toml())*);
    template<typename T>
    static std::false_type check(...);
};

/// Intel C++ compiler can not use decltype in parent class declaration, here
/// is a hack to work around it. https://stackoverflow.com/a/23953090/4692076
#ifdef __INTEL_COMPILER
#define decltype(...) std::enable_if<true, decltype(__VA_ARGS__)>::type
#endif

template<typename T>
struct has_iterator    : decltype(has_iterator_impl::check<T>(nullptr)){};
template<typename T>
struct has_value_type  : decltype(has_value_type_impl::check<T>(nullptr)){};
template<typename T>
struct has_key_type    : decltype(has_key_type_impl::check<T>(nullptr)){};
template<typename T>
struct has_mapped_type : decltype(has_mapped_type_impl::check<T>(nullptr)){};
template<typename T>
struct has_reserve_method : decltype(has_reserve_method_impl::check<T>(nullptr)){};
template<typename T>
struct has_push_back_method : decltype(has_push_back_method_impl::check<T>(nullptr)){};
template<typename T>
struct is_comparable : decltype(is_comparable_impl::check<T>(nullptr)){};

template<typename T, typename C,
         template<typename ...> class Tb, template<typename ...> class A>
struct has_from_toml_method
: decltype(has_from_toml_method_impl::check<T, C, Tb, A>(nullptr)){};

template<typename T>
struct has_into_toml_method
: decltype(has_into_toml_method_impl::check<T>(nullptr)){};

#ifdef __INTEL_COMPILER
#undef decltype
#endif

// ---------------------------------------------------------------------------
// C++17 and/or/not

#if __cplusplus >= 201703L

using std::conjunction;
using std::disjunction;
using std::negation;

#else

template<typename ...> struct conjunction : std::true_type{};
template<typename T>   struct conjunction<T> : T{};
template<typename T, typename ... Ts>
struct conjunction<T, Ts...> :
    std::conditional<static_cast<bool>(T::value), conjunction<Ts...>, T>::type
{};

template<typename ...> struct disjunction : std::false_type{};
template<typename T>   struct disjunction<T> : T {};
template<typename T, typename ... Ts>
struct disjunction<T, Ts...> :
    std::conditional<static_cast<bool>(T::value), T, disjunction<Ts...>>::type
{};

template<typename T>
struct negation : std::integral_constant<bool, !static_cast<bool>(T::value)>{};

#endif

// ---------------------------------------------------------------------------
// type checkers

template<typename T> struct is_std_pair : std::false_type{};
template<typename T1, typename T2>
struct is_std_pair<std::pair<T1, T2>> : std::true_type{};

template<typename T> struct is_std_tuple : std::false_type{};
template<typename ... Ts>
struct is_std_tuple<std::tuple<Ts...>> : std::true_type{};

template<typename T> struct is_std_forward_list : std::false_type{};
template<typename T>
struct is_std_forward_list<std::forward_list<T>> : std::true_type{};

template<typename T> struct is_chrono_duration: std::false_type{};
template<typename Rep, typename Period>
struct is_chrono_duration<std::chrono::duration<Rep, Period>>: std::true_type{};

template<typename T>
struct is_map : conjunction< // map satisfies all the following conditions
    has_iterator<T>,         // has T::iterator
    has_value_type<T>,       // has T::value_type
    has_key_type<T>,         // has T::key_type
    has_mapped_type<T>       // has T::mapped_type
    >{};
template<typename T> struct is_map<T&>                : is_map<T>{};
template<typename T> struct is_map<T const&>          : is_map<T>{};
template<typename T> struct is_map<T volatile&>       : is_map<T>{};
template<typename T> struct is_map<T const volatile&> : is_map<T>{};

template<typename T>
struct is_container : conjunction<
    negation<is_map<T>>,                         // not a map
    negation<std::is_same<T, std::string>>,      // not a std::string
#if __cplusplus >= 201703L
    negation<std::is_same<T, std::string_view>>, // not a std::string_view
#endif
    has_iterator<T>,                             // has T::iterator
    has_value_type<T>                            // has T::value_type
    >{};
template<typename T> struct is_container<T&>                : is_container<T>{};
template<typename T> struct is_container<T const&>          : is_container<T>{};
template<typename T> struct is_container<T volatile&>       : is_container<T>{};
template<typename T> struct is_container<T const volatile&> : is_container<T>{};

template<typename T>
struct is_basic_value: std::false_type{};
template<typename T> struct is_basic_value<T&>                : is_basic_value<T>{};
template<typename T> struct is_basic_value<T const&>          : is_basic_value<T>{};
template<typename T> struct is_basic_value<T volatile&>       : is_basic_value<T>{};
template<typename T> struct is_basic_value<T const volatile&> : is_basic_value<T>{};
template<typename C, template<typename ...> class M, template<typename ...> class V>
struct is_basic_value<::toml::basic_value<C, M, V>>: std::true_type{};

// ---------------------------------------------------------------------------
// C++14 index_sequence

#if __cplusplus >= 201402L

using std::index_sequence;
using std::make_index_sequence;

#else

template<std::size_t ... Ns> struct index_sequence{};

template<typename IS, std::size_t N> struct push_back_index_sequence{};
template<std::size_t N, std::size_t ... Ns>
struct push_back_index_sequence<index_sequence<Ns...>, N>
{
    typedef index_sequence<Ns..., N> type;
};

template<std::size_t N>
struct index_sequence_maker
{
    typedef typename push_back_index_sequence<
        typename index_sequence_maker<N-1>::type, N>::type type;
};
template<>
struct index_sequence_maker<0>
{
    typedef index_sequence<0> type;
};
template<std::size_t N>
using make_index_sequence = typename index_sequence_maker<N-1>::type;

#endif // __cplusplus >= 2014

// ---------------------------------------------------------------------------
// C++14 enable_if_t

#if __cplusplus >= 201402L

using std::enable_if_t;

#else

template<bool B, typename T>
using enable_if_t = typename std::enable_if<B, T>::type;

#endif // __cplusplus >= 2014

// ---------------------------------------------------------------------------
// return_type_of_t

#if __cplusplus >= 201703L

template<typename F, typename ... Args>
using return_type_of_t = std::invoke_result_t<F, Args...>;

#else
// result_of is deprecated after C++17
template<typename F, typename ... Args>
using return_type_of_t = typename std::result_of<F(Args...)>::type;

#endif

// ---------------------------------------------------------------------------
// is_string_literal
//
// to use this, pass `typename remove_reference<T>::type` to T.

template<typename T>
struct is_string_literal:
disjunction<
    std::is_same<const char*, T>,
    conjunction<
        std::is_array<T>,
        std::is_same<const char, typename std::remove_extent<T>::type>
        >
    >{};

// ---------------------------------------------------------------------------
// C++20 remove_cvref_t

template<typename T>
struct remove_cvref
{
    using type = typename std::remove_cv<
        typename std::remove_reference<T>::type>::type;
};

template<typename T>
using remove_cvref_t = typename remove_cvref<T>::type;

}// detail
}//toml
#endif // TOML_TRAITS
<commit_msg>feat: add detail::has_specialization_from/into<commit_after>//     Copyright Toru Niina 2017.
// Distributed under the MIT License.
#ifndef TOML11_TRAITS_HPP
#define TOML11_TRAITS_HPP

#include "from.hpp"
#include "into.hpp"

#include <chrono>
#include <forward_list>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>

#if __cplusplus >= 201703L
#if __has_include(<string_view>)
#include <string_view>
#endif // has_include(<string_view>)
#endif // cplusplus   >= C++17

namespace toml
{
template<typename C, template<typename ...> class T, template<typename ...> class A>
class basic_value;

namespace detail
{
// ---------------------------------------------------------------------------
// check whether type T is a kind of container/map class

struct has_iterator_impl
{
    template<typename T> static std::true_type  check(typename T::iterator*);
    template<typename T> static std::false_type check(...);
};
struct has_value_type_impl
{
    template<typename T> static std::true_type  check(typename T::value_type*);
    template<typename T> static std::false_type check(...);
};
struct has_key_type_impl
{
    template<typename T> static std::true_type  check(typename T::key_type*);
    template<typename T> static std::false_type check(...);
};
struct has_mapped_type_impl
{
    template<typename T> static std::true_type  check(typename T::mapped_type*);
    template<typename T> static std::false_type check(...);
};
struct has_reserve_method_impl
{
    template<typename T> static std::false_type check(...);
    template<typename T> static std::true_type  check(
        decltype(std::declval<T>().reserve(std::declval<std::size_t>()))*);
};
struct has_push_back_method_impl
{
    template<typename T> static std::false_type check(...);
    template<typename T> static std::true_type  check(
        decltype(std::declval<T>().push_back(std::declval<typename T::value_type>()))*);
};
struct is_comparable_impl
{
    template<typename T> static std::false_type check(...);
    template<typename T> static std::true_type  check(
        decltype(std::declval<T>() < std::declval<T>())*);
};

struct has_from_toml_method_impl
{
    template<typename T, typename C,
             template<typename ...> class Tb, template<typename ...> class A>
    static std::true_type  check(
        decltype(std::declval<T>().from_toml(
                std::declval<::toml::basic_value<C, Tb, A>>()))*);

    template<typename T, typename C,
             template<typename ...> class Tb, template<typename ...> class A>
    static std::false_type check(...);
};
struct has_into_toml_method_impl
{
    template<typename T>
    static std::true_type  check(decltype(std::declval<T>().into_toml())*);
    template<typename T>
    static std::false_type check(...);
};

struct has_specialized_from_impl
{
    template<typename T>
    static std::false_type check(...);
    template<typename T>
    static std::true_type check(std::nullptr_t, std::size_t S = sizeof(::toml::from<T>));
};
struct has_specialized_into_impl
{
    template<typename T>
    static std::false_type check(...);
    template<typename T>
    static std::true_type check(std::nullptr_t, std::size_t S = sizeof(::toml::into<T>));
};

/// Intel C++ compiler can not use decltype in parent class declaration, here
/// is a hack to work around it. https://stackoverflow.com/a/23953090/4692076
#ifdef __INTEL_COMPILER
#define decltype(...) std::enable_if<true, decltype(__VA_ARGS__)>::type
#endif

template<typename T>
struct has_iterator    : decltype(has_iterator_impl::check<T>(nullptr)){};
template<typename T>
struct has_value_type  : decltype(has_value_type_impl::check<T>(nullptr)){};
template<typename T>
struct has_key_type    : decltype(has_key_type_impl::check<T>(nullptr)){};
template<typename T>
struct has_mapped_type : decltype(has_mapped_type_impl::check<T>(nullptr)){};
template<typename T>
struct has_reserve_method : decltype(has_reserve_method_impl::check<T>(nullptr)){};
template<typename T>
struct has_push_back_method : decltype(has_push_back_method_impl::check<T>(nullptr)){};
template<typename T>
struct is_comparable : decltype(is_comparable_impl::check<T>(nullptr)){};

template<typename T, typename C,
         template<typename ...> class Tb, template<typename ...> class A>
struct has_from_toml_method
: decltype(has_from_toml_method_impl::check<T, C, Tb, A>(nullptr)){};

template<typename T>
struct has_into_toml_method
: decltype(has_into_toml_method_impl::check<T>(nullptr)){};

template<typename T>
struct has_specialized_from : decltype(has_specialized_from_impl::check<T>(nullptr)){};
template<typename T>
struct has_specialized_into : decltype(has_specialized_into_impl::check<T>(nullptr)){};

#ifdef __INTEL_COMPILER
#undef decltype
#endif

// ---------------------------------------------------------------------------
// C++17 and/or/not

#if __cplusplus >= 201703L

using std::conjunction;
using std::disjunction;
using std::negation;

#else

template<typename ...> struct conjunction : std::true_type{};
template<typename T>   struct conjunction<T> : T{};
template<typename T, typename ... Ts>
struct conjunction<T, Ts...> :
    std::conditional<static_cast<bool>(T::value), conjunction<Ts...>, T>::type
{};

template<typename ...> struct disjunction : std::false_type{};
template<typename T>   struct disjunction<T> : T {};
template<typename T, typename ... Ts>
struct disjunction<T, Ts...> :
    std::conditional<static_cast<bool>(T::value), T, disjunction<Ts...>>::type
{};

template<typename T>
struct negation : std::integral_constant<bool, !static_cast<bool>(T::value)>{};

#endif

// ---------------------------------------------------------------------------
// type checkers

template<typename T> struct is_std_pair : std::false_type{};
template<typename T1, typename T2>
struct is_std_pair<std::pair<T1, T2>> : std::true_type{};

template<typename T> struct is_std_tuple : std::false_type{};
template<typename ... Ts>
struct is_std_tuple<std::tuple<Ts...>> : std::true_type{};

template<typename T> struct is_std_forward_list : std::false_type{};
template<typename T>
struct is_std_forward_list<std::forward_list<T>> : std::true_type{};

template<typename T> struct is_chrono_duration: std::false_type{};
template<typename Rep, typename Period>
struct is_chrono_duration<std::chrono::duration<Rep, Period>>: std::true_type{};

template<typename T>
struct is_map : conjunction< // map satisfies all the following conditions
    has_iterator<T>,         // has T::iterator
    has_value_type<T>,       // has T::value_type
    has_key_type<T>,         // has T::key_type
    has_mapped_type<T>       // has T::mapped_type
    >{};
template<typename T> struct is_map<T&>                : is_map<T>{};
template<typename T> struct is_map<T const&>          : is_map<T>{};
template<typename T> struct is_map<T volatile&>       : is_map<T>{};
template<typename T> struct is_map<T const volatile&> : is_map<T>{};

template<typename T>
struct is_container : conjunction<
    negation<is_map<T>>,                         // not a map
    negation<std::is_same<T, std::string>>,      // not a std::string
#if __cplusplus >= 201703L
    negation<std::is_same<T, std::string_view>>, // not a std::string_view
#endif
    has_iterator<T>,                             // has T::iterator
    has_value_type<T>                            // has T::value_type
    >{};
template<typename T> struct is_container<T&>                : is_container<T>{};
template<typename T> struct is_container<T const&>          : is_container<T>{};
template<typename T> struct is_container<T volatile&>       : is_container<T>{};
template<typename T> struct is_container<T const volatile&> : is_container<T>{};

template<typename T>
struct is_basic_value: std::false_type{};
template<typename T> struct is_basic_value<T&>                : is_basic_value<T>{};
template<typename T> struct is_basic_value<T const&>          : is_basic_value<T>{};
template<typename T> struct is_basic_value<T volatile&>       : is_basic_value<T>{};
template<typename T> struct is_basic_value<T const volatile&> : is_basic_value<T>{};
template<typename C, template<typename ...> class M, template<typename ...> class V>
struct is_basic_value<::toml::basic_value<C, M, V>>: std::true_type{};

// ---------------------------------------------------------------------------
// C++14 index_sequence

#if __cplusplus >= 201402L

using std::index_sequence;
using std::make_index_sequence;

#else

template<std::size_t ... Ns> struct index_sequence{};

template<typename IS, std::size_t N> struct push_back_index_sequence{};
template<std::size_t N, std::size_t ... Ns>
struct push_back_index_sequence<index_sequence<Ns...>, N>
{
    typedef index_sequence<Ns..., N> type;
};

template<std::size_t N>
struct index_sequence_maker
{
    typedef typename push_back_index_sequence<
        typename index_sequence_maker<N-1>::type, N>::type type;
};
template<>
struct index_sequence_maker<0>
{
    typedef index_sequence<0> type;
};
template<std::size_t N>
using make_index_sequence = typename index_sequence_maker<N-1>::type;

#endif // __cplusplus >= 2014

// ---------------------------------------------------------------------------
// C++14 enable_if_t

#if __cplusplus >= 201402L

using std::enable_if_t;

#else

template<bool B, typename T>
using enable_if_t = typename std::enable_if<B, T>::type;

#endif // __cplusplus >= 2014

// ---------------------------------------------------------------------------
// return_type_of_t

#if __cplusplus >= 201703L

template<typename F, typename ... Args>
using return_type_of_t = std::invoke_result_t<F, Args...>;

#else
// result_of is deprecated after C++17
template<typename F, typename ... Args>
using return_type_of_t = typename std::result_of<F(Args...)>::type;

#endif

// ---------------------------------------------------------------------------
// is_string_literal
//
// to use this, pass `typename remove_reference<T>::type` to T.

template<typename T>
struct is_string_literal:
disjunction<
    std::is_same<const char*, T>,
    conjunction<
        std::is_array<T>,
        std::is_same<const char, typename std::remove_extent<T>::type>
        >
    >{};

// ---------------------------------------------------------------------------
// C++20 remove_cvref_t

template<typename T>
struct remove_cvref
{
    using type = typename std::remove_cv<
        typename std::remove_reference<T>::type>::type;
};

template<typename T>
using remove_cvref_t = typename remove_cvref<T>::type;

}// detail
}//toml
#endif // TOML_TRAITS
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2013 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_RENDERER_COMMON_PROCESS_BUILDING_SYMBOLIZER_HPP
#define MAPNIK_RENDERER_COMMON_PROCESS_BUILDING_SYMBOLIZER_HPP

#include <mapnik/segment.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/geometry.hpp>

#include <algorithm>

namespace mapnik {

template <typename F1, typename F2, typename F3>
void render_building_symbolizer(mapnik::feature_impl &feature,
                                double height,
                                F1 face_func, F2 frame_func, F3 roof_func)
{
    for (auto const& geom : feature.paths())
    {
        if (geom.size() > 2)
        {
            const std::unique_ptr<geometry_type> frame(new geometry_type(geometry_type::types::LineString));
            const std::unique_ptr<geometry_type> roof(new geometry_type(geometry_type::types::Polygon));
            std::deque<segment_t> face_segments;
            double x0 = 0;
            double y0 = 0;
            double x,y;
            geom.rewind(0);
            for (unsigned cm = geom.vertex(&x, &y); cm != SEG_END;
                 cm = geom.vertex(&x, &y))
            {
                if (cm == SEG_MOVETO)
                {
                    frame->move_to(x,y);
                }
                else if (cm == SEG_LINETO)
                {
                    frame->line_to(x,y);
                    face_segments.push_back(segment_t(x0,y0,x,y));
                }
                else if (cm == SEG_CLOSE)
                {
                    frame->close_path();
                }
                x0 = x;
                y0 = y;
            }

            std::sort(face_segments.begin(),face_segments.end(), y_order);
            for (auto const& seg : face_segments)
            {
                const std::unique_ptr<geometry_type> faces(new geometry_type(geometry_type::types::Polygon));
                faces->move_to(std::get<0>(seg),std::get<1>(seg));
                faces->line_to(std::get<2>(seg),std::get<3>(seg));
                faces->line_to(std::get<2>(seg),std::get<3>(seg) + height);
                faces->line_to(std::get<0>(seg),std::get<1>(seg) + height);

                face_func(*faces);
                //
                frame->move_to(std::get<0>(seg),std::get<1>(seg));
                frame->line_to(std::get<0>(seg),std::get<1>(seg)+height);

            }

            geom.rewind(0);
            for (unsigned cm = geom.vertex(&x, &y); cm != SEG_END;
                 cm = geom.vertex(&x, &y))
            {
                if (cm == SEG_MOVETO)
                {
                    frame->move_to(x,y+height);
                    roof->move_to(x,y+height);
                }
                else if (cm == SEG_LINETO)
                {
                    frame->line_to(x,y+height);
                    roof->line_to(x,y+height);
                }
                else if (cm == SEG_CLOSE)
                {
                    frame->close_path();
                    roof->close_path();
                }
            }

            frame_func(*frame);
            roof_func(*roof);
        }
    }
}

} // namespace mapnik

#endif // MAPNIK_RENDERER_COMMON_PROCESS_BUILDING_SYMBOLIZER_HPP
<commit_msg>fix issue 6 from #2396<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2013 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_RENDERER_COMMON_PROCESS_BUILDING_SYMBOLIZER_HPP
#define MAPNIK_RENDERER_COMMON_PROCESS_BUILDING_SYMBOLIZER_HPP

#include <mapnik/segment.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/geometry.hpp>

#include <algorithm>
#include <deque>

namespace mapnik {

template <typename F1, typename F2, typename F3>
void render_building_symbolizer(mapnik::feature_impl &feature,
                                double height,
                                F1 face_func, F2 frame_func, F3 roof_func)
{
    for (auto const& geom : feature.paths())
    {
        if (geom.size() > 2)
        {
            const std::unique_ptr<geometry_type> frame(new geometry_type(geometry_type::types::LineString));
            const std::unique_ptr<geometry_type> roof(new geometry_type(geometry_type::types::Polygon));
            std::deque<segment_t> face_segments;
            double x0 = 0;
            double y0 = 0;
            double x,y;
            geom.rewind(0);
            for (unsigned cm = geom.vertex(&x, &y); cm != SEG_END;
                 cm = geom.vertex(&x, &y))
            {
                if (cm == SEG_MOVETO)
                {
                    frame->move_to(x,y);
                }
                else if (cm == SEG_LINETO)
                {
                    frame->line_to(x,y);
                    face_segments.push_back(segment_t(x0,y0,x,y));
                }
                else if (cm == SEG_CLOSE)
                {
                    frame->close_path();
                }
                x0 = x;
                y0 = y;
            }

            std::sort(face_segments.begin(),face_segments.end(), y_order);
            for (auto const& seg : face_segments)
            {
                const std::unique_ptr<geometry_type> faces(new geometry_type(geometry_type::types::Polygon));
                faces->move_to(std::get<0>(seg),std::get<1>(seg));
                faces->line_to(std::get<2>(seg),std::get<3>(seg));
                faces->line_to(std::get<2>(seg),std::get<3>(seg) + height);
                faces->line_to(std::get<0>(seg),std::get<1>(seg) + height);

                face_func(*faces);
                //
                frame->move_to(std::get<0>(seg),std::get<1>(seg));
                frame->line_to(std::get<0>(seg),std::get<1>(seg)+height);

            }

            geom.rewind(0);
            for (unsigned cm = geom.vertex(&x, &y); cm != SEG_END;
                 cm = geom.vertex(&x, &y))
            {
                if (cm == SEG_MOVETO)
                {
                    frame->move_to(x,y+height);
                    roof->move_to(x,y+height);
                }
                else if (cm == SEG_LINETO)
                {
                    frame->line_to(x,y+height);
                    roof->line_to(x,y+height);
                }
                else if (cm == SEG_CLOSE)
                {
                    frame->close_path();
                    roof->close_path();
                }
            }

            frame_func(*frame);
            roof_func(*roof);
        }
    }
}

} // namespace mapnik

#endif // MAPNIK_RENDERER_COMMON_PROCESS_BUILDING_SYMBOLIZER_HPP
<|endoftext|>


<commit_before>#include "aquila/global.h"
#include "aquila/source/SignalSource.h"
#include "aquila/source/Frame.h"
#include "aquila/source/FramesCollection.h"
#include "UnitTest++/UnitTest++.h"
#include <algorithm>

bool equalSamples(Aquila::Frame frame, Aquila::SampleType arr[])
{
    return std::equal(std::begin(frame), std::end(frame), arr);
}

SUITE(FramesCollection)
{
    const int SIZE = 10;
    Aquila::SampleType testArray[SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    Aquila::FrequencyType sampleFrequency  = 100;
    Aquila::SignalSource data(testArray, SIZE, sampleFrequency);

    TEST(Empty)
    {
        Aquila::FramesCollection frames;
        CHECK_EQUAL(0u, frames.getSamplesPerFrame());
        CHECK_EQUAL(0u, frames.count());
    }

    TEST(EmptyWhenZeroSamples)
    {
        Aquila::FramesCollection frames(data, 0);
        CHECK_EQUAL(0u, frames.getSamplesPerFrame());
        CHECK_EQUAL(0u, frames.count());
    }

    TEST(FiveSamplesPerFrame)
    {
        Aquila::FramesCollection frames(data, 5);
        CHECK_EQUAL(5u, frames.getSamplesPerFrame());
        CHECK_EQUAL(2u, frames.count());
        Aquila::SampleType arr0[5] = {0, 1, 2, 3, 4};
        CHECK(equalSamples(frames.frame(0), arr0));
        Aquila::SampleType arr1[5] = {5, 6, 7, 8, 9};
        CHECK(equalSamples(frames.frame(1), arr1));
    }

    TEST(TwoSamplesPerFrame)
    {
        Aquila::FramesCollection frames(data, 2);
        CHECK_EQUAL(2u, frames.getSamplesPerFrame());
        CHECK_EQUAL(5u, frames.count());
        Aquila::SampleType arr[2] = {0, 1};
        CHECK(equalSamples(frames.frame(0), arr));
    }

    TEST(OneSamplePerFrame)
    {
        Aquila::FramesCollection frames(data, 1);
        CHECK_EQUAL(1u, frames.getSamplesPerFrame());
        CHECK_EQUAL(10u, frames.count());
        Aquila::SampleType arr[1] = {0};
        CHECK(equalSamples(frames.frame(0), arr));
    }

    TEST(AllSamplesPerFrame)
    {
        Aquila::FramesCollection frames(data, 10);
        CHECK_EQUAL(10u, frames.getSamplesPerFrame());
        CHECK_EQUAL(1u, frames.count());
        Aquila::SampleType arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        CHECK(equalSamples(frames.frame(0), arr));
    }

    TEST(MoreThanHalfSamplesPerFrame)
    {
        Aquila::FramesCollection frames(data, 7);
        CHECK_EQUAL(7u, frames.getSamplesPerFrame());
        CHECK_EQUAL(1u, frames.count());
        Aquila::SampleType arr[7] = {0, 1, 2, 3, 4, 5, 6};
        CHECK(equalSamples(frames.frame(0), arr));
    }

    TEST(TooManySamplesPerFrame)
    {
        Aquila::FramesCollection frames(data, 11);
        CHECK_EQUAL(0u, frames.count());
    }

    TEST(Iteration)
    {
        Aquila::FramesCollection frames(data, 2);
        for (auto it = frames.begin(); it != frames.end(); it++)
        {
            CHECK_EQUAL(2u, it->length());
        }
    }

    TEST(Duration)
    {
        // sampling at 100 Hz -> 10 miliseconds is 1 sample
        auto frames = Aquila::FramesCollection::createFromDuration(data, 10);
        CHECK_EQUAL(10u, frames.count());
    }

    TEST(Duration2)
    {
        // sampling at 100 Hz -> 50 miliseconds is 5 samples
        auto frames = Aquila::FramesCollection::createFromDuration(data, 50);
        CHECK_EQUAL(2u, frames.count());
    }

    TEST(DurationWithOverlap)
    {
        // sampling at 100 Hz -> 50 miliseconds is 5 samples
        // 80% overlap -> 4 common samples between consecutive frames
        // frame data:  0  1  2  3  4  5  6  7  8  9
        // frame 0:    |             |
        // frame 1:       |             |
        // frame 2:          |             |
        // frame 3:             |             |
        // frame 4:                |             |
        // frame 5:                   |              |
        auto frames = Aquila::FramesCollection::createFromDuration(data, 50, 0.8);
        CHECK_EQUAL(6u, frames.count());
    }

    TEST(ApplySimpleFunction)
    {
        Aquila::FramesCollection frames(data, 5);
        auto energies = frames.apply<double>(Aquila::mean);
        double expected[2] = {2.0, 7.0};
        CHECK_ARRAY_CLOSE(expected, energies, 2, 0.000001);
    }

    TEST(ApplyLambda)
    {
        Aquila::FramesCollection frames(data, 5);
        auto maximums = frames.apply<Aquila::SampleType>(
            [&](const Aquila::SignalSource& s) {
                return *std::max_element(s.begin(), s.end());
            }
        );
        Aquila::SampleType expected[2] = {4.0, 9.0};
        CHECK_ARRAY_CLOSE(expected, maximums, 2, 0.000001);
    }

    TEST(ApplyMemberFunction)
    {
        Aquila::FramesCollection frames(data, 5);
        auto lengths = frames.apply<std::size_t>(
#ifdef _MSC_VER
            std::mem_fn(&Aquila::SignalSource::getSamplesCount)
#else
            &Aquila::SignalSource::getSamplesCount
#endif // _MSC_VER
        );
        std::size_t expected[2] = {5, 5};
        CHECK_ARRAY_EQUAL(expected, lengths, 2);
    }
}
<commit_msg>Removed excessive space.<commit_after>#include "aquila/global.h"
#include "aquila/source/SignalSource.h"
#include "aquila/source/Frame.h"
#include "aquila/source/FramesCollection.h"
#include "UnitTest++/UnitTest++.h"
#include <algorithm>

bool equalSamples(Aquila::Frame frame, Aquila::SampleType arr[])
{
    return std::equal(std::begin(frame), std::end(frame), arr);
}

SUITE(FramesCollection)
{
    const int SIZE = 10;
    Aquila::SampleType testArray[SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    Aquila::FrequencyType sampleFrequency = 100;
    Aquila::SignalSource data(testArray, SIZE, sampleFrequency);

    TEST(Empty)
    {
        Aquila::FramesCollection frames;
        CHECK_EQUAL(0u, frames.getSamplesPerFrame());
        CHECK_EQUAL(0u, frames.count());
    }

    TEST(EmptyWhenZeroSamples)
    {
        Aquila::FramesCollection frames(data, 0);
        CHECK_EQUAL(0u, frames.getSamplesPerFrame());
        CHECK_EQUAL(0u, frames.count());
    }

    TEST(FiveSamplesPerFrame)
    {
        Aquila::FramesCollection frames(data, 5);
        CHECK_EQUAL(5u, frames.getSamplesPerFrame());
        CHECK_EQUAL(2u, frames.count());
        Aquila::SampleType arr0[5] = {0, 1, 2, 3, 4};
        CHECK(equalSamples(frames.frame(0), arr0));
        Aquila::SampleType arr1[5] = {5, 6, 7, 8, 9};
        CHECK(equalSamples(frames.frame(1), arr1));
    }

    TEST(TwoSamplesPerFrame)
    {
        Aquila::FramesCollection frames(data, 2);
        CHECK_EQUAL(2u, frames.getSamplesPerFrame());
        CHECK_EQUAL(5u, frames.count());
        Aquila::SampleType arr[2] = {0, 1};
        CHECK(equalSamples(frames.frame(0), arr));
    }

    TEST(OneSamplePerFrame)
    {
        Aquila::FramesCollection frames(data, 1);
        CHECK_EQUAL(1u, frames.getSamplesPerFrame());
        CHECK_EQUAL(10u, frames.count());
        Aquila::SampleType arr[1] = {0};
        CHECK(equalSamples(frames.frame(0), arr));
    }

    TEST(AllSamplesPerFrame)
    {
        Aquila::FramesCollection frames(data, 10);
        CHECK_EQUAL(10u, frames.getSamplesPerFrame());
        CHECK_EQUAL(1u, frames.count());
        Aquila::SampleType arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        CHECK(equalSamples(frames.frame(0), arr));
    }

    TEST(MoreThanHalfSamplesPerFrame)
    {
        Aquila::FramesCollection frames(data, 7);
        CHECK_EQUAL(7u, frames.getSamplesPerFrame());
        CHECK_EQUAL(1u, frames.count());
        Aquila::SampleType arr[7] = {0, 1, 2, 3, 4, 5, 6};
        CHECK(equalSamples(frames.frame(0), arr));
    }

    TEST(TooManySamplesPerFrame)
    {
        Aquila::FramesCollection frames(data, 11);
        CHECK_EQUAL(0u, frames.count());
    }

    TEST(Iteration)
    {
        Aquila::FramesCollection frames(data, 2);
        for (auto it = frames.begin(); it != frames.end(); it++)
        {
            CHECK_EQUAL(2u, it->length());
        }
    }

    TEST(Duration)
    {
        // sampling at 100 Hz -> 10 miliseconds is 1 sample
        auto frames = Aquila::FramesCollection::createFromDuration(data, 10);
        CHECK_EQUAL(10u, frames.count());
    }

    TEST(Duration2)
    {
        // sampling at 100 Hz -> 50 miliseconds is 5 samples
        auto frames = Aquila::FramesCollection::createFromDuration(data, 50);
        CHECK_EQUAL(2u, frames.count());
    }

    TEST(DurationWithOverlap)
    {
        // sampling at 100 Hz -> 50 miliseconds is 5 samples
        // 80% overlap -> 4 common samples between consecutive frames
        // frame data:  0  1  2  3  4  5  6  7  8  9
        // frame 0:    |             |
        // frame 1:       |             |
        // frame 2:          |             |
        // frame 3:             |             |
        // frame 4:                |             |
        // frame 5:                   |              |
        auto frames = Aquila::FramesCollection::createFromDuration(data, 50, 0.8);
        CHECK_EQUAL(6u, frames.count());
    }

    TEST(ApplySimpleFunction)
    {
        Aquila::FramesCollection frames(data, 5);
        auto energies = frames.apply<double>(Aquila::mean);
        double expected[2] = {2.0, 7.0};
        CHECK_ARRAY_CLOSE(expected, energies, 2, 0.000001);
    }

    TEST(ApplyLambda)
    {
        Aquila::FramesCollection frames(data, 5);
        auto maximums = frames.apply<Aquila::SampleType>(
            [&](const Aquila::SignalSource& s) {
                return *std::max_element(s.begin(), s.end());
            }
        );
        Aquila::SampleType expected[2] = {4.0, 9.0};
        CHECK_ARRAY_CLOSE(expected, maximums, 2, 0.000001);
    }

    TEST(ApplyMemberFunction)
    {
        Aquila::FramesCollection frames(data, 5);
        auto lengths = frames.apply<std::size_t>(
#ifdef _MSC_VER
            std::mem_fn(&Aquila::SignalSource::getSamplesCount)
#else
            &Aquila::SignalSource::getSamplesCount
#endif // _MSC_VER
        );
        std::size_t expected[2] = {5, 5};
        CHECK_ARRAY_EQUAL(expected, lengths, 2);
    }
}
<|endoftext|>