<commit_before>//
//  JdAssert.hpp
//  Jigidesign
//
//  Created by Steven Massey on 6/29/16.
//  Copyright © 2016 Jigidesign. All rights reserved.
//

#ifndef JdAssert_hpp
#define JdAssert_hpp

# if __APPLE__
#	include <signal.h>
#	include <unistd.h>
# endif

#include "JdConfig.hpp"
#include "JdResult.hpp"

class JdException : public std::exception, public JdResult
{
	public:

	JdException (cstr_t i_message, cstr_t i_location = 0, u32 i_line = 0);

	virtual const char * what() const throw ();
};

template <typename... args_t>
void JdAssert (bool i_shouldBeTrue, cstr_t i_truthfulOrLyingStatement, cstr_t i_filePath, u32 i_lineNum, cstr_t i_format, args_t... i_args)
{
	if (! i_shouldBeTrue)
	{
		std::ostringstream oss;
		// FIX: this should probably be wrapped in a JdException. Upper level code that catches the exception will log, display, or cerr the .what()
		if (strcmp (i_truthfulOrLyingStatement, "0") == 0)
			oss << "\n| throw: ";
		else
			oss << "\n| '" << i_truthfulOrLyingStatement << "' assertion failed. ";

		if (i_format)
		{
			Jd::SSPrintF (oss, i_format, i_args...);
		}

		cstr_t file = strstr (i_filePath, "../");
		if (! file) file = i_filePath;
		else file += 2;

		if (file)
		{
			oss << "\n+" << string (strlen (file) + 7, '-');
			oss << "\n| " << file << ":" << i_lineNum;
		}

		//epilog_(fatal, "%s", epistr (oss.str()));
		std::cout << oss.str() << std::endl << std::endl;

		// Break into the debugger
		if (not JdConfig::IsUnitTest () and JdConfig::IsDebug ())
		{
			#if __APPLE__
				usleep (50000);		// give epilog 50ms to flush.
			#endif
//			raise (SIGTRAP);
		}

		throw JdException (oss.str().c_str(), i_filePath, i_lineNum);
	}
}

template <typename... args_t>
JdResult JdResert (bool i_shouldBeTrue, cstr_t i_truthfulOrLyingStatement, cstr_t i_filePath, u32 i_lineNum, cstr_t i_format, args_t... i_args)
{
	JdResult result;

	if (! i_shouldBeTrue)
	{
		if (JdConfig::IsDebug ())
		{
			std::ostringstream oss;
			// FIX: this should probably be wrapped in a JdException. Upper level code that catches the exception will log, display, or cerr the .what()
			if (strcmp (i_truthfulOrLyingStatement, "0") == 0)
				oss << "\n| throw: ";
			else
				oss << "\n| '" << i_truthfulOrLyingStatement << "' assertion failed. ";

			if (i_format)
			{
				Jd::SSPrintF (oss, i_format, i_args...);
			}

			cstr_t file = strstr (i_filePath, "../");
			if (! file) file = i_filePath;
			else file += 2;

			if (file) oss << "\n| " << file << ":" << i_lineNum;

			//epilog_(fatal, "%s", epistr (oss.str()));
			std::cout << oss.str() << std::endl << std::endl;

			// Break into the debugger
			if (not JdConfig::IsUnitTest () and JdConfig::IsDebug ())
			{
				#if __APPLE__
					usleep (50000);		// give epilog 50ms to flush.
				#endif
//				raise (SIGTRAP);
			}

			throw JdException (oss.str().c_str(), i_filePath, i_lineNum);
		}
		else
		{
			std::ostringstream oss;
			if (i_format) Jd::SSPrintF (oss, i_format, i_args...);

			result = JdResult (oss.str().c_str(), i_filePath, i_lineNum, 0, true);
		}
	}

	return result;
}

#define d_jdPermAssert(TRUTH, ...) JdAssert (TRUTH, #TRUTH, __FILE__, __LINE__, __VA_ARGS__)

#if DEBUG
	#define d_jdAssert(TRUTH, ...) JdAssert (TRUTH, #TRUTH, __FILE__, __LINE__, __VA_ARGS__)
#else
	#define d_jdAssert(...)
#endif

#define d_jdResert(TRUTH, ...) JdResert (TRUTH, #TRUTH, __FILE__, __LINE__, __VA_ARGS__)

#define d_jdThrow(...) JdAssert (false, "throw", __FILE__, __LINE__, __VA_ARGS__)

#endif /* JdAssert_hpp */
<commit_msg>no message<commit_after>//
//  JdAssert.hpp
//  Jigidesign
//
//  Created by Steven Massey on 6/29/16.
//  Copyright © 2016 Jigidesign. All rights reserved.
//

#ifndef JdAssert_hpp
#define JdAssert_hpp

# if __APPLE__
#	include <signal.h>
#	include <unistd.h>
# endif

#include "JdConfig.hpp"
#include "JdResult.hpp"

class JdException : public std::exception, public JdResult
{
	public:

	JdException (cstr_t i_message, cstr_t i_location = 0, u32 i_line = 0);

	virtual const char * what() const throw ();
};

template <typename... args_t>
void JdAssert (bool i_shouldBeTrue, cstr_t i_truthfulOrLyingStatement, cstr_t i_filePath, u32 i_lineNum, cstr_t i_format, args_t... i_args)
{
	if (! i_shouldBeTrue)
	{
		std::ostringstream oss;
		// FIX: this should probably be wrapped in a JdException. Upper level code that catches the exception will log, display, or cerr the .what()
		if (strcmp (i_truthfulOrLyingStatement, "0") == 0)
			oss << "\n| throw: ";
		else
			oss << "\n| '" << i_truthfulOrLyingStatement << "' assertion failed. ";

		if (i_format)
		{
			Jd::SSPrintF (oss, i_format, i_args...);
		}

		cstr_t file = strstr (i_filePath, "../");
		if (! file) file = i_filePath;
		else file += 2;

		if (file)
		{
			oss << "\n+" << string (strlen (file) + 7, '-');
			oss << "\n| " << file << ":" << i_lineNum;
		}

		//epilog_(fatal, "%s", epistr (oss.str()));
		std::cout << oss.str() << std::endl << std::endl;

		// Break into the debugger
		if (not JdConfig::IsUnitTest () and JdConfig::IsDebug ())
		{
			#if __APPLE__
				usleep (50000);		// give epilog 50ms to flush.
			#endif
//			raise (SIGTRAP);
		}

		throw JdException (oss.str().c_str(), i_filePath, i_lineNum);
	}
}

template <typename... args_t>
JdResult JdResert (bool i_shouldBeTrue, cstr_t i_truthfulOrLyingStatement, cstr_t i_filePath, u32 i_lineNum, cstr_t i_format, args_t... i_args)
{
	JdResult result;

	if (! i_shouldBeTrue)
	{
		if (JdConfig::IsDebug ())
		{
			std::ostringstream oss;
			// FIX: this should probably be wrapped in a JdException. Upper level code that catches the exception will log, display, or cerr the .what()
			if (strcmp (i_truthfulOrLyingStatement, "0") == 0)
				oss << "\n| throw: ";
			else
				oss << "\n| '" << i_truthfulOrLyingStatement << "' assertion failed. ";

			if (i_format)
			{
				Jd::SSPrintF (oss, i_format, i_args...);
			}

			cstr_t file = strstr (i_filePath, "../");
			if (! file) file = i_filePath;
			else file += 2;

			if (file) oss << "\n| " << file << ":" << i_lineNum;

			//epilog_(fatal, "%s", epistr (oss.str()));
			std::cout << oss.str() << std::endl << std::endl;

			// Break into the debugger
			if (not JdConfig::IsUnitTest () and JdConfig::IsDebug ())
			{
				#if __APPLE__
					usleep (50000);		// give epilog 50ms to flush.
				#endif
//				raise (SIGTRAP);
			}

			throw JdException (oss.str().c_str(), i_filePath, i_lineNum);
		}
		else
		{
			std::ostringstream oss;
			if (i_format) Jd::SSPrintF (oss, i_format, i_args...);

			result = JdResult (oss.str().c_str(), i_filePath, i_lineNum, 0, true);
		}
	}

	return result;
}

#define d_jdPermAssert(TRUTH, ...) JdAssert (TRUTH, #TRUTH, __FILE__, __LINE__, __VA_ARGS__)

#if DEBUG
	#define d_jdAssert(TRUTH, ...) JdAssert (TRUTH, #TRUTH, __FILE__, __LINE__, __VA_ARGS__)
#else
	#define d_jdAssert(...)
#endif

#define d_jdResert(TRUTH, ...) JdResert (TRUTH, #TRUTH, __FILE__, __LINE__, __VA_ARGS__)

#define d_jdThrow(...) JdAssert (false, "throw", __FILE__, __LINE__, __VA_ARGS__)
#define d_jdFix() d_jdThrow ("fix")

#endif /* JdAssert_hpp */
<|endoftext|>


<commit_before>// Copyright (c) 2016 Google 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.

#include "spirv-tools/optimizer.hpp"

#include "build_module.h"
#include "make_unique.h"
#include "pass_manager.h"
#include "passes.h"

namespace spvtools {

struct Optimizer::PassToken::Impl {
  Impl(std::unique_ptr<opt::Pass> p) : pass(std::move(p)) {}

  std::unique_ptr<opt::Pass> pass;  // Internal implementation pass.
};

Optimizer::PassToken::PassToken(
    std::unique_ptr<Optimizer::PassToken::Impl> impl)
    : impl_(std::move(impl)) {}
Optimizer::PassToken::PassToken(PassToken&& that)
    : impl_(std::move(that.impl_)) {}

Optimizer::PassToken& Optimizer::PassToken::operator=(PassToken&& that) {
  impl_ = std::move(that.impl_);
  return *this;
}

Optimizer::PassToken::~PassToken() {}

struct Optimizer::Impl {
  explicit Impl(spv_target_env env) : target_env(env), pass_manager() {}

