<commit_before>//===- llvm-link.cpp - Low-level LLVM linker ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This utility may be invoked in the following manner:
//  llvm-link a.bc b.bc c.bc -o x.bc
//
//===----------------------------------------------------------------------===//

#include "llvm/Linker/Linker.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/ToolOutputFile.h"
#include <memory>
using namespace llvm;

static cl::list<std::string>
InputFilenames(cl::Positional, cl::OneOrMore,
               cl::desc("<input bitcode files>"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
               cl::value_desc("filename"));

static cl::opt<bool>
Force("f", cl::desc("Enable binary output on terminals"));

static cl::opt<bool>
OutputAssembly("S",
         cl::desc("Write output as LLVM assembly"), cl::Hidden);

static cl::opt<bool>
Verbose("v", cl::desc("Print information about actions taken"));

static cl::opt<bool>
DumpAsm("d", cl::desc("Print assembly as linked"), cl::Hidden);

static cl::opt<bool>
SuppressWarnings("suppress-warnings", cl::desc("Suppress all linking warnings"),
                 cl::init(false));

// Read the specified bitcode file in and return it. This routine searches the
// link path for the specified file to try to find it...
//
static std::unique_ptr<Module>
loadFile(const char *argv0, const std::string &FN, LLVMContext &Context) {
  SMDiagnostic Err;
  if (Verbose) errs() << "Loading '" << FN << "'\n";
  std::unique_ptr<Module> Result = parseIRFile(FN, Err, Context);
  if (!Result)
    Err.print(argv0, errs());

  return Result;
}

int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);

  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
  cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");

  unsigned BaseArg = 0;
  std::string ErrorMessage;

  std::unique_ptr<Module> Composite =
      loadFile(argv[0], InputFilenames[BaseArg], Context);
  if (!Composite.get()) {
    errs() << argv[0] << ": error loading file '"
           << InputFilenames[BaseArg] << "'\n";
    return 1;
  }

  Linker L(Composite.get(), SuppressWarnings);
  for (unsigned i = BaseArg+1; i < InputFilenames.size(); ++i) {
    std::unique_ptr<Module> M = loadFile(argv[0], InputFilenames[i], Context);
    if (!M.get()) {
      errs() << argv[0] << ": error loading file '" <<InputFilenames[i]<< "'\n";
      return 1;
    }

    if (Verbose) errs() << "Linking in '" << InputFilenames[i] << "'\n";

    if (L.linkInModule(M.get(), &ErrorMessage)) {
      errs() << argv[0] << ": link error in '" << InputFilenames[i]
             << "': " << ErrorMessage << "\n";
      return 1;
    }
  }

  if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite;

  std::error_code EC;
  tool_output_file Out(OutputFilename, EC, sys::fs::F_None);
  if (EC) {
    errs() << EC.message() << '\n';
    return 1;
  }

  if (verifyModule(*Composite)) {
    errs() << argv[0] << ": linked module is broken!\n";
    return 1;
  }

  if (Verbose) errs() << "Writing bitcode...\n";
  if (OutputAssembly) {
    Out.os() << *Composite;
  } else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true))
    WriteBitcodeToFile(Composite.get(), Out.os());

  // Declare success.
  Out.keep();

  return 0;
}
<commit_msg>Make llvm-link behave a bit more like LTO.<commit_after>//===- llvm-link.cpp - Low-level LLVM linker ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This utility may be invoked in the following manner:
//  llvm-link a.bc b.bc c.bc -o x.bc
//
//===----------------------------------------------------------------------===//

#include "llvm/Linker/Linker.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/ToolOutputFile.h"
#include <memory>
using namespace llvm;

static cl::list<std::string>
InputFilenames(cl::Positional, cl::OneOrMore,
               cl::desc("<input bitcode files>"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
               cl::value_desc("filename"));

static cl::opt<bool>
Force("f", cl::desc("Enable binary output on terminals"));

static cl::opt<bool>
OutputAssembly("S",
         cl::desc("Write output as LLVM assembly"), cl::Hidden);

static cl::opt<bool>
Verbose("v", cl::desc("Print information about actions taken"));

static cl::opt<bool>
DumpAsm("d", cl::desc("Print assembly as linked"), cl::Hidden);

static cl::opt<bool>
SuppressWarnings("suppress-warnings", cl::desc("Suppress all linking warnings"),
                 cl::init(false));

// Read the specified bitcode file in and return it. This routine searches the
// link path for the specified file to try to find it...
//
static std::unique_ptr<Module>
loadFile(const char *argv0, const std::string &FN, LLVMContext &Context) {
  SMDiagnostic Err;
  if (Verbose) errs() << "Loading '" << FN << "'\n";
  std::unique_ptr<Module> Result = getLazyIRFileModule(FN, Err, Context);
  if (!Result)
    Err.print(argv0, errs());

  return Result;
}

int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);

  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
  cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");

  auto Composite = make_unique<Module>("llvm-link", Context);
  Linker L(Composite.get(), SuppressWarnings);

  std::string ErrorMessage;
  for (unsigned i = 0; i < InputFilenames.size(); ++i) {
    std::unique_ptr<Module> M = loadFile(argv[0], InputFilenames[i], Context);
    if (!M.get()) {
      errs() << argv[0] << ": error loading file '" <<InputFilenames[i]<< "'\n";
      return 1;
    }

    if (Verbose) errs() << "Linking in '" << InputFilenames[i] << "'\n";

    if (L.linkInModule(M.get(), &ErrorMessage)) {
      errs() << argv[0] << ": link error in '" << InputFilenames[i]
             << "': " << ErrorMessage << "\n";
      return 1;
    }
  }

  if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite;

  std::error_code EC;
  tool_output_file Out(OutputFilename, EC, sys::fs::F_None);
  if (EC) {
    errs() << EC.message() << '\n';
    return 1;
  }

  if (verifyModule(*Composite)) {
    errs() << argv[0] << ": linked module is broken!\n";
    return 1;
  }

  if (Verbose) errs() << "Writing bitcode...\n";
  if (OutputAssembly) {
    Out.os() << *Composite;
  } else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true))
    WriteBitcodeToFile(Composite.get(), Out.os());

  // Declare success.
  Out.keep();

  return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SwNodeNum.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2005-11-17 16:21:26 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#include <svx/svxenum.hxx>
#include <SwNodeNum.hxx>
#include <ndtxt.hxx>
#include <pam.hxx>

SwNodeNum::SwNodeNum()
    : SwNumberTreeNode(), mpTxtNode(NULL), mpNumRule(NULL), mnStart(1),
      mbRestart(false)
{
}

SwNodeNum::SwNodeNum(const SwNodeNum & rNodeNum)
    : SwNumberTreeNode(rNodeNum), mpTxtNode(NULL),
      mpNumRule(NULL), mnStart(rNodeNum.mnStart),
      mbRestart(rNodeNum.mbRestart)
{
}

SwNodeNum::~SwNodeNum()
{
}

void SwNodeNum::SetTxtNode(SwTxtNode * pTxtNode)
{
    mpTxtNode = pTxtNode;
}

SwTxtNode * SwNodeNum::GetTxtNode() const
{
    return mpTxtNode;
}

void SwNodeNum::SetNumRule(SwNumRule * pRule)
{
    mpNumRule = pRule;
}

SwNumRule * SwNodeNum::GetNumRule() const
{
    return mpNumRule;
}

SwPosition SwNodeNum::GetPosition() const
{
    return SwPosition(*mpTxtNode);
}

SwNumberTreeNode * SwNodeNum::Create() const
{
    SwNodeNum * pResult = new SwNodeNum();

    pResult->SetNumRule(mpNumRule);

    return pResult;
}

SwNumberTreeNode * SwNodeNum::Copy() const
{
    return new SwNodeNum(*this);
}

void SwNodeNum::RemoveChild(SwNumberTreeNode * _pChild)
{
    SwNodeNum * pChild = static_cast<SwNodeNum*>(_pChild);

    pChild->SetNumRule(NULL);

    SwNumberTreeNode::RemoveChild(_pChild);
}

bool SwNodeNum::IsNotifiable() const
{
    bool aResult = true;

    if (mpTxtNode)
        aResult = mpTxtNode->IsNotifiable();

    return aResult;
}

bool SwNodeNum::IsContinuous() const
{
    bool aResult = false;

    if (mpTxtNode)
        aResult = mpTxtNode->IsContinuous();

    return aResult;
}

bool SwNodeNum::IsCounted() const
{
    bool aResult = false;

    if (mpTxtNode)
    {
        const SwNumFmt * pNumFmt = GetNumFmt();

        if (pNumFmt)
        {
            sal_Int16 nType = pNumFmt->GetNumberingType();

            if ( nType != SVX_NUM_NUMBER_NONE)
                aResult = mpTxtNode->IsCounted();
        }
    }
    else
        aResult = SwNumberTreeNode::IsCounted();

    return aResult;
}

void SwNodeNum::NotifyNode()
{
    ValidateMe();

    if (mpTxtNode)
    {
        mpTxtNode->NumRuleChgd();
    }
}

bool SwNodeNum::LessThan(const SwNumberTreeNode & rNode) const
{
    bool bResult = false;
    const SwNodeNum & rTmpNode = static_cast<const SwNodeNum &>(rNode);

    if (mpTxtNode == NULL && rTmpNode.mpTxtNode != NULL)
        bResult = true;
    else if (mpTxtNode != NULL && rTmpNode.mpTxtNode != NULL)
    {
        SwPosition aMyPos(*mpTxtNode);
        SwPosition aHisPos(*rTmpNode.mpTxtNode);

        bResult = (aMyPos < aHisPos) ? true : false;
    }

    return bResult;
}

void SwNodeNum::SetRestart(bool bRestart)
{
    // --> OD 2005-10-19 #126009#
    // - improvement: invalidation only, if <IsRestart()> state changes.
    const bool bInvalidate( mbRestart != bRestart );
    // <--
    mbRestart = bRestart;

    // --> OD 2005-10-19 #126009#
    if ( bInvalidate )
    {
        InvalidateMe();
        NotifyInvalidSiblings();
    }
    // <--
}

bool SwNodeNum::IsRestart() const
{
    return mbRestart;
}

void SwNodeNum::SetStart(SwNumberTreeNode::tSwNumTreeNumber nStart)
{
    // --> OD 2005-10-19 #126009#
    // - improvement: invalidation only, if <IsRestart()> state changes.
    const bool bInvalidate( mnStart != nStart );
    // <--
    mnStart = nStart;

    // --> OD 2005-10-19 #126009#
    if ( bInvalidate )
    {
        InvalidateMe();
        NotifyInvalidSiblings();
    }
}

bool SwNodeNum::IsCountPhantoms() const
{
    bool bResult = true;

    if (mpNumRule)
        bResult = mpNumRule->IsCountPhantoms();

    return bResult;
}

SwNumberTreeNode::tSwNumTreeNumber SwNodeNum::GetStart() const
{
    tSwNumTreeNumber aResult = 1;

    // --> OD 2005-11-16 #i57919# - consider that start value <USHRT_MAX>
    // indicates, that the numbering is restarted at this node with the
    // start value, which is set at the corresponding numbering level.
    if ( IsRestart() && mnStart != USHRT_MAX )
    // <--
    {
        aResult = mnStart;
    }
    else
    {
        SwNumRule * pRule = GetNumRule();

        if (pRule)
        {
            int nLevel = GetLevel();

            if (nLevel >= 0 && nLevel < MAXLEVEL)
            {
                const SwNumFmt * pFmt = pRule->GetNumFmt(nLevel);

                if (pFmt)
                    aResult = pFmt->GetStart();
            }
        }
    }

    return aResult;
}

