<commit_before>//
// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved.
//
#include "top.hpp"
#include "codegen.hpp"
#include "utils/libUtils.h"
#include "os/os.hpp"
#include "jit/src/jit.hpp"
#include "utils/target_mappings.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/CommandLine.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <memory>

using namespace amdcl;
using namespace llvm;

static std::string aclGetCodegenName(const aclTargetInfo &tgtInfo)
{
  assert(tgtInfo.arch_id <= aclLast && "Unknown device id!");
  const FamilyMapping *family = familySet + tgtInfo.arch_id;
  if (!family) return "";

  assert((tgtInfo.chip_id) < family->children_size && "Unknown family id!");
  const TargetMapping *target = &family->target[tgtInfo.chip_id];
  return (target) ? target->codegen_name : "";
}

/*! Function that modifies the code gen level based on the
 * function size threshhold.
 */
static CodeGenOpt::Level
AdjustCGOptLevel(Module& M, CodeGenOpt::Level OrigOLvl)
{
  const unsigned int FuncSizeThreshold = 10000;
  if (OrigOLvl == CodeGenOpt::None)
    return OrigOLvl;
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    Function *F = (Function *)I;
    if (F->size() > FuncSizeThreshold) {
      return CodeGenOpt::None;
    }
  }
  return OrigOLvl;
}

int
llvmCodeGen(
    Module* Composite,
    amd::option::Options *OptionsObj,
    std::string& output,
    aclBinary* binary)
{
  const FamilyMapping &familyMap = familySet[binary->target.arch_id];
  const bool optimize = (OptionsObj ? (OptionsObj->oVariables->OptLevel > 0) : true);
  const TargetMapping* targetMap = familyMap.target;
  unsigned famID = binary->target.chip_id;
  if (!targetMap || !targetMap[famID].supported) {
    LogError("Device is not supported by code generator!");
    return 1;
  }

#if 1 || LLVM_TRUNK_INTEGRATION_CL >= 1463
#else
  // a dirty way to guarantee "push bp" inserted by CodeGen in prologue
  llvm::NoFramePointerElim = !optimize;
#endif
  // Load the module to be compiled...
  Module &mod = *Composite;

  // FIXME: The triple given in this map is wrong and isn't really
  // useful. Only need the architecture.
  const std::string TargetTriple = std::string(familyMap.triple);
  Triple TheTriple(TargetTriple);
  if (TheTriple.getTriple().empty()) {
    TheTriple.setTriple(sys::getDefaultTargetTriple());
  }

  Triple::ArchType arch = TheTriple.getArch();

  bool isGPU = (arch == Triple::amdil || arch == Triple::amdil64 ||
                arch == Triple::hsail || arch == Triple::hsail64);

  if (isGPU) {
    TheTriple.setOS(Triple::UnknownOS);
  } else { // CPUs
    // FIXME: This should come from somewhere else.
#ifdef __linux__
    TheTriple.setOS(Triple::Linux);
#else
    TheTriple.setOS(Triple::MinGW32);
#endif
  }

  TheTriple.setEnvironment(Triple::AMDOpenCL);
  // FIXME: need to make AMDOpenCL be the same as ELF
  if (OptionsObj->oVariables->UseJIT)
    TheTriple.setEnvironment(Triple::ELF);
  mod.setTargetTriple(TheTriple.getTriple());

  // Allocate target machine.  First, check whether the user has explicitly
  // specified an architecture to compile for. If so we have to look it up by
  // name, because it might be a backend that has no mapping to a target triple.
  const Target *TheTarget = 0;
  assert(binary->target.arch_id != aclError && "Cannot have the error device!");

  std::string MArch = familyMap.architecture;

#ifdef WITH_TARGET_HSAIL
  if (MArch == "hsail" && OptionsObj->oVariables->GPU64BitIsa) {
    MArch = std::string("hsail-64");
  }
#endif

  for (TargetRegistry::iterator it = TargetRegistry::begin(),
      ie = TargetRegistry::end(); it != ie; ++it) {
    if (MArch == it->getName()) {
      TheTarget = &*it;
      break;
    }
  }

  if (!TheTarget) {
    errs() << ": ERROR: invalid target '" << MArch << "'.\n";
    return 1;
  }

  CodeGenOpt::Level OLvl = CodeGenOpt::None;
  switch (OptionsObj->oVariables->OptLevel) {
    case 0: // -O0
      OLvl = CodeGenOpt::None;
      break;
    case 1: // -O1
      OLvl = CodeGenOpt::Less;
      break;
    default:
      assert(!"Error with optimization level");
    case 2: // -O2
    case 5: // -O5(-Os)
      OLvl = CodeGenOpt::Default;
      break;
    case 3: // -O3
    case 4: // -O4
      OLvl = CodeGenOpt::Aggressive;
      break;
  };

  // If there is a very big function, lower the optimization level.
  OLvl = AdjustCGOptLevel(mod, OLvl);

  // Adjust the triple to match (if known), otherwise stick with the
  // module/host triple.
  Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
  if (Type != Triple::UnknownArch)
    TheTriple.setArch(Type);

  // Package up features to be passed to target/subtarget
  std::string FeatureStr;
  if ((Type == Triple::amdil || Type == Triple::amdil64) &&
      targetMap[famID].chip_options) {
    uint64_t y = targetMap[famID].chip_options;
    for (uint64_t x = 0; y != 0; y >>= 1, ++x) {
      if (!(y & 0x1) && (x >= 11 && x < 16)) {
        continue;
      }

      if ((1 << x) == F_NO_ALIAS) {
        FeatureStr += (!OptionsObj->oVariables->AssumeAlias ? '+' : '-');
      } else if ((1 << x) == F_STACK_UAV) {
        FeatureStr += (OptionsObj->oVariables->UseStackUAV ? '+' : '-');
      } else if ((1 << x) == F_MACRO_CALL) {
        FeatureStr += (OptionsObj->oVariables->UseMacroForCall ? '+' : '-');
      } else if ((1 << x) == F_64BIT_PTR) {
        FeatureStr += (binary->target.arch_id == aclAMDIL64) ? '+' : '-';
      } else {
        FeatureStr += ((y & 0x1) ? '+' : '-');
      }

      FeatureStr += GPUCodeGenFlagTable[x];
      if (y != 0x1) {
        FeatureStr += ',';
      }
    }
  }

  if (Type == Triple::amdil64) {
      if (OptionsObj->oVariables->SmallGlobalObjects)
          FeatureStr += ",+small-global-objects";
  }

#if 1 || LLVM_TRUNK_INTEGRATION_CL >= 1463
    llvm::TargetOptions targetOptions;
    targetOptions.NoFramePointerElim = false;
    targetOptions.StackAlignmentOverride =
      OptionsObj->oVariables->CPUStackAlignment;
    // jgolds
    //targetOptions.EnableEBB = (optimize && OptionsObj->oVariables->CGEBB);
    //targetOptions.EnableBFO = OptionsObj->oVariables->CGBFO;
    //targetOptions.NoExcessFPPrecision = !OptionsObj->oVariables->EnableFMA;

    // Don't allow unsafe optimizations for CPU because the library
    // contains code that is not safe.  See bug 9567.
    if (isGPU)
        targetOptions.UnsafeFPMath = OptionsObj->oVariables->UnsafeMathOpt;
    targetOptions.LessPreciseFPMADOption = OptionsObj->oVariables->MadEnable ||
                                           OptionsObj->oVariables->EnableMAD;
    targetOptions.NoInfsFPMath = OptionsObj->oVariables->FiniteMathOnly;
    // Need to add a support for OptionsObj->oVariables->NoSignedZeros,
    targetOptions.NoNaNsFPMath = OptionsObj->oVariables->FastRelaxedMath;

    std::auto_ptr<TargetMachine>
        target(TheTarget->createTargetMachine(TheTriple.getTriple(),
	       aclGetCodegenName(binary->target), FeatureStr, targetOptions,
        WINDOWS_SWITCH(Reloc::DynamicNoPIC, Reloc::PIC_),
        CodeModel::Default, OLvl));
#else
  std::auto_ptr<TargetMachine>
  target(TheTarget->createTargetMachine(TheTriple.getTriple(),
        aclGetCodegenName(binary->target), FeatureStr,
        WINDOWS_SWITCH(Reloc::DynamicNoPIC, Reloc::PIC_),
        CodeModel::Default));
  assert(target.get() && "Could not allocate target machine!");
#endif

  // MCJIT(Jan)
  if(!isGPU && OptionsObj->oVariables->UseJIT) {
    TargetMachine* jittarget(TheTarget->createTargetMachine(TheTriple.getTriple(),
	       aclGetCodegenName(binary->target), FeatureStr, targetOptions,
        WINDOWS_SWITCH(Reloc::DynamicNoPIC, Reloc::PIC_),
        CodeModel::Default, OLvl));

    std::string ErrStr = jitCodeGen(Composite, jittarget, OLvl, output);

    if (!ErrStr.empty()) {
      LogError("MCJIT failed to generate code");
      LogError(ErrStr.c_str());
      return 1;
    }
    return 0;
  }

  TargetMachine &Target = *target;

  // Figure out where we are going to send the output...
  raw_string_ostream *RSOut = new raw_string_ostream(output);
  formatted_raw_ostream *Out = new formatted_raw_ostream(*RSOut, formatted_raw_ostream::DELETE_STREAM);
  if (Out == 0) {
    LogError("llvmCodeGen couldn't create an output stream");
    return 1;
  }

  // Build up all of the passes that we want to do to the module or function or
  // Basic Block.
  PassManager Passes;

  // Add the target data from the target machine, if it exists, or the module.
  if (const DataLayout *TD = Target.getDataLayout())
    Passes.add(new DataLayout(*TD));
  else
    Passes.add(new DataLayout(&mod));

  // Override default to generate verbose assembly, if the device is not the GPU.
  // The GPU sets this in AMDILTargetMachine.cpp.
  if (familyMap.target == (const TargetMapping*)&X86TargetMapping ||
#if WITH_VERSION_0_9
      familyMap.target == (const TargetMapping*)&A32TargetMapping ||
      familyMap.target == (const TargetMapping*)&A32TargetMapping ||
#elif WITH_VERSION_0_8
#else
#error "The current version implementation was not implemented here."
#endif
      familyMap.target == (const TargetMapping*)&X64TargetMapping
      ) {
    Target.setAsmVerbosityDefault(true);
  }

#ifdef WITH_TARGET_HSAIL
  if (isHSAILTarget(binary->target)) {
    if (Target.addPassesToEmitFile(Passes, *Out, TargetMachine::CGFT_ObjectFile, true)) {
      delete Out;
      return 1;
    }
  } else
#endif
  {
#ifndef NDEBUG
#if 1 || LLVM_TRUNK_INTEGRATION_CL >= 1144
    if (Target.addPassesToEmitFile(Passes, *Out, TargetMachine::CGFT_AssemblyFile, false))
#else
    if (Target.addPassesToEmitFile(Passes, *Out, TargetMachine::CGFT_AssemblyFile, OLvl, false))
#endif
#else
#if 1 || LLVM_TRUNK_INTEGRATION_CL >= 1144
    if (Target.addPassesToEmitFile(Passes, *Out, TargetMachine::CGFT_AssemblyFile, true))
#else
    if (Target.addPassesToEmitFile(Passes, *Out, TargetMachine::CGFT_AssemblyFile, OLvl, true))
#endif
#endif
    {
      delete Out;
      return 1;
    }
  }

  Passes.run(mod);

  delete Out;
  return 0;
}

  int