  const spv_target_env target_env;  // Target environment.
  opt::PassManager pass_manager;    // Internal implementation pass manager.
};

Optimizer::Optimizer(spv_target_env env) : impl_(new Impl(env)) {}

Optimizer::~Optimizer() {}

void Optimizer::SetMessageConsumer(MessageConsumer c) {
  // All passes' message consumer needs to be updated.
  for (uint32_t i = 0; i < impl_->pass_manager.NumPasses(); ++i) {
    impl_->pass_manager.GetPass(i)->SetMessageConsumer(c);
  }
  impl_->pass_manager.SetMessageConsumer(std::move(c));
}

Optimizer& Optimizer::RegisterPass(PassToken&& p) {
  // Change to use the pass manager's consumer.
  p.impl_->pass->SetMessageConsumer(impl_->pass_manager.consumer());
  impl_->pass_manager.AddPass(std::move(p.impl_->pass));
  return *this;
}

Optimizer& Optimizer::RegisterPerformancePasses() {
  return RegisterPass(CreateInlineExhaustivePass())
      .RegisterPass(CreateLocalAccessChainConvertPass())
      .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
      .RegisterPass(CreateLocalSingleStoreElimPass())
      .RegisterPass(CreateInsertExtractElimPass())
      .RegisterPass(CreateAggressiveDCEPass())
      .RegisterPass(CreateDeadBranchElimPass())
      .RegisterPass(CreateBlockMergePass())
      .RegisterPass(CreateLocalMultiStoreElimPass())
      .RegisterPass(CreateInsertExtractElimPass())
      .RegisterPass(CreateCommonUniformElimPass())
      .RegisterPass(CreateDeadVariableEliminationPass());
}

Optimizer& Optimizer::RegisterSizePasses() {
  return RegisterPass(CreateInlineExhaustivePass())
      .RegisterPass(CreateLocalAccessChainConvertPass())
      .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
      .RegisterPass(CreateLocalSingleStoreElimPass())
      .RegisterPass(CreateInsertExtractElimPass())
      .RegisterPass(CreateAggressiveDCEPass())
      .RegisterPass(CreateDeadBranchElimPass())
      .RegisterPass(CreateBlockMergePass())
      .RegisterPass(CreateLocalMultiStoreElimPass())
      .RegisterPass(CreateInsertExtractElimPass())
      .RegisterPass(CreateCommonUniformElimPass())
      .RegisterPass(CreateDeadVariableEliminationPass());
}

bool Optimizer::Run(const uint32_t* original_binary,
                    const size_t original_binary_size,
                    std::vector<uint32_t>* optimized_binary) const {
  std::unique_ptr<ir::Module> module =
      BuildModule(impl_->target_env, impl_->pass_manager.consumer(),
                  original_binary, original_binary_size);
  if (module == nullptr) return false;
  ir::IRContext context(std::move(module));

  auto status = impl_->pass_manager.Run(&context);
  if (status == opt::Pass::Status::SuccessWithChange ||
      (status == opt::Pass::Status::SuccessWithoutChange &&
       (optimized_binary->data() != original_binary ||
        optimized_binary->size() != original_binary_size))) {
    optimized_binary->clear();
    context.module()->ToBinary(optimized_binary, /* skip_nop = */ true);
  }

  return status != opt::Pass::Status::Failure;
}

Optimizer::PassToken CreateNullPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(MakeUnique<opt::NullPass>());
}

Optimizer::PassToken CreateStripDebugInfoPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::StripDebugInfoPass>());
}

Optimizer::PassToken CreateEliminateDeadFunctionsPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::EliminateDeadFunctionsPass>());
}

Optimizer::PassToken CreateSetSpecConstantDefaultValuePass(
    const std::unordered_map<uint32_t, std::string>& id_value_map) {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::SetSpecConstantDefaultValuePass>(id_value_map));
}

Optimizer::PassToken CreateSetSpecConstantDefaultValuePass(
    const std::unordered_map<uint32_t, std::vector<uint32_t>>& id_value_map) {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::SetSpecConstantDefaultValuePass>(id_value_map));
}

Optimizer::PassToken CreateFlattenDecorationPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::FlattenDecorationPass>());
}

Optimizer::PassToken CreateFreezeSpecConstantValuePass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::FreezeSpecConstantValuePass>());
}

Optimizer::PassToken CreateFoldSpecConstantOpAndCompositePass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::FoldSpecConstantOpAndCompositePass>());
}

Optimizer::PassToken CreateUnifyConstantPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::UnifyConstantPass>());
}

Optimizer::PassToken CreateEliminateDeadConstantPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::EliminateDeadConstantPass>());
}

Optimizer::PassToken CreateDeadVariableEliminationPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::DeadVariableElimination>());
}

Optimizer::PassToken CreateStrengthReductionPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::StrengthReductionPass>());
}

Optimizer::PassToken CreateBlockMergePass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::BlockMergePass>());
}

Optimizer::PassToken CreateInlineExhaustivePass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::InlineExhaustivePass>());
}

Optimizer::PassToken CreateInlineOpaquePass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::InlineOpaquePass>());
}

Optimizer::PassToken CreateLocalAccessChainConvertPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::LocalAccessChainConvertPass>());
}

Optimizer::PassToken CreateLocalSingleBlockLoadStoreElimPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::LocalSingleBlockLoadStoreElimPass>());
}

Optimizer::PassToken CreateLocalSingleStoreElimPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::LocalSingleStoreElimPass>());
}

Optimizer::PassToken CreateInsertExtractElimPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::InsertExtractElimPass>());
}

Optimizer::PassToken CreateDeadBranchElimPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::DeadBranchElimPass>());
}

Optimizer::PassToken CreateLocalMultiStoreElimPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::LocalMultiStoreElimPass>());
}

Optimizer::PassToken CreateAggressiveDCEPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::AggressiveDCEPass>());
}

Optimizer::PassToken CreateCommonUniformElimPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::CommonUniformElimPass>());
}

Optimizer::PassToken CreateCompactIdsPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::CompactIdsPass>());
}

std::vector<const char*> Optimizer::GetPassNames() const {
  std::vector<const char*> v;
  for (uint32_t i = 0; i < impl_->pass_manager.NumPasses(); i++) {
    v.push_back(impl_->pass_manager.GetPass(i)->name());
  }
  return v;
}

Optimizer::PassToken CreateCFGCleanupPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::CFGCleanupPass>());
}

}  // namespace spvtools
<commit_msg>Opt: Remove CommonUniformElimination from -O and -Os (for now)<commit_after>// Copyright (c) 2016 Google 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.

#include "spirv-tools/optimizer.hpp"

#include "build_module.h"
#include "make_unique.h"
#include "pass_manager.h"
#include "passes.h"

namespace spvtools {

struct Optimizer::PassToken::Impl {
  Impl(std::unique_ptr<opt::Pass> p) : pass(std::move(p)) {}

  std::unique_ptr<opt::Pass> pass;  // Internal implementation pass.
};

Optimizer::PassToken::PassToken(
    std::unique_ptr<Optimizer::PassToken::Impl> impl)
    : impl_(std::move(impl)) {}
Optimizer::PassToken::PassToken(PassToken&& that)
    : impl_(std::move(that.impl_)) {}

Optimizer::PassToken& Optimizer::PassToken::operator=(PassToken&& that) {
  impl_ = std::move(that.impl_);
  return *this;
}

Optimizer::PassToken::~PassToken() {}

struct Optimizer::Impl {
  explicit Impl(spv_target_env env) : target_env(env), pass_manager() {}

  const spv_target_env target_env;  // Target environment.
  opt::PassManager pass_manager;    // Internal implementation pass manager.
};

Optimizer::Optimizer(spv_target_env env) : impl_(new Impl(env)) {}

Optimizer::~Optimizer() {}

void Optimizer::SetMessageConsumer(MessageConsumer c) {
  // All passes' message consumer needs to be updated.
  for (uint32_t i = 0; i < impl_->pass_manager.NumPasses(); ++i) {
    impl_->pass_manager.GetPass(i)->SetMessageConsumer(c);
  }
  impl_->pass_manager.SetMessageConsumer(std::move(c));
}

Optimizer& Optimizer::RegisterPass(PassToken&& p) {
  // Change to use the pass manager's consumer.
  p.impl_->pass->SetMessageConsumer(impl_->pass_manager.consumer());
  impl_->pass_manager.AddPass(std::move(p.impl_->pass));
  return *this;
}

Optimizer& Optimizer::RegisterPerformancePasses() {
  return RegisterPass(CreateInlineExhaustivePass())
      .RegisterPass(CreateLocalAccessChainConvertPass())
      .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
      .RegisterPass(CreateLocalSingleStoreElimPass())
      .RegisterPass(CreateInsertExtractElimPass())
      .RegisterPass(CreateAggressiveDCEPass())
      .RegisterPass(CreateDeadBranchElimPass())
      .RegisterPass(CreateBlockMergePass())
      .RegisterPass(CreateLocalMultiStoreElimPass())
      .RegisterPass(CreateInsertExtractElimPass())
      // Currently exposing driver bugs resulting in crashes (#946)
      // .RegisterPass(CreateCommonUniformElimPass())
      .RegisterPass(CreateDeadVariableEliminationPass());
}

Optimizer& Optimizer::RegisterSizePasses() {
  return RegisterPass(CreateInlineExhaustivePass())
      .RegisterPass(CreateLocalAccessChainConvertPass())
      .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
      .RegisterPass(CreateLocalSingleStoreElimPass())
      .RegisterPass(CreateInsertExtractElimPass())
      .RegisterPass(CreateAggressiveDCEPass())
      .RegisterPass(CreateDeadBranchElimPass())
      .RegisterPass(CreateBlockMergePass())
      .RegisterPass(CreateLocalMultiStoreElimPass())
      .RegisterPass(CreateInsertExtractElimPass())
      // Currently exposing driver bugs resulting in crashes (#946)
      // .RegisterPass(CreateCommonUniformElimPass())
      .RegisterPass(CreateDeadVariableEliminationPass());
}

bool Optimizer::Run(const uint32_t* original_binary,
                    const size_t original_binary_size,
                    std::vector<uint32_t>* optimized_binary) const {
  std::unique_ptr<ir::Module> module =
      BuildModule(impl_->target_env, impl_->pass_manager.consumer(),
                  original_binary, original_binary_size);
  if (module == nullptr) return false;
  ir::IRContext context(std::move(module));

  auto status = impl_->pass_manager.Run(&context);
  if (status == opt::Pass::Status::SuccessWithChange ||
      (status == opt::Pass::Status::SuccessWithoutChange &&
       (optimized_binary->data() != original_binary ||
        optimized_binary->size() != original_binary_size))) {
    optimized_binary->clear();
    context.module()->ToBinary(optimized_binary, /* skip_nop = */ true);
  }

  return status != opt::Pass::Status::Failure;
}

Optimizer::PassToken CreateNullPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(MakeUnique<opt::NullPass>());
}

Optimizer::PassToken CreateStripDebugInfoPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::StripDebugInfoPass>());
}

Optimizer::PassToken CreateEliminateDeadFunctionsPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::EliminateDeadFunctionsPass>());
}

Optimizer::PassToken CreateSetSpecConstantDefaultValuePass(
    const std::unordered_map<uint32_t, std::string>& id_value_map) {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::SetSpecConstantDefaultValuePass>(id_value_map));
}

Optimizer::PassToken CreateSetSpecConstantDefaultValuePass(
    const std::unordered_map<uint32_t, std::vector<uint32_t>>& id_value_map) {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::SetSpecConstantDefaultValuePass>(id_value_map));
}