String SwNodeNum::ToString() const
{
    String aResult("[ ", RTL_TEXTENCODING_ASCII_US);

    if (GetTxtNode())
    {
        char aBuffer[256];

        sprintf(aBuffer, "%p ", GetTxtNode());

        aResult += String(aBuffer, RTL_TEXTENCODING_ASCII_US);
        aResult += String::CreateFromInt32(GetPosition().nNode.GetIndex());
    }
    else
        aResult += String("*", RTL_TEXTENCODING_ASCII_US);

    aResult += String(" ", RTL_TEXTENCODING_ASCII_US);

    unsigned int nLvl = GetLevel();
    aResult += String::CreateFromInt32(nLvl);

    aResult += String(": ", RTL_TEXTENCODING_ASCII_US);

    tNumberVector aNumVector;

    _GetNumberVector(aNumVector, false);

    for (unsigned int n = 0; n < aNumVector.size(); n++)
    {
        if (n > 0)
            aResult += String(", ", RTL_TEXTENCODING_ASCII_US);

        aResult += String::CreateFromInt32(aNumVector[n]);
    }

    if (IsCounted())
//        aResult += String(" counted", RTL_TEXTENCODING_ASCII_US);
        aResult += String(" C", RTL_TEXTENCODING_ASCII_US);

    if (IsRestart())
    {
//        aResult += String(" restart(", RTL_TEXTENCODING_ASCII_US);
        aResult += String(" R(", RTL_TEXTENCODING_ASCII_US);
        aResult += String::CreateFromInt32(GetStart());
        aResult += String(")", RTL_TEXTENCODING_ASCII_US);
    }

    if (! IsValid())
//        aResult += String(" invalid", RTL_TEXTENCODING_ASCII_US);
        aResult += String(" I", RTL_TEXTENCODING_ASCII_US);

    aResult += String(" ]", RTL_TEXTENCODING_ASCII_US);

    return aResult;
}

void SwNodeNum::SetLevel(unsigned int nLevel)
{
    ASSERT(nLevel >= 0 && nLevel < MAXLEVEL, "illegal level");

    if (mpParent)
    {
        SwNumRule * pRule = GetNumRule();

        if (pRule != mpNumRule || nLevel != GetLevel())
        {
            RemoveMe();

            if (pRule)
                pRule->AddNumber(this, nLevel);
        }
    }
}

const SwNumFmt * SwNodeNum::GetNumFmt() const
{
    const SwNumFmt * pResult = NULL;

    unsigned int nLevel = GetLevel();
    if (mpNumRule && nLevel >= 0 && nLevel < MAXLEVEL)
        pResult = &mpNumRule->Get(nLevel);

    return pResult;
}
<commit_msg>INTEGRATION: CWS swnum202 (1.3.90); FILE MERGED 2006/01/26 08:15:52 od 1.3.90.1: #i59559# <SwNodeNum::IsCounted()> 	 - for text nodes <SwTxtNode::IsCounted()> determines, if the 	   text node is counted for numbering.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SwNodeNum.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2006-02-03 17:33:18 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#include <svx/svxenum.hxx>
#include <SwNodeNum.hxx>
#include <ndtxt.hxx>
#include <pam.hxx>

SwNodeNum::SwNodeNum()
    : SwNumberTreeNode(), mpTxtNode(NULL), mpNumRule(NULL), mnStart(1),
      mbRestart(false)
{
}

SwNodeNum::SwNodeNum(const SwNodeNum & rNodeNum)
    : SwNumberTreeNode(rNodeNum), mpTxtNode(NULL),
      mpNumRule(NULL), mnStart(rNodeNum.mnStart),
      mbRestart(rNodeNum.mbRestart)
{
}

SwNodeNum::~SwNodeNum()
{
}

void SwNodeNum::SetTxtNode(SwTxtNode * pTxtNode)
{
    mpTxtNode = pTxtNode;
}

SwTxtNode * SwNodeNum::GetTxtNode() const
{
    return mpTxtNode;
}

void SwNodeNum::SetNumRule(SwNumRule * pRule)
{
    mpNumRule = pRule;
}

SwNumRule * SwNodeNum::GetNumRule() const
{
    return mpNumRule;
}

SwPosition SwNodeNum::GetPosition() const
{
    return SwPosition(*mpTxtNode);
}

SwNumberTreeNode * SwNodeNum::Create() const
{
    SwNodeNum * pResult = new SwNodeNum();

    pResult->SetNumRule(mpNumRule);

    return pResult;
}

SwNumberTreeNode * SwNodeNum::Copy() const
{
    return new SwNodeNum(*this);
}

void SwNodeNum::RemoveChild(SwNumberTreeNode * _pChild)
{
    SwNodeNum * pChild = static_cast<SwNodeNum*>(_pChild);

    pChild->SetNumRule(NULL);

    SwNumberTreeNode::RemoveChild(_pChild);
}

bool SwNodeNum::IsNotifiable() const
{
    bool aResult = true;

    if (mpTxtNode)
        aResult = mpTxtNode->IsNotifiable();

    return aResult;
}

bool SwNodeNum::IsContinuous() const
{
    bool aResult = false;

    if (mpTxtNode)
        aResult = mpTxtNode->IsContinuous();

    return aResult;
}

bool SwNodeNum::IsCounted() const
{
    bool aResult = false;

    if (mpTxtNode)
    {
        // --> OD 2006-01-25 #i59559#
        // <SwTxtNode::IsCounted()> determines, if a text node is counted for numbering
//        const SwNumFmt * pNumFmt = GetNumFmt();
//        if (pNumFmt)
//        {
//            sal_Int16 nType = pNumFmt->GetNumberingType();
//            if ( nType != SVX_NUM_NUMBER_NONE)
//                aResult = mpTxtNode->IsCounted();
//        }
        aResult = mpTxtNode->IsCounted();
        // <--
    }
    else
        aResult = SwNumberTreeNode::IsCounted();

    return aResult;
}

void SwNodeNum::NotifyNode()
{
    ValidateMe();

    if (mpTxtNode)
    {
        mpTxtNode->NumRuleChgd();
    }
}

bool SwNodeNum::LessThan(const SwNumberTreeNode & rNode) const
{
    bool bResult = false;
    const SwNodeNum & rTmpNode = static_cast<const SwNodeNum &>(rNode);

    if (mpTxtNode == NULL && rTmpNode.mpTxtNode != NULL)
        bResult = true;
    else if (mpTxtNode != NULL && rTmpNode.mpTxtNode != NULL)
    {
        SwPosition aMyPos(*mpTxtNode);
        SwPosition aHisPos(*rTmpNode.mpTxtNode);

        bResult = (aMyPos < aHisPos) ? true : false;
    }

    return bResult;
}

void SwNodeNum::SetRestart(bool bRestart)
{
    // --> OD 2005-10-19 #126009#
    // - improvement: invalidation only, if <IsRestart()> state changes.
    const bool bInvalidate( mbRestart != bRestart );
    // <--
    mbRestart = bRestart;

    // --> OD 2005-10-19 #126009#
    if ( bInvalidate )
    {
        InvalidateMe();
        NotifyInvalidSiblings();
    }
    // <--
}

bool SwNodeNum::IsRestart() const
{
    return mbRestart;
}

void SwNodeNum::SetStart(SwNumberTreeNode::tSwNumTreeNumber nStart)
{
    // --> OD 2005-10-19 #126009#
    // - improvement: invalidation only, if <IsRestart()> state changes.
    const bool bInvalidate( mnStart != nStart );
    // <--
    mnStart = nStart;

    // --> OD 2005-10-19 #126009#
    if ( bInvalidate )
    {
        InvalidateMe();
        NotifyInvalidSiblings();
    }
}

bool SwNodeNum::IsCountPhantoms() const
{
    bool bResult = true;

    if (mpNumRule)
        bResult = mpNumRule->IsCountPhantoms();

    return bResult;
}

SwNumberTreeNode::tSwNumTreeNumber SwNodeNum::GetStart() const
{
    tSwNumTreeNumber aResult = 1;

    // --> OD 2005-11-16 #i57919# - consider that start value <USHRT_MAX>
    // indicates, that the numbering is restarted at this node with the
    // start value, which is set at the corresponding numbering level.
    if ( IsRestart() && mnStart != USHRT_MAX )
    // <--
    {
        aResult = mnStart;
    }
    else
    {
        SwNumRule * pRule = GetNumRule();

        if (pRule)
        {
            int nLevel = GetLevel();

            if (nLevel >= 0 && nLevel < MAXLEVEL)
            {
                const SwNumFmt * pFmt = pRule->GetNumFmt(nLevel);

                if (pFmt)
                    aResult = pFmt->GetStart();
            }
        }
    }

    return aResult;
}

String SwNodeNum::ToString() const
{
    String aResult("[ ", RTL_TEXTENCODING_ASCII_US);

    if (GetTxtNode())
    {
        char aBuffer[256];

        sprintf(aBuffer, "%p ", GetTxtNode());

        aResult += String(aBuffer, RTL_TEXTENCODING_ASCII_US);
        aResult += String::CreateFromInt32(GetPosition().nNode.GetIndex());
    }
    else
        aResult += String("*", RTL_TEXTENCODING_ASCII_US);

    aResult += String(" ", RTL_TEXTENCODING_ASCII_US);

    unsigned int nLvl = GetLevel();
    aResult += String::CreateFromInt32(nLvl);

    aResult += String(": ", RTL_TEXTENCODING_ASCII_US);

    tNumberVector aNumVector;

    _GetNumberVector(aNumVector, false);

    for (unsigned int n = 0; n < aNumVector.size(); n++)
    {
        if (n > 0)
            aResult += String(", ", RTL_TEXTENCODING_ASCII_US);

        aResult += String::CreateFromInt32(aNumVector[n]);
    }

    if (IsCounted())
//        aResult += String(" counted", RTL_TEXTENCODING_ASCII_US);
        aResult += String(" C", RTL_TEXTENCODING_ASCII_US);

    if (IsRestart())
    {
//        aResult += String(" restart(", RTL_TEXTENCODING_ASCII_US);
        aResult += String(" R(", RTL_TEXTENCODING_ASCII_US);
        aResult += String::CreateFromInt32(GetStart());
        aResult += String(")", RTL_TEXTENCODING_ASCII_US);
    }

    if (! IsValid())
//        aResult += String(" invalid", RTL_TEXTENCODING_ASCII_US);
        aResult += String(" I", RTL_TEXTENCODING_ASCII_US);

    aResult += String(" ]", RTL_TEXTENCODING_ASCII_US);

    return aResult;
}

void SwNodeNum::SetLevel(unsigned int nLevel)
{
    ASSERT(nLevel >= 0 && nLevel < MAXLEVEL, "illegal level");

    if (mpParent)
    {
        SwNumRule * pRule = GetNumRule();

        if (pRule != mpNumRule || nLevel != GetLevel())
        {
            RemoveMe();

            if (pRule)
                pRule->AddNumber(this, nLevel);
        }
    }
}

const SwNumFmt * SwNodeNum::GetNumFmt() const
{
    const SwNumFmt * pResult = NULL;

    unsigned int nLevel = GetLevel();
    if (mpNumRule && nLevel >= 0 && nLevel < MAXLEVEL)
        pResult = &mpNumRule->Get(nLevel);

    return pResult;
}
<|endoftext|>


<commit_before>/*
 * Written by Nitin Kumar Maharana
 * nitin.maharana@gmail.com
 */

