<commit_before>//===- InputFiles.cpp -----------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "InputFiles.h"
#include "InputSection.h"
#include "Error.h"
#include "Symbols.h"
#include "llvm/ADT/STLExtras.h"

using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::object;
using namespace llvm::sys::fs;

using namespace lld;
using namespace lld::elf2;

namespace {
class ECRAII {
  std::error_code EC;

public:
  std::error_code &getEC() { return EC; }
  ~ECRAII() { error(EC); }
};
}

template <class ELFT>
ELFFileBase<ELFT>::ELFFileBase(Kind K, ELFKind EKind, MemoryBufferRef M)
    : InputFile(K, M), EKind(EKind), ELFObj(MB.getBuffer(), ECRAII().getEC()) {}

template <class ELFT>
typename ELFFileBase<ELFT>::Elf_Sym_Range
ELFFileBase<ELFT>::getSymbolsHelper(bool Local) {
  if (!Symtab)
    return Elf_Sym_Range(nullptr, nullptr);
  Elf_Sym_Range Syms = ELFObj.symbols(Symtab);
  uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
  uint32_t FirstNonLocal = Symtab->sh_info;
  if (FirstNonLocal > NumSymbols)
    error("Invalid sh_info in symbol table");
  if (!Local)
    return make_range(Syms.begin() + FirstNonLocal, Syms.end());
  // +1 to skip over dummy symbol.
  return make_range(Syms.begin() + 1, Syms.begin() + FirstNonLocal);
}

template <class ELFT> void ELFFileBase<ELFT>::initStringTable() {
  if (!Symtab)
    return;
  ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab);
  error(StringTableOrErr.getError());
  StringTable = *StringTableOrErr;
}

template <class ELFT>
typename ELFFileBase<ELFT>::Elf_Sym_Range
ELFFileBase<ELFT>::getNonLocalSymbols() {
  return getSymbolsHelper(false);
}

template <class ELFT>
ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M)
    : ELFFileBase<ELFT>(Base::ObjectKind, Base::getStaticELFKind(), M) {}

template <class ELFT>
typename ObjectFile<ELFT>::Elf_Sym_Range ObjectFile<ELFT>::getLocalSymbols() {
  return this->getSymbolsHelper(true);
}

template <class ELFT>
void elf2::ObjectFile<ELFT>::parse(DenseSet<StringRef> &Comdats) {
  // Read section and symbol tables.
  initializeSections(Comdats);
  initializeSymbols();
}

template <class ELFT>
StringRef ObjectFile<ELFT>::getShtGroupSignature(const Elf_Shdr &Sec) {
  const ELFFile<ELFT> &Obj = this->ELFObj;
  uint32_t SymtabdSectionIndex = Sec.sh_link;
  ErrorOr<const Elf_Shdr *> SecOrErr = Obj.getSection(SymtabdSectionIndex);
  error(SecOrErr);
  const Elf_Shdr *SymtabSec = *SecOrErr;
  uint32_t SymIndex = Sec.sh_info;
  const Elf_Sym *Sym = Obj.getSymbol(SymtabSec, SymIndex);
  ErrorOr<StringRef> StringTableOrErr = Obj.getStringTableForSymtab(*SymtabSec);
  error(StringTableOrErr);
  ErrorOr<StringRef> SignatureOrErr = Sym->getName(*StringTableOrErr);
  error(SignatureOrErr);
  return *SignatureOrErr;
}

template <class ELFT>
ArrayRef<typename ObjectFile<ELFT>::GroupEntryType>
ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) {
  const ELFFile<ELFT> &Obj = this->ELFObj;
  ErrorOr<ArrayRef<GroupEntryType>> EntriesOrErr =
      Obj.template getSectionContentsAsArray<GroupEntryType>(&Sec);
  error(EntriesOrErr.getError());
  ArrayRef<GroupEntryType> Entries = *EntriesOrErr;
  if (Entries.empty() || Entries[0] != GRP_COMDAT)
    error("Unsupported SHT_GROUP format");
  return Entries.slice(1);
}

template <class ELFT>
void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) {
  uint64_t Size = this->ELFObj.getNumSections();
  Sections.resize(Size);
  unsigned I = -1;
  const ELFFile<ELFT> &Obj = this->ELFObj;
  for (const Elf_Shdr &Sec : Obj.sections()) {
    ++I;
    if (Sections[I] == &InputSection<ELFT>::Discarded)
      continue;

    switch (Sec.sh_type) {
    case SHT_GROUP:
      Sections[I] = &InputSection<ELFT>::Discarded;
      if (Comdats.insert(getShtGroupSignature(Sec)).second)
        continue;
      for (GroupEntryType E : getShtGroupEntries(Sec)) {
        uint32_t SecIndex = E;
        if (SecIndex >= Size)
          error("Invalid section index in group");
        Sections[SecIndex] = &InputSection<ELFT>::Discarded;
      }
      break;
    case SHT_SYMTAB:
      this->Symtab = &Sec;
      break;
    case SHT_SYMTAB_SHNDX: {
      ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = Obj.getSHNDXTable(Sec);
      error(ErrorOrTable);
      SymtabSHNDX = *ErrorOrTable;
      break;
    }
    case SHT_STRTAB:
    case SHT_NULL:
      break;
    case SHT_RELA:
    case SHT_REL: {
      uint32_t RelocatedSectionIndex = Sec.sh_info;
      if (RelocatedSectionIndex >= Size)
        error("Invalid relocated section index");
      InputSection<ELFT> *RelocatedSection = Sections[RelocatedSectionIndex];
      if (!RelocatedSection)
        error("Unsupported relocation reference");
      RelocatedSection->RelocSections.push_back(&Sec);
      break;
    }
    default:
      Sections[I] = new (this->Alloc) InputSection<ELFT>(this, &Sec);
      break;
    }
  }
}

template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {
  this->initStringTable();
  Elf_Sym_Range Syms = this->getNonLocalSymbols();
  uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
  this->SymbolBodies.reserve(NumSymbols);
  for (const Elf_Sym &Sym : Syms)
    this->SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym));
}

template <class ELFT>
SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
                                                     const Elf_Sym *Sym) {
  ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable);
  error(NameOrErr.getError());
  StringRef Name = *NameOrErr;

  uint32_t SecIndex = Sym->st_shndx;
  switch (SecIndex) {
  case SHN_ABS:
    return new (this->Alloc) DefinedAbsolute<ELFT>(Name, *Sym);
  case SHN_UNDEF:
    return new (this->Alloc) Undefined<ELFT>(Name, *Sym);
  case SHN_COMMON:
    return new (this->Alloc) DefinedCommon<ELFT>(Name, *Sym);
  case SHN_XINDEX:
    SecIndex = this->ELFObj.getExtendedSymbolTableIndex(Sym, this->Symtab,
                                                        SymtabSHNDX);
    break;
  }

  if (SecIndex >= Sections.size() || !SecIndex || !Sections[SecIndex])
    error("Invalid section index");

  switch (Sym->getBinding()) {
  default:
    error("unexpected binding");
  case STB_GLOBAL:
  case STB_WEAK:
  case STB_GNU_UNIQUE: {
    InputSection<ELFT> *Sec = Sections[SecIndex];
    if (Sec == &InputSection<ELFT>::Discarded)
      return new (this->Alloc) Undefined<ELFT>(Name, *Sym);
    return new (this->Alloc) DefinedRegular<ELFT>(Name, *Sym, *Sec);
  }
  }
}

static std::unique_ptr<Archive> openArchive(MemoryBufferRef MB) {
  ErrorOr<std::unique_ptr<Archive>> ArchiveOrErr = Archive::create(MB);
  error(ArchiveOrErr, "Failed to parse archive");
  return std::move(*ArchiveOrErr);
}

void ArchiveFile::parse() {
  File = openArchive(MB);

  // Allocate a buffer for Lazy objects.
  size_t NumSyms = File->getNumberOfSymbols();
  LazySymbols.reserve(NumSyms);

  // Read the symbol table to construct Lazy objects.
  for (const Archive::Symbol &Sym : File->symbols())
    LazySymbols.emplace_back(this, Sym);
}

// Returns a buffer pointing to a member file containing a given symbol.
MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) {
  ErrorOr<Archive::child_iterator> ItOrErr = Sym->getMember();
  error(ItOrErr,
        Twine("Could not get the member for symbol ") + Sym->getName());
  Archive::child_iterator It = *ItOrErr;

  if (!Seen.insert(It->getChildOffset()).second)
    return MemoryBufferRef();

  ErrorOr<MemoryBufferRef> Ret = It->getMemoryBufferRef();
  error(Ret, Twine("Could not get the buffer for the member defining symbol ") +
                 Sym->getName());
  return *Ret;
}

std::vector<MemoryBufferRef> ArchiveFile::getMembers() {
  File = openArchive(MB);

  std::vector<MemoryBufferRef> Result;
  for (const Archive::Child &Child : File->children()) {
    ErrorOr<MemoryBufferRef> MbOrErr = Child.getMemoryBufferRef();
    error(MbOrErr,
          Twine("Could not get the buffer for a child of the archive ") +
              File->getFileName());
    Result.push_back(MbOrErr.get());
  }
  return Result;
}

template <class ELFT>
SharedFile<ELFT>::SharedFile(MemoryBufferRef M)
    : ELFFileBase<ELFT>(Base::SharedKind, Base::getStaticELFKind(), M) {
  AsNeeded = Config->AsNeeded;
}

template <class ELFT> void SharedFile<ELFT>::parseSoName() {
  typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
  typedef typename ELFFile<ELFT>::uintX_t uintX_t;
  const Elf_Shdr *DynamicSec = nullptr;

  const ELFFile<ELFT> Obj = this->ELFObj;
  for (const Elf_Shdr &Sec : Obj.sections()) {
    uint32_t Type = Sec.sh_type;
    if (Type == SHT_DYNSYM)
      this->Symtab = &Sec;
    else if (Type == SHT_DYNAMIC)
      DynamicSec = &Sec;
  }

  this->initStringTable();
  this->SoName = this->getName();

  if (DynamicSec) {
    auto *Begin =
        reinterpret_cast<const Elf_Dyn *>(Obj.base() + DynamicSec->sh_offset);
    const Elf_Dyn *End = Begin + DynamicSec->sh_size / sizeof(Elf_Dyn);

    for (const Elf_Dyn &Dyn : make_range(Begin, End)) {
      if (Dyn.d_tag == DT_SONAME) {
        uintX_t Val = Dyn.getVal();
        if (Val >= this->StringTable.size())
          error("Invalid DT_SONAME entry");
        this->SoName = StringRef(this->StringTable.data() + Val);
        break;
      }
    }
  }
}

template <class ELFT> void SharedFile<ELFT>::parse() {
  Elf_Sym_Range Syms = this->getNonLocalSymbols();
  uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
  SymbolBodies.reserve(NumSymbols);
  for (const Elf_Sym &Sym : Syms) {
    if (Sym.isUndefined())
      continue;

    ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable);
    error(NameOrErr.getError());
    StringRef Name = *NameOrErr;

    SymbolBodies.emplace_back(this, Name, Sym);
  }
}

namespace lld {
namespace elf2 {
template class ELFFileBase<llvm::object::ELF32LE>;
template class ELFFileBase<llvm::object::ELF32BE>;
template class ELFFileBase<llvm::object::ELF64LE>;
template class ELFFileBase<llvm::object::ELF64BE>;

template class elf2::ObjectFile<llvm::object::ELF32LE>;
template class elf2::ObjectFile<llvm::object::ELF32BE>;
template class elf2::ObjectFile<llvm::object::ELF64LE>;
template class elf2::ObjectFile<llvm::object::ELF64BE>;

template class elf2::SharedFile<llvm::object::ELF32LE>;
template class elf2::SharedFile<llvm::object::ELF32BE>;
template class elf2::SharedFile<llvm::object::ELF64LE>;
template class elf2::SharedFile<llvm::object::ELF64BE>;
}
}
<commit_msg>Remove redundant namespace specifiers.<commit_after>//===- InputFiles.cpp -----------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "InputFiles.h"
#include "InputSection.h"
#include "Error.h"
#include "Symbols.h"
#include "llvm/ADT/STLExtras.h"