CLCodeGen::codegen(llvm::Module *input)
{
  uint64_t time_cg = 0ULL;
  if (Options()->oVariables->EnableBuildTiming) {
    time_cg = amd::Os::timeNanos();
  }
  llvmbinary_ = input;
  amdcl::CompilerStage *cs = reinterpret_cast<amdcl::CompilerStage*>(this);
  if (!isHSAILTarget(cs->Elf()->target)) {
    setWholeProgram(true);
  }

  int ret = llvmCodeGen(LLVMBinary(), Options(), Source(), Elf());

  if (Options()->oVariables->EnableBuildTiming) {
    time_cg = amd::Os::timeNanos() - time_cg;
    std::stringstream tmp_ss;
    tmp_ss << "    LLVM CodeGen time: "
      << time_cg/1000ULL
      << "us\n";
    appendLogToCL(CL(), tmp_ss.str());
  }
  if (!Source().empty() && Options()->isDumpFlagSet(amd::option::DUMP_CGIL)) {
    std::string ilFileName = Options()->getDumpFileName(".il");
    std::fstream f;
    f.open(ilFileName.c_str(), (std::fstream::out | std::fstream::binary));
    f.write(Source().data(), Source().length());
    f.close();
  }

  return ret;
}
<commit_msg>P4 to Git Change 1087805 by yaxunl@yaxunl_stg_win50 on 2014/10/15 16:07:03<commit_after>//
// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved.
//
#include "top.hpp"
#include "codegen.hpp"
#include "utils/libUtils.h"
#include "os/os.hpp"
#include "jit/src/jit.hpp"
#include "utils/target_mappings.h"
#ifdef _MSC_VER
/* for disabling warning in llvm/ADT/Statistic.h */
#pragma warning(disable:4146)
#endif
#include "llvm/ADT/Statistic.h"
#ifdef _MSC_VER
#pragma warning(default:4146)
#endif
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/CommandLine.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <memory>

using namespace amdcl;
using namespace llvm;

static std::string aclGetCodegenName(const aclTargetInfo &tgtInfo)
{
  assert(tgtInfo.arch_id <= aclLast && "Unknown device id!");
  const FamilyMapping *family = familySet + tgtInfo.arch_id;
  if (!family) return "";

  assert((tgtInfo.chip_id) < family->children_size && "Unknown family id!");
  const TargetMapping *target = &family->target[tgtInfo.chip_id];
  return (target) ? target->codegen_name : "";
}

/*! Function that modifies the code gen level based on the
 * function size threshhold.
 */
static CodeGenOpt::Level
AdjustCGOptLevel(Module& M, CodeGenOpt::Level OrigOLvl)
{
  const unsigned int FuncSizeThreshold = 10000;
  if (OrigOLvl == CodeGenOpt::None)
    return OrigOLvl;
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    Function *F = (Function *)I;
    if (F->size() > FuncSizeThreshold) {
      return CodeGenOpt::None;
    }
  }
  return OrigOLvl;
}

int
llvmCodeGen(
    Module* Composite,
    amd::option::Options *OptionsObj,
    std::string& output,
    aclBinary* binary)
{
  const FamilyMapping &familyMap = familySet[binary->target.arch_id];
  const bool optimize = (OptionsObj ? (OptionsObj->oVariables->OptLevel > 0) : true);
  const TargetMapping* targetMap = familyMap.target;
  unsigned famID = binary->target.chip_id;
  if (!targetMap || !targetMap[famID].supported) {
    LogError("Device is not supported by code generator!");
    return 1;
  }

#if 1 || LLVM_TRUNK_INTEGRATION_CL >= 1463
#else
  // a dirty way to guarantee "push bp" inserted by CodeGen in prologue
  llvm::NoFramePointerElim = !optimize;
#endif
  // Load the module to be compiled...
  Module &mod = *Composite;

  // FIXME: The triple given in this map is wrong and isn't really
  // useful. Only need the architecture.
  const std::string TargetTriple = std::string(familyMap.triple);
  Triple TheTriple(TargetTriple);
  if (TheTriple.getTriple().empty()) {
    TheTriple.setTriple(sys::getDefaultTargetTriple());
  }

  Triple::ArchType arch = TheTriple.getArch();

  bool isGPU = (arch == Triple::amdil || arch == Triple::amdil64 ||
                arch == Triple::hsail || arch == Triple::hsail64);

  if (isGPU) {
    TheTriple.setOS(Triple::UnknownOS);
  } else { // CPUs
    // FIXME: This should come from somewhere else.
#ifdef __linux__
    TheTriple.setOS(Triple::Linux);
#else
    TheTriple.setOS(Triple::MinGW32);
#endif
  }

  TheTriple.setEnvironment(Triple::AMDOpenCL);
  // FIXME: need to make AMDOpenCL be the same as ELF
  if (OptionsObj->oVariables->UseJIT)
    TheTriple.setEnvironment(Triple::ELF);
  mod.setTargetTriple(TheTriple.getTriple());

  // Allocate target machine.  First, check whether the user has explicitly
  // specified an architecture to compile for. If so we have to look it up by
  // name, because it might be a backend that has no mapping to a target triple.
  const Target *TheTarget = 0;
  assert(binary->target.arch_id != aclError && "Cannot have the error device!");

  std::string MArch = familyMap.architecture;

#ifdef WITH_TARGET_HSAIL
  if (MArch == "hsail" && OptionsObj->oVariables->GPU64BitIsa) {
    MArch = std::string("hsail-64");
  }
#endif

  for (TargetRegistry::iterator it = TargetRegistry::begin(),
      ie = TargetRegistry::end(); it != ie; ++it) {
    if (MArch == it->getName()) {
      TheTarget = &*it;
      break;
    }
  }

  if (!TheTarget) {
    errs() << ": ERROR: invalid target '" << MArch << "'.\n";
    return 1;
  }

  CodeGenOpt::Level OLvl = CodeGenOpt::None;
  switch (OptionsObj->oVariables->OptLevel) {
    case 0: // -O0
      OLvl = CodeGenOpt::None;
      break;
    case 1: // -O1
      OLvl = CodeGenOpt::Less;
      break;
    default:
      assert(!"Error with optimization level");
    case 2: // -O2
    case 5: // -O5(-Os)
      OLvl = CodeGenOpt::Default;
      break;
    case 3: // -O3
    case 4: // -O4
      OLvl = CodeGenOpt::Aggressive;
      break;
  };

  // If there is a very big function, lower the optimization level.
  OLvl = AdjustCGOptLevel(mod, OLvl);

  // Adjust the triple to match (if known), otherwise stick with the
  // module/host triple.
  Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
  if (Type != Triple::UnknownArch)
    TheTriple.setArch(Type);

  // Package up features to be passed to target/subtarget
  std::string FeatureStr;
  if ((Type == Triple::amdil || Type == Triple::amdil64) &&
      targetMap[famID].chip_options) {
    uint64_t y = targetMap[famID].chip_options;
    for (uint64_t x = 0; y != 0; y >>= 1, ++x) {
      if (!(y & 0x1) && (x >= 11 && x < 16)) {
        continue;
      }

      if ((1 << x) == F_NO_ALIAS) {
        FeatureStr += (!OptionsObj->oVariables->AssumeAlias ? '+' : '-');
      } else if ((1 << x) == F_STACK_UAV) {
        FeatureStr += (OptionsObj->oVariables->UseStackUAV ? '+' : '-');
      } else if ((1 << x) == F_MACRO_CALL) {
        FeatureStr += (OptionsObj->oVariables->UseMacroForCall ? '+' : '-');
      } else if ((1 << x) == F_64BIT_PTR) {
        FeatureStr += (binary->target.arch_id == aclAMDIL64) ? '+' : '-';
      } else {
        FeatureStr += ((y & 0x1) ? '+' : '-');
      }

      FeatureStr += GPUCodeGenFlagTable[x];
      if (y != 0x1) {
        FeatureStr += ',';
      }
    }
  }

  if (Type == Triple::amdil64) {
      if (OptionsObj->oVariables->SmallGlobalObjects)
          FeatureStr += ",+small-global-objects";
  }

#if 1 || LLVM_TRUNK_INTEGRATION_CL >= 1463
    llvm::TargetOptions targetOptions;
    targetOptions.NoFramePointerElim = false;
    targetOptions.StackAlignmentOverride =
      OptionsObj->oVariables->CPUStackAlignment;
    // jgolds
    //targetOptions.EnableEBB = (optimize && OptionsObj->oVariables->CGEBB);
    //targetOptions.EnableBFO = OptionsObj->oVariables->CGBFO;
    //targetOptions.NoExcessFPPrecision = !OptionsObj->oVariables->EnableFMA;

    // Don't allow unsafe optimizations for CPU because the library
    // contains code that is not safe.  See bug 9567.
    if (isGPU)
        targetOptions.UnsafeFPMath = OptionsObj->oVariables->UnsafeMathOpt;
    targetOptions.LessPreciseFPMADOption = OptionsObj->oVariables->MadEnable ||
                                           OptionsObj->oVariables->EnableMAD;
    targetOptions.NoInfsFPMath = OptionsObj->oVariables->FiniteMathOnly;
    // Need to add a support for OptionsObj->oVariables->NoSignedZeros,
    targetOptions.NoNaNsFPMath = OptionsObj->oVariables->FastRelaxedMath;

    std::auto_ptr<TargetMachine>
        target(TheTarget->createTargetMachine(TheTriple.getTriple(),
	       aclGetCodegenName(binary->target), FeatureStr, targetOptions,
        WINDOWS_SWITCH(Reloc::DynamicNoPIC, Reloc::PIC_),
        CodeModel::Default, OLvl));
#else
  std::auto_ptr<TargetMachine>
  target(TheTarget->createTargetMachine(TheTriple.getTriple(),
        aclGetCodegenName(binary->target), FeatureStr,
        WINDOWS_SWITCH(Reloc::DynamicNoPIC, Reloc::PIC_),
        CodeModel::Default));
  assert(target.get() && "Could not allocate target machine!");
#endif

  // MCJIT(Jan)
  if(!isGPU && OptionsObj->oVariables->UseJIT) {
    TargetMachine* jittarget(TheTarget->createTargetMachine(TheTriple.getTriple(),
	       aclGetCodegenName(binary->target), FeatureStr, targetOptions,
        WINDOWS_SWITCH(Reloc::DynamicNoPIC, Reloc::PIC_),
        CodeModel::Default, OLvl));

    std::string ErrStr = jitCodeGen(Composite, jittarget, OLvl, output);

    if (!ErrStr.empty()) {
      LogError("MCJIT failed to generate code");
      LogError(ErrStr.c_str());
      return 1;
    }
    return 0;
  }

  TargetMachine &Target = *target;

  // Figure out where we are going to send the output...
  raw_string_ostream *RSOut = new raw_string_ostream(output);
  formatted_raw_ostream *Out = new formatted_raw_ostream(*RSOut, formatted_raw_ostream::DELETE_STREAM);
  if (Out == 0) {
    LogError("llvmCodeGen couldn't create an output stream");
    return 1;
  }

  // Build up all of the passes that we want to do to the module or function or
  // Basic Block.
  PassManager Passes;

  // Add the target data from the target machine, if it exists, or the module.
  if (const DataLayout *TD = Target.getDataLayout())
    Passes.add(new DataLayout(*TD));
  else
    Passes.add(new DataLayout(&mod));

  // Override default to generate verbose assembly, if the device is not the GPU.
  // The GPU sets this in AMDILTargetMachine.cpp.
  if (familyMap.target == (const TargetMapping*)&X86TargetMapping ||
#if WITH_VERSION_0_9
      familyMap.target == (const TargetMapping*)&A32TargetMapping ||
      familyMap.target == (const TargetMapping*)&A32TargetMapping ||
#elif WITH_VERSION_0_8
#else
#error "The current version implementation was not implemented here."
#endif
      familyMap.target == (const TargetMapping*)&X64TargetMapping
      ) {
    Target.setAsmVerbosityDefault(true);
  }

#ifdef WITH_TARGET_HSAIL
  if (isHSAILTarget(binary->target)) {
    if (Target.addPassesToEmitFile(Passes, *Out, TargetMachine::CGFT_ObjectFile, true)) {
      delete Out;
      return 1;
    }
  } else
#endif
  {
#ifndef NDEBUG
#if 1 || LLVM_TRUNK_INTEGRATION_CL >= 1144
    if (Target.addPassesToEmitFile(Passes, *Out, TargetMachine::CGFT_AssemblyFile, false))
#else
    if (Target.addPassesToEmitFile(Passes, *Out, TargetMachine::CGFT_AssemblyFile, OLvl, false))
#endif
#else
#if 1 || LLVM_TRUNK_INTEGRATION_CL >= 1144
    if (Target.addPassesToEmitFile(Passes, *Out, TargetMachine::CGFT_AssemblyFile, true))
#else
    if (Target.addPassesToEmitFile(Passes, *Out, TargetMachine::CGFT_AssemblyFile, OLvl, true))
#endif
#endif
    {
      delete Out;
      return 1;
    }
  }

  Passes.run(mod);
  llvm::PrintStatistics();
  delete Out;
  return 0;
}

  int