#include <iostream>

using namespace std;

template <class T>
struct node
{
	T val;
	struct node *next;
};

template <class T>
class Stack
{
	struct node<T> *top;

	public:

		Stack()
		{
			top = NULL;
		}

		void push(T item)
		{
			struct node<T> *t;
			t = new struct node<T>;
			t->val = item;
			t->next = top;
			top = t;
		}

		void pop(void)
		{
			if(empty())
				throw "There are no items in stack to pop!!!";

			struct node<T> *t;
			t = top;
			top = top->next;
			delete t;
		}

		T peek(void)
		{
			if(empty())
				throw "There are no items in stack to peek!!!";

			T item;
			item = top->val;
			return item;
		}

		bool empty(void)
		{
			return top == NULL ? true : false;
		}
};

int main(void)
{
	Stack<int> s;

	s.push(1);
	s.push(2);
	s.push(3);

	cout << s.peek() << endl;

	s.pop();

	cout << s.peek() << endl;
	cout << s.empty() << endl;

	s.pop();
	s.pop();

	cout << s.empty() << endl;

	return 0;
}<commit_msg>1. Implementation of Stack in CPP<commit_after>/*
 * Written by Nitin Kumar Maharana
 * nitin.maharana@gmail.com
 */

#include <iostream>

using namespace std;

template <class T>
struct node
{
	T val;
	struct node *next;
};

template <class T>
class Stack
{
	struct node<T> *top;

	public:

		Stack()
		{
			top = nullptr;
		}

		void push(T item)
		{
			struct node<T> *t;
			t = new struct node<T>;
			t->val = item;
			t->next = top;
			top = t;
		}

		void pop(void)
		{
			if(empty())
				throw "There are no items in stack to pop!!!";

			struct node<T> *t;
			t = top;
			top = top->next;
			delete t;
		}

		T peek(void)
		{
			if(empty())
				throw "There are no items in stack to peek!!!";

			T item;
			item = top->val;
			return item;
		}

		bool empty(void)
		{
			return top == nullptr ? true : false;
		}
};

int main(void)
{
	Stack<int> s;

	s.push(1);
	s.push(2);
	s.push(3);

	cout << s.peek() << endl;

	s.pop();

	cout << s.peek() << endl;
	cout << s.empty() << endl;

	s.pop();
	s.pop();

	cout << s.empty() << endl;

	return 0;
}
<|endoftext|>


<commit_before>

// TLE SOLUTION
// class Solution {
// public:
//     /*
//      * @param n an integer
//      * @return the nth prime number as description.
//      */

//     set<int> a;

//     bool isUgly(int i){
//     	int j=i;
//     	while (j % 2==0) j=j/2;
//     	while (j % 3==0) j=j/3;
//     	while (j % 5==0) j=j/5;
//     	if (j==1) return true;
//     	else return false;
//     }

//     int nthUglyNumber(int n) {
//         // write your code here

//         if (n<=0) return -1;
//         if (n==1) return 1;

//         int i,j,k=1;

//         i=1;

//         while (i<INT_MAX){
//         	i++;
//         	if (isUgly(i))
//         		{
//         			k++;
//         			if (k==n) return i;
//         		}

//         }

//         set<int>::iterator it1=a.begin();
//         for (int i=2;i<=n;i++) {
//         	  cout<<*it1<<"	";
//         	it1++;
//         }

//         return *it1;

//     }

// };<commit_msg>Solving 4<commit_after>class Solution {
public:
    /*
     * @param n an integer
     * @return the nth prime number as description.
     */
    int nthUglyNumber(int n) {
        // write your code here

        vector<int> ugly(n,0);
        ugly[0]=1;
        int ugly2=0,ugly3=0,ugly5=0;

        int i=1;
        while(i<=n-1){
            int minUgly=min(min(ugly[ugly2]*2,ugly[ugly3]*3),ugly[ugly5]*5);
            ugly[i]=minUgly;

            /*注意这里分别if,因为有可能有多个等于minUgly*/
            if(minUgly==ugly[ugly2]*2){
                ugly2++;
            }
            if(minUgly==ugly[ugly3]*3){
                ugly3++;
            }
            if(minUgly==ugly[ugly5]*5){
                ugly5++;
            }
            i++;
        }

        return ugly[n-1];
    }
};

// TLE SOLUTION
// class Solution {
// public:
//     /*
//      * @param n an integer
//      * @return the nth prime number as description.
//      */

//     set<int> a;

//     bool isUgly(int i){
//     	int j=i;
//     	while (j % 2==0) j=j/2;
//     	while (j % 3==0) j=j/3;
//     	while (j % 5==0) j=j/5;
//     	if (j==1) return true;
//     	else return false;
//     }

//     int nthUglyNumber(int n) {
//         // write your code here

//         if (n<=0) return -1;
//         if (n==1) return 1;

//         int i,j,k=1;

//         i=1;

//         while (i<INT_MAX){
//         	i++;
//         	if (isUgly(i))
//         		{
//         			k++;
//         			if (k==n) return i;
//         		}

//         }

//         set<int>::iterator it1=a.begin();
//         for (int i=2;i<=n;i++) {
//         	  cout<<*it1<<"	";
//         	it1++;
//         }

//         return *it1;

//     }

// };<|endoftext|>


<commit_before>#include "InstructionParser.hpp"

#include "gtest/gtest.h"

using namespace ::testing;

struct InstructionParserTest : public Test
{
  InstructionParser parser;
};

TEST_F(InstructionParserTest, ParserShouldDeclineUnknownInstruction)
{
  EXPECT_THROW(parser.parseInstructions("Instructions"), InstructionParser::UnknownInstruction);
}

TEST_F(InstructionParserTest, ParserShouldRejectInstuctionLd)
{
  const Tokens expectedTokens{TokenType::Ld, TokenType::A};
  parser.parseInstructions("ld a,");
}

TEST_F(InstructionParserTest, ParserShouldAcceptInstructionOut)
{
  const Tokens expectedTokens{TokenType::Out, TokenType::ZeroWithBrackets, TokenType::A};
  EXPECT_EQ(expectedTokens, parser.parseInstructions("out (0),a"));
}

TEST_F(InstructionParserTest, ParserShouldAcceptEmptyLine)
{
  const Tokens expectedTokens{};
  EXPECT_EQ(expectedTokens, parser.parseInstructions(""));
}

TEST_F(InstructionParserTest, ParserShouldAcceptInstructionOutWithWhitespaces)
{
  const Tokens expectedTokens{TokenType::Out, TokenType::ZeroWithBrackets, TokenType::A};
  EXPECT_EQ(expectedTokens, parser.parseInstructions(" \t    out (0),a"));
}

TEST_F(InstructionParserTest, ParserShouldAcceptTwoInstructions)
{
  const Tokens expectedTokens{TokenType::Out, TokenType::ZeroWithBrackets, TokenType::A,
                              TokenType::Out, TokenType::ZeroWithBrackets, TokenType::A};
  EXPECT_EQ(expectedTokens, parser.parseInstructions("out (0),a\nout (0),a"));
}

TEST_F(InstructionParserTest, ParserShouldThrowIfSecondInstructionIsInvalid)
{
  EXPECT_THROW(parser.parseInstructions("out (0),a\ninvalid"), InstructionParser::UnknownInstruction);
}

TEST_F(InstructionParserTest, ParserShouldAcceptTwoInstructionsWithEmptyLine)
{
  const Tokens expectedTokens{TokenType::Out, TokenType::ZeroWithBrackets, TokenType::A,
                              TokenType::Out, TokenType::ZeroWithBrackets, TokenType::A};
  EXPECT_EQ(expectedTokens, parser.parseInstructions("out (0),a\n\nout (0),a"));
}

TEST_F(InstructionParserTest, ParserShouldAbleToGetNumberAsToken)
{
  const Tokens expectedTokens{TokenType::Number8Bit};
  parser.parseInstructions("0");
}
<commit_msg>InstructionParser is able to accept 0 as token<commit_after>#include "InstructionParser.hpp"

#include "gtest/gtest.h"

using namespace ::testing;

struct InstructionParserTest : public Test
{
  InstructionParser parser;
};

TEST_F(InstructionParserTest, ParserShouldDeclineUnknownInstruction)
{
  EXPECT_THROW(parser.parseInstructions("Instructions"), InstructionParser::UnknownInstruction);
}

TEST_F(InstructionParserTest, ParserShouldRejectInstuctionLd)
{
  const Tokens expectedTokens{TokenType::Ld, TokenType::A};
  parser.parseInstructions("ld a,");
}

TEST_F(InstructionParserTest, ParserShouldAcceptInstructionOut)
{
  const Tokens expectedTokens{TokenType::Out, TokenType::ZeroWithBrackets, TokenType::A};
  EXPECT_EQ(expectedTokens, parser.parseInstructions("out (0),a"));
}

TEST_F(InstructionParserTest, ParserShouldAcceptEmptyLine)
{
  const Tokens expectedTokens{};
  EXPECT_EQ(expectedTokens, parser.parseInstructions(""));
}

TEST_F(InstructionParserTest, ParserShouldAcceptInstructionOutWithWhitespaces)
{
  const Tokens expectedTokens{TokenType::Out, TokenType::ZeroWithBrackets, TokenType::A};
  EXPECT_EQ(expectedTokens, parser.parseInstructions(" \t    out (0),a"));
}

TEST_F(InstructionParserTest, ParserShouldAcceptTwoInstructions)
{
  const Tokens expectedTokens{TokenType::Out, TokenType::ZeroWithBrackets, TokenType::A,
                              TokenType::Out, TokenType::ZeroWithBrackets, TokenType::A};
  EXPECT_EQ(expectedTokens, parser.parseInstructions("out (0),a\nout (0),a"));
}

TEST_F(InstructionParserTest, ParserShouldThrowIfSecondInstructionIsInvalid)
{
  EXPECT_THROW(parser.parseInstructions("out (0),a\ninvalid"), InstructionParser::UnknownInstruction);
}

TEST_F(InstructionParserTest, ParserShouldAcceptTwoInstructionsWithEmptyLine)
{
  const Tokens expectedTokens{TokenType::Out, TokenType::ZeroWithBrackets, TokenType::A,
                              TokenType::Out, TokenType::ZeroWithBrackets, TokenType::A};
  EXPECT_EQ(expectedTokens, parser.parseInstructions("out (0),a\n\nout (0),a"));
}

TEST_F(InstructionParserTest, ParserShouldAbleToGet0AsToken)
{
  const Tokens expectedTokens{TokenType::Number8Bit};
  parser.parseInstructions("0");
}

TEST_F(InstructionParserTest, ParserShouldAbleToGet255AsToken)
{
  const Tokens expectedTokens{TokenType::Number8Bit};
  parser.parseInstructions("255");
}<|endoftext|>


