<commit_before>//===--- CrossTranslationUnit.cpp - -----------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements the CrossTranslationUnit interface.
//
//===----------------------------------------------------------------------===//
#include "clang/CrossTU/CrossTranslationUnit.h"
#include "clang/AST/ASTImporter.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CrossTU/CrossTUDiagnostic.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Index/USRGeneration.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <fstream>
#include <sstream>

namespace clang {
namespace cross_tu {

namespace {
// FIXME: This class is will be removed after the transition to llvm::Error.
class IndexErrorCategory : public std::error_category {
public:
  const char *name() const noexcept override { return "clang.index"; }

  std::string message(int Condition) const override {
    switch (static_cast<index_error_code>(Condition)) {
    case index_error_code::unspecified:
      return "An unknown error has occurred.";
    case index_error_code::missing_index_file:
      return "The index file is missing.";
    case index_error_code::invalid_index_format:
      return "Invalid index file format.";
    case index_error_code::multiple_definitions:
      return "Multiple definitions in the index file.";
    case index_error_code::missing_definition:
      return "Missing definition from the index file.";
    case index_error_code::failed_import:
      return "Failed to import the definition.";
    case index_error_code::failed_to_get_external_ast:
      return "Failed to load external AST source.";
    case index_error_code::failed_to_generate_usr:
      return "Failed to generate USR.";
    }
    llvm_unreachable("Unrecognized index_error_code.");
  }
};

static llvm::ManagedStatic<IndexErrorCategory> Category;
} // end anonymous namespace

char IndexError::ID;

void IndexError::log(raw_ostream &OS) const {
  OS << Category->message(static_cast<int>(Code)) << '\n';
}

std::error_code IndexError::convertToErrorCode() const {
  return std::error_code(static_cast<int>(Code), *Category);
}

llvm::Expected<llvm::StringMap<std::string>>
parseCrossTUIndex(StringRef IndexPath, StringRef CrossTUDir) {
  std::ifstream ExternalFnMapFile(IndexPath);
  if (!ExternalFnMapFile)
    return llvm::make_error<IndexError>(index_error_code::missing_index_file,
                                        IndexPath.str());

  llvm::StringMap<std::string> Result;
  std::string Line;
  unsigned LineNo = 1;
  while (std::getline(ExternalFnMapFile, Line)) {
    const size_t Pos = Line.find(" ");
    if (Pos > 0 && Pos != std::string::npos) {
      StringRef LineRef{Line};
      StringRef FunctionLookupName = LineRef.substr(0, Pos);
      if (Result.count(FunctionLookupName))
        return llvm::make_error<IndexError>(
            index_error_code::multiple_definitions, IndexPath.str(), LineNo);
      StringRef FileName = LineRef.substr(Pos + 1);
      SmallString<256> FilePath = CrossTUDir;
      if (llvm::sys::path::is_absolute(FileName))
        FilePath = FileName;
      else
        llvm::sys::path::append(FilePath, FileName);
      Result[FunctionLookupName] = FilePath.str().str();
    } else
      return llvm::make_error<IndexError>(
          index_error_code::invalid_index_format, IndexPath.str(), LineNo);
    LineNo++;
  }
  return Result;
}

std::string
createCrossTUIndexString(const llvm::StringMap<std::string> &Index) {
  std::ostringstream Result;
  for (const auto &E : Index)
    Result << E.getKey().str() << " " << E.getValue() << '\n';
  return Result.str();
}

CrossTranslationUnitContext::CrossTranslationUnitContext(CompilerInstance &CI)
    : CI(CI), Context(CI.getASTContext()) {}

CrossTranslationUnitContext::~CrossTranslationUnitContext() {}

std::string CrossTranslationUnitContext::getLookupName(const NamedDecl *ND) {
  SmallString<128> DeclUSR;
  bool Ret = index::generateUSRForDecl(ND, DeclUSR); (void)Ret;
  assert(!Ret && "Unable to generate USR");
  return DeclUSR.str();
}

/// Recursively visits the function decls of a DeclContext, and looks up a
/// function based on USRs.
const FunctionDecl *
CrossTranslationUnitContext::findFunctionInDeclContext(const DeclContext *DC,
                                                       StringRef LookupFnName) {
  assert(DC && "Declaration Context must not be null");
  for (const Decl *D : DC->decls()) {
    const auto *SubDC = dyn_cast<DeclContext>(D);
    if (SubDC)
      if (const auto *FD = findFunctionInDeclContext(SubDC, LookupFnName))
        return FD;

    const auto *ND = dyn_cast<FunctionDecl>(D);
    const FunctionDecl *ResultDecl;
    if (!ND || !ND->hasBody(ResultDecl))
      continue;
    if (getLookupName(ResultDecl) != LookupFnName)
      continue;
    return ResultDecl;
  }
  return nullptr;
}

llvm::Expected<const FunctionDecl *>
CrossTranslationUnitContext::getCrossTUDefinition(const FunctionDecl *FD,
                                                  StringRef CrossTUDir,
                                                  StringRef IndexName) {
  assert(!FD->hasBody() && "FD has a definition in current translation unit!");
  const std::string LookupFnName = getLookupName(FD);
  if (LookupFnName.empty())
    return llvm::make_error<IndexError>(
        index_error_code::failed_to_generate_usr);
  llvm::Expected<ASTUnit *> ASTUnitOrError =
      loadExternalAST(LookupFnName, CrossTUDir, IndexName);
  if (!ASTUnitOrError)
    return ASTUnitOrError.takeError();
  ASTUnit *Unit = *ASTUnitOrError;
  if (!Unit)
    return llvm::make_error<IndexError>(
        index_error_code::failed_to_get_external_ast);
  assert(&Unit->getFileManager() ==
         &Unit->getASTContext().getSourceManager().getFileManager());

  TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
  if (const FunctionDecl *ResultDecl =
          findFunctionInDeclContext(TU, LookupFnName))
    return importDefinition(ResultDecl);
  return llvm::make_error<IndexError>(index_error_code::failed_import);
}

void CrossTranslationUnitContext::emitCrossTUDiagnostics(const IndexError &IE) {
  switch (IE.getCode()) {
  case index_error_code::missing_index_file:
    Context.getDiagnostics().Report(diag::err_fe_error_opening)
        << IE.getFileName() << "required by the CrossTU functionality";
    break;
  case index_error_code::invalid_index_format:
    Context.getDiagnostics().Report(diag::err_fnmap_parsing)
        << IE.getFileName() << IE.getLineNum();
  case index_error_code::multiple_definitions:
    Context.getDiagnostics().Report(diag::err_multiple_def_index)
        << IE.getLineNum();
    break;
  default:
    break;
  }
}

llvm::Expected<ASTUnit *> CrossTranslationUnitContext::loadExternalAST(
    StringRef LookupName, StringRef CrossTUDir, StringRef IndexName) {
  // FIXME: The current implementation only supports loading functions with
  //        a lookup name from a single translation unit. If multiple
  //        translation units contains functions with the same lookup name an
  //        error will be returned.
  ASTUnit *Unit = nullptr;
  auto FnUnitCacheEntry = FunctionASTUnitMap.find(LookupName);
  if (FnUnitCacheEntry == FunctionASTUnitMap.end()) {
    if (FunctionFileMap.empty()) {
      SmallString<256> IndexFile = CrossTUDir;
      if (llvm::sys::path::is_absolute(IndexName))
        IndexFile = IndexName;
      else
        llvm::sys::path::append(IndexFile, IndexName);
      llvm::Expected<llvm::StringMap<std::string>> IndexOrErr =
          parseCrossTUIndex(IndexFile, CrossTUDir);
      if (IndexOrErr)
        FunctionFileMap = *IndexOrErr;
      else
        return IndexOrErr.takeError();
    }

    auto It = FunctionFileMap.find(LookupName);
    if (It == FunctionFileMap.end())
      return llvm::make_error<IndexError>(index_error_code::missing_definition);
    StringRef ASTFileName = It->second;
    auto ASTCacheEntry = FileASTUnitMap.find(ASTFileName);
    if (ASTCacheEntry == FileASTUnitMap.end()) {
      IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
      TextDiagnosticPrinter *DiagClient =
          new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
      IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
      IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
          new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient));

      std::unique_ptr<ASTUnit> LoadedUnit(ASTUnit::LoadFromASTFile(
          ASTFileName, CI.getPCHContainerOperations()->getRawReader(),
          ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts()));
      Unit = LoadedUnit.get();
      FileASTUnitMap[ASTFileName] = std::move(LoadedUnit);
    } else {
      Unit = ASTCacheEntry->second.get();
    }
    FunctionASTUnitMap[LookupName] = Unit;
  } else {
    Unit = FnUnitCacheEntry->second;
  }
  return Unit;
}

llvm::Expected<const FunctionDecl *>
CrossTranslationUnitContext::importDefinition(const FunctionDecl *FD) {
  ASTImporter &Importer = getOrCreateASTImporter(FD->getASTContext());
  auto *ToDecl =
      cast<FunctionDecl>(Importer.Import(const_cast<FunctionDecl *>(FD)));
  assert(ToDecl->hasBody());
  assert(FD->hasBody() && "Functions already imported should have body.");
  return ToDecl;
}

ASTImporter &
CrossTranslationUnitContext::getOrCreateASTImporter(ASTContext &From) {
  auto I = ASTUnitImporterMap.find(From.getTranslationUnitDecl());
  if (I != ASTUnitImporterMap.end())
    return *I->second;
  ASTImporter *NewImporter =
      new ASTImporter(Context, Context.getSourceManager().getFileManager(),
                      From, From.getSourceManager().getFileManager(), false);
  ASTUnitImporterMap[From.getTranslationUnitDecl()].reset(NewImporter);
  return *NewImporter;
}

} // namespace cross_tu
} // namespace clang
<commit_msg>Fix implicit-fallthrough warning by adding missing break<commit_after>//===--- CrossTranslationUnit.cpp - -----------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements the CrossTranslationUnit interface.
//
//===----------------------------------------------------------------------===//
#include "clang/CrossTU/CrossTranslationUnit.h"
#include "clang/AST/ASTImporter.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CrossTU/CrossTUDiagnostic.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Index/USRGeneration.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <fstream>
#include <sstream>