CLCodeGen::codegen(llvm::Module *input)
{
  uint64_t time_cg = 0ULL;
  if (Options()->oVariables->EnableBuildTiming) {
    time_cg = amd::Os::timeNanos();
  }
  llvmbinary_ = input;
  amdcl::CompilerStage *cs = reinterpret_cast<amdcl::CompilerStage*>(this);
  if (!isHSAILTarget(cs->Elf()->target)) {
    setWholeProgram(true);
  }

  int ret = llvmCodeGen(LLVMBinary(), Options(), Source(), Elf());

  if (Options()->oVariables->EnableBuildTiming) {
    time_cg = amd::Os::timeNanos() - time_cg;
    std::stringstream tmp_ss;
    tmp_ss << "    LLVM CodeGen time: "
      << time_cg/1000ULL
      << "us\n";
    appendLogToCL(CL(), tmp_ss.str());
  }
  if (!Source().empty() && Options()->isDumpFlagSet(amd::option::DUMP_CGIL)) {
    std::string ilFileName = Options()->getDumpFileName(".il");
    std::fstream f;
    f.open(ilFileName.c_str(), (std::fstream::out | std::fstream::binary));
    f.write(Source().data(), Source().length());
    f.close();
  }

  return ret;
}
<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 6/14/2020, 3:53:32 AM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
using ld = long double;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1'000'000'007LL};
// constexpr ll MOD{998'244'353LL}; // be careful
constexpr ll MAX_SIZE{3'000'010LL};
// constexpr ll MAX_SIZE{30'000'010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(Mint const &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(Mint const &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(Mint const &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(Mint const &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(Mint const &a) const { return Mint(*this) += a; }
  Mint operator-(Mint const &a) const { return Mint(*this) -= a; }
  Mint operator*(Mint const &a) const { return Mint(*this) *= a; }
  Mint operator/(Mint const &a) const { return Mint(*this) /= a; }
  bool operator<(Mint const &a) const { return x < a.x; }
  bool operator<=(Mint const &a) const { return x <= a.x; }
  bool operator>(Mint const &a) const { return x > a.x; }
  bool operator>=(Mint const &a) const { return x >= a.x; }
  bool operator==(Mint const &a) const { return x == a.x; }
  bool operator!=(Mint const &a) const { return !(*this == a); }
  Mint power(ll N) const
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, Mint<MOD> const &rhs) { return rhs + lhs; }
template <ll MOD>
Mint<MOD> operator-(ll lhs, Mint<MOD> const &rhs) { return -rhs + lhs; }
template <ll MOD>
Mint<MOD> operator*(ll lhs, Mint<MOD> const &rhs) { return rhs * lhs; }
template <ll MOD>
Mint<MOD> operator/(ll lhs, Mint<MOD> const &rhs) { return Mint<MOD>{lhs} / rhs; }
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a) { return stream >> a.x; }
template <ll MOD>
ostream &operator<<(ostream &stream, Mint<MOD> const &a) { return stream << a.x; }
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i{2LL}; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i{1LL}; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- Infty -----
template <typename T>
constexpr T Infty() { return numeric_limits<T>::max(); }
template <typename T>
constexpr T mInfty() { return numeric_limits<T>::min(); }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1'000'000'000'000'010LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

// ----- Solve -----

class Solve
{
  ll W, H, K;

public:
  Solve(ll W, ll H, ll K) : W{W}, H{H}, K{K} {}

  ll answer()
  {
    ll ans{0};
    for (auto y{1LL}; y < H; ++y)
    {
      ans += calc(0, y);
    }
    for (auto s{1LL}; s < W; ++s)
    {
      for (auto y{1LL}; s * y < 2 * K && y < H; ++y)
      {
        ans += calc(s, y);
      }
    }
    return ans;
  }

private:
  ll calc(ll s, ll y)
  {
    ll R{2 * K - H * s + s * y + gcd(s, H) + 2};
    if (R < 0)
    {
      return 0;
    }
    ll ans{min(W - 1, R / H)};
    ll x{R / H + 1};
    if (x <= W - 1 && H * x - gcd(H - y, x) + gcd(y, x + s) <= R)
    {
      ++ans;
    }
    return ans;
  }
};

// ----- main() -----

int main()
{
  ll W, H, K;
  cin >> W >> H >> K;
  Solve solve(W, H, K), solve2(H, W, K);
  ll ans{2 * (solve.answer() + solve2.answer())};
  cout << ans << endl;
}
<commit_msg>tried F.cpp to 'F'<commit_after>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 6/14/2020, 3:53:32 AM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
using ld = long double;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1'000'000'007LL};
// constexpr ll MOD{998'244'353LL}; // be careful
constexpr ll MAX_SIZE{3'000'010LL};
// constexpr ll MAX_SIZE{30'000'010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(Mint const &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(Mint const &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(Mint const &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(Mint const &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(Mint const &a) const { return Mint(*this) += a; }
  Mint operator-(Mint const &a) const { return Mint(*this) -= a; }
  Mint operator*(Mint const &a) const { return Mint(*this) *= a; }
  Mint operator/(Mint const &a) const { return Mint(*this) /= a; }
  bool operator<(Mint const &a) const { return x < a.x; }
  bool operator<=(Mint const &a) const { return x <= a.x; }
  bool operator>(Mint const &a) const { return x > a.x; }
  bool operator>=(Mint const &a) const { return x >= a.x; }
  bool operator==(Mint const &a) const { return x == a.x; }
  bool operator!=(Mint const &a) const { return !(*this == a); }
  Mint power(ll N) const
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, Mint<MOD> const &rhs) { return rhs + lhs; }
template <ll MOD>
Mint<MOD> operator-(ll lhs, Mint<MOD> const &rhs) { return -rhs + lhs; }
template <ll MOD>
Mint<MOD> operator*(ll lhs, Mint<MOD> const &rhs) { return rhs * lhs; }
template <ll MOD>
Mint<MOD> operator/(ll lhs, Mint<MOD> const &rhs) { return Mint<MOD>{lhs} / rhs; }
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a) { return stream >> a.x; }
template <ll MOD>
ostream &operator<<(ostream &stream, Mint<MOD> const &a) { return stream << a.x; }
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i{2LL}; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i{1LL}; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- Infty -----
template <typename T>
constexpr T Infty() { return numeric_limits<T>::max(); }
template <typename T>
constexpr T mInfty() { return numeric_limits<T>::min(); }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1'000'000'000'000'010LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

// ----- Solve -----

class Solve
{
  ll W, H, K;

public:
  Solve(ll W, ll H, ll K) : W{W}, H{H}, K{K} {}

  ll answer()
  {
    ll ans{0};
    for (auto y{1LL}; y < H; ++y)
    {
      ans += calc(0, y);
    }
    for (auto s{1LL}; s < W; ++s)
    {
      for (auto y{1LL}; s * y < 2 * K && y < H; ++y)
      {
        ans += calc(s, y);
      }
    }
    return ans;
  }

private:
  ll calc(ll s, ll y)
  {
    ll R{2 * K - H * s + s * y + gcd(s, H) + 2};
    if (R < 0)
    {
      return 0;
    }
    ll ans{min(W - s - 1, R / H)};
    ll x{R / H + 1};
    if (x + s < W && H * x - gcd(H - y, x) + gcd(y, x + s) <= R)
    {
      ++ans;
    }
    return ans;
  }
};

// ----- main() -----

int main()
{
  ll W, H, K;
  cin >> W >> H >> K;
  Solve solve(W, H, K), solve2(H, W, K);
  ll ans{2 * (solve.answer() + solve2.answer())};
  cout << ans << endl;
}
<|endoftext|>


<commit_before>// This file is part of the dune-hdd project:
//   http://users.dune-project.org/projects/dune-hdd
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_HDD_EXAMPLES_LINEARELLIPTIC_SWIPDG_HH
#define DUNE_HDD_EXAMPLES_LINEARELLIPTIC_SWIPDG_HH

#include <memory>

#include <dune/stuff/common/memory.hh>

#include <dune/hdd/playground/linearelliptic/discreteproblem.hh>
#include <dune/hdd/playground/linearelliptic/discretizations/swipdg.hh>

template< class GridImp >
class LinearellipticExampleSWIPDG
{
public:
  typedef GridImp GridType;
  typedef Dune::HDD::LinearElliptic::DiscreteProblem< GridType > DiscreteProblemType;
  typedef typename DiscreteProblemType::RangeFieldType RangeFieldType;
  static const unsigned int dimRange = DiscreteProblemType::dimRange;
  typedef Dune::HDD::LinearElliptic::Discretizations::SWIPDG< GridType, Dune::Stuff::Grid::ChooseLayer::leaf,
                                                              RangeFieldType, dimRange, 1 > DiscretizationType;

  static std::string static_id()
  {
    return "linearelliptic.swipdg";
  }

  static void write_config_file(const std::string filename = static_id() + ".cfg")
  {
    DiscreteProblemType::write_config(filename, static_id());
  }

  void initialize(const std::vector< std::string > arguments)
  {
    using namespace Dune;
    if (!discrete_problem_) {
      discrete_problem_ = Stuff::Common::make_unique< DiscreteProblemType >(static_id(), arguments);
      const bool debug_logging = discrete_problem_->debug_logging();
      auto& info = DSC_LOG_INFO;
      auto& debug = DSC_LOG_DEBUG;
      discretization_ = Stuff::Common::make_unique< DiscretizationType >(discrete_problem_->grid_provider(),
                                                                         discrete_problem_->boundary_info(),
                                                                         discrete_problem_->problem());
      info << "initializing discretization";
      if (debug_logging)
        info << ":" << std::endl;
      else
        info << "... " << std::flush;
      Dune::Timer timer;
      discretization_->init(debug, "  ");
      if (!debug_logging)
        info << "done (took " << timer.elapsed() << "s)" << std::endl;
    } else
      DSC_LOG_INFO << "initialize has already been called" << std::endl;
  } // ... initialize(...)