using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::object;
using namespace llvm::sys::fs;

using namespace lld;
using namespace lld::elf2;

namespace {
class ECRAII {
  std::error_code EC;

public:
  std::error_code &getEC() { return EC; }
  ~ECRAII() { error(EC); }
};
}

template <class ELFT>
ELFFileBase<ELFT>::ELFFileBase(Kind K, ELFKind EKind, MemoryBufferRef M)
    : InputFile(K, M), EKind(EKind), ELFObj(MB.getBuffer(), ECRAII().getEC()) {}

template <class ELFT>
typename ELFFileBase<ELFT>::Elf_Sym_Range
ELFFileBase<ELFT>::getSymbolsHelper(bool Local) {
  if (!Symtab)
    return Elf_Sym_Range(nullptr, nullptr);
  Elf_Sym_Range Syms = ELFObj.symbols(Symtab);
  uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
  uint32_t FirstNonLocal = Symtab->sh_info;
  if (FirstNonLocal > NumSymbols)
    error("Invalid sh_info in symbol table");
  if (!Local)
    return make_range(Syms.begin() + FirstNonLocal, Syms.end());
  // +1 to skip over dummy symbol.
  return make_range(Syms.begin() + 1, Syms.begin() + FirstNonLocal);
}

template <class ELFT> void ELFFileBase<ELFT>::initStringTable() {
  if (!Symtab)
    return;
  ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab);
  error(StringTableOrErr.getError());
  StringTable = *StringTableOrErr;
}

template <class ELFT>
typename ELFFileBase<ELFT>::Elf_Sym_Range
ELFFileBase<ELFT>::getNonLocalSymbols() {
  return getSymbolsHelper(false);
}

template <class ELFT>
ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M)
    : ELFFileBase<ELFT>(Base::ObjectKind, Base::getStaticELFKind(), M) {}

template <class ELFT>
typename ObjectFile<ELFT>::Elf_Sym_Range ObjectFile<ELFT>::getLocalSymbols() {
  return this->getSymbolsHelper(true);
}

template <class ELFT>
void elf2::ObjectFile<ELFT>::parse(DenseSet<StringRef> &Comdats) {
  // Read section and symbol tables.
  initializeSections(Comdats);
  initializeSymbols();
}

template <class ELFT>
StringRef ObjectFile<ELFT>::getShtGroupSignature(const Elf_Shdr &Sec) {
  const ELFFile<ELFT> &Obj = this->ELFObj;
  uint32_t SymtabdSectionIndex = Sec.sh_link;
  ErrorOr<const Elf_Shdr *> SecOrErr = Obj.getSection(SymtabdSectionIndex);
  error(SecOrErr);
  const Elf_Shdr *SymtabSec = *SecOrErr;
  uint32_t SymIndex = Sec.sh_info;
  const Elf_Sym *Sym = Obj.getSymbol(SymtabSec, SymIndex);
  ErrorOr<StringRef> StringTableOrErr = Obj.getStringTableForSymtab(*SymtabSec);
  error(StringTableOrErr);
  ErrorOr<StringRef> SignatureOrErr = Sym->getName(*StringTableOrErr);
  error(SignatureOrErr);
  return *SignatureOrErr;
}

template <class ELFT>
ArrayRef<typename ObjectFile<ELFT>::GroupEntryType>
ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) {
  const ELFFile<ELFT> &Obj = this->ELFObj;
  ErrorOr<ArrayRef<GroupEntryType>> EntriesOrErr =
      Obj.template getSectionContentsAsArray<GroupEntryType>(&Sec);
  error(EntriesOrErr.getError());
  ArrayRef<GroupEntryType> Entries = *EntriesOrErr;
  if (Entries.empty() || Entries[0] != GRP_COMDAT)
    error("Unsupported SHT_GROUP format");
  return Entries.slice(1);
}

template <class ELFT>
void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) {
  uint64_t Size = this->ELFObj.getNumSections();
  Sections.resize(Size);
  unsigned I = -1;
  const ELFFile<ELFT> &Obj = this->ELFObj;
  for (const Elf_Shdr &Sec : Obj.sections()) {
    ++I;
    if (Sections[I] == &InputSection<ELFT>::Discarded)
      continue;

    switch (Sec.sh_type) {
    case SHT_GROUP:
      Sections[I] = &InputSection<ELFT>::Discarded;
      if (Comdats.insert(getShtGroupSignature(Sec)).second)
        continue;
      for (GroupEntryType E : getShtGroupEntries(Sec)) {
        uint32_t SecIndex = E;
        if (SecIndex >= Size)
          error("Invalid section index in group");
        Sections[SecIndex] = &InputSection<ELFT>::Discarded;
      }
      break;
    case SHT_SYMTAB:
      this->Symtab = &Sec;
      break;
    case SHT_SYMTAB_SHNDX: {
      ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = Obj.getSHNDXTable(Sec);
      error(ErrorOrTable);
      SymtabSHNDX = *ErrorOrTable;
      break;
    }
    case SHT_STRTAB:
    case SHT_NULL:
      break;
    case SHT_RELA:
    case SHT_REL: {
      uint32_t RelocatedSectionIndex = Sec.sh_info;
      if (RelocatedSectionIndex >= Size)
        error("Invalid relocated section index");
      InputSection<ELFT> *RelocatedSection = Sections[RelocatedSectionIndex];
      if (!RelocatedSection)
        error("Unsupported relocation reference");
      RelocatedSection->RelocSections.push_back(&Sec);
      break;
    }
    default:
      Sections[I] = new (this->Alloc) InputSection<ELFT>(this, &Sec);
      break;
    }
  }
}

template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {
  this->initStringTable();
  Elf_Sym_Range Syms = this->getNonLocalSymbols();
  uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
  this->SymbolBodies.reserve(NumSymbols);
  for (const Elf_Sym &Sym : Syms)
    this->SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym));
}

template <class ELFT>
SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
                                                     const Elf_Sym *Sym) {
  ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable);
  error(NameOrErr.getError());
  StringRef Name = *NameOrErr;

  uint32_t SecIndex = Sym->st_shndx;
  switch (SecIndex) {
  case SHN_ABS:
    return new (this->Alloc) DefinedAbsolute<ELFT>(Name, *Sym);
  case SHN_UNDEF:
    return new (this->Alloc) Undefined<ELFT>(Name, *Sym);
  case SHN_COMMON:
    return new (this->Alloc) DefinedCommon<ELFT>(Name, *Sym);
  case SHN_XINDEX:
    SecIndex = this->ELFObj.getExtendedSymbolTableIndex(Sym, this->Symtab,
                                                        SymtabSHNDX);
    break;
  }

  if (SecIndex >= Sections.size() || !SecIndex || !Sections[SecIndex])
    error("Invalid section index");

  switch (Sym->getBinding()) {
  default:
    error("unexpected binding");
  case STB_GLOBAL:
  case STB_WEAK:
  case STB_GNU_UNIQUE: {
    InputSection<ELFT> *Sec = Sections[SecIndex];
    if (Sec == &InputSection<ELFT>::Discarded)
      return new (this->Alloc) Undefined<ELFT>(Name, *Sym);
    return new (this->Alloc) DefinedRegular<ELFT>(Name, *Sym, *Sec);
  }
  }
}

static std::unique_ptr<Archive> openArchive(MemoryBufferRef MB) {
  ErrorOr<std::unique_ptr<Archive>> ArchiveOrErr = Archive::create(MB);
  error(ArchiveOrErr, "Failed to parse archive");
  return std::move(*ArchiveOrErr);
}

void ArchiveFile::parse() {
  File = openArchive(MB);

  // Allocate a buffer for Lazy objects.
  size_t NumSyms = File->getNumberOfSymbols();
  LazySymbols.reserve(NumSyms);

  // Read the symbol table to construct Lazy objects.
  for (const Archive::Symbol &Sym : File->symbols())
    LazySymbols.emplace_back(this, Sym);
}

// Returns a buffer pointing to a member file containing a given symbol.
MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) {
  ErrorOr<Archive::child_iterator> ItOrErr = Sym->getMember();
  error(ItOrErr,
        Twine("Could not get the member for symbol ") + Sym->getName());
  Archive::child_iterator It = *ItOrErr;

  if (!Seen.insert(It->getChildOffset()).second)
    return MemoryBufferRef();

  ErrorOr<MemoryBufferRef> Ret = It->getMemoryBufferRef();
  error(Ret, Twine("Could not get the buffer for the member defining symbol ") +
                 Sym->getName());
  return *Ret;
}

std::vector<MemoryBufferRef> ArchiveFile::getMembers() {
  File = openArchive(MB);

  std::vector<MemoryBufferRef> Result;
  for (const Archive::Child &Child : File->children()) {
    ErrorOr<MemoryBufferRef> MbOrErr = Child.getMemoryBufferRef();
    error(MbOrErr,
          Twine("Could not get the buffer for a child of the archive ") +
              File->getFileName());
    Result.push_back(MbOrErr.get());
  }
  return Result;
}

template <class ELFT>
SharedFile<ELFT>::SharedFile(MemoryBufferRef M)
    : ELFFileBase<ELFT>(Base::SharedKind, Base::getStaticELFKind(), M) {
  AsNeeded = Config->AsNeeded;
}

template <class ELFT> void SharedFile<ELFT>::parseSoName() {
  typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
  typedef typename ELFFile<ELFT>::uintX_t uintX_t;
  const Elf_Shdr *DynamicSec = nullptr;

  const ELFFile<ELFT> Obj = this->ELFObj;
  for (const Elf_Shdr &Sec : Obj.sections()) {
    uint32_t Type = Sec.sh_type;
    if (Type == SHT_DYNSYM)
      this->Symtab = &Sec;
    else if (Type == SHT_DYNAMIC)
      DynamicSec = &Sec;
  }

  this->initStringTable();
  this->SoName = this->getName();

  if (DynamicSec) {
    auto *Begin =
        reinterpret_cast<const Elf_Dyn *>(Obj.base() + DynamicSec->sh_offset);
    const Elf_Dyn *End = Begin + DynamicSec->sh_size / sizeof(Elf_Dyn);

    for (const Elf_Dyn &Dyn : make_range(Begin, End)) {
      if (Dyn.d_tag == DT_SONAME) {
        uintX_t Val = Dyn.getVal();
        if (Val >= this->StringTable.size())
          error("Invalid DT_SONAME entry");
        this->SoName = StringRef(this->StringTable.data() + Val);
        break;
      }
    }
  }
}

template <class ELFT> void SharedFile<ELFT>::parse() {
  Elf_Sym_Range Syms = this->getNonLocalSymbols();
  uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
  SymbolBodies.reserve(NumSymbols);
  for (const Elf_Sym &Sym : Syms) {
    if (Sym.isUndefined())
      continue;

    ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable);
    error(NameOrErr.getError());
    StringRef Name = *NameOrErr;

    SymbolBodies.emplace_back(this, Name, Sym);
  }
}

namespace lld {
namespace elf2 {
template class ELFFileBase<llvm::object::ELF32LE>;
template class ELFFileBase<llvm::object::ELF32BE>;
template class ELFFileBase<llvm::object::ELF64LE>;
template class ELFFileBase<llvm::object::ELF64BE>;

template class ObjectFile<llvm::object::ELF32LE>;
template class ObjectFile<llvm::object::ELF32BE>;
template class ObjectFile<llvm::object::ELF64LE>;
template class ObjectFile<llvm::object::ELF64BE>;

template class SharedFile<llvm::object::ELF32LE>;
template class SharedFile<llvm::object::ELF32BE>;
template class SharedFile<llvm::object::ELF64LE>;
template class SharedFile<llvm::object::ELF64BE>;
}
}
<|endoftext|>


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

