<commit_before>/*
 * BSD License
 *
 * Copyright (c) 2007, The University of Manchester (UK)
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *     - Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     - Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     - Neither the name of the University of Manchester nor the names
 *       of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written
 *       permission.

 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <iostream>
#include <pthread.h>
#include <getopt.h>
#include <ctime>

#include "stm_api.h"
#include "lee.h"

using namespace stm;

///////////////
// constants //
///////////////

#define MILLISECONDS_IN_SECOND 1000
#define MICROSECONDS_IN_MILLISECOND 1000

/////////////////////
// data structures //
/////////////////////

struct command_line_args {
	char *input_file_name;

	unsigned thread_count;

	char *validation;

	char *cm;
};

struct thread_args {
	Lee *lee;

	int id;

	int ***private_buffer;

	pthread_barrier_t *start_barrier;

	pthread_barrier_t *end_barrier;

	unsigned commits;

	unsigned aborts;

	pthread_t pthread_tid;
};

/////////////////
// global data //
/////////////////

command_line_args cmdl_args;

pthread_barrier_t start_barrier;
pthread_barrier_t end_barrier;

thread_args targs[MAX_THREADS];

///////////////////////////
// function declarations //
///////////////////////////

void parse_arguments(command_line_args &args, char **argv, int argc);

void print_arguments(command_line_args &args);

void print_help();

void run_benchmark(void);

void initialize_benchmark(void);

void *thread_main(void *args);

int ***create_private_buffer(Lee *lee);

void run_transactions(thread_args *targ);

long get_time_ms();

//////////////////////////
// function definitions //
//////////////////////////

int main(int argc, char **argv) {
	parse_arguments(cmdl_args, argv, argc);
	print_arguments(cmdl_args);

	run_benchmark();
}

void parse_arguments(command_line_args &args, char **argv, int argc) {
	static struct option long_options[] = {
		{"input_file", 1, 0, 'f'},
		{"help", 0, 0, '?'},
		{"threads", 1, 0, 't'},
		{"validation", 1, 0, 'v'},
		{"cm", 1, 0, 'c'},
		{0, 0, 0, 0}
	};

	// set defaults
	args.thread_count = 1;
	args.input_file_name = NULL;
	args.validation = "invis-eager";
	args.cm = "Polka";

	// parse command line
	while(true) {
		int option_index;
		int c = getopt_long(argc, argv, "f:?t:v:c:",
			long_options, &option_index);

		if(c == -1) {
			break;
		}

		switch(c) {
			case '?':
				print_help();
				exit(0);
			break;
			case 'f':
				args.input_file_name = optarg;
			break;
			case 't':
				args.thread_count = atoi(optarg);
			break;
			case 'v':
				args.validation = optarg;
			break;
			case 'c':
				args.cm = optarg;
			break;
		}
	}

	if(args.input_file_name == NULL) {
		print_help();
		exit(1);
	}
}

void print_help() {
	std::cout << "lee -f file_name [-t thread_cnt] [-v validation] [-c cm]" << std::endl;
}

void print_arguments(command_line_args &args) {
	std::cout << std::endl;
	std::cout << "Parameters:" << std::endl;
	std::cout << "===========" << std::endl;
	std::cout << "input file: " << args.input_file_name << std::endl;
	std::cout << "threads: " << args.thread_count << std::endl;
	std::cout << "validation: " << args.validation << std::endl;
	std::cout << "cm: " << args.cm << std::endl;
	std::cout << std::endl;
}

void run_benchmark() {
	initialize_benchmark();

	//run_thread();
}

void initialize_benchmark() {
	// initialize barriers
	pthread_barrier_init(&start_barrier, NULL, cmdl_args.thread_count);
	pthread_barrier_init(&end_barrier, NULL, cmdl_args.thread_count);

	// initialize stm for first thread
	stm::init(
		cmdl_args.cm,
		cmdl_args.validation,
		false);

	// create Lee benchmark
	Lee *lee = new Lee(cmdl_args.input_file_name, false, false, false);

	// initialize thread arguments
	for(unsigned i = 0;i < cmdl_args.thread_count;i++) {
		targs[i].lee = lee;
		targs[i].id = i;
		targs[i].start_barrier = &start_barrier;
		targs[i].end_barrier = &end_barrier;
		targs[i].commits = 0;
		targs[i].aborts = 0;
	}

	// now start all threads
	for(unsigned i = 1;i < cmdl_args.thread_count;i++) {
		pthread_create(&targs[i].pthread_tid, NULL,
			thread_main, targs + i);
	}

	// run one instance in this thread
	long duration_ms = (long)thread_main(targs);
	float duration_s = (float)duration_ms / MILLISECONDS_IN_SECOND;

	// print statistics
	std::cout << "Duration: " << duration_ms << " ms" << std::endl;

	unsigned commits = 0;
	unsigned aborts = 0;

	for(unsigned i = 0;i < cmdl_args.thread_count;i++) {
		commits += targs[i].commits;
		aborts += targs[i].aborts;
	}

	std::cout << "Total commits: " << commits << std::endl;
	std::cout << "Total commits per second: " << commits / duration_s << std::endl;
	std::cout << "Total aborts: " << aborts << std::endl;
	std::cout << "Total aborts per second: " << aborts / duration_s << std::endl;
}

void *thread_main(void *voidargs) {
	thread_args *args = (thread_args *)voidargs;

	// initialize stm if needed
	if(args->id != 0) {
		stm::init(
			cmdl_args.cm,
			cmdl_args.validation,
			false);
	}

	Lee *lee = args->lee;

	// create needed scratch data
	args->private_buffer = create_private_buffer(lee);

	// wait for all threads to come to this point
	pthread_barrier_wait(args->start_barrier);

	long start_time_ms;

	if(args->id == 0) {
		start_time_ms = get_time_ms();
	}

	// perform work
	run_transactions(args);

	// wait for all threads to finish
	pthread_barrier_wait(args->end_barrier);

	long end_time_ms;

	if(args->id == 0) {
		end_time_ms = get_time_ms();
	}

	if(args->id == 0) {
		return (void *)(end_time_ms - start_time_ms);
	}

	return NULL;
}

void run_transactions(thread_args *targ) {
	Lee *lee = targ->lee;

	while(true) {
		stm::internal::Descriptor* locallyCachedTransactionContext = NULL;
		WorkQueue *track = lee->getNextTrack();

		if(track == NULL) {
			break;
		}

		do {
			try {
				// start transaction
				locallyCachedTransactionContext =
					stm::internal::begin_transaction();

				// transaction body
				lee->layNextTrack(track, targ->private_buffer);

				// end transaction
				locallyCachedTransactionContext->commit();

				targs->commits++;
			} catch (stm::Aborted) {
				// increment number of aborts for an operation
				targ->aborts++;
			} catch (...) {
				locallyCachedTransactionContext->abort(false);
				locallyCachedTransactionContext->cleanup();
				throw;
			}
		} while (!locallyCachedTransactionContext->cleanup()
			&& !stm::terminate);

		locallyCachedTransactionContext = NULL;
	}
}

int ***create_private_buffer(Lee *lee) {
	Grid *grid = lee->grid;
	int ***ret = (int ***)malloc(sizeof(int) * grid->getWidth());

	for(int i = 0;i < grid->getWidth();i++) {
		ret[i] = (int **)malloc(sizeof(int) * grid->getHeight());

		for(int k = 0;k < grid->getHeight();k++) {
			ret[i][k] = (int *)malloc(sizeof(int) * grid->getDepth());
		}
	}

	return ret;
}

long get_time_ms() {
	struct timeval t;
	gettimeofday(&t, NULL);
	return t.tv_sec * MILLISECONDS_IN_SECOND +
		t.tv_usec / MICROSECONDS_IN_MILLISECOND;
}
<commit_msg>removed unused file<commit_after><|endoftext|>


<commit_before>// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson

#include <gtest/gtest.h>
#include <ArduinoJson/StaticJsonBuffer.hpp>
#include <ArduinoJson/JsonArray.hpp>
#include <ArduinoJson/JsonObject.hpp>

using namespace ArduinoJson;

class JsonVariant_Subscript_Tests : public ::testing::Test {
 protected:
  StaticJsonBuffer<200> buffer;
  JsonVariant variant;
};

TEST_F(JsonVariant_Subscript_Tests, Array) {
  JsonArray &array = buffer.createArray();
  array.add("element at index 0");
  array.add("element at index 1");

  variant = array;

  EXPECT_EQ(2, variant.size());
  EXPECT_STREQ("element at index 0", variant[0].asString());
  EXPECT_STREQ("element at index 1", variant[1].asString());
  EXPECT_FALSE(variant[-1].success());
  EXPECT_FALSE(variant[3].success());
  EXPECT_FALSE(variant["0"].success());
}

TEST_F(JsonVariant_Subscript_Tests, Object) {
  JsonObject &object = buffer.createObject();
  object["a"] = "element at key \"a\"";
  object["b"] = "element at key \"b\"";

  variant = object;

  EXPECT_EQ(2, variant.size());
  EXPECT_STREQ("element at key \"a\"", variant["a"].asString());
  EXPECT_STREQ("element at key \"b\"", variant["b"].asString());
  EXPECT_FALSE(variant["c"].success());
  EXPECT_FALSE(variant[0].success());
}
<commit_msg>Added more tests of subscript operator<commit_after>// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson

#include <gtest/gtest.h>
#include <ArduinoJson/StaticJsonBuffer.hpp>
#include <ArduinoJson/JsonArray.hpp>
#include <ArduinoJson/JsonObject.hpp>

using namespace ArduinoJson;

class JsonVariant_Subscript_Tests : public ::testing::Test {
 protected:
  StaticJsonBuffer<200> buffer;
  JsonVariant variant;
};

TEST_F(JsonVariant_Subscript_Tests, Array) {
  JsonArray &array = buffer.createArray();
  array.add("element at index 0");
  array.add("element at index 1");

  variant = array;

  EXPECT_EQ(2, variant.size());
  EXPECT_STREQ("element at index 0", variant[0].asString());
  EXPECT_STREQ("element at index 1", variant[1].asString());
  EXPECT_FALSE(variant[-1].success());
  EXPECT_FALSE(variant[3].success());
  EXPECT_FALSE(variant["0"].success());
}

TEST_F(JsonVariant_Subscript_Tests, Object) {
  JsonObject &object = buffer.createObject();
  object["a"] = "element at key \"a\"";
  object["b"] = "element at key \"b\"";

  variant = object;

  EXPECT_EQ(2, variant.size());
  EXPECT_STREQ("element at key \"a\"", variant["a"].asString());
  EXPECT_STREQ("element at key \"b\"", variant["b"].asString());
  EXPECT_FALSE(variant["c"].success());
  EXPECT_FALSE(variant[0].success());
}

TEST_F(JsonVariant_Subscript_Tests, Undefined) {
  variant = JsonVariant();
  EXPECT_EQ(0, variant.size());
  EXPECT_FALSE(variant["0"].success());
  EXPECT_FALSE(variant[0].success());
}

TEST_F(JsonVariant_Subscript_Tests, Invalid) {
  variant = JsonVariant::invalid();
  EXPECT_EQ(0, variant.size());
  EXPECT_FALSE(variant["0"].success());
  EXPECT_FALSE(variant[0].success());
}

TEST_F(JsonVariant_Subscript_Tests, String) {
  variant = "hello world";
  EXPECT_EQ(0, variant.size());
  EXPECT_FALSE(variant["0"].success());
  EXPECT_FALSE(variant[0].success());
}
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBenchmark.h"
#include "SkRandom.h"

#include "SkChunkAlloc.h"
#include "SkDeque.h"
#include "SkTArray.h"
#include "SkTDArray.h"

// This file has several benchmarks using various data structures to do stack-like things:
//   - push
//   - push, immediately pop
//   - push many, pop all of them
//   - serial access
//   - random access
// When a data structure doesn't suppport an operation efficiently, we leave that combination out.
// Where possible we hint to the data structure to allocate in 4K pages.
//
// These benchmarks may help you decide which data structure to use for a dynamically allocated
// ordered list of allocations that grows on one end.
//
// Current overall winner (01/2014): SkTDArray.
// It wins every benchmark on every machine I tried (Desktop, Nexus S, Laptop).

template <typename Impl>
struct StackBench : public SkBenchmark {
    virtual bool isSuitableFor(Backend b) SK_OVERRIDE { return b == kNonRendering_Backend; }
    virtual const char* onGetName() SK_OVERRIDE { return Impl::kName; }
    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE { Impl::bench(loops); }
};

#define BENCH(name)                                                          \
    struct name { static const char* const kName; static void bench(int); }; \
    const char* const name::kName = #name;                                   \
    DEF_BENCH(return new StackBench<name>();)                                \
    void name::bench(int loops)

static const int K = 2049;

// Add K items, then iterate through them serially many times.

BENCH(Deque_Serial) {
    SkDeque s(sizeof(int), 1024);
    for (int i = 0; i < K; i++) *(int*)s.push_back() = i;

    volatile int junk = 0;
    for (int j = 0; j < loops; j++) {
        SkDeque::Iter it(s, SkDeque::Iter::kFront_IterStart);
        while(void* p = it.next()) {
            junk += *(int*)p;
        }
    }
}

BENCH(TArray_Serial) {
    SkTArray<int, true> s;
    for (int i = 0; i < K; i++) s.push_back(i);

    volatile int junk = 0;
    for (int j = 0; j < loops; j++) {
        for (int i = 0; i < s.count(); i++) junk += s[i];
    }
}

BENCH(TDArray_Serial) {
    SkTDArray<int> s;
    for (int i = 0; i < K; i++) s.push(i);

    volatile int junk = 0;
    for (int j = 0; j < loops; j++) {
        for (int i = 0; i < s.count(); i++) junk += s[i];
    }
}

// Add K items, then randomly access them many times.

BENCH(TArray_RandomAccess) {
    SkTArray<int, true> s;
    for (int i = 0; i < K; i++) s.push_back(i);

    SkRandom rand;
    volatile int junk = 0;
    for (int i = 0; i < K*loops; i++) {
        junk += s[rand.nextULessThan(K)];
    }
}

BENCH(TDArray_RandomAccess) {
    SkTDArray<int> s;
    for (int i = 0; i < K; i++) s.push(i);

    SkRandom rand;
    volatile int junk = 0;
    for (int i = 0; i < K*loops; i++) {
        junk += s[rand.nextULessThan(K)];
    }
}

// Push many times.

BENCH(ChunkAlloc_Push) {
    SkChunkAlloc s(4096);
    for (int i = 0; i < K*loops; i++) s.allocThrow(sizeof(int));
}

BENCH(Deque_Push) {
    SkDeque s(sizeof(int), 1024);
    for (int i = 0; i < K*loops; i++) *(int*)s.push_back() = i;
}

BENCH(TArray_Push) {
    SkTArray<int, true> s;
    for (int i = 0; i < K*loops; i++) s.push_back(i);
}

BENCH(TDArray_Push) {
    SkTDArray<int> s;
    for (int i = 0; i < K*loops; i++) s.push(i);
}

// Push then immediately pop many times.

BENCH(ChunkAlloc_PushPop) {
    SkChunkAlloc s(4096);
    for (int i = 0; i < K*loops; i++) {
        void* p = s.allocThrow(sizeof(int));
        s.unalloc(p);
    }
}

BENCH(Deque_PushPop) {
    SkDeque s(sizeof(int), 1024);
    for (int i = 0; i < K*loops; i++) {
        *(int*)s.push_back() = i;
        s.pop_back();
    }
}

BENCH(TArray_PushPop) {
    SkTArray<int, true> s;
    for (int i = 0; i < K*loops; i++) {
        s.push_back(i);
        s.pop_back();
    }
}

BENCH(TDArray_PushPop) {
    SkTDArray<int> s;
    for (int i = 0; i < K*loops; i++) {
        s.push(i);
        s.pop();
    }
}

// Push many items, then pop them all.

BENCH(Deque_PushAllPopAll) {
    SkDeque s(sizeof(int), 1024);
    for (int i = 0; i < K*loops; i++) *(int*)s.push_back() = i;
    for (int i = 0; i < K*loops; i++) s.pop_back();
}

BENCH(TArray_PushAllPopAll) {
    SkTArray<int, true> s;
    for (int i = 0; i < K*loops; i++) s.push_back(i);
    for (int i = 0; i < K*loops; i++) s.pop_back();
}

BENCH(TDArray_PushAllPopAll) {
    SkTDArray<int> s;
    for (int i = 0; i < K*loops; i++) s.push(i);
    for (int i = 0; i < K*loops; i++) s.pop();
}
<commit_msg>For comparison, add std::vector.<commit_after>/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBenchmark.h"
#include "SkRandom.h"

#include "SkChunkAlloc.h"
#include "SkDeque.h"
#include "SkTArray.h"
#include "SkTDArray.h"
#include <vector>

// This file has several benchmarks using various data structures to do stack-like things:
//   - push
//   - push, immediately pop
//   - push many, pop all of them
//   - serial access
//   - random access
// When a data structure doesn't suppport an operation efficiently, we leave that combination out.
// Where possible we hint to the data structure to allocate in 4K pages.
//
// These benchmarks may help you decide which data structure to use for a dynamically allocated
// ordered list of allocations that grows on one end.
//
// Current overall winner (01/2014): SkTDArray.
// It wins every benchmark on every machine I tried (Desktop, Nexus S, Laptop).

template <typename Impl>
struct StackBench : public SkBenchmark {
    virtual bool isSuitableFor(Backend b) SK_OVERRIDE { return b == kNonRendering_Backend; }
    virtual const char* onGetName() SK_OVERRIDE { return Impl::kName; }
    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE { Impl::bench(loops); }
};

#define BENCH(name)                                                          \
    struct name { static const char* const kName; static void bench(int); }; \
    const char* const name::kName = #name;                                   \
    DEF_BENCH(return new StackBench<name>();)                                \
    void name::bench(int loops)

static const int K = 2049;

// Add K items, then iterate through them serially many times.

BENCH(Deque_Serial) {
    SkDeque s(sizeof(int), 1024);
    for (int i = 0; i < K; i++) *(int*)s.push_back() = i;

    volatile int junk = 0;
    for (int j = 0; j < loops; j++) {
        SkDeque::Iter it(s, SkDeque::Iter::kFront_IterStart);
        while(void* p = it.next()) {
            junk += *(int*)p;
        }
    }
}

BENCH(TArray_Serial) {
    SkTArray<int, true> s;
    for (int i = 0; i < K; i++) s.push_back(i);

    volatile int junk = 0;
    for (int j = 0; j < loops; j++) {
        for (int i = 0; i < s.count(); i++) junk += s[i];
    }
}

BENCH(TDArray_Serial) {
    SkTDArray<int> s;
    for (int i = 0; i < K; i++) s.push(i);

    volatile int junk = 0;
    for (int j = 0; j < loops; j++) {
        for (int i = 0; i < s.count(); i++) junk += s[i];
    }
}

BENCH(vector_Serial) {
    std::vector<int> s;
    for (int i = 0; i < K; i++) s.push_back(i);

    volatile int junk = 0;
    for (int j = 0; j < loops; j++) {
        for (size_t i = 0; i < s.size(); i++) junk += s[i];
    }
}

// Add K items, then randomly access them many times.

BENCH(TArray_RandomAccess) {
    SkTArray<int, true> s;
    for (int i = 0; i < K; i++) s.push_back(i);

    SkRandom rand;
    volatile int junk = 0;
    for (int i = 0; i < K*loops; i++) {
        junk += s[rand.nextULessThan(K)];
    }
}

BENCH(TDArray_RandomAccess) {
    SkTDArray<int> s;
    for (int i = 0; i < K; i++) s.push(i);

    SkRandom rand;
    volatile int junk = 0;
    for (int i = 0; i < K*loops; i++) {
        junk += s[rand.nextULessThan(K)];
    }
}

BENCH(vector_RandomAccess) {
    std::vector<int> s;
    for (int i = 0; i < K; i++) s.push_back(i);

    SkRandom rand;
    volatile int junk = 0;
    for (int i = 0; i < K*loops; i++) {
        junk += s[rand.nextULessThan(K)];
    }
}

// Push many times.

BENCH(ChunkAlloc_Push) {
    SkChunkAlloc s(4096);
    for (int i = 0; i < K*loops; i++) s.allocThrow(sizeof(int));
}

BENCH(Deque_Push) {
    SkDeque s(sizeof(int), 1024);
    for (int i = 0; i < K*loops; i++) *(int*)s.push_back() = i;
}

BENCH(TArray_Push) {
    SkTArray<int, true> s;
    for (int i = 0; i < K*loops; i++) s.push_back(i);
}

BENCH(TDArray_Push) {
    SkTDArray<int> s;
    for (int i = 0; i < K*loops; i++) s.push(i);
}

BENCH(vector_Push) {
    std::vector<int> s;
    for (int i = 0; i < K*loops; i++) s.push_back(i);
}

// Push then immediately pop many times.

BENCH(ChunkAlloc_PushPop) {
    SkChunkAlloc s(4096);
    for (int i = 0; i < K*loops; i++) {
        void* p = s.allocThrow(sizeof(int));
        s.unalloc(p);
    }
}

BENCH(Deque_PushPop) {
    SkDeque s(sizeof(int), 1024);
    for (int i = 0; i < K*loops; i++) {
        *(int*)s.push_back() = i;
        s.pop_back();
    }
}

BENCH(TArray_PushPop) {
    SkTArray<int, true> s;
    for (int i = 0; i < K*loops; i++) {
        s.push_back(i);
        s.pop_back();
    }
}

BENCH(TDArray_PushPop) {
    SkTDArray<int> s;
    for (int i = 0; i < K*loops; i++) {
        s.push(i);
        s.pop();
    }
}

BENCH(vector_PushPop) {
    std::vector<int> s;
    for (int i = 0; i < K*loops; i++) {
        s.push_back(i);
        s.pop_back();
    }
}

// Push many items, then pop them all.

BENCH(Deque_PushAllPopAll) {
    SkDeque s(sizeof(int), 1024);
    for (int i = 0; i < K*loops; i++) *(int*)s.push_back() = i;
    for (int i = 0; i < K*loops; i++) s.pop_back();
}

BENCH(TArray_PushAllPopAll) {
    SkTArray<int, true> s;
    for (int i = 0; i < K*loops; i++) s.push_back(i);
    for (int i = 0; i < K*loops; i++) s.pop_back();
}

BENCH(TDArray_PushAllPopAll) {
    SkTDArray<int> s;
    for (int i = 0; i < K*loops; i++) s.push(i);
    for (int i = 0; i < K*loops; i++) s.pop();
}

BENCH(vector_PushAllPopAll) {
    std::vector<int> s;
    for (int i = 0; i < K*loops; i++) s.push_back(i);
    for (int i = 0; i < K*loops; i++) s.pop_back();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <znc/ZNCDebug.h>
#include <znc/Utils.h>
#include <iostream>
#include <sys/time.h>
#include <stdio.h>
#include <time.h>

bool CDebug::stdoutIsTTY = true;
bool CDebug::debug =
#ifdef _DEBUG
    true;
#else
    false;
#endif

CString CDebug::Filter(const CString& sUnfilteredLine) {
    CString sFilteredLine = sUnfilteredLine;

    // If the line is a PASS command to authenticate to a server / znc
    if (sUnfilteredLine.StartsWith("PASS ")) {
        VCString vsSafeCopy;
        sUnfilteredLine.Split(":", vsSafeCopy);

        if (vsSafeCopy.size() > 1) {
            sFilteredLine = vsSafeCopy[0] + ":<censored>";
        }
    }

    return sFilteredLine;
}

CDebugStream::~CDebugStream() {
    timeval tTime = CUtils::GetTime();
    time_t tSec = (time_t)tTime.tv_sec;  // some systems (e.g. openbsd) define
                                         // tv_sec as long int instead of time_t
    tm tM;
    tzset();  // localtime_r requires this
    localtime_r(&tSec, &tM);
    char sTime[20] = {};
    strftime(sTime, sizeof(sTime), "%Y-%m-%d %H:%M:%S", &tM);
    char sUsec[7] = {};
    snprintf(sUsec, sizeof(sUsec), "%06lu", (unsigned long int)tTime.tv_usec);
    std::cout << "[" << sTime << "." << sUsec << "] "
              << CString(this->str()).Escape_n(CString::EDEBUG) << std::endl;
}
<commit_msg>Stop mixing up ./configure --enable-debug with znc --debug<commit_after>/*
 * Copyright (C) 2004-2017 ZNC, see the NOTICE file for details.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <znc/ZNCDebug.h>
#include <znc/Utils.h>
#include <iostream>
#include <sys/time.h>
#include <stdio.h>
#include <time.h>

bool CDebug::stdoutIsTTY = true;
bool CDebug::debug = false;

CString CDebug::Filter(const CString& sUnfilteredLine) {
    CString sFilteredLine = sUnfilteredLine;

    // If the line is a PASS command to authenticate to a server / znc
    if (sUnfilteredLine.StartsWith("PASS ")) {
        VCString vsSafeCopy;
        sUnfilteredLine.Split(":", vsSafeCopy);

        if (vsSafeCopy.size() > 1) {
            sFilteredLine = vsSafeCopy[0] + ":<censored>";
        }
    }

    return sFilteredLine;
}

CDebugStream::~CDebugStream() {
    timeval tTime = CUtils::GetTime();
    time_t tSec = (time_t)tTime.tv_sec;  // some systems (e.g. openbsd) define
                                         // tv_sec as long int instead of time_t
    tm tM;
    tzset();  // localtime_r requires this
    localtime_r(&tSec, &tM);
    char sTime[20] = {};
    strftime(sTime, sizeof(sTime), "%Y-%m-%d %H:%M:%S", &tM);
    char sUsec[7] = {};
    snprintf(sUsec, sizeof(sUsec), "%06lu", (unsigned long int)tTime.tv_usec);
    std::cout << "[" << sTime << "." << sUsec << "] "
              << CString(this->str()).Escape_n(CString::EDEBUG) << std::endl;
}
<|endoftext|>


<commit_before>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/autofill/content/renderer/page_click_tracker.h"

#include "base/command_line.h"
#include "components/autofill/content/renderer/form_autofill_util.h"
#include "components/autofill/content/renderer/page_click_listener.h"
#include "components/autofill/core/common/autofill_util.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
#include "third_party/WebKit/public/platform/WebPoint.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebHitTestResult.h"
#include "third_party/WebKit/public/web/WebInputElement.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebTextAreaElement.h"
#include "third_party/WebKit/public/web/WebView.h"

using blink::WebElement;
using blink::WebGestureEvent;
using blink::WebInputElement;
using blink::WebInputEvent;
using blink::WebMouseEvent;
using blink::WebNode;
using blink::WebPoint;
using blink::WebSize;
using blink::WebTextAreaElement;

namespace {

// Casts |node| to a WebInputElement.
// Returns an empty (isNull()) WebInputElement if |node| is not a text field.
const WebInputElement GetTextWebInputElement(const WebNode& node) {
  if (!node.isElementNode())
    return WebInputElement();
  const WebElement element = node.toConst<WebElement>();
  if (!element.hasHTMLTagName("input"))
    return WebInputElement();
  const WebInputElement* input = blink::toWebInputElement(&element);
  if (!autofill::IsTextInput(input))
    return WebInputElement();
  return *input;
}

// Casts |node| to a WebTextAreaElement.
// Returns an empty (isNull()) WebTextAreaElement if |node| is not a
// textarea field.
const WebTextAreaElement GetWebTextAreaElement(const WebNode& node) {
  if (!node.isElementNode())
    return WebTextAreaElement();
  const WebElement element = node.toConst<WebElement>();
  if (!element.hasHTMLTagName("textarea"))
    return WebTextAreaElement();
  return element.toConst<WebTextAreaElement>();
}

}  // namespace

namespace autofill {

PageClickTracker::PageClickTracker(content::RenderFrame* render_frame,
                                   PageClickListener* listener)
    : content::RenderFrameObserver(render_frame),
      focused_node_was_last_clicked_(false),
      was_focused_before_now_(false),
      listener_(listener),
      legacy_(this) {
}

PageClickTracker::~PageClickTracker() {
}

void PageClickTracker::OnMouseDown(const WebNode& mouse_down_node) {
  focused_node_was_last_clicked_ = !mouse_down_node.isNull() &&
                                   mouse_down_node.focused();
}

void PageClickTracker::FocusedNodeChanged(const WebNode& node) {
  was_focused_before_now_ = false;

  if (IsKeyboardAccessoryEnabled()) {
    focused_node_was_last_clicked_ = true;
    DoFocusChangeComplete();
  }
}

void PageClickTracker::FocusChangeComplete() {
  if (IsKeyboardAccessoryEnabled())
    return;

  DoFocusChangeComplete();
}

void PageClickTracker::DoFocusChangeComplete() {
  WebNode focused_node = render_frame()->GetFocusedElement();
  if (focused_node_was_last_clicked_ && !focused_node.isNull()) {
    const WebInputElement input_element = GetTextWebInputElement(focused_node);
    if (!input_element.isNull()) {
      listener_->FormControlElementClicked(input_element,
                                           was_focused_before_now_);
    } else {
      const WebTextAreaElement textarea_element =
          GetWebTextAreaElement(focused_node);
      if (!textarea_element.isNull()) {
        listener_->FormControlElementClicked(textarea_element,
                                             was_focused_before_now_);
      }
    }
  }

  was_focused_before_now_ = true;
  focused_node_was_last_clicked_ = false;
}

// PageClickTracker::Legacy ----------------------------------------------------

PageClickTracker::Legacy::Legacy(PageClickTracker* tracker)
    : content::RenderViewObserver(tracker->render_frame()->GetRenderView()),
      tracker_(tracker) {
}

void PageClickTracker::Legacy::OnDestruct() {
  // No-op. Don't delete |this|.
}

void PageClickTracker::Legacy::OnMouseDown(const WebNode& mouse_down_node) {
  tracker_->OnMouseDown(mouse_down_node);
}

void PageClickTracker::Legacy::FocusChangeComplete() {
  tracker_->FocusChangeComplete();
}

}  // namespace autofill
<commit_msg>Only user gesture focus change and mouse click show autofill.<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/autofill/content/renderer/page_click_tracker.h"

#include "base/command_line.h"
#include "components/autofill/content/renderer/form_autofill_util.h"
#include "components/autofill/content/renderer/page_click_listener.h"
#include "components/autofill/core/common/autofill_util.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
#include "third_party/WebKit/public/platform/WebPoint.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebHitTestResult.h"
#include "third_party/WebKit/public/web/WebInputElement.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebTextAreaElement.h"
#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
#include "third_party/WebKit/public/web/WebView.h"

using blink::WebElement;
using blink::WebGestureEvent;
using blink::WebInputElement;
using blink::WebInputEvent;
using blink::WebMouseEvent;
using blink::WebNode;
using blink::WebPoint;
using blink::WebSize;
using blink::WebTextAreaElement;
using blink::WebUserGestureIndicator;

namespace {

// Casts |node| to a WebInputElement.
// Returns an empty (isNull()) WebInputElement if |node| is not a text field.
const WebInputElement GetTextWebInputElement(const WebNode& node) {
  if (!node.isElementNode())
    return WebInputElement();
  const WebElement element = node.toConst<WebElement>();
  if (!element.hasHTMLTagName("input"))
    return WebInputElement();
  const WebInputElement* input = blink::toWebInputElement(&element);
  if (!autofill::IsTextInput(input))
    return WebInputElement();
  return *input;
}

// Casts |node| to a WebTextAreaElement.
// Returns an empty (isNull()) WebTextAreaElement if |node| is not a
// textarea field.
const WebTextAreaElement GetWebTextAreaElement(const WebNode& node) {
  if (!node.isElementNode())
    return WebTextAreaElement();
  const WebElement element = node.toConst<WebElement>();
  if (!element.hasHTMLTagName("textarea"))
    return WebTextAreaElement();
  return element.toConst<WebTextAreaElement>();
}

}  // namespace

namespace autofill {

PageClickTracker::PageClickTracker(content::RenderFrame* render_frame,
                                   PageClickListener* listener)
    : content::RenderFrameObserver(render_frame),
      focused_node_was_last_clicked_(false),
      was_focused_before_now_(false),
      listener_(listener),
      legacy_(this) {
}

PageClickTracker::~PageClickTracker() {
}

void PageClickTracker::OnMouseDown(const WebNode& mouse_down_node) {
  focused_node_was_last_clicked_ = !mouse_down_node.isNull() &&
                                   mouse_down_node.focused();

  if (IsKeyboardAccessoryEnabled())
    DoFocusChangeComplete();
}

void PageClickTracker::FocusedNodeChanged(const WebNode& node) {
  was_focused_before_now_ = false;

  if (IsKeyboardAccessoryEnabled() &&
      WebUserGestureIndicator::isProcessingUserGesture()) {
    focused_node_was_last_clicked_ = true;
    DoFocusChangeComplete();
  }
}

void PageClickTracker::FocusChangeComplete() {
  if (IsKeyboardAccessoryEnabled())
    return;

  DoFocusChangeComplete();
}

void PageClickTracker::DoFocusChangeComplete() {
  WebNode focused_node = render_frame()->GetFocusedElement();
  if (focused_node_was_last_clicked_ && !focused_node.isNull()) {
    const WebInputElement input_element = GetTextWebInputElement(focused_node);
    if (!input_element.isNull()) {
      listener_->FormControlElementClicked(input_element,
                                           was_focused_before_now_);
    } else {
      const WebTextAreaElement textarea_element =
          GetWebTextAreaElement(focused_node);
      if (!textarea_element.isNull()) {
        listener_->FormControlElementClicked(textarea_element,
                                             was_focused_before_now_);
      }
    }
  }

  was_focused_before_now_ = true;
  focused_node_was_last_clicked_ = false;
}

// PageClickTracker::Legacy ----------------------------------------------------

PageClickTracker::Legacy::Legacy(PageClickTracker* tracker)
    : content::RenderViewObserver(tracker->render_frame()->GetRenderView()),
      tracker_(tracker) {
}

void PageClickTracker::Legacy::OnDestruct() {
  // No-op. Don't delete |this|.
}

void PageClickTracker::Legacy::OnMouseDown(const WebNode& mouse_down_node) {
  tracker_->OnMouseDown(mouse_down_node);
}

void PageClickTracker::Legacy::FocusChangeComplete() {
  tracker_->FocusChangeComplete();
}

}  // namespace autofill
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2006 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// object that creates and contains a spawn position

#include "common.h"

#include <string>

#include "SpawnPosition.h"
#include "DropGeometry.h"
#include "Obstacle.h"
#include "PlayerInfo.h"
#include "PlayerState.h"
#include "StateDatabase.h"
#include "BZDBCache.h"

// bzfs specific headers
#include "bzfs.h"

SpawnPosition::SpawnPosition(int playerId, bool onGroundOnly, bool notNearEdges) :
		curMaxPlayers(getCurMaxPlayers())
{
  GameKeeper::Player *playerData
    = GameKeeper::Player::getPlayerByIndex(playerId);
  if (!playerData)
    return;

  const PlayerInfo& pi = playerData->player;
  team = pi.getTeam();
  azimuth = (float)(bzfrand() * 2.0 * M_PI);

  if (!BZDB.isTrue("freeCtfSpawns") &&
      playerData->player.shouldRestartAtBase() &&
      (team >= RedTeam) && (team <= PurpleTeam) &&
      (bases.find(team) != bases.end())) {
    TeamBases &teamBases = bases[team];
    const TeamBase &base = teamBases.getRandomBase((int)(bzfrand() * 100));
    base.getRandomPosition(pos[0], pos[1], pos[2]);
    playerData->player.setRestartOnBase(false);
  } else {
    const float tankRadius = BZDBCache::tankRadius;
    safeSWRadius = (float)((BZDB.eval(StateDatabase::BZDB_SHOCKOUTRADIUS) + BZDBCache::tankRadius) * BZDB.eval("_spawnSafeSWMod"));
    safeSRRadius = tankRadius * BZDB.eval("_spawnSafeSRMod");
    safeDistance = tankRadius * BZDB.eval("_spawnSafeRadMod");
    const float size = BZDBCache::worldSize;
    const float maxWorldHeight = world->getMaxWorldHeight();

    // keep track of how much time we spend searching for a location
    TimeKeeper start = TimeKeeper::getCurrent();

    int tries = 0;
    float minProximity = size / BZDB.eval("_spawnSafeSRMod");
    float bestDist = -1.0f;
    bool foundspot = false;
    while (!foundspot) {
      if (!world->getPlayerSpawnPoint(&pi, testPos)) {
	if (notNearEdges) {
	  // don't spawn close to map edges in CTF mode
	  testPos[0] = ((float)bzfrand() - 0.5f) * size * 0.6f;
	  testPos[1] = ((float)bzfrand() - 0.5f) * size * 0.6f;
	} else {
	  testPos[0] = ((float)bzfrand() - 0.5f) * (size - 2.0f * tankRadius);
	  testPos[1] = ((float)bzfrand() - 0.5f) * (size - 2.0f * tankRadius);
	}
	testPos[2] = onGroundOnly ? 0.0f : ((float)bzfrand() * maxWorldHeight);
      }
      tries++;

      const float waterLevel = world->getWaterLevel();
      float minZ = 0.0f;
      if (waterLevel > minZ) {
	minZ = waterLevel;
      }
      float maxZ = maxWorldHeight;
      if (onGroundOnly) {
	maxZ = 0.0f;
      }

      if (DropGeometry::dropPlayer(testPos, minZ, maxZ)) {
	foundspot = true;
      }

      // check every now and then if we have already used up 10ms of time
      if (tries >= 50) {
	tries = 0;
	if (TimeKeeper::getCurrent() - start > BZDB.eval("_spawnMaxCompTime")) {
	  if (bestDist < 0.0f) { // haven't found a single spot
	    //Just drop the sucka in, and pray
	    pos[0] = testPos[0];
	    pos[1] = testPos[1];
	    pos[2] = maxWorldHeight;
	    DEBUG1("Warning: getSpawnLocation ran out of time, just dropping the sucker in\n");
	  }
	  break;
	}
      }

      // check if spot is safe enough
      bool dangerous = isImminentlyDangerous();
      if (foundspot && !dangerous) {
	float enemyAngle;
	float dist = enemyProximityCheck(enemyAngle);
	if (dist > bestDist) { // best so far
	  bestDist = dist;
	  pos[0] = testPos[0];
	  pos[1] = testPos[1];
	  pos[2] = testPos[2];
	  azimuth = fmod((float)(enemyAngle + M_PI), (float)(2.0 * M_PI));
	}
	if (bestDist < minProximity) { // not good enough, keep looking
	  foundspot = false;
	  minProximity *= 0.99f; // relax requirements a little
	}
      } else if (dangerous) {
	foundspot = false;
      }
    }
  }
}

SpawnPosition::~SpawnPosition()
{
}

const bool SpawnPosition::isFacing(const float *enemyPos, const float enemyAzimuth,
				   const float deviation) const
{
  // vector points from test to enemy
  float dx = enemyPos[0] - testPos[0];
  float dy = enemyPos[1] - testPos[1];
  float angActual = atan2f (dy, dx);
  float diff = fmodf(enemyAzimuth - angActual, (float)M_PI * 2.0f);

  // now diff is between {-PI*2 and +PI*2}, and we're looking for values around
  // -PI or +PI, because that's when the enemy is facing the source.
  diff = fabsf (diff); // between {0 and +PI*2}
  diff = fabsf ((float)(diff - M_PI));

  if (diff < (deviation / 2.0f)) {
    return true;
  } else {
    return false;
  }
}

const bool SpawnPosition::isImminentlyDangerous() const
{
  GameKeeper::Player *playerData;
  for (int i = 0; i < curMaxPlayers; i++) {
    playerData = GameKeeper::Player::getPlayerByIndex(i);
    if (!playerData)
      continue;
    if (playerData->player.isAlive()) {
      float *enemyPos   = playerData->lastState.pos;
      float  enemyAngle = playerData->lastState.azimuth;
      if (playerData->player.getFlag() >= 0) {
	// check for dangerous flags
	const FlagInfo *finfo = FlagInfo::get(playerData->player.getFlag());
	const FlagType *ftype = finfo->flag.type;
	// FIXME: any more?
	if (ftype == Flags::Laser) {  // don't spawn in the line of sight of an L
	  if (isFacing(enemyPos, enemyAngle, (float)(M_PI / 9.0))) { // he's looking within 20 degrees of spawn point
	    return true;	// eek, don't spawn here
	  }
	} else if (ftype == Flags::ShockWave) {  // don't spawn next to a SW
	  if (distanceFrom(enemyPos) < safeSWRadius) { // too close to SW
	    return true;	// eek, don't spawn here
	  }
	} else if (ftype == Flags::Steamroller || ftype == Flags::Burrow) { // don't spawn if you'll squish or be squished
	  if (distanceFrom(enemyPos) < safeSRRadius) { // too close to SR or BU
	    return true;	// eek, don't spawn here
	  }
	}
      }
      // don't spawn in the line of sight of a normal-shot tank within a certain distance
      if (distanceFrom(enemyPos) < safeDistance) { // within danger zone?
	if (isFacing(enemyPos, enemyAngle, (float)(M_PI / 9.0))) { //and he's looking at me
	  return true;
	}
      }
    }
  }

  // TODO: should check world weapons also

  return false;
}

const float SpawnPosition::enemyProximityCheck(float &enemyAngle) const
{
  GameKeeper::Player *playerData;
  float worstDist = 1e12f; // huge number
  bool noEnemy    = true;

  for (int i = 0; i < curMaxPlayers; i++) {
    playerData = GameKeeper::Player::getPlayerByIndex(i);
    if (!playerData)
      continue;
    if (playerData->player.isAlive()
	&& areFoes(playerData->player.getTeam(), team)) {
      float *enemyPos = playerData->lastState.pos;
      if (fabs(enemyPos[2] - testPos[2]) < 1.0f) {
	float x = enemyPos[0] - testPos[0];
	float y = enemyPos[1] - testPos[1];
	float distSq = x * x + y * y;
	if (distSq < worstDist) {
	  worstDist  = distSq;
	  enemyAngle = playerData->lastState.azimuth;
	  noEnemy    = false;
	}
      }
    }
  }
  if (noEnemy)
    enemyAngle = (float)(bzfrand() * 2.0 * M_PI);
  return sqrtf(worstDist);
}

const float SpawnPosition::distanceFrom(const float* farPos) const
{
  float dx = farPos[0] - testPos[0];
  float dy = farPos[1] - testPos[1];
  float dz = farPos[2] - testPos[2];
  return (float)sqrt(dx*dx + dy*dy + dz*dz);
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>Do not consider facing lasers above or below the spawn position as dangerous.<commit_after>/* bzflag
 * Copyright (c) 1993 - 2006 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// object that creates and contains a spawn position

#include "common.h"

#include <string>

#include "SpawnPosition.h"
#include "DropGeometry.h"
#include "Obstacle.h"
#include "PlayerInfo.h"
#include "PlayerState.h"
#include "StateDatabase.h"
#include "BZDBCache.h"

// bzfs specific headers
#include "bzfs.h"

SpawnPosition::SpawnPosition(int playerId, bool onGroundOnly, bool notNearEdges) :
		curMaxPlayers(getCurMaxPlayers())
{
  GameKeeper::Player *playerData
    = GameKeeper::Player::getPlayerByIndex(playerId);
  if (!playerData)
    return;

  const PlayerInfo& pi = playerData->player;
  team = pi.getTeam();
  azimuth = (float)(bzfrand() * 2.0 * M_PI);

  if (!BZDB.isTrue("freeCtfSpawns") &&
      playerData->player.shouldRestartAtBase() &&
      (team >= RedTeam) && (team <= PurpleTeam) &&
      (bases.find(team) != bases.end())) {
    TeamBases &teamBases = bases[team];
    const TeamBase &base = teamBases.getRandomBase((int)(bzfrand() * 100));
    base.getRandomPosition(pos[0], pos[1], pos[2]);
    playerData->player.setRestartOnBase(false);
  } else {
    const float tankRadius = BZDBCache::tankRadius;
    safeSWRadius = (float)((BZDB.eval(StateDatabase::BZDB_SHOCKOUTRADIUS) + BZDBCache::tankRadius) * BZDB.eval("_spawnSafeSWMod"));
    safeSRRadius = tankRadius * BZDB.eval("_spawnSafeSRMod");
    safeDistance = tankRadius * BZDB.eval("_spawnSafeRadMod");
    const float size = BZDBCache::worldSize;
    const float maxWorldHeight = world->getMaxWorldHeight();

    // keep track of how much time we spend searching for a location
    TimeKeeper start = TimeKeeper::getCurrent();

    int tries = 0;
    float minProximity = size / BZDB.eval("_spawnSafeSRMod");
    float bestDist = -1.0f;
    bool foundspot = false;
    while (!foundspot) {
      if (!world->getPlayerSpawnPoint(&pi, testPos)) {
	if (notNearEdges) {
	  // don't spawn close to map edges in CTF mode
	  testPos[0] = ((float)bzfrand() - 0.5f) * size * 0.6f;
	  testPos[1] = ((float)bzfrand() - 0.5f) * size * 0.6f;
	} else {
	  testPos[0] = ((float)bzfrand() - 0.5f) * (size - 2.0f * tankRadius);
	  testPos[1] = ((float)bzfrand() - 0.5f) * (size - 2.0f * tankRadius);
	}
	testPos[2] = onGroundOnly ? 0.0f : ((float)bzfrand() * maxWorldHeight);
      }
      tries++;

      const float waterLevel = world->getWaterLevel();
      float minZ = 0.0f;
      if (waterLevel > minZ) {
	minZ = waterLevel;
      }
      float maxZ = maxWorldHeight;
      if (onGroundOnly) {
	maxZ = 0.0f;
      }

      if (DropGeometry::dropPlayer(testPos, minZ, maxZ)) {
	foundspot = true;
      }

      // check every now and then if we have already used up 10ms of time
      if (tries >= 50) {
	tries = 0;
	if (TimeKeeper::getCurrent() - start > BZDB.eval("_spawnMaxCompTime")) {
	  if (bestDist < 0.0f) { // haven't found a single spot
	    //Just drop the sucka in, and pray
	    pos[0] = testPos[0];
	    pos[1] = testPos[1];
	    pos[2] = maxWorldHeight;
	    DEBUG1("Warning: getSpawnLocation ran out of time, just dropping the sucker in\n");
	  }
	  break;
	}
      }

      // check if spot is safe enough
      bool dangerous = isImminentlyDangerous();
      if (foundspot && !dangerous) {
	float enemyAngle;
	float dist = enemyProximityCheck(enemyAngle);
	if (dist > bestDist) { // best so far
	  bestDist = dist;
	  pos[0] = testPos[0];
	  pos[1] = testPos[1];
	  pos[2] = testPos[2];
	  azimuth = fmod((float)(enemyAngle + M_PI), (float)(2.0 * M_PI));
	}
	if (bestDist < minProximity) { // not good enough, keep looking
	  foundspot = false;
	  minProximity *= 0.99f; // relax requirements a little
	}
      } else if (dangerous) {
	foundspot = false;
      }
    }
  }
}

SpawnPosition::~SpawnPosition()
{
}

const bool SpawnPosition::isFacing(const float *enemyPos, const float enemyAzimuth,
				   const float deviation) const
{
  // vector points from test to enemy
  float dx = enemyPos[0] - testPos[0];
  float dy = enemyPos[1] - testPos[1];
  float dz = enemyPos[2] - testPos[2];
  float angActual = atan2f (dy, dx);
  float diff = fmodf(enemyAzimuth - angActual, (float)M_PI * 2.0f);

  // Ignore tanks that are above or below us
  if (fabs(dz) > 2.0f * BZDBCache::tankHeight )
    return false;

  // now diff is between {-PI*2 and +PI*2}, and we're looking for values around
  // -PI or +PI, because that's when the enemy is facing the source.
  diff = fabsf (diff); // between {0 and +PI*2}
  diff = fabsf ((float)(diff - M_PI));

  if (diff < (deviation / 2.0f)) {
    return true;
  } else {
    return false;
  }
}

const bool SpawnPosition::isImminentlyDangerous() const
{
  GameKeeper::Player *playerData;
  float twentyDegrees = (float)(M_PI / 9.0);
  for (int i = 0; i < curMaxPlayers; i++) {
    playerData = GameKeeper::Player::getPlayerByIndex(i);
    if (!playerData)
      continue;
    if (playerData->player.isAlive()) {
      float *enemyPos   = playerData->lastState.pos;
      float  enemyAngle = playerData->lastState.azimuth;
      if (playerData->player.getFlag() >= 0) {
	// check for dangerous flags
	const FlagInfo *finfo = FlagInfo::get(playerData->player.getFlag());
	const FlagType *ftype = finfo->flag.type;
	// FIXME: any more?
	if (ftype == Flags::Laser) {  // don't spawn in the line of sight of an L
	  if (isFacing(enemyPos, enemyAngle, twentyDegrees)) { // he's looking within 20 degrees of spawn point
	    return true;	// eek, don't spawn here
	  }
	} else if (ftype == Flags::ShockWave) {  // don't spawn next to a SW
	  if (distanceFrom(enemyPos) < safeSWRadius) { // too close to SW
	    return true;	// eek, don't spawn here
	  }
	} else if (ftype == Flags::Steamroller || ftype == Flags::Burrow) { // don't spawn if you'll squish or be squished
	  if (distanceFrom(enemyPos) < safeSRRadius) { // too close to SR or BU
	    return true;	// eek, don't spawn here
	  }
	}
      }
      // don't spawn in the line of sight of a normal-shot tank within a certain distance
      if (distanceFrom(enemyPos) < safeDistance) { // within danger zone?
	if (isFacing(enemyPos, enemyAngle, twentyDegrees)) { //and he's looking at me
	  return true;
	}
      }
    }
  }

  // TODO: should check world weapons also

  return false;
}

const float SpawnPosition::enemyProximityCheck(float &enemyAngle) const
{
  GameKeeper::Player *playerData;
  float worstDist = 1e12f; // huge number
  bool noEnemy    = true;

  for (int i = 0; i < curMaxPlayers; i++) {
    playerData = GameKeeper::Player::getPlayerByIndex(i);
    if (!playerData)
      continue;
    if (playerData->player.isAlive()
	&& areFoes(playerData->player.getTeam(), team)) {
      float *enemyPos = playerData->lastState.pos;
      if (fabs(enemyPos[2] - testPos[2]) < 1.0f) {
	float x = enemyPos[0] - testPos[0];
	float y = enemyPos[1] - testPos[1];
	float distSq = x * x + y * y;
	if (distSq < worstDist) {
	  worstDist  = distSq;
	  enemyAngle = playerData->lastState.azimuth;
	  noEnemy    = false;
	}
      }
    }
  }
  if (noEnemy)
    enemyAngle = (float)(bzfrand() * 2.0 * M_PI);
  return sqrtf(worstDist);
}

const float SpawnPosition::distanceFrom(const float* farPos) const
{
  float dx = farPos[0] - testPos[0];
  float dy = farPos[1] - testPos[1];
  float dz = farPos[2] - testPos[2];
  return (float)sqrt(dx*dx + dy*dy + dz*dz);
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/*
 * bacteria-core, core for cellular automaton
 * Copyright (C) 2016 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#include <QStringList>

#include <boost/foreach.hpp>

#include <iostream>
#include <string>

#include "YamlReader.hpp"
#include "YamlEmitter.hpp"

#include "CoreGlobals.hpp"
#include "Creator.hpp"
#include "Model.hpp"
#include "Changer.hpp"
#include "Interpreter.hpp"
#include "Exception.hpp"

static Units getUnits(const ModelPtr& model, int teams) {
    Units units;
    for (int team = 0; team < teams; team++) {
        for (int b = 0; b < model->getBacteriaNumber(team); b++) {
            Implementation::Unit unit(
                model->getCoordinates(team, b),
                model->getMass(team, b),
                model->getDirection(team, b),
                team,
                model->getInstruction(team, b)
            );
            units.push_back(unit);
        }
    }
    return units;
}

static void writeResults(
    const std::string& output_yaml,
    ModelPtr& model,
    int teams
) {
    YamlEmitter emitter;
    emitter.writeWidth(model->getWidth());
    emitter.writeHeight(model->getHeight());
    Units units = getUnits(model, teams);
    emitter.writeUnits(units);
    std::ofstream out_file(output_yaml.c_str());
    out_file << emitter.out_;
}

static void runTest(
    ModelPtr& model,
    ChangerPtrs& changers,
    InterpreterPtr& interpreter,
    int moves_number
) {
    for (int move = 0; move < moves_number; move++) {
        BOOST_FOREACH (ChangerPtr changer, changers) {
            interpreter->makeMove(*(changer.data()), 0);
        }
    }
}

// Return number of moves
static int createEverything(
    const std::string& input_yaml,
    const QStringList& scripts,
    ModelPtr& model,
    ChangerPtrs& changers,
    InterpreterPtr& interpreter
) {
    YamlReader reader(input_yaml);
    int width = reader.getWidth();
    int height = reader.getHeight();
    int moves_number = reader.getMovesNumber();
    Units units = reader.getUnits();
    model = Creator::createSpecialModel(
        width,
        height,
        scripts.size(),
        units
    );
    interpreter = Creator::createCoreObjects(
        model,
        scripts,
        changers
    );
    return moves_number;
}

static void argParse(
    int argc,
    char* argv[],
    std::string& input_yaml,
    std::string& output_yaml,
    QStringList& scripts
) {
    // input yaml, script and output yaml
    int min_args_number = 4;
    if (argc < min_args_number) {
        throw Exception(
            "Integration tests: you must specify input yaml, "
            "script(s) and output yaml in args."
        );
    }
    input_yaml = argv[1];
    for (int i = 2; i < argc - 1; i++) {
        scripts.append(argv[i]);
    }
    output_yaml = argv[argc - 1];
}

int main(int argc, char* argv[]) {
    std::string input_yaml, output_yaml;
    QStringList scripts;
    argParse(
        argc,
        argv,
        input_yaml,
        output_yaml,
        scripts
    );
    ModelPtr model;
    ChangerPtrs changers;
    InterpreterPtr interpreter;
    int moves_number = createEverything(
        input_yaml,
        scripts,
        model,
        changers,
        interpreter
    );
    runTest(model, changers, interpreter, moves_number);
    writeResults(output_yaml, model, changers.size());
    return 0;
}
<commit_msg>Integration tests: clear model in runTest() func<commit_after>/*
 * bacteria-core, core for cellular automaton
 * Copyright (C) 2016 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#include <QStringList>

#include <boost/foreach.hpp>

#include <iostream>
#include <string>

#include "YamlReader.hpp"
#include "YamlEmitter.hpp"

#include "CoreGlobals.hpp"
#include "Creator.hpp"
#include "Model.hpp"
#include "Changer.hpp"
#include "Interpreter.hpp"
#include "Exception.hpp"

static Units getUnits(const ModelPtr& model, int teams) {
    Units units;
    for (int team = 0; team < teams; team++) {
        for (int b = 0; b < model->getBacteriaNumber(team); b++) {
            Implementation::Unit unit(
                model->getCoordinates(team, b),
                model->getMass(team, b),
                model->getDirection(team, b),
                team,
                model->getInstruction(team, b)
            );
            units.push_back(unit);
        }
    }
    return units;
}

static void writeResults(
    const std::string& output_yaml,
    ModelPtr& model,
    int teams
) {
    YamlEmitter emitter;
    emitter.writeWidth(model->getWidth());
    emitter.writeHeight(model->getHeight());
    Units units = getUnits(model, teams);
    emitter.writeUnits(units);
    std::ofstream out_file(output_yaml.c_str());
    out_file << emitter.out_;
}

static void runTest(
    ModelPtr& model,
    ChangerPtrs& changers,
    InterpreterPtr& interpreter,
    int moves_number
) {
    for (int move = 0; move < moves_number; move++) {
        BOOST_FOREACH (ChangerPtr changer, changers) {
            interpreter->makeMove(*(changer.data()), 0);
        }
    }
    BOOST_FOREACH (ChangerPtr changer, changers) {
        changer->clearBeforeMove();
    }
}

// Return number of moves
static int createEverything(
    const std::string& input_yaml,
    const QStringList& scripts,
    ModelPtr& model,
    ChangerPtrs& changers,
    InterpreterPtr& interpreter
) {
    YamlReader reader(input_yaml);
    int width = reader.getWidth();
    int height = reader.getHeight();
    int moves_number = reader.getMovesNumber();
    Units units = reader.getUnits();
    model = Creator::createSpecialModel(
        width,
        height,
        scripts.size(),
        units
    );
    interpreter = Creator::createCoreObjects(
        model,
        scripts,
        changers
    );
    return moves_number;
}

static void argParse(
    int argc,
    char* argv[],
    std::string& input_yaml,
    std::string& output_yaml,
    QStringList& scripts
) {
    // input yaml, script and output yaml
    int min_args_number = 4;
    if (argc < min_args_number) {
        throw Exception(
            "Integration tests: you must specify input yaml, "
            "script(s) and output yaml in args."
        );
    }
    input_yaml = argv[1];
    for (int i = 2; i < argc - 1; i++) {
        scripts.append(argv[i]);
    }
    output_yaml = argv[argc - 1];
}

int main(int argc, char* argv[]) {
    std::string input_yaml, output_yaml;
    QStringList scripts;
    argParse(
        argc,
        argv,
        input_yaml,
        output_yaml,
        scripts
    );
    ModelPtr model;
    ChangerPtrs changers;
    InterpreterPtr interpreter;
    int moves_number = createEverything(
        input_yaml,
        scripts,
        model,
        changers,
        interpreter
    );
    runTest(model, changers, interpreter, moves_number);
    writeResults(output_yaml, model, changers.size());
    return 0;
}
<|endoftext|>


<commit_before>//
//  main.cpp
//  casting
//
//  Created by Sunil on 2/21/17.
//  Copyright © 2017 Sunil. All rights reserved.
//

#include <iostream>
#include <memory>

#include "base.hpp"
#include "derived.hpp"

using namespace std;

struct Person {
    string name;
    int id;
};

struct Doppelganger {
    string name;
    int id;
    bool fake = true;

    Doppelganger(string n, int i) {
        name =  n;
        id = i;
    }
};

void logAndPrint(shared_ptr<base> p) {
    cout << "In log " << p.use_count() << endl;
    // dynamic_pointer_cast is only experimental.
    // ref: http://en.cppreference.com/w/cpp/experimental/shared_ptr/pointer_cast
    // auto d = dynamic_pointer_cast<derived>(p);

    // C++11 casting:
    // * const_cast, reinterpret_cast, dynamic_cast, static_cast
    // * static_pointer_cast, const_pointer_cast, dynamic_pointer_cast
    auto d = dynamic_pointer_cast<derived>(p);
    if (d) {
        //d->extraPrint();
        d->extraPrint();
    }

    if (p) {
        p->print();
    }
}

// ref: https://arne-mertz.de/2015/01/a-casting-show/
void nochange(Person const& person) {
    // person object shouldn't be changed.
    // person.name = "changed!"; // error

    // throw away the constness and change it anyway!
    Person& sudo = const_cast<Person&>(person);
    sudo.name = "changed!";
    sudo.id = 56;
}

// reinterpret_cast works only with pointers on unrelated types
void fake(Person* p) {
    cout << "real person: " << p->name << " " << p->id << endl;
    Doppelganger* d = reinterpret_cast<Doppelganger*>(p);
    if(d) {
        cout << boolalpha << "fake person: " << d->name << " " << d->id << d->fake << endl;
    }
}

void fake(Doppelganger* p) {
    Doppelganger* d = reinterpret_cast<Doppelganger*>(p);
    if(d) {
        cout << boolalpha << "fake person: " << d->name << " " << d->id << d->fake << endl;
    }
}

// static_cast: aware of narrowing
// caution: Also works if dynamic types are known and gaurenteed at runtime
void convert(float f) {
    int v = static_cast<int>(f);
    cout << "val = " << v << endl;
}

// dynamic_cast used for downcasts/ crosscasts on related types(class hierarchy).
// works only on pointers
void downcast(base* b) {
    derived* d = dynamic_cast<derived*>(b);
    if (d) {
        d->extraPrint();
        d->print();
    }
}

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

    cout << "const_cast example" << endl;
    {
        Person p = {.name="Sunil", .id = 99};
        nochange(p);
        cout << p.name << " " << p.id << endl;
    }
    cout << "-----------------" << endl;

    cout << "reinterpret_cast example" << endl;
    {
        Person p = {.name="Sunil", .id = 99};
        fake(&p);

        Doppelganger f("Hello",98);
        fake(&f);
    }
    cout << "-----------------" << endl;

    cout << "static_cast example" << endl;
    {
        float d = 45.454656;
        convert(d);
    }
    cout << "-----------------" << endl;

    cout << "dynamic_cast example" << endl;
    {
        auto b = new derived("hello");
        downcast(b);
        delete b;

        Person p = {"Sunil", 56};
        // Doppelganger* d = dynamic_cast<Doppelganger*>(&p); // error . unrelated types
        Doppelganger* d = reinterpret_cast<Doppelganger*>(&p);
        if(d) {
            cout << d->name << d->id << d->fake << endl;
        }
    }
    cout << "-----------------" << endl;

    cout << "base pointing to base" << endl;
    {
        shared_ptr<base> b(new base("base"));
        b->print();
        logAndPrint(b);
    }
    cout << "-----------------" << endl;

    cout << "derived pointing to derived" << endl;
    {
        shared_ptr<derived> d(new derived("derived"));
        d->print();
        logAndPrint(d);
    }
    cout << "-----------------" << endl;

    cout << "base pointing to derived" << endl;
    {
        shared_ptr<base> d(new derived("derived"));
        d->print();
        logAndPrint(d);
    }
    cout << "-----------------" << endl;

    cout << "experimenting with smart pointers." << endl;
    {
        logAndPrint(nullptr);
        if (nullptr == NULL) {
            cout << "nullptr and NULL are one and the same" << endl;
        }
        shared_ptr<shared_ptr<base>> b(new shared_ptr<base>(new base("weird")));
        b->operator->()->print();
    }
    cout << "-----------------" << endl;

    return 0;
}
<commit_msg>Call fake function for both person and doppleganger<commit_after>//
//  main.cpp
//  casting
//
//  Created by Sunil on 2/21/17.
//  Copyright © 2017 Sunil. All rights reserved.
//

#include <iostream>
#include <memory>

#include "base.hpp"
#include "derived.hpp"

using namespace std;

struct Person {
    string name;
    int id;
};

struct Doppelganger {
    string name;
    int id;
    bool fake = true;

    Doppelganger(string n, int i) {
        name =  n;
        id = i;
    }
};

void logAndPrint(shared_ptr<base> p) {
    cout << "In log " << p.use_count() << endl;
    // dynamic_pointer_cast is only experimental.
    // ref: http://en.cppreference.com/w/cpp/experimental/shared_ptr/pointer_cast
    // auto d = dynamic_pointer_cast<derived>(p);

    // C++11 casting:
    // * const_cast, reinterpret_cast, dynamic_cast, static_cast
    // * static_pointer_cast, const_pointer_cast, dynamic_pointer_cast
    auto d = dynamic_pointer_cast<derived>(p);
    if (d) {
        //d->extraPrint();
        d->extraPrint();
    }

    if (p) {
        p->print();
    }
}

// ref: https://arne-mertz.de/2015/01/a-casting-show/
void nochange(const Person& person) {
    // person object shouldn't be changed.
    // person.name = "changed!"; // error

    // throw away the constness and change it anyway!
    Person& sudo = const_cast<Person&>(person);
    sudo.name = "changed!";
    sudo.id = 56;
}

// reinterpret_cast works only with pointers on unrelated types
void fake(Person* p) {
    cout << "person: " << p->name << " " << p->id << endl;
    Doppelganger* d = reinterpret_cast<Doppelganger*>(p);
    if(d && d->fake) {
        cout << boolalpha << "fake person: " << d->name << " " << d->id << d->fake << endl;
    }
}

// void fake(Doppelganger* p) {
//     Doppelganger* d = reinterpret_cast<Doppelganger*>(p);
//     if(d) {
//         cout << boolalpha << "fake person: " << d->name << " " << d->id << d->fake << endl;
//     }
// }

// static_cast: aware of narrowing
// caution: Also works if dynamic types are known and gaurenteed at runtime
void convert(float f) {
    int v = static_cast<int>(f);
    cout << "val = " << v << endl;
}

// dynamic_cast used for downcasts/ crosscasts on related types(class hierarchy).
// works only on pointers
void downcast(base* b) {
    derived* d = dynamic_cast<derived*>(b);
    if (d) {
        d->extraPrint();
        d->print();
    }
}

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

    cout << "const_cast example" << endl;
    {
        Person p = {.name="Sunil", .id = 99};
        nochange(p);
        cout << p.name << " " << p.id << endl;
    }
    cout << "-----------------" << endl;

    cout << "reinterpret_cast example" << endl;
    {
        Person p = {.name="Sunil", .id = 99};
        fake(&p);

        Doppelganger f("Hello",98);
        fake(reinterpret_cast<Person*>(&f));
    }
    cout << "-----------------" << endl;

    cout << "static_cast example" << endl;
    {
        float d = 45.454656;
        convert(d);
    }
    cout << "-----------------" << endl;

    cout << "dynamic_cast example" << endl;
    {
        auto b = new derived("hello");
        downcast(b);
        delete b;

        Person p = {"Sunil", 56};
        // Doppelganger* d = dynamic_cast<Doppelganger*>(&p); // error . unrelated types
        Doppelganger* d = reinterpret_cast<Doppelganger*>(&p);
        if(d) {
            cout << d->name << d->id << d->fake << endl;
        }
    }
    cout << "-----------------" << endl;

    cout << "base pointing to base" << endl;
    {
        shared_ptr<base> b(new base("base"));
        b->print();
        logAndPrint(b);
    }
    cout << "-----------------" << endl;

    cout << "derived pointing to derived" << endl;
    {
        shared_ptr<derived> d(new derived("derived"));
        d->print();
        logAndPrint(d);
    }
    cout << "-----------------" << endl;

    cout << "base pointing to derived" << endl;
    {
        shared_ptr<base> d(new derived("derived"));
        d->print();
        logAndPrint(d);
    }
    cout << "-----------------" << endl;

    cout << "experimenting with smart pointers." << endl;
    {
        logAndPrint(nullptr);
        if (nullptr == NULL) {
            cout << "nullptr and NULL are one and the same" << endl;
        }
        shared_ptr<shared_ptr<base>> b(new shared_ptr<base>(new base("weird")));
        b->operator->()->print();
    }
    cout << "-----------------" << endl;

    return 0;
}
<|endoftext|>


<commit_before>// Test the mmap_limit_mb flag.
//
// RUN: %clangxx_asan -std=c++11 -O2 %s -o %t
// RUN: %t 100 16
// RUN: %t 100 1000000
// RUN: ASAN_OPTIONS=mmap_limit_mb=500 %t 100 16
// RUN: ASAN_OPTIONS=mmap_limit_mb=500 %t 100 1000000
// RUN: ASAN_OPTIONS=mmap_limit_mb=500 not %t 500 16 2>&1 | FileCheck %s
// RUN: ASAN_OPTIONS=mmap_limit_mb=500 not %t 500 1000000 2>&1 | FileCheck %s

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

#include <algorithm>
#include <vector>

int main(int argc, char **argv) {
  assert(argc == 3);
  long total_mb = atoi(argv[1]);
  long allocation_size = atoi(argv[2]);
  std::vector<char *> v;
  for (long total = total_mb << 20; total > 0; total -= allocation_size)
    v.push_back(new char[allocation_size]);
  std::for_each(v.begin(), v.end(),
                [](std::vector<char *>::reference ref) { delete[] ref; });
  printf("PASS\n");
  // CHECK: AddressSanitizer CHECK failed{{.*}}total_mmaped{{.*}}mmap_limit_mb
  return 0;
}
<commit_msg>[asan] Do not use lambda in sanitizer lit tests.<commit_after>// Test the mmap_limit_mb flag.
//
// RUN: %clangxx_asan -std=c++11 -O2 %s -o %t
// RUN: %t 100 16
// RUN: %t 100 1000000
// RUN: ASAN_OPTIONS=mmap_limit_mb=500 %t 100 16
// RUN: ASAN_OPTIONS=mmap_limit_mb=500 %t 100 1000000
// RUN: ASAN_OPTIONS=mmap_limit_mb=500 not %t 500 16 2>&1 | FileCheck %s
// RUN: ASAN_OPTIONS=mmap_limit_mb=500 not %t 500 1000000 2>&1 | FileCheck %s

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

#include <algorithm>
#include <vector>

int main(int argc, char **argv) {
  assert(argc == 3);
  long total_mb = atoi(argv[1]);
  long allocation_size = atoi(argv[2]);
  std::vector<char *> v;
  for (long total = total_mb << 20; total > 0; total -= allocation_size)
    v.push_back(new char[allocation_size]);
  for (auto p : v) delete[] p;
  printf("PASS\n");
  // CHECK: AddressSanitizer CHECK failed{{.*}}total_mmaped{{.*}}mmap_limit_mb
  return 0;
}
<|endoftext|>


<commit_before>#include <boost/test/unit_test.hpp>
#include <envire_core/all>
#include <envire/Core.hpp>
#include <chrono>
#include <iostream>

using namespace std;
using namespace Eigen;

/**
 *  1.) add 100 children to root node.
 *  2.) create a chain of 100 children.
 *  3.) update each transform in the chain once.
 *
 *
 *  Repeat all tests several times and calc avg
 *
 *
 * */