namespace clang {
namespace cross_tu {

namespace {
// FIXME: This class is will be removed after the transition to llvm::Error.
class IndexErrorCategory : public std::error_category {
public:
  const char *name() const noexcept override { return "clang.index"; }

  std::string message(int Condition) const override {
    switch (static_cast<index_error_code>(Condition)) {
    case index_error_code::unspecified:
      return "An unknown error has occurred.";
    case index_error_code::missing_index_file:
      return "The index file is missing.";
    case index_error_code::invalid_index_format:
      return "Invalid index file format.";
    case index_error_code::multiple_definitions:
      return "Multiple definitions in the index file.";
    case index_error_code::missing_definition:
      return "Missing definition from the index file.";
    case index_error_code::failed_import:
      return "Failed to import the definition.";
    case index_error_code::failed_to_get_external_ast:
      return "Failed to load external AST source.";
    case index_error_code::failed_to_generate_usr:
      return "Failed to generate USR.";
    }
    llvm_unreachable("Unrecognized index_error_code.");
  }
};

static llvm::ManagedStatic<IndexErrorCategory> Category;
} // end anonymous namespace

char IndexError::ID;

void IndexError::log(raw_ostream &OS) const {
  OS << Category->message(static_cast<int>(Code)) << '\n';
}

std::error_code IndexError::convertToErrorCode() const {
  return std::error_code(static_cast<int>(Code), *Category);
}

llvm::Expected<llvm::StringMap<std::string>>
parseCrossTUIndex(StringRef IndexPath, StringRef CrossTUDir) {
  std::ifstream ExternalFnMapFile(IndexPath);
  if (!ExternalFnMapFile)
    return llvm::make_error<IndexError>(index_error_code::missing_index_file,
                                        IndexPath.str());

  llvm::StringMap<std::string> Result;
  std::string Line;
  unsigned LineNo = 1;
  while (std::getline(ExternalFnMapFile, Line)) {
    const size_t Pos = Line.find(" ");
    if (Pos > 0 && Pos != std::string::npos) {
      StringRef LineRef{Line};
      StringRef FunctionLookupName = LineRef.substr(0, Pos);
      if (Result.count(FunctionLookupName))
        return llvm::make_error<IndexError>(
            index_error_code::multiple_definitions, IndexPath.str(), LineNo);
      StringRef FileName = LineRef.substr(Pos + 1);
      SmallString<256> FilePath = CrossTUDir;
      if (llvm::sys::path::is_absolute(FileName))
        FilePath = FileName;
      else
        llvm::sys::path::append(FilePath, FileName);
      Result[FunctionLookupName] = FilePath.str().str();
    } else
      return llvm::make_error<IndexError>(
          index_error_code::invalid_index_format, IndexPath.str(), LineNo);
    LineNo++;
  }
  return Result;
}

std::string
createCrossTUIndexString(const llvm::StringMap<std::string> &Index) {
  std::ostringstream Result;
  for (const auto &E : Index)
    Result << E.getKey().str() << " " << E.getValue() << '\n';
  return Result.str();
}

CrossTranslationUnitContext::CrossTranslationUnitContext(CompilerInstance &CI)
    : CI(CI), Context(CI.getASTContext()) {}

CrossTranslationUnitContext::~CrossTranslationUnitContext() {}

std::string CrossTranslationUnitContext::getLookupName(const NamedDecl *ND) {
  SmallString<128> DeclUSR;
  bool Ret = index::generateUSRForDecl(ND, DeclUSR); (void)Ret;
  assert(!Ret && "Unable to generate USR");
  return DeclUSR.str();
}

/// Recursively visits the function decls of a DeclContext, and looks up a
/// function based on USRs.
const FunctionDecl *
CrossTranslationUnitContext::findFunctionInDeclContext(const DeclContext *DC,
                                                       StringRef LookupFnName) {
  assert(DC && "Declaration Context must not be null");
  for (const Decl *D : DC->decls()) {
    const auto *SubDC = dyn_cast<DeclContext>(D);
    if (SubDC)
      if (const auto *FD = findFunctionInDeclContext(SubDC, LookupFnName))
        return FD;

    const auto *ND = dyn_cast<FunctionDecl>(D);
    const FunctionDecl *ResultDecl;
    if (!ND || !ND->hasBody(ResultDecl))
      continue;
    if (getLookupName(ResultDecl) != LookupFnName)
      continue;
    return ResultDecl;
  }
  return nullptr;
}

llvm::Expected<const FunctionDecl *>
CrossTranslationUnitContext::getCrossTUDefinition(const FunctionDecl *FD,
                                                  StringRef CrossTUDir,
                                                  StringRef IndexName) {
  assert(!FD->hasBody() && "FD has a definition in current translation unit!");
  const std::string LookupFnName = getLookupName(FD);
  if (LookupFnName.empty())
    return llvm::make_error<IndexError>(
        index_error_code::failed_to_generate_usr);
  llvm::Expected<ASTUnit *> ASTUnitOrError =
      loadExternalAST(LookupFnName, CrossTUDir, IndexName);
  if (!ASTUnitOrError)
    return ASTUnitOrError.takeError();
  ASTUnit *Unit = *ASTUnitOrError;
  if (!Unit)
    return llvm::make_error<IndexError>(
        index_error_code::failed_to_get_external_ast);
  assert(&Unit->getFileManager() ==
         &Unit->getASTContext().getSourceManager().getFileManager());

  TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
  if (const FunctionDecl *ResultDecl =
          findFunctionInDeclContext(TU, LookupFnName))
    return importDefinition(ResultDecl);
  return llvm::make_error<IndexError>(index_error_code::failed_import);
}

void CrossTranslationUnitContext::emitCrossTUDiagnostics(const IndexError &IE) {
  switch (IE.getCode()) {
  case index_error_code::missing_index_file:
    Context.getDiagnostics().Report(diag::err_fe_error_opening)
        << IE.getFileName() << "required by the CrossTU functionality";
    break;
  case index_error_code::invalid_index_format:
    Context.getDiagnostics().Report(diag::err_fnmap_parsing)
        << IE.getFileName() << IE.getLineNum();
    break;
  case index_error_code::multiple_definitions:
    Context.getDiagnostics().Report(diag::err_multiple_def_index)
        << IE.getLineNum();
    break;
  default:
    break;
  }
}

llvm::Expected<ASTUnit *> CrossTranslationUnitContext::loadExternalAST(
    StringRef LookupName, StringRef CrossTUDir, StringRef IndexName) {
  // FIXME: The current implementation only supports loading functions with
  //        a lookup name from a single translation unit. If multiple
  //        translation units contains functions with the same lookup name an
  //        error will be returned.
  ASTUnit *Unit = nullptr;
  auto FnUnitCacheEntry = FunctionASTUnitMap.find(LookupName);
  if (FnUnitCacheEntry == FunctionASTUnitMap.end()) {
    if (FunctionFileMap.empty()) {
      SmallString<256> IndexFile = CrossTUDir;
      if (llvm::sys::path::is_absolute(IndexName))
        IndexFile = IndexName;
      else
        llvm::sys::path::append(IndexFile, IndexName);
      llvm::Expected<llvm::StringMap<std::string>> IndexOrErr =
          parseCrossTUIndex(IndexFile, CrossTUDir);
      if (IndexOrErr)
        FunctionFileMap = *IndexOrErr;
      else
        return IndexOrErr.takeError();
    }

    auto It = FunctionFileMap.find(LookupName);
    if (It == FunctionFileMap.end())
      return llvm::make_error<IndexError>(index_error_code::missing_definition);
    StringRef ASTFileName = It->second;
    auto ASTCacheEntry = FileASTUnitMap.find(ASTFileName);
    if (ASTCacheEntry == FileASTUnitMap.end()) {
      IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
      TextDiagnosticPrinter *DiagClient =
          new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
      IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
      IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
          new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient));

      std::unique_ptr<ASTUnit> LoadedUnit(ASTUnit::LoadFromASTFile(
          ASTFileName, CI.getPCHContainerOperations()->getRawReader(),
          ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts()));
      Unit = LoadedUnit.get();
      FileASTUnitMap[ASTFileName] = std::move(LoadedUnit);
    } else {
      Unit = ASTCacheEntry->second.get();
    }
    FunctionASTUnitMap[LookupName] = Unit;
  } else {
    Unit = FnUnitCacheEntry->second;
  }
  return Unit;
}

llvm::Expected<const FunctionDecl *>
CrossTranslationUnitContext::importDefinition(const FunctionDecl *FD) {
  ASTImporter &Importer = getOrCreateASTImporter(FD->getASTContext());
  auto *ToDecl =
      cast<FunctionDecl>(Importer.Import(const_cast<FunctionDecl *>(FD)));
  assert(ToDecl->hasBody());
  assert(FD->hasBody() && "Functions already imported should have body.");
  return ToDecl;
}

ASTImporter &
CrossTranslationUnitContext::getOrCreateASTImporter(ASTContext &From) {
  auto I = ASTUnitImporterMap.find(From.getTranslationUnitDecl());
  if (I != ASTUnitImporterMap.end())
    return *I->second;
  ASTImporter *NewImporter =
      new ASTImporter(Context, Context.getSourceManager().getFileManager(),
                      From, From.getSourceManager().getFileManager(), false);
  ASTUnitImporterMap[From.getTranslationUnitDecl()].reset(NewImporter);
  return *NewImporter;
}

} // namespace cross_tu
} // namespace clang
<|endoftext|>


<commit_before>#ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__INV_GAMMA_HPP__
#define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__INV_GAMMA_HPP__

#include <stan/agrad.hpp>
#include <stan/math/error_handling.hpp>
#include <stan/math/special_functions.hpp>
#include <stan/meta/traits.hpp>
#include <stan/prob/constants.hpp>
#include <stan/prob/traits.hpp>
#include <stan/prob/internal_math.hpp>

namespace stan {

  namespace prob {