#include <geos/geomgraph.h>
//#include "../headers/util.h"

#ifndef DEBUG
#define DEBUG 0
#endif
#ifndef COMPUTE_Z
#define COMPUTE_Z 1
#endif

namespace geos {

Node::Node(Coordinate& newCoord, EdgeEndStar* newEdges): GraphComponent(new Label(0,Location::UNDEF)) {
	coord=newCoord;
#if DEBUG
	cerr<<"["<<this<<"] Node::Node("<<newCoord.toString()<<")"<<endl;
#endif

#if COMPUTE_Z
	ztot = 0;
	addZ(newCoord.z);
	if ( newEdges )
	{
		vector<EdgeEnd*>*eev = newEdges->getEdges();
		for (unsigned int i=0; i<eev->size(); i++)
		{
			EdgeEnd *ee = (*eev)[i];
			addZ(ee->getCoordinate().z);
		}
	}
#endif // COMPUTE_Z

	edges=newEdges;
}

Node::~Node(){
#if DEBUG
	cerr<<"["<<this<<"] Node::~Node()"<<endl;
#endif
	delete edges;
}

const Coordinate& Node::getCoordinate() const {
	return coord;
}

EdgeEndStar* Node::getEdges() {
	return edges;
}

bool Node::isIsolated() {
	return (label->getGeometryCount()==1);
}

void Node::add(EdgeEnd *e) {
#if DEBUG
	cerr<<"["<<this<<"] Node::add("<<e->print()<<")"<<endl;
#endif
	// Assert: start pt of e is equal to node point
	if (edges==NULL) edges=new EdgeEndStar();
	edges->insert(e);
	e->setNode(this);
#if COMPUTE_Z
	addZ(e->getCoordinate().z);
#endif
}

void Node::mergeLabel(const Node* n) {
	mergeLabel(n->label);
}

void Node::mergeLabel(const Label* label2) {
	for (int i=0; i<2; i++) {
		int loc=computeMergedLocation(label2, i);
		int thisLoc=label->getLocation(i);
		if (thisLoc==Location::UNDEF) label->setLocation(i,loc);
	}
}

void Node::setLabel(int argIndex, int onLocation) {
	if (label==NULL) {
		label=new Label(argIndex, onLocation);
	} else
		label->setLocation(argIndex, onLocation);
}

void Node::setLabelBoundary(int argIndex) {
	int loc=Location::UNDEF;
	if (label!=NULL)
		loc=label->getLocation(argIndex);
	// flip the loc
	int newLoc;
	switch (loc){
		case Location::BOUNDARY: newLoc=Location::INTERIOR; break;
		case Location::INTERIOR: newLoc=Location::BOUNDARY; break;
		default: newLoc=Location::BOUNDARY;  break;
	}
	label->setLocation(argIndex, newLoc);
}

int Node::computeMergedLocation(const Label* label2, int eltIndex){
	int loc=Location::UNDEF;
	loc=label->getLocation(eltIndex);
	if (!label2->isNull(eltIndex)) {
		int nLoc=label2->getLocation(eltIndex);
		if (loc!=Location::BOUNDARY) loc=nLoc;
	}
	return loc;
}

string Node::print(){
	string out="node "+coord.toString()+" lbl: "+label->toString();
	return out;
}

void
Node::addZ(double z)
{
#if DEBUG
	cerr<<"["<<this<<"] Node::addZ("<<z<<")";
#endif
	if ( ISNAN(z) )
	{
#if DEBUG
		cerr<<" skipped"<<endl;
#endif
		return;
	}
	for (unsigned int i=0; i<zvals.size(); i++) if ( zvals[i] == z )
	{
#if DEBUG
		cerr<<" already stored"<<endl;
#endif
		return;
	}
	zvals.push_back(z);
	ztot+=z;
	coord.z=ztot/zvals.size();
#if DEBUG
	cerr<<" added "<<z<<": ["<<ztot<<"/"<<zvals.size()<<"="<<coord.z<<"]"<<endl;
#endif
}

const vector<double>&
Node::getZ() const
{
	return zvals;
}

bool
Node::isIncidentEdgeInResult() const
{
	vector<EdgeEnd*>*v = edges->getEdges();
	unsigned int size = v->size();
	for (unsigned int i=0; i<size; i++)
	{
		DirectedEdge *de = (DirectedEdge *)(*v)[i];
		if ( de->isInResult() ) return true;
	}
	return false;
}

} // namespace geos

/**********************************************************************
 * $Log$
 * Revision 1.10.2.1  2005/06/26 09:40:19  strk
 * Backport of OverlayOp performance improvements
 *
 * Revision 1.10  2004/12/08 13:54:43  strk
 * gcc warnings checked and fixed, general cleanups.
 *
 * Revision 1.9  2004/11/29 16:05:33  strk
 * Fixed a bug in LineIntersector::interpolateZ causing NaN values
 * to come out.
 * Handled dimensional collapses in ElevationMatrix.
 * Added ISNAN macro and changed ISNAN/FINITE macros to avoid
 * dispendious isnan() and finite() calls.
 *
 * Revision 1.8  2004/11/26 09:53:48  strk
 * Added more FINITE calls, and added inf and -inf to FINITE checks
 *
 * Revision 1.7  2004/11/20 15:41:18  strk
 * Added management of vector of composing Z values.
 *
 * Revision 1.6  2004/11/19 10:10:23  strk
 * COMPUTE_Z re-enabled by default
 *
 * Revision 1.5  2004/11/17 15:09:08  strk
 * Changed COMPUTE_Z defaults to be more conservative
 *
 * Revision 1.4  2004/11/17 08:13:16  strk
 * Indentation changes.
 * Some Z_COMPUTATION activated by default.
 *
 * Revision 1.3  2004/10/21 22:29:54  strk
 * Indentation changes and some more COMPUTE_Z rules
 *
 * Revision 1.2  2004/07/02 13:28:26  strk
 * Fixed all #include lines to reflect headers layout change.
 * Added client application build tips in README.
 *
 * Revision 1.1  2004/03/19 09:48:45  ybychkov
 * "geomgraph" and "geomgraph/indexl" upgraded to JTS 1.4
 *
 * Revision 1.12  2003/11/07 01:23:42  pramsey
 * Add standard CVS headers licence notices and copyrights to all cpp and h
 * files.
 *
 *
 **********************************************************************/

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

#include <geos/geomgraph.h>
//#include "../headers/util.h"

#ifndef DEBUG
#define DEBUG 0
#endif
#ifndef COMPUTE_Z
#define COMPUTE_Z 1
#endif

namespace geos {

Node::Node(Coordinate& newCoord, EdgeEndStar* newEdges): GraphComponent(new Label(0,Location::UNDEF)) {
	coord=newCoord;
#if DEBUG
	cerr<<"["<<this<<"] Node::Node("<<newCoord.toString()<<")"<<endl;
#endif

#if COMPUTE_Z
	ztot = 0;
	addZ(newCoord.z);
	if ( newEdges )
	{
		vector<EdgeEnd*>*eev = newEdges->getEdges();
		for (unsigned int i=0; i<eev->size(); i++)
		{
			EdgeEnd *ee = (*eev)[i];
			addZ(ee->getCoordinate().z);
		}
	}
#endif // COMPUTE_Z

	edges=newEdges;
}

Node::~Node(){
#if DEBUG
	cerr<<"["<<this<<"] Node::~Node()"<<endl;
#endif
	delete edges;
}

const Coordinate& Node::getCoordinate() const {
	return coord;
}

EdgeEndStar* Node::getEdges() {
	return edges;
}

bool Node::isIsolated() {
	return (label->getGeometryCount()==1);
}

void Node::add(EdgeEnd *e) {
#if DEBUG
	cerr<<"["<<this<<"] Node::add("<<e->print()<<")"<<endl;
#endif
	// Assert: start pt of e is equal to node point
	if (edges==NULL) edges=new EdgeEndStar();
	edges->insert(e);
	e->setNode(this);
#if COMPUTE_Z
	addZ(e->getCoordinate().z);
#endif
}

void Node::mergeLabel(const Node* n) {
	mergeLabel(n->label);
}

void Node::mergeLabel(const Label* label2) {
	for (int i=0; i<2; i++) {
		int loc=computeMergedLocation(label2, i);
		int thisLoc=label->getLocation(i);
		if (thisLoc==Location::UNDEF) label->setLocation(i,loc);
	}
}

void Node::setLabel(int argIndex, int onLocation) {
	if (label==NULL) {
		label=new Label(argIndex, onLocation);
	} else
		label->setLocation(argIndex, onLocation);
}

void Node::setLabelBoundary(int argIndex) {
	int loc=Location::UNDEF;
	if (label!=NULL)
		loc=label->getLocation(argIndex);
	// flip the loc
	int newLoc;
	switch (loc){
		case Location::BOUNDARY: newLoc=Location::INTERIOR; break;
		case Location::INTERIOR: newLoc=Location::BOUNDARY; break;
		default: newLoc=Location::BOUNDARY;  break;
	}
	label->setLocation(argIndex, newLoc);
}

int Node::computeMergedLocation(const Label* label2, int eltIndex){
	int loc=Location::UNDEF;
	loc=label->getLocation(eltIndex);
	if (!label2->isNull(eltIndex)) {
		int nLoc=label2->getLocation(eltIndex);
		if (loc!=Location::BOUNDARY) loc=nLoc;
	}
	return loc;
}

string Node::print(){
	string out="node "+coord.toString()+" lbl: "+label->toString();
	return out;
}

void
Node::addZ(double z)
{
#if DEBUG
	cerr<<"["<<this<<"] Node::addZ("<<z<<")";
#endif
	if ( ISNAN(z) )
	{
#if DEBUG
		cerr<<" skipped"<<endl;
#endif
		return;
	}
	for (unsigned int i=0; i<zvals.size(); i++) if ( zvals[i] == z )
	{
#if DEBUG
		cerr<<" already stored"<<endl;
#endif
		return;
	}
	zvals.push_back(z);
	ztot+=z;
	coord.z=ztot/zvals.size();
#if DEBUG
	cerr<<" added "<<z<<": ["<<ztot<<"/"<<zvals.size()<<"="<<coord.z<<"]"<<endl;
#endif
}

const vector<double>&
Node::getZ() const
{
	return zvals;
}

bool
Node::isIncidentEdgeInResult() const
{
	vector<EdgeEnd*>*v = edges->getEdges();
	unsigned int size = v->size();
	for (unsigned int i=0; i<size; i++)
	{
		DirectedEdge *de = (DirectedEdge *)(*v)[i];
		if ( de->getEdge()->isInResult() ) return true;
	}
	return false;
}

} // namespace geos

/**********************************************************************
 * $Log$
 * Revision 1.10.2.2  2005/06/28 00:05:50  strk
 * improved ::isIncidentEdgeInResult() method
 *
 * Revision 1.10.2.1  2005/06/26 09:40:19  strk
 * Backport of OverlayOp performance improvements
 *
 * Revision 1.10  2004/12/08 13:54:43  strk
 * gcc warnings checked and fixed, general cleanups.
 *
 * Revision 1.9  2004/11/29 16:05:33  strk
 * Fixed a bug in LineIntersector::interpolateZ causing NaN values
 * to come out.
 * Handled dimensional collapses in ElevationMatrix.
 * Added ISNAN macro and changed ISNAN/FINITE macros to avoid
 * dispendious isnan() and finite() calls.
 *
 * Revision 1.8  2004/11/26 09:53:48  strk
 * Added more FINITE calls, and added inf and -inf to FINITE checks
 *
 * Revision 1.7  2004/11/20 15:41:18  strk
 * Added management of vector of composing Z values.
 *
 * Revision 1.6  2004/11/19 10:10:23  strk
 * COMPUTE_Z re-enabled by default
 *
 * Revision 1.5  2004/11/17 15:09:08  strk
 * Changed COMPUTE_Z defaults to be more conservative
 *
 * Revision 1.4  2004/11/17 08:13:16  strk
 * Indentation changes.
 * Some Z_COMPUTATION activated by default.
 *
 * Revision 1.3  2004/10/21 22:29:54  strk
 * Indentation changes and some more COMPUTE_Z rules
 *
 * Revision 1.2  2004/07/02 13:28:26  strk
 * Fixed all #include lines to reflect headers layout change.
 * Added client application build tips in README.
 *
 * Revision 1.1  2004/03/19 09:48:45  ybychkov
 * "geomgraph" and "geomgraph/indexl" upgraded to JTS 1.4
 *
 * Revision 1.12  2003/11/07 01:23:42  pramsey
 * Add standard CVS headers licence notices and copyrights to all cpp and h
 * files.
 *
 *
 **********************************************************************/