  const DiscreteProblemType& discrete_problem() const
  {
    return *discrete_problem_;
  }

  const DiscretizationType& discretization() const
  {
    return *discretization_;
  }

  DiscretizationType* discretization_and_return_ptr() const
  {
    return new DiscretizationType(*discretization_);
  }

private:
  std::unique_ptr< DiscreteProblemType > discrete_problem_;
  std::unique_ptr< DiscretizationType > discretization_;
}; // class LinearellipticExampleSWIPDG

namespace Dune {

// forward grid declaratios
template< int dim, int dimworld, typename _ctype >
class SGrid;

template< int dim >
class YaspGrid;

} // namespace Dune

extern template class LinearellipticExampleSWIPDG< Dune::SGrid< 1, 1 > >;
extern template class LinearellipticExampleSWIPDG< Dune::SGrid< 2, 2 > >;
extern template class LinearellipticExampleSWIPDG< Dune::SGrid< 3, 3 > >;

extern template class LinearellipticExampleSWIPDG< Dune::YaspGrid< 1 > >;
extern template class LinearellipticExampleSWIPDG< Dune::YaspGrid< 2 > >;
extern template class LinearellipticExampleSWIPDG< Dune::YaspGrid< 3 > >;

#endif // DUNE_HDD_EXAMPLES_LINEARELLIPTIC_SWIPDG_HH
<commit_msg>[examples.linearelliptic.swipdg] choose istl backend * way faster than eigen for large systems<commit_after>// This file is part of the dune-hdd project:
//   http://users.dune-project.org/projects/dune-hdd
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_HDD_EXAMPLES_LINEARELLIPTIC_SWIPDG_HH
#define DUNE_HDD_EXAMPLES_LINEARELLIPTIC_SWIPDG_HH

#include <memory>

#include <dune/stuff/common/memory.hh>

#include <dune/hdd/playground/linearelliptic/discreteproblem.hh>
#include <dune/hdd/playground/linearelliptic/discretizations/swipdg.hh>

template< class GridImp >
class LinearellipticExampleSWIPDG
{
public:
  typedef GridImp GridType;
  typedef Dune::HDD::LinearElliptic::DiscreteProblem< GridType > DiscreteProblemType;
  typedef typename DiscreteProblemType::RangeFieldType RangeFieldType;
  static const unsigned int dimRange = DiscreteProblemType::dimRange;
  typedef Dune::HDD::LinearElliptic::Discretizations::SWIPDG
      < GridType, Dune::Stuff::Grid::ChooseLayer::leaf, RangeFieldType, dimRange, 1
      , Dune::GDT::ChooseSpaceBackend::fem_localfunction
      , Dune::Stuff::LA::ChooseBackend::istl_sparse > DiscretizationType;

  static std::string static_id()
  {
    return "linearelliptic.swipdg";
  }

  static void write_config_file(const std::string filename = static_id() + ".cfg")
  {
    DiscreteProblemType::write_config(filename, static_id());
  }

  void initialize(const std::vector< std::string > arguments)
  {
    using namespace Dune;
    if (!discrete_problem_) {
      discrete_problem_ = Stuff::Common::make_unique< DiscreteProblemType >(static_id(), arguments);
      const bool debug_logging = discrete_problem_->debug_logging();
      auto& info = DSC_LOG_INFO;
      auto& debug = DSC_LOG_DEBUG;
      discretization_ = Stuff::Common::make_unique< DiscretizationType >(discrete_problem_->grid_provider(),
                                                                         discrete_problem_->boundary_info(),
                                                                         discrete_problem_->problem());
      info << "initializing discretization";
      if (debug_logging)
        info << ":" << std::endl;
      else
        info << "... " << std::flush;
      Dune::Timer timer;
      discretization_->init(debug, "  ");
      if (!debug_logging)
        info << "done (took " << timer.elapsed() << "s)" << std::endl;
    } else
      DSC_LOG_INFO << "initialize has already been called" << std::endl;
  } // ... initialize(...)

  const DiscreteProblemType& discrete_problem() const
  {
    return *discrete_problem_;
  }

  const DiscretizationType& discretization() const
  {
    return *discretization_;
  }

  DiscretizationType* discretization_and_return_ptr() const
  {
    return new DiscretizationType(*discretization_);
  }

private:
  std::unique_ptr< DiscreteProblemType > discrete_problem_;
  std::unique_ptr< DiscretizationType > discretization_;
}; // class LinearellipticExampleSWIPDG

namespace Dune {

// forward grid declaratios
template< int dim, int dimworld, typename _ctype >
class SGrid;

template< int dim >
class YaspGrid;

} // namespace Dune

extern template class LinearellipticExampleSWIPDG< Dune::SGrid< 1, 1 > >;
extern template class LinearellipticExampleSWIPDG< Dune::SGrid< 2, 2 > >;
extern template class LinearellipticExampleSWIPDG< Dune::SGrid< 3, 3 > >;

extern template class LinearellipticExampleSWIPDG< Dune::YaspGrid< 1 > >;
extern template class LinearellipticExampleSWIPDG< Dune::YaspGrid< 2 > >;
extern template class LinearellipticExampleSWIPDG< Dune::YaspGrid< 3 > >;

#endif // DUNE_HDD_EXAMPLES_LINEARELLIPTIC_SWIPDG_HH
<|endoftext|>


<commit_before>#ifndef ITERTOOLS_SAMPLE_CLASSES_HPP
#define ITERTOOLS_SAMPLE_CLASSES_HPP

#include <iostream>
#include <cstddef>

namespace itertest {
    class MoveOnly {
        private:
            int i; // not an aggregate
        public:
            MoveOnly(int v)
                : i{v}
            { }

            MoveOnly(const MoveOnly&) = delete;
            MoveOnly& operator=(const MoveOnly&) = delete;

            MoveOnly(MoveOnly&& other) noexcept
                : i{other.i}
            { }
            MoveOnly& operator=(MoveOnly&& other) noexcept {
                this->i = other.i;
                return *this;
            }
            friend std::ostream& operator<<(
                    std::ostream& out, const MoveOnly& self) {
                return out << self.i;
            }
    };

    class DerefByValue {
        private:
            static constexpr std::size_t N = 3;
            int array[N] = {0};
        public:
            DerefByValue() = default;

            class Iterator {
                private:
                    int *current;
                public:
                    Iterator() = default;
                    Iterator(int *p)
                        : current{p}
                    { }

                    bool operator!=(const Iterator& other) const {
                        return this->current != other.current;
                    }

                    // for testing, iterator derefences to an int instead of
                    // an int&
                    int operator*() {
                        return *this->current;
                    }

                    Iterator& operator++() {
                        ++this->current;
                        return *this;
                    }
            };

            Iterator begin() {
                return {this->array};
            }

            Iterator end() {
                return {this->array + N};
            }
    };
}
#endif // #ifndef ITERTOOLS_SAMPLE_CLASSES_HPP
<commit_msg>makes MoveOnly less-than comparable<commit_after>#ifndef ITERTOOLS_SAMPLE_CLASSES_HPP
#define ITERTOOLS_SAMPLE_CLASSES_HPP

#include <iostream>
#include <utility>
#include <cstddef>

namespace itertest {
    class MoveOnly {
        private:
            int i; // not an aggregate
        public:
            MoveOnly(int v)
                : i{v}
            { }

            MoveOnly(const MoveOnly&) = delete;
            MoveOnly& operator=(const MoveOnly&) = delete;

            MoveOnly(MoveOnly&& other) noexcept
                : i{other.i}
            { }

            MoveOnly& operator=(MoveOnly&& other) noexcept {
                this->i = other.i;
                return *this;
            }

            // for std::next_permutation compatibility
            friend bool operator<(const MoveOnly& lhs, const MoveOnly& rhs) {
                return lhs.i < rhs.i;
            }

            friend std::ostream& operator<<(
                    std::ostream& out, const MoveOnly& self) {
                return out << self.i;
            }

    };

    class DerefByValue {
        private:
            static constexpr std::size_t N = 3;
            int array[N] = {0};
        public:
            DerefByValue() = default;

            class Iterator {
                private:
                    int *current;
                public:
                    Iterator() = default;
                    Iterator(int *p)
                        : current{p}
                    { }

                    bool operator!=(const Iterator& other) const {
                        return this->current != other.current;
                    }

                    // for testing, iterator derefences to an int instead of
                    // an int&
                    int operator*() {
                        return *this->current;
                    }

                    Iterator& operator++() {
                        ++this->current;
                        return *this;
                    }
            };

            Iterator begin() {
                return {this->array};
            }

            Iterator end() {
                return {this->array + N};
            }
    };
}
#endif // #ifndef ITERTOOLS_SAMPLE_CLASSES_HPP
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "openpagesmanager.h"

#include "centralwidget.h"
#include "helpconstants.h"
#include "helpmanager.h"
#include "helpviewer.h"
#include "openpagesmodel.h"
#include "openpageswidget.h"

#include <QtGui/QComboBox>
#include <QtGui/QTreeView>

#include <QtHelp/QHelpEngineCore>

using namespace Help::Internal;

OpenPagesManager *OpenPagesManager::m_instance = 0;

// -- OpenPagesManager

OpenPagesManager::OpenPagesManager(QObject *parent)
    : QObject(parent)
    , m_comboBox(0)
    , m_model(0)
    , m_openPagesWidget(0)
{
    Q_ASSERT(!m_instance);

    m_instance = this;
    m_model = new OpenPagesModel(this);

    m_openPagesWidget = new OpenPagesWidget(m_model);
    connect(m_openPagesWidget, SIGNAL(setCurrentPage(QModelIndex)), this,
        SLOT(setCurrentPage(QModelIndex)));
    connect(m_openPagesWidget, SIGNAL(closePage(QModelIndex)), this,
        SLOT(closePage(QModelIndex)));
    connect(m_openPagesWidget, SIGNAL(closePagesExcept(QModelIndex)), this,
        SLOT(closePagesExcept(QModelIndex)));

    m_comboBox = new QComboBox;
    m_comboBox->setModel(m_model);
    m_comboBox->setMinimumContentsLength(40);
    connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this,
        SLOT(setCurrentPage(int)));
}

OpenPagesManager &OpenPagesManager::instance()
{
    Q_ASSERT(m_instance);
    return *m_instance;
}

QWidget* OpenPagesManager::openPagesWidget() const
{
    return m_openPagesWidget;
}

QComboBox* OpenPagesManager::openPagesComboBox() const
{
    if (!m_comboBox) {
    }
    return m_comboBox;
}

int OpenPagesManager::pageCount() const
{
    return m_model->rowCount();
}

QStringList splitString(const QVariant &value)
{
    using namespace Help::Constants;
    return value.toString().split(ListSeparator, QString::SkipEmptyParts);
}