Optimizer::PassToken CreateFlattenDecorationPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::FlattenDecorationPass>());
}

Optimizer::PassToken CreateFreezeSpecConstantValuePass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::FreezeSpecConstantValuePass>());
}

Optimizer::PassToken CreateFoldSpecConstantOpAndCompositePass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::FoldSpecConstantOpAndCompositePass>());
}

Optimizer::PassToken CreateUnifyConstantPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::UnifyConstantPass>());
}

Optimizer::PassToken CreateEliminateDeadConstantPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::EliminateDeadConstantPass>());
}

Optimizer::PassToken CreateDeadVariableEliminationPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::DeadVariableElimination>());
}

Optimizer::PassToken CreateStrengthReductionPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::StrengthReductionPass>());
}

Optimizer::PassToken CreateBlockMergePass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::BlockMergePass>());
}

Optimizer::PassToken CreateInlineExhaustivePass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::InlineExhaustivePass>());
}

Optimizer::PassToken CreateInlineOpaquePass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::InlineOpaquePass>());
}

Optimizer::PassToken CreateLocalAccessChainConvertPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::LocalAccessChainConvertPass>());
}

Optimizer::PassToken CreateLocalSingleBlockLoadStoreElimPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::LocalSingleBlockLoadStoreElimPass>());
}

Optimizer::PassToken CreateLocalSingleStoreElimPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::LocalSingleStoreElimPass>());
}

Optimizer::PassToken CreateInsertExtractElimPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::InsertExtractElimPass>());
}

Optimizer::PassToken CreateDeadBranchElimPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::DeadBranchElimPass>());
}

Optimizer::PassToken CreateLocalMultiStoreElimPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::LocalMultiStoreElimPass>());
}

Optimizer::PassToken CreateAggressiveDCEPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::AggressiveDCEPass>());
}

Optimizer::PassToken CreateCommonUniformElimPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::CommonUniformElimPass>());
}

Optimizer::PassToken CreateCompactIdsPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::CompactIdsPass>());
}

std::vector<const char*> Optimizer::GetPassNames() const {
  std::vector<const char*> v;
  for (uint32_t i = 0; i < impl_->pass_manager.NumPasses(); i++) {
    v.push_back(impl_->pass_manager.GetPass(i)->name());
  }
  return v;
}

Optimizer::PassToken CreateCFGCleanupPass() {
  return MakeUnique<Optimizer::PassToken::Impl>(
      MakeUnique<opt::CFGCleanupPass>());
}

}  // namespace spvtools
<|endoftext|>


<commit_before>/* Copyright (C) 2003 MySQL AB

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

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

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifndef NDB_VECTOR_HPP
#define NDB_VECTOR_HPP

#include <ndb_global.h>
#include <NdbMutex.h>

template<class T>
struct Vector {
public:
  Vector(int sz = 10);
  ~Vector();

  T& operator[](unsigned i);
  const T& operator[](unsigned i) const;
  unsigned size() const { return m_size; };

  void push_back(const T &);
  T& back();

  void erase(unsigned index);

  void clear();

  void fill(unsigned new_size, T & obj);

  Vector<T>& operator=(const Vector<T>&);

  T* getBase() { return m_items;}
  const T* getBase() const { return m_items;}
private:
  T * m_items;
  unsigned m_size;
  unsigned m_incSize;
  unsigned m_arraySize;
};

template<class T>
Vector<T>::Vector(int i){
  m_items = new T[i];
  m_size = 0;
  m_arraySize = i;
  m_incSize = 50;
}

template<class T>
Vector<T>::~Vector(){
  delete[] m_items;
  // safety for placement new usage
  m_items = 0;
  m_size = 0;
  m_arraySize = 0;
}

template<class T>
T &
Vector<T>::operator[](unsigned i){
  if(i >= m_size)
    abort();
  return m_items[i];
}

template<class T>
const T &
Vector<T>::operator[](unsigned i) const {
  if(i >= m_size)
    abort();
  return m_items[i];
}

template<class T>
T &
Vector<T>::back(){
  return (* this)[m_size - 1];
}

template<class T>
void
Vector<T>::push_back(const T & t){
  if(m_size == m_arraySize){
    T * tmp = new T [m_arraySize + m_incSize];
    for (unsigned k = 0; k < m_size; k++)
      tmp[k] = m_items[k];
    delete[] m_items;
    m_items = tmp;
    m_arraySize = m_arraySize + m_incSize;
  }
  m_items[m_size] = t;
  m_size++;
}

template<class T>
void
Vector<T>::erase(unsigned i){
  if(i >= m_size)
    abort();

  for (unsigned k = i; k + 1 < m_size; k++)
    m_items[k] = m_items[k + 1];
  m_size--;
}

template<class T>
void
Vector<T>::clear(){
  m_size = 0;
}

template<class T>
void
Vector<T>::fill(unsigned new_size, T & obj){
  while(m_size <= new_size)
    push_back(obj);
}

template<class T>
Vector<T>&
Vector<T>::operator=(const Vector<T>& obj){
  if(this != &obj){
    clear();
    for(size_t i = 0; i<obj.size(); i++){
      push_back(obj[i]);
    }
  }
  return * this;
}

template<class T>
struct MutexVector : public NdbLockable {
  MutexVector(int sz = 10);
  ~MutexVector();

  T& operator[](unsigned i);
  const T& operator[](unsigned i) const;
  unsigned size() const { return m_size; };

  void push_back(const T &);
  void push_back(const T &, bool lockMutex);
  T& back();

  void erase(unsigned index);
  void erase(unsigned index, bool lockMutex);

  void clear();
  void clear(bool lockMutex);

  void fill(unsigned new_size, T & obj);
private:
  T * m_items;
  unsigned m_size;
  unsigned m_incSize;
  unsigned m_arraySize;
};

template<class T>
MutexVector<T>::MutexVector(int i){
  m_items = new T[i];
  m_size = 0;
  m_arraySize = i;
  m_incSize = 50;
}

template<class T>
MutexVector<T>::~MutexVector(){
  delete[] m_items;
  // safety for placement new usage
  m_items = 0;
  m_size = 0;
  m_arraySize = 0;
}

template<class T>
T &
MutexVector<T>::operator[](unsigned i){
  if(i >= m_size)
    abort();
  return m_items[i];
}

template<class T>
const T &
MutexVector<T>::operator[](unsigned i) const {
  if(i >= m_size)
    abort();
  return m_items[i];
}

template<class T>
T &
MutexVector<T>::back(){
  return (* this)[m_size - 1];
}

template<class T>
void
MutexVector<T>::push_back(const T & t){
  lock();
  if(m_size == m_arraySize){
    T * tmp = new T [m_arraySize + m_incSize];
    for (unsigned k = 0; k < m_size; k++)
      tmp[k] = m_items[k];
    delete[] m_items;
    m_items = tmp;
    m_arraySize = m_arraySize + m_incSize;
  }
  m_items[m_size] = t;
  m_size++;
  unlock();
}

template<class T>
void
MutexVector<T>::push_back(const T & t, bool lockMutex){
  if(lockMutex)
    lock();
  if(m_size == m_arraySize){
    T * tmp = new T [m_arraySize + m_incSize];
    for (unsigned k = 0; k < m_size; k++)
      tmp[k] = m_items[k];
    delete[] m_items;
    m_items = tmp;
    m_arraySize = m_arraySize + m_incSize;
  }
  m_items[m_size] = t;
  m_size++;
  if(lockMutex)
    unlock();
}

template<class T>
void
MutexVector<T>::erase(unsigned i){
  if(i >= m_size)
    abort();

  lock();
  for (unsigned k = i; k + 1 < m_size; k++)
    m_items[k] = m_items[k + 1];
  m_size--;
  unlock();
}

template<class T>
void
MutexVector<T>::erase(unsigned i, bool _lock){
  if(i >= m_size)
    abort();

  if(_lock)
    lock();
  for (unsigned k = i; k + 1 < m_size; k++)
    m_items[k] = m_items[k + 1];
  m_size--;
  if(_lock)
    unlock();
}

template<class T>
void
MutexVector<T>::clear(){
  lock();
  m_size = 0;
  unlock();
}

template<class T>
void
MutexVector<T>::clear(bool l){
  if(l) lock();
  m_size = 0;
  if(l) unlock();
}

template<class T>
void
MutexVector<T>::fill(unsigned new_size, T & obj){
  while(m_size <= new_size)
    push_back(obj);
}

#endif
<commit_msg>BUG#22299 mgmd crash due to unchecked TransporterFacade::ThreadData expand()<commit_after>/* Copyright (C) 2003 MySQL AB

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

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

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifndef NDB_VECTOR_HPP
#define NDB_VECTOR_HPP

#include <ndb_global.h>
#include <NdbMutex.h>

template<class T>
struct Vector {
public:
  Vector(int sz = 10);
  ~Vector();

  T& operator[](unsigned i);
  const T& operator[](unsigned i) const;
  unsigned size() const { return m_size; };

  void push_back(const T &);
  T& back();

  void erase(unsigned index);

  void clear();

  void fill(unsigned new_size, T & obj);

  Vector<T>& operator=(const Vector<T>&);

  T* getBase() { return m_items;}
  const T* getBase() const { return m_items;}
private:
  T * m_items;
  unsigned m_size;
  unsigned m_incSize;
  unsigned m_arraySize;
};

template<class T>
Vector<T>::Vector(int i){
  m_items = new T[i];
  m_size = 0;
  m_arraySize = i;
  m_incSize = 50;
}

template<class T>
Vector<T>::~Vector(){
  delete[] m_items;
  // safety for placement new usage
  m_items = 0;
  m_size = 0;
  m_arraySize = 0;
}

template<class T>
T &
Vector<T>::operator[](unsigned i){
  if(i >= m_size)
    abort();
  return m_items[i];
}

template<class T>
const T &
Vector<T>::operator[](unsigned i) const {
  if(i >= m_size)
    abort();
  return m_items[i];
}

template<class T>
T &
Vector<T>::back(){
  return (* this)[m_size - 1];
}

template<class T>
void
Vector<T>::push_back(const T & t){
  if(m_size == m_arraySize){
    T * tmp = new T [m_arraySize + m_incSize];
    if(!tmp)
      abort();
    for (unsigned k = 0; k < m_size; k++)
      tmp[k] = m_items[k];
    delete[] m_items;
    m_items = tmp;
    m_arraySize = m_arraySize + m_incSize;
  }
  m_items[m_size] = t;
  m_size++;
}

template<class T>
void
Vector<T>::erase(unsigned i){
  if(i >= m_size)
    abort();

  for (unsigned k = i; k + 1 < m_size; k++)
    m_items[k] = m_items[k + 1];
  m_size--;
}

template<class T>
void
Vector<T>::clear(){
  m_size = 0;
}

template<class T>
void
Vector<T>::fill(unsigned new_size, T & obj){
  while(m_size <= new_size)
    push_back(obj);
}

template<class T>
Vector<T>&
Vector<T>::operator=(const Vector<T>& obj){
  if(this != &obj){
    clear();
    for(size_t i = 0; i<obj.size(); i++){
      push_back(obj[i]);
    }
  }
  return * this;
}

template<class T>
struct MutexVector : public NdbLockable {
  MutexVector(int sz = 10);
  ~MutexVector();

  T& operator[](unsigned i);
  const T& operator[](unsigned i) const;
  unsigned size() const { return m_size; };

  void push_back(const T &);
  void push_back(const T &, bool lockMutex);
  T& back();

  void erase(unsigned index);
  void erase(unsigned index, bool lockMutex);

  void clear();
  void clear(bool lockMutex);

  void fill(unsigned new_size, T & obj);
private:
  T * m_items;
  unsigned m_size;
  unsigned m_incSize;
  unsigned m_arraySize;
};

template<class T>
MutexVector<T>::MutexVector(int i){
  m_items = new T[i];
  m_size = 0;
  m_arraySize = i;
  m_incSize = 50;
}

template<class T>
MutexVector<T>::~MutexVector(){
  delete[] m_items;
  // safety for placement new usage
  m_items = 0;
  m_size = 0;
  m_arraySize = 0;
}

template<class T>
T &
MutexVector<T>::operator[](unsigned i){
  if(i >= m_size)
    abort();
  return m_items[i];
}

template<class T>
const T &
MutexVector<T>::operator[](unsigned i) const {
  if(i >= m_size)
    abort();
  return m_items[i];
}

template<class T>
T &
MutexVector<T>::back(){
  return (* this)[m_size - 1];
}

template<class T>
void
MutexVector<T>::push_back(const T & t){
  lock();
  if(m_size == m_arraySize){
    T * tmp = new T [m_arraySize + m_incSize];
    for (unsigned k = 0; k < m_size; k++)
      tmp[k] = m_items[k];
    delete[] m_items;
    m_items = tmp;
    m_arraySize = m_arraySize + m_incSize;
  }
  m_items[m_size] = t;
  m_size++;
  unlock();
}

template<class T>
void
MutexVector<T>::push_back(const T & t, bool lockMutex){
  if(lockMutex)
    lock();
  if(m_size == m_arraySize){
    T * tmp = new T [m_arraySize + m_incSize];
    for (unsigned k = 0; k < m_size; k++)
      tmp[k] = m_items[k];
    delete[] m_items;
    m_items = tmp;
    m_arraySize = m_arraySize + m_incSize;
  }
  m_items[m_size] = t;
  m_size++;
  if(lockMutex)
    unlock();
}

template<class T>
void
MutexVector<T>::erase(unsigned i){
  if(i >= m_size)
    abort();

  lock();
  for (unsigned k = i; k + 1 < m_size; k++)
    m_items[k] = m_items[k + 1];
  m_size--;
  unlock();
}

template<class T>
void
MutexVector<T>::erase(unsigned i, bool _lock){
  if(i >= m_size)
    abort();

  if(_lock)
    lock();
  for (unsigned k = i; k + 1 < m_size; k++)
    m_items[k] = m_items[k + 1];
  m_size--;
  if(_lock)
    unlock();
}

template<class T>
void
MutexVector<T>::clear(){
  lock();
  m_size = 0;
  unlock();
}

template<class T>
void
MutexVector<T>::clear(bool l){
  if(l) lock();
  m_size = 0;
  if(l) unlock();
}

template<class T>
void
MutexVector<T>::fill(unsigned new_size, T & obj){
  while(m_size <= new_size)
    push_back(obj);
}

#endif
<|endoftext|>


<commit_before>/**********************************************************************
 * $Id$
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************/