<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

/*
 * 最长公共子列
 *
 * 问题描述：
 * 给定两个子列，找到他们的最长公共子列的长度，子列只要求保持相对位置不变
 * 例如：acf 是 abcdefg的一个子列
 */

/*
 * 问题解决思路：
 * 考虑两个序列 X[0...m-1] 和 Y[0...n-1]的最后一个字母是否被LCS匹配到？
 * 如果被匹配到(X[m-1] == Y[n-1]) 则
 * LCS(x[0...m-1], Y[0...n-1]) = 1 + LCS(x[0...m-2], Y[0...n-2]);
 * 如果没有被匹配到(X[m-1] != Y[n-1]) 则
 * LCS(x[0...m-1], Y[0...n-1] = max{LCS(X[0...m-1], Y[0...n-2]), LCS(X[0...m-2],Y[0...n-1])}
 *
 * 初始条件：如果其中一个子列长度为0，则LCS=0；
 */

/* 定义L[i][j]表示X[0...i-1] 和 Y[0...j-1]的LCS
 *
 * 则 L[0][j] = 0 for all j
 *    L[i][0] = 0 for all i
 * LCS(X, Y) = L[m][n]
 *
 * 注意：L[i][j]表示的长度为i的X和长度为j的Y的LCS
 *       因此维度要比以前的数组各加1，注意边界情况
 */

int LCS(char* X, char* Y, int m, int n)
{
	int L[m + 1][n + 1];
	//vector<vector<int> > L(m + 1, vector<int>(n + 1));

	// init
	for (int j = 0; j <= n; ++j) L[0][j] = 0;
	for (int i = 0; i <= m; ++i) L[i][0] = 0;

	// DP by bottom to up
	for (int i = 1; i <= n; ++i)
	{
		for (int j = 1; j <= n; ++j)
		{
			if (X[i-1] == Y[j-1])
			{
				L[i][j] = 1 + L[i-1][j-1];
			}
			else
			{
				L[i][j] = max(L[i-1][j], L[i][j-1]);
			}
		}
	}

	// print the LCS;
	int ii = m; int jj = n;
	int index = L[m][n];

	char lcs[index+1]; lcs[index] = '\0';
	while(ii > 0 && jj > 0)
	{
		if (X[ii-1] == Y[jj-1])
		{
			lcs[index-1] = X[ii-1];
			ii--;
			jj--;
			index--;
		}
		else if (L[ii-1][jj] > L[ii][jj-1])
		{
			ii--;
		}
		else
		{
			jj--;
		}
	}

	cout << "The LCS is: " << lcs << endl;

	/*
	// print table
	for (int i = 0; i <= m; ++i)
	{
		for (int j = 0; j <= n; ++j)
		{
			cout <<" " << L[i][j];
		}
		cout << endl;
	}
	*/

	return L[m][n];
}
/* 复杂度分析：
 * 时间复杂度：O(mn)
 * 空间复杂度：O(mn)
 */

int main()
{
	char X[] = "AGGTAB";
	char Y[] = "GXTXAYB";

	int m = strlen(X);
	int n = strlen(Y);
	int ans = LCS(X, Y, m, n);

	cout << "The Length of LCS is : " << ans << endl;
	return 0;
}
<commit_msg>fix index bug<commit_after>#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

/*
 * 最长公共子列
 *
 * 问题描述：
 * 给定两个子列，找到他们的最长公共子列的长度，子列只要求保持相对位置不变
 * 例如：acf 是 abcdefg的一个子列
 */

/*
 * 问题解决思路：
 * 考虑两个序列 X[0...m-1] 和 Y[0...n-1]的最后一个字母是否被LCS匹配到？
 * 如果被匹配到(X[m-1] == Y[n-1]) 则
 * LCS(x[0...m-1], Y[0...n-1]) = 1 + LCS(x[0...m-2], Y[0...n-2]);
 * 如果没有被匹配到(X[m-1] != Y[n-1]) 则
 * LCS(x[0...m-1], Y[0...n-1] = max{LCS(X[0...m-1], Y[0...n-2]), LCS(X[0...m-2],Y[0...n-1])}
 *
 * 初始条件：如果其中一个子列长度为0，则LCS=0；
 */

/* 定义L[i][j]表示X[0...i-1] 和 Y[0...j-1]的LCS
 *
 * 则 L[0][j] = 0 for all j
 *    L[i][0] = 0 for all i
 * LCS(X, Y) = L[m][n]
 *
 * 注意：L[i][j]表示的长度为i的X和长度为j的Y的LCS
 *       因此维度要比以前的数组各加1，注意边界情况
 */

int LCS(char* X, char* Y, int m, int n)
{
	int L[m + 1][n + 1];
	//vector<vector<int> > L(m + 1, vector<int>(n + 1));

	// init
	for (int j = 0; j <= n; ++j) L[0][j] = 0;
	for (int i = 0; i <= m; ++i) L[i][0] = 0;

	// DP by bottom to up
	for (int i = 1; i <= m; ++i)
	{
		for (int j = 1; j <= n; ++j)
		{
			if (X[i-1] == Y[j-1])
			{
				L[i][j] = 1 + L[i-1][j-1];
			}
			else
			{
				L[i][j] = max(L[i-1][j], L[i][j-1]);
			}
		}
	}

	// print the LCS;
	int ii = m; int jj = n;
	int index = L[m][n];

	char lcs[index+1]; lcs[index] = '\0';
	while(ii > 0 && jj > 0)
	{
		if (X[ii-1] == Y[jj-1])
		{
			lcs[index-1] = X[ii-1];
			ii--;
			jj--;
			index--;
		}
		else if (L[ii-1][jj] > L[ii][jj-1])
		{
			ii--;
		}
		else
		{
			jj--;
		}
	}

	cout << "The LCS is: " << lcs << endl;

	/*
	// print table
	for (int i = 0; i <= m; ++i)
	{
		for (int j = 0; j <= n; ++j)
		{
			cout <<" " << L[i][j];
		}
		cout << endl;
	}
	*/

	return L[m][n];
}
/* 复杂度分析：
 * 时间复杂度：O(mn)
 * 空间复杂度：O(mn)
 */

int main()
{
	char X[] = "AGGTAB";
	char Y[] = "GXTXAYB";

	int m = strlen(X);
	int n = strlen(Y);
	int ans = LCS(X, Y, m, n);

	cout << "The Length of LCS is : " << ans << endl;
	return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: spritecanvas.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-09-08 16:58:33 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _CPPCANVAS_SPRITECANVAS_HXX
#define _CPPCANVAS_SPRITECANVAS_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef _BGFX_VECTOR_B2DSIZE_HXX
#include <basegfx/vector/b2dsize.hxx>
#endif

#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
#include <boost/shared_ptr.hpp>
#endif

#ifndef _CPPCANVAS_BITMAPCANVAS_HXX
#include <cppcanvas/bitmapcanvas.hxx>
#endif
#ifndef _CPPCANVAS_SPRITE_HXX
#include <cppcanvas/sprite.hxx>
#endif
#ifndef _CPPCANVAS_CUSTOMSPRITE_HXX
#include <cppcanvas/customsprite.hxx>
#endif

namespace drafts { namespace com { namespace sun { namespace star { namespace rendering
{
    class  XSpriteCanvas;
} } } } }

/* Definition of SpriteCanvas */

namespace cppcanvas
{
    class SpriteCanvas;

    // forward declaration, since cloneSpriteCanvas() also references SpriteCanvas
    typedef ::boost::shared_ptr< ::cppcanvas::SpriteCanvas > SpriteCanvasSharedPtr;

    /** SpriteCanvas interface
     */
    class SpriteCanvas : public virtual BitmapCanvas
    {
    public:
        virtual bool                    updateScreen() const = 0;

        virtual CustomSpriteSharedPtr   createCustomSprite( const ::basegfx::B2DSize& ) const = 0;
        virtual SpriteSharedPtr         createClonedSprite( const SpriteSharedPtr& ) const = 0;

        virtual SpriteCanvasSharedPtr   cloneSpriteCanvas() const = 0; // shared_ptr does not allow for covariant return types

        virtual ::com::sun::star::uno::Reference<
            ::drafts::com::sun::star::rendering::XSpriteCanvas >    getUNOSpriteCanvas() const = 0;
    };

}

#endif /* _CPPCANVAS_SPRITECANVAS_HXX */
<commit_msg>INTEGRATION: CWS presentationengine01 (1.2.2); FILE MERGED 2004/08/27 18:49:14 thb 1.2.2.6: #110496# Adapted to recent canvas API changes (XSpriteCanvas::updateScreen) 2004/08/19 17:21:08 thb 1.2.2.5: #110496# Switched from deprecated to recommended shared_ptr dynamic cast method 2004/07/20 19:08:43 thb 1.2.2.4: #110496# Unified include statements; removed external prefix from boost includes 2004/06/25 14:01:07 thb 1.2.2.3: #100000# Old boost does not have operator bool on shared_ptr 2004/06/25 10:30:18 thb 1.2.2.2: #110496# Some header cleanups (missing forward declarations), changed Canvas and derived to emulate covariant return types on clone() (not directly possible with shared_ptr) 2004/04/05 15:58:44 thb 1.2.2.1: Resync with canvas01 changes<commit_after>/*************************************************************************
 *
 *  $RCSfile: spritecanvas.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-11-26 20:52:28 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _CPPCANVAS_SPRITECANVAS_HXX
#define _CPPCANVAS_SPRITECANVAS_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _BGFX_VECTOR_B2DSIZE_HXX
#include <basegfx/vector/b2dsize.hxx>
#endif

#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
#include <boost/shared_ptr.hpp>
#endif

#ifndef _CPPCANVAS_BITMAPCANVAS_HXX
#include <cppcanvas/bitmapcanvas.hxx>
#endif
#ifndef _CPPCANVAS_SPRITE_HXX
#include <cppcanvas/sprite.hxx>
#endif
#ifndef _CPPCANVAS_CUSTOMSPRITE_HXX
#include <cppcanvas/customsprite.hxx>
#endif

namespace drafts { namespace com { namespace sun { namespace star { namespace rendering
{
    class  XSpriteCanvas;
} } } } }

/* Definition of SpriteCanvas */

namespace cppcanvas
{
    class SpriteCanvas;

    // forward declaration, since cloneSpriteCanvas() also references SpriteCanvas
    typedef ::boost::shared_ptr< ::cppcanvas::SpriteCanvas > SpriteCanvasSharedPtr;

    /** SpriteCanvas interface
     */
    class SpriteCanvas : public virtual BitmapCanvas
    {
    public:
        virtual bool                    updateScreen( bool bUpdateAll ) const = 0;

        virtual CustomSpriteSharedPtr   createCustomSprite( const ::basegfx::B2DSize& ) const = 0;
        virtual SpriteSharedPtr         createClonedSprite( const SpriteSharedPtr& ) const = 0;

        // shared_ptr does not allow for covariant return types
        SpriteCanvasSharedPtr           cloneSpriteCanvas() const
        {
            SpriteCanvasSharedPtr p( ::boost::dynamic_pointer_cast< SpriteCanvas >(this->clone()) );
            OSL_ENSURE(p.get(), "SpriteCanvas::cloneSpriteCanvas(): dynamic cast failed");
            return p;
        }

        virtual ::com::sun::star::uno::Reference<
            ::drafts::com::sun::star::rendering::XSpriteCanvas >    getUNOSpriteCanvas() const = 0;
    };

}

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


<commit_before>//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.

#include <cassert>
#include <vector>
#include <set>

#include "llvm/IR/DataLayout.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/TypeBuilder.h"
#if LLVM_VERSION_MAJOR >= 4 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5)
  #include "llvm/IR/InstIterator.h"
#else
  #include "llvm/Support/InstIterator.h"
#endif
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include <llvm/IR/DebugInfoMetadata.h>

using namespace llvm;

namespace {

class MarkVolatile : public FunctionPass {
  public:
    static char ID;

    MarkVolatile() : FunctionPass(ID) {}

    virtual bool runOnFunction(Function &F);
};

bool MarkVolatile::runOnFunction(Function &F)
{
  bool modified = false;

  for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
    Instruction *ins = &*I;
    if (CallInst *CI = dyn_cast<CallInst>(ins)) {
      if (CI->isInlineAsm())
        continue;

      const Value *val = CI->getCalledValue()->stripPointerCasts();
      const Function *callee = dyn_cast<Function>(val);
      if (!callee || callee->isIntrinsic())
        continue;

      assert(callee->hasName());
      StringRef name = callee->getName();

      if (!name.startswith("__INSTR_mark_pointer"))
        continue;

      // we found a marked instruction, make it volatile
      // if it is store or load
      auto nextIt = I;
      ++nextIt;
      if (StoreInst *SI = dyn_cast<StoreInst>(&*nextIt)) {
          SI->setVolatile(true);
          modified = true;
      } else if (LoadInst *LI = dyn_cast<LoadInst>(&*nextIt)) {
          LI->setVolatile(true);
          modified = true;
      } else {
          errs() << "[Warning]: this marked instruction was not made volatile:\n";
          errs() << *nextIt << "\n";
      }
    }
  }
  return modified;
}

} // namespace

