<commit_before>#include "MineControllerSystem.h"
#include "Transform.h"
#include "RenderInfo.h"
#include "GraphicsBackendSystem.h"
#include <AglMatrix.h>
#include <AglQuaternion.h>
#include "InputBackendSystem.h"
#include <Control.h>
#include "PhysicsBody.h"
#include "BodyInitData.h"
#include "PhysicsSystem.h"
#include "ShipModule.h"
#include "StandardMine.h"
#include "PhysicsSystem.h"
#include <PhysicsController.h>
#include "SpawnSoundEffectPacket.h"

MineControllerSystem::MineControllerSystem(TcpServer* p_server)
	: EntitySystem(SystemType::MineControllerSystem, 1, ComponentType::StandardMine)
{
	m_server = p_server;
}

MineControllerSystem::~MineControllerSystem()
{
}

void MineControllerSystem::initialize()
{
}

void MineControllerSystem::processEntities(const vector<Entity*>& p_entities)
{
	float dt = m_world->getDelta();

	for (unsigned int i = 0; i < p_entities.size(); i++)
	{
		StandardMine* mine = static_cast<StandardMine*>(p_entities[i]->getComponent(ComponentType::StandardMine));
		mine->m_age += dt;

		//Check collision
		if (mine->m_age > 2)
		{
			PhysicsBody* pb = static_cast<PhysicsBody*>(p_entities[i]->getComponent(ComponentType::PhysicsBody));
			PhysicsSystem* ps = static_cast<PhysicsSystem*>(m_world->getSystem(SystemType::PhysicsSystem));

			vector<unsigned int> col = ps->getController()->CollidesWith(pb->m_id);
			Body* b = ps->getController()->getBody(pb->m_id);
			if (mine->m_age > 2 && col.size() > 0)
			{
				ps->getController()->ApplyExternalImpulse(b->GetWorld().GetTranslation(), 300);
				mine->m_age = 0;

				//Send an explosion sound effect

				Transform* t = static_cast<Transform*>(p_entities[i]->getComponent(ComponentType::Transform));

				SpawnSoundEffectPacket soundEffectPacket;
				soundEffectPacket.soundIdentifier = (int)SpawnSoundEffectPacket::Explosion;
				soundEffectPacket.positional = true;
				soundEffectPacket.position = t->getTranslation();
				soundEffectPacket.attachedToNetsyncEntity = -1; // entity->getIndex();
				m_server->broadcastPacket(soundEffectPacket.pack());
			}
		}
	}
}<commit_msg>Started on damage from mine<commit_after>#include "MineControllerSystem.h"
#include "Transform.h"
#include "RenderInfo.h"
#include "GraphicsBackendSystem.h"
#include <AglMatrix.h>
#include <AglQuaternion.h>
#include "InputBackendSystem.h"
#include <Control.h>
#include "PhysicsBody.h"
#include "BodyInitData.h"
#include "PhysicsSystem.h"
#include "ShipModule.h"
#include "StandardMine.h"
#include "PhysicsSystem.h"
#include <PhysicsController.h>
#include "SpawnSoundEffectPacket.h"

MineControllerSystem::MineControllerSystem(TcpServer* p_server)
	: EntitySystem(SystemType::MineControllerSystem, 1, ComponentType::StandardMine)
{
	m_server = p_server;
}

MineControllerSystem::~MineControllerSystem()
{
}

void MineControllerSystem::initialize()
{
}

void MineControllerSystem::processEntities(const vector<Entity*>& p_entities)
{
	float dt = m_world->getDelta();

	for (unsigned int i = 0; i < p_entities.size(); i++)
	{
		StandardMine* mine = static_cast<StandardMine*>(p_entities[i]->getComponent(ComponentType::StandardMine));
		mine->m_age += dt;

		//Check collision
		if (mine->m_age > 2)
		{
			PhysicsBody* pb = static_cast<PhysicsBody*>(p_entities[i]->getComponent(ComponentType::PhysicsBody));
			PhysicsSystem* ps = static_cast<PhysicsSystem*>(m_world->getSystem(SystemType::PhysicsSystem));

			vector<unsigned int> col = ps->getController()->CollidesWith(pb->m_id);
			Body* b = ps->getController()->getBody(pb->m_id);
			if (mine->m_age > 2 && col.size() > 0)
			{
				//Do some damage
				for (unsigned int j = 0; j < col.size(); j++)
				{
					/*Entity* hitEntity = ps->getEntity(col[j]);
					ShipModule* hitModule = static_cast<ShipModule*>(hitEntity->getComponent(ComponentType::ShipModule));
					if (hitModule)
						hitModule->m_health = 0;*/
				}

				//Send a shockwave
				ps->getController()->ApplyExternalImpulse(b->GetWorld().GetTranslation(), 300);
				mine->m_age = 0;

				//Send an explosion sound effect
				Transform* t = static_cast<Transform*>(p_entities[i]->getComponent(ComponentType::Transform));

				SpawnSoundEffectPacket soundEffectPacket;
				soundEffectPacket.soundIdentifier = (int)SpawnSoundEffectPacket::Explosion;
				soundEffectPacket.positional = true;
				soundEffectPacket.position = t->getTranslation();
				soundEffectPacket.attachedToNetsyncEntity = -1; // entity->getIndex();
				m_server->broadcastPacket(soundEffectPacket.pack());
			}
		}
	}
}<|endoftext|>


<commit_before>//===- llvm-cov.cpp - LLVM coverage tool ----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// llvm-cov is a command line tools to analyze and report coverage information.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/GCOV.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/system_error.h"
using namespace llvm;

static cl::opt<std::string> SourceFile(cl::Positional, cl::Required,
                                       cl::desc("SOURCEFILE"));

static cl::opt<bool> AllBlocks("a", cl::init(false),
                               cl::desc("Display all basic blocks"));

static cl::opt<bool> BranchProb("b", cl::init(false),
                                cl::desc("Display branch probabilities"));

static cl::opt<bool> BranchCount("c", cl::init(false),
                                 cl::desc("Display branch counts instead "
                                           "of percentages (requires -b)"));

static cl::opt<bool> FuncSummary("f", cl::init(false),
                                 cl::desc("Show coverage for each function"));

static cl::opt<bool> UncondBranch("u", cl::init(false),
                                  cl::desc("Display unconditional branch info "
                                           "(requires -b)"));

static cl::OptionCategory DebugCat("Internal and debugging options");
static cl::opt<bool> DumpGCOV("dump", cl::init(false), cl::cat(DebugCat),
                              cl::desc("Dump the gcov file to stderr"));
static cl::opt<std::string> InputGCNO("gcno", cl::cat(DebugCat), cl::init(""),
                                      cl::desc("Override inferred gcno file"));
static cl::opt<std::string> InputGCDA("gcda", cl::cat(DebugCat), cl::init(""),
                                      cl::desc("Override inferred gcda file"));

//===----------------------------------------------------------------------===//
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");

  if (InputGCNO.empty())
    InputGCNO = SourceFile.substr(0, SourceFile.rfind(".")) + ".gcno";
  if (InputGCDA.empty())
    InputGCDA = SourceFile.substr(0, SourceFile.rfind(".")) + ".gcda";

  GCOVFile GF;

  OwningPtr<MemoryBuffer> GCNO_Buff;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputGCNO, GCNO_Buff)) {
    errs() << InputGCNO << ": " << ec.message() << "\n";
    return 1;
  }
  GCOVBuffer GCNO_GB(GCNO_Buff.get());
  if (!GF.readGCNO(GCNO_GB)) {
    errs() << "Invalid .gcno File!\n";
    return 1;
  }

  OwningPtr<MemoryBuffer> GCDA_Buff;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputGCDA, GCDA_Buff)) {
    errs() << InputGCDA << ": " << ec.message() << "\n";
    return 1;
  }
  GCOVBuffer GCDA_GB(GCDA_Buff.get());
  if (!GF.readGCDA(GCDA_GB)) {
    errs() << "Invalid .gcda File!\n";
    return 1;
  }

  if (DumpGCOV)
    GF.dump();

  GCOVOptions Options(AllBlocks, BranchProb, BranchCount, FuncSummary,
                      UncondBranch);
  FileInfo FI(Options);
  GF.collectLineCounts(FI);
  FI.print(InputGCNO, InputGCDA);
  return 0;
}
<commit_msg>llvm-cov: Accept the long forms of gcov options<commit_after>//===- llvm-cov.cpp - LLVM coverage tool ----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// llvm-cov is a command line tools to analyze and report coverage information.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/GCOV.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/system_error.h"
using namespace llvm;

static cl::opt<std::string> SourceFile(cl::Positional, cl::Required,
                                       cl::desc("SOURCEFILE"));

static cl::opt<bool> AllBlocks("a", cl::init(false),
                               cl::desc("Display all basic blocks"));
static cl::alias AllBlocksA("all-blocks", cl::aliasopt(AllBlocks));

static cl::opt<bool> BranchProb("b", cl::init(false),
                                cl::desc("Display branch probabilities"));
static cl::alias BranchProbA("branch-probabilities", cl::aliasopt(BranchProb));

static cl::opt<bool> BranchCount("c", cl::init(false),
                                 cl::desc("Display branch counts instead "
                                           "of percentages (requires -b)"));
static cl::alias BranchCountA("branch-counts", cl::aliasopt(BranchCount));

static cl::opt<bool> FuncSummary("f", cl::init(false),
                                 cl::desc("Show coverage for each function"));
static cl::alias FuncSummaryA("function-summaries", cl::aliasopt(FuncSummary));

static cl::opt<bool> UncondBranch("u", cl::init(false),
                                  cl::desc("Display unconditional branch info "
                                           "(requires -b)"));
static cl::alias UncondBranchA("unconditional-branches",
                               cl::aliasopt(UncondBranch));

static cl::OptionCategory DebugCat("Internal and debugging options");
static cl::opt<bool> DumpGCOV("dump", cl::init(false), cl::cat(DebugCat),
                              cl::desc("Dump the gcov file to stderr"));
static cl::opt<std::string> InputGCNO("gcno", cl::cat(DebugCat), cl::init(""),
                                      cl::desc("Override inferred gcno file"));
static cl::opt<std::string> InputGCDA("gcda", cl::cat(DebugCat), cl::init(""),
                                      cl::desc("Override inferred gcda file"));