<commit_before>/*
 * Copyright (C) 2019 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <functional>
#include <optional>
#include <map>
#include <string>
#include <vector>

#include <seastar/core/future.hh>
#include <seastar/core/lowres_clock.hh>
#include <seastar/core/shared_ptr.hh>
#include <seastar/core/sstring.hh>

#include "exceptions/exceptions.hh"
#include "json.hh"
#include "timestamp.hh"

class schema;
using schema_ptr = seastar::lw_shared_ptr<const schema>;

namespace locator {

class snitch_ptr;
class token_metadata;

} // namespace locator

namespace service {

class migration_manager;
class storage_proxy;
class query_state;

} // namespace service

namespace dht {

class i_partitioner;

} // namespace dht

class mutation;
class partition_key;

namespace cdc {

class options final {
    bool _enabled = false;
    bool _preimage = false;
    bool _postimage = false;
    int _ttl = 86400; // 24h in seconds
public:
    options() = default;
    options(const std::map<sstring, sstring>& map) {
        if (map.find("enabled") == std::end(map)) {
            throw exceptions::configuration_exception("Missing enabled CDC option");
        }

        for (auto& p : map) {
            if (p.first == "enabled") {
                _enabled = p.second == "true";
            } else if (p.first == "preimage") {
                _preimage = p.second == "true";
            } else if (p.first == "postimage") {
                _postimage = p.second == "true";
            } else if (p.first == "ttl") {
                _ttl = std::stoi(p.second);
            } else {
                throw exceptions::configuration_exception("Invalid CDC option: " + p.first);
            }
        }
    }
    std::map<sstring, sstring> to_map() const {
        return {
            { "enabled", _enabled ? "true" : "false" },
            { "preimage", _preimage ? "true" : "false" },
            { "postimage", _postimage ? "true" : "false" },
            { "ttl", std::to_string(_ttl) },
        };
    }

    sstring to_sstring() const {
        return json::to_json(to_map());
    }

    bool enabled() const { return _enabled; }
    bool preimage() const { return _preimage; }
    bool postimage() const { return _postimage; }
    int ttl() const { return _ttl; }

    bool operator==(const options& o) const {
        return _enabled == o._enabled && _preimage == o._preimage && _postimage == o._postimage && _ttl == o._ttl;
    }
    bool operator!=(const options& o) const {
        return !(*this == o);
    }
};

struct db_context final {
    service::storage_proxy& _proxy;
    service::migration_manager& _migration_manager;
    locator::token_metadata& _token_metadata;
    locator::snitch_ptr& _snitch;
    dht::i_partitioner& _partitioner;

    class builder final {
        service::storage_proxy& _proxy;
        std::optional<std::reference_wrapper<service::migration_manager>> _migration_manager;
        std::optional<std::reference_wrapper<locator::token_metadata>> _token_metadata;
        std::optional<std::reference_wrapper<locator::snitch_ptr>> _snitch;
        std::optional<std::reference_wrapper<dht::i_partitioner>> _partitioner;
    public:
        builder(service::storage_proxy& proxy) : _proxy(proxy) { }

        builder with_migration_manager(service::migration_manager& migration_manager) {
            _migration_manager = migration_manager;
            return *this;
        }

        builder with_token_metadata(locator::token_metadata& token_metadata) {
            _token_metadata = token_metadata;
            return *this;
        }

        builder with_snitch(locator::snitch_ptr& snitch) {
            _snitch = snitch;
            return *this;
        }

        builder with_partitioner(dht::i_partitioner& partitioner) {
            _partitioner = partitioner;
            return *this;
        }

        db_context build();
    };
};

/// \brief Sets up CDC related tables for a given table
///
/// This function not only creates CDC Log and CDC Description for a given table
/// but also populates CDC Description with a list of change streams.
///
/// param[in] ctx object with references to database components
/// param[in] schema schema of a table for which CDC tables are being created
seastar::future<> setup(db_context ctx, schema_ptr schema);

/// \brief Deletes CDC Log and CDC Description tables for a given table
///
/// This function cleans up all CDC related tables created for a given table.
/// At the moment, CDC Log and CDC Description are the only affected tables.
/// It's ok if some/all of them don't exist.
///
/// \param[in] ctx object with references to database components
/// \param[in] ks_name keyspace name of a table for which CDC tables are removed
/// \param[in] table_name name of a table for which CDC tables are removed
///
/// \pre This function works correctly no matter if CDC Log and/or CDC Description
///      exist.
seastar::future<>
remove(db_context ctx, const seastar::sstring& ks_name, const seastar::sstring& table_name);

seastar::sstring log_name(const seastar::sstring& table_name);

seastar::sstring desc_name(const seastar::sstring& table_name);

/// \brief For each mutation in the set appends related CDC Log mutation
///
/// This function should be called with a set of mutations of a table
/// with CDC enabled. Returned set of mutations contains all original mutations
/// and for each original mutation appends a mutation to CDC Log that reflects
/// the change.
///
/// \param[in] ctx object with references to database components
/// \param[in] s schema of a CDC enabled table which is being modified
/// \param[in] timeout period of time after which a request is considered timed out
/// \param[in] qs the state of the query that's being executed
/// \param[in] mutations set of changes of a CDC enabled table
///
/// \return set of mutations from input parameter with relevant CDC Log mutations appended
///
/// \pre CDC Log and CDC Description have to exist
/// \pre CDC Description has to be in sync with cluster topology
///
/// \note At the moment, cluster topology changes are not supported
//        so the assumption that CDC Description is in sync with cluster topology
//        is easy to enforce. When support for cluster topology changes is added
//        it has to make sure the assumption holds.
seastar::future<std::vector<mutation>>append_log_mutations(
        db_context ctx,
        schema_ptr s,
        lowres_clock::time_point timeout,
        service::query_state& qs,
        std::vector<mutation> mutations);

} // namespace cdc
<commit_msg>cdc: Return db_context::builder by reference<commit_after>/*
 * Copyright (C) 2019 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <functional>
#include <optional>
#include <map>
#include <string>
#include <vector>

#include <seastar/core/future.hh>
#include <seastar/core/lowres_clock.hh>
#include <seastar/core/shared_ptr.hh>
#include <seastar/core/sstring.hh>

#include "exceptions/exceptions.hh"
#include "json.hh"
#include "timestamp.hh"

class schema;
using schema_ptr = seastar::lw_shared_ptr<const schema>;

namespace locator {

class snitch_ptr;
class token_metadata;

} // namespace locator

namespace service {

class migration_manager;
class storage_proxy;
class query_state;

} // namespace service

namespace dht {

class i_partitioner;

} // namespace dht

class mutation;
class partition_key;

namespace cdc {

class options final {
    bool _enabled = false;
    bool _preimage = false;
    bool _postimage = false;
    int _ttl = 86400; // 24h in seconds
public:
    options() = default;
    options(const std::map<sstring, sstring>& map) {
        if (map.find("enabled") == std::end(map)) {
            throw exceptions::configuration_exception("Missing enabled CDC option");
        }

        for (auto& p : map) {
            if (p.first == "enabled") {
                _enabled = p.second == "true";
            } else if (p.first == "preimage") {
                _preimage = p.second == "true";
            } else if (p.first == "postimage") {
                _postimage = p.second == "true";
            } else if (p.first == "ttl") {
                _ttl = std::stoi(p.second);
            } else {
                throw exceptions::configuration_exception("Invalid CDC option: " + p.first);
            }
        }
    }
    std::map<sstring, sstring> to_map() const {
        return {
            { "enabled", _enabled ? "true" : "false" },
            { "preimage", _preimage ? "true" : "false" },
            { "postimage", _postimage ? "true" : "false" },
            { "ttl", std::to_string(_ttl) },
        };
    }

    sstring to_sstring() const {
        return json::to_json(to_map());
    }

    bool enabled() const { return _enabled; }
    bool preimage() const { return _preimage; }
    bool postimage() const { return _postimage; }
    int ttl() const { return _ttl; }

    bool operator==(const options& o) const {
        return _enabled == o._enabled && _preimage == o._preimage && _postimage == o._postimage && _ttl == o._ttl;
    }
    bool operator!=(const options& o) const {
        return !(*this == o);
    }
};

struct db_context final {
    service::storage_proxy& _proxy;
    service::migration_manager& _migration_manager;
    locator::token_metadata& _token_metadata;
    locator::snitch_ptr& _snitch;
    dht::i_partitioner& _partitioner;

    class builder final {
        service::storage_proxy& _proxy;
        std::optional<std::reference_wrapper<service::migration_manager>> _migration_manager;
        std::optional<std::reference_wrapper<locator::token_metadata>> _token_metadata;
        std::optional<std::reference_wrapper<locator::snitch_ptr>> _snitch;
        std::optional<std::reference_wrapper<dht::i_partitioner>> _partitioner;
    public:
        builder(service::storage_proxy& proxy) : _proxy(proxy) { }

        builder& with_migration_manager(service::migration_manager& migration_manager) {
            _migration_manager = migration_manager;
            return *this;
        }

        builder& with_token_metadata(locator::token_metadata& token_metadata) {
            _token_metadata = token_metadata;
            return *this;
        }

        builder& with_snitch(locator::snitch_ptr& snitch) {
            _snitch = snitch;
            return *this;
        }

        builder& with_partitioner(dht::i_partitioner& partitioner) {
            _partitioner = partitioner;
            return *this;
        }

        db_context build();
    };
};

/// \brief Sets up CDC related tables for a given table
///
/// This function not only creates CDC Log and CDC Description for a given table
/// but also populates CDC Description with a list of change streams.
///
/// param[in] ctx object with references to database components
/// param[in] schema schema of a table for which CDC tables are being created
seastar::future<> setup(db_context ctx, schema_ptr schema);

/// \brief Deletes CDC Log and CDC Description tables for a given table
///
/// This function cleans up all CDC related tables created for a given table.
/// At the moment, CDC Log and CDC Description are the only affected tables.
/// It's ok if some/all of them don't exist.
///
/// \param[in] ctx object with references to database components
/// \param[in] ks_name keyspace name of a table for which CDC tables are removed
/// \param[in] table_name name of a table for which CDC tables are removed
///
/// \pre This function works correctly no matter if CDC Log and/or CDC Description
///      exist.
seastar::future<>
remove(db_context ctx, const seastar::sstring& ks_name, const seastar::sstring& table_name);

seastar::sstring log_name(const seastar::sstring& table_name);

seastar::sstring desc_name(const seastar::sstring& table_name);

/// \brief For each mutation in the set appends related CDC Log mutation
///
/// This function should be called with a set of mutations of a table
/// with CDC enabled. Returned set of mutations contains all original mutations
/// and for each original mutation appends a mutation to CDC Log that reflects
/// the change.
///
/// \param[in] ctx object with references to database components
/// \param[in] s schema of a CDC enabled table which is being modified
/// \param[in] timeout period of time after which a request is considered timed out
/// \param[in] qs the state of the query that's being executed
/// \param[in] mutations set of changes of a CDC enabled table
///
/// \return set of mutations from input parameter with relevant CDC Log mutations appended
///
/// \pre CDC Log and CDC Description have to exist
/// \pre CDC Description has to be in sync with cluster topology
///
/// \note At the moment, cluster topology changes are not supported
//        so the assumption that CDC Description is in sync with cluster topology
//        is easy to enforce. When support for cluster topology changes is added
//        it has to make sure the assumption holds.
seastar::future<std::vector<mutation>>append_log_mutations(
        db_context ctx,
        schema_ptr s,
        lowres_clock::time_point timeout,
        service::query_state& qs,
        std::vector<mutation> mutations);

} // namespace cdc
<|endoftext|>


<commit_before>/**
 * The MIT License
 *
 * 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.
 *
 * @copyright  2009-2012 Roberto Perpuly
 * @license    http://www.opensource.org/licenses/mit-license.php The MIT License
 */
#include <pelet/ParserClass.h>
#include <pelet/TokenClass.h>
#include <unicode/unistr.h>
#include <unicode/ustdio.h>

// this is only used so that this program ca be run through valgrind (memory leak
// detector). In real-world usage, this include is not needed.
#include <unicode/uclean.h>