static RegisterPass<MarkVolatile> MVLTL("mark-volatile",
                                        "Make marked instructions as volatile");
char MarkVolatile::ID;

<commit_msg>MarkVolatile: mark also memintrinsic functions as volatile<commit_after>//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.

#include <cassert>
#include <vector>
#include <set>

#include "llvm/IR/DataLayout.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/TypeBuilder.h"
#if LLVM_VERSION_MAJOR >= 4 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5)
  #include "llvm/IR/InstIterator.h"
#else
  #include "llvm/Support/InstIterator.h"
#endif
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include <llvm/IR/DebugInfoMetadata.h>

using namespace llvm;

namespace {

class MarkVolatile : public FunctionPass {
  public:
    static char ID;

    MarkVolatile() : FunctionPass(ID) {}

    virtual bool runOnFunction(Function &F);
};

bool MarkVolatile::runOnFunction(Function &F)
{
  bool modified = false;
  LLVMContext& ctx = F.getParent()->getContext();

  for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
    Instruction *ins = &*I;
    if (CallInst *CI = dyn_cast<CallInst>(ins)) {
      if (CI->isInlineAsm())
        continue;

      const Value *val = CI->getCalledValue()->stripPointerCasts();
      const Function *callee = dyn_cast<Function>(val);
      if (!callee || callee->isIntrinsic())
        continue;

      assert(callee->hasName());
      StringRef name = callee->getName();

      if (!name.startswith("__INSTR_mark_pointer"))
        continue;

      // we found a marked instruction, make it volatile
      // if it is store or load
      auto nextIt = I;
      ++nextIt;
      if (StoreInst *SI = dyn_cast<StoreInst>(&*nextIt)) {
          SI->setVolatile(true);
          modified = true;
      } else if (LoadInst *LI = dyn_cast<LoadInst>(&*nextIt)) {
          LI->setVolatile(true);
          modified = true;
      } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&*nextIt)) {
          MI->setVolatile(ConstantInt::getTrue(ctx));
          modified = true;
      } else {
          errs() << "[Warning]: this marked instruction was not made volatile:\n";
          errs() << *nextIt << "\n";
      }
    }
  }
  return modified;
}

} // namespace

static RegisterPass<MarkVolatile> MVLTL("mark-volatile",
                                        "Make marked instructions as volatile");
char MarkVolatile::ID;

<|endoftext|>


<commit_before>/*
 * SPDX-FileCopyrightText: 2017-2017 CSSlayer <wengxt@gmail.com>
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 */
#include "ime.h"
#include "config.h"
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream_buffer.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <fcitx-config/iniparser.h>
#include <fcitx-utils/log.h>
#include <fcitx-utils/standardpath.h>
#include <fcntl.h>
#include <libime/core/utils.h>
#include <libime/table/tablebaseddictionary.h>
#include <libime/table/tableoptions.h>

namespace fcitx {

FCITX_DEFINE_LOG_CATEGORY(table_logcategory, "table")

namespace {

libime::OrderPolicy converOrderPolicy(fcitx::OrderPolicy policy) {
    switch (policy) {
#define POLICY_CONVERT(NAME)                                                   \
    case fcitx::OrderPolicy::NAME:                                             \
        return libime::OrderPolicy::NAME;
        POLICY_CONVERT(No)
        POLICY_CONVERT(Freq)
        POLICY_CONVERT(Fast)
    }
    return libime::OrderPolicy::Freq;
}

void populateOptions(libime::TableBasedDictionary *dict,
                     const TableConfigRoot &root) {
    libime::TableOptions options;

    options.setOrderPolicy(converOrderPolicy(*root.config->orderPolicy));
    options.setNoSortInputLength(*root.config->noSortInputLength);
    options.setAutoSelect(*root.config->autoSelect);
    options.setAutoSelectLength(*root.config->autoSelectLength);
    options.setNoMatchAutoSelectLength(*root.config->noMatchAutoSelectLength);
    options.setCommitRawInput(*root.config->commitRawInput);
    options.setMatchingKey(
        Key::keySymToUnicode(root.config->matchingKey->sym()));
    std::set<uint32_t> endKeys;
    TABLE_DEBUG() << "End key" << *root.config->endKey;
    for (const auto &key : *root.config->endKey) {
        auto chr = Key::keySymToUnicode(key.sym());
        if (chr) {
            endKeys.insert(chr);
        }
    }
    options.setEndKey(endKeys);
    options.setExactMatch(*root.config->exactMatch);
    options.setLearning(*root.config->learning);
    options.setAutoPhraseLength(*root.config->autoPhraseLength);
    options.setSaveAutoPhraseAfter(*root.config->saveAutoPhraseAfter);
    options.setAutoRuleSet(std::unordered_set<std::string>(
        root.config->autoRuleSet->begin(), root.config->autoRuleSet->end()));
    options.setLanguageCode(*root.im->languageCode);

    dict->setTableOptions(options);
}
} // namespace

TableIME::TableIME(libime::LanguageModelResolver *lm) : lm_(lm) {}

std::tuple<libime::TableBasedDictionary *, libime::UserLanguageModel *,
           const TableConfig *>
TableIME::requestDict(const std::string &name) {
    auto iter = tables_.find(name);
    if (iter == tables_.end()) {
        TABLE_DEBUG() << "Load table config for: " << name;
        std::string filename = "inputmethod/";
        filename.append(name.begin(), name.end());
        filename += ".conf";
        auto files = StandardPath::global().openAll(StandardPath::Type::PkgData,
                                                    filename, O_RDONLY);
        RawConfig rawConfig;
        // reverse the order, so we end up parse user file at last.
        for (const auto &file : files | boost::adaptors::reversed) {
            readFromIni(rawConfig, file.fd());
        }

        iter = tables_
                   .emplace(std::piecewise_construct, std::make_tuple(name),
                            std::make_tuple())
                   .first;
        auto &root = iter->second.root;
        root.load(rawConfig);

        try {
            auto dict = std::make_unique<libime::TableBasedDictionary>();
            auto dictFile = StandardPath::global().open(
                StandardPath::Type::PkgData, *root.config->file, O_RDONLY);
            TABLE_DEBUG() << "Load table at: " << *root.config->file;
            if (dictFile.fd() < 0) {
                throw std::runtime_error("Couldn't open file");
            }
            boost::iostreams::stream_buffer<
                boost::iostreams::file_descriptor_source>
                buffer(dictFile.fd(), boost::iostreams::file_descriptor_flags::
                                          never_close_handle);
            std::istream in(&buffer);
            dict->load(in);
            iter->second.dict = std::move(dict);
        } catch (const std::exception &) {
        }

        if (auto dict = iter->second.dict.get()) {
            try {
                auto dictFile = StandardPath::global().openUser(
                    StandardPath::Type::PkgData,
                    stringutils::concat("table/", name, ".user.dict"),
                    O_RDONLY);
                boost::iostreams::stream_buffer<
                    boost::iostreams::file_descriptor_source>
                    buffer(dictFile.fd(),
                           boost::iostreams::file_descriptor_flags::
                               never_close_handle);
                std::istream in(&buffer);
                dict->loadUser(in);
            } catch (const std::exception &e) {
                TABLE_DEBUG() << e.what();
            }

            populateOptions(dict, iter->second.root);
            std::shared_ptr<const libime::StaticLanguageModelFile> lmFile;
            try {
                lmFile = lm_->languageModelFileForLanguage(
                    dict->tableOptions().languageCode());
            } catch (...) {
                TABLE_DEBUG()
                    << "Load language model for "
                    << dict->tableOptions().languageCode() << " failed.";
            }
            iter->second.model =
                std::make_unique<libime::UserLanguageModel>(lmFile);

            try {
                auto dictFile = StandardPath::global().openUser(
                    StandardPath::Type::PkgData,
                    stringutils::concat("table/", name, ".history"), O_RDONLY);
                boost::iostreams::stream_buffer<
                    boost::iostreams::file_descriptor_source>
                    buffer(dictFile.fd(),
                           boost::iostreams::file_descriptor_flags::
                               never_close_handle);
                std::istream in(&buffer);
                iter->second.model->load(in);
            } catch (const std::exception &e) {
                TABLE_DEBUG() << e.what();
            }
        }
    }

    return {iter->second.dict.get(), iter->second.model.get(),
            &(*iter->second.root.config)};
}

void TableIME::saveAll() {
    for (const auto &p : tables_) {
        saveDict(p.first);
    }
}

void TableIME::updateConfig(const std::string &name, const RawConfig &config) {
    auto iter = tables_.find(name);
    if (iter == tables_.end()) {
        return;
    }
    iter->second.root.config.mutableValue()->load(config, true);

    if (iter->second.dict) {
        populateOptions(iter->second.dict.get(), iter->second.root);
    }
    safeSaveAsIni(iter->second.root, StandardPath::Type::PkgData,
                  stringutils::concat("inputmethod/", name, ".conf"));
}

void TableIME::releaseUnusedDict(const std::unordered_set<std::string> &names) {
    for (auto iter = tables_.begin(); iter != tables_.end();) {
        if (names.count(iter->first) == 0) {
            TABLE_DEBUG() << "Release unused table: " << iter->first;
            saveDict(iter->first);
            iter = tables_.erase(iter);
        } else {
            ++iter;
        }
    }
}

void TableIME::saveDict(const std::string &name) {
    auto iter = tables_.find(name);
    if (iter == tables_.end()) {
        return;
    }
    libime::TableBasedDictionary *dict = iter->second.dict.get();
    libime::UserLanguageModel *lm = iter->second.model.get();
    if (!dict || !lm || !*iter->second.root.config->learning) {
        return;
    }
    auto fileName = stringutils::joinPath("table", name);

    StandardPath::global().safeSave(
        StandardPath::Type::PkgData, fileName + ".user.dict", [dict](int fd) {
            boost::iostreams::stream_buffer<
                boost::iostreams::file_descriptor_sink>
                buffer(fd, boost::iostreams::file_descriptor_flags::
                               never_close_handle);
            std::ostream out(&buffer);
            try {
                dict->saveUser(out);
                return static_cast<bool>(out);
            } catch (const std::exception &) {
                return false;
            }
        });

    StandardPath::global().safeSave(
        StandardPath::Type::PkgData, fileName + ".history", [lm](int fd) {
            boost::iostreams::stream_buffer<
                boost::iostreams::file_descriptor_sink>
                buffer(fd, boost::iostreams::file_descriptor_flags::
                               never_close_handle);
            std::ostream out(&buffer);
            try {
                lm->save(out);
                return static_cast<bool>(out);
            } catch (const std::exception &) {
                return false;
            }
        });
}
} // namespace fcitx
<commit_msg>Make sure when we save im config, we don't override other part of it.<commit_after>/*
 * SPDX-FileCopyrightText: 2017-2017 CSSlayer <wengxt@gmail.com>
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 */
#include "ime.h"
#include "config.h"
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream_buffer.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <fcitx-config/iniparser.h>
#include <fcitx-utils/log.h>
#include <fcitx-utils/standardpath.h>
#include <fcntl.h>
#include <libime/core/utils.h>
#include <libime/table/tablebaseddictionary.h>
#include <libime/table/tableoptions.h>