    /**
     * The log of an inverse gamma density for y with the specified
     * shape and scale parameters.
     * Shape and scale parameters must be greater than 0.
     * y must be greater than 0.
     *
     * @param y A scalar variable.
     * @param alpha Shape parameter.
     * @param beta Scale parameter.
     * @throw std::domain_error if alpha is not greater than 0.
     * @throw std::domain_error if beta is not greater than 0.
     * @throw std::domain_error if y is not greater than 0.
     * @tparam T_y Type of scalar.
     * @tparam T_shape Type of shape.
     * @tparam T_scale Type of scale.
     */
    template <bool propto,
              typename T_y, typename T_shape, typename T_scale,
              class Policy>
    typename return_type<T_y,T_shape,T_scale>::type
    inv_gamma_log(const T_y& y, const T_shape& alpha, const T_scale& beta,
                  const Policy&) {
      static const char* function = "stan::prob::inv_gamma_log(%1%)";

      using stan::is_constant_struct;
      using stan::math::check_not_nan;
      using stan::math::check_positive;
      using stan::math::check_finite;
      using boost::math::tools::promote_args;
      using stan::math::check_consistent_sizes;
      using stan::math::value_of;

      // check if any vectors are zero length
      if (!(stan::length(y)
            && stan::length(alpha)
            && stan::length(beta)))
        return 0.0;

      // set up return value accumulator
      double logp(0.0);

      if (!check_not_nan(function, y, "Random variable", &logp, Policy()))
        return logp;
      if (!check_finite(function, alpha, "Shape parameter",
                        &logp, Policy()))
        return logp;
      if (!check_positive(function, alpha, "Shape parameter",
                          &logp, Policy()))
        return logp;
      if (!check_finite(function, beta, "Scale parameter",
                        &logp, Policy()))
        return logp;
      if (!check_positive(function, beta, "Scale parameter",
                          &logp, Policy()))
        return logp;
      if (!(check_consistent_sizes(function,
                                   y,alpha,beta,
				   "Random variable","Shape parameter","Scale parameter",
                                   &logp, Policy())))
        return logp;

      // check if no variables are involved and prop-to
      if (!include_summand<propto,T_y,T_shape,T_scale>::value)
	return 0.0;

      // set up template expressions wrapping scalars into vector views
      VectorView<const T_y> y_vec(y);
      VectorView<const T_shape> alpha_vec(alpha);
      VectorView<const T_scale> beta_vec(beta);

      for (size_t n = 0; n < length(y); n++) {
	const double y_dbl = value_of(y_vec[n]);
	if (y_dbl <= 0)
	  return LOG_ZERO;
      }

      size_t N = max_size(y, alpha, beta);
      agrad::OperandsAndPartials<T_y, T_shape, T_scale> operands_and_partials(y, alpha, beta);

      using boost::math::lgamma;
      using stan::math::multiply_log;
      using boost::math::digamma;

      DoubleVectorView<include_summand<propto,T_y,T_shape>::value,T_y>
	log_y(length(y));
      DoubleVectorView<include_summand<propto,T_y,T_scale>::value,T_y>
	inv_y(length(y));
      for(size_t n = 0; n < length(y); n++) {
	if (include_summand<propto,T_y,T_shape>::value)
	  if (value_of(y_vec[n]) > 0)
	    log_y[n] = log(value_of(y_vec[n]));
	if (include_summand<propto,T_y,T_scale>::value)
	  inv_y[n] = 1.0 / value_of(y_vec[n]);
      }

      DoubleVectorView<include_summand<propto,T_shape>::value,T_shape>
	lgamma_alpha(length(alpha));
      DoubleVectorView<!is_constant_struct<T_shape>::value,T_shape>
	digamma_alpha(length(alpha));
      for (size_t n = 0; n < length(alpha); n++) {
	if (include_summand<propto,T_shape>::value)
	  lgamma_alpha[n] = lgamma(value_of(alpha_vec[n]));
	if (!is_constant_struct<T_shape>::value)
	  digamma_alpha[n] = digamma(value_of(alpha_vec[n]));
      }

      DoubleVectorView<include_summand<propto,T_shape,T_scale>::value,T_scale>
	log_beta(length(beta));
      if (include_summand<propto,T_shape,T_scale>::value)
	for (size_t n = 0; n < length(beta); n++)
	  log_beta[n] = log(value_of(beta_vec[n]));

      for (size_t n = 0; n < N; n++) {
	// pull out values of arguments
	const double alpha_dbl = value_of(alpha_vec[n]);
	const double beta_dbl = value_of(beta_vec[n]);

	if (include_summand<propto,T_shape>::value)
	  logp -= lgamma_alpha[n];
	if (include_summand<propto,T_shape,T_scale>::value)
	  logp += alpha_dbl * log_beta[n];
	if (include_summand<propto,T_y,T_shape>::value)
	  logp -= (alpha_dbl+1.0) * log_y[n];
	if (include_summand<propto,T_y,T_scale>::value)
	  logp -= beta_dbl * inv_y[n];

	// gradients
	if (!is_constant<typename is_vector<T_y>::type>::value)
	  operands_and_partials.d_x1[n] += -(alpha_dbl+1) * inv_y[n] + beta_dbl * inv_y[n] * inv_y[n];
	if (!is_constant<typename is_vector<T_shape>::type>::value)
	  operands_and_partials.d_x2[n] += -digamma_alpha[n] + log_beta[n] - log_y[n];
	if (!is_constant<typename is_vector<T_scale>::type>::value)
	  operands_and_partials.d_x3[n] += alpha_dbl / beta_dbl - inv_y[n];
      }
      return operands_and_partials.to_var(logp);
    }

    template <bool propto,
              typename T_y, typename T_shape, typename T_scale>
    inline
    typename return_type<T_y,T_shape,T_scale>::type
    inv_gamma_log(const T_y& y, const T_shape& alpha, const T_scale& beta) {
      return inv_gamma_log<propto>(y,alpha,beta,stan::math::default_policy());
    }

    template <typename T_y, typename T_shape, typename T_scale,
              class Policy>
    inline
    typename return_type<T_y,T_shape,T_scale>::type
    inv_gamma_log(const T_y& y, const T_shape& alpha, const T_scale& beta,
                  const Policy&) {
      return inv_gamma_log<false>(y,alpha,beta,Policy());
    }

    template <typename T_y, typename T_shape, typename T_scale>
    inline
    typename return_type<T_y,T_shape,T_scale>::type
    inv_gamma_log(const T_y& y, const T_shape& alpha, const T_scale& beta) {
      return inv_gamma_log<false>(y,alpha,beta,stan::math::default_policy());
    }

      /**
       * The CDF of an inverse gamma density for y with the specified
       * shape and scale parameters. y, shape, and scale parameters must be greater than 0.
       *
       * @param y A scalar variable.
       * @param alpha Shape parameter.
       * @param beta Scale parameter.
       * @throw std::domain_error if alpha is not greater than 0.
       * @throw std::domain_error if beta is not greater than 0.
       * @throw std::domain_error if y is not greater than 0.
       * @tparam T_y Type of scalar.
       * @tparam T_shape Type of shape.
       * @tparam T_scale Type of scale.
       */

      template <typename T_y, typename T_shape, typename T_scale, class Policy>
      typename return_type<T_y,T_shape,T_scale>::type
      inv_gamma_cdf(const T_y& y, const T_shape& alpha, const T_scale& beta, const Policy&) {

          // Size checks
          if ( !( stan::length(y) && stan::length(alpha) && stan::length(beta) ) ) return 0.0;

          // Error checks
          static const char* function = "stan::prob::inv_gamma_cdf(%1%)";

          using stan::math::check_finite;
          using stan::math::check_positive;
          using stan::math::check_not_nan;
          using stan::math::check_consistent_sizes;
          using stan::math::check_greater_or_equal;
          using stan::math::check_less_or_equal;

          using boost::math::tools::promote_args;

          double P(1.0);

          if (!check_finite(function, alpha, "Shape parameter", &P, Policy()))
              return P;

          if (!check_positive(function, alpha, "Shape parameter", &P, Policy()))
              return P;

          if (!check_finite(function, beta, "Scale parameter", &P, Policy()))
              return P;

          if (!check_positive(function, beta, "Scale parameter", &P, Policy()))
              return P;

          if (!check_not_nan(function, y, "Random variable", &P, Policy()))
              return P;

          if (!check_positive(function, y, "Random variable", &P, Policy()))
              return P;

          if (!(check_consistent_sizes(function, y, alpha, beta,
                                       "Random variable", "Shape parameter", "Scale Parameter",
                                       &P, Policy())))
              return P;

          // Wrap arguments in vectors
          VectorView<const T_y> y_vec(y);
          VectorView<const T_shape> alpha_vec(alpha);
          VectorView<const T_scale> beta_vec(beta);
          size_t N = max_size(y, alpha, beta);

          agrad::OperandsAndPartials<T_y, T_shape, T_scale> operands_and_partials(y, alpha, beta);

          std::fill(operands_and_partials.all_partials,
                    operands_and_partials.all_partials + operands_and_partials.nvaris, 0.0);

          // Compute CDF and its gradients
          using stan::math::value_of;
          using boost::math::gamma_p_derivative;
          using boost::math::gamma_q;
          using boost::math::digamma;
	  using boost::math::tgamma;

          // Cache a few expensive function calls if nu is a parameter
          DoubleVectorView<!is_constant_struct<T_shape>::value, T_shape> gamma_vec(stan::length(alpha));
          DoubleVectorView<!is_constant_struct<T_shape>::value, T_shape> digamma_vec(stan::length(alpha));

          if (!is_constant_struct<T_shape>::value) {

              for (size_t i = 0; i < stan::length(alpha); i++) {
                  const double alpha_dbl = value_of(alpha_vec[i]);
                  gamma_vec[i] = tgamma(alpha_dbl);
                  digamma_vec[i] = digamma(alpha_dbl);
              }

          }

          // Compute vectorized CDF and gradient
          for (size_t n = 0; n < N; n++) {

              // Pull out values
              const double y_dbl = value_of(y_vec[n]);
              const double y_inv_dbl = 1.0 / y_dbl;
              const double alpha_dbl = value_of(alpha_vec[n]);
              const double beta_dbl = value_of(beta_vec[n]);

              // Compute
              const double Pn = gamma_q(alpha_dbl, beta_dbl * y_inv_dbl);

              P *= Pn;

              if (!is_constant_struct<T_y>::value)
                  operands_and_partials.d_x1[n]
                  += beta_dbl * y_inv_dbl * y_inv_dbl * gamma_p_derivative(alpha_dbl, beta_dbl * y_inv_dbl) / Pn;

              if (!is_constant_struct<T_shape>::value)
                  operands_and_partials.d_x2[n]
                  += stan::math::gradRegIncGamma(alpha_dbl, beta_dbl * y_inv_dbl, gamma_vec[n], digamma_vec[n]) / Pn;

              if (!is_constant_struct<T_scale>::value)
                  operands_and_partials.d_x3[n]
                  += - y_inv_dbl * gamma_p_derivative(alpha_dbl, beta_dbl * y_inv_dbl) / Pn;

          }

          for (size_t n = 0; n < N; n++) {

              if (!is_constant_struct<T_y>::value)
                  operands_and_partials.d_x1[n] *= P;

              if (!is_constant_struct<T_shape>::value)
                  operands_and_partials.d_x2[n] *= P;

              if (!is_constant_struct<T_scale>::value)
                  operands_and_partials.d_x3[n] *= P;

          }

          return operands_and_partials.to_var(P);

      }