/**
 * This is a program that shows the sample usage of the pelet library.
 *
 * The pelet library interface to the parser.  We will given pelet::ParserClass an instance
 * of this object; as pelet::ParserClass is tokenizing source code, it will call only the appropriate
 * pelet::(Class|ClassMember|Function)ObserverClass methods AS SOON AS THE TOKEN IS REACHED.
 */
class SampleObserver :
	public pelet::ClassObserverClass,   // for classes and define()
	public pelet::ClassMemberObserverClass,  // for properties and methods
	public pelet::FunctionObserverClass,  // for functions
	public pelet::VariableObserverClass { // for variables

public:

	/**
	 * This method gets called when a class is found.
	 *
	 * @param const UnicodeString& className the name of the class that was found
	 * @param const UnicodeString& signature the list of classes that the class inherits / implements in code format
	 *        for example "extends UserClass implements Runnable"
	 * @param const UnicodeString& comment PHPDoc attached to the class
	 * @param lineNumber the line number (1-based) that the class was found in
	 */
	virtual void ClassFound(const UnicodeString& className, const UnicodeString& signature,
		const UnicodeString& comment, const int lineNumber) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		u_fprintf(ufout, "Class Found: %.*S on line %d\n", className.length(), className.getBuffer(), lineNumber);
		u_fclose(ufout);
	}

	/**
	 * This method gets called when a define declaration is found.
	 *
	 * @param const UnicodeString& variableName the name of the defined variable
	 * @param const UnicodeString& variableValue the variable value
	 * @param const UnicodeString& comment PHPDoc attached to the define
	 * @param lineNumber the line number (1-based) that the define was found in
	 */
	virtual void DefineDeclarationFound(const UnicodeString& variableName, const UnicodeString& variableValue,
		const UnicodeString& comment, const int lineNumber) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		u_fprintf(ufout, "Define Found: %.*S on line %d\n", variableName.length(), variableName.getBuffer(), lineNumber);
		u_fclose(ufout);
	}

	/**
	 * Override this method to perform any custom logic when an include / require / require_once / include_once declaration is found.
	 *
	 * @param const UnicodeString& filename the name of the included file, but only if the statement
	 *        is a constant expression. Otherwise, lineNumber will be an empty string
	 * @param lineNumber the line number (1-based) that the include/ was found in
	 */
	virtual void IncludeFound(const UnicodeString& filename, const int lineNumber) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		u_fprintf(ufout, "Include or Require Found: %.*S on line %d\n", filename.length(), filename.getBuffer(), lineNumber);
		u_fclose(ufout);
	}

	/* This method gets called when a class method is found.
	 *
	 * @param const UnicodeString& className the name of the class that was found
	 * @param const UnicodeString& methodName the name of the method that was found
	 * @param const UnicodeString& signature string containing method parameters.  String is normalized, meaning that
	 *        any extra white space is removed, and every token is separated by one space only. ie. for the code
	 *        "public function doWork( $item1,   $item2  ) " the signature will be  "($item1, $item2)"
	 * @param const UnicodeString& returnType the method's return type, as dictated by the PHPDoc comment
	 * @param const UnicodeString& comment PHPDoc attached to the class
	 * @param visibility the visibility token attached to the method: PUBLIC, PROTECTED, or PRIVATE
	 * @param isStatic true if the method is static
	 * @param lineNumber the line number (1-based) that the method was found in
	 */
	virtual void MethodFound(const UnicodeString& className, const UnicodeString& methodName,
		const UnicodeString& signature, const UnicodeString& returnType, const UnicodeString& comment,
		pelet::TokenClass::TokenIds visibility, bool isStatic, const int lineNumber) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		if (returnType.isEmpty()) {
			u_fprintf(ufout, "Method Found: %.*S in class %.*S on line %d. Method did not have @return in PHPDoc comment\n",
				methodName.length(), methodName.getBuffer(), className.length(), className.getBuffer(), lineNumber);
		}
		else {
			u_fprintf(ufout, "Method Found: %.*S in class %.*S on line %d and returns %.*S\n",
				methodName.length(), methodName.getBuffer(), className.length(), className.getBuffer(), lineNumber,
				returnType.length(), returnType.getBuffer());
		}
		u_fclose(ufout);
	}

	/**
	 * Override this method to perform any custom logic when a class property is found.
	 *
	 * @param const UnicodeString& className the name of the class that was found
	 * @param const UnicodeString& propertyName the name of the property that was found
	 * @param const UnicodeString& propertyType the property's type, as dictated by the PHPDoc comment
	 * @param const UnicodeString& comment PHPDoc attached to the property
	 * @param visibility the visibility token attached  to the property: PUBLIC, PROTECTED, or PRIVATE
	 * @param bool isConst true if property is a constant
	 * @param isStatic true if the property is static
	 * @param lineNumber the line number (1-based) that the property was found in
	 */
	virtual void PropertyFound(const UnicodeString& className, const UnicodeString& propertyName,
		const UnicodeString& propertyType, const UnicodeString& comment,
		pelet::TokenClass::TokenIds visibility, bool isConst, bool isStatic, const int lineNumber) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		if (propertyType.isEmpty()) {
			u_fprintf(ufout, "Property Found: %.*S in class %.*S on line %d. Did not have @return in PHPDoc comment\n",
				propertyName.length(), propertyName.getBuffer(), className.length(), className.getBuffer(), lineNumber);
		}
		else {
			u_fprintf(ufout, "Property Found: %.*S in class %.*S on line %d and is of type %.*S\n",
				propertyName.length(), propertyName.getBuffer(), className.length(), className.getBuffer(), lineNumber,
				propertyType.length(), propertyType.getBuffer());
		}
		u_fclose(ufout);
	}

	/**
	 * This method gets called when the function has ended (a closing brace '}' was encountered).
	 *
	 * @param const UnicodeString& className the name of the class that was found
	 * @param const UnicodeString& methodName the name of the method that was found
	 * @param pos the character position (of the closing brace '}' original source code)
	 */
	virtual void MethodEnd(const UnicodeString& className, const UnicodeString& methodName, int pos) {

	}

	/**
	 * This method gets called when a function is found.
	 *
	 * @param const UnicodeString& functionName the name of the method that was found
	 * @param const UnicodeString& signature string containing method parameters.  String is normalized, meaning that
	 *        any extra white space is removed, and every token is separated by one space only. ie. for the code
	 *        "public function doWork( $item1,   $item2  ) " the signature will be  "($item1, $item2)"
	 * @param const UnicodeString& returnType the function's return type, as dictated by the PHPDoc comment
	 * @param const UnicodeString& comment PHPDoc attached to the class
	 * @param lineNumber the line number (1-based) that the function was found in
	 */
	virtual void FunctionFound(const UnicodeString& functionName,
		const UnicodeString& signature, const UnicodeString& returnType, const UnicodeString& comment, const int lineNumber) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		if (returnType.isEmpty()) {
			u_fprintf(ufout, "Function Found: %.*S on line %d. Function Did not have @return in PHPDoc comment\n",
				functionName.length(), functionName.getBuffer(), lineNumber);
		}
		else {
			u_fprintf(ufout, "Function Found: %.*S on line %d and it returns %.*S\n",
				functionName.length(), functionName.getBuffer(), lineNumber,
				returnType.length(), returnType.getBuffer());
		}
		u_fclose(ufout);
	}

	/**
	 * This method gets called when the function has ended (a closing brace '}' was encountered).
	 * @param const UnicodeString& functionName the name of the method that was found
	 * @param pos the character position (of the closing brace '}' original source code)
	 */
	virtual void FunctionEnd(const UnicodeString& functionName, int pos) {

	}

	/**
	 * This method gets called when a variable assignment is found. Note that the same
	 * variable may be assigned different values at different times within the same function.
	 * The symbol will be constructed in the following way:
	 *
	 * Example assignment:  $name = $this->getName()->toString();
	 *
	 * Lexeme: lexeme will contain the variable's name (ie $name)
	 * ChainList: This is a list of  properties / methods
	 *            that were successively invoked.
	 *            In this example, the expression chain list will have 3 items in
	 *           the chain list "$this" "->getName()" and "->toString()".
	 *
	 *
	 * @param const UnicodeString& className class where the variable was found. may be empty is variable is scoped
	 *        inside a function or is global.
	 * @param const UnicodeString& methodName function/method name where the variable was found. may be empty if
	 *        variable is globally scoped.
	 * @param const SymbolClass& symbol the name  & type of the variable that was found
	 * @param const UnicodeString& comment PHPDoc attached to the variable
	 */
	virtual void VariableFound(const UnicodeString& className, const UnicodeString& methodName,
			const pelet::SymbolClass& symbol, const UnicodeString& comment) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		UnicodeString scope;
		if (className.isEmpty() && methodName.isEmpty()) {
			scope = UNICODE_STRING_SIMPLE("<global>");
		}
		else if (className.isEmpty() && !methodName.isEmpty()) {
			scope = methodName;
		}
		else {
			scope = className + UNICODE_STRING_SIMPLE("::") + methodName;
		}
		UnicodeString type;
		if (pelet::SymbolClass::ARRAY == symbol.Type) {
			type = UNICODE_STRING_SIMPLE("Variable is an array");
		}
		else if (pelet::SymbolClass::PRIMITIVE == symbol.Type) {
			type = UNICODE_STRING_SIMPLE("Variable is a primitive");
		}
		else if (pelet::SymbolClass::OBJECT == symbol.Type) {
			type = UNICODE_STRING_SIMPLE("Variable is the result of an object operation. ");
			type += UNICODE_STRING_SIMPLE("Chain list is: ");
			for (size_t i = 0; i < symbol.ChainList.size(); ++i) {
				type += symbol.ChainList[i];
				if (i < (symbol.ChainList.size() - 1)) {
					type += UNICODE_STRING_SIMPLE(", ");
				}
			}

		}
		else if (pelet::SymbolClass::UNKNOWN == symbol.Type) {
			type = UNICODE_STRING_SIMPLE("Variable is dynamic variable");
		}
		if (!symbol.PhpDocType.isEmpty()) {
			type += UNICODE_STRING_SIMPLE("Variable is decorated with a PHPDoc comment: ");
			type += symbol.PhpDocType;
		}
		u_fprintf(ufout, "Variable Found: %.*S in scope %S. %S\n",
				symbol.Lexeme.length(), symbol.Lexeme.getBuffer(),
				scope.getTerminatedBuffer(),
				type.getTerminatedBuffer());
	}
};

int main(int argc, char** argv) {
	if (argc < 2) {
		printf("This program requires 1 argument: The path of the PHP file to parse.\n");
		return -1;
	}
	SampleObserver observer;
	pelet::ParserClass parser;
	parser.SetClassObserver(&observer);
	parser.SetClassMemberObserver(&observer);
	parser.SetFunctionObserver(&observer);
	parser.SetVariableObserver(&observer);

	pelet::LintResultsClass results;
	bool parsed = parser.ScanFile(argv[1], results);
	if (parsed) {
		printf("Parsing complete.\n");
	}
	else {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		u_fprintf(ufout, "Parse error: %S on line %d\n", results.Error.getTerminatedBuffer(), results.LineNumber);
		u_fclose(ufout);
	}

	// this is only used so that this program can be run through valgrind (memory leak
	// detector). In real-world usage, this include is not needed.
	u_cleanup();
	return 0;
}<commit_msg>sample now uses the pelet 5.4 parser<commit_after>/**
 * The MIT License
 *
 * 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.
 *
 * @copyright  2009-2012 Roberto Perpuly
 * @license    http://www.opensource.org/licenses/mit-license.php The MIT License
 */