namespace fcitx {

FCITX_DEFINE_LOG_CATEGORY(table_logcategory, "table")

namespace {

libime::OrderPolicy converOrderPolicy(fcitx::OrderPolicy policy) {
    switch (policy) {
#define POLICY_CONVERT(NAME)                                                   \
    case fcitx::OrderPolicy::NAME:                                             \
        return libime::OrderPolicy::NAME;
        POLICY_CONVERT(No)
        POLICY_CONVERT(Freq)
        POLICY_CONVERT(Fast)
    }
    return libime::OrderPolicy::Freq;
}

void populateOptions(libime::TableBasedDictionary *dict,
                     const TableConfigRoot &root) {
    libime::TableOptions options;

    options.setOrderPolicy(converOrderPolicy(*root.config->orderPolicy));
    options.setNoSortInputLength(*root.config->noSortInputLength);
    options.setAutoSelect(*root.config->autoSelect);
    options.setAutoSelectLength(*root.config->autoSelectLength);
    options.setNoMatchAutoSelectLength(*root.config->noMatchAutoSelectLength);
    options.setCommitRawInput(*root.config->commitRawInput);
    options.setMatchingKey(
        Key::keySymToUnicode(root.config->matchingKey->sym()));
    std::set<uint32_t> endKeys;
    TABLE_DEBUG() << "End key" << *root.config->endKey;
    for (const auto &key : *root.config->endKey) {
        auto chr = Key::keySymToUnicode(key.sym());
        if (chr) {
            endKeys.insert(chr);
        }
    }
    options.setEndKey(endKeys);
    options.setExactMatch(*root.config->exactMatch);
    options.setLearning(*root.config->learning);
    options.setAutoPhraseLength(*root.config->autoPhraseLength);
    options.setSaveAutoPhraseAfter(*root.config->saveAutoPhraseAfter);
    options.setAutoRuleSet(std::unordered_set<std::string>(
        root.config->autoRuleSet->begin(), root.config->autoRuleSet->end()));
    options.setLanguageCode(*root.im->languageCode);

    dict->setTableOptions(options);
}
} // namespace

TableIME::TableIME(libime::LanguageModelResolver *lm) : lm_(lm) {}

std::tuple<libime::TableBasedDictionary *, libime::UserLanguageModel *,
           const TableConfig *>
TableIME::requestDict(const std::string &name) {
    auto iter = tables_.find(name);
    if (iter == tables_.end()) {
        TABLE_DEBUG() << "Load table config for: " << name;
        std::string filename = "inputmethod/";
        filename.append(name.begin(), name.end());
        filename += ".conf";
        auto files = StandardPath::global().openAll(StandardPath::Type::PkgData,
                                                    filename, O_RDONLY);
        RawConfig rawConfig;
        // reverse the order, so we end up parse user file at last.
        for (const auto &file : files | boost::adaptors::reversed) {
            readFromIni(rawConfig, file.fd());
        }

        iter = tables_
                   .emplace(std::piecewise_construct, std::make_tuple(name),
                            std::make_tuple())
                   .first;
        auto &root = iter->second.root;
        root.load(rawConfig);

        try {
            auto dict = std::make_unique<libime::TableBasedDictionary>();
            auto dictFile = StandardPath::global().open(
                StandardPath::Type::PkgData, *root.config->file, O_RDONLY);
            TABLE_DEBUG() << "Load table at: " << *root.config->file;
            if (dictFile.fd() < 0) {
                throw std::runtime_error("Couldn't open file");
            }
            boost::iostreams::stream_buffer<
                boost::iostreams::file_descriptor_source>
                buffer(dictFile.fd(), boost::iostreams::file_descriptor_flags::
                                          never_close_handle);
            std::istream in(&buffer);
            dict->load(in);
            iter->second.dict = std::move(dict);
        } catch (const std::exception &) {
        }

        if (auto dict = iter->second.dict.get()) {
            try {
                auto dictFile = StandardPath::global().openUser(
                    StandardPath::Type::PkgData,
                    stringutils::concat("table/", name, ".user.dict"),
                    O_RDONLY);
                boost::iostreams::stream_buffer<
                    boost::iostreams::file_descriptor_source>
                    buffer(dictFile.fd(),
                           boost::iostreams::file_descriptor_flags::
                               never_close_handle);
                std::istream in(&buffer);
                dict->loadUser(in);
            } catch (const std::exception &e) {
                TABLE_DEBUG() << e.what();
            }

            populateOptions(dict, iter->second.root);
            std::shared_ptr<const libime::StaticLanguageModelFile> lmFile;
            try {
                lmFile = lm_->languageModelFileForLanguage(
                    dict->tableOptions().languageCode());
            } catch (...) {
                TABLE_DEBUG()
                    << "Load language model for "
                    << dict->tableOptions().languageCode() << " failed.";
            }
            iter->second.model =
                std::make_unique<libime::UserLanguageModel>(lmFile);

            try {
                auto dictFile = StandardPath::global().openUser(
                    StandardPath::Type::PkgData,
                    stringutils::concat("table/", name, ".history"), O_RDONLY);
                boost::iostreams::stream_buffer<
                    boost::iostreams::file_descriptor_source>
                    buffer(dictFile.fd(),
                           boost::iostreams::file_descriptor_flags::
                               never_close_handle);
                std::istream in(&buffer);
                iter->second.model->load(in);
            } catch (const std::exception &e) {
                TABLE_DEBUG() << e.what();
            }
        }
    }

    return {iter->second.dict.get(), iter->second.model.get(),
            &(*iter->second.root.config)};
}

void TableIME::saveAll() {
    for (const auto &p : tables_) {
        saveDict(p.first);
    }
}

void TableIME::updateConfig(const std::string &name, const RawConfig &config) {
    auto iter = tables_.find(name);
    if (iter == tables_.end()) {
        return;
    }
    iter->second.root.config.mutableValue()->load(config, true);

    if (iter->second.dict) {
        populateOptions(iter->second.dict.get(), iter->second.root);
    }

    // Load existing user level config, in order to avoid overwrite user config.
    RawConfig existingConfig;
    {
        auto file = StandardPath::global().openUser(
            StandardPath::Type::PkgData,
            stringutils::concat("inputmethod/", name, ".conf"), O_RDONLY);
        if (file.fd() >= 0) {
            readFromIni(existingConfig, file.fd());
        }
    }
    iter->second.root.save(existingConfig);
    safeSaveAsIni(existingConfig, StandardPath::Type::PkgData,
                  stringutils::concat("inputmethod/", name, ".conf"));
}

void TableIME::releaseUnusedDict(const std::unordered_set<std::string> &names) {
    for (auto iter = tables_.begin(); iter != tables_.end();) {
        if (names.count(iter->first) == 0) {
            TABLE_DEBUG() << "Release unused table: " << iter->first;
            saveDict(iter->first);
            iter = tables_.erase(iter);
        } else {
            ++iter;
        }
    }
}

void TableIME::saveDict(const std::string &name) {
    auto iter = tables_.find(name);
    if (iter == tables_.end()) {
        return;
    }
    libime::TableBasedDictionary *dict = iter->second.dict.get();
    libime::UserLanguageModel *lm = iter->second.model.get();
    if (!dict || !lm || !*iter->second.root.config->learning) {
        return;
    }
    auto fileName = stringutils::joinPath("table", name);

    StandardPath::global().safeSave(
        StandardPath::Type::PkgData, fileName + ".user.dict", [dict](int fd) {
            boost::iostreams::stream_buffer<
                boost::iostreams::file_descriptor_sink>
                buffer(fd, boost::iostreams::file_descriptor_flags::
                               never_close_handle);
            std::ostream out(&buffer);
            try {
                dict->saveUser(out);
                return static_cast<bool>(out);
            } catch (const std::exception &) {
                return false;
            }
        });

    StandardPath::global().safeSave(
        StandardPath::Type::PkgData, fileName + ".history", [lm](int fd) {
            boost::iostreams::stream_buffer<
                boost::iostreams::file_descriptor_sink>
                buffer(fd, boost::iostreams::file_descriptor_flags::
                               never_close_handle);
            std::ostream out(&buffer);
            try {
                lm->save(out);
                return static_cast<bool>(out);
            } catch (const std::exception &) {
                return false;
            }
        });
}
} // namespace fcitx
<|endoftext|>


<commit_before>#include <map>

#include <unistd.h>

#include "database.hpp"

#include "cmap.hpp"

#define MAX_COLLECTIONS 100
#define WRITE_INTERVAL  30

using namespace std;

static int backup = -1;

struct Coll {
  pthread_mutex_t mutex;
  string name;
  cmap<int,JSON> documents;
  Coll() : mutex(PTHREAD_MUTEX_INITIALIZER) {}
  void read() { // this function is called only once, by a locked piece of code
    JSON tmp;
    if (!tmp.read_file("database/"+name+".json")) return;
    for (auto& doc : tmp.arr()) documents[doc("_id")] = doc("document");
  }
  void write() {
    JSON tmp(vector<JSON>{});
    pthread_mutex_lock(&mutex);
    for (auto& kv : documents) tmp.emplace_back(move(map<string,JSON>{
      {"_id"      , kv.first},
      {"document" , kv.second}
    }));
    pthread_mutex_unlock(&mutex);
    tmp.write_file("database/"+name+".json");
  }
  int create(JSON&& doc) {
    int id = 1;
    pthread_mutex_lock(&mutex);
    if (documents.size() > 0) id += documents.max_key();
    documents[id] = move(doc);
    pthread_mutex_unlock(&mutex);
    return id;
  }
  bool retrieve(int id, JSON& doc) {
    pthread_mutex_lock(&mutex);
    auto it = documents.find(id);
    if (it == documents.end()) {
      doc.setnull();
      pthread_mutex_unlock(&mutex);
      return false;
    }
    doc = it->second;
    pthread_mutex_unlock(&mutex);
    return true;
  }
  JSON retrieve(const JSON& filter) {
    JSON ans(vector<JSON>{});
    pthread_mutex_lock(&mutex);
    for (auto& kv : documents) if (filter.issubobj(kv.second)) {
      JSON tmp = kv.second;
      tmp["id"] = kv.first;
      ans.push_back(move(tmp));
    }
    pthread_mutex_unlock(&mutex);
    return ans;
  }
  JSON retrieve_page(unsigned p, unsigned ps) {
    JSON ans(vector<JSON>{});
    pthread_mutex_lock(&mutex);
    if (!ps) p = 0, ps = documents.size();
    auto it = documents.at(p*ps);
    for (int i = 0; i < ps && it != documents.end(); i++, it++) {
      JSON tmp = it->second;
      tmp["id"] = it->first;
      ans.push_back(move(tmp));
    }
    pthread_mutex_unlock(&mutex);
    return ans;
  }
  bool update(int id, JSON&& doc) {
    pthread_mutex_lock(&mutex);
    auto it = documents.find(id);
    if (it == documents.end()) {
      pthread_mutex_unlock(&mutex);
      return false;
    }
    it->second = move(doc);
    pthread_mutex_unlock(&mutex);
    return true;
  }
  bool update(const Database::Updater& upd, int id) {
    bool ans = false;
    pthread_mutex_lock(&mutex);
    auto it = documents.find(id);
    if (it != documents.end()) {
      ans = upd(*it);
      pthread_mutex_unlock(&mutex);
      return ans;
    }
    for (auto& kv : documents) ans = ans || upd(kv);
    pthread_mutex_unlock(&mutex);
    return ans;
  }
  bool destroy(int id) {
    pthread_mutex_lock(&mutex);
    auto it = documents.find(id);
    if (it == documents.end()) {
      pthread_mutex_unlock(&mutex);
      return false;
    }
    documents.erase(it);
    pthread_mutex_unlock(&mutex);
    return true;
  }
};
static Coll collection[MAX_COLLECTIONS];
static int ncolls = 0;
static pthread_mutex_t colls_mutex = PTHREAD_MUTEX_INITIALIZER;
static int get(const string& name) {
  static map<string,int> colls;
  int i;
  pthread_mutex_lock(&colls_mutex);
  auto it = colls.find(name);
  if (it != colls.end()) {
    i = it->second;
    pthread_mutex_unlock(&colls_mutex);
    return i;
  }
  i = ncolls++;
  colls[name] = i;
  collection[i].name = name;
  collection[i].read();
  pthread_mutex_unlock(&colls_mutex);
  return i;
}