//===----------------------------------------------------------------------===//
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");

  if (InputGCNO.empty())
    InputGCNO = SourceFile.substr(0, SourceFile.rfind(".")) + ".gcno";
  if (InputGCDA.empty())
    InputGCDA = SourceFile.substr(0, SourceFile.rfind(".")) + ".gcda";

  GCOVFile GF;

  OwningPtr<MemoryBuffer> GCNO_Buff;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputGCNO, GCNO_Buff)) {
    errs() << InputGCNO << ": " << ec.message() << "\n";
    return 1;
  }
  GCOVBuffer GCNO_GB(GCNO_Buff.get());
  if (!GF.readGCNO(GCNO_GB)) {
    errs() << "Invalid .gcno File!\n";
    return 1;
  }

  OwningPtr<MemoryBuffer> GCDA_Buff;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputGCDA, GCDA_Buff)) {
    errs() << InputGCDA << ": " << ec.message() << "\n";
    return 1;
  }
  GCOVBuffer GCDA_GB(GCDA_Buff.get());
  if (!GF.readGCDA(GCDA_GB)) {
    errs() << "Invalid .gcda File!\n";
    return 1;
  }

  if (DumpGCOV)
    GF.dump();

  GCOVOptions Options(AllBlocks, BranchProb, BranchCount, FuncSummary,
                      UncondBranch);
  FileInfo FI(Options);
  GF.collectLineCounts(FI);
  FI.print(InputGCNO, InputGCDA);
  return 0;
}
<|endoftext|>


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

#include <sensor_msgs/PointCloud2.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/console/print.h>
#include <pcl/console/parse.h>
#include <pcl/console/time.h>

using namespace pcl;
using namespace pcl::io;
using namespace pcl::console;

int    default_k = 0;
double default_radius = 0.0;

Eigen::Vector4f    translation;
Eigen::Quaternionf orientation;

void
printHelp (int argc, char **argv)
{
  print_error ("Syntax is: %s input.pcd output.pcd <options>\n", argv[0]);
  print_info ("  where options are:\n");
  print_info ("                     -radius X = use a radius of Xm around each point to determine the neighborhood (default: ");
  print_value ("%f", default_radius); print_info (")\n");
  print_info ("                     -k X      = use a fixed number of X-nearest neighbors around each point (default: ");
  print_value ("%f", default_k); print_info (")\n");
}

bool
loadCloud (const std::string &filename, sensor_msgs::PointCloud2 &cloud)
{
  TicToc tt;
  print_highlight ("Loading "); print_value ("%s ", filename.c_str ());

  tt.tic ();
  if (loadPCDFile (filename, cloud, translation, orientation) < 0)
    return (false);
  print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", cloud.width * cloud.height); print_info (" points]\n");
  print_info ("Available dimensions: "); print_value ("%s\n", pcl::getFieldsList (cloud).c_str ());

  return (true);
}

void
compute (const sensor_msgs::PointCloud2::ConstPtr &input, sensor_msgs::PointCloud2 &output,
         int k, double radius)
{
  // Convert data to PointCloud<T>
  PointCloud<PointXYZ>::Ptr xyz (new PointCloud<PointXYZ>);
  fromROSMsg (*input, *xyz);

  // Estimate
  TicToc tt;
  tt.tic ();

  print_highlight (stderr, "Computing ");

  NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
  ne.setInputCloud (xyz);
  //ne.setSearchMethod (pcl::KdTreeFLANN<pcl::PointXYZ>::Ptr (new pcl::KdTreeFLANN<pcl::PointXYZ>));
  ne.setKSearch (k);
  ne.setRadiusSearch (radius);

  PointCloud<Normal> normals;
  ne.compute (normals);

  print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", normals.width * normals.height); print_info (" points]\n");

  // Convert data back
  sensor_msgs::PointCloud2 output_normals;
  toROSMsg (normals, output_normals);
  concatenateFields (*input, output_normals, output);
}

void
saveCloud (const std::string &filename, const sensor_msgs::PointCloud2 &output)
{
  TicToc tt;
  tt.tic ();

  print_highlight ("Saving "); print_value ("%s ", filename.c_str ());

  pcl::io::savePCDFile (filename, output, translation, orientation, false);

  print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", output.width * output.height); print_info (" points]\n");
}

/* ---[ */
int
main (int argc, char** argv)
{
  print_info ("Estimate surface normals using pcl::NormalEstimation. For more information, use: %s -h\n", argv[0]);

  if (argc < 3)
  {
    printHelp (argc, argv);
    return (-1);
  }

  // Parse the command line arguments for .pcd files
  std::vector<int> p_file_indices;
  p_file_indices = parse_file_extension_argument (argc, argv, ".pcd");
  if (p_file_indices.size () != 2)
  {
    print_error ("Need one input PCD file and one output PCD file to continue.\n");
    return (-1);
  }

  // Command line parsing
  int k = default_k;
  double radius = default_radius;
  parse_argument (argc, argv, "-k", k);
  parse_argument (argc, argv, "-radius", radius);

  // Load the first file
  sensor_msgs::PointCloud2::Ptr cloud (new sensor_msgs::PointCloud2);
  if (!loadCloud (argv[p_file_indices[0]], *cloud))
    return (-1);

  // Perform the feature estimation
  sensor_msgs::PointCloud2 output;
  compute (cloud, output, k, radius);

  // Save into the second file
  saveCloud (argv[p_file_indices[1]], output);
}

<commit_msg>NormalEstimation tool temporary fix for orgranized point clouds<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id: normal_estimation.cpp 1032 2011-05-18 22:43:27Z marton $
 *
 */

#include <sensor_msgs/PointCloud2.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/console/print.h>
#include <pcl/console/parse.h>
#include <pcl/console/time.h>

using namespace pcl;
using namespace pcl::io;
using namespace pcl::console;

int    default_k = 0;
double default_radius = 0.0;

Eigen::Vector4f    translation;
Eigen::Quaternionf orientation;

void
printHelp (int argc, char **argv)
{
  print_error ("Syntax is: %s input.pcd output.pcd <options>\n", argv[0]);
  print_info ("  where options are:\n");
  print_info ("                     -radius X = use a radius of Xm around each point to determine the neighborhood (default: ");
  print_value ("%f", default_radius); print_info (")\n");
  print_info ("                     -k X      = use a fixed number of X-nearest neighbors around each point (default: ");
  print_value ("%f", default_k); print_info (")\n");
}

bool
loadCloud (const std::string &filename, sensor_msgs::PointCloud2 &cloud)
{
  TicToc tt;
  print_highlight ("Loading "); print_value ("%s ", filename.c_str ());

  tt.tic ();
  if (loadPCDFile (filename, cloud, translation, orientation) < 0)
    return (false);
  print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", cloud.width * cloud.height); print_info (" points]\n");
  print_info ("Available dimensions: "); print_value ("%s\n", pcl::getFieldsList (cloud).c_str ());

  return (true);
}

void
compute (const sensor_msgs::PointCloud2::ConstPtr &input, sensor_msgs::PointCloud2 &output,
         int k, double radius)
{
  // Convert data to PointCloud<T>
  PointCloud<PointXYZ>::Ptr xyz (new PointCloud<PointXYZ>);
  fromROSMsg (*input, *xyz);

  // Estimate
  TicToc tt;
  tt.tic ();

  print_highlight (stderr, "Computing ");

  NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
  ne.setInputCloud (xyz);
  ne.setSearchMethod (pcl::search::KdTree<pcl::PointXYZ>::Ptr (new pcl::search::KdTree<pcl::PointXYZ>));
  ne.setKSearch (k);
  ne.setRadiusSearch (radius);

  PointCloud<Normal> normals;
  ne.compute (normals);

  print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", normals.width * normals.height); print_info (" points]\n");

  // Convert data back
  sensor_msgs::PointCloud2 output_normals;
  toROSMsg (normals, output_normals);
  concatenateFields (*input, output_normals, output);
}

void
saveCloud (const std::string &filename, const sensor_msgs::PointCloud2 &output)
{
  TicToc tt;
  tt.tic ();

  print_highlight ("Saving "); print_value ("%s ", filename.c_str ());

  pcl::io::savePCDFile (filename, output, translation, orientation, false);

  print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", output.width * output.height); print_info (" points]\n");
}

/* ---[ */
int
main (int argc, char** argv)
{
  print_info ("Estimate surface normals using pcl::NormalEstimation. For more information, use: %s -h\n", argv[0]);

  if (argc < 3)
  {
    printHelp (argc, argv);
    return (-1);
  }

  // Parse the command line arguments for .pcd files
  std::vector<int> p_file_indices;
  p_file_indices = parse_file_extension_argument (argc, argv, ".pcd");
  if (p_file_indices.size () != 2)
  {
    print_error ("Need one input PCD file and one output PCD file to continue.\n");
    return (-1);
  }

  // Command line parsing
  int k = default_k;
  double radius = default_radius;
  parse_argument (argc, argv, "-k", k);
  parse_argument (argc, argv, "-radius", radius);

  // Load the first file
  sensor_msgs::PointCloud2::Ptr cloud (new sensor_msgs::PointCloud2);
  if (!loadCloud (argv[p_file_indices[0]], *cloud))
    return (-1);

  // Perform the feature estimation
  sensor_msgs::PointCloud2 output;
  compute (cloud, output, k, radius);

  // Save into the second file
  saveCloud (argv[p_file_indices[1]], output);
}

<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2020 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#ifndef ETL_COUNTERS

namespace etl {

/*!
 * \brief Dump all counters values to the console.
 */
inline void dump_counters() {
    //No counters
}

/*!
 * \brief Increase the given counter
 * \param name The name of the counter to increase
 */
inline void inc_counter([[maybe_unused]] const char* name) {}

} //end of namespace etl

#else

#include <chrono>
#include <iosfwd>
#include <iomanip>
#include <sstream>

namespace etl {

constexpr const size_t max_counters = 64;

struct counter_t {
    const char* name;
    std::atomic<size_t> count;

    counter_t() : name(nullptr), count(0) {}

    counter_t(const counter_t& rhs) : name(rhs.name), count(rhs.count.load()) {}

    counter_t& operator=(const counter_t& rhs) {
        if (&rhs != this) {
            name  = rhs.name;
            count = rhs.count.load();
        }

        return *this;
    }

    counter_t(counter_t&& rhs) : name(std::move(rhs.name)), count(rhs.count.load()) {}

    counter_t& operator=(counter_t&& rhs) {
        if (&rhs != this) {
            name  = std::move(rhs.name);
            count = rhs.count.load();
        }

        return *this;
    }
};

struct counters_t {
    std::array<counter_t, max_counters> counters;
    std::mutex lock;