      template <typename T_y, typename T_shape, typename T_scale>
      inline typename return_type<T_y, T_shape, T_scale>::type
      inv_gamma_cdf(const T_y& y, const T_shape& alpha, const T_scale& beta) {
          return inv_gamma_cdf(y, alpha, beta, stan::math::default_policy());
      }

  }
}

#endif
<commit_msg>refactoring inv_gamma distribution<commit_after>#ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__INV_GAMMA_HPP__
#define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__INV_GAMMA_HPP__

#include <stan/agrad.hpp>
#include <stan/math/error_handling.hpp>
#include <stan/math/special_functions.hpp>
#include <stan/meta/traits.hpp>
#include <stan/prob/constants.hpp>
#include <stan/prob/traits.hpp>
#include <stan/prob/internal_math.hpp>

namespace stan {

  namespace prob {

    /**
     * The log of an inverse gamma density for y with the specified
     * shape and scale parameters.
     * Shape and scale parameters must be greater than 0.
     * y must be greater than 0.
     *
     * @param y A scalar variable.
     * @param alpha Shape parameter.
     * @param beta Scale parameter.
     * @throw std::domain_error if alpha is not greater than 0.
     * @throw std::domain_error if beta is not greater than 0.
     * @throw std::domain_error if y is not greater than 0.
     * @tparam T_y Type of scalar.
     * @tparam T_shape Type of shape.
     * @tparam T_scale Type of scale.
     */
    template <bool propto,
              typename T_y, typename T_shape, typename T_scale,
              class Policy>
    typename return_type<T_y,T_shape,T_scale>::type
    inv_gamma_log(const T_y& y, const T_shape& alpha, const T_scale& beta,
                  const Policy&) {
      static const char* function = "stan::prob::inv_gamma_log(%1%)";

      using stan::is_constant_struct;
      using stan::math::check_not_nan;
      using stan::math::check_positive;
      using stan::math::check_finite;
      using boost::math::tools::promote_args;
      using stan::math::check_consistent_sizes;
      using stan::math::value_of;

      // check if any vectors are zero length
      if (!(stan::length(y)
            && stan::length(alpha)
            && stan::length(beta)))
        return 0.0;

      // set up return value accumulator
      double logp(0.0);

      if (!check_not_nan(function, y, "Random variable", &logp, Policy()))
        return logp;
      if (!check_finite(function, alpha, "Shape parameter",
                        &logp, Policy()))
        return logp;
      if (!check_positive(function, alpha, "Shape parameter",
                          &logp, Policy()))
        return logp;
      if (!check_finite(function, beta, "Scale parameter",
                        &logp, Policy()))
        return logp;
      if (!check_positive(function, beta, "Scale parameter",
                          &logp, Policy()))
        return logp;
      if (!(check_consistent_sizes(function,
                                   y,alpha,beta,
				   "Random variable","Shape parameter","Scale parameter",
                                   &logp, Policy())))
        return logp;

      // check if no variables are involved and prop-to
      if (!include_summand<propto,T_y,T_shape,T_scale>::value)
	return 0.0;

      // set up template expressions wrapping scalars into vector views
      VectorView<const T_y> y_vec(y);
      VectorView<const T_shape> alpha_vec(alpha);
      VectorView<const T_scale> beta_vec(beta);

      for (size_t n = 0; n < length(y); n++) {
	const double y_dbl = value_of(y_vec[n]);
	if (y_dbl <= 0)
	  return LOG_ZERO;
      }

      size_t N = max_size(y, alpha, beta);
      agrad::OperandsAndPartials<T_y, T_shape, T_scale> operands_and_partials(y, alpha, beta);

      using boost::math::lgamma;
      using stan::math::multiply_log;
      using boost::math::digamma;

      DoubleVectorView<include_summand<propto,T_y,T_shape>::value,is_vector<T_y>::value>
	log_y(length(y));
      DoubleVectorView<include_summand<propto,T_y,T_scale>::value,is_vector<T_y>::value>
	inv_y(length(y));
      for(size_t n = 0; n < length(y); n++) {
	if (include_summand<propto,T_y,T_shape>::value)
	  if (value_of(y_vec[n]) > 0)
	    log_y[n] = log(value_of(y_vec[n]));
	if (include_summand<propto,T_y,T_scale>::value)
	  inv_y[n] = 1.0 / value_of(y_vec[n]);
      }

      DoubleVectorView<include_summand<propto,T_shape>::value,is_vector<T_shape>::value>
	lgamma_alpha(length(alpha));
      DoubleVectorView<!is_constant_struct<T_shape>::value,is_vector<T_shape>::value>
	digamma_alpha(length(alpha));
      for (size_t n = 0; n < length(alpha); n++) {
	if (include_summand<propto,T_shape>::value)
	  lgamma_alpha[n] = lgamma(value_of(alpha_vec[n]));
	if (!is_constant_struct<T_shape>::value)
	  digamma_alpha[n] = digamma(value_of(alpha_vec[n]));
      }

      DoubleVectorView<include_summand<propto,T_shape,T_scale>::value,is_vector<T_scale>::value>
	log_beta(length(beta));
      if (include_summand<propto,T_shape,T_scale>::value)
	for (size_t n = 0; n < length(beta); n++)
	  log_beta[n] = log(value_of(beta_vec[n]));

      for (size_t n = 0; n < N; n++) {
	// pull out values of arguments
	const double alpha_dbl = value_of(alpha_vec[n]);
	const double beta_dbl = value_of(beta_vec[n]);

	if (include_summand<propto,T_shape>::value)
	  logp -= lgamma_alpha[n];
	if (include_summand<propto,T_shape,T_scale>::value)
	  logp += alpha_dbl * log_beta[n];
	if (include_summand<propto,T_y,T_shape>::value)
	  logp -= (alpha_dbl+1.0) * log_y[n];
	if (include_summand<propto,T_y,T_scale>::value)
	  logp -= beta_dbl * inv_y[n];

	// gradients
	if (!is_constant<typename is_vector<T_y>::type>::value)
	  operands_and_partials.d_x1[n] += -(alpha_dbl+1) * inv_y[n] + beta_dbl * inv_y[n] * inv_y[n];
	if (!is_constant<typename is_vector<T_shape>::type>::value)
	  operands_and_partials.d_x2[n] += -digamma_alpha[n] + log_beta[n] - log_y[n];
	if (!is_constant<typename is_vector<T_scale>::type>::value)
	  operands_and_partials.d_x3[n] += alpha_dbl / beta_dbl - inv_y[n];
      }
      return operands_and_partials.to_var(logp);
    }

    template <bool propto,
              typename T_y, typename T_shape, typename T_scale>
    inline
    typename return_type<T_y,T_shape,T_scale>::type
    inv_gamma_log(const T_y& y, const T_shape& alpha, const T_scale& beta) {
      return inv_gamma_log<propto>(y,alpha,beta,stan::math::default_policy());
    }

    template <typename T_y, typename T_shape, typename T_scale,
              class Policy>
    inline
    typename return_type<T_y,T_shape,T_scale>::type
    inv_gamma_log(const T_y& y, const T_shape& alpha, const T_scale& beta,
                  const Policy&) {
      return inv_gamma_log<false>(y,alpha,beta,Policy());
    }

    template <typename T_y, typename T_shape, typename T_scale>
    inline
    typename return_type<T_y,T_shape,T_scale>::type
    inv_gamma_log(const T_y& y, const T_shape& alpha, const T_scale& beta) {
      return inv_gamma_log<false>(y,alpha,beta,stan::math::default_policy());
    }

      /**
       * The CDF of an inverse gamma density for y with the specified
       * shape and scale parameters. y, shape, and scale parameters must be greater than 0.
       *
       * @param y A scalar variable.
       * @param alpha Shape parameter.
       * @param beta Scale parameter.
       * @throw std::domain_error if alpha is not greater than 0.
       * @throw std::domain_error if beta is not greater than 0.
       * @throw std::domain_error if y is not greater than 0.
       * @tparam T_y Type of scalar.
       * @tparam T_shape Type of shape.
       * @tparam T_scale Type of scale.
       */