void OpenPagesManager::setupInitialPages()
{
    const QHelpEngineCore &engine = HelpManager::helpEngineCore();
    const int option = engine.customValue(QLatin1String("StartOption"),
        Help::Constants::ShowLastPages).toInt();
    QString homePage = engine.customValue(QLatin1String("DefaultHomePage"),
        Help::Constants::AboutBlank).toString();

    int initialPage = 0;
    switch (option) {
        case Help::Constants::ShowHomePage: {
            m_model->addPage(engine.customValue(QLatin1String("HomePage"),
                homePage).toString());
        }   break;

        case Help::Constants::ShowBlankPage: {
            m_model->addPage(QUrl(Help::Constants::AboutBlank));
        }   break;

        case Help::Constants::ShowLastPages: {
            const QStringList &lastShownPageList = splitString(engine
                .customValue(QLatin1String("LastShownPages")));
            const int pageCount = lastShownPageList.count();

            if (pageCount > 0) {
                QStringList zoomFactors = splitString(engine
                    .customValue(QLatin1String("LastShownPagesZoom")));
                while (zoomFactors.count() < pageCount)
                    zoomFactors.append(Help::Constants::DefaultZoomFactor);

                initialPage = engine.customValue(QLatin1String("LastTabPage"), 0).toInt();
                for (int curPage = 0; curPage < pageCount; ++curPage) {
                    const QString &curFile = lastShownPageList.at(curPage);
                    if (engine.findFile(curFile).isValid()
                        || curFile == Help::Constants::AboutBlank) {
                        m_model->addPage(curFile, zoomFactors.at(curPage).toFloat());
                    } else if (curPage <= initialPage && initialPage > 0) {
                        --initialPage;
                    }
                }
            }
        }   break;

        default: break;
    }

    if (m_model->rowCount() == 0)
        m_model->addPage(homePage);

    for (int i = 0; i < m_model->rowCount(); ++i)
        CentralWidget::instance()->addPage(m_model->pageAt(i));

    emit pagesChanged();
    setCurrentPage(initialPage);
}

// -- public slots

HelpViewer *OpenPagesManager::createPage()
{
    return createPage(QUrl(Help::Constants::AboutBlank));
}

HelpViewer *OpenPagesManager::createPageFromSearch(const QUrl &url)
{
    return createPage(url, true);
}

HelpViewer *OpenPagesManager::createPage(const QUrl &url, bool fromSearch)
{
    if (HelpViewer::launchWithExternalApp(url))
        return 0;

    m_model->addPage(url);

    const int index = m_model->rowCount() - 1;
    HelpViewer * const page = m_model->pageAt(index);
    CentralWidget::instance()->addPage(page, fromSearch);

    emit pagesChanged();
    setCurrentPage(index);

    return page;
}

void OpenPagesManager::setCurrentPage(int index)
{
    m_comboBox->setCurrentIndex(index);
    CentralWidget::instance()->setCurrentPage(m_model->pageAt(index));

    selectCurrentPage();    // update the selction inside the tree view
}

void OpenPagesManager::setCurrentPage(const QModelIndex &index)
{
    if (index.isValid()) {
        m_comboBox->setCurrentIndex(index.row());
        CentralWidget::instance()->setCurrentPage(m_model->pageAt(index.row()));
    }
}

void OpenPagesManager::closeCurrentPage()
{
    QModelIndexList indexes = m_openPagesWidget->selectionModel()->selectedRows();
    if (indexes.isEmpty())
        return;
    Q_ASSERT(indexes.count() == 1);
    removePage(indexes.first().row());
}

void OpenPagesManager::closePage(const QModelIndex &index)
{
    if (index.isValid())
        removePage(index.row());
}

void OpenPagesManager::closePagesExcept(const QModelIndex &index)
{
    if (index.isValid()) {
        int i = 0;
        HelpViewer *viewer = m_model->pageAt(index.row());
        while (m_model->rowCount() > 1) {
            if (m_model->pageAt(i) != viewer) {
                removePage(i);
            } else {
                i++;
            }
        }
    }
}

// -- private

void OpenPagesManager::selectCurrentPage()
{
    QItemSelectionModel * selModel = m_openPagesWidget->selectionModel();
    selModel->clearSelection();
    selModel->select(m_model->index(CentralWidget::instance()->currentIndex(), 0),
        QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
    m_openPagesWidget->scrollTo(m_openPagesWidget->currentIndex());
}

void OpenPagesManager::removePage(int index)
{
    Q_ASSERT(m_model->rowCount() > 1);

    m_model->removePage(index);
    CentralWidget::instance()->removePage(index);

    emit pagesChanged();
    selectCurrentPage();    // update the selction inside the tree view
}
<commit_msg>Fix typo and code leftover.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "openpagesmanager.h"

#include "centralwidget.h"
#include "helpconstants.h"
#include "helpmanager.h"
#include "helpviewer.h"
#include "openpagesmodel.h"
#include "openpageswidget.h"

#include <QtGui/QComboBox>
#include <QtGui/QTreeView>

#include <QtHelp/QHelpEngineCore>

using namespace Help::Internal;

OpenPagesManager *OpenPagesManager::m_instance = 0;

// -- OpenPagesManager

OpenPagesManager::OpenPagesManager(QObject *parent)
    : QObject(parent)
    , m_comboBox(0)
    , m_model(0)
    , m_openPagesWidget(0)
{
    Q_ASSERT(!m_instance);

    m_instance = this;
    m_model = new OpenPagesModel(this);

    m_openPagesWidget = new OpenPagesWidget(m_model);
    connect(m_openPagesWidget, SIGNAL(setCurrentPage(QModelIndex)), this,
        SLOT(setCurrentPage(QModelIndex)));
    connect(m_openPagesWidget, SIGNAL(closePage(QModelIndex)), this,
        SLOT(closePage(QModelIndex)));
    connect(m_openPagesWidget, SIGNAL(closePagesExcept(QModelIndex)), this,
        SLOT(closePagesExcept(QModelIndex)));

    m_comboBox = new QComboBox;
    m_comboBox->setModel(m_model);
    m_comboBox->setMinimumContentsLength(40);
    connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this,
        SLOT(setCurrentPage(int)));
}

OpenPagesManager &OpenPagesManager::instance()
{
    Q_ASSERT(m_instance);
    return *m_instance;
}

QWidget* OpenPagesManager::openPagesWidget() const
{
    return m_openPagesWidget;
}

QComboBox* OpenPagesManager::openPagesComboBox() const
{
    return m_comboBox;
}

int OpenPagesManager::pageCount() const
{
    return m_model->rowCount();
}

QStringList splitString(const QVariant &value)
{
    using namespace Help::Constants;
    return value.toString().split(ListSeparator, QString::SkipEmptyParts);
}

void OpenPagesManager::setupInitialPages()
{
    const QHelpEngineCore &engine = HelpManager::helpEngineCore();
    const int option = engine.customValue(QLatin1String("StartOption"),
        Help::Constants::ShowLastPages).toInt();
    QString homePage = engine.customValue(QLatin1String("DefaultHomePage"),
        Help::Constants::AboutBlank).toString();

    int initialPage = 0;
    switch (option) {
        case Help::Constants::ShowHomePage: {
            m_model->addPage(engine.customValue(QLatin1String("HomePage"),
                homePage).toString());
        }   break;

        case Help::Constants::ShowBlankPage: {
            m_model->addPage(QUrl(Help::Constants::AboutBlank));
        }   break;

        case Help::Constants::ShowLastPages: {
            const QStringList &lastShownPageList = splitString(engine
                .customValue(QLatin1String("LastShownPages")));
            const int pageCount = lastShownPageList.count();

            if (pageCount > 0) {
                QStringList zoomFactors = splitString(engine
                    .customValue(QLatin1String("LastShownPagesZoom")));
                while (zoomFactors.count() < pageCount)
                    zoomFactors.append(Help::Constants::DefaultZoomFactor);

                initialPage = engine.customValue(QLatin1String("LastTabPage"), 0).toInt();
                for (int curPage = 0; curPage < pageCount; ++curPage) {
                    const QString &curFile = lastShownPageList.at(curPage);
                    if (engine.findFile(curFile).isValid()
                        || curFile == Help::Constants::AboutBlank) {
                        m_model->addPage(curFile, zoomFactors.at(curPage).toFloat());
                    } else if (curPage <= initialPage && initialPage > 0) {
                        --initialPage;
                    }
                }
            }
        }   break;

        default: break;
    }

    if (m_model->rowCount() == 0)
        m_model->addPage(homePage);

    for (int i = 0; i < m_model->rowCount(); ++i)
        CentralWidget::instance()->addPage(m_model->pageAt(i));

    emit pagesChanged();
    setCurrentPage(initialPage);
}

// -- public slots

HelpViewer *OpenPagesManager::createPage()
{
    return createPage(QUrl(Help::Constants::AboutBlank));
}

HelpViewer *OpenPagesManager::createPageFromSearch(const QUrl &url)
{
    return createPage(url, true);
}

HelpViewer *OpenPagesManager::createPage(const QUrl &url, bool fromSearch)
{
    if (HelpViewer::launchWithExternalApp(url))
        return 0;

    m_model->addPage(url);

    const int index = m_model->rowCount() - 1;
    HelpViewer * const page = m_model->pageAt(index);
    CentralWidget::instance()->addPage(page, fromSearch);

    emit pagesChanged();
    setCurrentPage(index);

    return page;
}

void OpenPagesManager::setCurrentPage(int index)
{
    m_comboBox->setCurrentIndex(index);
    CentralWidget::instance()->setCurrentPage(m_model->pageAt(index));

    selectCurrentPage();    // update the selection inside the tree view
}

void OpenPagesManager::setCurrentPage(const QModelIndex &index)
{
    if (index.isValid()) {
        m_comboBox->setCurrentIndex(index.row());
        CentralWidget::instance()->setCurrentPage(m_model->pageAt(index.row()));
    }
}

void OpenPagesManager::closeCurrentPage()
{
    QModelIndexList indexes = m_openPagesWidget->selectionModel()->selectedRows();
    if (indexes.isEmpty())
        return;
    Q_ASSERT(indexes.count() == 1);
    removePage(indexes.first().row());
}

void OpenPagesManager::closePage(const QModelIndex &index)
{
    if (index.isValid())
        removePage(index.row());
}

void OpenPagesManager::closePagesExcept(const QModelIndex &index)
{
    if (index.isValid()) {
        int i = 0;
        HelpViewer *viewer = m_model->pageAt(index.row());
        while (m_model->rowCount() > 1) {
            if (m_model->pageAt(i) != viewer) {
                removePage(i);
            } else {
                i++;
            }
        }
    }
}

// -- private