    void reset() {
        std::lock_guard<std::mutex> l(lock);

        for (auto& counter : counters) {
            counter.name  = nullptr;
            counter.count = 0;
        }
    }
};

inline counters_t& get_counters() {
    static counters_t counters;
    return counters;
}

/*!
 * \brief Reset all counters
 */
inline void reset_counters() {
    decltype(auto) counters = get_counters();
    counters.reset();
}

/*!
 * \brief Dump all counters values to the console.
 */
inline void dump_counters() {
    decltype(auto) counters = get_counters().counters;

    //Sort the counters by count (DESC)
    std::sort(counters.begin(), counters.end(), [](auto& left, auto& right) { return left.count > right.count; });

    // Print all the used counters
    for (decltype(auto) counter : counters) {
        if (counter.name) {
            std::cout << counter.name << ": " << counter.count << std::endl;
        }
    }
}

/*!
 * \brief Increase the given counter
 * \param name The name of the counter to increase
 */
inline void inc_counter(const char* name) {
#ifdef ETL_COUNTERS_VERBOSE
    std::cout << "counter:inc:" << name << std::endl;
#endif

    decltype(auto) counters = get_counters();

    for (decltype(auto) counter : counters.counters) {
        if (counter.name == name) {
            ++counter.count;

            return;
        }
    }

    std::lock_guard<std::mutex> lock(counters.lock);

    for (decltype(auto) counter : counters.counters) {
        if (counter.name == name) {
            ++counter.count;

            return;
        }
    }

    for (decltype(auto) counter : counters.counters) {
        if (!counter.name) {
            counter.name  = name;
            counter.count = 1;

            return;
        }
    }

    std::cerr << "Unable to register counter " << name << std::endl;
}

} //end of namespace etl

#endif
<commit_msg>Add support for dump_counters_pretty<commit_after>//=======================================================================
// Copyright (c) 2014-2020 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#ifndef ETL_COUNTERS

namespace etl {

/*!
 * \brief Dump all counters values to the console.
 */
inline void dump_counters() {
    //No counters
}

/*!
 * \brief Increase the given counter
 * \param name The name of the counter to increase
 */
inline void inc_counter([[maybe_unused]] const char* name) {}

} //end of namespace etl

#else

#include <chrono>
#include <iosfwd>
#include <iomanip>
#include <sstream>

namespace etl {

constexpr const size_t max_counters = 64;

struct counter_t {
    const char* name;
    std::atomic<size_t> count;

    counter_t() : name(nullptr), count(0) {}

    counter_t(const counter_t& rhs) : name(rhs.name), count(rhs.count.load()) {}

    counter_t& operator=(const counter_t& rhs) {
        if (&rhs != this) {
            name  = rhs.name;
            count = rhs.count.load();
        }

        return *this;
    }

    counter_t(counter_t&& rhs) : name(std::move(rhs.name)), count(rhs.count.load()) {}

    counter_t& operator=(counter_t&& rhs) {
        if (&rhs != this) {
            name  = std::move(rhs.name);
            count = rhs.count.load();
        }

        return *this;
    }
};

struct counters_t {
    std::array<counter_t, max_counters> counters;
    std::mutex lock;

    void reset() {
        std::lock_guard<std::mutex> l(lock);

        for (auto& counter : counters) {
            counter.name  = nullptr;
            counter.count = 0;
        }
    }
};

inline counters_t& get_counters() {
    static counters_t counters;
    return counters;
}

/*!
 * \brief Reset all counters
 */
inline void reset_counters() {
    decltype(auto) counters = get_counters();
    counters.reset();
}

/*!
 * \brief Dump all counters values to the console.
 */
inline void dump_counters() {
    decltype(auto) counters = get_counters().counters;

    //Sort the counters by count (DESC)
    std::sort(counters.begin(), counters.end(), [](auto& left, auto& right) { return left.count > right.count; });

    // Print all the used counters
    for (decltype(auto) counter : counters) {
        if (counter.name) {
            std::cout << counter.name << ": " << counter.count << std::endl;
        }
    }
}

/*!
 * \brief Dump all counters values to the console.
 */
inline void dump_counters_pretty() {
    decltype(auto) counters = get_counters().counters;

    if(counters.empty()){
        std::cout << "No counters have been recorded!" << std::endl;
        return;
    }

    std::cout << std::endl;

    //Sort the counters by count (DESC)
    std::sort(counters.begin(), counters.end(), [](auto& left, auto& right) { return left.count > right.count; });

    constexpr size_t columns = 2;

    std::string column_name[columns];
    column_name[0] = "Counter";
    column_name[1] = "Count";

    size_t column_length[columns];
    column_length[0] = column_name[0].size();
    column_length[1] = column_name[1].size();

    // Compute the width of each column
    for (decltype(auto) counter : counters) {
        if (counter.name) {
            column_length[0] = std::max(column_length[0], std::string(counter.name).size());
            column_length[1] = std::max(column_length[1], std::to_string(counter.count).size());
        }
    }

    const size_t line_length = (columns + 1) * 1 + 2 + (columns - 1) * 2 + std::accumulate(column_length, column_length + columns, 0);

    std::cout << " " << std::string(line_length, '-') << '\n';

    printf(" | %-*s | %-*s |\n",
        int(column_length[0]), column_name[0].c_str(),
        int(column_length[1]), column_name[1].c_str());

    // Print all the used counters
    for (decltype(auto) counter : counters) {
        if (counter.name) {
            printf(" | %-*s | %-*s |\n",
                int(column_length[0]), counter.name,
                int(column_length[1]), std::to_string(counter.count).c_str());
        }
    }

    std::cout << " " << std::string(line_length, '-') << '\n';

    // Print all the used counters
    for (decltype(auto) counter : counters) {
        if (counter.name) {
            std::cout << counter.name << ": " << counter.count << std::endl;
        }
    }
}

/*!
 * \brief Increase the given counter
 * \param name The name of the counter to increase
 */
inline void inc_counter(const char* name) {
#ifdef ETL_COUNTERS_VERBOSE
    std::cout << "counter:inc:" << name << std::endl;
#endif

    decltype(auto) counters = get_counters();

    for (decltype(auto) counter : counters.counters) {
        if (counter.name == name) {
            ++counter.count;

            return;
        }
    }

    std::lock_guard<std::mutex> lock(counters.lock);

    for (decltype(auto) counter : counters.counters) {
        if (counter.name == name) {
            ++counter.count;

            return;
        }
    }

    for (decltype(auto) counter : counters.counters) {
        if (!counter.name) {
            counter.name  = name;
            counter.count = 1;

            return;
        }
    }

    std::cerr << "Unable to register counter " << name << std::endl;
}

} //end of namespace etl

#endif
<|endoftext|>


<commit_before>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
The MIT License