      template <typename T_y, typename T_shape, typename T_scale, class Policy>
      typename return_type<T_y,T_shape,T_scale>::type
      inv_gamma_cdf(const T_y& y, const T_shape& alpha, const T_scale& beta, const Policy&) {

          // Size checks
          if ( !( stan::length(y) && stan::length(alpha) && stan::length(beta) ) ) return 0.0;

          // Error checks
          static const char* function = "stan::prob::inv_gamma_cdf(%1%)";

          using stan::math::check_finite;
          using stan::math::check_positive;
          using stan::math::check_not_nan;
          using stan::math::check_consistent_sizes;
          using stan::math::check_greater_or_equal;
          using stan::math::check_less_or_equal;

          using boost::math::tools::promote_args;

          double P(1.0);

          if (!check_finite(function, alpha, "Shape parameter", &P, Policy()))
              return P;

          if (!check_positive(function, alpha, "Shape parameter", &P, Policy()))
              return P;

          if (!check_finite(function, beta, "Scale parameter", &P, Policy()))
              return P;

          if (!check_positive(function, beta, "Scale parameter", &P, Policy()))
              return P;

          if (!check_not_nan(function, y, "Random variable", &P, Policy()))
              return P;

          if (!check_positive(function, y, "Random variable", &P, Policy()))
              return P;

          if (!(check_consistent_sizes(function, y, alpha, beta,
                                       "Random variable", "Shape parameter", "Scale Parameter",
                                       &P, Policy())))
              return P;

          // Wrap arguments in vectors
          VectorView<const T_y> y_vec(y);
          VectorView<const T_shape> alpha_vec(alpha);
          VectorView<const T_scale> beta_vec(beta);
          size_t N = max_size(y, alpha, beta);

          agrad::OperandsAndPartials<T_y, T_shape, T_scale> operands_and_partials(y, alpha, beta);

          std::fill(operands_and_partials.all_partials,
                    operands_and_partials.all_partials + operands_and_partials.nvaris, 0.0);

          // Compute CDF and its gradients
          using stan::math::value_of;
          using boost::math::gamma_p_derivative;
          using boost::math::gamma_q;
          using boost::math::digamma;
	  using boost::math::tgamma;

          // Cache a few expensive function calls if nu is a parameter
          DoubleVectorView<!is_constant_struct<T_shape>::value, is_vector<T_shape>::value> gamma_vec(stan::length(alpha));
          DoubleVectorView<!is_constant_struct<T_shape>::value, is_vector<T_shape>::value> digamma_vec(stan::length(alpha));

          if (!is_constant_struct<T_shape>::value) {

              for (size_t i = 0; i < stan::length(alpha); i++) {
                  const double alpha_dbl = value_of(alpha_vec[i]);
                  gamma_vec[i] = tgamma(alpha_dbl);
                  digamma_vec[i] = digamma(alpha_dbl);
              }

          }

          // Compute vectorized CDF and gradient
          for (size_t n = 0; n < N; n++) {

              // Pull out values
              const double y_dbl = value_of(y_vec[n]);
              const double y_inv_dbl = 1.0 / y_dbl;
              const double alpha_dbl = value_of(alpha_vec[n]);
              const double beta_dbl = value_of(beta_vec[n]);

              // Compute
              const double Pn = gamma_q(alpha_dbl, beta_dbl * y_inv_dbl);

              P *= Pn;

              if (!is_constant_struct<T_y>::value)
                  operands_and_partials.d_x1[n]
                  += beta_dbl * y_inv_dbl * y_inv_dbl * gamma_p_derivative(alpha_dbl, beta_dbl * y_inv_dbl) / Pn;

              if (!is_constant_struct<T_shape>::value)
                  operands_and_partials.d_x2[n]
                  += stan::math::gradRegIncGamma(alpha_dbl, beta_dbl * y_inv_dbl, gamma_vec[n], digamma_vec[n]) / Pn;

              if (!is_constant_struct<T_scale>::value)
                  operands_and_partials.d_x3[n]
                  += - y_inv_dbl * gamma_p_derivative(alpha_dbl, beta_dbl * y_inv_dbl) / Pn;

          }

          for (size_t n = 0; n < N; n++) {

              if (!is_constant_struct<T_y>::value)
                  operands_and_partials.d_x1[n] *= P;

              if (!is_constant_struct<T_shape>::value)
                  operands_and_partials.d_x2[n] *= P;

              if (!is_constant_struct<T_scale>::value)
                  operands_and_partials.d_x3[n] *= P;

          }

          return operands_and_partials.to_var(P);

      }

      template <typename T_y, typename T_shape, typename T_scale>
      inline typename return_type<T_y, T_shape, T_scale>::type
      inv_gamma_cdf(const T_y& y, const T_shape& alpha, const T_scale& beta) {
          return inv_gamma_cdf(y, alpha, beta, stan::math::default_policy());
      }

  }
}

#endif
<|endoftext|>


<commit_before>#include "Log.h"

#include "utils/FileSystemUtil.h"
#include "platform.h"
#include <iostream>

LogLevel Log::reportingLevel = LogInfo;
FILE* Log::file = NULL; //fopen(getLogPath().c_str(), "w");

LogLevel Log::getReportingLevel()
{
	return reportingLevel;
}

std::string Log::getLogPath()
{
	std::string home = Utils::FileSystem::getHomePath();
	return home + "/.emulationstation/es_log.txt";
}

void Log::setReportingLevel(LogLevel level)
{
	reportingLevel = level;
}

void Log::init()
{
	remove((getLogPath() + ".bak").c_str());
	// rename previous log file
	rename(getLogPath().c_str(), (getLogPath() + ".bak").c_str());
	return;
}

void Log::open()
{
	file = fopen(getLogPath().c_str(), "w");
}

std::ostringstream& Log::get(LogLevel level)
{
	os << "lvl" << level << ": \t";
	messageLevel = level;

	return os;
}

void Log::flush()
{
	fflush(getOutput());
}

void Log::close()
{
	fclose(file);
	file = NULL;
}

FILE* Log::getOutput()
{
	return file;
}

Log::~Log()
{
	os << std::endl;

	if(getOutput() == NULL)
	{
		// not open yet, print to stdout
		std::cerr << "ERROR - tried to write to log file before it was open! The following won't be logged:\n";
		std::cerr << os.str();
		return;
	}

	fprintf(getOutput(), "%s", os.str().c_str());

	//if it's an error, also print to console
	//print all messages if using --debug
	if(messageLevel == LogError || reportingLevel >= LogDebug)
		fprintf(stderr, "%s", os.str().c_str());
}
<commit_msg>Timestamp'ed log entries<commit_after>#include "Log.h"

#include "utils/FileSystemUtil.h"
#include "platform.h"
#include <iostream>
#include <iomanip>

LogLevel Log::reportingLevel = LogInfo;
FILE* Log::file = NULL; //fopen(getLogPath().c_str(), "w");

LogLevel Log::getReportingLevel()
{
	return reportingLevel;
}

std::string Log::getLogPath()
{
	std::string home = Utils::FileSystem::getHomePath();
	return home + "/.emulationstation/es_log.txt";
}

void Log::setReportingLevel(LogLevel level)
{
	reportingLevel = level;
}

void Log::init()
{
	remove((getLogPath() + ".bak").c_str());
	// rename previous log file
	rename(getLogPath().c_str(), (getLogPath() + ".bak").c_str());
	return;
}

void Log::open()
{
	file = fopen(getLogPath().c_str(), "w");
}

std::ostringstream& Log::get(LogLevel level)
{
	time_t t = time(nullptr);
	os << std::put_time(localtime(&t), "%b %d %T ") << "lvl" << level << ": \t";
	messageLevel = level;

	return os;
}

void Log::flush()
{
	fflush(getOutput());
}

void Log::close()
{
	fclose(file);
	file = NULL;
}

FILE* Log::getOutput()
{
	return file;
}

Log::~Log()
{
	os << std::endl;

	if(getOutput() == NULL)
	{
		// not open yet, print to stdout
		std::cerr << "ERROR - tried to write to log file before it was open! The following won't be logged:\n";
		std::cerr << os.str();
		return;
	}

	fprintf(getOutput(), "%s", os.str().c_str());

	//if it's an error, also print to console
	//print all messages if using --debug
	if(messageLevel == LogError || reportingLevel >= LogDebug)
		fprintf(stderr, "%s", os.str().c_str());
}
<|endoftext|>


<commit_before>//===- ValueMapper.cpp - Interface shared by lib/Transforms/Utils ---------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MapValue function, which is shared by various parts of
// the lib/Transforms/Utils library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/DerivedTypes.h"  // For getNullValue(Type::Int32Ty)
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Metadata.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;

Value *llvm::MapValue(const Value *V, ValueMapTy &VM) {
  Value *&VMSlot = VM[V];
  if (VMSlot) return VMSlot;      // Does it exist in the map yet?

  // NOTE: VMSlot can be invalidated by any reference to VM, which can grow the
  // DenseMap.  This includes any recursive calls to MapValue.

  // Global values and metadata do not need to be seeded into the ValueMap if
  // they are using the identity mapping.
  if (isa<GlobalValue>(V) || isa<InlineAsm>(V) || isa<MetadataBase>(V))
    return VMSlot = const_cast<Value*>(V);

  Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));
  if (C == 0) return 0;

  if (isa<ConstantInt>(C) || isa<ConstantFP>(C) ||
      isa<ConstantPointerNull>(C) || isa<ConstantAggregateZero>(C) ||
      isa<UndefValue>(C) || isa<MDString>(C))
    return VMSlot = C;           // Primitive constants map directly

  if (ConstantArray *CA = dyn_cast<ConstantArray>(C)) {
    for (User::op_iterator b = CA->op_begin(), i = b, e = CA->op_end();
         i != e; ++i) {
      Value *MV = MapValue(*i, VM);
      if (MV != *i) {
        // This array must contain a reference to a global, make a new array
        // and return it.
        //
        std::vector<Constant*> Values;
        Values.reserve(CA->getNumOperands());
        for (User::op_iterator j = b; j != i; ++j)
          Values.push_back(cast<Constant>(*j));
        Values.push_back(cast<Constant>(MV));
        for (++i; i != e; ++i)
          Values.push_back(cast<Constant>(MapValue(*i, VM)));
        return VM[V] = ConstantArray::get(CA->getType(), Values);
      }
    }
    return VM[V] = C;
  }

  if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
    for (User::op_iterator b = CS->op_begin(), i = b, e = CS->op_end();
         i != e; ++i) {
      Value *MV = MapValue(*i, VM);
      if (MV != *i) {
        // This struct must contain a reference to a global, make a new struct
        // and return it.
        //
        std::vector<Constant*> Values;
        Values.reserve(CS->getNumOperands());
        for (User::op_iterator j = b; j != i; ++j)
          Values.push_back(cast<Constant>(*j));
        Values.push_back(cast<Constant>(MV));
        for (++i; i != e; ++i)
          Values.push_back(cast<Constant>(MapValue(*i, VM)));
        return VM[V] = ConstantStruct::get(CS->getType(), Values);
      }
    }
    return VM[V] = C;
  }

  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
    std::vector<Constant*> Ops;
    for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i)
      Ops.push_back(cast<Constant>(MapValue(*i, VM)));
    return VM[V] = CE->getWithOperands(Ops);
  }

  if (ConstantVector *CV = dyn_cast<ConstantVector>(C)) {
    for (User::op_iterator b = CV->op_begin(), i = b, e = CV->op_end();
         i != e; ++i) {
      Value *MV = MapValue(*i, VM);
      if (MV != *i) {
        // This vector value must contain a reference to a global, make a new
        // vector constant and return it.
        //
        std::vector<Constant*> Values;
        Values.reserve(CV->getNumOperands());
        for (User::op_iterator j = b; j != i; ++j)
          Values.push_back(cast<Constant>(*j));
        Values.push_back(cast<Constant>(MV));
        for (++i; i != e; ++i)
          Values.push_back(cast<Constant>(MapValue(*i, VM)));
        return VM[V] = ConstantVector::get(Values);
      }
    }
    return VM[V] = C;
  }

  if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
    Function *F = cast<Function>(MapValue(BA->getFunction(), VM));
    BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(),VM));
    return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock());
  }

  llvm_unreachable("Unknown type of constant!");
  return 0;
}