// thread
static bool quit = false;
static pthread_t db;
static void do_backup() {
  stringstream ss("backup");
  ss << backup;
  system(("mkdir -p database/"+ss.str()).c_str());
  system(("cp database/*.json database/"+ss.str()).c_str());
}
static void update() {
  int nc;
  pthread_mutex_lock(&colls_mutex);
  nc = ncolls;
  pthread_mutex_unlock(&colls_mutex);
  for (int i = 0; i < nc; i++) collection[i].write();
  if (backup < 0) return;
  do_backup();
  backup = 1-backup;
}
static void* thread(void*) {
  static time_t upd = 0;
  while (!quit) {
    if (upd <= time(nullptr)) {
      update();
      upd = time(nullptr)+WRITE_INTERVAL;
    }
    usleep(100000);
  }
}

namespace Database {

Collection::Collection(const string& name) : collid(get(name)) {

}

int Collection::create(const JSON& document) {
  JSON tmp(document);
  return collection[collid].create(move(tmp));
}

int Collection::create(JSON&& document) {
  return collection[collid].create(move(document));
}

JSON Collection::retrieve(int docid) {
  JSON ans;
  collection[collid].retrieve(docid,ans);
  return ans;
}

bool Collection::retrieve(int docid, JSON& document) {
  return collection[collid].retrieve(docid,document);
}

JSON Collection::retrieve(const JSON& filter) {
  return collection[collid].retrieve(filter);
}

JSON Collection::retrieve_page(unsigned page,unsigned page_size) {
  return collection[collid].retrieve_page(page,page_size);
}

bool Collection::update(int docid, const JSON& document) {
  JSON tmp(document);
  return collection[collid].update(docid,move(tmp));
}

bool Collection::update(int docid, JSON&& document) {
  return collection[collid].update(docid,move(document));
}

bool Collection::update(const Updater& upd, int docid) {
  return collection[collid].update(upd,docid);
}

bool Collection::destroy(int docid) {
  return collection[collid].destroy(docid);
}

void init(bool backup) {
  if (backup) ::backup = 0;
  system("mkdir -p database");
  pthread_create(&db,nullptr,thread,nullptr);
}

void close() {
  quit = true;
  pthread_join(db,nullptr);
  update();
}

} // namespace Database
<commit_msg>Fixing bug<commit_after>#include <map>

#include <unistd.h>

#include "database.hpp"

#include "cmap.hpp"

#define MAX_COLLECTIONS 100
#define WRITE_INTERVAL  30

using namespace std;

static int backup = -1;

struct Coll {
  pthread_mutex_t mutex;
  string name;
  cmap<int,JSON> documents;
  Coll() : mutex(PTHREAD_MUTEX_INITIALIZER) {}
  void read() { // this function is called only once, by a locked piece of code
    JSON tmp;
    if (!tmp.read_file("database/"+name+".json")) return;
    for (auto& doc : tmp.arr()) documents[doc("_id")] = doc("document");
  }
  void write() {
    JSON tmp(vector<JSON>{});
    pthread_mutex_lock(&mutex);
    for (auto& kv : documents) tmp.emplace_back(move(map<string,JSON>{
      {"_id"      , kv.first},
      {"document" , kv.second}
    }));
    pthread_mutex_unlock(&mutex);
    tmp.write_file("database/"+name+".json");
  }
  int create(JSON&& doc) {
    int id = 1;
    pthread_mutex_lock(&mutex);
    if (documents.size() > 0) id += documents.max_key();
    documents[id] = move(doc);
    pthread_mutex_unlock(&mutex);
    return id;
  }
  bool retrieve(int id, JSON& doc) {
    pthread_mutex_lock(&mutex);
    auto it = documents.find(id);
    if (it == documents.end()) {
      doc.setnull();
      pthread_mutex_unlock(&mutex);
      return false;
    }
    doc = it->second;
    pthread_mutex_unlock(&mutex);
    return true;
  }
  JSON retrieve(const JSON& filter) {
    JSON ans(vector<JSON>{});
    pthread_mutex_lock(&mutex);
    for (auto& kv : documents) if (filter.issubobj(kv.second)) {
      JSON tmp = kv.second;
      tmp["id"] = kv.first;
      ans.push_back(move(tmp));
    }
    pthread_mutex_unlock(&mutex);
    return ans;
  }
  JSON retrieve_page(unsigned p, unsigned ps) {
    JSON ans(vector<JSON>{});
    pthread_mutex_lock(&mutex);
    if (!ps) p = 0, ps = documents.size();
    auto it = documents.at(p*ps);
    for (int i = 0; i < ps && it != documents.end(); i++, it++) {
      JSON tmp = it->second;
      tmp["id"] = it->first;
      ans.push_back(move(tmp));
    }
    pthread_mutex_unlock(&mutex);
    return ans;
  }
  bool update(int id, JSON&& doc) {
    pthread_mutex_lock(&mutex);
    auto it = documents.find(id);
    if (it == documents.end()) {
      pthread_mutex_unlock(&mutex);
      return false;
    }
    it->second = move(doc);
    pthread_mutex_unlock(&mutex);
    return true;
  }
  bool update(const Database::Updater& upd, int id) {
    bool ans = false;
    pthread_mutex_lock(&mutex);
    auto it = documents.find(id);
    if (it != documents.end()) {
      ans = upd(*it);
      pthread_mutex_unlock(&mutex);
      return ans;
    }
    for (auto& kv : documents) ans = ans || upd(kv);
    pthread_mutex_unlock(&mutex);
    return ans;
  }
  bool destroy(int id) {
    pthread_mutex_lock(&mutex);
    auto it = documents.find(id);
    if (it == documents.end()) {
      pthread_mutex_unlock(&mutex);
      return false;
    }
    documents.erase(it);
    pthread_mutex_unlock(&mutex);
    return true;
  }
};
static Coll collection[MAX_COLLECTIONS];
static int ncolls = 0;
static pthread_mutex_t colls_mutex = PTHREAD_MUTEX_INITIALIZER;
static int get(const string& name) {
  static map<string,int> colls;
  int i;
  pthread_mutex_lock(&colls_mutex);
  auto it = colls.find(name);
  if (it != colls.end()) {
    i = it->second;
    pthread_mutex_unlock(&colls_mutex);
    return i;
  }
  i = ncolls++;
  colls[name] = i;
  collection[i].name = name;
  collection[i].read();
  pthread_mutex_unlock(&colls_mutex);
  return i;
}

// thread
static bool quit = false;
static pthread_t db;
static void do_backup() {
  stringstream ss;
  ss << "backup" << backup;
  system(("mkdir -p database/"+ss.str()).c_str());
  system(("cp database/*.json database/"+ss.str()).c_str());
}
static void update() {
  int nc;
  pthread_mutex_lock(&colls_mutex);
  nc = ncolls;
  pthread_mutex_unlock(&colls_mutex);
  for (int i = 0; i < nc; i++) collection[i].write();
  if (backup < 0) return;
  do_backup();
  backup = 1-backup;
}
static void* thread(void*) {
  static time_t upd = 0;
  while (!quit) {
    if (upd <= time(nullptr)) {
      update();
      upd = time(nullptr)+WRITE_INTERVAL;
    }
    usleep(100000);
  }
}

namespace Database {

Collection::Collection(const string& name) : collid(get(name)) {

}

int Collection::create(const JSON& document) {
  JSON tmp(document);
  return collection[collid].create(move(tmp));
}

int Collection::create(JSON&& document) {
  return collection[collid].create(move(document));
}

JSON Collection::retrieve(int docid) {
  JSON ans;
  collection[collid].retrieve(docid,ans);
  return ans;
}

bool Collection::retrieve(int docid, JSON& document) {
  return collection[collid].retrieve(docid,document);
}

JSON Collection::retrieve(const JSON& filter) {
  return collection[collid].retrieve(filter);
}

JSON Collection::retrieve_page(unsigned page,unsigned page_size) {
  return collection[collid].retrieve_page(page,page_size);
}

bool Collection::update(int docid, const JSON& document) {
  JSON tmp(document);
  return collection[collid].update(docid,move(tmp));
}

bool Collection::update(int docid, JSON&& document) {
  return collection[collid].update(docid,move(document));
}

bool Collection::update(const Updater& upd, int docid) {
  return collection[collid].update(upd,docid);
}

bool Collection::destroy(int docid) {
  return collection[collid].destroy(docid);
}

void init(bool backup) {
  if (backup) ::backup = 0;
  system("mkdir -p database");
  pthread_create(&db,nullptr,thread,nullptr);
}

void close() {
  quit = true;
  pthread_join(db,nullptr);
  update();
}

} // namespace Database
<|endoftext|>


<commit_before>#include "database.h"

bool Database::openDB () {
    // Find QSLite driver
    QSqlDatabase db = QSqlDatabase::addDatabase ( "QSQLITE" );

#ifdef Q_OS_LINUX
    QString path( QDir::home ().path () + "/.config/" + QCoreApplication::applicationName () + "/" + QCoreApplication::applicationName () + ".db" );
    if( QFile::exists ( path ))
        return true;
    // NOTE: We have to store database file into user home folder in Linux
    db.setDatabaseName( path );
#else
    if( QFile::exists ( QCoreApplication::applicationName () + ".db" ))
        return true;
    // NOTE: File exists in the application private folder, in Symbian Qt implementation
    db.setDatabaseName( QCoreApplication::applicationName () + ".db" );
#endif
    if ( !db.open ()) {
        qWarning ( "Unable to establish a database connection.\n" );
        return false;
    }

    QSqlQuery query;
    query.exec( "create table lineEditComplete (id int primary key, seachWord varchar(20), numberOfUsed int)" );

    return true;
}

bool Database::deleteDB () {
#ifdef Q_OS_LINUX
    // NOTE: We have to store database file into user home folder in Linux
    return QFile::remove ( QDir::home ().path () + "/.config/" + QCoreApplication::applicationName () + "/" + QCoreApplication::applicationName () + ".db" );
#else

    // Remove created database binary file
    return QFile::remove ( QCoreApplication::applicationName () + ".db" );
#endif
}
<commit_msg>remove needless new line<commit_after>#include "database.h"