Copyright (c) 2008, 2009 Flusspferd contributors (see "CONTRIBUTORS" or
                                       http://flusspferd.org/contributors.txt)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef FLUSSPFERD_CREATE_HPP
#define FLUSSPFERD_CREATE_HPP

#ifndef PREPROC_DEBUG
#include "object.hpp"
#include "function.hpp"
#include "array.hpp"
#include "native_function.hpp"
#include "local_root_scope.hpp"
#include <boost/type_traits/is_function.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/range.hpp>
#include <boost/parameter/parameters.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/name.hpp>
#include <boost/parameter/binding.hpp>
#endif
#include "detail/limit.hpp"
#include <boost/preprocessor.hpp>

namespace flusspferd {

class native_object_base;
class function;
class native_function_base;

#ifndef IN_DOXYGEN
namespace detail {

object create_native_object(object const &proto);
object create_native_enumerable_object(object const &proto);

}
#endif

/**
 * @name Creating values
 * @addtogroup create
 */
//@{
/**
 * Create a simple object.
 *
 * Creates a new object with prototype @p proto. If proto is @c null,
 * @c Object.prototype will be used.
 *
 * @param proto The object to use as prototype.
 * @return The new object.
 */
object create_object(object const &proto = object());

#ifndef IN_DOXYGEN

#define FLUSSPFERD_FN_CREATE_NATIVE_OBJECT(z, n_args, d) \
  template< \
    typename T \
    BOOST_PP_ENUM_TRAILING_PARAMS(n_args, typename T) \
  > \
  typename boost::enable_if< boost::mpl::not_<  \
    typename T::class_info::custom_enumerate >, \
  T& >::type                                    \
  create_native_object(      \
    object proto \
    BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(n_args, T, const & param) \
  ) { \
    if (proto.is_null()) \
      proto = current_context().prototype<T>(); \
    local_root_scope scope; \
    object obj = detail::create_native_object(proto); \
    return *(new T(obj BOOST_PP_ENUM_TRAILING_PARAMS(n_args, param))); \
  } \
  \
  template< \
    typename T \
    BOOST_PP_ENUM_TRAILING_PARAMS(n_args, typename T) \
  > \
  typename boost::enable_if<                          \
    typename T::class_info::custom_enumerate,         \
  T& >::type                                          \
  create_native_object(                               \
    object proto                                      \
    BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(n_args, T, const & param) \
  ) { \
    if (proto.is_null()) \
      proto = current_context().prototype<T>(); \
    local_root_scope scope; \
    object obj = detail::create_native_enumerable_object(proto); \
    return *(new T(obj BOOST_PP_ENUM_TRAILING_PARAMS(n_args, param))); \
  } \
  /* */

BOOST_PP_REPEAT(
  BOOST_PP_INC(FLUSSPFERD_PARAM_LIMIT),
  FLUSSPFERD_FN_CREATE_NATIVE_OBJECT,
  ~
)

#else

/**
 * Create a new native object of type @p T.
 *
 * @param T The type of the object's class.
 * @param proto The prototype to be used. If @p null, the class' default
 *          prototype will be used.
 * @param ... The parameters to the constructor of @p T.
 * @return The new object.
 */
template<typename T>
T &create_native_object(object const &proto, ...);

#endif
//@}

/**
 * @name Creating functions
 * @addtogroup create_function
 */
//@{

function create_function(
    std::string const &name,
    unsigned n_args,
    std::vector<std::string> argnames,
    flusspferd::string const &body,
    std::string const &file,
    unsigned line);

/**
 * Create a new native function.
 *
 * @p ptr will be deleted by Flusspferd.
 *
 * @param ptr The native function object.
 * @return The new function.
 */
function create_native_function(native_function_base *ptr);

/**
 * Create a new native function as method of an object.
 *
 * The new method of object @p o will have the name @c ptr->name().
 *
 * @param o The object to add the method to.
 * @param ptr The native function object.
 * @return The new method.
 */
function create_native_function(object const &o, native_function_base *ptr);

#ifndef IN_DOXYGEN

#define FLUSSPFERD_FN_CREATE_NATIVE_FUNCTION(z, n_args, d) \
  template< \
    typename T \
    BOOST_PP_ENUM_TRAILING_PARAMS(n_args, typename T) \
  > \
  object create_native_functor_function( \
    object const &o \
    BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(n_args, T, const & param), \
    typename boost::enable_if_c<!boost::is_function<T>::value>::type * = 0 \
  ) { \
    return create_native_function(o, new T(BOOST_PP_ENUM_PARAMS(n_args, param))); \
  } \
  /* */

BOOST_PP_REPEAT(
  BOOST_PP_INC(FLUSSPFERD_PARAM_LIMIT),
  FLUSSPFERD_FN_CREATE_NATIVE_FUNCTION,
  ~
)

#else

/**
 * Create a new native function of type @p F as method of an object.
 *
 * @p F must inherit from #native_function_base.
 *
 * The new method of object @p o will have the name @c ptr->name().
 *
 * @param F The functor type.
 * @param o The object to add the method to.
 * @param ... The parameters to pass to the constructor of @p F.
 * @return The new method.
 */
template<typename F>
object create_native_functor_function(object const &o, ...);

#endif

/**
 * Create a new native method of an object.
 *
 * @param o The object to add the method to.
 * @param name The method name.
 * @param fn The functor to call.
 * @param arity The function arity.
 * @return The new function.
 */
inline function create_native_function(
  object const &o,
  std::string const &name,
  boost::function<void (call_context &)> const &fn,
  unsigned arity = 0)
{
  return create_native_functor_function<native_function<void> >(
      o, fn, arity, name);
}

/**
 * Create a new native method of an object.
 *
 * @param T The function signature to use.
 * @param o The object to add the method to.
 * @param name The function name.
 * @param fn The functor to call.
 * @return The new function.
 */
template<typename T>
function create_native_function(
  object const &o,
  std::string const &name,
  boost::function<T> const &fn)
{
  return create_native_functor_function<native_function<T,false> >(o, fn, name);
}

/**
 * Create a new native method of an object.
 *
 * The first parameter passed will be 'this'.
 *
 * @param T The function signature to use.
 * @param o The object to add the method to.
 * @param name The function name.
 * @param fn The functor to call.
 * @return The new function.
 */
template<typename T>
function create_native_method(
  object const &o,
  std::string const &name,
  boost::function<T> const &fn)
{
  return create_native_functor_function<native_function<T,true> >(o, fn, name);
}

/**
 * Create a new native method of an object.
 *
 * @param o The object to add the method to.
 * @param name The method name.
 * @param fnptr The function to call (also determines the function signature).
 * @return The new method.
 */
template<typename T>
function create_native_function(
  object const &o,
  std::string const &name,
  T *fnptr,
  typename boost::enable_if_c<boost::is_function<T>::value>::type* =0)
{
  return create_native_function<T>(o, name, boost::function<T>(fnptr));
}

/**
 * Create a new native method of an object.
 *
 * The first parameter passed will be 'this'.
 *
 * @param o The object to add the method to.
 * @param name The method name.
 * @param fnptr The function to call (also determines the function signature).
 * @return The new method.
 */
template<typename T>
function create_native_method(
  object const &o,
  std::string const &name,
  T *fnptr,
  typename boost::enable_if_c<boost::is_function<T>::value>::type* =0)
{
  return create_native_method<T>(o, name, boost::function<T>(fnptr));
}

/**
 * Create a new native method of an object.
 *
 * @param o The object to add the method to.
 * @param name The method name.
 * @param memfnptr The member function to call.
 * @return The new function.
 */
template<typename T>
function create_native_method(
  object const &o,
  std::string const &name,
  void (T::*memfnptr)(call_context &),
  unsigned arity = 0)
{
  return create_native_functor_function<native_member_function<void, T> >(
    o, memfnptr, arity, name);
}

/**
 * Create a new native method of an object.
 *
 * @param o The object to add the method to.
 * @param name The method name.
 * @param memfnptr The member function to call (also determines the function
 *                 signature).
 * @return The new function.
 */
template<typename R, typename T>
function create_native_method(
  object const &o,
  std::string const &name,
  R T::*memfnptr)
{
  return create_native_functor_function<native_member_function<R, T> >(
    o, memfnptr, name);
}

//@}

namespace param {
  BOOST_PARAMETER_NAME(length)
  BOOST_PARAMETER_NAME(contents)
}

namespace detail {
  flusspferd::array create_length_array(std::size_t length);

  template<typename Class>
  struct create_traits;

  template<typename T, typename C = void>
  struct is_boost_range_impl {
    typedef boost::mpl::false_ type;
  };

  template<>
  struct create_traits<flusspferd::array> {
    typedef flusspferd::array result_type;

    typedef boost::parameter::parameters<
        boost::parameter::optional<
          boost::parameter::deduced<param::tag::length>,
          boost::is_integral<boost::mpl::_>
        >,
        boost::parameter::optional<
          boost::parameter::deduced<param::tag::contents>,
          boost::mpl::not_<boost::is_integral<boost::mpl::_> >
        >
      >
      parameters;

    static flusspferd::array create() {
      return create_length_array(0);
    }

    template<typename ArgPack>
    static
    typename boost::enable_if<
      boost::is_same<
        typename boost::parameter::binding<
          ArgPack,
          param::tag::contents,
          void
        >::type,
        void
      >,
      flusspferd::array
    >::type
    create(ArgPack const &arg) {
      return create_length_array(arg[param::_length | 0]);
    }

    template<typename ArgPack>
    static
    typename boost::disable_if<
      boost::is_same<
        typename boost::parameter::binding<
          ArgPack,
          param::tag::contents,
          void
        >::type,
        void
      >,
      flusspferd::array
    >::type
    create(ArgPack const &arg) {
      typedef typename boost::parameter::value_type<
          ArgPack,
          param::tag::contents
        >::type
        Range;

      typedef typename boost::range_iterator<Range>::type iterator;

      Range const &r = arg[param::_contents];

      local_root_scope scope;

      array arr = create_length_array(0);

      iterator first = boost::begin(r);
      iterator last = boost::end(r);

      for (iterator it = first; it != last; ++it)
        arr.push(*it);

      return arr;
    }
  };

}

template<typename Class>
typename detail::create_traits<Class>::result_type
create()
{
  typedef detail::create_traits<Class> traits;

  return traits::create();
}

template<typename Class, typename T0>
typename detail::create_traits<Class>::result_type
create(
  T0 const &x0,
  typename detail::create_traits<Class>::parameters::template match<T0>::type kw = typename detail::create_traits<Class>::parameters())
{
  typedef detail::create_traits<Class> traits;

  return traits::create(kw(x0));
}

}

#endif
<commit_msg>new_create: allow multiple parameters (how fancy)<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
The MIT License

Copyright (c) 2008, 2009 Flusspferd contributors (see "CONTRIBUTORS" or
                                       http://flusspferd.org/contributors.txt)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef FLUSSPFERD_CREATE_HPP
#define FLUSSPFERD_CREATE_HPP

#ifndef PREPROC_DEBUG
#include "object.hpp"
#include "function.hpp"
#include "array.hpp"
#include "native_function.hpp"
#include "local_root_scope.hpp"
#include <boost/type_traits/is_function.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/range.hpp>
#include <boost/parameter/parameters.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/name.hpp>
#include <boost/parameter/binding.hpp>
#endif
#include "detail/limit.hpp"
#include <boost/preprocessor.hpp>
#include <boost/parameter/config.hpp>

namespace flusspferd {

class native_object_base;
class function;
class native_function_base;

#ifndef IN_DOXYGEN
namespace detail {

object create_native_object(object const &proto);
object create_native_enumerable_object(object const &proto);

}
#endif

/**
 * @name Creating values
 * @addtogroup create
 */
//@{
/**
 * Create a simple object.
 *
 * Creates a new object with prototype @p proto. If proto is @c null,
 * @c Object.prototype will be used.
 *
 * @param proto The object to use as prototype.
 * @return The new object.
 */
object create_object(object const &proto = object());

#ifndef IN_DOXYGEN

#define FLUSSPFERD_FN_CREATE_NATIVE_OBJECT(z, n_args, d) \
  template< \
    typename T \
    BOOST_PP_ENUM_TRAILING_PARAMS(n_args, typename T) \
  > \
  typename boost::enable_if< boost::mpl::not_<  \
    typename T::class_info::custom_enumerate >, \
  T& >::type                                    \
  create_native_object(      \
    object proto \
    BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(n_args, T, const & param) \
  ) { \
    if (proto.is_null()) \
      proto = current_context().prototype<T>(); \
    local_root_scope scope; \
    object obj = detail::create_native_object(proto); \
    return *(new T(obj BOOST_PP_ENUM_TRAILING_PARAMS(n_args, param))); \
  } \
  \
  template< \
    typename T \
    BOOST_PP_ENUM_TRAILING_PARAMS(n_args, typename T) \
  > \
  typename boost::enable_if<                          \
    typename T::class_info::custom_enumerate,         \
  T& >::type                                          \
  create_native_object(                               \
    object proto                                      \
    BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(n_args, T, const & param) \
  ) { \
    if (proto.is_null()) \
      proto = current_context().prototype<T>(); \
    local_root_scope scope; \
    object obj = detail::create_native_enumerable_object(proto); \
    return *(new T(obj BOOST_PP_ENUM_TRAILING_PARAMS(n_args, param))); \
  } \
  /* */

BOOST_PP_REPEAT(
  BOOST_PP_INC(FLUSSPFERD_PARAM_LIMIT),
  FLUSSPFERD_FN_CREATE_NATIVE_OBJECT,
  ~
)

#else

/**
 * Create a new native object of type @p T.
 *
 * @param T The type of the object's class.
 * @param proto The prototype to be used. If @p null, the class' default
 *          prototype will be used.
 * @param ... The parameters to the constructor of @p T.
 * @return The new object.
 */
template<typename T>
T &create_native_object(object const &proto, ...);

#endif
//@}

/**
 * @name Creating functions
 * @addtogroup create_function
 */
//@{

function create_function(
    std::string const &name,
    unsigned n_args,
    std::vector<std::string> argnames,
    flusspferd::string const &body,
    std::string const &file,
    unsigned line);

/**
 * Create a new native function.
 *
 * @p ptr will be deleted by Flusspferd.
 *
 * @param ptr The native function object.
 * @return The new function.
 */
function create_native_function(native_function_base *ptr);

/**
 * Create a new native function as method of an object.
 *
 * The new method of object @p o will have the name @c ptr->name().
 *
 * @param o The object to add the method to.
 * @param ptr The native function object.
 * @return The new method.
 */
function create_native_function(object const &o, native_function_base *ptr);

#ifndef IN_DOXYGEN

#define FLUSSPFERD_FN_CREATE_NATIVE_FUNCTION(z, n_args, d) \
  template< \
    typename T \
    BOOST_PP_ENUM_TRAILING_PARAMS(n_args, typename T) \
  > \
  object create_native_functor_function( \
    object const &o \
    BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(n_args, T, const & param), \
    typename boost::enable_if_c<!boost::is_function<T>::value>::type * = 0 \
  ) { \
    return create_native_function(o, new T(BOOST_PP_ENUM_PARAMS(n_args, param))); \
  } \
  /* */

BOOST_PP_REPEAT(
  BOOST_PP_INC(FLUSSPFERD_PARAM_LIMIT),
  FLUSSPFERD_FN_CREATE_NATIVE_FUNCTION,
  ~
)

#else

/**
 * Create a new native function of type @p F as method of an object.
 *
 * @p F must inherit from #native_function_base.
 *
 * The new method of object @p o will have the name @c ptr->name().
 *
 * @param F The functor type.
 * @param o The object to add the method to.
 * @param ... The parameters to pass to the constructor of @p F.
 * @return The new method.
 */
template<typename F>
object create_native_functor_function(object const &o, ...);

#endif

/**
 * Create a new native method of an object.
 *
 * @param o The object to add the method to.
 * @param name The method name.
 * @param fn The functor to call.
 * @param arity The function arity.
 * @return The new function.
 */
inline function create_native_function(
  object const &o,
  std::string const &name,
  boost::function<void (call_context &)> const &fn,
  unsigned arity = 0)
{
  return create_native_functor_function<native_function<void> >(
      o, fn, arity, name);
}

/**
 * Create a new native method of an object.
 *
 * @param T The function signature to use.
 * @param o The object to add the method to.
 * @param name The function name.
 * @param fn The functor to call.
 * @return The new function.
 */
template<typename T>
function create_native_function(
  object const &o,
  std::string const &name,
  boost::function<T> const &fn)
{
  return create_native_functor_function<native_function<T,false> >(o, fn, name);
}

/**
 * Create a new native method of an object.
 *
 * The first parameter passed will be 'this'.
 *
 * @param T The function signature to use.
 * @param o The object to add the method to.
 * @param name The function name.
 * @param fn The functor to call.
 * @return The new function.
 */
template<typename T>
function create_native_method(
  object const &o,
  std::string const &name,
  boost::function<T> const &fn)
{
  return create_native_functor_function<native_function<T,true> >(o, fn, name);
}

/**
 * Create a new native method of an object.
 *
 * @param o The object to add the method to.
 * @param name The method name.
 * @param fnptr The function to call (also determines the function signature).
 * @return The new method.
 */
template<typename T>
function create_native_function(
  object const &o,
  std::string const &name,
  T *fnptr,
  typename boost::enable_if_c<boost::is_function<T>::value>::type* =0)
{
  return create_native_function<T>(o, name, boost::function<T>(fnptr));
}

/**
 * Create a new native method of an object.
 *
 * The first parameter passed will be 'this'.
 *
 * @param o The object to add the method to.
 * @param name The method name.
 * @param fnptr The function to call (also determines the function signature).
 * @return The new method.
 */
template<typename T>
function create_native_method(
  object const &o,
  std::string const &name,
  T *fnptr,
  typename boost::enable_if_c<boost::is_function<T>::value>::type* =0)
{
  return create_native_method<T>(o, name, boost::function<T>(fnptr));
}

/**
 * Create a new native method of an object.
 *
 * @param o The object to add the method to.
 * @param name The method name.
 * @param memfnptr The member function to call.
 * @return The new function.
 */
template<typename T>
function create_native_method(
  object const &o,
  std::string const &name,
  void (T::*memfnptr)(call_context &),
  unsigned arity = 0)
{
  return create_native_functor_function<native_member_function<void, T> >(
    o, memfnptr, arity, name);
}

/**
 * Create a new native method of an object.
 *
 * @param o The object to add the method to.
 * @param name The method name.
 * @param memfnptr The member function to call (also determines the function
 *                 signature).
 * @return The new function.
 */
template<typename R, typename T>
function create_native_method(
  object const &o,
  std::string const &name,
  R T::*memfnptr)
{
  return create_native_functor_function<native_member_function<R, T> >(
    o, memfnptr, name);
}

//@}

namespace param {
  BOOST_PARAMETER_NAME(length)
  BOOST_PARAMETER_NAME(contents)
}

namespace detail {
  flusspferd::array create_length_array(std::size_t length);

  template<typename Class>
  struct create_traits;

  template<typename T, typename C = void>
  struct is_boost_range_impl {
    typedef boost::mpl::false_ type;
  };

  template<>
  struct create_traits<flusspferd::array> {
    typedef flusspferd::array result_type;

    typedef boost::parameter::parameters<
        boost::parameter::optional<
          boost::parameter::deduced<param::tag::length>,
          boost::is_integral<boost::mpl::_>
        >,
        boost::parameter::optional<
          boost::parameter::deduced<param::tag::contents>,
          boost::mpl::not_<boost::is_integral<boost::mpl::_> >
        >
      >
      parameters;

    static flusspferd::array create() {
      return create_length_array(0);
    }

    template<typename ArgPack>
    static
    typename boost::enable_if<
      boost::is_same<
        typename boost::parameter::binding<
          ArgPack,
          param::tag::contents,
          void
        >::type,
        void
      >,
      flusspferd::array
    >::type
    create(ArgPack const &arg) {
      return create_length_array(arg[param::_length | 0]);
    }

    template<typename ArgPack>
    static
    typename boost::disable_if<
      boost::is_same<
        typename boost::parameter::binding<
          ArgPack,
          param::tag::contents,
          void
        >::type,
        void
      >,
      flusspferd::array
    >::type
    create(ArgPack const &arg) {
      typedef typename boost::parameter::value_type<
          ArgPack,
          param::tag::contents
        >::type
        Range;

      typedef typename boost::range_iterator<Range>::type iterator;

      Range const &r = arg[param::_contents];

      local_root_scope scope;

      array arr = create_length_array(0);

      iterator first = boost::begin(r);
      iterator last = boost::end(r);

      for (iterator it = first; it != last; ++it)
        arr.push(*it);

      return arr;
    }
  };

}

template<typename Class>
typename detail::create_traits<Class>::result_type
create()
{
  return detail::create_traits<Class>::create();
}

#define FLUSSPFERD_CREATE(z, n, d) \
  template< \
    typename Class, \
    BOOST_PP_ENUM_PARAMS(n, typename T) \
  > \
  typename detail::create_traits<Class>::result_type \
  create( \
    BOOST_PP_ENUM_BINARY_PARAMS(n, T, const &x), \
    typename detail::create_traits<Class>::parameters::template match<T0>::type kw = typename detail::create_traits<Class>::parameters()) \
  { \
    typedef detail::create_traits<Class> traits; \
    return traits::create(kw(BOOST_PP_ENUM_PARAMS(n, x))); \
  } \
  /* */

BOOST_PP_REPEAT_FROM_TO(
  1,
  BOOST_PP_INC(BOOST_PARAMETER_MAX_ARITY),
  FLUSSPFERD_CREATE,
  ~)

#undef FLUSSPFERD_CREATE

}

#endif
<|endoftext|>


<commit_before>#pragma once

#include <cassert>
#include <algorithm>
#include <fstream>

#include <glow/logging.h>

#include <glowutils/RawFile.h>

namespace glowutils
{

template<typename T>
RawFile<T>::RawFile(const std::string & filePath)
:   m_filePath(filePath)
,   m_valid(false)
{
    read();
}

template<typename T>
RawFile<T>::~RawFile()
{
}

template<typename T>
bool RawFile<T>::valid() const
{
    return m_valid;
}

template<typename T>
const T * RawFile<T>::data() const
{
    return &m_data.data()[0];
}

template<typename T>
const size_t RawFile<T>::size() const
{
    return m_data.size();
}

template<typename T>
bool RawFile<T>::read()
{
    std::ifstream ifs(m_filePath, std::ios::in | std::ios::binary | std::ios::ate);

    if (!ifs)
    {
        warning() << "Reading from file \"" << m_filePath << "\" failed.";
        return false;
    }

    const size_t size = ifs.tellg();
    ifs.seekg(0, std::ios::beg);

    m_data.resize(size / sizeof(T));

    ifs.read(reinterpret_cast<char*>(&m_data[0]), size);
    ifs.close();

    m_valid = true;
    return true;
}

} // namespace glowutils
<commit_msg>Fix namespace error in RawFile<commit_after>#pragma once

#include <cassert>
#include <algorithm>
#include <fstream>

#include <glow/logging.h>

#include <glowutils/RawFile.h>

namespace glowutils
{

template<typename T>
RawFile<T>::RawFile(const std::string & filePath)
:   m_filePath(filePath)
,   m_valid(false)
{
    read();
}

template<typename T>
RawFile<T>::~RawFile()
{
}

template<typename T>
bool RawFile<T>::valid() const
{
    return m_valid;
}

template<typename T>
const T * RawFile<T>::data() const
{
    return &m_data.data()[0];
}

template<typename T>
const size_t RawFile<T>::size() const
{
    return m_data.size();
}

template<typename T>
bool RawFile<T>::read()
{
    std::ifstream ifs(m_filePath, std::ios::in | std::ios::binary | std::ios::ate);

    if (!ifs)
    {
        glow::warning() << "Reading from file \"" << m_filePath << "\" failed.";
        return false;
    }

    const size_t size = ifs.tellg();
    ifs.seekg(0, std::ios::beg);

    m_data.resize(size / sizeof(T));

    ifs.read(reinterpret_cast<char*>(&m_data[0]), size);
    ifs.close();

    m_valid = true;
    return true;
}

} // namespace glowutils
<|endoftext|>


<commit_before>/*

Copyright (c) 2007, Arvid Norberg
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 author 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.

*/

#ifndef TORRENT_ASSERT

#include "libtorrent/config.hpp"
#include <string>

#ifdef __GNUC__
std::string demangle(char const* name);
#endif

#if (defined __linux__ || defined __MACH__) && defined __GNUC__ && !defined(NDEBUG)

TORRENT_EXPORT void assert_fail(const char* expr, int line, char const* file, char const* function);
#define TORRENT_ASSERT(x) if (x) {} else assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__)

#else
#include <cassert>
#define TORRENT_ASSERT(x) assert(x)
#endif

#endif

<commit_msg>fixed warning on gcc 4.3<commit_after>/*

Copyright (c) 2007, Arvid Norberg
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 author 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.

*/

#ifndef TORRENT_ASSERT

#include "libtorrent/config.hpp"
#include <string>

#ifdef __GNUC__
std::string demangle(char const* name);
#endif

#if (defined __linux__ || defined __MACH__) && defined __GNUC__ && !defined(NDEBUG)

TORRENT_EXPORT void assert_fail(const char* expr, int line, char const* file, char const* function);
#define TORRENT_ASSERT(x) do { if (x) {} else assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__); } while (false)

#else
#include <cassert>
#define TORRENT_ASSERT(x) assert(x)
#endif

#endif

<|endoftext|>


<commit_before>/*

Copyright (c) 2005, Arvid Norberg
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 author 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.

*/

#ifndef TORRENT_CONFIG_HPP_INCLUDED
#define TORRENT_CONFIG_HPP_INCLUDED

#include <boost/config.hpp>
#include <boost/version.hpp>
#include <stdio.h> // for snprintf

#ifndef WIN32
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#endif

#ifndef PRId64
#ifdef _WIN32
#define PRId64 "I64d"
#else
#define PRId64 "lld"
#endif
#endif

// ======= GCC =========

#if defined __GNUC__

# define TORRENT_DEPRECATED __attribute__ ((deprecated))

// GCC pre 4.0 did not have support for the visibility attribute
# if __GNUC__ >= 4
#  if defined(TORRENT_BUILDING_SHARED) || defined(TORRENT_LINKING_SHARED)
#   define TORRENT_EXPORT __attribute__ ((visibility("default")))
#  else
#   define TORRENT_EXPORT
#  endif
# else
#  define TORRENT_EXPORT
# endif

// ======= SUNPRO =========

#elif defined __SUNPRO_CC

# if __SUNPRO_CC >= 0x550
#  if defined(TORRENT_BUILDING_SHARED) || defined(TORRENT_LINKING_SHARED)
#   define TORRENT_EXPORT __global
#  else
#   define TORRENT_EXPORT
#  endif
# else
#  define TORRENT_EXPORT
# endif

// ======= MSVC =========

#elif defined BOOST_MSVC

#pragma warning(disable: 4258)
#pragma warning(disable: 4251)

# if defined(TORRENT_BUILDING_SHARED)
#  define TORRENT_EXPORT __declspec(dllexport)
# elif defined(TORRENT_LINKING_SHARED)
#  define TORRENT_EXPORT __declspec(dllimport)
# else
#  define TORRENT_EXPORT
# endif

#define TORRENT_DEPRECATED_PREFIX __declspec(deprecated)

// ======= GENERIC COMPILER =========

#else
# define TORRENT_EXPORT
#endif

#ifndef TORRENT_DEPRECATED_PREFIX
#define TORRENT_DEPRECATED_PREFIX
#endif

#ifndef TORRENT_DEPRECATED
#define TORRENT_DEPRECATED
#endif

// set up defines for target environments
#if (defined __APPLE__ && __MACH__) || defined __FreeBSD__ || defined __NetBSD__ \
	|| defined __OpenBSD__ || defined __bsdi__ || defined __DragonFly__ \
	|| defined __FreeBSD_kernel__
#define TORRENT_BSD
#elif defined __linux__
#define TORRENT_LINUX
#elif defined __MINGW32__
#define TORRENT_MINGW
#elif defined WIN32
#define TORRENT_WINDOWS
#elif defined sun || defined __sun
#define TORRENT_SOLARIS
#else
#warning unkown OS, assuming BSD
#define TORRENT_BSD
#endif

#define TORRENT_USE_IPV6 1
#define TORRENT_USE_MLOCK 1
#define TORRENT_USE_READV 1
#define TORRENT_USE_WRITEV 1
#define TORRENT_USE_IOSTREAM 1

#define TORRENT_USE_I2P 1

// should wpath or path be used?
#if defined UNICODE && !defined BOOST_FILESYSTEM_NARROW_ONLY \
	&& BOOST_VERSION >= 103400 && !defined __APPLE__
#define TORRENT_USE_WPATH 1
#else
#define TORRENT_USE_WPATH 0
#endif

// set this to 1 to disable all floating point operations
// (disables some float-dependent APIs)
#define TORRENT_NO_FPU 0

// on windows, NAME_MAX refers to Unicode characters
// on linux it refers to bytes (utf-8 encoded)
// TODO: Make this count Unicode characters instead of bytes on windows

// windows
#if defined FILENAME_MAX
#define TORRENT_MAX_PATH FILENAME_MAX

// solaris
#elif defined MAXPATH
#define TORRENT_MAX_PATH MAXPATH

// posix
#elif defined NAME_MAX
#define TORRENT_MAX_PATH NAME_MAX

// none of the above
#else
// this is the maximum number of characters in a
// path element / filename on windows
#define TORRENT_MAX_PATH 255
#warning unknown platform, assuming the longest path is 255

#endif

#ifdef TORRENT_WINDOWS

// class X needs to have dll-interface to be used by clients of class Y
#pragma warning(disable:4251)

#include <stdarg.h>

inline int snprintf(char* buf, int len, char const* fmt, ...)
{
	va_list lp;
	va_start(lp, fmt);
	int ret = _vsnprintf(buf, len, fmt, lp);
	va_end(lp);
	if (ret < 0) { buf[len-1] = 0; ret = len-1; }
	return ret;
}

#define strtoll _strtoi64
#else
#include <limits.h>
#endif

#if (defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)) && !defined (TORRENT_UPNP_LOGGING)
#define TORRENT_UPNP_LOGGING
#endif

#if !TORRENT_USE_WPATH && defined TORRENT_LINUX
// libiconv presnce, not implemented yet
#define TORRENT_USE_LOCALE_FILENAMES 1
#else
#define TORRENT_USE_LOCALE_FILENAMES 0
#endif

#if !defined(TORRENT_READ_HANDLER_MAX_SIZE)
# define TORRENT_READ_HANDLER_MAX_SIZE 256
#endif

#if !defined(TORRENT_WRITE_HANDLER_MAX_SIZE)
# define TORRENT_WRITE_HANDLER_MAX_SIZE 256
#endif

#if defined _MSC_VER && _MSC_VER <= 1200
#define for if (false) {} else for
#endif

// determine what timer implementation we can use

#if defined(__MACH__)
#define TORRENT_USE_ABSOLUTE_TIME 1
#elif defined(_WIN32)
#define TORRENT_USE_QUERY_PERFORMANCE_TIMER 1
#elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
#define TORRENT_USE_CLOCK_GETTIME 1
#else
#define TORRENT_USE_BOOST_DATE_TIME 1
#endif

#endif // TORRENT_CONFIG_HPP_INCLUDED

<commit_msg>fix some error/warning strings typos<commit_after>/*

Copyright (c) 2005, Arvid Norberg
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 author 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.

*/

#ifndef TORRENT_CONFIG_HPP_INCLUDED
#define TORRENT_CONFIG_HPP_INCLUDED

#include <boost/config.hpp>
#include <boost/version.hpp>
#include <stdio.h> // for snprintf

#ifndef WIN32
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#endif

#ifndef PRId64
#ifdef _WIN32
#define PRId64 "I64d"
#else
#define PRId64 "lld"
#endif
#endif

// ======= GCC =========

#if defined __GNUC__

# define TORRENT_DEPRECATED __attribute__ ((deprecated))

// GCC pre 4.0 did not have support for the visibility attribute
# if __GNUC__ >= 4
#  if defined(TORRENT_BUILDING_SHARED) || defined(TORRENT_LINKING_SHARED)
#   define TORRENT_EXPORT __attribute__ ((visibility("default")))
#  else
#   define TORRENT_EXPORT
#  endif
# else
#  define TORRENT_EXPORT
# endif

// ======= SUNPRO =========

#elif defined __SUNPRO_CC

# if __SUNPRO_CC >= 0x550
#  if defined(TORRENT_BUILDING_SHARED) || defined(TORRENT_LINKING_SHARED)
#   define TORRENT_EXPORT __global
#  else
#   define TORRENT_EXPORT
#  endif
# else
#  define TORRENT_EXPORT
# endif

// ======= MSVC =========

#elif defined BOOST_MSVC

#pragma warning(disable: 4258)
#pragma warning(disable: 4251)

# if defined(TORRENT_BUILDING_SHARED)
#  define TORRENT_EXPORT __declspec(dllexport)
# elif defined(TORRENT_LINKING_SHARED)
#  define TORRENT_EXPORT __declspec(dllimport)
# else
#  define TORRENT_EXPORT
# endif

#define TORRENT_DEPRECATED_PREFIX __declspec(deprecated)

// ======= GENERIC COMPILER =========

#else
# define TORRENT_EXPORT
#endif

#ifndef TORRENT_DEPRECATED_PREFIX
#define TORRENT_DEPRECATED_PREFIX
#endif

#ifndef TORRENT_DEPRECATED
#define TORRENT_DEPRECATED
#endif

// set up defines for target environments
#if (defined __APPLE__ && __MACH__) || defined __FreeBSD__ || defined __NetBSD__ \
	|| defined __OpenBSD__ || defined __bsdi__ || defined __DragonFly__ \
	|| defined __FreeBSD_kernel__
#define TORRENT_BSD
#elif defined __linux__
#define TORRENT_LINUX
#elif defined __MINGW32__
#define TORRENT_MINGW
#elif defined WIN32
#define TORRENT_WINDOWS
#elif defined sun || defined __sun
#define TORRENT_SOLARIS
#else
#warning unknown OS, assuming BSD
#define TORRENT_BSD
#endif

#define TORRENT_USE_IPV6 1
#define TORRENT_USE_MLOCK 1
#define TORRENT_USE_READV 1
#define TORRENT_USE_WRITEV 1
#define TORRENT_USE_IOSTREAM 1

#define TORRENT_USE_I2P 1

// should wpath or path be used?
#if defined UNICODE && !defined BOOST_FILESYSTEM_NARROW_ONLY \
	&& BOOST_VERSION >= 103400 && !defined __APPLE__
#define TORRENT_USE_WPATH 1
#else
#define TORRENT_USE_WPATH 0
#endif

// set this to 1 to disable all floating point operations
// (disables some float-dependent APIs)
#define TORRENT_NO_FPU 0

// on windows, NAME_MAX refers to Unicode characters
// on linux it refers to bytes (utf-8 encoded)
// TODO: Make this count Unicode characters instead of bytes on windows

// windows
#if defined FILENAME_MAX
#define TORRENT_MAX_PATH FILENAME_MAX

// solaris
#elif defined MAXPATH
#define TORRENT_MAX_PATH MAXPATH

// posix
#elif defined NAME_MAX
#define TORRENT_MAX_PATH NAME_MAX

// none of the above
#else
// this is the maximum number of characters in a
// path element / filename on windows
#define TORRENT_MAX_PATH 255
#warning unknown platform, assuming the longest path is 255

#endif

#ifdef TORRENT_WINDOWS

// class X needs to have dll-interface to be used by clients of class Y
#pragma warning(disable:4251)

#include <stdarg.h>

inline int snprintf(char* buf, int len, char const* fmt, ...)
{
	va_list lp;
	va_start(lp, fmt);
	int ret = _vsnprintf(buf, len, fmt, lp);
	va_end(lp);
	if (ret < 0) { buf[len-1] = 0; ret = len-1; }
	return ret;
}

#define strtoll _strtoi64
#else
#include <limits.h>
#endif

#if (defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)) && !defined (TORRENT_UPNP_LOGGING)
#define TORRENT_UPNP_LOGGING
#endif

#if !TORRENT_USE_WPATH && defined TORRENT_LINUX
// libiconv presnce, not implemented yet
#define TORRENT_USE_LOCALE_FILENAMES 1
#else
#define TORRENT_USE_LOCALE_FILENAMES 0
#endif

#if !defined(TORRENT_READ_HANDLER_MAX_SIZE)
# define TORRENT_READ_HANDLER_MAX_SIZE 256
#endif

#if !defined(TORRENT_WRITE_HANDLER_MAX_SIZE)
# define TORRENT_WRITE_HANDLER_MAX_SIZE 256
#endif

#if defined _MSC_VER && _MSC_VER <= 1200
#define for if (false) {} else for
#endif

// determine what timer implementation we can use

#if defined(__MACH__)
#define TORRENT_USE_ABSOLUTE_TIME 1
#elif defined(_WIN32)
#define TORRENT_USE_QUERY_PERFORMANCE_TIMER 1
#elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
#define TORRENT_USE_CLOCK_GETTIME 1
#else
#define TORRENT_USE_BOOST_DATE_TIME 1
#endif

#endif // TORRENT_CONFIG_HPP_INCLUDED

<|endoftext|>


<commit_before>#pragma once

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <atomic>
#include <memory>
#include <mutex>

#define FMT_STRING_ALIAS 1
#define FMT_ENFORCE_COMPILE_STRING 1
#define FMT_USE_GRISU 0
#include <fmt/format.h>

#ifdef __SWITCH__
#include "nxstl/mutex"
#endif

extern "C" void logvisorBp();

namespace logvisor {

void logvisorAbort();

#if _WIN32 && UNICODE
#define LOG_UCS2 1
#endif

/* True if ANSI color available */
extern bool XtermColor;

/**
 * @brief Severity level for log messages
 */
enum Level {
  Info,    /**< Non-error informative message */
  Warning, /**< Non-error warning message */
  Error,   /**< Recoverable error message */
  Fatal    /**< Non-recoverable error message (throws exception) */
};

/**
 * @brief Backend interface for receiving app-wide log events
 */
struct ILogger {
  virtual ~ILogger() = default;
  virtual void report(const char* modName, Level severity, fmt::string_view format, fmt::format_args args) = 0;
  virtual void report(const char* modName, Level severity, fmt::wstring_view format, fmt::wformat_args args) = 0;
  virtual void reportSource(const char* modName, Level severity, const char* file, unsigned linenum,
                            fmt::string_view format, fmt::format_args args) = 0;
  virtual void reportSource(const char* modName, Level severity, const char* file, unsigned linenum,
                            fmt::wstring_view format, fmt::wformat_args args) = 0;
};

/**
 * @brief Terminate all child processes
 *
 * Implicitly called on abort condition.
 */
void KillProcessTree();

/**
 * @brief Assign calling thread a descriptive name
 * @param name Descriptive thread name
 */
void RegisterThreadName(const char* name);

/**
 * @brief Centralized logger vector
 *
 * All loggers added to this vector will receive reports as they occur
 */
extern std::vector<std::unique_ptr<ILogger>> MainLoggers;

/**
 * @brief Centralized error counter
 *
 * All submodules accumulate this value
 */
extern std::atomic_size_t ErrorCount;

/**
 * @brief Centralized frame index
 *
 * All log events include this as part of their timestamp if non-zero.
 * The default value is zero, the app is responsible for updating it
 * within its main loop.
 */
extern std::atomic_uint_fast64_t FrameIndex;

/**
 * @brief Centralized logging lock
 *
 * Ensures logging streams aren't written concurrently
 */
struct LogMutex {
  bool enabled = true;
  std::recursive_mutex mutex;
  ~LogMutex() { enabled = false; }
  std::unique_lock<std::recursive_mutex> lock() {
    if (enabled)
      return std::unique_lock<std::recursive_mutex>(mutex);
    else
      return std::unique_lock<std::recursive_mutex>();
  }
};
extern LogMutex _LogMutex;

/**
 * @brief Take a centralized lock for the logging output stream(s)
 * @return RAII mutex lock
 */
inline std::unique_lock<std::recursive_mutex> LockLog() { return _LogMutex.lock(); }

extern uint64_t _LogCounter;

/**
 * @brief Get current count of logging events
 * @return Log Count
 */
inline uint64_t GetLogCounter() { return _LogCounter; }

/**
 * @brief Restore centralized logger vector to default state (silent operation)
 */
inline void UnregisterLoggers() { MainLoggers.clear(); }

/**
 * @brief Construct and register a real-time console logger singleton
 *
 * This will output to stderr on POSIX platforms and spawn a new console window on Windows.
 * If there's already a registered console logger, this is a no-op.
 */
void RegisterConsoleLogger();

/**
 * @brief Construct and register a file logger
 * @param filepath Path to write the file
 *
 * If there's already a file logger registered to the same file, this is a no-op.
 */
void RegisterFileLogger(const char* filepath);

/**
 * @brief Register signal handlers with system for common client exceptions
 */
void RegisterStandardExceptions();

#if _WIN32
/**
 * @brief Spawn an application-owned cmd.exe window for displaying console output
 */
void CreateWin32Console();
#endif

#if LOG_UCS2

/**
 * @brief Construct and register a file logger (wchar_t version)
 * @param filepath Path to write the file
 *
 * If there's already a file logger registered to the same file, this is a no-op.
 */
void RegisterFileLogger(const wchar_t* filepath);

#endif

/**
 * @brief This is constructed per-subsystem in a locally centralized fashon
 */
class Module {
  const char* m_modName;

  template <typename Char>
  void _vreport(Level severity, fmt::basic_string_view<Char> format,
                fmt::basic_format_args<fmt::buffer_context<Char>> args) {
    auto lk = LockLog();
    ++_LogCounter;
    if (severity == Fatal)
      RegisterConsoleLogger();
    for (auto& logger : MainLoggers)
      logger->report(m_modName, severity, format, args);
    if (severity == Error || severity == Fatal)
      logvisorBp();
    if (severity == Fatal)
      logvisorAbort();
    else if (severity == Error)
      ++ErrorCount;
  }

  template <typename Char>
  void _vreportSource(Level severity, const char* file, unsigned linenum, fmt::basic_string_view<Char> format,
                      fmt::basic_format_args<fmt::buffer_context<Char>> args) {
    auto lk = LockLog();
    ++_LogCounter;
    if (severity == Fatal)
      RegisterConsoleLogger();
    for (auto& logger : MainLoggers)
      logger->reportSource(m_modName, severity, file, linenum, format, args);
    if (severity == Error || severity == Fatal)
      logvisorBp();
    if (severity == Fatal)
      logvisorAbort();
    else if (severity == Error)
      ++ErrorCount;
  }

public:
  constexpr Module(const char* modName) : m_modName(modName) {}

  /**
   * @brief Route new log message to centralized ILogger
   * @param severity Level of log report severity
   * @param format Standard printf-style format string
   */
  template <typename S, typename... Args, typename Char = fmt::char_t<S>>
  void report(Level severity, const S& format, Args&&... args) {
    if (MainLoggers.empty() && severity != Level::Fatal)
      return;
    _vreport(severity, fmt::to_string_view<Char>(format),
             fmt::basic_format_args<fmt::buffer_context<Char>>(
                 fmt::internal::make_args_checked<Args...>(format, args...)));
  }

  template <typename Char>
  void vreport(Level severity, fmt::basic_string_view<Char> format,
               fmt::basic_format_args<fmt::buffer_context<Char>> args) {
    if (MainLoggers.empty() && severity != Level::Fatal)
      return;
    _vreport(severity, format, args);
  }

  /**
   * @brief Route new log message with source info to centralized ILogger
   * @param severity Level of log report severity
   * @param file Source file name from __FILE__ macro
   * @param linenum Source line number from __LINE__ macro
   * @param format Standard printf-style format string
   */
  template <typename S, typename... Args, typename Char = fmt::char_t<S>>
  void reportSource(Level severity, const char* file, unsigned linenum, const S& format, Args&&... args) {
    if (MainLoggers.empty() && severity != Level::Fatal)
      return;
    _vreportSource(
        severity, file, linenum, fmt::to_string_view<Char>(format),
        fmt::basic_format_args<fmt::buffer_context<Char>>(
            fmt::internal::make_args_checked<Args...>(format, args...)));
  }

  template <typename Char>
  void vreportSource(Level severity, const char* file, unsigned linenum, fmt::basic_string_view<Char> format,
                     fmt::basic_format_args<fmt::buffer_context<Char>> args) {
    if (MainLoggers.empty() && severity != Level::Fatal)
      return;
    _vreportSource(severity, file, linenum, format, args);
  }
};

#define FMT_CUSTOM_FORMATTER(tp, fmtstr, ...) \
namespace fmt { \
template <> \
struct formatter<tp, char> { \
  template <typename ParseContext> \
  constexpr auto parse(ParseContext &ctx) { return ctx.begin(); } \
  template <typename FormatContext> \
  auto format(const tp &obj, FormatContext &ctx) { \
    return format_to(ctx.out(), fmt(fmtstr), __VA_ARGS__); \
  } \
}; \
template <> \
struct formatter<tp, wchar_t> { \
  template <typename ParseContext> \
  constexpr auto parse(ParseContext &ctx) { return ctx.begin(); } \
  template <typename FormatContext> \
  auto format(const tp &obj, FormatContext &ctx) { \
    return format_to(ctx.out(), fmt(L##fmtstr), __VA_ARGS__); \
  } \
}; \
template <> \
struct formatter<tp, char16_t> { \
  template <typename ParseContext> \
  constexpr auto parse(ParseContext &ctx) { return ctx.begin(); } \
  template <typename FormatContext> \
  auto format(const tp &obj, FormatContext &ctx) { \
    return format_to(ctx.out(), fmt(u##fmtstr), __VA_ARGS__); \
  } \
}; \
template <> \
struct formatter<tp, char32_t> { \
  template <typename ParseContext> \
  constexpr auto parse(ParseContext &ctx) { return ctx.begin(); } \
  template <typename FormatContext> \
  auto format(const tp &obj, FormatContext &ctx) { \
    return format_to(ctx.out(), fmt(U##fmtstr), __VA_ARGS__); \
  } \
}; \
}

} // namespace logvisor
<commit_msg>logvisor: std::forward arguments where applicable<commit_after>#pragma once

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <atomic>
#include <memory>
#include <mutex>

#define FMT_STRING_ALIAS 1
#define FMT_ENFORCE_COMPILE_STRING 1
#define FMT_USE_GRISU 0
#include <fmt/format.h>

#ifdef __SWITCH__
#include "nxstl/mutex"
#endif

extern "C" void logvisorBp();

namespace logvisor {

void logvisorAbort();

#if _WIN32 && UNICODE
#define LOG_UCS2 1
#endif

/* True if ANSI color available */
extern bool XtermColor;

/**
 * @brief Severity level for log messages
 */
enum Level {
  Info,    /**< Non-error informative message */
  Warning, /**< Non-error warning message */
  Error,   /**< Recoverable error message */
  Fatal    /**< Non-recoverable error message (throws exception) */
};

/**
 * @brief Backend interface for receiving app-wide log events
 */
struct ILogger {
  virtual ~ILogger() = default;
  virtual void report(const char* modName, Level severity, fmt::string_view format, fmt::format_args args) = 0;
  virtual void report(const char* modName, Level severity, fmt::wstring_view format, fmt::wformat_args args) = 0;
  virtual void reportSource(const char* modName, Level severity, const char* file, unsigned linenum,
                            fmt::string_view format, fmt::format_args args) = 0;
  virtual void reportSource(const char* modName, Level severity, const char* file, unsigned linenum,
                            fmt::wstring_view format, fmt::wformat_args args) = 0;
};

/**
 * @brief Terminate all child processes
 *
 * Implicitly called on abort condition.
 */
void KillProcessTree();

/**
 * @brief Assign calling thread a descriptive name
 * @param name Descriptive thread name
 */
void RegisterThreadName(const char* name);

/**
 * @brief Centralized logger vector
 *
 * All loggers added to this vector will receive reports as they occur
 */
extern std::vector<std::unique_ptr<ILogger>> MainLoggers;

/**
 * @brief Centralized error counter
 *
 * All submodules accumulate this value
 */
extern std::atomic_size_t ErrorCount;

/**
 * @brief Centralized frame index
 *
 * All log events include this as part of their timestamp if non-zero.
 * The default value is zero, the app is responsible for updating it
 * within its main loop.
 */
extern std::atomic_uint_fast64_t FrameIndex;

/**
 * @brief Centralized logging lock
 *
 * Ensures logging streams aren't written concurrently
 */
struct LogMutex {
  bool enabled = true;
  std::recursive_mutex mutex;
  ~LogMutex() { enabled = false; }
  std::unique_lock<std::recursive_mutex> lock() {
    if (enabled)
      return std::unique_lock<std::recursive_mutex>(mutex);
    else
      return std::unique_lock<std::recursive_mutex>();
  }
};
extern LogMutex _LogMutex;

/**
 * @brief Take a centralized lock for the logging output stream(s)
 * @return RAII mutex lock
 */
inline std::unique_lock<std::recursive_mutex> LockLog() { return _LogMutex.lock(); }

extern uint64_t _LogCounter;

/**
 * @brief Get current count of logging events
 * @return Log Count
 */
inline uint64_t GetLogCounter() { return _LogCounter; }

/**
 * @brief Restore centralized logger vector to default state (silent operation)
 */
inline void UnregisterLoggers() { MainLoggers.clear(); }

/**
 * @brief Construct and register a real-time console logger singleton
 *
 * This will output to stderr on POSIX platforms and spawn a new console window on Windows.
 * If there's already a registered console logger, this is a no-op.
 */
void RegisterConsoleLogger();

/**
 * @brief Construct and register a file logger
 * @param filepath Path to write the file
 *
 * If there's already a file logger registered to the same file, this is a no-op.
 */
void RegisterFileLogger(const char* filepath);

/**
 * @brief Register signal handlers with system for common client exceptions
 */
void RegisterStandardExceptions();

#if _WIN32
/**
 * @brief Spawn an application-owned cmd.exe window for displaying console output
 */
void CreateWin32Console();
#endif

#if LOG_UCS2

/**
 * @brief Construct and register a file logger (wchar_t version)
 * @param filepath Path to write the file
 *
 * If there's already a file logger registered to the same file, this is a no-op.
 */
void RegisterFileLogger(const wchar_t* filepath);

#endif

/**
 * @brief This is constructed per-subsystem in a locally centralized fashon
 */
class Module {
  const char* m_modName;

  template <typename Char>
  void _vreport(Level severity, fmt::basic_string_view<Char> format,
                fmt::basic_format_args<fmt::buffer_context<Char>> args) {
    auto lk = LockLog();
    ++_LogCounter;
    if (severity == Fatal)
      RegisterConsoleLogger();
    for (auto& logger : MainLoggers)
      logger->report(m_modName, severity, format, args);
    if (severity == Error || severity == Fatal)
      logvisorBp();
    if (severity == Fatal)
      logvisorAbort();
    else if (severity == Error)
      ++ErrorCount;
  }

  template <typename Char>
  void _vreportSource(Level severity, const char* file, unsigned linenum, fmt::basic_string_view<Char> format,
                      fmt::basic_format_args<fmt::buffer_context<Char>> args) {
    auto lk = LockLog();
    ++_LogCounter;
    if (severity == Fatal)
      RegisterConsoleLogger();
    for (auto& logger : MainLoggers)
      logger->reportSource(m_modName, severity, file, linenum, format, args);
    if (severity == Error || severity == Fatal)
      logvisorBp();
    if (severity == Fatal)
      logvisorAbort();
    else if (severity == Error)
      ++ErrorCount;
  }

public:
  constexpr Module(const char* modName) : m_modName(modName) {}

  /**
   * @brief Route new log message to centralized ILogger
   * @param severity Level of log report severity
   * @param format Standard printf-style format string
   */
  template <typename S, typename... Args, typename Char = fmt::char_t<S>>
  void report(Level severity, const S& format, Args&&... args) {
    if (MainLoggers.empty() && severity != Level::Fatal)
      return;
    _vreport(severity, fmt::to_string_view<Char>(format),
             fmt::basic_format_args<fmt::buffer_context<Char>>(
                 fmt::internal::make_args_checked<Args...>(format, std::forward<Args>(args)...)));
  }

  template <typename Char>
  void vreport(Level severity, fmt::basic_string_view<Char> format,
               fmt::basic_format_args<fmt::buffer_context<Char>> args) {
    if (MainLoggers.empty() && severity != Level::Fatal)
      return;
    _vreport(severity, format, args);
  }

  /**
   * @brief Route new log message with source info to centralized ILogger
   * @param severity Level of log report severity
   * @param file Source file name from __FILE__ macro
   * @param linenum Source line number from __LINE__ macro
   * @param format Standard printf-style format string
   */
  template <typename S, typename... Args, typename Char = fmt::char_t<S>>
  void reportSource(Level severity, const char* file, unsigned linenum, const S& format, Args&&... args) {
    if (MainLoggers.empty() && severity != Level::Fatal)
      return;
    _vreportSource(severity, file, linenum, fmt::to_string_view<Char>(format),
                   fmt::basic_format_args<fmt::buffer_context<Char>>(
                       fmt::internal::make_args_checked<Args...>(format, std::forward<Args>(args)...)));
  }

  template <typename Char>
  void vreportSource(Level severity, const char* file, unsigned linenum, fmt::basic_string_view<Char> format,
                     fmt::basic_format_args<fmt::buffer_context<Char>> args) {
    if (MainLoggers.empty() && severity != Level::Fatal)
      return;
    _vreportSource(severity, file, linenum, format, args);
  }
};

#define FMT_CUSTOM_FORMATTER(tp, fmtstr, ...) \
namespace fmt { \
template <> \
struct formatter<tp, char> { \
  template <typename ParseContext> \
  constexpr auto parse(ParseContext &ctx) { return ctx.begin(); } \
  template <typename FormatContext> \
  auto format(const tp &obj, FormatContext &ctx) { \
    return format_to(ctx.out(), fmt(fmtstr), __VA_ARGS__); \
  } \
}; \
template <> \
struct formatter<tp, wchar_t> { \
  template <typename ParseContext> \
  constexpr auto parse(ParseContext &ctx) { return ctx.begin(); } \
  template <typename FormatContext> \
  auto format(const tp &obj, FormatContext &ctx) { \
    return format_to(ctx.out(), fmt(L##fmtstr), __VA_ARGS__); \
  } \
}; \
template <> \
struct formatter<tp, char16_t> { \
  template <typename ParseContext> \
  constexpr auto parse(ParseContext &ctx) { return ctx.begin(); } \
  template <typename FormatContext> \
  auto format(const tp &obj, FormatContext &ctx) { \
    return format_to(ctx.out(), fmt(u##fmtstr), __VA_ARGS__); \
  } \
}; \
template <> \
struct formatter<tp, char32_t> { \
  template <typename ParseContext> \
  constexpr auto parse(ParseContext &ctx) { return ctx.begin(); } \
  template <typename FormatContext> \
  auto format(const tp &obj, FormatContext &ctx) { \
    return format_to(ctx.out(), fmt(U##fmtstr), __VA_ARGS__); \
  } \
}; \
}

} // namespace logvisor
<|endoftext|>