#include <geos/profiler.h>
#include <iostream>
#include <map>
#include <string>
#include <utility>

using namespace std;

namespace geos {
namespace util { // geos.util

static Profiler *internal_profiler = new Profiler();

Profile::Profile(string newname)
{
	name = newname;
	totaltime = 0;
	min = max = avg = 0;
}

Profile::~Profile()
{
}

#if 0
void
Profile::start()
{
	gettimeofday(&starttime, NULL);
}

void
Profile::stop()
{
	gettimeofday(&stoptime, NULL);
	double elapsed = 1000000*(stoptime.tv_sec-starttime.tv_sec)+
		(stoptime.tv_usec-starttime.tv_usec);

	timings.push_back(elapsed);
	totaltime += elapsed;
	if ( timings.size() == 1 ) max = min = elapsed;
	else
	{
		if ( elapsed > max ) max = elapsed;
		if ( elapsed < min ) min = elapsed;
	}
	avg = totaltime / timings.size();
}
#endif

double
Profile::getMax() const
{
	return max;
}

double
Profile::getMin() const
{
	return min;
}

double
Profile::getAvg() const
{
	return avg;
}

double
Profile::getTot() const
{
	return totaltime;
}

unsigned int
Profile::getNumTimings() const
{
	return timings.size();
}

Profiler::Profiler()
{
}

Profiler::~Profiler()
{
	map<string, Profile *>::const_iterator it;
	for ( it=profs.begin(); it != profs.end(); ++it )
	{
		delete it->second;
	}
}

void
Profiler::start(string name)
{
	Profile *prof = get(name);
	prof->start();
}

void
Profiler::stop(string name)
{
	map<string, Profile *>::iterator iter = profs.find(name);
	if ( iter == profs.end() )
		cerr<<name<<": no such Profile started";
	iter->second->stop();
}

Profile *
Profiler::get(string name)
{
	Profile *prof;
	map<string, Profile *>::iterator iter = profs.find(name);
	if ( iter == profs.end() ) {
		prof = new Profile(name);
		profs.insert(pair<string, Profile *>(name, prof));
	} else {
		prof = iter->second;
	}
	return prof;
}

Profiler *
Profiler::instance()
{
	return internal_profiler;
}

ostream&
operator<< (ostream &os, const Profile &prof)
{
	os << " num:"<<prof.getNumTimings()<<" min:"<<
		prof.getMin()<<" max:"<<prof.getMax()<<
		" avg:"<<prof.getAvg()<<" tot:"<<prof.getTot()<<
		" ["<<prof.name<<"]";
	return os;
}

ostream&
operator<< (ostream &os, const Profiler &prof)
{
	map<string, Profile *>::const_iterator it;
	for ( it=prof.profs.begin(); it != prof.profs.end(); ++it )
	{
		os<<*(it->second)<<endl;
	}
	return os;
}

} // namespace geos.util
} // namespace geos

/**********************************************************************
 * $Log$
 * Revision 1.8  2006/03/06 19:40:48  strk
 * geos::util namespace. New GeometryCollection::iterator interface, many cleanups.
 *
 * Revision 1.7  2006/03/03 10:46:22  strk
 * Removed 'using namespace' from headers, added missing headers in .cpp files, removed useless includes in headers (bug#46)
 *
 * Revision 1.6  2005/02/01 14:18:04  strk
 * Made profiler start/stop inline
 *
 * Revision 1.5  2005/02/01 13:44:59  strk
 * More profiling labels.
 *
 * Revision 1.4  2004/12/03 22:52:56  strk
 * enforced const return of CoordinateSequence::toVector() method to derivate classes.
 *
 * Revision 1.3  2004/11/08 12:15:35  strk
 * Added number of gathered timings in output.
 *
 * Revision 1.2  2004/11/08 11:19:39  strk
 * Profiler::get() always return a Profile (new if not existant).
 *
 * Revision 1.1  2004/11/01 16:43:04  strk
 * Added Profiler code.
 * Temporarly patched a bug in DoubleBits (must check drawbacks).
 * Various cleanups and speedups.
 *
 **********************************************************************/
<commit_msg>Profiler singleton implemented with a function-static Profiler instance<commit_after>/**********************************************************************
 * $Id$
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************/

#include <geos/profiler.h>
#include <iostream>
#include <map>
#include <string>
#include <utility>

using namespace std;

namespace geos {
namespace util { // geos.util

Profile::Profile(string newname)
{
	name = newname;
	totaltime = 0;
	min = max = avg = 0;
}

Profile::~Profile()
{
}

#if 0
void
Profile::start()
{
	gettimeofday(&starttime, NULL);
}

void
Profile::stop()
{
	gettimeofday(&stoptime, NULL);
	double elapsed = 1000000*(stoptime.tv_sec-starttime.tv_sec)+
		(stoptime.tv_usec-starttime.tv_usec);

	timings.push_back(elapsed);
	totaltime += elapsed;
	if ( timings.size() == 1 ) max = min = elapsed;
	else
	{
		if ( elapsed > max ) max = elapsed;
		if ( elapsed < min ) min = elapsed;
	}
	avg = totaltime / timings.size();
}
#endif

double
Profile::getMax() const
{
	return max;
}

double
Profile::getMin() const
{
	return min;
}

double
Profile::getAvg() const
{
	return avg;
}

double
Profile::getTot() const
{
	return totaltime;
}

unsigned int
Profile::getNumTimings() const
{
	return timings.size();
}

Profiler::Profiler()
{
}

Profiler::~Profiler()
{
	map<string, Profile *>::const_iterator it;
	for ( it=profs.begin(); it != profs.end(); ++it )
	{
		delete it->second;
	}
}

void
Profiler::start(string name)
{
	Profile *prof = get(name);
	prof->start();
}

void
Profiler::stop(string name)
{
	map<string, Profile *>::iterator iter = profs.find(name);
	if ( iter == profs.end() )
		cerr<<name<<": no such Profile started";
	iter->second->stop();
}

Profile *
Profiler::get(string name)
{
	Profile *prof;
	map<string, Profile *>::iterator iter = profs.find(name);
	if ( iter == profs.end() ) {
		prof = new Profile(name);
		profs.insert(pair<string, Profile *>(name, prof));
	} else {
		prof = iter->second;
	}
	return prof;
}

Profiler *
Profiler::instance()
{
	static Profiler internal_profiler;
	return &internal_profiler;
}

ostream&
operator<< (ostream &os, const Profile &prof)
{
	os << " num:"<<prof.getNumTimings()<<" min:"<<
		prof.getMin()<<" max:"<<prof.getMax()<<
		" avg:"<<prof.getAvg()<<" tot:"<<prof.getTot()<<
		" ["<<prof.name<<"]";
	return os;
}

ostream&
operator<< (ostream &os, const Profiler &prof)
{
	map<string, Profile *>::const_iterator it;
	for ( it=prof.profs.begin(); it != prof.profs.end(); ++it )
	{
		os<<*(it->second)<<endl;
	}
	return os;
}

} // namespace geos.util
} // namespace geos