bool Database::openDB () {
    // Find QSLite driver
    QSqlDatabase db = QSqlDatabase::addDatabase ( "QSQLITE" );

#ifdef Q_OS_LINUX
    QString path( QDir::home ().path () + "/.config/" + QCoreApplication::applicationName () + "/" + QCoreApplication::applicationName () + ".db" );
    if( QFile::exists ( path ))
        return true;
    // NOTE: We have to store database file into user home folder in Linux
    db.setDatabaseName( path );
#else
    if( QFile::exists ( QCoreApplication::applicationName () + ".db" ))
        return true;
    // NOTE: File exists in the application private folder, in Symbian Qt implementation
    db.setDatabaseName( QCoreApplication::applicationName () + ".db" );
#endif
    if ( !db.open ()) {
        qWarning ( "Unable to establish a database connection." );
        return false;
    }

    QSqlQuery query;
    query.exec( "create table lineEditComplete (id int primary key, seachWord varchar(20), numberOfUsed int)" );

    return true;
}

bool Database::deleteDB () {
#ifdef Q_OS_LINUX
    // NOTE: We have to store database file into user home folder in Linux
    return QFile::remove ( QDir::home ().path () + "/.config/" + QCoreApplication::applicationName () + "/" + QCoreApplication::applicationName () + ".db" );
#else

    // Remove created database binary file
    return QFile::remove ( QCoreApplication::applicationName () + ".db" );
#endif
}
<|endoftext|>


<commit_before>/*!
 * \file xgboost.cpp
 * \brief bootser implementations
 * \author Tianqi Chen: tianqi.tchen@gmail.com
 */
// implementation of boosters go to here
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#include <climits>
#include "xgboost.h"
#include "../utils/xgboost_utils.h"
#include "xgboost_gbmbase.h"
// implementations of boosters
#include "tree/xgboost_svdf_tree.hpp"

namespace xgboost{
    namespace booster{
        /*!
         * \brief create a gradient booster, given type of booster
         * \param booster_type type of gradient booster, can be used to specify implements
         * \return the pointer to the gradient booster created
         */
        IBooster *CreateBooster( int booster_type ){
            // TODO
            return NULL;
        }
    };
};

<commit_msg>adapt tree booster<commit_after>/*!
 * \file xgboost.cpp
 * \brief bootser implementations
 * \author Tianqi Chen: tianqi.tchen@gmail.com
 */
// implementation of boosters go to here
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#include <climits>
#include "xgboost.h"
#include "../utils/xgboost_utils.h"
#include "xgboost_gbmbase.h"
// implementations of boosters
#include "tree/xgboost_svdf_tree.hpp"

namespace xgboost{
    namespace booster{
        /*!
         * \brief create a gradient booster, given type of booster
         * \param booster_type type of gradient booster, can be used to specify implements
         * \return the pointer to the gradient booster created
         */
        IBooster *CreateBooster( int booster_type ){
            return new RTreeTrainer();
        }
    };
};

<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2016 Northeastern University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

// This file tests the CpuOperations::Transpose() function by checking to
// See if a matrix passed is transposed in the test IsTransposed
// A transposed Nice matrix is compared to a transposed Eigen Matrix in
// Transpose Eigen
// Behavior with oddly shaped matrices is also tested with test DifferentShapes
// And TransposeZeroRows
// All tests are made using a templated test fixture which attempts
// Integer, float, and double data types

#include <stdio.h>
#include <iostream>
#include <cmath>
#include "Eigen/Dense"
#include "include/svd_solver.h"
#include "gtest/gtest.h"
#include "include/matrix.h"
#include "include/vector.h"

// This is a template test fixture class containing test matrices
template<class T>  // Template
class CpuSvdSolverTest : public ::testing::Test {
  // Inherits from testing::Test

 public:  // Members must be public to be accessed by tests
  Nice::Matrix<T> matrix_;
  Nice::Matrix<T> u_;
  Nice::Matrix<T> v_;
  Nice::Vector<T> s_;
  int row_;
  int col_;

  // Constructor
  void CreateTestData() {
    // Check matrix
    if (matrix_.rows() != 0 && matrix_.cols() != 0)
      return;

    row_ = 5;
    col_ = row_;
    matrix_.resize(row_, col_);
    matrix_ << -129.3026,  1031.7118,  2548.9163,  -511.0120,  2.7719,
                583.9671,  220.9613,  536.9512,  55.0691,  954.5454,
                694.9577,  -626.7673,  -972.7809,  800.4132,  298.9344,
                659.9324,  1235.7984,  -688.4173,  -55.1088,  -1194.2583,
                1552.5551,  513.1012,  -2574.5784,  -1489.1966,  -55.4250;
    u_.resize(row_, col_);
    u_ << -0.555596,  -0.617009,  -0.244002,  -0.092006,   0.492557,
          -0.088014,  -0.051527,  -0.654019,  -0.478284,  -0.577150,
          0.240369,   0.395314,  -0.108216,  -0.651940,   0.590943,
          0.228426,  -0.529382,   0.585784,  -0.527902,  -0.213902,
          0.757372,  -0.424414,  -0.397328,   0.243049,   0.171226;
    v_.resize(row_, col_);
    v_ << 0.363743,  -0.277844,  -0.404770,  -0.608509,   0.506332,
          -0.017398,  -0.718194,   0.118253,  -0.281295,  -0.625128,
          -0.913964,  -0.214438,  -0.153148,  -0.105130,   0.290136,
          -0.160719,   0.524143,   0.346509,  -0.733898,  -0.201915,
          -0.078912,  0.293753,  -0.823805,  -0.030541,  -0.477383;
    s_.resize(row_);
    s_ << 4162.54, 2461.32, 1620.37, 1136.40, 265.90;
  }
};

// Establishes a test case with the given types, Char and short types will
// Throw compiler errors
typedef ::testing::Types<float, double> dataTypes;
TYPED_TEST_CASE(CpuSvdSolverTest, dataTypes);

TYPED_TEST(CpuSvdSolverTest, FuncionalityTest) {
  // Create test data
  this->CreateTestData();

  // Test svd solver in Nice
  Nice::SvdSolver<TypeParam> svd_solver;
  svd_solver.Compute(this->matrix_);
  Nice::Matrix<TypeParam> result_u = svd_solver.MatrixU();
  Nice::Matrix<TypeParam> result_v = svd_solver.MatrixV();
  Nice::Vector<TypeParam> result_s = svd_solver.SingularValues();

  // Verify the result U
  for (int i = 0; i < this->row_; i++)
    for (int i = 0; i < this->col_; i++)
      EXPECT_NEAR(abs(this->u_(i)), abs(result_u(i)), 0.001);

  // Verify the result V
  for (int i = 0; i < this->row_; i++)
    for (int i = 0; i < this->col_; i++)
      EXPECT_NEAR(abs(this->v_(i)), abs(result_v(i)), 0.001);

  // Verify the result S
  for (int i = 0; i < this->row_; i++)
    EXPECT_NEAR(this->s_(i), result_s(i), 0.1);
}

TYPED_TEST(CpuSvdSolverTest, RankTest) {
  // Create test data
  this->CreateTestData();

  // Test svd solver in Nice
  Nice::SvdSolver<TypeParam> svd_solver;
  int rank = svd_solver.Rank(this->matrix_);

  // Verify the rank
  EXPECT_EQ(5, rank);
}

<commit_msg>Revert "fixed all google codestyle errors"<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2016 Northeastern University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

// This file tests the CpuOperations::Transpose() function by checking to
// See if a matrix passed is transposed in the test IsTransposed
// A transposed Nice matrix is compared to a transposed Eigen Matrix in
// Transpose Eigen
// Behavior with oddly shaped matrices is also tested with test DifferentShapes
// And TransposeZeroRows
// All tests are made using a templated test fixture which attempts
// Integer, float, and double data types

#include <stdio.h>
#include <iostream>

#include <iostream>
#include <cmath>

#include "Eigen/Dense"
#include "include/svd_solver.h"
#include "gtest/gtest.h"
#include "include/svd_solver.h"
#include "include/matrix.h"
#include "include/vector.h"

// This is a template test fixture class containing test matrices
template<class T>  // Template
class CpuSvdSolverTest : public ::testing::Test {

  // Inherits from testing::Test

 public:  // Members must be public to be accessed by tests
  Nice::Matrix<T> matrix_;
  Nice::Matrix<T> u_;
  Nice::Matrix<T> v_;
  Nice::Vector<T> s_;
  int row_;
  int col_;

  // Constructor
  void CreateTestData() {
    // Check matrix
    if (matrix_.rows() != 0 && matrix_.cols() != 0)
      return;

    row_ = 5;
    col_ = row_;
    matrix_.resize(row_, col_);
    matrix_ << -129.3026,  1031.7118,  2548.9163,  -511.0120,  2.7719,
                583.9671,  220.9613,  536.9512,  55.0691,  954.5454,
                694.9577,  -626.7673,  -972.7809,  800.4132,  298.9344,
                659.9324,  1235.7984,  -688.4173,  -55.1088,  -1194.2583,
                1552.5551,  513.1012,  -2574.5784,  -1489.1966,  -55.4250;
    u_.resize(row_, col_);
    u_ << -0.555596,  -0.617009,  -0.244002,  -0.092006,   0.492557,
          -0.088014,  -0.051527,  -0.654019,  -0.478284,  -0.577150,
          0.240369,   0.395314,  -0.108216,  -0.651940,   0.590943,
          0.228426,  -0.529382,   0.585784,  -0.527902,  -0.213902,
          0.757372,  -0.424414,  -0.397328,   0.243049,   0.171226;
    v_.resize(row_, col_);
    v_ << 0.363743,  -0.277844,  -0.404770,  -0.608509,   0.506332,
          -0.017398,  -0.718194,   0.118253,  -0.281295,  -0.625128,
          -0.913964,  -0.214438,  -0.153148,  -0.105130,   0.290136,
          -0.160719,   0.524143,   0.346509,  -0.733898,  -0.201915,
          -0.078912,  0.293753,  -0.823805,  -0.030541,  -0.477383;
    s_.resize(row_);
    s_ << 4162.54, 2461.32, 1620.37, 1136.40, 265.90;
  }
};

// Establishes a test case with the given types, Char and short types will
// Throw compiler errors
typedef ::testing::Types<float, double> dataTypes;
TYPED_TEST_CASE(CpuSvdSolverTest, dataTypes);

TYPED_TEST(CpuSvdSolverTest, FuncionalityTest) {
  // Create test data
  this->CreateTestData();

  // Test svd solver in Nice
  Nice::SvdSolver<TypeParam> svd_solver;
  svd_solver.Compute(this->matrix_);
  Nice::Matrix<TypeParam> result_u = svd_solver.MatrixU();
  Nice::Matrix<TypeParam> result_v = svd_solver.MatrixV();
  Nice::Vector<TypeParam> result_s = svd_solver.SingularValues();

  // Verify the result U
  for (int i = 0; i < this->row_; i++)
    for (int i = 0; i < this->col_; i++)
      EXPECT_NEAR(abs(this->u_(i)), abs(result_u(i)), 0.001);

  // Verify the result V
  for (int i = 0; i < this->row_; i++)
    for (int i = 0; i < this->col_; i++)
      EXPECT_NEAR(abs(this->v_(i)), abs(result_v(i)), 0.001);

  // Verify the result S
  for (int i = 0; i < this->row_; i++)
    EXPECT_NEAR(this->s_(i), result_s(i), 0.1);
}

TYPED_TEST(CpuSvdSolverTest, RankTest) {
  // Create test data
  this->CreateTestData();

  // Test svd solver in Nice
  Nice::SvdSolver<TypeParam> svd_solver;
  int rank = svd_solver.Rank(this->matrix_);

  // Verify the rank
  EXPECT_EQ(5, rank);
}

<|endoftext|>