const double newAdd10000Children()
{
    using namespace envire::core;
    TransformGraph graph;
    const FrameId root("root");
    graph.addFrame(root);

    //create frameids beforehand. we dont want to benchmark boost::lexical_cast
    vector<FrameId> ids;
    for(int i = 0; i < 10000; ++i)
    {
        ids.push_back(boost::lexical_cast<FrameId>(i));
    }

    envire::core::Transform tf;

    auto start = chrono::steady_clock::now();
    for(size_t i = 0; i < 10000; ++i)
    {
        graph.addTransform(root, ids[i], tf);
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;

}

const double oldAdd10000Children()
{
    using namespace envire;

    boost::scoped_ptr<Environment> env(new Environment());
    Affine3d transform(Translation3d( 0.0, 0.0, 0.5 ));

    FrameNode* root = env->getRootNode();
    auto start = chrono::steady_clock::now();
    for(size_t i = 0; i < 10000; ++i)
    {
        FrameNode* pNode = new FrameNode();
        pNode->setTransform(transform);
        env->addChild(root, pNode);
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

const double oldAdd10000Chain()
{
  using namespace envire;

  boost::scoped_ptr<Environment> env(new Environment());
  Affine3d transform(Translation3d( 0.0, 0.0, 0.5 ));

  auto start = chrono::steady_clock::now();

  FrameNode* node = env->getRootNode();
  for(int i = 0; i < 10000; ++i)
  {
      FrameNode* child = new FrameNode();
      child->setTransform(transform);
      env->addChild(node, child);
      node = child;
  }

  auto end = chrono::steady_clock::now();
  double diff = chrono::duration <double, milli> (end - start).count();
  return diff;
}

const double newAdd10000Chain()
{
    using namespace envire::core;
    TransformGraph graph;
    envire::core::Transform tf;

    //create frameids beforehand. we dont want to benchmark boost::lexical_cast
    vector<FrameId> ids;
    for(int i = 0; i < 10000; ++i)
    {
        ids.push_back(boost::lexical_cast<FrameId>(i));
    }

    auto start = chrono::steady_clock::now();
    for(int i = 0; i < 10000 - 1; ++i)
    {
        graph.addTransform(ids[i], ids[i+1], tf);
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

/**Helper method that builds a tree of depth @p i with 4 children per node */
void addFourChildren(envire::core::TransformGraph& graph, const envire::core::FrameId& id, const int i)
{
  if(i == 0)
      return;
  for(int j = 0; j < 4; ++j)
  {
      envire::core::Transform tf;
      tf.setTransform(base::TransformWithCovariance::Identity());
      const envire::core::FrameId newId = id + boost::lexical_cast<envire::core::FrameId>(j);
      graph.addTransform(id, newId, tf);
      addFourChildren(graph, newId, i - 1);
  }
}

/**Calculate the transform for a path of length 4 in a tree of depth 4 where
   each vertex has 4 children*/
const double newTranformSearch10000()
{
    using namespace envire::core;
    TransformGraph graph;
    const FrameId root("4");
    graph.addFrame(root);
    addFourChildren(graph, root, 3);

    GraphViz viz;
    viz.write(graph, "test.dot");

    //we search from "4" to "4333" which is the rightmost child
    //according to the naming schema of addFourChildren()

    auto start = chrono::steady_clock::now();
    for(int i = 0; i < 10000; ++i)
    {
        const envire::core::Transform tf = graph.getTransform("4", "4333");
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

/** same as addFourChildren() for the old envire. returns the rightmost child */
envire::FrameNode* addFourChildrenOld(envire::Environment* env, envire::FrameNode* parent, const int i)
{
  envire::FrameNode* target = NULL;
  if(i == 0)
      return parent;
  for(int j = 0; j < 4; ++j)
  {
      Affine3d transform(Translation3d( 0.0, 0.0, 0.5 ));
      envire::FrameNode* child = new envire::FrameNode();
      child->setTransform(transform);
      env->addChild(parent, child);
      target =  addFourChildrenOld(env, child, i - 1);
  }
  return target;
}

const double oldTransformSearch10000()
{
    using namespace envire;
    boost::scoped_ptr<Environment> env(new Environment());
    FrameNode* root = new FrameNode();
    FrameNode* target = addFourChildrenOld(env.get(), root, 3);
    auto start = chrono::steady_clock::now();
    for(int i = 0; i < 10000; ++i)
    {
        const auto transform = env->relativeTransform(root, target);
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

int main()
{
    cout << "-------------------------" << endl;
    cout << "Add 10000 children to root:" << endl;
    cout << "-------------------------" << endl;
    const double old10000 = oldAdd10000Children();
    const double new10000 = newAdd10000Children();
    cout << "old: " << old10000 << " millis, (" << old10000 / 10000.0 << " millis/frame)" << endl;
    cout << "new: " << new10000 << " millis, (" << new10000 / 10000.0 << " millis/frame)" << endl;
    cout << endl;

    cout << "-------------------------" << endl;
    cout << "Add 10000 children chain:" << endl;
    cout << "-------------------------" << endl;
    const double oldChain = oldAdd10000Chain();
    const double newChain = newAdd10000Chain();
    cout << "old: " << oldChain << " millis, (" << oldChain / 10000.0 << " millis/frame)" << endl;
    cout << "new: " << newChain << " millis, (" << newChain / 10000.0 << " millis/frame)" << endl;
    cout << endl;

    cout << "-------------------------" << endl;
    cout << "Calculate transform 10000 times:" << endl;
    cout << "-------------------------" << endl;
    const double oldSearch = oldTransformSearch10000();
    const double newSearch = newTranformSearch10000();
    cout << "old: " << oldSearch << " millis, (" << oldSearch / 10000.0 << " millis/search)" << endl;
    cout << "new: " << newSearch << " millis, (" << newSearch / 10000.0 << " millis/search)" << endl;

}<commit_msg>more perf testing<commit_after>#include <boost/test/unit_test.hpp>
#include <envire/Core.hpp>
#include <envire_core/all>
#include <chrono>
#include <iostream>

using namespace std;
using namespace Eigen;

/**
 *  1.) add 100 children to root node.
 *  2.) create a chain of 100 children.
 *  3.) update each transform in the chain once.
 *
 *
 *  Repeat all tests several times and calc avg
 *
 *
 * */

const double newAdd10000Children()
{
    using namespace envire::core;
    TransformGraph graph;
    const FrameId root("root");
    graph.addFrame(root);

    //create frameids beforehand. we dont want to benchmark boost::lexical_cast
    vector<FrameId> ids;
    for(int i = 0; i < 10000; ++i)
    {
        ids.push_back(boost::lexical_cast<FrameId>(i));
    }

    envire::core::Transform tf;

    auto start = chrono::steady_clock::now();
    for(size_t i = 0; i < 10000; ++i)
    {
        graph.addTransform(root, ids[i], tf);
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;

}

const double oldAdd10000Children()
{
    using namespace envire;

    boost::scoped_ptr<Environment> env(new Environment());
    Affine3d transform(Translation3d( 0.0, 0.0, 0.5 ));

    FrameNode* root = env->getRootNode();
    auto start = chrono::steady_clock::now();
    for(size_t i = 0; i < 10000; ++i)
    {
        FrameNode* pNode = new FrameNode();
        pNode->setTransform(transform);
        env->addChild(root, pNode);
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

const double oldAdd10000Chain()
{
  using namespace envire;

  boost::scoped_ptr<Environment> env(new Environment());
  Affine3d transform(Translation3d( 0.0, 0.0, 0.5 ));

  auto start = chrono::steady_clock::now();

  FrameNode* node = env->getRootNode();
  for(int i = 0; i < 10000; ++i)
  {
      FrameNode* child = new FrameNode();
      child->setTransform(transform);
      env->addChild(node, child);
      node = child;
  }

  auto end = chrono::steady_clock::now();
  double diff = chrono::duration <double, milli> (end - start).count();
  return diff;
}

const double newAdd10000Chain()
{
    using namespace envire::core;
    TransformGraph graph;
    envire::core::Transform tf;

    //create frameids beforehand. we dont want to benchmark boost::lexical_cast
    vector<FrameId> ids;
    for(int i = 0; i < 10000; ++i)
    {
        ids.push_back(boost::lexical_cast<FrameId>(i));
    }

    auto start = chrono::steady_clock::now();
    for(int i = 0; i < 10000 - 1; ++i)
    {
        graph.addTransform(ids[i], ids[i+1], tf);
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

/**Helper method that builds a tree of depth @p i with 4 children per node */
void addFourChildren(envire::core::TransformGraph& graph, const envire::core::FrameId& id, const int i)
{
  if(i == 0)
      return;
  for(int j = 0; j < 4; ++j)
  {
      envire::core::Transform tf;
      tf.setTransform(base::TransformWithCovariance::Identity());
      const envire::core::FrameId newId = id + boost::lexical_cast<envire::core::FrameId>(j);
      graph.addTransform(id, newId, tf);
      addFourChildren(graph, newId, i - 1);
  }
}

/**Calculate the transform for a path of length 4 in a tree of depth 4 where
   each vertex has 4 children*/
const double newTranformSearch10000()
{
    using namespace envire::core;
    TransformGraph graph;
    const FrameId root("4");
    graph.addFrame(root);
    addFourChildren(graph, root, 3);

    //we search from "4" to "4333" which is the rightmost child
    //according to the naming schema of addFourChildren()

    auto start = chrono::steady_clock::now();
    for(int i = 0; i < 10000; ++i)
    {
        const envire::core::Transform tf = graph.getTransform("4", "4333");
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

/** same as addFourChildren() for the old envire. returns the rightmost child */
envire::FrameNode* addFourChildrenOld(envire::Environment* env, envire::FrameNode* parent, const int i)
{
  envire::FrameNode* target = NULL;
  if(i == 0)
  {
      return parent;
  }
  for(int j = 0; j < 4; ++j)
  {
      Affine3d transform(Translation3d( 0.0, 0.0, 0.5 ));
      envire::FrameNode* child = new envire::FrameNode();
      child->setTransform(transform);
      env->addChild(parent, child);
      target =  addFourChildrenOld(env, child, i - 1);
  }
  return target;
}

const double oldTransformSearch10000()
{
    using namespace envire;
    boost::scoped_ptr<Environment> env(new Environment());
    FrameNode* root = env->getRootNode();
    FrameNode* target = addFourChildrenOld(env.get(), root, 3);
    auto start = chrono::steady_clock::now();
    for(int i = 0; i < 10000; ++i)
    {
      const auto transform = env->relativeTransform(target, root);
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

const double oldUpdateTransform10000()
{
    using namespace envire;
    Environment* env = new Environment();
    FrameNode* root = env->getRootNode();
    FrameNode* other = new FrameNode();
    env->addChild(root, other);
    Affine3d transform(Translation3d( 0.0, 0.0, 0.5 ));
    other->setTransform(transform);
    auto start = chrono::steady_clock::now();
    for(int i = 0; i < 10000; ++i)
    {
        other->setTransform(transform);
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

const double newUpdateTransform10000()
{
    using namespace envire::core;
    TransformGraph graph;
    const FrameId root("4");
    const FrameId other("other");
    envire::core::Transform tf;
    graph.addTransform(root, other, tf);

    auto start = chrono::steady_clock::now();
    for(int i = 0; i < 10000; ++i)
    {
        graph.updateTransform(root, other, tf);
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

const double oldGetTransform10000()
{
    using namespace envire;
    Environment* env = new Environment();
    FrameNode* root = env->getRootNode();
    FrameNode* other = new FrameNode();
    env->addChild(root, other);
    Affine3d transform(Translation3d( 0.0, 0.0, 0.5 ));
    other->setTransform(transform);

    auto start = chrono::steady_clock::now();
    for(int i = 0; i < 10000; ++i)
    {
        const envire::TransformWithUncertainty tf = other->getTransformWithUncertainty();
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

const double newGetTransform10000()
{
    using namespace envire::core;
    TransformGraph graph;
    const FrameId roo("4");
    const FrameId othe("other");
    envire::core::Transform tf;
    graph.addTransform(roo, othe, tf);

    vertex_descriptor root = graph.vertex(roo);
    vertex_descriptor other = graph.vertex(othe);

    auto start = chrono::steady_clock::now();
    for(int i = 0; i < 10000; ++i)
    {
        const envire::core::Transform tf = graph.getTransform(root, other);
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

class MyMap : public envire::CartesianMap
{
public:
  MyMap(const std::string& id) : CartesianMap(id) {}
  virtual int getDimension() const override {return 42;}
};

const double newAddItemCartesianMap10000()
{
    using namespace envire::core;
    using Item = Item<MyMap>;

    TransformGraph graph;
    const FrameId root("4");
    graph.addFrame(root);

    //create items beforehand, we dont want ti benchmark the item ctor
    vector<Item::Ptr> items;
    for(int i = 0; i < 10000; ++i)
    {
      items.emplace_back(new Item("bla")); //id is not used, therefore just use "bla"
    }

    auto start = chrono::steady_clock::now();
    for(int i = 0; i < 10000; ++i)
    {
        graph.addItemToFrame(root, items[i]);
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

const double oldAddItemCartesianMap10000()
{
    using namespace envire;
    Environment* env = new Environment();
    FrameNode* root = env->getRootNode();

    //create items beforehand, we dont want ti benchmark the item ctor
    vector<MyMap*> items;
    for(int i = 0; i < 10000; ++i)
    {
      const string id = string("root/") + boost::lexical_cast<string>(i);
      items.emplace_back(new MyMap(id)); //id is not used, therefore just use "bla"
    }

    auto start = chrono::steady_clock::now();
    for(int i = 0; i < 10000; ++i)
    {
        env->attachItem(items[i], root);
    }
    auto end = chrono::steady_clock::now();
    double diff = chrono::duration <double, milli> (end - start).count();
    return diff;
}

int main()
{
    cout << "-------------------------" << endl;
    cout << "Add 10000 children to root:" << endl;
    cout << "-------------------------" << endl;
    const double old10000 = oldAdd10000Children();
    const double new10000 = newAdd10000Children();
    cout << "old: " << old10000 << " millis, (" << old10000 / 10000.0 << " millis/frame)" << endl;
    cout << "new: " << new10000 << " millis, (" << new10000 / 10000.0 << " millis/frame)" << endl;
    cout << endl;

    cout << "-------------------------" << endl;
    cout << "Add 10000 children chain:" << endl;
    cout << "-------------------------" << endl;
    const double oldChain = oldAdd10000Chain();
    const double newChain = newAdd10000Chain();
    cout << "old: " << oldChain << " millis, (" << oldChain / 10000.0 << " millis/frame)" << endl;
    cout << "new: " << newChain << " millis, (" << newChain / 10000.0 << " millis/frame)" << endl;
    cout << endl;

    cout << "-------------------------" << endl;
    cout << "Calculate transform 10000 times:" << endl;
    cout << "-------------------------" << endl;
    const double oldSearch = oldTransformSearch10000();
    const double newSearch = newTranformSearch10000();
    cout << "old: " << oldSearch << " millis, (" << oldSearch / 10000.0 << " millis/search)" << endl;
    cout << "new: " << newSearch << " millis, (" << newSearch / 10000.0 << " millis/search)" << endl;

    cout << "-------------------------" << endl;
    cout << "Update transform 10000 times:" << endl;
    cout << "-------------------------" << endl;
    const double oldUpdateTransform = oldUpdateTransform10000();
    const double newUpdateTransform = newUpdateTransform10000();
    cout << "old: " << oldUpdateTransform << " millis, (" << oldUpdateTransform / 10000.0 << " millis/update)" << endl;
    cout << "new: " << newUpdateTransform << " millis, (" << newUpdateTransform / 10000.0 << " millis/update)" << endl;

    cout << "-------------------------" << endl;
    cout << "Get direct transform 10000 times:" << endl;
    cout << "-------------------------" << endl;
    const double oldGet = oldGetTransform10000();
    const double newGet = newGetTransform10000();
    cout << "old: " << oldGet << " millis, (" << oldGet / 10000.0 << " millis/get)" << endl;
    cout << "new: " << newGet << " millis, (" << newGet / 10000.0 << " millis/get)" << endl;

    cout << "-------------------------" << endl;
    cout << "Add 10000 CartesianMaps to frame:" << endl;
    cout << "-------------------------" << endl;
    const double oldAddItem = oldAddItemCartesianMap10000();
    double newAddItem = newAddItemCartesianMap10000();
    cout << "old: " << oldAddItem << " millis, (" << oldAddItem / 10000.0 << " millis/item)" << endl;
    cout << "new: " << newAddItem << " millis, (" << newAddItem / 10000.0 << " millis/item)" << endl;

}

<|endoftext|>


<commit_before>/** @file
    @brief Lists all the connected displays.

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com>

*/

// Copyright 2016 Sensics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Internal Includes
#include <display/DisplayEnumerator.h>

// Library/third-party includes
// - none

// Standard includes
#include <iostream>

inline std::string to_string(osvr::display::Rotation rotation)
{
    switch (rotation) {
    case osvr::display::Rotation::Zero:
        return "Landscape";
    case osvr::display::Rotation::Ninety:
        return "Portrait";
    case osvr::display::Rotation::OneEighty:
        return "Landscape (flipped)";
    case osvr::display::Rotation::TwoSeventy:
        return "Portrait (flipped)";
    }
}

int main(int argc, char* argv[])
{
    auto displays = osvr::display::getDisplays();

    for (const auto& display : displays) {
        using std::cout;
        using std::endl;

        cout << "Display: " << display.name << endl;
        cout << "  Adapter: " << display.adapter.description << endl;
        cout << "  Monitor name: " << display.name << endl;
        cout << "  Resolution: " << display.size.width << "x" << display.size.height << endl;
        cout << "  Position: (" << display.position.x << ", " << display.position.y << ")" << endl;
        cout << "  Rotation: " << to_string(display.rotation) << endl;
        cout << "  Refresh rate: " << display.verticalRefreshRate << endl;
        cout << "  " << (display.attachedToDesktop ? "Extended mode" : "Direct mode") << endl;
        cout << "  EDID vendor ID: " << display.edidVendorId << endl;
        cout << "  EDID product ID: " << display.edidProductId << endl;
        cout << "" << endl;
    }

    return 0;
}

<commit_msg>Print EDID vendor and product ID values in hexadecimal.<commit_after>/** @file
    @brief Lists all the connected displays.

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com>

*/

// Copyright 2016 Sensics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Internal Includes
#include <display/DisplayEnumerator.h>

// Library/third-party includes
// - none

// Standard includes
#include <iostream>

inline std::string to_string(osvr::display::Rotation rotation)
{
    switch (rotation) {
    case osvr::display::Rotation::Zero:
        return "Landscape";
    case osvr::display::Rotation::Ninety:
        return "Portrait";
    case osvr::display::Rotation::OneEighty:
        return "Landscape (flipped)";
    case osvr::display::Rotation::TwoSeventy:
        return "Portrait (flipped)";
    }
}

int main(int argc, char* argv[])
{
    auto displays = osvr::display::getDisplays();

    for (const auto& display : displays) {
        using std::cout;
        using std::endl;

        cout << "Display: " << display.name << endl;
        cout << "  Adapter: " << display.adapter.description << endl;
        cout << "  Monitor name: " << display.name << endl;
        cout << "  Resolution: " << display.size.width << "x" << display.size.height << endl;
        cout << "  Position: (" << display.position.x << ", " << display.position.y << ")" << endl;
        cout << "  Rotation: " << to_string(display.rotation) << endl;
        cout << "  Refresh rate: " << display.verticalRefreshRate << endl;
        cout << "  " << (display.attachedToDesktop ? "Extended mode" : "Direct mode") << endl;
        cout << "  EDID vendor ID: 0x" << std::hex << display.edidVendorId << std::dec << endl;
        cout << "  EDID product ID: 0x" << std::hex << display.edidProductId << std::dec << endl;
        cout << "" << endl;
    }

    return 0;
}

<|endoftext|>