/**********************************************************************
 * $Log$
 * Revision 1.9  2006/03/07 14:18:34  strk
 * Profiler singleton implemented with a function-static Profiler instance
 *
 * Revision 1.8  2006/03/06 19:40:48  strk
 * geos::util namespace. New GeometryCollection::iterator interface, many cleanups.
 *
 * Revision 1.7  2006/03/03 10:46:22  strk
 * Removed 'using namespace' from headers, added missing headers in .cpp files, removed useless includes in headers (bug#46)
 *
 * Revision 1.6  2005/02/01 14:18:04  strk
 * Made profiler start/stop inline
 *
 * Revision 1.5  2005/02/01 13:44:59  strk
 * More profiling labels.
 *
 * Revision 1.4  2004/12/03 22:52:56  strk
 * enforced const return of CoordinateSequence::toVector() method to derivate classes.
 *
 * Revision 1.3  2004/11/08 12:15:35  strk
 * Added number of gathered timings in output.
 *
 * Revision 1.2  2004/11/08 11:19:39  strk
 * Profiler::get() always return a Profile (new if not existant).
 *
 * Revision 1.1  2004/11/01 16:43:04  strk
 * Added Profiler code.
 * Temporarly patched a bug in DoubleBits (must check drawbacks).
 * Various cleanups and speedups.
 *
 **********************************************************************/
<|endoftext|>


<commit_before>/**
 * \file
 * \brief FifoQueueBase class header
 *
 * \author Copyright (C) 2014 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2014-12-10
 */

#ifndef INCLUDE_DISTORTOS_SCHEDULER_FIFOQUEUEBASE_HPP_
#define INCLUDE_DISTORTOS_SCHEDULER_FIFOQUEUEBASE_HPP_

#include "distortos/Semaphore.hpp"

#include "distortos/scheduler/SemaphoreWaitFunctor.hpp"

namespace distortos
{

namespace scheduler
{

/// FifoQueueBase class is a base for FifoQueue template class
class FifoQueueBase
{
private:

	/// required by templated constructor to deduce type
	template<typename T>
	class TypeTag
	{

	};

	/// type of uninitialized storage for data
	template<typename T>
	using Storage = typename std::aligned_storage<sizeof(T), alignof(T)>::type;

	/**
	 * \brief Functor is a type-erased interface for functors which execute some action on queue's storage (like
	 * copy-constructing, swapping, destroying, emplacing, ...).
	 *
	 * The functor will be called by FifoQueueBase internals with one argument - \a storage - which is a reference to
	 * pointer to queue's storage - after executing functor's action, the pointer should be incremented to next position
	 * (using the actual size of element)
	 */

	using Functor = estd::TypeErasedFunctor<void(void*&)>;

	/**
	 * \brief BoundedFunctor is a type-erased Functor which calls its bounded functor to execute actions on queue's
	 * storage and deals with the pointer increments
	 *
	 * \param T is the type of element
	 * \param F is the type of bounded functor, it will be called with Storage<T>* as only argument
	 */

	template<typename T, typename F>
	class BoundedFunctor : public Functor
	{
	public:

		/**
		 * \brief BoundedFunctor's constructor
		 *
		 * \param [in] boundedFunctor is a rvalue reference to bounded functor which will be used to move-construct
		 * internal bounded functor
		 */

		constexpr explicit BoundedFunctor(F&& boundedFunctor) :
				boundedFunctor_{std::move(boundedFunctor)}
		{

		}

		/**
		 * \brief Calls the bounded functor which will execute some action on queue's storage (like copy-constructing,
		 * swapping, destroying, emplacing, ...) and increments the storage pointer to next position (using the actual
		 * size of element)
		 *
		 * \param [in,out] storage is a reference to pointer to queue's storage - after executing bounded functor, the
		 * pointer will be incremented to next position (using the actual size of element)
		 */

		virtual void operator()(void*& storage) const override
		{
			auto typedStorage = static_cast<Storage<T>*>(storage);
			boundedFunctor_(typedStorage);
			storage = typedStorage + 1;
		}

	private:

		/// bounded functor
		F boundedFunctor_;
	};

	/**
	 * \brief Helper factory function to make BoundedFunctor object with partially deduced template arguments
	 *
	 * \param T is the type of element
	 * \param F is the type of bounded functor, it will be called with Storage<T>* as only argument
	 *
	 * \param [in] boundedFunctor is a rvalue reference to bounded functor which will be used to move-construct internal
	 * bounded functor
	 *
	 * \return BoundedFunctor object with partially deduced template arguments
	 */

	template<typename T, typename F>
	constexpr static BoundedFunctor<T, F> makeBoundedFunctor(F&& boundedFunctor)
	{
		return BoundedFunctor<T, F>{std::move(boundedFunctor)};
	}

protected:

	/**
	 * \brief FifoQueueBase's constructor
	 *
	 * \param T is the type of data in queue
	 *
	 * \param [in] storage is an array of Storage<T> elements
	 * \param [in] maxElements is the number of elements in storage array
	 * \param [in] typeTag is used to deduce T, as deduction from storage is not possible (nested-name-specifier, so a
	 * non-deduced context)
	 */

	template<typename T>
	FifoQueueBase(Storage<T>* const storage, const size_t maxElements, TypeTag<T>) :
			popSemaphore_{0, maxElements},
			pushSemaphore_{maxElements, maxElements},
			storageBegin_{storage},
			storageEnd_{storage + maxElements},
			readPosition_{storage},
			writePosition_{storage}
	{

	}

	/**
	 * \brief FifoQueueBase's destructor
	 *
	 * \note Polymorphic objects of FifoQueueBase type must not be deleted via pointer/reference
	 */

	~FifoQueueBase()
	{

	}

	/**
	 * \brief Pops the oldest (first) element from the queue.
	 *
	 * \param T is the type of data popped from queue
	 *
	 * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
	 * with the value in the queue's storage and destructed when no longer needed
	 *
	 * \return zero if element was popped successfully, error code otherwise:
	 * - error codes returned by Semaphore::wait();
	 * - error codes returned by Semaphore::post();
	 */

	template<typename T>
	int pop(T& value)
	{
		const SemaphoreWaitFunctor semaphoreWaitFunctor;
		return popInternal(semaphoreWaitFunctor, value);
	}

	/**
	 * \brief Pushes the element to the queue.
	 *
	 * \param T is the type of data pushed to queue
	 *
	 * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
	 *
	 * \return zero if element was pushed successfully, error code otherwise:
	 * - error codes returned by Semaphore::wait();
	 * - error codes returned by Semaphore::post();
	 */

	template<typename T>
	int push(const T& value)
	{
		const auto copyFunctor = makeBoundedFunctor<T>(
				[&value](Storage<T>* const storage)
				{
					new (storage) T{value};
				});
		const SemaphoreWaitFunctor semaphoreWaitFunctor;
		return pushImplementation(semaphoreWaitFunctor, copyFunctor);
	}

	/**
	 * \brief Pushes the element to the queue.
	 *
	 * \param T is the type of data pushed to queue
	 *
	 * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
	 * move-constructed
	 *
	 * \return zero if element was pushed successfully, error code otherwise:
	 * - error codes returned by Semaphore::wait();
	 * - error codes returned by Semaphore::post();
	 */

	template<typename T>
	int push(T&& value)
	{
		const auto moveFunctor = makeBoundedFunctor<T>(
				[&value](Storage<T>* const storage)
				{
					new (storage) T{std::move(value)};
				});
		const SemaphoreWaitFunctor semaphoreWaitFunctor;
		return pushImplementation(semaphoreWaitFunctor, moveFunctor);
	}

private:

	/**
	 * \brief Implementation of pop() using type-erased functor
	 *
	 * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a popSemaphore_
	 * \param [in] functor is a reference to Functor which will execute actions related to popping - it will get a
	 * reference to readPosition_ as argument
	 *
	 * \return zero if element was popped successfully, error code otherwise:
	 * - error codes returned by \a waitSemaphoreFunctor's operator() call;
	 * - error codes returned by Semaphore::post();
	 */

	int popImplementation(const SemaphoreFunctor& waitSemaphoreFunctor, const Functor& functor)
	{
		return popPushImplementation(waitSemaphoreFunctor, functor, popSemaphore_, pushSemaphore_, readPosition_);
	}

	/**
	 * \brief Pops the oldest (first) element from the queue.
	 *
	 * Internal version - builds the Functor object.
	 *
	 * \param T is the type of data popped from queue
	 *
	 * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a popSemaphore_
	 * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
	 * with the value in the queue's storage and destructed when no longer needed
	 *
	 * \return zero if element was popped successfully, error code otherwise:
	 * - error codes returned by \a waitSemaphoreFunctor's operator() call;
	 * - error codes returned by Semaphore::post();
	 */

	template<typename T>
	int popInternal(const SemaphoreFunctor& waitSemaphoreFunctor, T& value)
	{
		const auto swapFunctor = makeBoundedFunctor<T>(
				[&value](Storage<T>* const storage)
				{
					auto& swappedValue = *reinterpret_cast<T*>(storage);
					std::swap(value, swappedValue);
					swappedValue.~T();
				});
		return popImplementation(waitSemaphoreFunctor, swapFunctor);
	}

	/**
	 * \brief Implementation of pop() and push() using type-erased functor
	 *
	 * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a waitSemaphore
	 * \param [in] functor is a reference to Functor which will execute actions related to popping/pushing - it will get
	 * a reference to \a storage as argument
	 * \param [in] waitSemaphore is a reference to semaphore that will be waited for, \a popSemaphore_ for pop(), \a
	 * pushSemaphore_ for push()
	 * \param [in] postSemaphore is a reference to semaphore that will be posted after the operation, \a pushSemaphore_
	 * for pop(), \a popSemaphore_ for push()
	 * \param [in] storage is a reference to appropriate pointer to storage, which will be passed to \a functor, \a
	 * readPosition_ for pop(), \a writePosition_ for push()
	 *
	 * \return zero if operation was successful, error code otherwise:
	 * - error codes returned by \a waitSemaphoreFunctor's operator() call;
	 * - error codes returned by Semaphore::post();
	 */

	int popPushImplementation(const SemaphoreFunctor& waitSemaphoreFunctor, const Functor& functor,
			Semaphore& waitSemaphore, Semaphore& postSemaphore, void*& storage);

	/**
	 * \brief Implementation of push() using type-erased functor
	 *
	 * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a pushSemaphore_
	 * \param [in] functor is a reference to Functor which will execute actions related to pushing - it will get a
	 * reference to writePosition_ as argument
	 *
	 * \return zero if element was pushed successfully, error code otherwise:
	 * - error codes returned by \a waitSemaphoreFunctor's operator() call;
	 * - error codes returned by Semaphore::post();
	 */

	int pushImplementation(const SemaphoreFunctor& waitSemaphoreFunctor, const Functor& functor)
	{
		return popPushImplementation(waitSemaphoreFunctor, functor, pushSemaphore_, popSemaphore_, writePosition_);
	}