/// RemapInstruction - Convert the instruction operands from referencing the
/// current values into those specified by ValueMap.
///
void llvm::RemapInstruction(Instruction *I, ValueMapTy &ValueMap) {
  for (User::op_iterator op = I->op_begin(), E = I->op_end(); op != E; ++op) {
    Value *V = MapValue(*op, ValueMap);
    assert(V && "Referenced value not in value map!");
    *op = V;
  }

  // Map llvm.dbg.declare instruction's first operand, which points to
  // alloca instruction through MDNode. Since MDNodes are not counted as normal
  // uses, this will fall through cracks otherwise.
  const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I);
  if (!DDI) return;

  Value *AddrInsn = DDI->getAddress();
  if (!AddrInsn) return;

  ValueMapTy::iterator VMI = ValueMap.find(AddrInsn);
  if (VMI == ValueMap.end()) return;

  Value *Elts[] =  { VMI->second };
  MDNode *NewAddr = MDNode::get(AddrInsn->getContext(), Elts, 1);
  I->setOperand(1, NewAddr);
}

<commit_msg>Map operands of all function-local metadata, not just metadata passed to llvm.dbg.declare intrinsics<commit_after>//===- ValueMapper.cpp - Interface shared by lib/Transforms/Utils ---------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MapValue function, which is shared by various parts of
// the lib/Transforms/Utils library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/DerivedTypes.h"  // For getNullValue(Type::Int32Ty)
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Metadata.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;

Value *llvm::MapValue(const Value *V, ValueMapTy &VM) {
  Value *&VMSlot = VM[V];
  if (VMSlot) return VMSlot;      // Does it exist in the map yet?

  // NOTE: VMSlot can be invalidated by any reference to VM, which can grow the
  // DenseMap.  This includes any recursive calls to MapValue.

  // Global values and non-function-local metadata do not need to be seeded into
  // the ValueMap if they are using the identity mapping.
  if (isa<GlobalValue>(V) || isa<InlineAsm>(V) || isa<MDString>(V) ||
      (isa<MDNode>(V) && !dyn_cast<MDNode>(V)->isFunctionLocal()))
    return VMSlot = const_cast<Value*>(V);

  if (isa<MDNode>(V)) {
    const MDNode *MD = dyn_cast<MDNode>(V);
    std::vector<Value*> Elts;
    Elts.reserve(MD->getNumOperands());
    for (unsigned i = 0; i != MD->getNumOperands(); i++)
      Elts.push_back(MapValue(MD->getOperand(i), VM));
    return VM[V] = MDNode::get(V->getContext(), Elts.data(), Elts.size());
  }

  Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));
  if (C == 0) return 0;

  if (isa<ConstantInt>(C) || isa<ConstantFP>(C) ||
      isa<ConstantPointerNull>(C) || isa<ConstantAggregateZero>(C) ||
      isa<UndefValue>(C) || isa<MDString>(C))
    return VMSlot = C;           // Primitive constants map directly

  if (ConstantArray *CA = dyn_cast<ConstantArray>(C)) {
    for (User::op_iterator b = CA->op_begin(), i = b, e = CA->op_end();
         i != e; ++i) {
      Value *MV = MapValue(*i, VM);
      if (MV != *i) {
        // This array must contain a reference to a global, make a new array
        // and return it.
        //
        std::vector<Constant*> Values;
        Values.reserve(CA->getNumOperands());
        for (User::op_iterator j = b; j != i; ++j)
          Values.push_back(cast<Constant>(*j));
        Values.push_back(cast<Constant>(MV));
        for (++i; i != e; ++i)
          Values.push_back(cast<Constant>(MapValue(*i, VM)));
        return VM[V] = ConstantArray::get(CA->getType(), Values);
      }
    }
    return VM[V] = C;
  }

  if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
    for (User::op_iterator b = CS->op_begin(), i = b, e = CS->op_end();
         i != e; ++i) {
      Value *MV = MapValue(*i, VM);
      if (MV != *i) {
        // This struct must contain a reference to a global, make a new struct
        // and return it.
        //
        std::vector<Constant*> Values;
        Values.reserve(CS->getNumOperands());
        for (User::op_iterator j = b; j != i; ++j)
          Values.push_back(cast<Constant>(*j));
        Values.push_back(cast<Constant>(MV));
        for (++i; i != e; ++i)
          Values.push_back(cast<Constant>(MapValue(*i, VM)));
        return VM[V] = ConstantStruct::get(CS->getType(), Values);
      }
    }
    return VM[V] = C;
  }

  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
    std::vector<Constant*> Ops;
    for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i)
      Ops.push_back(cast<Constant>(MapValue(*i, VM)));
    return VM[V] = CE->getWithOperands(Ops);
  }

  if (ConstantVector *CV = dyn_cast<ConstantVector>(C)) {
    for (User::op_iterator b = CV->op_begin(), i = b, e = CV->op_end();
         i != e; ++i) {
      Value *MV = MapValue(*i, VM);
      if (MV != *i) {
        // This vector value must contain a reference to a global, make a new
        // vector constant and return it.
        //
        std::vector<Constant*> Values;
        Values.reserve(CV->getNumOperands());
        for (User::op_iterator j = b; j != i; ++j)
          Values.push_back(cast<Constant>(*j));
        Values.push_back(cast<Constant>(MV));
        for (++i; i != e; ++i)
          Values.push_back(cast<Constant>(MapValue(*i, VM)));
        return VM[V] = ConstantVector::get(Values);
      }
    }
    return VM[V] = C;
  }

  if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
    Function *F = cast<Function>(MapValue(BA->getFunction(), VM));
    BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(),VM));
    return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock());
  }

  llvm_unreachable("Unknown type of constant!");
  return 0;
}

/// RemapInstruction - Convert the instruction operands from referencing the
/// current values into those specified by ValueMap.
///
void llvm::RemapInstruction(Instruction *I, ValueMapTy &ValueMap) {
  for (User::op_iterator op = I->op_begin(), E = I->op_end(); op != E; ++op) {
    Value *V = MapValue(*op, ValueMap);
    assert(V && "Referenced value not in value map!");
    *op = V;
  }
}

<|endoftext|>


<commit_before><commit_msg>cleanup chainparams.cpp<commit_after><|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// catalog_cache.cpp
//
// Identification: src/catalog/catalog_cache.cpp
//
// Copyright (c) 2015-17, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <memory>

#include "catalog/catalog_cache.h"