#include <pelet/ParserClass.h>
#include <pelet/TokenClass.h>
#include <unicode/unistr.h>
#include <unicode/ustdio.h>

// this is only used so that this program ca be run through valgrind (memory leak
// detector). In real-world usage, this include is not needed.
#include <unicode/uclean.h>

/**
 * This is a program that shows the sample usage of the pelet library.
 *
 * The pelet library interface to the parser.  We will given pelet::ParserClass an instance
 * of this object; as pelet::ParserClass is tokenizing source code, it will call only the appropriate
 * pelet::(Class|ClassMember|Function)ObserverClass methods AS SOON AS THE TOKEN IS REACHED.
 */
class SampleObserver :
	public pelet::ClassObserverClass,   // for classes and define()
	public pelet::ClassMemberObserverClass,  // for properties and methods
	public pelet::FunctionObserverClass,  // for functions
	public pelet::VariableObserverClass { // for variables

public:

	/**
	 * This method gets called when a class is found.
	 *
	 * @param const UnicodeString& className the name of the class that was found
	 * @param const UnicodeString& signature the list of classes that the class inherits / implements in code format
	 *        for example "extends UserClass implements Runnable"
	 * @param const UnicodeString& comment PHPDoc attached to the class
	 * @param lineNumber the line number (1-based) that the class was found in
	 */
	virtual void ClassFound(const UnicodeString& className, const UnicodeString& signature,
		const UnicodeString& comment, const int lineNumber) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		u_fprintf(ufout, "Class Found: %.*S on line %d\n", className.length(), className.getBuffer(), lineNumber);
		u_fclose(ufout);
	}

	/**
	 * This method gets called when a define declaration is found.
	 *
	 * @param const UnicodeString& variableName the name of the defined variable
	 * @param const UnicodeString& variableValue the variable value
	 * @param const UnicodeString& comment PHPDoc attached to the define
	 * @param lineNumber the line number (1-based) that the define was found in
	 */
	virtual void DefineDeclarationFound(const UnicodeString& variableName, const UnicodeString& variableValue,
		const UnicodeString& comment, const int lineNumber) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		u_fprintf(ufout, "Define Found: %.*S on line %d\n", variableName.length(), variableName.getBuffer(), lineNumber);
		u_fclose(ufout);
	}

	/**
	 * Override this method to perform any custom logic when an include / require / require_once / include_once declaration is found.
	 *
	 * @param const UnicodeString& filename the name of the included file, but only if the statement
	 *        is a constant expression. Otherwise, lineNumber will be an empty string
	 * @param lineNumber the line number (1-based) that the include/ was found in
	 */
	virtual void IncludeFound(const UnicodeString& filename, const int lineNumber) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		u_fprintf(ufout, "Include or Require Found: %.*S on line %d\n", filename.length(), filename.getBuffer(), lineNumber);
		u_fclose(ufout);
	}

	/* This method gets called when a class method is found.
	 *
	 * @param const UnicodeString& className the name of the class that was found
	 * @param const UnicodeString& methodName the name of the method that was found
	 * @param const UnicodeString& signature string containing method parameters.  String is normalized, meaning that
	 *        any extra white space is removed, and every token is separated by one space only. ie. for the code
	 *        "public function doWork( $item1,   $item2  ) " the signature will be  "($item1, $item2)"
	 * @param const UnicodeString& returnType the method's return type, as dictated by the PHPDoc comment
	 * @param const UnicodeString& comment PHPDoc attached to the class
	 * @param visibility the visibility token attached to the method: PUBLIC, PROTECTED, or PRIVATE
	 * @param isStatic true if the method is static
	 * @param lineNumber the line number (1-based) that the method was found in
	 */
	virtual void MethodFound(const UnicodeString& className, const UnicodeString& methodName,
		const UnicodeString& signature, const UnicodeString& returnType, const UnicodeString& comment,
		pelet::TokenClass::TokenIds visibility, bool isStatic, const int lineNumber) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		if (returnType.isEmpty()) {
			u_fprintf(ufout, "Method Found: %.*S in class %.*S on line %d. Method did not have @return in PHPDoc comment\n",
				methodName.length(), methodName.getBuffer(), className.length(), className.getBuffer(), lineNumber);
		}
		else {
			u_fprintf(ufout, "Method Found: %.*S in class %.*S on line %d and returns %.*S\n",
				methodName.length(), methodName.getBuffer(), className.length(), className.getBuffer(), lineNumber,
				returnType.length(), returnType.getBuffer());
		}
		u_fclose(ufout);
	}

	/**
	 * Override this method to perform any custom logic when a class property is found.
	 *
	 * @param const UnicodeString& className the name of the class that was found
	 * @param const UnicodeString& propertyName the name of the property that was found
	 * @param const UnicodeString& propertyType the property's type, as dictated by the PHPDoc comment
	 * @param const UnicodeString& comment PHPDoc attached to the property
	 * @param visibility the visibility token attached  to the property: PUBLIC, PROTECTED, or PRIVATE
	 * @param bool isConst true if property is a constant
	 * @param isStatic true if the property is static
	 * @param lineNumber the line number (1-based) that the property was found in
	 */
	virtual void PropertyFound(const UnicodeString& className, const UnicodeString& propertyName,
		const UnicodeString& propertyType, const UnicodeString& comment,
		pelet::TokenClass::TokenIds visibility, bool isConst, bool isStatic, const int lineNumber) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		if (propertyType.isEmpty()) {
			u_fprintf(ufout, "Property Found: %.*S in class %.*S on line %d. Did not have @return in PHPDoc comment\n",
				propertyName.length(), propertyName.getBuffer(), className.length(), className.getBuffer(), lineNumber);
		}
		else {
			u_fprintf(ufout, "Property Found: %.*S in class %.*S on line %d and is of type %.*S\n",
				propertyName.length(), propertyName.getBuffer(), className.length(), className.getBuffer(), lineNumber,
				propertyType.length(), propertyType.getBuffer());
		}
		u_fclose(ufout);
	}

	/**
	 * This method gets called when the function has ended (a closing brace '}' was encountered).
	 *
	 * @param const UnicodeString& className the name of the class that was found
	 * @param const UnicodeString& methodName the name of the method that was found
	 * @param pos the character position (of the closing brace '}' original source code)
	 */
	virtual void MethodEnd(const UnicodeString& className, const UnicodeString& methodName, int pos) {

	}

	/**
	 * This method gets called when a trait use statement has been found
	 *
	 * @param className the fully qualified name of the class that uses the trait
	 * @param traitName the fully qualified name of the trait to be used
	 */
	virtual void TraitUseFound(const UnicodeString& className, const UnicodeString& traitName) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		u_fprintf(ufout, "Trait Usage Found in class %.*S. Trait Name %.*S \n",
			className.length(), className.getBuffer(), traitName.length(), traitName.getBuffer());
		u_fclose(ufout);
	}

	/**
	 * Override this method to perform custom logic when a trait method has been aliased
	 *
	 * @param traitUsedClassName the class name of the trait to be aliased
	 * @param traitMethodName the fully qualified name of the trait method that is to be aliased (hidden)
	 *        this may be empty if the trait adaptation only changes the visibility and
	 *        does not need to resolve a trait conflict
	 * @param alias the name of the new alias. alias may be empty when ONLY the visibility is changed.
	 * @param visibility the visbility of the trait method. may be PUBLIC if the visibility was not changed.
	 */
	virtual void TraitAliasFound(const UnicodeString& className, const UnicodeString& traitUsedClassName,
		const UnicodeString& traitMethodName,
		const UnicodeString& alias, pelet::TokenClass::TokenIds visibility) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		if (!alias.isEmpty()) {
			char* visibilityStr;
			if (pelet::TokenClass::PRIVATE == visibility) {
				visibilityStr = "private";
			}
			else if (pelet::TokenClass::PROTECTED == visibility) {
				visibilityStr = "protected";
			}
			else {
				visibilityStr = "public";
			}
			u_fprintf(ufout, "Trait Alias Found in class %.*S. Trait Class %.*S Trait Method %.*S Trait Alias %.*S New Visibility %s \n",
				className.length(), className.getBuffer(),
				traitUsedClassName.length(), traitUsedClassName.getBuffer(),
				traitMethodName.length(), traitMethodName.getBuffer(),
				alias.length(), alias.getBuffer(),
				visibilityStr);
		}
		else {
			char* visibilityStr;
			if (pelet::TokenClass::PRIVATE == visibility) {
				visibilityStr = "private";
			}
			else if (pelet::TokenClass::PROTECTED == visibility) {
				visibilityStr = "protected";
			}
			else {
				visibilityStr = "public";
			}
			u_fprintf(ufout, "Trait Change in visbility Found in class %.*S. Trait Class %.*S Trait Method %.*S New Visibility %s\n",
				className.length(), className.getBuffer(),
				traitUsedClassName.length(), traitUsedClassName.getBuffer(),
				traitMethodName.length(), traitMethodName.getBuffer(),
				visibilityStr
			);
		}
		u_fclose(ufout);
	}

	/**
	 * This method gets called when a function is found.
	 *
	 * @param const UnicodeString& functionName the name of the method that was found
	 * @param const UnicodeString& signature string containing method parameters.  String is normalized, meaning that
	 *        any extra white space is removed, and every token is separated by one space only. ie. for the code
	 *        "public function doWork( $item1,   $item2  ) " the signature will be  "($item1, $item2)"
	 * @param const UnicodeString& returnType the function's return type, as dictated by the PHPDoc comment
	 * @param const UnicodeString& comment PHPDoc attached to the class
	 * @param lineNumber the line number (1-based) that the function was found in
	 */
	virtual void FunctionFound(const UnicodeString& functionName,
		const UnicodeString& signature, const UnicodeString& returnType, const UnicodeString& comment, const int lineNumber) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		if (returnType.isEmpty()) {
			u_fprintf(ufout, "Function Found: %.*S on line %d. Function Did not have @return in PHPDoc comment\n",
				functionName.length(), functionName.getBuffer(), lineNumber);
		}
		else {
			u_fprintf(ufout, "Function Found: %.*S on line %d and it returns %.*S\n",
				functionName.length(), functionName.getBuffer(), lineNumber,
				returnType.length(), returnType.getBuffer());
		}
		u_fclose(ufout);
	}

	/**
	 * This method gets called when the function has ended (a closing brace '}' was encountered).
	 * @param const UnicodeString& functionName the name of the method that was found
	 * @param pos the character position (of the closing brace '}' original source code)
	 */
	virtual void FunctionEnd(const UnicodeString& functionName, int pos) {

	}

	/**
	 * This method gets called when a variable assignment is found. Note that the same
	 * variable may be assigned different values at different times within the same function.
	 * The symbol will be constructed in the following way:
	 *
	 * Example assignment:  $name = $this->getName()->toString();
	 *
	 * Lexeme: lexeme will contain the variable's name (ie $name)
	 * ChainList: This is a list of  properties / methods
	 *            that were successively invoked.
	 *            In this example, the expression chain list will have 3 items in
	 *           the chain list "$this" "->getName()" and "->toString()".
	 *
	 *
	 * @param const UnicodeString& className class where the variable was found. may be empty is variable is scoped
	 *        inside a function or is global.
	 * @param const UnicodeString& methodName function/method name where the variable was found. may be empty if
	 *        variable is globally scoped.
	 * @param const SymbolClass& symbol the name  & type of the variable that was found
	 * @param const UnicodeString& comment PHPDoc attached to the variable
	 */
	virtual void VariableFound(const UnicodeString& className, const UnicodeString& methodName,
			const pelet::SymbolClass& symbol, const UnicodeString& comment) {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		UnicodeString scope;
		if (className.isEmpty() && methodName.isEmpty()) {
			scope = UNICODE_STRING_SIMPLE("<global>");
		}
		else if (className.isEmpty() && !methodName.isEmpty()) {
			scope = methodName;
		}
		else {
			scope = className + UNICODE_STRING_SIMPLE("::") + methodName;
		}
		UnicodeString type;
		if (pelet::SymbolClass::ARRAY == symbol.Type) {
			type = UNICODE_STRING_SIMPLE("Variable is an array");
		}
		else if (pelet::SymbolClass::PRIMITIVE == symbol.Type) {
			type = UNICODE_STRING_SIMPLE("Variable is a primitive");
		}
		else if (pelet::SymbolClass::OBJECT == symbol.Type) {
			type = UNICODE_STRING_SIMPLE("Variable is the result of an object operation. ");
			type += UNICODE_STRING_SIMPLE("Chain list is: ");
			for (size_t i = 0; i < symbol.ChainList.size(); ++i) {
				type += symbol.ChainList[i];
				if (i < (symbol.ChainList.size() - 1)) {
					type += UNICODE_STRING_SIMPLE(", ");
				}
			}

		}
		else if (pelet::SymbolClass::UNKNOWN == symbol.Type) {
			type = UNICODE_STRING_SIMPLE("Variable is dynamic variable");
		}
		if (!symbol.PhpDocType.isEmpty()) {
			type += UNICODE_STRING_SIMPLE("Variable is decorated with a PHPDoc comment: ");
			type += symbol.PhpDocType;
		}
		u_fprintf(ufout, "Variable Found: %.*S in scope %S. %S\n",
				symbol.Lexeme.length(), symbol.Lexeme.getBuffer(),
				scope.getTerminatedBuffer(),
				type.getTerminatedBuffer());
	}
};