	/// semaphore guarding access to "pop" functions - its value is equal to the number of available elements
	Semaphore popSemaphore_;

	/// semaphore guarding access to "push" functions - its value is equal to the number of free slots
	Semaphore pushSemaphore_;

	/// beginning of array with Storage elements
	void* const storageBegin_;

	/// pointer to past-the-last element of array with Storage elements
	void* const storageEnd_;

	/// pointer to first element available for reading
	void* readPosition_;

	/// pointer to first free slot available for writing
	void* writePosition_;
};

}	// namespace scheduler

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_SCHEDULER_FIFOQUEUEBASE_HPP_
<commit_msg>FifoQueueBase: split FifoQueueBase::push(const T&) into "outer" part - which only builds the SemaphoreFunctor for waiting, and the "inner" part (FifoQueueBase::pushInternal(const T&)) - which builds the Functor object which does the "pushing" via copy<commit_after>/**
 * \file
 * \brief FifoQueueBase class header
 *
 * \author Copyright (C) 2014 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2014-12-10
 */

#ifndef INCLUDE_DISTORTOS_SCHEDULER_FIFOQUEUEBASE_HPP_
#define INCLUDE_DISTORTOS_SCHEDULER_FIFOQUEUEBASE_HPP_

#include "distortos/Semaphore.hpp"

#include "distortos/scheduler/SemaphoreWaitFunctor.hpp"

namespace distortos
{

namespace scheduler
{

/// FifoQueueBase class is a base for FifoQueue template class
class FifoQueueBase
{
private:

	/// required by templated constructor to deduce type
	template<typename T>
	class TypeTag
	{

	};

	/// type of uninitialized storage for data
	template<typename T>
	using Storage = typename std::aligned_storage<sizeof(T), alignof(T)>::type;

	/**
	 * \brief Functor is a type-erased interface for functors which execute some action on queue's storage (like
	 * copy-constructing, swapping, destroying, emplacing, ...).
	 *
	 * The functor will be called by FifoQueueBase internals with one argument - \a storage - which is a reference to
	 * pointer to queue's storage - after executing functor's action, the pointer should be incremented to next position
	 * (using the actual size of element)
	 */

	using Functor = estd::TypeErasedFunctor<void(void*&)>;

	/**
	 * \brief BoundedFunctor is a type-erased Functor which calls its bounded functor to execute actions on queue's
	 * storage and deals with the pointer increments
	 *
	 * \param T is the type of element
	 * \param F is the type of bounded functor, it will be called with Storage<T>* as only argument
	 */

	template<typename T, typename F>
	class BoundedFunctor : public Functor
	{
	public:

		/**
		 * \brief BoundedFunctor's constructor
		 *
		 * \param [in] boundedFunctor is a rvalue reference to bounded functor which will be used to move-construct
		 * internal bounded functor
		 */

		constexpr explicit BoundedFunctor(F&& boundedFunctor) :
				boundedFunctor_{std::move(boundedFunctor)}
		{

		}

		/**
		 * \brief Calls the bounded functor which will execute some action on queue's storage (like copy-constructing,
		 * swapping, destroying, emplacing, ...) and increments the storage pointer to next position (using the actual
		 * size of element)
		 *
		 * \param [in,out] storage is a reference to pointer to queue's storage - after executing bounded functor, the
		 * pointer will be incremented to next position (using the actual size of element)
		 */

		virtual void operator()(void*& storage) const override
		{
			auto typedStorage = static_cast<Storage<T>*>(storage);
			boundedFunctor_(typedStorage);
			storage = typedStorage + 1;
		}

	private:

		/// bounded functor
		F boundedFunctor_;
	};

	/**
	 * \brief Helper factory function to make BoundedFunctor object with partially deduced template arguments
	 *
	 * \param T is the type of element
	 * \param F is the type of bounded functor, it will be called with Storage<T>* as only argument
	 *
	 * \param [in] boundedFunctor is a rvalue reference to bounded functor which will be used to move-construct internal
	 * bounded functor
	 *
	 * \return BoundedFunctor object with partially deduced template arguments
	 */

	template<typename T, typename F>
	constexpr static BoundedFunctor<T, F> makeBoundedFunctor(F&& boundedFunctor)
	{
		return BoundedFunctor<T, F>{std::move(boundedFunctor)};
	}

protected:

	/**
	 * \brief FifoQueueBase's constructor
	 *
	 * \param T is the type of data in queue
	 *
	 * \param [in] storage is an array of Storage<T> elements
	 * \param [in] maxElements is the number of elements in storage array
	 * \param [in] typeTag is used to deduce T, as deduction from storage is not possible (nested-name-specifier, so a
	 * non-deduced context)
	 */

	template<typename T>
	FifoQueueBase(Storage<T>* const storage, const size_t maxElements, TypeTag<T>) :
			popSemaphore_{0, maxElements},
			pushSemaphore_{maxElements, maxElements},
			storageBegin_{storage},
			storageEnd_{storage + maxElements},
			readPosition_{storage},
			writePosition_{storage}
	{

	}

	/**
	 * \brief FifoQueueBase's destructor
	 *
	 * \note Polymorphic objects of FifoQueueBase type must not be deleted via pointer/reference
	 */

	~FifoQueueBase()
	{

	}

	/**
	 * \brief Pops the oldest (first) element from the queue.
	 *
	 * \param T is the type of data popped from queue
	 *
	 * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
	 * with the value in the queue's storage and destructed when no longer needed
	 *
	 * \return zero if element was popped successfully, error code otherwise:
	 * - error codes returned by Semaphore::wait();
	 * - error codes returned by Semaphore::post();
	 */

	template<typename T>
	int pop(T& value)
	{
		const SemaphoreWaitFunctor semaphoreWaitFunctor;
		return popInternal(semaphoreWaitFunctor, value);
	}

	/**
	 * \brief Pushes the element to the queue.
	 *
	 * \param T is the type of data pushed to queue
	 *
	 * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
	 *
	 * \return zero if element was pushed successfully, error code otherwise:
	 * - error codes returned by Semaphore::wait();
	 * - error codes returned by Semaphore::post();
	 */

	template<typename T>
	int push(const T& value)
	{
		const SemaphoreWaitFunctor semaphoreWaitFunctor;
		return pushInternal(semaphoreWaitFunctor, value);
	}

	/**
	 * \brief Pushes the element to the queue.
	 *
	 * \param T is the type of data pushed to queue
	 *
	 * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
	 * move-constructed
	 *
	 * \return zero if element was pushed successfully, error code otherwise:
	 * - error codes returned by Semaphore::wait();
	 * - error codes returned by Semaphore::post();
	 */

	template<typename T>
	int push(T&& value)
	{
		const auto moveFunctor = makeBoundedFunctor<T>(
				[&value](Storage<T>* const storage)
				{
					new (storage) T{std::move(value)};
				});
		const SemaphoreWaitFunctor semaphoreWaitFunctor;
		return pushImplementation(semaphoreWaitFunctor, moveFunctor);
	}

private:

	/**
	 * \brief Implementation of pop() using type-erased functor
	 *
	 * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a popSemaphore_
	 * \param [in] functor is a reference to Functor which will execute actions related to popping - it will get a
	 * reference to readPosition_ as argument
	 *
	 * \return zero if element was popped successfully, error code otherwise:
	 * - error codes returned by \a waitSemaphoreFunctor's operator() call;
	 * - error codes returned by Semaphore::post();
	 */

	int popImplementation(const SemaphoreFunctor& waitSemaphoreFunctor, const Functor& functor)
	{
		return popPushImplementation(waitSemaphoreFunctor, functor, popSemaphore_, pushSemaphore_, readPosition_);
	}

	/**
	 * \brief Pops the oldest (first) element from the queue.
	 *
	 * Internal version - builds the Functor object.
	 *
	 * \param T is the type of data popped from queue
	 *
	 * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a popSemaphore_
	 * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
	 * with the value in the queue's storage and destructed when no longer needed
	 *
	 * \return zero if element was popped successfully, error code otherwise:
	 * - error codes returned by \a waitSemaphoreFunctor's operator() call;
	 * - error codes returned by Semaphore::post();
	 */

	template<typename T>
	int popInternal(const SemaphoreFunctor& waitSemaphoreFunctor, T& value)
	{
		const auto swapFunctor = makeBoundedFunctor<T>(
				[&value](Storage<T>* const storage)
				{
					auto& swappedValue = *reinterpret_cast<T*>(storage);
					std::swap(value, swappedValue);
					swappedValue.~T();
				});
		return popImplementation(waitSemaphoreFunctor, swapFunctor);
	}

	/**
	 * \brief Implementation of pop() and push() using type-erased functor
	 *
	 * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a waitSemaphore
	 * \param [in] functor is a reference to Functor which will execute actions related to popping/pushing - it will get
	 * a reference to \a storage as argument
	 * \param [in] waitSemaphore is a reference to semaphore that will be waited for, \a popSemaphore_ for pop(), \a
	 * pushSemaphore_ for push()
	 * \param [in] postSemaphore is a reference to semaphore that will be posted after the operation, \a pushSemaphore_
	 * for pop(), \a popSemaphore_ for push()
	 * \param [in] storage is a reference to appropriate pointer to storage, which will be passed to \a functor, \a
	 * readPosition_ for pop(), \a writePosition_ for push()
	 *
	 * \return zero if operation was successful, error code otherwise:
	 * - error codes returned by \a waitSemaphoreFunctor's operator() call;
	 * - error codes returned by Semaphore::post();
	 */

	int popPushImplementation(const SemaphoreFunctor& waitSemaphoreFunctor, const Functor& functor,
			Semaphore& waitSemaphore, Semaphore& postSemaphore, void*& storage);

	/**
	 * \brief Implementation of push() using type-erased functor
	 *
	 * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a pushSemaphore_
	 * \param [in] functor is a reference to Functor which will execute actions related to pushing - it will get a
	 * reference to writePosition_ as argument
	 *
	 * \return zero if element was pushed successfully, error code otherwise:
	 * - error codes returned by \a waitSemaphoreFunctor's operator() call;
	 * - error codes returned by Semaphore::post();
	 */

	int pushImplementation(const SemaphoreFunctor& waitSemaphoreFunctor, const Functor& functor)
	{
		return popPushImplementation(waitSemaphoreFunctor, functor, pushSemaphore_, popSemaphore_, writePosition_);
	}

	/**
	 * \brief Pushes the element to the queue.
	 *
	 * Internal version - builds the Functor object.
	 *
	 * \param T is the type of data pushed to queue
	 *
	 * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a pushSemaphore_
	 * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
	 *
	 * \return zero if element was pushed successfully, error code otherwise:
	 * - error codes returned by \a waitSemaphoreFunctor's operator() call;
	 * - error codes returned by Semaphore::post();
	 */