void OpenPagesManager::selectCurrentPage()
{
    QItemSelectionModel * selModel = m_openPagesWidget->selectionModel();
    selModel->clearSelection();
    selModel->select(m_model->index(CentralWidget::instance()->currentIndex(), 0),
        QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
    m_openPagesWidget->scrollTo(m_openPagesWidget->currentIndex());
}

void OpenPagesManager::removePage(int index)
{
    Q_ASSERT(m_model->rowCount() > 1);

    m_model->removePage(index);
    CentralWidget::instance()->removePage(index);

    emit pagesChanged();
    selectCurrentPage();    // update the selection inside the tree view
}
<|endoftext|>


<commit_before>/******************************************************************************
* Controls.cpp
*
* Contains the yaw_controller() and depth_controller functions
******************************************************************************/
#include "Mapper.h"

/******************************************************************************
* float yaw_controller()
*
* Takes in readings from the IMU and returns a value between -1 and 1 (-100% -
* +100%) that the port and starboard thrusters should run at
******************************************************************************/

float yaw_controller(bno055_t bno055, pid_data_t yaw_pid)
{
	float motor_percent;
	float DT = .005;
	float YAW_SAT = .2;

	// control output //
	if( bno055.yaw < 180 ) // AUV is pointed right
	{
		// u[2] is negative

		motor_percent = yaw_pid.kp*(yaw_pid.err)
			+ yaw_pid.kd*(bno055.r)+ yaw_pid.ki*yaw_pid.i_err; // yaw controller

	}
	else		// AUV is pointed left
	{
		// u[2] is positive
	motor_percent = yaw_pid.kp*(yaw_pid.err) + yaw_pid.kd*(bno055.r)
			+ yaw_pid.ki*yaw_pid.i_err; // yaw controller
	}
	// saturate yaw controller //
	if( motor_percent > YAW_SAT )
	{
		motor_percent=YAW_SAT;
	}
	else if( motor_percent < -YAW_SAT )
	{
		motor_percent = -YAW_SAT;
	}

	yaw_pid.i_err += yaw_pid.err*DT;
	// set current yaw to be the old yaw //
	yaw_pid.oldyaw = bno055.yaw;

	return motor_percent;
}

/******************************************************************************
* float depth_controller(float range)
*
* Takes a range-from-bottom reading from the laser range-finder code and
* returns a value between -1 and 1 (-100% - +100%) that the vertical thruster
* should run at
******************************************************************************/
/*
float depth_controller(float range)
{
	float vert_percent;			// vertical thruster output in a percentage
	float depth_sum_error = 0;	// accumulated range error for integral control
    float range_current;
    float range_old;
    float

	// accumulated range error for integral control //
	depth_sum_error += range - depth_pid.setpoint;

	if( range > depth_pid.setpoint )
	{
		vert_percent = depth_pid.kp*(range-depth_pid.setpoint)
			+ depth_pid.ki*(depth_sum_error)
			+ depth_pid.kd*((range_current-range_old)/DT);
	}
	else
	{
		// shut off vertical thruster //
		vert_percent = 0;
	}

	// saturate depth controller //
	if( vert_percent > DEPTH_SAT )
	{
		vert_percent = DEPTH_SAT;
	}
	else if( vert_percent < -DEPTH_SAT )
	{
		vert_percent = -DEPTH_SAT;
	}

	// set current depth to be the old depth //
	depth_pid.old = depth_pid.current;

	return vert_percent;
}
*/
<commit_msg>Uncommented depth_controller<commit_after>/******************************************************************************
* Controls.cpp
*
* Contains the yaw_controller() and depth_controller functions
******************************************************************************/
#include "Mapper.h"

/******************************************************************************
* float yaw_controller()
*
* Takes in readings from the IMU and returns a value between -1 and 1 (-100% -
* +100%) that the port and starboard thrusters should run at
******************************************************************************/

float yaw_controller(bno055_t bno055, pid_data_t yaw_pid)
{
	float motor_percent;
	float DT = .005;
	float YAW_SAT = .2;

	// control output //
	if( bno055.yaw < 180 ) // AUV is pointed right
	{
		// u[2] is negative

		motor_percent = yaw_pid.kp*(yaw_pid.err)
			+ yaw_pid.kd*(bno055.r)+ yaw_pid.ki*yaw_pid.i_err; // yaw controller

	}
	else		// AUV is pointed left
	{
		// u[2] is positive
	motor_percent = yaw_pid.kp*(yaw_pid.err) + yaw_pid.kd*(bno055.r)
			+ yaw_pid.ki*yaw_pid.i_err; // yaw controller
	}
	// saturate yaw controller //
	if( motor_percent > YAW_SAT )
	{
		motor_percent=YAW_SAT;
	}
	else if( motor_percent < -YAW_SAT )
	{
		motor_percent = -YAW_SAT;
	}

	yaw_pid.i_err += yaw_pid.err*DT;
	// set current yaw to be the old yaw //
	yaw_pid.oldyaw = bno055.yaw;

	return motor_percent;
}

/******************************************************************************
* float depth_controller(float range)
*
* Takes a range-from-bottom reading from the laser range-finder code and
* returns a value between -1 and 1 (-100% - +100%) that the vertical thruster
* should run at
******************************************************************************/

float depth_controller(float range)
{
	float vert_percent;			// vertical thruster output in a percentage
	float depth_sum_error = 0;	// accumulated range error for integral control
    float range_current;
    float range_old;

	// accumulated range error for integral control //
	depth_sum_error += range - depth_pid.setpoint;

	if( range > depth_pid.setpoint )
	{
		vert_percent = depth_pid.kp*(range-depth_pid.setpoint)
			+ depth_pid.ki*(depth_sum_error)
			+ depth_pid.kd*((range_current-range_old)/DT);
	}
	else
	{
		// shut off vertical thruster //
		vert_percent = 0;
	}

	// saturate depth controller //
	if( vert_percent > DEPTH_SAT )
	{
		vert_percent = DEPTH_SAT;
	}
	else if( vert_percent < -DEPTH_SAT )
	{
		vert_percent = -DEPTH_SAT;
	}

	// set current depth to be the old depth //
	depth_pid.old = depth_pid.current;

	return vert_percent;
}

<|endoftext|>


<commit_before>
#include <cstdio>
#include <iostream>

#include "utility.hpp"

// Inludes common necessary includes for development using depthai library
#include "depthai/depthai.hpp"

static bool syncNN = true;

dai::Pipeline createNNPipeline(std::string nnPath) {
    dai::Pipeline p;

    auto colorCam = p.create<dai::node::ColorCamera>();
    auto xlinkOut = p.create<dai::node::XLinkOut>();
    auto nn1 = p.create<dai::node::NeuralNetwork>();
    auto nnOut = p.create<dai::node::XLinkOut>();

    nn1->setBlobPath(nnPath);

    xlinkOut->setStreamName("preview");
    nnOut->setStreamName("detections");

    colorCam->setPreviewSize(300, 300);
    colorCam->setResolution(dai::ColorCameraProperties::SensorResolution::THE_1080_P);
    colorCam->setInterleaved(false);
    colorCam->setColorOrder(dai::ColorCameraProperties::ColorOrder::BGR);

    // Link plugins CAM -> NN -> XLINK
    colorCam->preview.link(nn1->input);
    if(syncNN) {
        nn1->passthrough.link(xlinkOut->input);
    } else {
        colorCam->preview.link(xlinkOut->input);
    }

    nn1->out.link(nnOut->input);

    return p;
}

int main(int argc, char** argv) {
    using namespace std;

    // Default blob path provided by Hunter private data download
    // Applicable for easier example usage only
    std::string nnPath(BLOB_PATH);

    // If path to blob specified, use that
    if(argc > 1) {
        nnPath = std::string(argv[1]);
    }

    // Print which blob we are using
    printf("Using blob at path: %s\n", nnPath.c_str());

    // Create pipeline
    dai::Pipeline p = createNNPipeline(nnPath);

    // Connect to device with above created pipeline
    dai::Device d(p);
    // Start the pipeline
    d.startPipeline();

    cv::Mat frame;
    auto preview = d.getOutputQueue("preview");
    auto detections = d.getOutputQueue("detections");

    while(1) {
        auto imgFrame = preview->get<dai::ImgFrame>();
        if(imgFrame) {
            printf("Frame - w: %d, h: %d\n", imgFrame->getWidth(), imgFrame->getHeight());
            frame = toMat(imgFrame->getData(), imgFrame->getWidth(), imgFrame->getHeight(), 3, 1);
        }

        struct Detection {
            unsigned int label;
            float score;
            float x_min;
            float y_min;
            float x_max;
            float y_max;
        };

        vector<Detection> dets;

        auto det = detections->get<dai::NNData>();
        std::vector<float> detData = det->getFirstLayerFp16();
        if(detData.size() > 0) {
            int i = 0;
            while(detData[i * 7] != -1.0f) {
                Detection d;
                d.label = detData[i * 7 + 1];
                d.score = detData[i * 7 + 2];
                d.x_min = detData[i * 7 + 3];
                d.y_min = detData[i * 7 + 4];
                d.x_max = detData[i * 7 + 5];
                d.y_max = detData[i * 7 + 6];
                i++;
                dets.push_back(d);
            }
        }

        for(const auto& d : dets) {
            int x1 = d.x_min * frame.cols;
            int y1 = d.y_min * frame.rows;
            int x2 = d.x_max * frame.cols;
            int y2 = d.y_max * frame.rows;

            cv::rectangle(frame, cv::Rect(cv::Point(x1, y1), cv::Point(x2, y2)), cv::Scalar(255, 255, 255));
        }

        printf("===================== %lu detection(s) =======================\n", dets.size());
        for(unsigned det = 0; det < dets.size(); ++det) {
            printf("%5d | %6.4f | %7.4f | %7.4f | %7.4f | %7.4f\n",
                   dets[det].label,
                   dets[det].score,
                   dets[det].x_min,
                   dets[det].y_min,
                   dets[det].x_max,
                   dets[det].y_max);
        }

        cv::imshow("preview", frame);
        int key = cv::waitKey(1);
        if(key == 'q') {
            return 0;
        }
    }

    return 0;
}
<commit_msg>Upgraded rgb mobilenet example<commit_after>#include <chrono>
#include <cstdio>
#include <iostream>

#include "utility.hpp"

// Inludes common necessary includes for development using depthai library
#include "depthai/depthai.hpp"

// MobilenetSSD label texts
static const std::vector<std::string> labelMap = {"background", "aeroplane", "bicycle",     "bird",  "boat",        "bottle", "bus",
                                                  "car",        "cat",       "chair",       "cow",   "diningtable", "dog",    "horse",
                                                  "motorbike",  "person",    "pottedplant", "sheep", "sofa",        "train",  "tvmonitor"};

static std::atomic<bool> syncNN{true};

int main(int argc, char** argv) {
    using namespace std;
    using namespace std::chrono;
    // Default blob path provided by Hunter private data download
    // Applicable for easier example usage only
    std::string nnPath(BLOB_PATH);

    // If path to blob specified, use that
    if(argc > 1) {
        nnPath = std::string(argv[1]);
    }

    // Print which blob we are using
    printf("Using blob at path: %s\n", nnPath.c_str());

    // Create pipeline
    dai::Pipeline pipeline;

    // Define source
    auto camRgb = pipeline.create<dai::node::ColorCamera>();
    auto xoutRgb = pipeline.create<dai::node::XLinkOut>();
    auto nn = pipeline.create<dai::node::MobileNetDetectionNetwork>();
    auto nnOut = pipeline.create<dai::node::XLinkOut>();

    // Properties
    camRgb->setPreviewSize(300, 300);    // NN input
    camRgb->setInterleaved(false);
    camRgb->setFps(40);
    // Define a neural network that will make predictions based on the source frames
    nn->setConfidenceThreshold(0.5);
    nn->setBlobPath(nnPath);
    nn->setNumInferenceThreads(2);
    nn->input.setBlocking(false);

    xoutRgb->setStreamName("rgb");
    nnOut->setStreamName("nn");

    // Create outputs
    if (syncNN) {
        nn->passthrough.link(xoutRgb->input);
    } else {
        camRgb->preview.link(xoutRgb->input);
    }

    camRgb->preview.link(nn->input);
    nn->out.link(nnOut->input);

    // Connect to device with above created pipeline
    dai::Device device(pipeline);
    // Start the pipeline
    device.startPipeline();

    // Queues
    auto qRgb = device.getOutputQueue("rgb", 4, false);
    auto qDet = device.getOutputQueue("nn", 4, false);

    // Add bounding boxes and text to the frame and show it to the user
    auto displayFrame = [](std::string name, auto frame, auto detections) {
        auto color = cv::Scalar(255, 0, 0);
        // nn data, being the bounding box locations, are in <0..1> range - they need to be normalized with frame width/height
        for(auto& detection : detections) {
            int x1 = detection.xmin * frame.cols;
            int y1 = detection.ymin * frame.rows;
            int x2 = detection.xmax * frame.cols;
            int y2 = detection.ymax * frame.rows;

            int labelIndex = detection.label;
            std::string labelStr = to_string(labelIndex);
            if(labelIndex < labelMap.size()) {
                labelStr = labelMap[labelIndex];
            }
            cv::putText(frame, labelStr, cv::Point(x1 + 10, y1 + 20), cv::FONT_HERSHEY_TRIPLEX, 0.5, color);
            std::stringstream confStr;
            confStr << std::fixed << std::setprecision(2) << detection.confidence * 100;
            cv::putText(frame, confStr.str(), cv::Point(x1 + 10, y1 + 40), cv::FONT_HERSHEY_TRIPLEX, 0.5, color);
            cv::rectangle(frame, cv::Rect(cv::Point(x1, y1), cv::Point(x2, y2)), color, cv::FONT_HERSHEY_SIMPLEX);
        }
        // Show the frame
        cv::imshow(name, frame);
    };

    auto startTime = steady_clock::now();
    int counter = 0;
    float fps = 0;

    while(true) {
        auto inRgb = qRgb->get<dai::ImgFrame>();
        auto inDet = qDet->get<dai::ImgDetections>();
        auto detections = inDet->detections;
        cv::Mat frame = inRgb->getCvFrame();

        counter++;
        auto currentTime = steady_clock::now();
        auto elapsed = duration_cast<duration<float>>(currentTime - startTime);
        if(elapsed > seconds(1)) {
            fps = counter / elapsed.count();
            counter = 0;
            startTime = currentTime;
        }

        std::stringstream fpsStr;
        fpsStr << "NN fps: " <<std::fixed << std::setprecision(2) << fps;
        cv::putText(frame, fpsStr.str(), cv::Point(2, inRgb->getHeight() - 4), cv::FONT_HERSHEY_TRIPLEX, 0.4, 255, 0, 0);

        displayFrame("video", frame, detections);

        int key = cv::waitKey(1);
        if(key == 'q' || key == 'Q')
            return 0;
    }
    return 0;
}<|endoftext|>


<commit_before>#include <iostream>

#include "libaps.h"
#include "constants.h"
#include <thread>

using namespace std;

int main ()
{
  cout << "BBN X6-1000 Test Executable" << endl;

  set_malibu_threading_enable(false);

  int numDevices;
  numDevices = get_numDevices();

  cout << numDevices << " X6 device" << (numDevices > 1 ? "s": "")  << " found" << endl;

  if (numDevices < 1)
  	return 0;

  char s[] = "stdout";
  set_log(s);

  cout << "Attempting to initialize libaps" << endl;

  init();

  char serialBuffer[100];

  for (int cnt; cnt < numDevices; cnt++) {
  	get_deviceSerial(cnt, serialBuffer);
  	cout << "Device " << cnt << " serial #: " << serialBuffer << endl;
  }

  int rc;
  rc = connect_by_ID(0);

  cout << "connect_by_ID(0) returned " << rc << endl;

  cout << "current logic temperature = " << get_logic_temperature(0) << endl;

  cout << "current PLL frequency = " << get_sampleRate(0) << " MHz" << endl;

  cout << "setting trigger source = EXTERNAL" << endl;

  set_trigger_source(0, EXTERNAL);

  cout << "get trigger source returns " << ((get_trigger_source(0) == INTERNAL) ? "INTERNAL" : "EXTERNAL") << endl;

  cout << "setting trigger source = INTERNAL" << endl;

  set_trigger_source(0, INTERNAL);

  cout << "get trigger source returns " << ((get_trigger_source(0) == INTERNAL) ? "INTERNAL" : "EXTERNAL") << endl;

  cout << "get channel(0) enable: " << get_channel_enabled(0,0) << endl;

  cout << "set channel(0) enabled = 1" << endl;

  set_channel_enabled(0,0,true);

  cout << "enable ramp output" << endl;

  enable_test_generator(0,0,0.001);

  std::this_thread::sleep_for(std::chrono::seconds(5));

  cout << "enable sine wave output" << endl;

  disable_test_generator(0);
  enable_test_generator(0,1,0.001);

  std::this_thread::sleep_for(std::chrono::seconds(5));

  cout << "disabling channel" << endl;
  disable_test_generator(0);
  set_channel_enabled(0,0,false);

  cout << "get channel(0) enable: " << get_channel_enabled(0,0) << endl;

  rc = disconnect_by_ID(0);

  cout << "disconnect_by_ID(0) returned " << rc << endl;

  return 0;
}<commit_msg>First output through X6_1000 class<commit_after>#include <iostream>

#include "libaps.h"
#include "constants.h"
#include <thread>

using namespace std;

int main ()
{
  cout << "BBN X6-1000 Test Executable" << endl;

  set_malibu_threading_enable(false);

  set_logging_level(5);

  int numDevices;
  numDevices = get_numDevices();

  cout << numDevices << " X6 device" << (numDevices > 1 ? "s": "")  << " found" << endl;

  if (numDevices < 1)
  	return 0;

  char s[] = "stdout";
  set_log(s);

  cout << "Attempting to initialize libaps" << endl;

  init();

  char serialBuffer[100];

  for (int cnt; cnt < numDevices; cnt++) {
  	get_deviceSerial(cnt, serialBuffer);
  	cout << "Device " << cnt << " serial #: " << serialBuffer << endl;
  }

  int rc;
  rc = connect_by_ID(0);

  cout << "connect_by_ID(0) returned " << rc << endl;

  cout << "current logic temperature = " << get_logic_temperature(0) << endl;

  cout << "current PLL frequency = " << get_sampleRate(0) << " MHz" << endl;

  cout << "setting trigger source = EXTERNAL" << endl;

  set_trigger_source(0, EXTERNAL);

  cout << "get trigger source returns " << ((get_trigger_source(0) == INTERNAL) ? "INTERNAL" : "EXTERNAL") << endl;

  cout << "setting trigger source = INTERNAL" << endl;

  set_trigger_source(0, INTERNAL);

  cout << "get trigger source returns " << ((get_trigger_source(0) == INTERNAL) ? "INTERNAL" : "EXTERNAL") << endl;

  cout << "get channel(0) enable: " << get_channel_enabled(0,0) << endl;

  cout << "set channel(0) enabled = 1" << endl;

  set_channel_enabled(0,0,true);

  cout << "enable ramp output" << endl;

  enable_test_generator(0,0,0.001);

  std::this_thread::sleep_for(std::chrono::seconds(5));

  cout << "enable sine wave output" << endl;

  disable_test_generator(0);
  enable_test_generator(0,1,0.001);

  std::this_thread::sleep_for(std::chrono::seconds(5));

  cout << "disabling channel" << endl;
  disable_test_generator(0);
  set_channel_enabled(0,0,false);

  cout << "get channel(0) enable: " << get_channel_enabled(0,0) << endl;

  rc = disconnect_by_ID(0);

  cout << "disconnect_by_ID(0) returned " << rc << endl;

  return 0;
}<|endoftext|>


<commit_before>#pragma once

#include "kl/binary_rw.hpp"

#include <vector>

namespace kl {

template <typename T>
kl::binary_reader& operator>>(kl::binary_reader& r, std::vector<T>& vec)
{
    const auto size = r.read<std::uint32_t>();

    vec.clear();
    vec.reserve(size);

    for (std::uint32_t i = 0; i < size; ++i)
    {
        vec.push_back(r.read<T>());
        if (r.err())
        {
            vec.clear();
            break;
        }
    }

    return r;
}
} // namespace kl
<commit_msg>specialize operator>> for vector<T> of trivial type T<commit_after>#pragma once

#include "kl/binary_rw.hpp"
#include "kl/type_traits.hpp"

#include <vector>

namespace kl {

namespace detail {

// Specialized operator>> for vector<T> of trivial type T
template <typename T>
void decode_vector(kl::binary_reader& r, std::vector<T>& vec,
                   std::true_type /*is_trivial*/)
{
    const auto size = r.read<std::uint32_t>();

    vec.clear();

    if (size)
    {
        auto span = r.view(size * sizeof(T));
        if (r.err())
            return;

        vec.resize(size);
        // Use .data() so we get a pointer and memmove fast path
        std::copy_n(span.data(), size, vec.begin());
    }
}

template <typename T>
void decode_vector(kl::binary_reader& r, std::vector<T>& vec,
                   std::false_type /*is_trivial*/)
{
    const auto size = r.read<std::uint32_t>();

    vec.clear();
    vec.reserve(size);

    for (std::uint32_t i = 0; i < size; ++i)
    {
        vec.push_back(r.read<T>());
        if (r.err())
        {
            vec.clear();
            break;
        }
    }
}
} // namespace detail

template <typename T>
kl::binary_reader& operator>>(kl::binary_reader& r, std::vector<T>& vec)
{

    detail::decode_vector(r, vec,
                          kl::bool_constant<std::is_trivial<T>::value>{});
    return r;
}
} // namespace kl
<|endoftext|>


<commit_before>#include "Dictionary.h"

#include <string>
#include <vector>
#include <map>

#include "NounDefinition.h"
#include "AdjunctDefinition.h"
#include "ModifierDefinition.h"
#include "Grammar.h"

#ifdef DEBUG
#include "../util/Sysout.h"
#endif // DEBUG

// =====
// Nouns
// =====

// Vector
std::map<gmr::NounId, NounDefinition*> Dictionary::registeredNouns;
std::map<std::string, gmr::NounId> Dictionary::nounIdBySingularForm;
std::map<std::string, gmr::NounId> Dictionary::nounIdByPluralForm;

//
gmr::NounId Dictionary::erroneousNounId;

// Add
void Dictionary::addNoun(gmr::NounId nounId, NounDefinition* newNoun)
{
    #ifdef DEBUG
    std::map<gmr::NounId, NounDefinition*>::iterator focus = registeredNouns.find(nounId);

    if(focus != registeredNouns.end())
    {
        Sysout::print("[Warning] You are trying to add two nouns with the same id! ");
        Sysout::println(Sysout::toString(nounId));
    }
    #endif // DEBUG

    registeredNouns.insert(std::pair<gmr::NounId, NounDefinition*>(nounId, newNoun));

    nounIdBySingularForm.insert(std::pair<std::string, gmr::NounId>(newNoun->getSingularForm(), nounId));
    nounIdByPluralForm.insert(std::pair<std::string, gmr::NounId>(newNoun->getPluralForm(), nounId));
}

// Get
NounDefinition* Dictionary::getNoun(gmr::NounId nounId)
{
    std::map<gmr::NounId, NounDefinition*>::iterator focus = registeredNouns.find(nounId);

    if(focus == registeredNouns.end())
    {
        return registeredNouns.find(erroneousModifierId)->second;
    }

    return focus->second;
}

// Get Id
gmr::NounId Dictionary::getNounIdBySingular(std::string singularNounForm)
{
    std::map<std::string, gmr::NounId>::iterator focus = nounIdBySingularForm.find(singularNounForm);

    if(focus == nounIdBySingularForm.end())
    {
        return erroneousNounId;
    }

    return focus->second;
}
gmr::NounId Dictionary::getNounIdByPlural(std::string pluralNounForm)
{
    std::map<std::string, gmr::NounId>::iterator focus = nounIdByPluralForm.find(pluralNounForm);

    if(focus == nounIdByPluralForm.end())
    {
        return erroneousNounId;
    }

    return focus->second;
}

// Add
void Dictionary::addNounAsErroneous(gmr::NounId nounId, NounDefinition* newNoun)
{
    registeredNouns.insert(std::pair<gmr::NounId, NounDefinition*>(nounId, newNoun));

    erroneousNounId = nounId;
}

gmr::NounId Dictionary::getErroneousNounId()
{
    return erroneousNounId;
}

// ========
// Adjuncts
// ========

// Vector
std::vector<AdjunctDefinition*> Dictionary::registeredAdjuncts;
//
gmr::AdjunctId Dictionary::erroneousAdjunctId;

// Add
gmr::AdjunctId Dictionary::addAdjunct(AdjunctDefinition* newAdjunct)
{
    registeredAdjuncts.push_back(newAdjunct);

    return registeredAdjuncts.size() - 1;
}

// Add
gmr::AdjunctId Dictionary::addAdjunctAsErroneous(AdjunctDefinition* newAdjunct)
{
    registeredAdjuncts.push_back(newAdjunct);

    erroneousAdjunctId = registeredAdjuncts.size() - 1;

    return registeredAdjuncts.size() - 1;
}

// Get
AdjunctDefinition* Dictionary::getAdjunct(gmr::AdjunctId adjunctId)
{
    return registeredAdjuncts.at(adjunctId);
}

gmr::AdjunctId Dictionary::getErroneousAdjunctId()
{
    return erroneousAdjunctId;
}

// =========
// Modifiers
// =========

// Maps
std::map<gmr::ModifierId, ModifierDefinition*> Dictionary::registeredModifiers;
std::map<std::string, gmr::ModifierId> Dictionary::modifierIdByForm;
//
gmr::ModifierId Dictionary::erroneousModifierId;

// Add
void Dictionary::addModifier(gmr::ModifierId modifierId, ModifierDefinition* newModifier)
{
    #ifdef DEBUG
    std::map<gmr::ModifierId, ModifierDefinition*>::iterator focus = registeredModifiers.find(modifierIdId);

    if(focus != registeredModifiers.end())
    {
        Sysout::print("[Warning] You are trying to add two modifiers with the same id! ");
        Sysout::println(Sysout::toString(modifierId));
    }
    #endif // DEBUG

    registeredModifiers.insert(std::pair<gmr::ModifierId, ModifierDefinition*>(modifierId, newModifier));

    modifierIdByForm.insert(std::pair<std::string, gmr::ModifierId>(newModifier->getForm(), modifierId));
}

// Get
ModifierDefinition* Dictionary::getModifier(gmr::ModifierId modifierId)
{
    std::map<gmr::ModifierId, ModifierDefinition*>::iterator focus = registeredModifiers.find(modifierId);

    if(focus == registeredModifiers.end())
    {
        return registeredModifiers.find(erroneousModifierId)->second;
    }

    return focus->second;
}

// Get Id
gmr::ModifierId Dictionary::getModifierId(std::string modifierForm)
{
    std::map<std::string, gmr::ModifierId>::iterator focus = modifierIdByForm.find(modifierForm);

    if(focus == modifierIdByForm.end())
    {
        return erroneousModifierId;
    }

    return focus->second;
}

// Add Erroneous
void Dictionary::addModifierAsErroneous(gmr::ModifierId modifierId, ModifierDefinition* newModifier)
{
    registeredModifiers.insert(std::pair<gmr::ModifierId, ModifierDefinition*>(modifierId, newModifier));

    erroneousModifierId = modifierId;
}

// Get Erroneous
gmr::ModifierId Dictionary::getErroneousModifierId()
{
    return erroneousModifierId;
}

// ========
// Articles
// ========
// I'm different!

// Vector
std::map<std::string, gmr::ArticleProperties> Dictionary::registeredArticles;

// Add by name
void Dictionary::addArticle(std::string name, gmr::Definity mtype, gmr::Plurality mquantity)
{
    gmr::ArticleProperties a;
    a.type = mtype;
    a.plurality = mquantity;

    registeredArticles.insert(std::pair<std::string, gmr::ArticleProperties>(name, a));
}

// Get by name
gmr::ArticleProperties Dictionary::getArticle(std::string name)
{
    std::map<std::string, gmr::ArticleProperties>::iterator focus = registeredArticles.find(name);

    if(focus == registeredArticles.end())
    {
        // Returns a default value
        gmr::ArticleProperties erroneous;
        erroneous.type = gmr::undefinite;
        erroneous.plurality = gmr::ambiguous;
        return erroneous;
    }

    return focus->second;
}

std::string Dictionary::getArticleForm(gmr::AdjunctType definity, gmr::Plurality plurality)
{
    return "put something better here";
}
<commit_msg>Fixed variable name<commit_after>#include "Dictionary.h"

#include <string>
#include <vector>
#include <map>

#include "NounDefinition.h"
#include "AdjunctDefinition.h"
#include "ModifierDefinition.h"
#include "Grammar.h"

#ifdef DEBUG
#include "../util/Sysout.h"
#endif // DEBUG

// =====
// Nouns
// =====

// Vector
std::map<gmr::NounId, NounDefinition*> Dictionary::registeredNouns;
std::map<std::string, gmr::NounId> Dictionary::nounIdBySingularForm;
std::map<std::string, gmr::NounId> Dictionary::nounIdByPluralForm;

//
gmr::NounId Dictionary::erroneousNounId;

// Add
void Dictionary::addNoun(gmr::NounId nounId, NounDefinition* newNoun)
{
    #ifdef DEBUG
    std::map<gmr::NounId, NounDefinition*>::iterator focus = registeredNouns.find(nounId);

    if(focus != registeredNouns.end())
    {
        Sysout::print("[Warning] You are trying to add two nouns with the same id! ");
        Sysout::println(Sysout::toString(nounId));
    }
    #endif // DEBUG

    registeredNouns.insert(std::pair<gmr::NounId, NounDefinition*>(nounId, newNoun));

    nounIdBySingularForm.insert(std::pair<std::string, gmr::NounId>(newNoun->getSingularForm(), nounId));
    nounIdByPluralForm.insert(std::pair<std::string, gmr::NounId>(newNoun->getPluralForm(), nounId));
}

// Get
NounDefinition* Dictionary::getNoun(gmr::NounId nounId)
{
    std::map<gmr::NounId, NounDefinition*>::iterator focus = registeredNouns.find(nounId);

    if(focus == registeredNouns.end())
    {
        return registeredNouns.find(erroneousModifierId)->second;
    }

    return focus->second;
}

// Get Id
gmr::NounId Dictionary::getNounIdBySingular(std::string singularNounForm)
{
    std::map<std::string, gmr::NounId>::iterator focus = nounIdBySingularForm.find(singularNounForm);

    if(focus == nounIdBySingularForm.end())
    {
        return erroneousNounId;
    }

    return focus->second;
}
gmr::NounId Dictionary::getNounIdByPlural(std::string pluralNounForm)
{
    std::map<std::string, gmr::NounId>::iterator focus = nounIdByPluralForm.find(pluralNounForm);

    if(focus == nounIdByPluralForm.end())
    {
        return erroneousNounId;
    }

    return focus->second;
}

// Add
void Dictionary::addNounAsErroneous(gmr::NounId nounId, NounDefinition* newNoun)
{
    registeredNouns.insert(std::pair<gmr::NounId, NounDefinition*>(nounId, newNoun));

    erroneousNounId = nounId;
}

gmr::NounId Dictionary::getErroneousNounId()
{
    return erroneousNounId;
}

// ========
// Adjuncts
// ========

// Vector
std::vector<AdjunctDefinition*> Dictionary::registeredAdjuncts;
//
gmr::AdjunctId Dictionary::erroneousAdjunctId;

// Add
gmr::AdjunctId Dictionary::addAdjunct(AdjunctDefinition* newAdjunct)
{
    registeredAdjuncts.push_back(newAdjunct);

    return registeredAdjuncts.size() - 1;
}

// Add
gmr::AdjunctId Dictionary::addAdjunctAsErroneous(AdjunctDefinition* newAdjunct)
{
    registeredAdjuncts.push_back(newAdjunct);

    erroneousAdjunctId = registeredAdjuncts.size() - 1;

    return registeredAdjuncts.size() - 1;
}

// Get
AdjunctDefinition* Dictionary::getAdjunct(gmr::AdjunctId adjunctId)
{
    return registeredAdjuncts.at(adjunctId);
}

gmr::AdjunctId Dictionary::getErroneousAdjunctId()
{
    return erroneousAdjunctId;
}

// =========
// Modifiers
// =========

// Maps
std::map<gmr::ModifierId, ModifierDefinition*> Dictionary::registeredModifiers;
std::map<std::string, gmr::ModifierId> Dictionary::modifierIdByForm;
//
gmr::ModifierId Dictionary::erroneousModifierId;

// Add
void Dictionary::addModifier(gmr::ModifierId modifierId, ModifierDefinition* newModifier)
{
    #ifdef DEBUG
    std::map<gmr::ModifierId, ModifierDefinition*>::iterator focus = registeredModifiers.find(modifierId);

    if(focus != registeredModifiers.end())
    {
        Sysout::print("[Warning] You are trying to add two modifiers with the same id! ");
        Sysout::println(Sysout::toString(modifierId));
    }
    #endif // DEBUG

    registeredModifiers.insert(std::pair<gmr::ModifierId, ModifierDefinition*>(modifierId, newModifier));

    modifierIdByForm.insert(std::pair<std::string, gmr::ModifierId>(newModifier->getForm(), modifierId));
}

// Get
ModifierDefinition* Dictionary::getModifier(gmr::ModifierId modifierId)
{
    std::map<gmr::ModifierId, ModifierDefinition*>::iterator focus = registeredModifiers.find(modifierId);

    if(focus == registeredModifiers.end())
    {
        return registeredModifiers.find(erroneousModifierId)->second;
    }

    return focus->second;
}

// Get Id
gmr::ModifierId Dictionary::getModifierId(std::string modifierForm)
{
    std::map<std::string, gmr::ModifierId>::iterator focus = modifierIdByForm.find(modifierForm);

    if(focus == modifierIdByForm.end())
    {
        return erroneousModifierId;
    }

    return focus->second;
}

// Add Erroneous
void Dictionary::addModifierAsErroneous(gmr::ModifierId modifierId, ModifierDefinition* newModifier)
{
    registeredModifiers.insert(std::pair<gmr::ModifierId, ModifierDefinition*>(modifierId, newModifier));

    erroneousModifierId = modifierId;
}

// Get Erroneous
gmr::ModifierId Dictionary::getErroneousModifierId()
{
    return erroneousModifierId;
}

// ========
// Articles
// ========
// I'm different!

// Vector
std::map<std::string, gmr::ArticleProperties> Dictionary::registeredArticles;

// Add by name
void Dictionary::addArticle(std::string name, gmr::Definity mtype, gmr::Plurality mquantity)
{
    gmr::ArticleProperties a;
    a.type = mtype;
    a.plurality = mquantity;

    registeredArticles.insert(std::pair<std::string, gmr::ArticleProperties>(name, a));
}

// Get by name
gmr::ArticleProperties Dictionary::getArticle(std::string name)
{
    std::map<std::string, gmr::ArticleProperties>::iterator focus = registeredArticles.find(name);

    if(focus == registeredArticles.end())
    {
        // Returns a default value
        gmr::ArticleProperties erroneous;
        erroneous.type = gmr::undefinite;
        erroneous.plurality = gmr::ambiguous;
        return erroneous;
    }

    return focus->second;
}

std::string Dictionary::getArticleForm(gmr::AdjunctType definity, gmr::Plurality plurality)
{
    return "put something better here";
}
<|endoftext|>