int main(int argc, char** argv) {
	if (argc < 2) {
		printf("This program requires 1 argument: The path of the PHP file to parse.\n");
		return -1;
	}
	SampleObserver observer;
	pelet::ParserClass parser;
	parser.SetVersion(pelet::PHP_54);
	parser.SetClassObserver(&observer);
	parser.SetClassMemberObserver(&observer);
	parser.SetFunctionObserver(&observer);
	parser.SetVariableObserver(&observer);

	pelet::LintResultsClass results;
	bool parsed = parser.ScanFile(argv[1], results);
	if (parsed) {
		printf("Parsing complete.\n");
	}
	else {
		UFILE* ufout = u_finit(stdout, NULL, NULL);
		u_fprintf(ufout, "Parse error: %S on line %d\n", results.Error.getTerminatedBuffer(), results.LineNumber);
		u_fclose(ufout);
	}

	// this is only used so that this program can be run through valgrind (memory leak
	// detector). In real-world usage, this include is not needed.
	u_cleanup();
	return 0;
}<|endoftext|>


<commit_before>#include <primesieve/soe/PrimeSieve.h>
#include <iostream>

unsigned int sum = 0;

void callback(unsigned int prime) {
  sum += prime;
}

int main() {
  PrimeSieve ps;
  ps.generatePrimes(2, 1000, callback);
  std::cout << "Sum of the primes below 1000 = " << sum << std::endl;
  return 0;
}
<commit_msg>not needed anymore<commit_after><|endoftext|>


<commit_before>// @(#)root/tree:$Name:  $:$Id: TMethodBrowsable.cxx,v 1.1 2004/10/17 11:55:47 brun Exp $
// Author: Axel Naumann   14/10/2004

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TMethodBrowsable                                                     //
//                                                                      //
// A helper object to browse methods (see                               //
// TBranchElement::GetBrowsableMethods)                                 //
//////////////////////////////////////////////////////////////////////////

#include "TMethodBrowsable.h"
#include "TBranchElement.h"
#include "TMethod.h"
#include "TBrowser.h"
#include "TTree.h"
#include "TPad.h"
#include "TClass.h"
#include "TBaseClass.h"

ClassImp(TMethodBrowsable);

//______________________________________________________________________________
TMethodBrowsable::TMethodBrowsable(TBranchElement* be, TMethod* m,
                                   TMethodBrowsable* parent /* =0 */):
      fBranchElement(be), fParent(parent), fMethod(m),
      fReturnClass(0), fReturnLeafs(0), fReturnIsPointer(kFALSE) {
// standard constructor.
// Links a TBranchElement with a TMethod, allowing the TBrowser to
// Browser simple methods.
//
// The c'tor sets the name for a method "Class::Method(params) const"
// to "Method(params)", title to TMethod::GetPrototype
   TString name(m->GetName());
   name+="()";
   if (name.EndsWith(" const")) name.Remove(name.Length()-6);
   SetName(name);

   name=m->GetPrototype();
   if (m->GetCommentString() && strlen(m->GetCommentString()))
      name.Append(" // ").Append(m->GetCommentString());
   SetTitle(name);

   TString plainReturnType(m->GetReturnTypeName());
   if (plainReturnType.EndsWith("*")) {
      fReturnIsPointer=kTRUE;
      plainReturnType.Remove(plainReturnType.Length()-1);
      plainReturnType.Strip();
   }
   fReturnClass=gROOT->GetClass(plainReturnType);
}

//______________________________________________________________________________
void TMethodBrowsable::Browse(TBrowser *b) {
// Calls TTree::Draw on the method if return type is not a class;
// otherwise expands returned object's "folder"

   if (!fReturnClass) {
      TString name;
      GetScope(name);
      fBranchElement->GetTree()->Draw(name, "", b ? b->GetDrawOption() : "");
      if (gPad) gPad->Update();
   } else {
      if (!fReturnLeafs)
         fReturnLeafs=GetMethodBrowsables(fBranchElement, fReturnClass, this);
      if (fReturnLeafs)
         fReturnLeafs->Browse(b);
   }
}

//______________________________________________________________________________
TList* TMethodBrowsable::GetMethodBrowsables(TBranchElement* be, TClass* cl,
                                             TMethodBrowsable* parent /* =0 */) {
// Given a class, this methods returns a list of TMethodBrowsables
// for the class and its base classes.
// This list has to be deleted by the caller!

   if (!cl) return 0;

   TList allClasses;
   allClasses.Add(cl);

   for(TObjLink* lnk=allClasses.FirstLink();
       lnk; lnk=lnk->Next()){
      cl=(TClass*)lnk->GetObject();
      TList* bases=cl->GetListOfBases();
      TBaseClass* base;
      TIter iB(bases);
      while ((base=(TBaseClass*)iB())) {
         TClass* bc=base->GetClassPointer();
         if (bc) allClasses.Add(bc);
      }
   }

   TList allMethods;
   TIter iC(&allClasses);
   while ((cl=(TClass*)iC())) {
      TList* methods=cl->GetListOfMethods();
      if (!methods) continue;
      TMethod* method=0;
      TIter iM(methods);
      while ((method=(TMethod*)iM()))
         if (method && !allMethods.FindObject(method->GetName()))
             allMethods.Add(method);
   }

   TIter iM(&allMethods);
   TMethod* m=0;
   TList* browsableMethods=new TList();
   browsableMethods->SetOwner();
   while ((m=(TMethod*)iM()))
      if (TMethodBrowsable::IsMethodBrowsable(m))
         browsableMethods->Add(new TMethodBrowsable(be, m, parent));

   return browsableMethods;
}

//______________________________________________________________________________
void TMethodBrowsable::GetScope(TString & scope) {
// Returns the full name for TTree::Draw to draw *this.
// Recursively appends, starting form the top TBranchElement,
// all method names with proper reference operators (->, .)
// depending on fReturnIsPointer.

   if (fParent)
      fParent->GetScope(scope);
   else {
      scope=fBranchElement->GetName();
      scope+=".";
      TBranch* mother=fBranchElement;
      while (mother != mother->GetMother() && (mother=mother->GetMother()))
         scope.Prepend(".").Prepend(mother->GetName());
   }
   scope+=GetName();
   if (fReturnClass) // otherwise we're a leaf, and we are the one drawn
      if (fReturnIsPointer)
         scope+="->";
      else scope+=".";
}

//______________________________________________________________________________
Bool_t TMethodBrowsable::IsMethodBrowsable(TMethod* m) {
// A TMethod is browsable if it is const, public and not pure virtual,
// if does not have any parameter without default value, and if it has
// a (non-void) return value.

   return (m->GetNargs()-m->GetNargsOpt()==0
           && (m->Property() & kIsConstant
               & ~kIsPrivate & ~kIsProtected & ~kIsPureVirtual )
           && m->GetReturnTypeName()
           && strcmp("void",m->GetReturnTypeName())
           && !strstr(m->GetName(),"DeclFile")
           && !strstr(m->GetName(),"ImplFile")
           && strcmp(m->GetName(),"IsA")
           && strcmp(m->GetName(),"Class")
           && strcmp(m->GetName(),"CanBypassStreamer")
           && strcmp(m->GetName(),"Class_Name")
           && strcmp(m->GetName(),"ClassName")
           && strcmp(m->GetName(),"Clone")
           && strcmp(m->GetName(),"DrawClone")
           && strcmp(m->GetName(),"GetName")
           && strcmp(m->GetName(),"GetDrawOption")
           && strcmp(m->GetName(),"GetIconName")
           && strcmp(m->GetName(),"GetOption")
           && strcmp(m->GetName(),"GetTitle")
           && strcmp(m->GetName(),"GetUniqueID")
           && strcmp(m->GetName(),"Hash")
           && strcmp(m->GetName(),"IsFolder")
           && strcmp(m->GetName(),"IsOnHeap")
           && strcmp(m->GetName(),"IsSortable")
           && strcmp(m->GetName(),"IsZombie"));
}
<commit_msg>From Axel naumann: Browsable methods may not have a corresponding data member, i.e. if a member fX, _X, or mX exists, the methods GetX(), getX(), and X() will not be browsable.<commit_after>// @(#)root/tree:$Name:  $:$Id: TMethodBrowsable.cxx,v 1.2 2004/10/17 20:59:58 brun Exp $
// Author: Axel Naumann   14/10/2004

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TMethodBrowsable                                                     //
//                                                                      //
// A helper object to browse methods (see                               //
// TBranchElement::GetBrowsableMethods)                                 //
//////////////////////////////////////////////////////////////////////////

#include "TMethodBrowsable.h"
#include "TBranchElement.h"
#include "TMethod.h"
#include "TBrowser.h"
#include "TTree.h"
#include "TPad.h"
#include "TClass.h"
#include "TBaseClass.h"

ClassImp(TMethodBrowsable);

//______________________________________________________________________________
TMethodBrowsable::TMethodBrowsable(TBranchElement* be, TMethod* m,
                                   TMethodBrowsable* parent /* =0 */):
      fBranchElement(be), fParent(parent), fMethod(m),
      fReturnClass(0), fReturnLeafs(0), fReturnIsPointer(kFALSE) {
// standard constructor.
// Links a TBranchElement with a TMethod, allowing the TBrowser to
// Browser simple methods.
//
// The c'tor sets the name for a method "Class::Method(params) const"
// to "Method(params)", title to TMethod::GetPrototype
   TString name(m->GetName());
   name+="()";
   if (name.EndsWith(" const")) name.Remove(name.Length()-6);
   SetName(name);

   name=m->GetPrototype();
   if (m->GetCommentString() && strlen(m->GetCommentString()))
      name.Append(" // ").Append(m->GetCommentString());
   SetTitle(name);

   TString plainReturnType(m->GetReturnTypeName());
   if (plainReturnType.EndsWith("*")) {
      fReturnIsPointer=kTRUE;
      plainReturnType.Remove(plainReturnType.Length()-1);
      plainReturnType.Strip();
   }
   fReturnClass=gROOT->GetClass(plainReturnType);
}