	template<typename T>
	int pushInternal(const SemaphoreFunctor& waitSemaphoreFunctor, const T& value)
	{
		const auto copyFunctor = makeBoundedFunctor<T>(
				[&value](Storage<T>* const storage)
				{
					new (storage) T{value};
				});
		return pushImplementation(waitSemaphoreFunctor, copyFunctor);
	}

	/// semaphore guarding access to "pop" functions - its value is equal to the number of available elements
	Semaphore popSemaphore_;

	/// semaphore guarding access to "push" functions - its value is equal to the number of free slots
	Semaphore pushSemaphore_;

	/// beginning of array with Storage elements
	void* const storageBegin_;

	/// pointer to past-the-last element of array with Storage elements
	void* const storageEnd_;

	/// pointer to first element available for reading
	void* readPosition_;

	/// pointer to first free slot available for writing
	void* writePosition_;
};

}	// namespace scheduler

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_SCHEDULER_FIFOQUEUEBASE_HPP_
<|endoftext|>


<commit_before>#include "net.h"

spnp::Net::Net():AbstractData()
{
    this->places = new std::vector<Place*>();
    this->transitions = new std::vector<ImmediateTransition*>();
    this->arcs = new std::vector<Arc*>();
}

spnp::Net::Net(std::string name, std::vector<Place *> *places,
               std::vector<ImmediateTransition *> *transitions, std::vector<Arc *> *arcs):AbstractData(name)
{
    this->places = places;
    this->transitions = transitions;
    this->arcs = arcs;
}

spnp::Net::~Net()
{
    for(int i=0, total = this->places->size(); i<total; ++i)
    {
        spnp::Place* _place = this->places->at(i);
        delete _place;
    }
    places->clear();
    delete places;

    /*for(auto it = transitions->begin(); it != transitions->end(); ++it)
        delete(*it);
    for(auto it = arcs->begin(); it != arcs->end(); ++it)
        delete(*it);*/

    //transitions->clear();
    //arcs->clear();

    //delete transitions;
    //delete arcs;
}

XMLNode *spnp::Net::toXML()
{
    XMLNode* node = AbstractData::toXML();
    for(auto it = places->begin(); it != places->end(); ++it)
    {
        node->addChild((*it)->toXML());
    }
    for(auto it = transitions->begin(); it != transitions->end(); ++it)
    {
        node->addChild((*it)->toXML());
    }
    for(auto it = arcs->begin(); it != arcs->end(); ++it)
    {
        node->addChild((*it)->toXML());
    }

    return node;
}

void spnp::Net::fromXML(XMLNode *xml)
{
    AbstractData::fromXML(xml);
    std::vector<XMLNode*> *v = xml->getChildrenByName("place");
    for(auto it = v->begin(); it != v->end(); ++it)
    {
        Place* p = new Place();
        p->fromXML(*it);
        this->places->push_back(p);
        delete (*it);
    }
    delete v;

    v = xml->getChildrenByName("fluid_place");
    for(auto it = v->begin(); it != v->end(); ++it)
    {
        FluidPlace* fp = new FluidPlace();
        fp->fromXML(*it);
        this->places->push_back(fp);
        delete (*it);
    }
    delete v;

    v = xml->getChildrenByName("timed_transition");
    for(auto it = v->begin(); it != v->end(); ++it)
    {
        TimedTransition* tt = new TimedTransition();
        tt->fromXML(*it);
        this->transitions->push_back(tt);
        delete (*it);
    }
    delete v;

    v = xml->getChildrenByName("transition");
    for(auto it = v->begin(); it != v->end(); ++it)
    {
        ImmediateTransition* t = new ImmediateTransition();
        t->fromXML(*it);
        this->transitions->push_back(t);
        delete (*it);
    }
    delete v;

    v = xml->getChildrenByName("arc");
    for(auto it = v->begin(); it != v->end(); ++it)
    {
        Arc* a = new Arc();
        a->fromXML(*it);
        this->arcs->push_back(a);
        delete (*it);
    }
    delete v;
}

void spnp::Net::add(Place *p)
{
    this->places->push_back(p);
}

void spnp::Net::add(ImmediateTransition *t)
{
    this->transitions->push_back(t);
}

void spnp::Net::add(Arc *a)
{
    this->arcs->push_back(a);
}

void spnp::Net::removePlace(std::string id)
{
    for(unsigned int i=0, total = this->places->size(); i<total; ++i)
    {
        spnp::Place *place = this->places->at(i);

        if(place->id.compare(id))
        {
            places->erase(places->begin()+i);
            break;
        }
    }
}

void spnp::Net::removeTransition(std::string id)
{
    for(unsigned int i=0, total = this->transitions->size(); i<total; ++i)
    {
        spnp::ImmediateTransition *transition = this->transitions->at(i);
        if(transition->id.compare(id))
        {
            transitions->erase(transitions->begin()+i);
            break;
        }
    }
}

void spnp::Net::removeArc(std::string id)
{
    for(unsigned int i=0, total = this->arcs->size(); i<total; ++i)
    {
        spnp::Arc *arc = this->arcs->at(i);
        if(arc->id.compare(id))
        {
            arcs->erase(arcs->begin()+i);
            break;
        }
    }
}

spnp::Place *spnp::Net::getPlace(std::string id)
{
    for(unsigned int i=0, total = this->places->size(); i<total; ++i)
    {
        spnp::Place *place = this->places->at(i);
        if(place->id.compare(id))
            return (place);
    }
    return nullptr;
}

spnp::ImmediateTransition *spnp::Net::getTransition(std::string id)
{
    for(unsigned int i=0, total = this->transitions->size(); i<total; ++i)
    {
        spnp::ImmediateTransition* trans = this->transitions->at(i);
        if(trans->id.compare(id))
            return trans;
    }
    return nullptr;
}

spnp::Arc *spnp::Net::getArc(std::string id)
{
    for(unsigned int i=0, total = this->arcs->size(); i<total; ++i)
    {
        spnp::Arc *arc = this->arcs->at(i);
        if(arc->id.compare(id))
            return arc;
    }
    return nullptr;
}

std::vector<spnp::Place *> *spnp::Net::getPlaces() const
{
    return this->places;
}

std::vector<spnp::ImmediateTransition *> *spnp::Net::getTransitions() const
{
    return this->transitions;
}

std::vector<spnp::Arc *> *spnp::Net::getArcs() const
{
    return this->arcs;
}

std::string spnp::Net::getClassNodeName()
{
    return "net";
}
<commit_msg>Apagando ponteiros.<commit_after>#include "net.h"

spnp::Net::Net():AbstractData()
{
    this->places = new std::vector<Place*>();
    this->transitions = new std::vector<ImmediateTransition*>();
    this->arcs = new std::vector<Arc*>();
}

spnp::Net::Net(std::string name, std::vector<Place *> *places,
               std::vector<ImmediateTransition *> *transitions, std::vector<Arc *> *arcs):AbstractData(name)
{
    this->places = places;
    this->transitions = transitions;
    this->arcs = arcs;
}

spnp::Net::~Net()
{
    for(int i=0, total = this->places->size(); i<total; ++i)
    {
        spnp::Place* _place = this->places->at(i);
        delete _place;
    }
    places->clear();
    delete places;

    /*for(auto it = transitions->begin(); it != transitions->end(); ++it)
        delete(*it);
    for(auto it = arcs->begin(); it != arcs->end(); ++it)
        delete(*it);*/

    //transitions->clear();
    //arcs->clear();

    //delete transitions;
    //delete arcs;
}

XMLNode *spnp::Net::toXML()
{
    XMLNode* node = AbstractData::toXML();
    for(auto it = places->begin(); it != places->end(); ++it)
    {
        node->addChild((*it)->toXML());
    }
    for(auto it = transitions->begin(); it != transitions->end(); ++it)
    {
        node->addChild((*it)->toXML());
    }
    for(auto it = arcs->begin(); it != arcs->end(); ++it)
    {
        node->addChild((*it)->toXML());
    }

    return node;
}

void spnp::Net::fromXML(XMLNode *xml)
{
    AbstractData::fromXML(xml);
    std::vector<XMLNode*> *v = xml->getChildrenByName("place");
    for(auto it = v->begin(); it != v->end(); ++it)
    {
        Place* p = new Place();
        p->fromXML(*it);
        this->places->push_back(p);
        delete (*it);
    }
    delete v;

    v = xml->getChildrenByName("fluid_place");
    for(auto it = v->begin(); it != v->end(); ++it)
    {
        FluidPlace* fp = new FluidPlace();
        fp->fromXML(*it);
        this->places->push_back(fp);
        delete (*it);
    }
    delete v;

    v = xml->getChildrenByName("timed_transition");
    for(auto it = v->begin(); it != v->end(); ++it)
    {
        TimedTransition* tt = new TimedTransition();
        tt->fromXML(*it);
        this->transitions->push_back(tt);
        delete (*it);
    }
    delete v;

    v = xml->getChildrenByName("transition");
    for(auto it = v->begin(); it != v->end(); ++it)
    {
        ImmediateTransition* t = new ImmediateTransition();
        t->fromXML(*it);
        this->transitions->push_back(t);
        delete (*it);
    }
    delete v;

    v = xml->getChildrenByName("arc");
    for(auto it = v->begin(); it != v->end(); ++it)
    {
        Arc* a = new Arc();
        a->fromXML(*it);
        this->arcs->push_back(a);
        delete (*it);
    }
    delete v;
}

void spnp::Net::add(Place *p)
{
    this->places->push_back(p);
}

void spnp::Net::add(ImmediateTransition *t)
{
    this->transitions->push_back(t);
}

void spnp::Net::add(Arc *a)
{
    this->arcs->push_back(a);
}

void spnp::Net::removePlace(std::string id)
{
    for(unsigned int i=0, total = this->places->size(); i<total; ++i)
    {
        spnp::Place *place = this->places->at(i);

        if(place->id.compare(id))
        {
            places->erase(places->begin()+i);
            delete place;
            break;
        }
    }
}

void spnp::Net::removeTransition(std::string id)
{
    for(unsigned int i=0, total = this->transitions->size(); i<total; ++i)
    {
        spnp::ImmediateTransition *transition = this->transitions->at(i);
        if(transition->id.compare(id))
        {
            transitions->erase(transitions->begin()+i);
            delete transition;
            break;
        }
    }
}

void spnp::Net::removeArc(std::string id)
{
    for(unsigned int i=0, total = this->arcs->size(); i<total; ++i)
    {
        spnp::Arc *arc = this->arcs->at(i);
        if(arc->id.compare(id))
        {
            arcs->erase(arcs->begin()+i);
            delete arc;
            break;
        }
    }
}

spnp::Place *spnp::Net::getPlace(std::string id)
{
    for(unsigned int i=0, total = this->places->size(); i<total; ++i)
    {
        spnp::Place *place = this->places->at(i);
        if(place->id.compare(id))
            return (place);
    }
    return nullptr;
}

spnp::ImmediateTransition *spnp::Net::getTransition(std::string id)
{
    for(unsigned int i=0, total = this->transitions->size(); i<total; ++i)
    {
        spnp::ImmediateTransition* trans = this->transitions->at(i);
        if(trans->id.compare(id))
            return trans;
    }
    return nullptr;
}

spnp::Arc *spnp::Net::getArc(std::string id)
{
    for(unsigned int i=0, total = this->arcs->size(); i<total; ++i)
    {
        spnp::Arc *arc = this->arcs->at(i);
        if(arc->id.compare(id))
            return arc;
    }
    return nullptr;
}

std::vector<spnp::Place *> *spnp::Net::getPlaces() const
{
    return this->places;
}

std::vector<spnp::ImmediateTransition *> *spnp::Net::getTransitions() const
{
    return this->transitions;
}

std::vector<spnp::Arc *> *spnp::Net::getArcs() const
{
    return this->arcs;
}

std::string spnp::Net::getClassNodeName()
{
    return "net";
}
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2011 Heiko Strathmann
 * Copyright (C) 2011 Berlin Institute of Technology and Max-Planck-Society
 */

#include <shogun/base/init.h>
#include <shogun/evaluation/CrossValidation.h>
#include <shogun/evaluation/ContingencyTableEvaluation.h>
#include <shogun/evaluation/StratifiedCrossValidationSplitting.h>
#include <shogun/modelselection/GridSearchModelSelection.h>
#include <shogun/modelselection/ModelSelectionParameters.h>
#include <shogun/modelselection/ParameterCombination.h>
#include <shogun/features/Labels.h>
#include <shogun/features/StringFeatures.h>
#include <shogun/classifier/svm/LibSVM.h>
#include <shogun/kernel/DistantSegmentsKernel.h>

using namespace shogun;

void print_message(FILE* target, const char* str)
{
	fprintf(target, "%s", str);
}

CModelSelectionParameters* create_param_tree()
{
	CModelSelectionParameters* root=new CModelSelectionParameters();

	CModelSelectionParameters* c1=new CModelSelectionParameters("C1");
	root->append_child(c1);
	c1->build_values(-1.0, 1.0, R_EXP);

	CModelSelectionParameters* c2=new CModelSelectionParameters("C2");
	root->append_child(c2);
	c2->build_values(-1.0, 1.0, R_EXP);

	CDistantSegmentsKernel* ds_kernel=new CDistantSegmentsKernel();
	CModelSelectionParameters* param_ds_kernel=
			new CModelSelectionParameters("kernel", ds_kernel);
	root->append_child(param_ds_kernel);

	CModelSelectionParameters* ds_kernel_delta=
			new CModelSelectionParameters("delta");
	ds_kernel_delta->build_values(1, 3, R_LINEAR);
	param_ds_kernel->append_child(ds_kernel_delta);

	CModelSelectionParameters* ds_kernel_theta=
			new CModelSelectionParameters("theta");
	ds_kernel_theta->build_values(1, 3, R_LINEAR);
	param_ds_kernel->append_child(ds_kernel_theta);

	return root;
}

int main(int argc, char **argv)
{
	init_shogun(&print_message, &print_message, &print_message);

	index_t num_strings=10;
	index_t max_string_length=20;
	index_t min_string_length=max_string_length/2;
	index_t num_subsets=num_strings/3;

	SGStringList<char> strings(num_strings, max_string_length);

	for (index_t i=0; i<num_strings; ++i)
	{
		index_t len=CMath::random(min_string_length, max_string_length);
		SGString<char> current(len);

		SG_SPRINT("string %i: \"", i);
		/* fill with random uppercase letters (ASCII) */
		for (index_t j=0; j<len; ++j)
		{
			current.string[j]=(char)CMath::random('A', 'Z');

			char* string=new char[2];
			string[0]=current.string[j];
			string[1]='\0';
			SG_SPRINT("%s", string);
			delete[] string;
		}
		SG_SPRINT("\"\n");

		strings.strings[i]=current;
	}

	/* create num_feautres 2-dimensional vectors */
	CStringFeatures<char>* features=new CStringFeatures<char>(strings, ALPHANUM);

	/* create labels, two classes */
	CLabels* labels=new CLabels(num_strings);
	for (index_t i=0; i<num_strings; ++i)
		labels->set_label(i, i%2==0 ? 1 : -1);

	/* create svm classifier */
	CLibSVM* classifier=new CLibSVM();

	/* splitting strategy */
	CStratifiedCrossValidationSplitting* splitting_strategy=
			new CStratifiedCrossValidationSplitting(labels, num_subsets);

	/* accuracy evaluation */
	CContingencyTableEvaluation* evaluation_criterium=
			new CContingencyTableEvaluation(ACCURACY);

	/* cross validation class for evaluation in model selection, 3 repetitions */
	CCrossValidation* cross=new CCrossValidation(classifier, features, labels,
			splitting_strategy, evaluation_criterium);
	cross->set_num_runs(3);

	/* model parameter selection, deletion is handled by modsel class (SG_UNREF) */
	CModelSelectionParameters* param_tree=create_param_tree();
	param_tree->print_tree();

	/* this is on the stack and handles all of the above structures in memory */
	CGridSearchModelSelection grid_search(param_tree, cross);

	CParameterCombination* best_combination=grid_search.select_model();
	SG_SPRINT("best parameter(s):\n");
	best_combination->print_tree();

	best_combination->apply_to_machine(classifier);

	/* larger number of runs to have tighter confidence intervals */
	cross->set_num_runs(100);
	cross->set_conf_int_alpha(0.01);
	CrossValidationResult result=cross->evaluate();
	SG_SPRINT("result: ");
	result.print_result();

	/* clean up destroy result parameter */
	SG_UNREF(best_combination);

	SG_SPRINT("\nEND\n");
	exit_shogun();

	return 0;
}

<commit_msg>made example smaller<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2011 Heiko Strathmann
 * Copyright (C) 2011 Berlin Institute of Technology and Max-Planck-Society
 */

#include <shogun/base/init.h>
#include <shogun/evaluation/CrossValidation.h>
#include <shogun/evaluation/ContingencyTableEvaluation.h>
#include <shogun/evaluation/StratifiedCrossValidationSplitting.h>
#include <shogun/modelselection/GridSearchModelSelection.h>
#include <shogun/modelselection/ModelSelectionParameters.h>
#include <shogun/modelselection/ParameterCombination.h>
#include <shogun/features/Labels.h>
#include <shogun/features/StringFeatures.h>
#include <shogun/classifier/svm/LibSVM.h>
#include <shogun/kernel/DistantSegmentsKernel.h>

using namespace shogun;

void print_message(FILE* target, const char* str)
{
	fprintf(target, "%s", str);
}

CModelSelectionParameters* create_param_tree()
{
	CModelSelectionParameters* root=new CModelSelectionParameters();

	CModelSelectionParameters* c1=new CModelSelectionParameters("C1");
	root->append_child(c1);
	c1->build_values(1.0, 2.0, R_EXP);

	CModelSelectionParameters* c2=new CModelSelectionParameters("C2");
	root->append_child(c2);
	c2->build_values(1.0, 2.0, R_EXP);

	CDistantSegmentsKernel* ds_kernel=new CDistantSegmentsKernel();
	CModelSelectionParameters* param_ds_kernel=
			new CModelSelectionParameters("kernel", ds_kernel);
	root->append_child(param_ds_kernel);

	CModelSelectionParameters* ds_kernel_delta=
			new CModelSelectionParameters("delta");
	ds_kernel_delta->build_values(1, 2, R_LINEAR);
	param_ds_kernel->append_child(ds_kernel_delta);

	CModelSelectionParameters* ds_kernel_theta=
			new CModelSelectionParameters("theta");
	ds_kernel_theta->build_values(1, 2, R_LINEAR);
	param_ds_kernel->append_child(ds_kernel_theta);

	return root;
}

int main(int argc, char **argv)
{
	init_shogun(&print_message, &print_message, &print_message);

	index_t num_strings=10;
	index_t max_string_length=20;
	index_t min_string_length=max_string_length/2;
	index_t num_subsets=num_strings/3;

	SGStringList<char> strings(num_strings, max_string_length);

	for (index_t i=0; i<num_strings; ++i)
	{
		index_t len=CMath::random(min_string_length, max_string_length);
		SGString<char> current(len);

		SG_SPRINT("string %i: \"", i);
		/* fill with random uppercase letters (ASCII) */
		for (index_t j=0; j<len; ++j)
		{
			current.string[j]=(char)CMath::random('A', 'Z');

			char* string=new char[2];
			string[0]=current.string[j];
			string[1]='\0';
			SG_SPRINT("%s", string);
			delete[] string;
		}
		SG_SPRINT("\"\n");

		strings.strings[i]=current;
	}

	/* create num_feautres 2-dimensional vectors */
	CStringFeatures<char>* features=new CStringFeatures<char>(strings, ALPHANUM);

	/* create labels, two classes */
	CLabels* labels=new CLabels(num_strings);
	for (index_t i=0; i<num_strings; ++i)
		labels->set_label(i, i%2==0 ? 1 : -1);

	/* create svm classifier */
	CLibSVM* classifier=new CLibSVM();

	/* splitting strategy */
	CStratifiedCrossValidationSplitting* splitting_strategy=
			new CStratifiedCrossValidationSplitting(labels, num_subsets);

	/* accuracy evaluation */
	CContingencyTableEvaluation* evaluation_criterium=
			new CContingencyTableEvaluation(ACCURACY);

	/* cross validation class for evaluation in model selection, 3 repetitions */
	CCrossValidation* cross=new CCrossValidation(classifier, features, labels,
			splitting_strategy, evaluation_criterium);
	cross->set_num_runs(3);

	/* model parameter selection, deletion is handled by modsel class (SG_UNREF) */
	CModelSelectionParameters* param_tree=create_param_tree();
	param_tree->print_tree();

	/* this is on the stack and handles all of the above structures in memory */
	CGridSearchModelSelection grid_search(param_tree, cross);

	CParameterCombination* best_combination=grid_search.select_model();
	SG_SPRINT("best parameter(s):\n");
	best_combination->print_tree();

	best_combination->apply_to_machine(classifier);

	/* larger number of runs to have tighter confidence intervals */
	cross->set_num_runs(100);
	cross->set_conf_int_alpha(0.01);
	CrossValidationResult result=cross->evaluate();
	SG_SPRINT("result: ");
	result.print_result();

	/* clean up destroy result parameter */
	SG_UNREF(best_combination);

	exit_shogun();

	return 0;
}

<|endoftext|>