namespace peloton {
namespace catalog {

/*@brief   insert database catalog object into cache
* @param   database_object
* @param   forced   if forced, replace existing object, else return false if oid
*          already exists
* @return  false only if not forced and database_oid already exists in cache
*/
bool CatalogCache::InsertDatabaseObject(
    std::shared_ptr<DatabaseCatalogObject> &database_object, bool forced) {
  if (!database_object || database_object->database_oid == INVALID_OID) {
    return false;  // invalid object
  }
  // std::lock_guard<std::mutex> lock(database_cache_lock);

  auto object_iter = database_objects_cache.find(database_object->database_oid);

  if (forced == true && object_iter != database_objects_cache.end()) {
    database_objects_cache.erase(object_iter);  // Evict old
    database_name_cache.erase(database_object->database_name);
    object_iter = database_objects_cache.find(database_object->database_oid);
  }
  if (object_iter == database_objects_cache.end()) {
    auto cached_object =
        std::shared_ptr<DatabaseCatalogObject>(database_object);
    database_objects_cache.insert(
        std::make_pair(database_object->database_oid, cached_object));
    database_name_cache.insert(std::make_pair(database_object->database_name,
                                              cached_object->database_oid));
    return true;
  } else {
    return false;
  }
}

/*@brief   evict database catalog object from cache
* @param   database_oid
* @return  true if database_oid is found and evicted; false if not found
*/
bool CatalogCache::EvictDatabaseObject(oid_t database_oid) {
  // std::lock_guard<std::mutex> lock(database_cache_lock);
  auto it = database_objects_cache.find(database_oid);
  if (it == database_objects_cache.end()) {
    return false;
  } else {
    database_name_cache.erase(it->second->database_name);
    database_objects_cache.erase(it);
    return true;
  }
}

/*@brief   get database catalog object from cache
* @param   database_oid
* @return  database catalog object; if not found return object with invalid oid
*/
std::shared_ptr<DatabaseCatalogObject> CatalogCache::GetDatabaseObject(
    oid_t database_oid) {
  // std::lock_guard<std::mutex> lock(database_cache_lock);
  auto it = database_objects_cache.find(database_oid);
  if (it == database_objects_cache.end()) {
    return std::make_shared<DatabaseCatalogObject>();
  }
  return it->second;
}

/*@brief   get database catalog object from cache
* @param   database_name
* @return  database catalog object; if not found return object with invalid oid
*/
std::shared_ptr<DatabaseCatalogObject> CatalogCache::GetDatabaseObject(
    const std::string &database_name) {
  // std::lock_guard<std::mutex> lock(database_cache_lock);
  auto it = database_name_cache.find(database_name);
  if (it == database_name_cache.end()) {
    return std::make_shared<DatabaseCatalogObject>();
  }
  oid_t database_oid = it->second;
  return database_objects_cache.find(database_oid)->second;
}

/*@brief   insert table catalog object into cache
* @param   table_object
* @param   forced   if forced, replace existing object, else return false if oid
*          already exists
* @return  false only if not forced and table_oid already exists in cache
*/
bool CatalogCache::InsertTableObject(
    std::shared_ptr<TableCatalogObject> table_object, bool forced) {
  if (!table_object || table_object->table_oid == INVALID_OID) {
    return false;  // invalid object
  }

  // find old table catalog object
  // std::lock_guard<std::mutex> lock(table_cache_lock);
  auto it = table_objects_cache.find(table_object->table_oid);

  // forced evict if found
  if (forced == true && it != table_objects_cache.end()) {
    if (it->second == table_object) return false;  // no need to replace
    EvictTableObject(table_object->table_oid);     // evict old
    it = table_objects_cache.find(table_object->table_oid);
  }

  // insert into table object cache
  if (it == table_objects_cache.end()) {
    table_objects_cache.insert(
        std::make_pair(table_object->table_oid, table_object));
    // find and insert into database catalog object too
    auto database_object = GetDatabaseObject(table_object->database_oid);
    if (database_object) {
      database_object->InsertTableObject(table_object, forced);
    }
    return true;
  } else {
    return false;  // table oid already exists
  }
}

/*@brief   evict table catalog object from cache
* @param   table_oid
* @return  true if table_oid is found and evicted; false if not found
*/
bool CatalogCache::EvictTableObject(oid_t table_oid) {
  if (table_oid == INVALID_OID) return false;
  // std::lock_guard<std::mutex> lock(table_cache_lock);

  // find table oid from catalog cache
  auto it = table_objects_cache.find(table_oid);
  if (it != table_objects_cache.end()) {
    auto table_object = it->second;
    table_objects_cache.erase(it);
    if (table_object) {
      // find and evict table name from database object's cache
      auto database_object = GetDatabaseObject(table_object->database_oid);
      if (database_object) {
        database_object->EvictTableObject(
            table_object->table_name);  // evict old name
      }
    }
    return true;
  } else {
    return false;  // table oid not found in cache
  }
}

/*@brief   get table catalog object from cache
* @param   table_oid
* @return  table catalog object; if not found return object with invalid oid
*/
std::shared_ptr<TableCatalogObject> CatalogCache::GetTableObject(
    oid_t table_oid) {
  // std::lock_guard<std::mutex> lock(table_cache_lock);
  auto it = table_objects_cache.find(table_oid);
  if (it == table_objects_cache.end()) {
    // if (txn == nullptr) return TableCatalogObject();
    // bool success = InsertTableObject(
    //     TableCatalog::GetInstance()->GetTableObject(table_oid, txn));
    // PL_ASSERT(success == true);
    // it = table_objects_cache.find(table_oid)
    return nullptr;
  }
  return it->second;
}

}  // namespace catalog
}  // namespace peloton
<commit_msg>fixed shared pointer nullptr problem<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// catalog_cache.cpp
//
// Identification: src/catalog/catalog_cache.cpp
//
// Copyright (c) 2015-17, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <memory>

#include "catalog/catalog_cache.h"

namespace peloton {
namespace catalog {

/*@brief   insert database catalog object into cache
* @param   database_object
* @param   forced   if forced, replace existing object, else return false if oid
*          already exists
* @return  false only if not forced and database_oid already exists in cache
*/
bool CatalogCache::InsertDatabaseObject(
    std::shared_ptr<DatabaseCatalogObject> &database_object, bool forced) {
  if (!database_object || database_object->database_oid == INVALID_OID) {
    return false;  // invalid object
  }
  // std::lock_guard<std::mutex> lock(database_cache_lock);

  auto object_iter = database_objects_cache.find(database_object->database_oid);

  if (forced == true && object_iter != database_objects_cache.end()) {
    database_objects_cache.erase(object_iter);  // Evict old
    database_name_cache.erase(database_object->database_name);
    object_iter = database_objects_cache.find(database_object->database_oid);
  }
  if (object_iter == database_objects_cache.end()) {
    auto cached_object =
        std::shared_ptr<DatabaseCatalogObject>(database_object);
    database_objects_cache.insert(
        std::make_pair(database_object->database_oid, cached_object));
    database_name_cache.insert(std::make_pair(database_object->database_name,
                                              cached_object->database_oid));
    return true;
  } else {
    return false;
  }
}

/*@brief   evict database catalog object from cache
* @param   database_oid
* @return  true if database_oid is found and evicted; false if not found
*/
bool CatalogCache::EvictDatabaseObject(oid_t database_oid) {
  // std::lock_guard<std::mutex> lock(database_cache_lock);
  auto it = database_objects_cache.find(database_oid);
  if (it == database_objects_cache.end()) {
    return false;
  } else {
    database_name_cache.erase(it->second->database_name);
    database_objects_cache.erase(it);
    return true;
  }
}

/*@brief   get database catalog object from cache
* @param   database_oid
* @return  database catalog object; if not found return object with invalid oid
*/
std::shared_ptr<DatabaseCatalogObject> CatalogCache::GetDatabaseObject(
    oid_t database_oid) {
  // std::lock_guard<std::mutex> lock(database_cache_lock);
  auto it = database_objects_cache.find(database_oid);
  if (it == database_objects_cache.end()) {
    return nullptr;
  }
  return it->second;
}

/*@brief   get database catalog object from cache
* @param   database_name
* @return  database catalog object; if not found return object with invalid oid
*/
std::shared_ptr<DatabaseCatalogObject> CatalogCache::GetDatabaseObject(
    const std::string &database_name) {
  // std::lock_guard<std::mutex> lock(database_cache_lock);
  auto it = database_name_cache.find(database_name);
  if (it == database_name_cache.end()) {
    return nullptr;
  }
  oid_t database_oid = it->second;
  return database_objects_cache.find(database_oid)->second;
}

/*@brief   insert table catalog object into cache
* @param   table_object
* @param   forced   if forced, replace existing object, else return false if oid
*          already exists
* @return  false only if not forced and table_oid already exists in cache
*/
bool CatalogCache::InsertTableObject(
    std::shared_ptr<TableCatalogObject> table_object, bool forced) {
  if (!table_object || table_object->table_oid == INVALID_OID) {
    return false;  // invalid object
  }

  // find old table catalog object
  // std::lock_guard<std::mutex> lock(table_cache_lock);
  auto it = table_objects_cache.find(table_object->table_oid);

  // forced evict if found
  if (forced == true && it != table_objects_cache.end()) {
    if (it->second == table_object) return false;  // no need to replace
    EvictTableObject(table_object->table_oid);     // evict old
    it = table_objects_cache.find(table_object->table_oid);
  }

  // insert into table object cache
  if (it == table_objects_cache.end()) {
    table_objects_cache.insert(
        std::make_pair(table_object->table_oid, table_object));
    // find and insert into database catalog object too
    auto database_object = GetDatabaseObject(table_object->database_oid);
    if (database_object) {
      database_object->InsertTableObject(table_object, forced);
    }
    return true;
  } else {
    return false;  // table oid already exists
  }
}

/*@brief   evict table catalog object from cache
* @param   table_oid
* @return  true if table_oid is found and evicted; false if not found
*/
bool CatalogCache::EvictTableObject(oid_t table_oid) {
  if (table_oid == INVALID_OID) return false;
  // std::lock_guard<std::mutex> lock(table_cache_lock);

  // find table oid from catalog cache
  auto it = table_objects_cache.find(table_oid);
  if (it != table_objects_cache.end()) {
    auto table_object = it->second;
    table_objects_cache.erase(it);
    if (table_object) {
      // find and evict table name from database object's cache
      auto database_object = GetDatabaseObject(table_object->database_oid);
      if (database_object) {
        database_object->EvictTableObject(
            table_object->table_name);  // evict old name
      }
    }
    return true;
  } else {
    return false;  // table oid not found in cache
  }
}

/*@brief   get table catalog object from cache
* @param   table_oid
* @return  table catalog object; if not found return object with invalid oid
*/
std::shared_ptr<TableCatalogObject> CatalogCache::GetTableObject(
    oid_t table_oid) {
  // std::lock_guard<std::mutex> lock(table_cache_lock);
  auto it = table_objects_cache.find(table_oid);
  if (it == table_objects_cache.end()) {
    // if (txn == nullptr) return TableCatalogObject();
    // bool success = InsertTableObject(
    //     TableCatalog::GetInstance()->GetTableObject(table_oid, txn));
    // PL_ASSERT(success == true);
    // it = table_objects_cache.find(table_oid)
    return nullptr;
  }
  return it->second;
}

}  // namespace catalog
}  // namespace peloton
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008 James Molloy, Jörg Pfähler, Matthew Iselin
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <Debugger.h>

#include <DebuggerIO.h>
#include <LocalIO.h>
#include <SerialIO.h>

#include <utilities/StaticString.h>

#include <processor/Processor.h>
#include <machine/Machine.h>

#include <Log.h>
#include <utilities/utility.h>

#include <panic.h>

void _assert(bool b, const char *file, int line, const char *func)
{
    if(b)
        return;

    ERROR("Assertion failed in file " << file << " (line " << Dec << line << Hex << ")");
    ERROR("In function '" << func << "'.");
    Processor::breakpoint();

    ERROR("You may not resume after a failed assertion.");

    // Best reason for a return is that the debugger isn't active. Either way, it's an error condition, panic.
    panic("assertion failed");
    Processor::halt();
}
<commit_msg>Make sure assertion failure messages don't put really important information such as line numbers past the 80 character limit.<commit_after>/*
 * Copyright (c) 2008 James Molloy, Jörg Pfähler, Matthew Iselin
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <Debugger.h>