//______________________________________________________________________________
void TMethodBrowsable::Browse(TBrowser *b) {
// Calls TTree::Draw on the method if return type is not a class;
// otherwise expands returned object's "folder"

   if (!fReturnClass) {
      TString name;
      GetScope(name);
      fBranchElement->GetTree()->Draw(name, "", b ? b->GetDrawOption() : "");
      if (gPad) gPad->Update();
   } else {
      if (!fReturnLeafs)
         fReturnLeafs=GetMethodBrowsables(fBranchElement, fReturnClass, this);
      if (fReturnLeafs)
         fReturnLeafs->Browse(b);
   }
}

//______________________________________________________________________________
TList* TMethodBrowsable::GetMethodBrowsables(TBranchElement* be, TClass* cl,
                                             TMethodBrowsable* parent /* =0 */) {
// Given a class, this methods returns a list of TMethodBrowsables
// for the class and its base classes.
// This list has to be deleted by the caller!

   if (!cl) return 0;

   TList allClasses;
   allClasses.Add(cl);

   for(TObjLink* lnk=allClasses.FirstLink();
       lnk; lnk=lnk->Next()){
      cl=(TClass*)lnk->GetObject();
      TList* bases=cl->GetListOfBases();
      TBaseClass* base;
      TIter iB(bases);
      while ((base=(TBaseClass*)iB())) {
         TClass* bc=base->GetClassPointer();
         if (bc) allClasses.Add(bc);
      }
   }

   TList allMethods;
   TIter iC(&allClasses);
   while ((cl=(TClass*)iC())) {
      TList* methods=cl->GetListOfMethods();
      if (!methods) continue;
      TMethod* method=0;
      TIter iM(methods);
      while ((method=(TMethod*)iM()))
         if (method && !allMethods.FindObject(method->GetName()))
             allMethods.Add(method);
   }

   TIter iM(&allMethods);
   TMethod* m=0;
   TList* browsableMethods=new TList();
   browsableMethods->SetOwner();
   while ((m=(TMethod*)iM()))
      if (TMethodBrowsable::IsMethodBrowsable(m))
         browsableMethods->Add(new TMethodBrowsable(be, m, parent));

   return browsableMethods;
}

//______________________________________________________________________________
void TMethodBrowsable::GetScope(TString & scope) {
// Returns the full name for TTree::Draw to draw *this.
// Recursively appends, starting form the top TBranchElement,
// all method names with proper reference operators (->, .)
// depending on fReturnIsPointer.

   if (fParent)
      fParent->GetScope(scope);
   else {
      scope=fBranchElement->GetName();
      scope+=".";
      TBranch* mother=fBranchElement;
      while (mother != mother->GetMother() && (mother=mother->GetMother()))
         scope.Prepend(".").Prepend(mother->GetName());
   }
   scope+=GetName();
   if (fReturnClass) // otherwise we're a leaf, and we are the one drawn
      if (fReturnIsPointer)
         scope+="->";
      else scope+=".";
}

//______________________________________________________________________________
Bool_t TMethodBrowsable::IsMethodBrowsable(TMethod* m) {
// A TMethod is browsable if it is const, public and not pure virtual,
// if does not have any parameter without default value, and if it has
// a (non-void) return value.
// A method called *, Get*, or get* will not be browsable if there is a
// data member called f*, _*, or m*, as data member access is faster
// than method access. Examples: if one of fX, _X, or mX is a data
// member, the methods GetX(), getX(), and X() will not be browsable.

   if (m->GetNargs()-m->GetNargsOpt()==0
       && (m->Property() & kIsConstant
           & ~kIsPrivate & ~kIsProtected & ~kIsPureVirtual )
       && m->GetReturnTypeName()
       && strcmp("void",m->GetReturnTypeName())
       && !strstr(m->GetName(),"DeclFile")
       && !strstr(m->GetName(),"ImplFile")
       && strcmp(m->GetName(),"IsA")
       && strcmp(m->GetName(),"Class")
       && strcmp(m->GetName(),"CanBypassStreamer")
       && strcmp(m->GetName(),"Class_Name")
       && strcmp(m->GetName(),"ClassName")
       && strcmp(m->GetName(),"Clone")
       && strcmp(m->GetName(),"DrawClone")
       && strcmp(m->GetName(),"GetName")
       && strcmp(m->GetName(),"GetDrawOption")
       && strcmp(m->GetName(),"GetIconName")
       && strcmp(m->GetName(),"GetOption")
       && strcmp(m->GetName(),"GetTitle")
       && strcmp(m->GetName(),"GetUniqueID")
       && strcmp(m->GetName(),"Hash")
       && strcmp(m->GetName(),"IsFolder")
       && strcmp(m->GetName(),"IsOnHeap")
       && strcmp(m->GetName(),"IsSortable")
       && strcmp(m->GetName(),"IsZombie")) {
         // look for matching data member
         TClass* cl=m->GetClass();
         if (!cl) return kTRUE;
         TList* members=cl->GetListOfDataMembers();
         if (!members) return kTRUE;
         const char* baseName=m->GetName();
         if (!strncmp(m->GetName(), "Get", 3) ||
             !strncmp(m->GetName(), "get", 3))
            baseName+=3;
         if (!baseName[0]) return kTRUE;
         return (!members->FindObject(Form("f%s", baseName)) &&
                 !members->FindObject(Form("_%s", baseName)) &&
                 !members->FindObject(Form("m%s", baseName)));
   };
   return kFALSE;
}
<|endoftext|>


<commit_before>#include <moe/moe.hpp>
#include <iostream>

#ifdef _MSC_VER
    #include <string> // needed with MSVC 19.0 for overloaded << on std::string
#endif

#include <chrono>
#include <unordered_map>

void remove_duplicates(std::string &str)
{
    std::string unique = "";
    unique += str[0];
    for(unsigned int i = 1; i < str.size(); i++)
    {
        bool found = false;
        for(unsigned int j = 0; j < unique.size(); j++)
        {
            if(str[i] == unique[j])
                found = true;
        }
        if(found == false)
            unique += str[i];
    }
    str = unique;
}

int main()
{
    Moether<Moe> moether;

    std::unordered_map< std::string, unsigned int > distances;
    distances["AB"] = 100;
    distances["AC"] = 300;
    distances["AD"] = 100;
    distances["AE"] = 75;

    distances["BA"] = distances["AB"];
    distances["BC"] = 50;
    distances["BD"] = 75;
    distances["BE"] = 125;

    distances["CA"] = distances["AC"];
    distances["CB"] = distances["BC"];
    distances["CD"] = 100;
    distances["CE"] = 125;

    distances["DA"] = distances["AD"];
    distances["DB"] = distances["BD"];
    distances["DC"] = distances["CD"];
    distances["DE"] = 50;

    distances["EA"] = distances["AE"];
    distances["EB"] = distances["BE"];
    distances["EC"] = distances["CE"];
    distances["ED"] = distances["DE"];

    moether.setFitnessFunction( [&distances](const Moe& moe) -> double
    {
        std::string genotype = moe.getGenotype();

        unsigned int fitness = 0;

        std::string test_string = genotype;
        remove_duplicates(test_string);

        if( test_string.size() == genotype.size() && genotype.size() == 4 )
        {

            int error = -1000;
            genotype.insert(0, "A");
            genotype += "A";

            while( genotype.size() >= 2 )
            {
                std::string pair = "";
                pair += genotype[0];
                pair += genotype[1];

                error += distances[ pair ];

                genotype.erase( genotype.begin() );
            }
            fitness += -error;
        }

        return fitness;
    });

    moether.setInitGenotypeSize( 5 );
    moether.setCharset("BCDE");
    moether.setCrossover( moe::Crossover::Uniform );

    auto start = std::chrono::high_resolution_clock::now();

        moether.init( 30 , 5 );
        moether.run( 100 );

    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<float> diff = end-start;

    std::cout   << "genotype: " << moether.getBestMoe().getGenotype() << "\n"
                << "fitness: " << moether.getBestMoe().getFitness() << "\n"
                << "time spent: " << diff.count() << " seconds" << "\n";

    std::cout   << "path = A" << moether.getBestMoe().getGenotype() + "A\n"
                << "distance = " << std::abs(moether.getBestMoe().getFitness() - 1000) << std::endl;
}<commit_msg>Updated salesman example<commit_after>#include <moe/moe.hpp>
#include <iostream>

#ifdef _MSC_VER
    #include <string> // needed with MSVC 19.0 for overloaded << on std::string
#endif

#include <chrono>
#include <unordered_map>

void remove_duplicates(std::string &str)
{
    std::string unique = "";
    unique += str[0];
    for(unsigned int i = 1; i < str.size(); i++)
    {
        bool found = false;
        for(unsigned int j = 0; j < unique.size(); j++)
        {
            if(str[i] == unique[j])
                found = true;
        }
        if(found == false)
            unique += str[i];
    }
    str = unique;
}

int main()
{
    Moether<Moe> moether;

    std::unordered_map< std::string, unsigned int > distances;
    distances["AB"] = 100;
    distances["AC"] = 300;
    distances["AD"] = 100;
    distances["AE"] = 75;

    distances["BA"] = distances["AB"];
    distances["BC"] = 50;
    distances["BD"] = 75;
    distances["BE"] = 125;

    distances["CA"] = distances["AC"];
    distances["CB"] = distances["BC"];
    distances["CD"] = 100;
    distances["CE"] = 125;

    distances["DA"] = distances["AD"];
    distances["DB"] = distances["BD"];
    distances["DC"] = distances["CD"];
    distances["DE"] = 50;

    distances["EA"] = distances["AE"];
    distances["EB"] = distances["BE"];
    distances["EC"] = distances["CE"];
    distances["ED"] = distances["DE"];

    moether.setFitnessFunction( [&distances](const Moe& moe) -> double
    {
        std::string genotype = moe.getGenotype();

        unsigned int fitness = 0;

        std::string test_string = genotype;
        remove_duplicates(test_string);

        if( test_string.size() == genotype.size() && genotype.size() == 4 )
        {

            int error = -1000;
            genotype.insert(0, "A");
            genotype += "A";

            while( genotype.size() >= 2 )
            {
                std::string pair = "";
                pair += genotype[0];
                pair += genotype[1];

                error += distances[ pair ];

                genotype.erase( genotype.begin() );
            }
            fitness += -error;
        }

        return fitness;
    });

    moether.setInitGenotypeSize( 4 );
    moether.setCharset("BCDE");
    moether.setCrossover( moe::Crossover::Uniform );
    moether.unregisterMutation( moe::Mutation::Insertion );
    moether.unregisterMutation( moe::Mutation::Deletion );

    auto start = std::chrono::high_resolution_clock::now();

        moether.init( 30 , 5 );
        moether.run( 100 );

    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<float> diff = end-start;

    std::cout   << "genotype: " << moether.getBestMoe().getGenotype() << "\n"
                << "fitness: " << moether.getBestMoe().getFitness() << "\n"
                << "time spent: " << diff.count() << " seconds" << "\n";

    std::cout   << "path = A" << moether.getBestMoe().getGenotype() + "A\n"
                << "distance = " << std::abs(moether.getBestMoe().getFitness() - 1000) << std::endl;
}<|endoftext|>