#include <DebuggerIO.h>
#include <LocalIO.h>
#include <SerialIO.h>

#include <utilities/StaticString.h>

#include <processor/Processor.h>
#include <machine/Machine.h>

#include <Log.h>
#include <utilities/utility.h>

#include <panic.h>

void _assert(bool b, const char *file, int line, const char *func)
{
    if(b)
        return;

    ERROR("Assertion failed in file " << file);
    ERROR("In function '" << func << "'");
    ERROR("On line " << Dec << line << Hex << ".");
    Processor::breakpoint();

    ERROR("You may not resume after a failed assertion.");

    // Best reason for a return is that the debugger isn't active. Either way, it's an error condition, panic.
    panic("assertion failed");
    Processor::halt();
}
<|endoftext|>


<commit_before>/*
// License Agreement (3-clause BSD License)
// Copyright (c) 2015, Klaus Haag, all rights reserved.
// Third party copyrights and patents are property of their respective owners.
//
// 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 names of the copyright holders nor the names of the 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 copyright holders 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 KCF_DEBUG_HPP_
#define KCF_DEBUG_HPP_

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include <iostream>
#include <fstream>

#include "tracker_debug.hpp"

namespace cf_tracking
{
    template<typename T>
    class KcfDebug : public TrackerDebug
    {
    public:
        KcfDebug() :
            _maxResponse(0),
            _psrClamped(0)
        {}

        virtual ~KcfDebug()
        {
            if (_outputFile.is_open())
                _outputFile.close();
        }

        virtual void init(std::string outputFilePath)
        {
            namedWindow(_SUB_WINDOW_TITLE, cv::WINDOW_NORMAL);
            namedWindow(_RESPONSE_TITLE, cv::WINDOW_NORMAL);
            _outputFile.open(outputFilePath.c_str());
        }

        virtual void printOnImage(cv::Mat& image)
        {
            _ss.str("");
            _ss.clear();
            _ss << "Max Response: " << _maxResponse;
            putText(image, _ss.str(), cv::Point(20, 40), cv::FONT_HERSHEY_TRIPLEX, 0.5, cv::Scalar(255, 0, 0));

            _ss.str("");
            _ss.clear();
            _ss << "PSR Clamped: " << _psrClamped;
            putText(image, _ss.str(), cv::Point(20, 80), cv::FONT_HERSHEY_TRIPLEX, 0.5, cv::Scalar(255, 0, 0));
        }

        virtual void printConsoleOutput()
        {
        }

        virtual void printToFile()
        {
            _outputFile << _maxResponse << "," << _psrClamped << std::endl;
        }

        void showPatch(const cv::Mat& patchResized)
        {
            imshow(_SUB_WINDOW_TITLE, patchResized);
        }

        void setPsr(T psrClamped)
        {
            _psrClamped = psrClamped;
            std::cout << "PSR: " << psrClamped << std::endl;
        }

        void showResponse(const cv::Mat& response, T maxResponse)
        {
            cv::Mat responseOutput = response.clone();
            _maxResponse = maxResponse;
            imshow(_RESPONSE_TITLE, responseOutput);
        }

    private:
        const std::string _SUB_WINDOW_TITLE = "Sub Window";
        const std::string _RESPONSE_TITLE = "Response";
        T _maxResponse;
        T _psrClamped;
        std::stringstream _ss;
        std::ofstream _outputFile;
    };
}

#endif
<commit_msg>even more embedded changes<commit_after>/*
// License Agreement (3-clause BSD License)
// Copyright (c) 2015, Klaus Haag, all rights reserved.
// Third party copyrights and patents are property of their respective owners.
//
// 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 names of the copyright holders nor the names of the 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 copyright holders 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 KCF_DEBUG_HPP_
#define KCF_DEBUG_HPP_

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include <iostream>
#include <fstream>

#include "tracker_debug.hpp"

namespace cf_tracking
{
    template<typename T>
    class KcfDebug : public TrackerDebug
    {
    public:
        KcfDebug() :
            _maxResponse(0),
            _psrClamped(0),
            _SUB_WINDOW_TITLE("Sub Window"),
            _RESPONSE_TITLE("Response")
        {}

        virtual ~KcfDebug()
        {
            if (_outputFile.is_open())
                _outputFile.close();
        }

        virtual void init(std::string outputFilePath)
        {
            namedWindow(_SUB_WINDOW_TITLE, cv::WINDOW_NORMAL);
            namedWindow(_RESPONSE_TITLE, cv::WINDOW_NORMAL);
            _outputFile.open(outputFilePath.c_str());
        }

        virtual void printOnImage(cv::Mat& image)
        {
            _ss.str("");
            _ss.clear();
            _ss << "Max Response: " << _maxResponse;
            putText(image, _ss.str(), cv::Point(20, 40), cv::FONT_HERSHEY_TRIPLEX, 0.5, cv::Scalar(255, 0, 0));

            _ss.str("");
            _ss.clear();
            _ss << "PSR Clamped: " << _psrClamped;
            putText(image, _ss.str(), cv::Point(20, 80), cv::FONT_HERSHEY_TRIPLEX, 0.5, cv::Scalar(255, 0, 0));
        }

        virtual void printConsoleOutput()
        {
        }

        virtual void printToFile()
        {
            _outputFile << _maxResponse << "," << _psrClamped << std::endl;
        }

        void showPatch(const cv::Mat& patchResized)
        {
            imshow(_SUB_WINDOW_TITLE, patchResized);
        }

        void setPsr(T psrClamped)
        {
            _psrClamped = psrClamped;
            std::cout << "PSR: " << psrClamped << std::endl;
        }

        void showResponse(const cv::Mat& response, T maxResponse)
        {
            cv::Mat responseOutput = response.clone();
            _maxResponse = maxResponse;
            imshow(_RESPONSE_TITLE, responseOutput);
        }

    private:
        const std::string _SUB_WINDOW_TITLE;
        const std::string _RESPONSE_TITLE;
        T _maxResponse;
        T _psrClamped;
        std::stringstream _ss;
        std::ofstream _outputFile;
    };
}

#endif
<|endoftext|>


<commit_before>#ifndef VARIADIC_TEMPLATES_HPP
#define VARIADIC_TEMPLATES_HPP

/*
We need to implement variadic template function that takes arbitrary number
of arguments of unknown types and it should return sum of the arguments with
type int.
*/

#include <iostream>

namespace Templates::VariadicTemplates {

template<typename... Args>
int CalcInts() {
    return 0;
}

template<typename T, typename... Args>
int CalcInts(T /*value*/, Args... args) {
    return 0 + CalcInts(args...);
}

template<typename... Args>
int CalcInts(int /*value*/, Args... args) {
    return 1 + CalcInts(args...);
}

template<typename T>
int CalcInts(T /*value*/) {
    return 0;
}

template<>
int CalcInts<int>(int /*value*/) {
    return 1;
}

void SumIntegersViaVariadicTemplate() {
    std::cout << "Take 1: " << CalcInts() << std::endl;
    std::cout << "Take 2: " << CalcInts(1) << std::endl;
    std::cout << "Take 3: " << CalcInts("abc") << std::endl;
    std::cout << "Take 4: " << CalcInts(1, 2) << std::endl;
    std::cout << "Take 5: " << CalcInts("ab", 2) << std::endl;
    std::cout << "Take 6: " << CalcInts(5, "ab", 2) << std::endl;
}

void Start() {
    SumIntegersViaVariadicTemplate();
}

}

#endif // VARIADIC_TEMPLATES_HPP
<commit_msg>Fix variadic template examples<commit_after>#ifndef VARIADIC_TEMPLATES_HPP
#define VARIADIC_TEMPLATES_HPP

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

namespace Templates::VariadicTemplates {

/*
We need a function that accept unknown number of parameters, convert them
to strings and return vector of these strings
*/

// Template function that transform argument to a string
template<typename T>
std::string ToStringImpl(const T& value) {
    std::stringstream ss;
    ss << value;
    return ss.str();
}

// Base case of the variadic template - no args
std::vector<std::string> ToString() {
    return {};
}

// Variadic template that accepts unknown number of args, pass them to
// ToStringImpl() and put result into a vector
template<typename T, typename... Args>
std::vector<std::string> ToString(const T& value, const Args& ... args) {
    std::vector<std::string> vec;
    vec.push_back(ToStringImpl(value));

    const auto remainder = ToString(args...);
    vec.insert(vec.end(), remainder.begin(), remainder.end());
    return vec;
}

// Simplified solution
template<typename... Args>
std::vector<std::string> ToStringSimplified(const Args& ... args) {
    return { ToStringImpl(args)... };
}

void TransformValuesToStrings() {
    const auto strings = ToString(1, "hello", 7.1);
    for (const auto& s : strings) {
        std::cout << s << std::endl;
    }

    const auto strings2 = ToString("world", 'a');
    for (const auto& s : strings2) {
        std::cout << s << std::endl;
    }
}

/*
We need to implement variadic template function that takes arbitrary number
of arguments of unknown types and it should return sum of the arguments with
type int.
*/

int DetectInt(int /*value*/) {
    return 1;
}

template<typename T>
int DetectInt(T /*value*/) {
    return 0;
}

int CalcInts() {
    return 0;
}

template<typename T, typename... Args>
int CalcInts(T value, Args... args) {
    return DetectInt(value) + CalcInts(args...);
}

void SumIntegersViaVariadicTemplate() {
    std::cout << "Take 1: " << CalcInts() << std::endl;
    std::cout << "Take 2: " << CalcInts(1) << std::endl;
    std::cout << "Take 3: " << CalcInts("abc") << std::endl;
    std::cout << "Take 4: " << CalcInts(1, 2) << std::endl;
    std::cout << "Take 5: " << CalcInts("ab", 2) << std::endl;
    std::cout << "Take 6: " << CalcInts(5, "ab", 2, 3) << std::endl;
}

void Start() {
    TransformValuesToStrings();
    SumIntegersViaVariadicTemplate();
}

}

#endif // VARIADIC_TEMPLATES_HPP
<|endoftext|>