<commit_before>////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
//    you must not claim that you wrote the original software.
//    If you use this software in a product, an acknowledgment
//    in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
//    and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////

#ifndef RESOURCE_FACTORY_HPP
#define RESOURCE_FACTORY_HPP

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////

#include <map>
////////////////////////////////////////////////////////////
/// \breif Resource Factory that serves as the creation location
///  for all resources
///
////////////////////////////////////////////////////////////

namespace rm
{

class ResourceFactory
{
 public:

 private:

	////////////////////////////////////////////////////////////
    /// \brief A Strandard Map to hold all the resouce type
    /// classes that define how they are created
    ///
    /// Example: It could hold a image ResourceAllicatorInterface
    /// that will define how to load an image
    ///
    ////////////////////////////////////////////////////////////
    std::map<std::string, std::shared_ptr<ResourceAllocatorInterface>> allocatorFunctions;

	////////////////////////////////////////////////////////////
    /// \brief Looks up the ResouceAllocatorInterface needed to create
    /// The resouce based on the type and calls create on it to make a
    /// A new resouce of the specified type
    ///
    /// \return Shared Pointer of the newly Created Resouce
    ///
    ////////////////////////////////////////////////////////////
    static std::shared_ptr<BaseResource> createResource(std::string& path, std::string& type);

	////////////////////////////////////////////////////////////
    /// \brief Creates a new ResouceAllocatorInterface based on the passed
	/// Resource type. Gets the type name from the resouceType class and stores
	/// The created resourceAllocatorInterface is stored in allicatorFunctions
    /// A new resouce of the specified type.
    ///
    ////////////////////////////////////////////////////////////
    static void addType<shared_ptr<BaseResource> resourceType>;
}

}

#endif //RESOURCE_FACTORY_HPP<commit_msg>ResourceMananger.hpp<commit_after>////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
//    you must not claim that you wrote the original software.
//    If you use this software in a product, an acknowledgment
//    in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
//    and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////

#ifndef RESOURCE_FACTORY_HPP
#define RESOURCE_FACTORY_HPP

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////

#include <map>
////////////////////////////////////////////////////////////
/// \breif Resource Factory that serves as the creation location
///  for all resources
///
////////////////////////////////////////////////////////////

namespace rm
{

class ResourceFactory
{
 public:

 private:

	////////////////////////////////////////////////////////////
    /// \brief A Strandard Map to hold all the resouce type
    /// classes that define how they are created
    ///
    /// Example: It could hold a image ResourceAllicatorInterface
    /// that will define how to load an image
    ///
    ////////////////////////////////////////////////////////////
    std::map<std::string, std::shared_ptr<ResourceAllocatorInterface>> allocatorFunctions;

	////////////////////////////////////////////////////////////
    /// \brief Looks up the ResouceAllocatorInterface needed to create
    /// The resouce based on the type and calls create on it to make a
    /// A new resouce of the specified type
    ///
    /// \return Shared Pointer of the newly Created Resouce
    ///
    ////////////////////////////////////////////////////////////
    static std::shared_ptr<BaseResource> createResource(std::string& path, std::string& type);

	////////////////////////////////////////////////////////////
    /// \brief Creates a new ResouceAllocatorInterface based on the passed
	/// Resource type. Gets the type name from the resouceType class and stores
	/// The created resourceAllocatorInterface is stored in allicatorFunctions
    /// A new resouce of the specified type.
    ///
    ////////////////////////////////////////////////////////////
    template <class T>
    static void addType();
}

}

#endif //RESOURCE_FACTORY_HPP<|endoftext|>


<commit_before>//=-- GRExprEngineInternalChecks.cpp - Builtin GRExprEngine Checks---*- C++ -*-=
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the BugType classes used by GRExprEngine to report
//  bugs derived from builtin checks in the path-sensitive engine.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "llvm/Support/Compiler.h"
#include <sstream>

using namespace clang;

//===----------------------------------------------------------------------===//
// Utility functions.
//===----------------------------------------------------------------------===//

template <typename ITERATOR> inline
ExplodedNode<GRState>* GetNode(ITERATOR I) {
  return *I;
}

template <> inline
ExplodedNode<GRState>* GetNode(GRExprEngine::undef_arg_iterator I) {
  return I->first;
}

//===----------------------------------------------------------------------===//
// Bug Descriptions.
//===----------------------------------------------------------------------===//

namespace {
class VISIBILITY_HIDDEN BuiltinBug : public BugTypeCacheLocation {
  const char* name;
  const char* desc;
public:
  BuiltinBug(const char* n, const char* d = 0) : name(n), desc(d) {}
  virtual const char* getName() const { return name; }
  virtual const char* getDescription() const {
    return desc ? desc : name;
  }

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) = 0;
  virtual void EmitWarnings(BugReporter& BR) {
    EmitBuiltinWarnings(BR, cast<GRBugReporter>(BR).getEngine());
  }

  template <typename ITER>
  void Emit(BugReporter& BR, ITER I, ITER E) {
    for (; I != E; ++I) {
      BugReport R(*this, GetNode(I));
      BR.EmitWarning(R);
    }
  }

  virtual const char* getCategory() const { return "Logic Errors"; }
};

class VISIBILITY_HIDDEN NullDeref : public BuiltinBug {
public:
  NullDeref() : BuiltinBug("null dereference",
                           "Dereference of null pointer.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.null_derefs_begin(), Eng.null_derefs_end());
  }
};

class VISIBILITY_HIDDEN UndefinedDeref : public BuiltinBug {
public:
  UndefinedDeref() : BuiltinBug("uninitialized pointer dereference",
                                "Dereference of undefined value.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.undef_derefs_begin(), Eng.undef_derefs_end());
  }
};

class VISIBILITY_HIDDEN DivZero : public BuiltinBug {
public:
  DivZero() : BuiltinBug("divide-by-zero",
                         "Division by zero/undefined value.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.explicit_bad_divides_begin(), Eng.explicit_bad_divides_end());
  }
};

class VISIBILITY_HIDDEN UndefResult : public BuiltinBug {
public:
  UndefResult() : BuiltinBug("undefined result",
                             "Result of operation is undefined.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.undef_results_begin(), Eng.undef_results_end());
  }
};

class VISIBILITY_HIDDEN BadCall : public BuiltinBug {
public:
  BadCall()
  : BuiltinBug("invalid function call",
        "Called function is a NULL or undefined function pointer value.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.bad_calls_begin(), Eng.bad_calls_end());
  }
};

class VISIBILITY_HIDDEN BadArg : public BuiltinBug {
public:
  BadArg() : BuiltinBug("uninitialized argument",
    "Pass-by-value argument in function is undefined.") {}

  BadArg(const char* d) : BuiltinBug("uninitialized argument", d) {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::UndefArgsTy::iterator I = Eng.undef_arg_begin(),
         E = Eng.undef_arg_end(); I!=E; ++I) {

      // Generate a report for this bug.
      RangedBugReport report(*this, I->first);
      report.addRange(I->second->getSourceRange());

      // Emit the warning.
      BR.EmitWarning(report);
    }
  }
};

class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg {
public:
  BadMsgExprArg()
    : BadArg("Pass-by-value argument in message expression is undefined.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
         E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {

      // Generate a report for this bug.
      RangedBugReport report(*this, I->first);
      report.addRange(I->second->getSourceRange());

      // Emit the warning.
      BR.EmitWarning(report);
    }
  }
};

class VISIBILITY_HIDDEN BadReceiver : public BuiltinBug {
public:
  BadReceiver()
  : BuiltinBug("uninitialized receiver",
               "Receiver in message expression is an uninitialized value.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::UndefReceiversTy::iterator I=Eng.undef_receivers_begin(),
         End = Eng.undef_receivers_end(); I!=End; ++I) {

      // Generate a report for this bug.
      RangedBugReport report(*this, *I);

      ExplodedNode<GRState>* N = *I;
      Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
      Expr* E = cast<ObjCMessageExpr>(S)->getReceiver();
      assert (E && "Receiver cannot be NULL");
      report.addRange(E->getSourceRange());

      // Emit the warning.
      BR.EmitWarning(report);
    }
  }
};

class VISIBILITY_HIDDEN RetStack : public BuiltinBug {
public:
  RetStack() : BuiltinBug("return of stack address") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::ret_stackaddr_iterator I=Eng.ret_stackaddr_begin(),
         End = Eng.ret_stackaddr_end(); I!=End; ++I) {

      ExplodedNode<GRState>* N = *I;
      Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
      Expr* E = cast<ReturnStmt>(S)->getRetValue();
      assert (E && "Return expression cannot be NULL");

      // Get the value associated with E.
      loc::MemRegionVal V =
        cast<loc::MemRegionVal>(Eng.getStateManager().GetSVal(N->getState(),
                                                               E));

      // Generate a report for this bug.
      std::ostringstream os;
      os << "Address of stack memory associated with local variable '"
         << V.getRegion()->getString() << "' returned.";

      std::string s = os.str();

      RangedBugReport report(*this, N, s.c_str());
      report.addRange(E->getSourceRange());

      // Emit the warning.
      BR.EmitWarning(report);
    }
  }
};

class VISIBILITY_HIDDEN UndefBranch : public BuiltinBug {
  struct VISIBILITY_HIDDEN FindUndefExpr {
    GRStateManager& VM;
    const GRState* St;

    FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}

    Expr* FindExpr(Expr* Ex) {
      if (!MatchesCriteria(Ex))
        return 0;

      for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end();I!=E;++I)
        if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
          Expr* E2 = FindExpr(ExI);
          if (E2) return E2;
        }

      return Ex;
    }

    bool MatchesCriteria(Expr* Ex) { return VM.GetSVal(St, Ex).isUndef(); }
  };

public:
  UndefBranch()
    : BuiltinBug("uninitialized value",
                 "Branch condition evaluates to an uninitialized value.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::undef_branch_iterator I=Eng.undef_branches_begin(),
         E=Eng.undef_branches_end(); I!=E; ++I) {

      // What's going on here: we want to highlight the subexpression of the
      // condition that is the most likely source of the "uninitialized
      // branch condition."  We do a recursive walk of the condition's
      // subexpressions and roughly look for the most nested subexpression
      // that binds to Undefined.  We then highlight that expression's range.

      BlockEdge B = cast<BlockEdge>((*I)->getLocation());
      Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition());
      assert (Ex && "Block must have a terminator.");

      // Get the predecessor node and check if is a PostStmt with the Stmt
      // being the terminator condition.  We want to inspect the state
      // of that node instead because it will contain main information about
      // the subexpressions.

      assert (!(*I)->pred_empty());

      // Note: any predecessor will do.  They should have identical state,
      // since all the BlockEdge did was act as an error sink since the value
      // had to already be undefined.
      ExplodedNode<GRState> *N = *(*I)->pred_begin();
      ProgramPoint P = N->getLocation();

      const GRState* St = (*I)->getState();

      if (PostStmt* PS = dyn_cast<PostStmt>(&P))
        if (PS->getStmt() == Ex)
          St = N->getState();

      FindUndefExpr FindIt(Eng.getStateManager(), St);
      Ex = FindIt.FindExpr(Ex);

      RangedBugReport R(*this, *I);
      R.addRange(Ex->getSourceRange());

      BR.EmitWarning(R);
    }
  }
};

//===----------------------------------------------------------------------===//
// __attribute__(nonnull) checking

class VISIBILITY_HIDDEN CheckAttrNonNull : public GRSimpleAPICheck {
  SimpleBugType BT;
  std::list<RangedBugReport> Reports;

public:
  CheckAttrNonNull() :
  BT("'nonnull' argument passed null", "API",
     "Null pointer passed as an argument to a 'nonnull' parameter") {}

  virtual bool Audit(ExplodedNode<GRState>* N, GRStateManager& VMgr) {
    CallExpr* CE = cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
    const GRState* state = N->getState();

    SVal X = VMgr.GetSVal(state, CE->getCallee());

    if (!isa<loc::FuncVal>(X))
      return false;

    FunctionDecl* FD = dyn_cast<FunctionDecl>(cast<loc::FuncVal>(X).getDecl());
    const NonNullAttr* Att = FD->getAttr<NonNullAttr>();

    if (!Att)
      return false;

    // Iterate through the arguments of CE and check them for null.

    unsigned idx = 0;
    bool hasError = false;

    for (CallExpr::arg_iterator I=CE->arg_begin(), E=CE->arg_end(); I!=E;
         ++I, ++idx) {

      if (!VMgr.isEqual(state, *I, 0) || !Att->isNonNull(idx))
        continue;

      RangedBugReport R(BT, N);
      R.addRange((*I)->getSourceRange());
      Reports.push_back(R);
      hasError = true;
    }

    return hasError;
  }

  virtual void EmitWarnings(BugReporter& BR) {
    for (std::list<RangedBugReport>::iterator I=Reports.begin(),
         E=Reports.end(); I!=E; ++I)
      BR.EmitWarning(*I);
  }
};
} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Check registration.

void GRExprEngine::RegisterInternalChecks() {
  Register(new NullDeref());
  Register(new UndefinedDeref());
  Register(new UndefBranch());
  Register(new DivZero());
  Register(new UndefResult());
  Register(new BadCall());
  Register(new RetStack());
  Register(new BadArg());
  Register(new BadMsgExprArg());
  Register(new BadReceiver());
  AddCheck(new CheckAttrNonNull(), Stmt::CallExprClass);
}
<commit_msg>Enhance path-sensitive return-of-stack-address check to print out the line number of a compound literal (whose address is being returned) instead of printing out the hex representation of the pointer address of the CompoundLiteralExpr.<commit_after>//=-- GRExprEngineInternalChecks.cpp - Builtin GRExprEngine Checks---*- C++ -*-=
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the BugType classes used by GRExprEngine to report
//  bugs derived from builtin checks in the path-sensitive engine.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/Compiler.h"
#include <sstream>

using namespace clang;

//===----------------------------------------------------------------------===//
// Utility functions.
//===----------------------------------------------------------------------===//

template <typename ITERATOR> inline
ExplodedNode<GRState>* GetNode(ITERATOR I) {
  return *I;
}

template <> inline
ExplodedNode<GRState>* GetNode(GRExprEngine::undef_arg_iterator I) {
  return I->first;
}

//===----------------------------------------------------------------------===//
// Bug Descriptions.
//===----------------------------------------------------------------------===//

namespace {
class VISIBILITY_HIDDEN BuiltinBug : public BugTypeCacheLocation {
  const char* name;
  const char* desc;
public:
  BuiltinBug(const char* n, const char* d = 0) : name(n), desc(d) {}
  virtual const char* getName() const { return name; }
  virtual const char* getDescription() const {
    return desc ? desc : name;
  }

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) = 0;
  virtual void EmitWarnings(BugReporter& BR) {
    EmitBuiltinWarnings(BR, cast<GRBugReporter>(BR).getEngine());
  }

  template <typename ITER>
  void Emit(BugReporter& BR, ITER I, ITER E) {
    for (; I != E; ++I) {
      BugReport R(*this, GetNode(I));
      BR.EmitWarning(R);
    }
  }

  virtual const char* getCategory() const { return "Logic Errors"; }
};

class VISIBILITY_HIDDEN NullDeref : public BuiltinBug {
public:
  NullDeref() : BuiltinBug("null dereference",
                           "Dereference of null pointer.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.null_derefs_begin(), Eng.null_derefs_end());
  }
};

class VISIBILITY_HIDDEN UndefinedDeref : public BuiltinBug {
public:
  UndefinedDeref() : BuiltinBug("uninitialized pointer dereference",
                                "Dereference of undefined value.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.undef_derefs_begin(), Eng.undef_derefs_end());
  }
};

class VISIBILITY_HIDDEN DivZero : public BuiltinBug {
public:
  DivZero() : BuiltinBug("divide-by-zero",
                         "Division by zero/undefined value.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.explicit_bad_divides_begin(), Eng.explicit_bad_divides_end());
  }
};

class VISIBILITY_HIDDEN UndefResult : public BuiltinBug {
public:
  UndefResult() : BuiltinBug("undefined result",
                             "Result of operation is undefined.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.undef_results_begin(), Eng.undef_results_end());
  }
};

class VISIBILITY_HIDDEN BadCall : public BuiltinBug {
public:
  BadCall()
  : BuiltinBug("invalid function call",
        "Called function is a NULL or undefined function pointer value.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.bad_calls_begin(), Eng.bad_calls_end());
  }
};

class VISIBILITY_HIDDEN BadArg : public BuiltinBug {
public:
  BadArg() : BuiltinBug("uninitialized argument",
    "Pass-by-value argument in function is undefined.") {}

  BadArg(const char* d) : BuiltinBug("uninitialized argument", d) {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::UndefArgsTy::iterator I = Eng.undef_arg_begin(),
         E = Eng.undef_arg_end(); I!=E; ++I) {

      // Generate a report for this bug.
      RangedBugReport report(*this, I->first);
      report.addRange(I->second->getSourceRange());

      // Emit the warning.
      BR.EmitWarning(report);
    }
  }
};

class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg {
public:
  BadMsgExprArg()
    : BadArg("Pass-by-value argument in message expression is undefined.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
         E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {

      // Generate a report for this bug.
      RangedBugReport report(*this, I->first);
      report.addRange(I->second->getSourceRange());

      // Emit the warning.
      BR.EmitWarning(report);
    }
  }
};

class VISIBILITY_HIDDEN BadReceiver : public BuiltinBug {
public:
  BadReceiver()
  : BuiltinBug("uninitialized receiver",
               "Receiver in message expression is an uninitialized value.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::UndefReceiversTy::iterator I=Eng.undef_receivers_begin(),
         End = Eng.undef_receivers_end(); I!=End; ++I) {

      // Generate a report for this bug.
      RangedBugReport report(*this, *I);

      ExplodedNode<GRState>* N = *I;
      Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
      Expr* E = cast<ObjCMessageExpr>(S)->getReceiver();
      assert (E && "Receiver cannot be NULL");
      report.addRange(E->getSourceRange());

      // Emit the warning.
      BR.EmitWarning(report);
    }
  }
};

class VISIBILITY_HIDDEN RetStack : public BuiltinBug {
public:
  RetStack() : BuiltinBug("return of stack address") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::ret_stackaddr_iterator I=Eng.ret_stackaddr_begin(),
         End = Eng.ret_stackaddr_end(); I!=End; ++I) {

      ExplodedNode<GRState>* N = *I;
      Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
      Expr* E = cast<ReturnStmt>(S)->getRetValue();
      assert (E && "Return expression cannot be NULL");

      // Get the value associated with E.
      loc::MemRegionVal V =
        cast<loc::MemRegionVal>(Eng.getStateManager().GetSVal(N->getState(),
                                                               E));

      // Generate a report for this bug.
      std::ostringstream os;
      SourceRange R;

      // Check if the region is a compound literal.
      if (const CompoundLiteralRegion* CR =
            dyn_cast<CompoundLiteralRegion>(V.getRegion())) {

        const CompoundLiteralExpr* CL = CR->getLiteralExpr();
        os << "Address of stack memory associated with a compound literal "
              "declared on line "
            << BR.getSourceManager().getLogicalLineNumber(CL->getLocStart())
            << " returned.";

        R = CL->getSourceRange();
      }
      else {
        os << "Address of stack memory associated with local variable '"
           << V.getRegion()->getString() << "' returned.";
      }

      std::string s = os.str();
      RangedBugReport report(*this, N, s.c_str());
      report.addRange(E->getSourceRange());
      if (R.isValid()) report.addRange(R);

      // Emit the warning.
      BR.EmitWarning(report);
    }
  }
};

class VISIBILITY_HIDDEN UndefBranch : public BuiltinBug {
  struct VISIBILITY_HIDDEN FindUndefExpr {
    GRStateManager& VM;
    const GRState* St;

    FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}

    Expr* FindExpr(Expr* Ex) {
      if (!MatchesCriteria(Ex))
        return 0;

      for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end();I!=E;++I)
        if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
          Expr* E2 = FindExpr(ExI);
          if (E2) return E2;
        }

      return Ex;
    }

    bool MatchesCriteria(Expr* Ex) { return VM.GetSVal(St, Ex).isUndef(); }
  };

public:
  UndefBranch()
    : BuiltinBug("uninitialized value",
                 "Branch condition evaluates to an uninitialized value.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::undef_branch_iterator I=Eng.undef_branches_begin(),
         E=Eng.undef_branches_end(); I!=E; ++I) {

      // What's going on here: we want to highlight the subexpression of the
      // condition that is the most likely source of the "uninitialized
      // branch condition."  We do a recursive walk of the condition's
      // subexpressions and roughly look for the most nested subexpression
      // that binds to Undefined.  We then highlight that expression's range.

      BlockEdge B = cast<BlockEdge>((*I)->getLocation());
      Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition());
      assert (Ex && "Block must have a terminator.");

      // Get the predecessor node and check if is a PostStmt with the Stmt
      // being the terminator condition.  We want to inspect the state
      // of that node instead because it will contain main information about
      // the subexpressions.

      assert (!(*I)->pred_empty());

      // Note: any predecessor will do.  They should have identical state,
      // since all the BlockEdge did was act as an error sink since the value
      // had to already be undefined.
      ExplodedNode<GRState> *N = *(*I)->pred_begin();
      ProgramPoint P = N->getLocation();

      const GRState* St = (*I)->getState();

      if (PostStmt* PS = dyn_cast<PostStmt>(&P))
        if (PS->getStmt() == Ex)
          St = N->getState();

      FindUndefExpr FindIt(Eng.getStateManager(), St);
      Ex = FindIt.FindExpr(Ex);

      RangedBugReport R(*this, *I);
      R.addRange(Ex->getSourceRange());

      BR.EmitWarning(R);
    }
  }
};

//===----------------------------------------------------------------------===//
// __attribute__(nonnull) checking

class VISIBILITY_HIDDEN CheckAttrNonNull : public GRSimpleAPICheck {
  SimpleBugType BT;
  std::list<RangedBugReport> Reports;

public:
  CheckAttrNonNull() :
  BT("'nonnull' argument passed null", "API",
     "Null pointer passed as an argument to a 'nonnull' parameter") {}

  virtual bool Audit(ExplodedNode<GRState>* N, GRStateManager& VMgr) {
    CallExpr* CE = cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
    const GRState* state = N->getState();

    SVal X = VMgr.GetSVal(state, CE->getCallee());

    if (!isa<loc::FuncVal>(X))
      return false;

    FunctionDecl* FD = dyn_cast<FunctionDecl>(cast<loc::FuncVal>(X).getDecl());
    const NonNullAttr* Att = FD->getAttr<NonNullAttr>();

    if (!Att)
      return false;

    // Iterate through the arguments of CE and check them for null.

    unsigned idx = 0;
    bool hasError = false;

    for (CallExpr::arg_iterator I=CE->arg_begin(), E=CE->arg_end(); I!=E;
         ++I, ++idx) {

      if (!VMgr.isEqual(state, *I, 0) || !Att->isNonNull(idx))
        continue;

      RangedBugReport R(BT, N);
      R.addRange((*I)->getSourceRange());
      Reports.push_back(R);
      hasError = true;
    }

    return hasError;
  }

  virtual void EmitWarnings(BugReporter& BR) {
    for (std::list<RangedBugReport>::iterator I=Reports.begin(),
         E=Reports.end(); I!=E; ++I)
      BR.EmitWarning(*I);
  }
};
} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Check registration.

void GRExprEngine::RegisterInternalChecks() {
  Register(new NullDeref());
  Register(new UndefinedDeref());
  Register(new UndefBranch());
  Register(new DivZero());
  Register(new UndefResult());
  Register(new BadCall());
  Register(new RetStack());
  Register(new BadArg());
  Register(new BadMsgExprArg());
  Register(new BadReceiver());
  AddCheck(new CheckAttrNonNull(), Stmt::CallExprClass);
}
<|endoftext|>


<commit_before>// Copyright (C) 2016 Pierre-Luc Perrier <pluc-dev@the-pluc.net>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef abz_type_traits_hpp
#define abz_type_traits_hpp

/// @file type_traits.hpp
/// @brief Compile-time type information.
///
/// This file provides additional type traits.

#include "abz/compiler.hpp"
#include "abz/detail/macros.hpp"

#include <type_traits> // IWYU pragma: export

ABZ_NAMESPACE_BEGIN

////////////////////////////////
// C++14 #WG21 N3655          //
// TransformationTraits Redux //
////////////////////////////////

// 20.9.7.1, const-volatile modifications:
template <class T>
using remove_const_t = typename std::remove_const<T>::type;
template <class T>
using remove_volatile_t = typename std::remove_volatile<T>::type;
template <class T>
using remove_cv_t = typename std::remove_cv<T>::type;
template <class T>
using add_const_t = typename std::add_const<T>::type;
template <class T>
using add_volatile_t = typename std::add_volatile<T>::type;
template <class T>
using add_cv_t = typename std::add_cv<T>::type;

// 20.9.7.2, reference modifications:
template <class T>
using remove_reference_t = typename std::remove_reference<T>::type;
template <class T>
using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type;
template <class T>
using add_rvalue_reference_t = typename std::add_rvalue_reference<T>::type;

// 20.9.7.3, sign modifications:
template <class T>
using make_signed_t = typename std::make_signed<T>::type;
template <class T>
using make_unsigned_t = typename std::make_unsigned<T>::type;

// 20.9.7.4, array modifications:
template <class T>
using remove_extent_t = typename std::remove_extent<T>::type;
template <class T>
using remove_all_extents_t = typename std::remove_all_extents<T>::type;

// 20.9.7.5, pointer modifications:
template <class T>
using remove_pointer_t = typename std::remove_pointer<T>::type;
template <class T>
using add_pointer_t = typename std::add_pointer<T>::type;

// 20.9.7.6, other transformations:
template <std::size_t Len, std::size_t Align = alignof(typename std::aligned_storage<Len>::type)>
using aligned_storage_t = typename std::aligned_storage<Len, Align>::type;
template <std::size_t Len, class... Types>
using aligned_union_t = typename std::aligned_union<Len, Types...>::type;
template <class T>
using decay_t = typename std::decay<T>::type;
template <bool b, class T = void>
using enable_if_t = typename std::enable_if<b, T>::type;
template <bool b, class T, class F>
using conditional_t = typename std::conditional<b, T, F>::type;
template <class... T>
using common_type_t = typename std::common_type<T...>::type;
template <class T>
using underlying_type_t = typename std::underlying_type<T>::type;
template <class F, class... ArgTypes>
using result_of_t = typename std::result_of<F(ArgTypes...)>::type;

ABZ_NAMESPACE_END

#endif // abz_type_traits_hpp
<commit_msg>Add type traits variable templates from C++17<commit_after>// Copyright (C) 2016 Pierre-Luc Perrier <pluc-dev@the-pluc.net>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef abz_type_traits_hpp
#define abz_type_traits_hpp

/// @file type_traits.hpp
/// @brief Compile-time type information.
///
/// This file provides additional type traits.

#include "abz/compiler.hpp"
#include "abz/detail/macros.hpp"

#include <type_traits> // IWYU pragma: export

ABZ_NAMESPACE_BEGIN

////////////////////////////////
// C++14 #WG21 N3655          //
// TransformationTraits Redux //
////////////////////////////////

// 20.9.7.1, const-volatile modifications:
template <class T>
using remove_const_t = typename std::remove_const<T>::type;
template <class T>
using remove_volatile_t = typename std::remove_volatile<T>::type;
template <class T>
using remove_cv_t = typename std::remove_cv<T>::type;
template <class T>
using add_const_t = typename std::add_const<T>::type;
template <class T>
using add_volatile_t = typename std::add_volatile<T>::type;
template <class T>
using add_cv_t = typename std::add_cv<T>::type;

// 20.9.7.2, reference modifications:
template <class T>
using remove_reference_t = typename std::remove_reference<T>::type;
template <class T>
using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type;
template <class T>
using add_rvalue_reference_t = typename std::add_rvalue_reference<T>::type;

// 20.9.7.3, sign modifications:
template <class T>
using make_signed_t = typename std::make_signed<T>::type;
template <class T>
using make_unsigned_t = typename std::make_unsigned<T>::type;

// 20.9.7.4, array modifications:
template <class T>
using remove_extent_t = typename std::remove_extent<T>::type;
template <class T>
using remove_all_extents_t = typename std::remove_all_extents<T>::type;

// 20.9.7.5, pointer modifications:
template <class T>
using remove_pointer_t = typename std::remove_pointer<T>::type;
template <class T>
using add_pointer_t = typename std::add_pointer<T>::type;

// 20.9.7.6, other transformations:
template <std::size_t Len, std::size_t Align = alignof(typename std::aligned_storage<Len>::type)>
using aligned_storage_t = typename std::aligned_storage<Len, Align>::type;
template <std::size_t Len, class... Types>
using aligned_union_t = typename std::aligned_union<Len, Types...>::type;
template <class T>
using decay_t = typename std::decay<T>::type;
template <bool b, class T = void>
using enable_if_t = typename std::enable_if<b, T>::type;
template <bool b, class T, class F>
using conditional_t = typename std::conditional<b, T, F>::type;
template <class... T>
using common_type_t = typename std::common_type<T...>::type;
template <class T>
using underlying_type_t = typename std::underlying_type<T>::type;
template <class F, class... ArgTypes>
using result_of_t = typename std::result_of<F(ArgTypes...)>::type;

/////////////////////////////////////////////////////////////////////////////////
// C++17 #P0006R0                                                              //
// Adopt Type Traits Variable Templates from Library Fundamentals TS for C++17 //
/////////////////////////////////////////////////////////////////////////////////

#ifdef __cpp_variable_templates

// 20.10.4.1, primary type categories
template <class T>
constexpr bool is_void_v = std::is_void<T>::value;
template <class T>
constexpr bool is_null_pointer_v = std::is_null_pointer<T>::value;
template <class T>
constexpr bool is_integral_v = std::is_integral<T>::value;
template <class T>
constexpr bool is_floating_point_v = std::is_floating_point<T>::value;
template <class T>
constexpr bool is_array_v = std::is_array<T>::value;
template <class T>
constexpr bool is_pointer_v = std::is_pointer<T>::value;
template <class T>
constexpr bool is_lvalue_reference_v = std::is_lvalue_reference<T>::value;
template <class T>
constexpr bool is_rvalue_reference_v = std::is_rvalue_reference<T>::value;
template <class T>
constexpr bool is_member_object_pointer_v = std::is_member_object_pointer<T>::value;
template <class T>
constexpr bool is_member_function_pointer_v = std::is_member_function_pointer<T>::value;
template <class T>
constexpr bool is_enum_v = std::is_enum<T>::value;
template <class T>
constexpr bool is_union_v = std::is_union<T>::value;
template <class T>
constexpr bool is_class_v = std::is_class<T>::value;
template <class T>
constexpr bool is_function_v = std::is_function<T>::value;

// 20.10.4.2, composite type categories
template <class T>
constexpr bool is_reference_v = std::is_reference<T>::value;
template <class T>
constexpr bool is_arithmetic_v = std::is_arithmetic<T>::value;
template <class T>
constexpr bool is_fundamental_v = std::is_fundamental<T>::value;
template <class T>
constexpr bool is_object_v = std::is_object<T>::value;
template <class T>
constexpr bool is_scalar_v = std::is_scalar<T>::value;
template <class T>
constexpr bool is_compound_v = std::is_compound<T>::value;
template <class T>
constexpr bool is_member_pointer_v = std::is_member_pointer<T>::value;

// 20.10.4.3, type properties
template <class T>
constexpr bool is_const_v = std::is_const<T>::value;
template <class T>
constexpr bool is_volatile_v = std::is_volatile<T>::value;
template <class T>
constexpr bool is_trivial_v = std::is_trivial<T>::value;
template <class T>
constexpr bool is_trivially_copyable_v = std::is_trivially_copyable<T>::value;
template <class T>
constexpr bool is_standard_layout_v = std::is_standard_layout<T>::value;
template <class T>
constexpr bool is_pod_v = std::is_pod<T>::value;
template <class T>
constexpr bool is_literal_type_v = std::is_literal_type<T>::value;
template <class T>
constexpr bool is_empty_v = std::is_empty<T>::value;
template <class T>
constexpr bool is_polymorphic_v = std::is_polymorphic<T>::value;
template <class T>
constexpr bool is_abstract_v = std::is_abstract<T>::value;
template <class T>
constexpr bool is_final_v = std::is_final<T>::value;
template <class T>
constexpr bool is_signed_v = std::is_signed<T>::value;
template <class T>
constexpr bool is_unsigned_v = std::is_unsigned<T>::value;
template <class T, class... Args>
constexpr bool is_constructible_v = std::is_constructible<T, Args...>::value;
template <class T>
constexpr bool is_default_constructible_v = std::is_default_constructible<T>::value;
template <class T>
constexpr bool is_copy_constructible_v = std::is_copy_constructible<T>::value;
template <class T>
constexpr bool is_move_constructible_v = std::is_move_constructible<T>::value;
template <class T, class U>
constexpr bool is_assignable_v = std::is_assignable<T, U>::value;
template <class T>
constexpr bool is_copy_assignable_v = std::is_copy_assignable<T>::value;
template <class T>
constexpr bool is_move_assignable_v = std::is_move_assignable<T>::value;
template <class T>
constexpr bool is_destructible_v = std::is_destructible<T>::value;
template <class T, class... Args>
constexpr bool is_trivially_constructible_v = std::is_trivially_constructible<T, Args...>::value;
template <class T>
constexpr bool is_trivially_default_constructible_v
  = std::is_trivially_default_constructible<T>::value;
template <class T>
constexpr bool is_trivially_copy_constructible_v = std::is_trivially_copy_constructible<T>::value;
template <class T>
constexpr bool is_trivially_move_constructible_v = std::is_trivially_move_constructible<T>::value;
template <class T, class U>
constexpr bool is_trivially_assignable_v = std::is_trivially_assignable<T, U>::value;
template <class T>
constexpr bool is_trivially_copy_assignable_v = std::is_trivially_copy_assignable<T>::value;
template <class T>
constexpr bool is_trivially_move_assignable_v = std::is_trivially_move_assignable<T>::value;
template <class T>
constexpr bool is_trivially_destructible_v = std::is_trivially_destructible<T>::value;
template <class T, class... Args>
constexpr bool is_nothrow_constructible_v = std::is_nothrow_constructible<T, Args...>::value;
template <class T>
constexpr bool is_nothrow_default_constructible_v = std::is_nothrow_default_constructible<T>::value;
template <class T>
constexpr bool is_nothrow_copy_constructible_v = std::is_nothrow_copy_constructible<T>::value;
template <class T>
constexpr bool is_nothrow_move_constructible_v = std::is_nothrow_move_constructible<T>::value;
template <class T, class U>
constexpr bool is_nothrow_assignable_v = std::is_nothrow_assignable<T, U>::value;
template <class T>
constexpr bool is_nothrow_copy_assignable_v = std::is_nothrow_copy_assignable<T>::value;
template <class T>
constexpr bool is_nothrow_move_assignable_v = std::is_nothrow_move_assignable<T>::value;
template <class T>
constexpr bool is_nothrow_destructible_v = std::is_nothrow_destructible<T>::value;
template <class T>
constexpr bool has_virtual_destructor_v = std::has_virtual_destructor<T>::value;

// See 20.10.5, type property queries
template <class T>
constexpr std::size_t alignment_of_v = std::alignment_of<T>::value;
template <class T>
constexpr std::size_t rank_v = std::rank<T>::value;
template <class T, unsigned I = 0>
constexpr std::size_t extent_v = std::extent<T, I>::value;

// See 20.10.6, type relations
template <class T, class U>
constexpr bool is_same_v = std::is_same<T, U>::value;
template <class Base, class Derived>
constexpr bool is_base_of_v = std::is_base_of<Base, Derived>::value;
template <class From, class To>
constexpr bool is_convertible_v = std::is_convertible<From, To>::value;

#endif // __cpp_variable_templates

ABZ_NAMESPACE_END

#endif // abz_type_traits_hpp
<|endoftext|>


<commit_before>#ifndef TOML11_TRAITS
#define TOML11_TRAITS
#include <type_traits>

namespace toml
{
namespace detail
{

template<typename T>
using unwrap_t = typename std::decay<T>::type;

struct has_iterator_impl
{
    template<typename T> static std::true_type  check(typename T::iterator*);
    template<typename T> static std::false_type check(...);
};
struct has_value_type_impl
{
    template<typename T> static std::true_type  check(typename T::value_type*);
    template<typename T> static std::false_type check(...);
};
struct has_key_type_impl
{
    template<typename T> static std::true_type  check(typename T::key_type*);
    template<typename T> static std::false_type check(...);
};
struct has_mapped_type_impl
{
    template<typename T> static std::true_type  check(typename T::mapped_type*);
    template<typename T> static std::false_type check(...);
};
struct has_resize_method_impl
{
    constexpr static std::size_t dummy=0;
    template<typename T> static std::true_type  check(decltype(std::declval<T>().resize(dummy))*);
    template<typename T> static std::false_type check(...);
};

/// Intel C++ compiler can not use decltype in parent class declaration, here
/// is a hack to work around it. https://stackoverflow.com/a/23953090/4692076
#ifdef __INTEL_COMPILER
#define decltype(...) std::enable_if<true, decltype(__VA_ARGS__)>::type
#endif

template<typename T>
struct has_iterator    : decltype(has_iterator_impl::check<T>(nullptr)){};
template<typename T>
struct has_value_type  : decltype(has_value_type_impl::check<T>(nullptr)){};
template<typename T>
struct has_key_type    : decltype(has_key_type_impl::check<T>(nullptr)){};
template<typename T>
struct has_mapped_type : decltype(has_mapped_type_impl::check<T>(nullptr)){};
template<typename T>
struct has_resize_method : decltype(has_resize_method_impl::check<T>(nullptr)){};

#ifdef __INTEL_COMPILER
#undef decltype(...)
#endif

}// detail
}//toml
#endif // TOML_TRAITS
<commit_msg>add conjunction, disjunction, negation, index_seq<commit_after>#ifndef TOML11_TRAITS
#define TOML11_TRAITS
#include <type_traits>
#include <utility>
#include <tuple>

namespace toml
{
namespace detail
{

template<typename T>
using unwrap_t = typename std::decay<T>::type;

struct has_iterator_impl
{
    template<typename T> static std::true_type  check(typename T::iterator*);
    template<typename T> static std::false_type check(...);
};
struct has_value_type_impl
{
    template<typename T> static std::true_type  check(typename T::value_type*);
    template<typename T> static std::false_type check(...);
};
struct has_key_type_impl
{
    template<typename T> static std::true_type  check(typename T::key_type*);
    template<typename T> static std::false_type check(...);
};
struct has_mapped_type_impl
{
    template<typename T> static std::true_type  check(typename T::mapped_type*);
    template<typename T> static std::false_type check(...);
};
struct has_resize_method_impl
{
    constexpr static std::size_t dummy=0;
    template<typename T> static std::true_type  check(decltype(std::declval<T>().resize(dummy))*);
    template<typename T> static std::false_type check(...);
};

/// Intel C++ compiler can not use decltype in parent class declaration, here
/// is a hack to work around it. https://stackoverflow.com/a/23953090/4692076
#ifdef __INTEL_COMPILER
#define decltype(...) std::enable_if<true, decltype(__VA_ARGS__)>::type
#endif

template<typename T>
struct has_iterator    : decltype(has_iterator_impl::check<T>(nullptr)){};
template<typename T>
struct has_value_type  : decltype(has_value_type_impl::check<T>(nullptr)){};
template<typename T>
struct has_key_type    : decltype(has_key_type_impl::check<T>(nullptr)){};
template<typename T>
struct has_mapped_type : decltype(has_mapped_type_impl::check<T>(nullptr)){};
template<typename T>
struct has_resize_method : decltype(has_resize_method_impl::check<T>(nullptr)){};

#ifdef __INTEL_COMPILER
#undef decltype(...)
#endif

template<typename ...> struct conjunction : std::true_type{};
template<typename T>   struct conjunction<T> : T{};
template<typename T, typename ... Ts>
struct conjunction<T, Ts...> :
    std::conditional<static_cast<bool>(T::value), conjunction<Ts...>, T>::type
{};

template<typename ...> struct disjunction : std::false_type{};
template<typename T>   struct disjunction<T> : T {};
template<typename T, typename ... Ts>
struct disjunction<T, Ts...> :
    std::conditional<static_cast<bool>(T::value), T, disjunction<Ts...>>::type
{};

template<typename T>
struct negation : std::integral_constant<bool, !static_cast<bool>(T::value)>{};

template<typename T> struct is_std_pair : std::false_type{};
template<typename T1, typename T2>
struct is_std_pair<std::pair<T1, T2>> : std::true_type{};

template<typename T> struct is_std_tuple : std::false_type{};
template<typename ... Ts>
struct is_std_tuple<std::tuple<Ts...>> : std::true_type{};

// to use toml::get<std::tuple<T1, T2, ...>> in C++11
template<std::size_t ... Ns> struct index_sequence{};

template<typename IS, std::size_t N> struct push_back_index_sequence{};
template<std::size_t N, std::size_t ... Ns>
struct push_back_index_sequence<index_sequence<Ns...>, N>
{
    typedef index_sequence<Ns..., N> type;
};

template<std::size_t N>
struct index_sequence_maker
{
    typedef typename push_back_index_sequence<
        typename index_sequence_maker<N-1>::type, N>::type type;
};
template<>
struct index_sequence_maker<0>
{
    typedef index_sequence<0> type;
};
template<std::size_t N>
using make_index_sequence = typename index_sequence_maker<N-1>::type;

}// detail
}//toml
#endif // TOML_TRAITS
<|endoftext|>


<commit_before>#pragma once
#include <bts/db/peer.hpp>

namespace bts { namespace db {

   namespace detail { class peer_ram_impl; }

   /**
    *  @brief manages the peer database in memory, nothing
    *  persists after relaunch.
    */
   class peer_ram : public peer
   {
       public:
         peer_ram();
         virtual  ~peer_ram();

         virtual void                 store( const record& r );
         virtual record               fetch( const fc::ip::endpoint& ep )const;
         virtual void                 remove( const fc::ip::endpoint& ep );
         virtual void                 update_last_com( const fc::ip::endpoint& ep,
                                                       const fc::time_point& );

         virtual std::vector<peer::record>  get_all_peers()const;
         virtual std::vector<peer::record>  get_peers_on_channel( const network::channel_id& cid )const;
         virtual std::vector<peer::record>  get_peers_with_feature( const std::string& s )const;
       private:
         std::unique_ptr<detail::peer_ram_impl> my;
   };

   typedef std::shared_ptr<peer_ram> peer_ram_ptr;

} }
<commit_msg>removing defunct header<commit_after><|endoftext|>


<commit_before>/* Copyright 2014 Jonas Platte
 *
 * This file is part of Cyvasse Online.
 *
 * Cyvasse Online 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.
 *
 * Cyvasse Online 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License along with this program.
 * If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _CYVMATH_HEXAGON_HPP_
#define _CYVMATH_HEXAGON_HPP_

#include "coordinate.hpp"

#include <algorithm>
#include <array>
#include <functional>
#include <set>
#include <string>
#include <stdexcept>
#include <valarray>
#include <cassert>
#include <cmath>
#include <make_unique.hpp>

namespace cyvmath
{
	enum class DirectionOrthogonal
	{
		UNDEFINED,
		TOP_LEFT,
		TOP_RIGHT,
		RIGHT,
		BOTTOM_RIGHT,
		BOTTOM_LEFT,
		LEFT
	};

	enum class DirectionDiagonal
	{
		UNDEFINED,
		TOP_LEFT,
		TOP,
		TOP_RIGHT,
		BOTTOM_RIGHT,
		BOTTOM,
		BOTTOM_LEFT
	};

	/* This should rather be a namespace, but namespaces cannot have template parameters.
	   hexagon<6>::Coordinate is way better understandable than hexagon::Coordinate<6>
	   so this is implemented as a template class with a deleted constructor.
	   The template parameter l stands for the edge length of the hexagon.
	 */
	template <uint_least8_t l>
	class Hexagon
	{
		/* The smallest possible hexagon has 7 tiles and an edge lenth of 2
		   The largest possible hexagon in which the highest x and y can be represented
		   using a signed 8 bit integer has an edge length of 64 (=> width and height 127)
		 */
		static_assert(l >= 2,  "The minimum size of the hexagon edge length is 2.");
		static_assert(l <= 64, "The maximum size of the hexagon edge length is 64.");

		private:
			Hexagon() = delete;

		public:
			/// A coordinate on the hexboard (see mockup/hexboard-coordinates-internal.svg)
			class Coordinate : public cyvmath::Coordinate
			{
				private:
					int_least8_t _x;
					int_least8_t _y;

					constexpr Coordinate(int_least8_t x, int_least8_t y)
						: _x(x)
						, _y(y)
					{ }

					static constexpr bool isValid(int_least8_t x, int_least8_t y)
					{
						return x >= 0 && x < (l * 2 - 1) &&
							   y >= 0 && y < (l * 2 - 1) &&
							   (x + y) >= (l - 1) &&
							   (x + y) <= (l - 1) * 3;
					}

					bool isValid() const
					{
						return isValid(_x, _y);
					}

				public:
					virtual ~Coordinate() = default;

					int_least8_t x() const final override
					{
						return _x;
					}

					int_least8_t y() const final override
					{
						return _y;
					}

					constexpr int_least8_t z() const
					{
						return -(_x + _y);
					}

					int_least16_t dump() const final override
					{
						return (_x << 8) | _y;
					}

					/** Get the distance to another coordinate in form of the amount
						of single moves to adjacent tiles required to move there
					 */
					constexpr int_least8_t getDistance(Coordinate other) const
					{
						// Concept from http://keekerdc.com/2011/03/hexagon-grids-coordinate-systems-and-distance-calculations/
						// I have no idea why the maximum of x-, y- and z-difference
						// of the coordinates equals the distance between them...
						return std::max(abs(_x - other._x), std::max(abs(_y - other._y), abs(z() - other.z())));
					}

					/// Check if the given coordinate is reachable in one orthogonal move
					constexpr bool isOrthogonal(Coordinate other) const
					{
						return _x == other._x || _y == other._y || z() == other.z();
					}

					DirectionOrthogonal getDirectionOrthogonal(Coordinate other) const
					{
						if(*this == other) return DirectionOrthogonal::UNDEFINED;

						if(_x == other._x)
							return (_y > other._y) ? DirectionOrthogonal::BOTTOM_LEFT
							                       : DirectionOrthogonal::TOP_RIGHT;
						if(_y == other._y)
							return (_x > other._x) ? DirectionOrthogonal::LEFT
							                       : DirectionOrthogonal::RIGHT;
						if(z() == other.z())
							return (_x > other._x) ? DirectionOrthogonal::TOP_LEFT
							                       : DirectionOrthogonal::BOTTOM_RIGHT;

						return DirectionOrthogonal::UNDEFINED;
					}

					/** Like getDistance(), but return -1 if the given coordinate
						is not reachable in one orthogonal move

						An orthogonal move is a straight move in one of the six
						directions of the neighboring hex-tiles.
					 */
					constexpr int_least8_t getDistanceOrthogonal(Coordinate other) const
					{
						return isOrthogonal(other) ? getDistance(other) : -1;
					}

					/// Check if the given coordinate is reachable in one diagonal move
					constexpr bool isDiagonal(Coordinate other) const
					{
						// until C++14, this has to be implemented using
						// macros because C++11 doesn't allow constexpr
						// functions to include variable declarations
						#define dX _x - other._x
						#define dY _y - other._y
						#define dZ z() - other.z()

						return dX == dY ||
							   dY == dZ ||
							   dZ == dX;

						#undef dX
						#undef dY
						#undef dZ
					}

					DirectionDiagonal getDirectionDiagonal(Coordinate other) const
					{
						if(*this == other) return DirectionDiagonal::UNDEFINED;

						int_least8_t dX = _x  - other._x;
						int_least8_t dY = _y  - other._y;
						int_least8_t dZ = z() - other.z();

						if(dX == dY)
							return (dX > 0) ? DirectionDiagonal::BOTTOM_LEFT
							                : DirectionDiagonal::TOP_RIGHT;
						if(dY == dZ)
							return (dY > 0) ? DirectionDiagonal::BOTTOM_RIGHT
							                : DirectionDiagonal::TOP_LEFT;
						if(dZ == dX)
							return (dZ > 0) ? DirectionDiagonal::TOP
							                : DirectionDiagonal::BOTTOM;

						return DirectionDiagonal::UNDEFINED;
					}

					/** Get the diagonal distance to a coordinate, or -1 if
						the coordinate isn't reachable in one diagonal move

						A diagonal move is a straight move in one of the six
						directions of the lines between the neighboring hex-tiles.
					 */
					constexpr int_least8_t getDistanceDiagonal(Coordinate other) const
					{
						return isDiagonal(other) ? getDistance(other) / 2 : -1;
					}

					/** Get the distance to another coordinate with the same distance to
						the center Coordinate along the line of these coordinates, or -1
						if the coordinate isn't reachable while only moving on that line.

						All possible movement targets here are along a hexagonal line.
						The direct distance from this coordinate to another one on that
						line may be different than the distance along the line.
					 */
					int_least8_t getDistanceHexagonalLine(Coordinate other, Coordinate center) const
					{
						auto distance = getDistance(center);

						// Check if the given coordinate has the same distance to center as this
						if(distance != other.getDistance(center))
							return -1;

						// TODO
						/*const MovementVec steps {
								{-distance,  distance}, // top left
								{        0,  distance}, // top right
								{ distance,         0}, // right
								{ distance, -distance}, // bottom right
								{        0, -distance}, // bottom left
								{-distance,         0}  // left
							};

						auto cornerCoords = getCoordinates(steps, 1);*/

						return 0;
					}

					bool set(int_least8_t x, int_least8_t y)
					{
						if(isValid(x, y))
						{
							_x = x;
							_y = y;

							return true;
						}

						return false;
					}

					std::string toString() const
					{
						std::string ret;
						ret.append(1, char(x()) + 'A');
						ret.append(std::to_string(int(y() + 1)));

						return ret;
					}

					std::valarray<int_least8_t> toValarray() const
					{ return {_x, _y}; }

					/// @{
					/// Create a Coordinate object from an x and an y
					/// If the coordinte is invalid, return nullptr
					static constexpr std::unique_ptr<Coordinate> create(int_least8_t x, int_least8_t y)
					{
						// can't use make_unique because private constructor has to be called directly
						return isValid(x, y)
							? std::unique_ptr<Coordinate>(new Coordinate(x, y))
							: nullptr;
					}

					static std::unique_ptr<Coordinate> create(std::valarray<int_least8_t> a)
					{
						assert(a.size() == 2);
						return create(a[0], a[1]);
					}
					/// @}

					/// Create a Coordinate object from a coordinate in the public notation
					/// (see mockup/hexboard-coordinates-public.svg)
					static std::unique_ptr<Coordinate> createFromStr(const std::string& str)
					{
						// This function will currently fail on hexagons with l > 13 because there
						// would be multiple letters for the y coordinate in the public notation.
						// TODO: Decide on whether to set a maximum l of 13 or to alter this function

						if(str.length() < 2)
							return nullptr;

						/* x: When using char's for calculations, their ASCII values are used,
							  and as the uppercase letters are consecutive in the ASCII table,
							  this will result in 0 for 'A', 1 for 'B' and so on.
							  We don't accept lowercase letters.
						   y: Public coordinate notation starts with 1, we start with 0
						 */
						return std::unique_ptr<Coordinate>(
							new Coordinate(str.at(0) - 'A', std::stoi(str.substr(1)) - 1)
						);
					}
			};

			/// The edge length of the hexagon (template parameter)
			static constexpr uint_least8_t edgeLength = l;

			/// The amount of tiles that make up the hexagon
			static constexpr uint_least16_t tileCount = (l * (l - 1)) / 2 * 6 + 1;

			/// Get a container with all possible coordinates in this hexagon
			static const std::set<Coordinate>& getAllCoordinates()
			{
				static std::set<Coordinate> set;

				if(set.empty())
				{
					for(auto x = 0; x < (2 * l) - 1; x++)
					{
						auto yBegin = (x < (l - 1)) ? (l - 1 - x) : 0;
						auto yEnd   = (x < (l - 1)) ? (2 * l - 1) : (2 * l - 1) + (l - 1 - x);

						for(auto y = yBegin; y < yEnd; y++)
						{
							std::unique_ptr<Coordinate> c = Coordinate::create(x, y);
							assert(c);

							auto res = set.insert(*c);
							assert(res.second);
						}
					}
				}

				return set;
			}
	};
}

#endif // _CYVMATH_HEXAGON_HPP_
<commit_msg>Fixed missing include<commit_after>/* Copyright 2014 Jonas Platte
 *
 * This file is part of Cyvasse Online.
 *
 * Cyvasse Online 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.
 *
 * Cyvasse Online 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License along with this program.
 * If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _CYVMATH_HEXAGON_HPP_
#define _CYVMATH_HEXAGON_HPP_

#include "coordinate.hpp"

#include <algorithm>
#include <array>
#include <functional>
#include <set>
#include <string>
#include <stdexcept>
#include <valarray>
#include <cassert>
#include <cmath>
#include <cstdlib>
#include <make_unique.hpp>

namespace cyvmath
{
	enum class DirectionOrthogonal
	{
		UNDEFINED,
		TOP_LEFT,
		TOP_RIGHT,
		RIGHT,
		BOTTOM_RIGHT,
		BOTTOM_LEFT,
		LEFT
	};

	enum class DirectionDiagonal
	{
		UNDEFINED,
		TOP_LEFT,
		TOP,
		TOP_RIGHT,
		BOTTOM_RIGHT,
		BOTTOM,
		BOTTOM_LEFT
	};

	/* This should rather be a namespace, but namespaces cannot have template parameters.
	   hexagon<6>::Coordinate is way better understandable than hexagon::Coordinate<6>
	   so this is implemented as a template class with a deleted constructor.
	   The template parameter l stands for the edge length of the hexagon.
	 */
	template <uint_least8_t l>
	class Hexagon
	{
		/* The smallest possible hexagon has 7 tiles and an edge lenth of 2
		   The largest possible hexagon in which the highest x and y can be represented
		   using a signed 8 bit integer has an edge length of 64 (=> width and height 127)
		 */
		static_assert(l >= 2,  "The minimum size of the hexagon edge length is 2.");
		static_assert(l <= 64, "The maximum size of the hexagon edge length is 64.");

		private:
			Hexagon() = delete;

		public:
			/// A coordinate on the hexboard (see mockup/hexboard-coordinates-internal.svg)
			class Coordinate : public cyvmath::Coordinate
			{
				private:
					int_least8_t _x;
					int_least8_t _y;

					constexpr Coordinate(int_least8_t x, int_least8_t y)
						: _x(x)
						, _y(y)
					{ }

					static constexpr bool isValid(int_least8_t x, int_least8_t y)
					{
						return x >= 0 && x < (l * 2 - 1) &&
							   y >= 0 && y < (l * 2 - 1) &&
							   (x + y) >= (l - 1) &&
							   (x + y) <= (l - 1) * 3;
					}

					bool isValid() const
					{
						return isValid(_x, _y);
					}

				public:
					virtual ~Coordinate() = default;

					int_least8_t x() const final override
					{
						return _x;
					}

					int_least8_t y() const final override
					{
						return _y;
					}

					constexpr int_least8_t z() const
					{
						return -(_x + _y);
					}

					int_least16_t dump() const final override
					{
						return (_x << 8) | _y;
					}

					/** Get the distance to another coordinate in form of the amount
						of single moves to adjacent tiles required to move there
					 */
					constexpr int_least8_t getDistance(Coordinate other) const
					{
						// Concept from http://keekerdc.com/2011/03/hexagon-grids-coordinate-systems-and-distance-calculations/
						// I have no idea why the maximum of x-, y- and z-difference
						// of the coordinates equals the distance between them...
						return std::max(abs(_x - other._x), std::max(abs(_y - other._y), abs(z() - other.z())));
					}

					/// Check if the given coordinate is reachable in one orthogonal move
					constexpr bool isOrthogonal(Coordinate other) const
					{
						return _x == other._x || _y == other._y || z() == other.z();
					}

					DirectionOrthogonal getDirectionOrthogonal(Coordinate other) const
					{
						if(*this == other) return DirectionOrthogonal::UNDEFINED;

						if(_x == other._x)
							return (_y > other._y) ? DirectionOrthogonal::BOTTOM_LEFT
							                       : DirectionOrthogonal::TOP_RIGHT;
						if(_y == other._y)
							return (_x > other._x) ? DirectionOrthogonal::LEFT
							                       : DirectionOrthogonal::RIGHT;
						if(z() == other.z())
							return (_x > other._x) ? DirectionOrthogonal::TOP_LEFT
							                       : DirectionOrthogonal::BOTTOM_RIGHT;

						return DirectionOrthogonal::UNDEFINED;
					}

					/** Like getDistance(), but return -1 if the given coordinate
						is not reachable in one orthogonal move

						An orthogonal move is a straight move in one of the six
						directions of the neighboring hex-tiles.
					 */
					constexpr int_least8_t getDistanceOrthogonal(Coordinate other) const
					{
						return isOrthogonal(other) ? getDistance(other) : -1;
					}

					/// Check if the given coordinate is reachable in one diagonal move
					constexpr bool isDiagonal(Coordinate other) const
					{
						// until C++14, this has to be implemented using
						// macros because C++11 doesn't allow constexpr
						// functions to include variable declarations
						#define dX _x - other._x
						#define dY _y - other._y
						#define dZ z() - other.z()

						return dX == dY ||
							   dY == dZ ||
							   dZ == dX;

						#undef dX
						#undef dY
						#undef dZ
					}

					DirectionDiagonal getDirectionDiagonal(Coordinate other) const
					{
						if(*this == other) return DirectionDiagonal::UNDEFINED;

						int_least8_t dX = _x  - other._x;
						int_least8_t dY = _y  - other._y;
						int_least8_t dZ = z() - other.z();

						if(dX == dY)
							return (dX > 0) ? DirectionDiagonal::BOTTOM_LEFT
							                : DirectionDiagonal::TOP_RIGHT;
						if(dY == dZ)
							return (dY > 0) ? DirectionDiagonal::BOTTOM_RIGHT
							                : DirectionDiagonal::TOP_LEFT;
						if(dZ == dX)
							return (dZ > 0) ? DirectionDiagonal::TOP
							                : DirectionDiagonal::BOTTOM;

						return DirectionDiagonal::UNDEFINED;
					}

					/** Get the diagonal distance to a coordinate, or -1 if
						the coordinate isn't reachable in one diagonal move

						A diagonal move is a straight move in one of the six
						directions of the lines between the neighboring hex-tiles.
					 */
					constexpr int_least8_t getDistanceDiagonal(Coordinate other) const
					{
						return isDiagonal(other) ? getDistance(other) / 2 : -1;
					}

					/** Get the distance to another coordinate with the same distance to
						the center Coordinate along the line of these coordinates, or -1
						if the coordinate isn't reachable while only moving on that line.

						All possible movement targets here are along a hexagonal line.
						The direct distance from this coordinate to another one on that
						line may be different than the distance along the line.
					 */
					int_least8_t getDistanceHexagonalLine(Coordinate other, Coordinate center) const
					{
						auto distance = getDistance(center);

						// Check if the given coordinate has the same distance to center as this
						if(distance != other.getDistance(center))
							return -1;

						// TODO
						/*const MovementVec steps {
								{-distance,  distance}, // top left
								{        0,  distance}, // top right
								{ distance,         0}, // right
								{ distance, -distance}, // bottom right
								{        0, -distance}, // bottom left
								{-distance,         0}  // left
							};

						auto cornerCoords = getCoordinates(steps, 1);*/

						return 0;
					}

					bool set(int_least8_t x, int_least8_t y)
					{
						if(isValid(x, y))
						{
							_x = x;
							_y = y;

							return true;
						}

						return false;
					}

					std::string toString() const
					{
						std::string ret;
						ret.append(1, char(x()) + 'A');
						ret.append(std::to_string(int(y() + 1)));

						return ret;
					}

					std::valarray<int_least8_t> toValarray() const
					{ return {_x, _y}; }

					/// @{
					/// Create a Coordinate object from an x and an y
					/// If the coordinte is invalid, return nullptr
					static constexpr std::unique_ptr<Coordinate> create(int_least8_t x, int_least8_t y)
					{
						// can't use make_unique because private constructor has to be called directly
						return isValid(x, y)
							? std::unique_ptr<Coordinate>(new Coordinate(x, y))
							: nullptr;
					}

					static std::unique_ptr<Coordinate> create(std::valarray<int_least8_t> a)
					{
						assert(a.size() == 2);
						return create(a[0], a[1]);
					}
					/// @}

					/// Create a Coordinate object from a coordinate in the public notation
					/// (see mockup/hexboard-coordinates-public.svg)
					static std::unique_ptr<Coordinate> createFromStr(const std::string& str)
					{
						// This function will currently fail on hexagons with l > 13 because there
						// would be multiple letters for the y coordinate in the public notation.
						// TODO: Decide on whether to set a maximum l of 13 or to alter this function

						if(str.length() < 2)
							return nullptr;

						/* x: When using char's for calculations, their ASCII values are used,
							  and as the uppercase letters are consecutive in the ASCII table,
							  this will result in 0 for 'A', 1 for 'B' and so on.
							  We don't accept lowercase letters.
						   y: Public coordinate notation starts with 1, we start with 0
						 */
						return std::unique_ptr<Coordinate>(
							new Coordinate(str.at(0) - 'A', std::stoi(str.substr(1)) - 1)
						);
					}
			};

			/// The edge length of the hexagon (template parameter)
			static constexpr uint_least8_t edgeLength = l;

			/// The amount of tiles that make up the hexagon
			static constexpr uint_least16_t tileCount = (l * (l - 1)) / 2 * 6 + 1;

			/// Get a container with all possible coordinates in this hexagon
			static const std::set<Coordinate>& getAllCoordinates()
			{
				static std::set<Coordinate> set;

				if(set.empty())
				{
					for(auto x = 0; x < (2 * l) - 1; x++)
					{
						auto yBegin = (x < (l - 1)) ? (l - 1 - x) : 0;
						auto yEnd   = (x < (l - 1)) ? (2 * l - 1) : (2 * l - 1) + (l - 1 - x);

						for(auto y = yBegin; y < yEnd; y++)
						{
							std::unique_ptr<Coordinate> c = Coordinate::create(x, y);
							assert(c);

							auto res = set.insert(*c);
							assert(res.second);
						}
					}
				}

				return set;
			}
	};
}

#endif // _CYVMATH_HEXAGON_HPP_
<|endoftext|>


<commit_before>#ifndef GCN_ALLEGRO_HPP
#define GCN_ALLEGRO_HPP

#include <guichan/allegro/allegrographics.hpp>
#include <guichan/allegro/allegroimage.hpp>
#include <guichan/allegro/allegroinput.hpp>

#endif // end GCN_ALLEGRO_HPP
<commit_msg>Commented out allegroinput.hpp<commit_after>#ifndef GCN_ALLEGRO_HPP
#define GCN_ALLEGRO_HPP

#include <guichan/allegro/allegrographics.hpp>
#include <guichan/allegro/allegroimageloader.hpp>
//#include <guichan/allegro/allegroinput.hpp>

#endif // end GCN_ALLEGRO_HPP
<|endoftext|>


<commit_before>//
//  inpal_algorithm.hpp
//  Inverse Palindrome Library
//
//  Created by Bryan Triana
//  Copyright © 2016 Inverse Palindrome. All rights reserved.
//

#ifndef inpal_algorithm_hpp
#define inpal_algorithm_hpp

#include <cstdlib>
#include <string>

namespace inpal
{
    namespace algorithm
    {
        std::size_t gcd(std::size_t a, std::size_t b);
        std::size_t lcm(std::size_t a, std::size_t b);
        std::size_t modulo(std::size_t a, std::size_t b, std::size_t c);
        std::size_t mulmod(std::size_t a, std::size_t b, std::size_t c);
        std::size_t pollard_rho(std::size_t num);
        bool palindrome_test(std::size_t num);
    }
}

#endif /* inpal_algorithm_hpp */
<commit_msg>Delete inpal_algorithm.hpp<commit_after><|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_GEOMETRY_HPP
#define MAPNIK_GEOMETRY_HPP

// mapnik
#include <mapnik/vertex_vector.hpp>
#include <mapnik/geom_util.hpp>

// boost
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/ptr_container/ptr_vector.hpp>

namespace mapnik {

enum eGeomType {
    Point = 1,
    LineString = 2,
    Polygon = 3
};

template <typename T, template <typename> class Container=vertex_vector>
class geometry : private::noncopyable
{
public:
    typedef T coord_type;
    typedef Container<coord_type> container_type;
    typedef typename container_type::value_type value_type;

private:
    container_type cont_;
    eGeomType type_;
    mutable unsigned itr_;
public:

    explicit geometry(eGeomType type)
        : type_(type),
          itr_(0)
    {}

    eGeomType type() const
    {
        return type_;
    }

    container_type const& data() const
    {
        return cont_;
    }

    box2d<double> envelope() const
    {
        box2d<double> result;
        double x(0);
        double y(0);
        rewind(0);
        for (unsigned i=0;i<num_points();++i)
        {
            vertex(&x,&y);
            if (i==0)
            {
                result.init(x,y,x,y);
            }
            else
            {
                result.expand_to_include(x,y);
            }
        }
        return result;
    }

    void label_interior_position(double *x, double *y) const
    {
        // start with the default label position
        label_position(x,y);
        unsigned size = cont_.size();
        // if we are not a polygon, or the default is within the polygon we are done
        if (size < 3 || hit_test(*x,*y,0))
            return;

        // otherwise we find a horizontal line across the polygon and then return the
        // center of the widest intersection between the polygon and the line.

        std::vector<double> intersections; // only need to store the X as we know the y

        double x0=0;
        double y0=0;
        rewind(0);
        unsigned command = vertex(&x0, &y0);
        double x1,y1;
        while (SEG_END != (command=vertex(&x1, &y1)))
        {
            if (command != SEG_MOVETO)
            {
                // if the segments overlap
                if (y0==y1)
                {
                    if (y0==*y)
                    {
                        double xi = (x0+x1)/2.0;
                        intersections.push_back(xi);
                    }
                }
                // if the path segment crosses the bisector
                else if ((y0 <= *y && y1 >= *y) ||
                        (y0 >= *y && y1 <= *y))
                {
                    // then calculate the intersection
                    double xi = x0;
                    if (x0 != x1)
                    {
                        double m = (y1-y0)/(x1-x0);
                        double c = y0 - m*x0;
                        xi = (*y-c)/m;
                    }

                    intersections.push_back(xi);
                }
            }
            x0 = x1;
            y0 = y1;
        }
        // no intersections we just return the default
        if (intersections.empty())
            return;
        x0=intersections[0];
        double max_width = 0;
        for (unsigned ii = 1; ii < intersections.size(); ++ii)
        {
            double x1=intersections[ii];
            double xc=(x0+x1)/2.0;
            double width = fabs(x1-x0);
            if (width > max_width && hit_test(xc,*y,0))
            {
                *x=xc;
                max_width = width;
            }
        }
    }

    /* center of gravity centroid
      - best visually but does not work with multipolygons
    */
    void label_position(double *x, double *y) const
    {
        if (type_ == LineString)
        {
            middle_point(x,y);
            return;
        }

        unsigned size = cont_.size();
        if (size < 3)
        {
            cont_.get_vertex(0,x,y);
            return;
        }

        double ai;
        double atmp = 0;
        double xtmp = 0;
        double ytmp = 0;
        double x0 =0;
        double y0 =0;
        double x1 =0;
        double y1 =0;
        double ox =0;
        double oy =0;

        unsigned i;

        // Use first point as origin to improve numerical accuracy
        cont_.get_vertex(0,&ox,&oy);

        for (i = 0; i < size-1; i++)
        {
            cont_.get_vertex(i,&x0,&y0);
            cont_.get_vertex(i+1,&x1,&y1);

            x0 -= ox; y0 -= oy;
            x1 -= ox; y1 -= oy;

            ai = x0 * y1 - x1 * y0;
            atmp += ai;
            xtmp += (x1 + x0) * ai;
            ytmp += (y1 + y0) * ai;
        }
        if (atmp != 0)
        {
            *x = (xtmp/(3*atmp)) + ox;
            *y = (ytmp/(3*atmp)) + oy;
            return;
        }
        *x=x0;
        *y=y0;
    }

    /* center of bounding box centroid */
    void label_position2(double *x, double *y) const
    {

        box2d<double> box = envelope();
        *x = box.center().x;
        *y = box.center().y;
    }

    /* summarized distance centroid */
    void label_position3(double *x, double *y) const
    {
        if (type_ == LineString)
        {
            middle_point(x,y);
            return;
        }

        unsigned i = 0;
        double l = 0.0;
        double tl = 0.0;
        double cx = 0.0;
        double cy = 0.0;
        double x0 = 0.0;
        double y0 = 0.0;
        double x1 = 0.0;
        double y1 = 0.0;
        unsigned size = cont_.size();
        for (i = 0; i < size-1; i++)
        {
            cont_.get_vertex(i,&x0,&y0);
            cont_.get_vertex(i+1,&x1,&y1);
            l = distance(x0,y0,x1,y1);
            cx += l * (x1 + x0)/2;
            cy += l * (y1 + y0)/2;
            tl += l;
        }
        *x = cx / tl;
        *y = cy / tl;
    }

    void middle_point(double *x, double *y) const
    {
        // calculate mid point on path
        double x0=0;
        double y0=0;
        double x1=0;
        double y1=0;

        unsigned size = cont_.size();
        if (size == 1)
        {
            cont_.get_vertex(0,x,y);
        }
        else if (size == 2)
        {
            cont_.get_vertex(0,&x0,&y0);
            cont_.get_vertex(1,&x1,&y1);
            *x = 0.5 * (x1 + x0);
            *y = 0.5 * (y1 + y0);
        }
        else
        {
            double len=0.0;
            for (unsigned pos = 1; pos < size; ++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                len += std::sqrt(dx * dx + dy * dy);
            }
            double midlen = 0.5 * len;
            double dist = 0.0;
            for (unsigned pos = 1; pos < size;++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                double seg_len = std::sqrt(dx * dx + dy * dy);
                if (( dist + seg_len) >= midlen)
                {
                    double r = (midlen - dist)/seg_len;
                    *x = x0 + (x1 - x0) * r;
                    *y = y0 + (y1 - y0) * r;
                    break;
                }
                dist += seg_len;
            }
        }
    }

    void push_vertex(coord_type x, coord_type y, CommandType c)
    {
        cont_.push_back(x,y,c);
    }

    void line_to(coord_type x,coord_type y)
    {
        push_vertex(x,y,SEG_LINETO);
    }

    void move_to(coord_type x,coord_type y)
    {
        push_vertex(x,y,SEG_MOVETO);
    }

    unsigned num_points() const
    {
        return cont_.size();
    }

    unsigned vertex(double* x, double* y) const
    {
        return cont_.get_vertex(itr_++,x,y);
    }

    unsigned get_vertex(unsigned pos, double* x, double* y) const
    {
        return cont_.get_vertex(pos, x, y);
    }

    void rewind(unsigned ) const
    {
        itr_=0;
    }

    bool hit_test(coord_type x, coord_type y, double tol) const
    {
        if (cont_.size() == 1) {
            // Handle points
            double x0, y0;
            cont_.get_vertex(0, &x0, &y0);
            return distance(x, y, x0, y0) <= fabs(tol);
        } else if (cont_.size() > 1) {
            bool inside=false;
            double x0=0;
            double y0=0;
            rewind(0);
            vertex(&x0, &y0);

            unsigned command;
            double x1,y1;
            while (SEG_END != (command=vertex(&x1, &y1)))
            {
                if (command == SEG_MOVETO)
                {
                    x0 = x1;
                    y0 = y1;
                    continue;
                }
                if ((((y1 <= y) && (y < y0)) ||
                     ((y0 <= y) && (y < y1))) &&
                    ( x < (x0 - x1) * (y - y1)/ (y0 - y1) + x1))
                    inside=!inside;
                x0=x1;
                y0=y1;
            }
            return inside;
        }
        return false;
    }

    void set_capacity(size_t size)
    {
        cont_.set_capacity(size);
    }
};

typedef geometry<double,vertex_vector> geometry_type;
typedef boost::shared_ptr<geometry_type> geometry_ptr;
typedef boost::ptr_vector<geometry_type> geometry_containter;

}

#endif // MAPNIK_GEOMETRY_HPP
<commit_msg>fix missing qualifier<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_GEOMETRY_HPP
#define MAPNIK_GEOMETRY_HPP

// mapnik
#include <mapnik/vertex_vector.hpp>
#include <mapnik/geom_util.hpp>

// boost
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/ptr_container/ptr_vector.hpp>

namespace mapnik {

enum eGeomType {
    Point = 1,
    LineString = 2,
    Polygon = 3
};

template <typename T, template <typename> class Container=vertex_vector>
class geometry : private::boost::noncopyable
{
public:
    typedef T coord_type;
    typedef Container<coord_type> container_type;
    typedef typename container_type::value_type value_type;
private:
    container_type cont_;
    eGeomType type_;
    mutable unsigned itr_;
public:

    explicit geometry(eGeomType type)
        : type_(type),
          itr_(0)
    {}

    eGeomType type() const
    {
        return type_;
    }

    container_type const& data() const
    {
        return cont_;
    }

    box2d<double> envelope() const
    {
        box2d<double> result;
        double x(0);
        double y(0);
        rewind(0);
        for (unsigned i=0;i<num_points();++i)
        {
            vertex(&x,&y);
            if (i==0)
            {
                result.init(x,y,x,y);
            }
            else
            {
                result.expand_to_include(x,y);
            }
        }
        return result;
    }

    void label_interior_position(double *x, double *y) const
    {
        // start with the default label position
        label_position(x,y);
        unsigned size = cont_.size();
        // if we are not a polygon, or the default is within the polygon we are done
        if (size < 3 || hit_test(*x,*y,0))
            return;

        // otherwise we find a horizontal line across the polygon and then return the
        // center of the widest intersection between the polygon and the line.

        std::vector<double> intersections; // only need to store the X as we know the y

        double x0=0;
        double y0=0;
        rewind(0);
        unsigned command = vertex(&x0, &y0);
        double x1,y1;
        while (SEG_END != (command=vertex(&x1, &y1)))
        {
            if (command != SEG_MOVETO)
            {
                // if the segments overlap
                if (y0==y1)
                {
                    if (y0==*y)
                    {
                        double xi = (x0+x1)/2.0;
                        intersections.push_back(xi);
                    }
                }
                // if the path segment crosses the bisector
                else if ((y0 <= *y && y1 >= *y) ||
                        (y0 >= *y && y1 <= *y))
                {
                    // then calculate the intersection
                    double xi = x0;
                    if (x0 != x1)
                    {
                        double m = (y1-y0)/(x1-x0);
                        double c = y0 - m*x0;
                        xi = (*y-c)/m;
                    }

                    intersections.push_back(xi);
                }
            }
            x0 = x1;
            y0 = y1;
        }
        // no intersections we just return the default
        if (intersections.empty())
            return;
        x0=intersections[0];
        double max_width = 0;
        for (unsigned ii = 1; ii < intersections.size(); ++ii)
        {
            double x1=intersections[ii];
            double xc=(x0+x1)/2.0;
            double width = fabs(x1-x0);
            if (width > max_width && hit_test(xc,*y,0))
            {
                *x=xc;
                max_width = width;
            }
        }
    }

    /* center of gravity centroid
      - best visually but does not work with multipolygons
    */
    void label_position(double *x, double *y) const
    {
        if (type_ == LineString)
        {
            middle_point(x,y);
            return;
        }

        unsigned size = cont_.size();
        if (size < 3)
        {
            cont_.get_vertex(0,x,y);
            return;
        }

        double ai;
        double atmp = 0;
        double xtmp = 0;
        double ytmp = 0;
        double x0 =0;
        double y0 =0;
        double x1 =0;
        double y1 =0;
        double ox =0;
        double oy =0;

        unsigned i;

        // Use first point as origin to improve numerical accuracy
        cont_.get_vertex(0,&ox,&oy);

        for (i = 0; i < size-1; i++)
        {
            cont_.get_vertex(i,&x0,&y0);
            cont_.get_vertex(i+1,&x1,&y1);

            x0 -= ox; y0 -= oy;
            x1 -= ox; y1 -= oy;

            ai = x0 * y1 - x1 * y0;
            atmp += ai;
            xtmp += (x1 + x0) * ai;
            ytmp += (y1 + y0) * ai;
        }
        if (atmp != 0)
        {
            *x = (xtmp/(3*atmp)) + ox;
            *y = (ytmp/(3*atmp)) + oy;
            return;
        }
        *x=x0;
        *y=y0;
    }

    /* center of bounding box centroid */
    void label_position2(double *x, double *y) const
    {

        box2d<double> box = envelope();
        *x = box.center().x;
        *y = box.center().y;
    }

    /* summarized distance centroid */
    void label_position3(double *x, double *y) const
    {
        if (type_ == LineString)
        {
            middle_point(x,y);
            return;
        }

        unsigned i = 0;
        double l = 0.0;
        double tl = 0.0;
        double cx = 0.0;
        double cy = 0.0;
        double x0 = 0.0;
        double y0 = 0.0;
        double x1 = 0.0;
        double y1 = 0.0;
        unsigned size = cont_.size();
        for (i = 0; i < size-1; i++)
        {
            cont_.get_vertex(i,&x0,&y0);
            cont_.get_vertex(i+1,&x1,&y1);
            l = distance(x0,y0,x1,y1);
            cx += l * (x1 + x0)/2;
            cy += l * (y1 + y0)/2;
            tl += l;
        }
        *x = cx / tl;
        *y = cy / tl;
    }

    void middle_point(double *x, double *y) const
    {
        // calculate mid point on path
        double x0=0;
        double y0=0;
        double x1=0;
        double y1=0;

        unsigned size = cont_.size();
        if (size == 1)
        {
            cont_.get_vertex(0,x,y);
        }
        else if (size == 2)
        {
            cont_.get_vertex(0,&x0,&y0);
            cont_.get_vertex(1,&x1,&y1);
            *x = 0.5 * (x1 + x0);
            *y = 0.5 * (y1 + y0);
        }
        else
        {
            double len=0.0;
            for (unsigned pos = 1; pos < size; ++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                len += std::sqrt(dx * dx + dy * dy);
            }
            double midlen = 0.5 * len;
            double dist = 0.0;
            for (unsigned pos = 1; pos < size;++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                double seg_len = std::sqrt(dx * dx + dy * dy);
                if (( dist + seg_len) >= midlen)
                {
                    double r = (midlen - dist)/seg_len;
                    *x = x0 + (x1 - x0) * r;
                    *y = y0 + (y1 - y0) * r;
                    break;
                }
                dist += seg_len;
            }
        }
    }

    void push_vertex(coord_type x, coord_type y, CommandType c)
    {
        cont_.push_back(x,y,c);
    }

    void line_to(coord_type x,coord_type y)
    {
        push_vertex(x,y,SEG_LINETO);
    }

    void move_to(coord_type x,coord_type y)
    {
        push_vertex(x,y,SEG_MOVETO);
    }

    unsigned num_points() const
    {
        return cont_.size();
    }

    unsigned vertex(double* x, double* y) const
    {
        return cont_.get_vertex(itr_++,x,y);
    }

    unsigned get_vertex(unsigned pos, double* x, double* y) const
    {
        return cont_.get_vertex(pos, x, y);
    }

    void rewind(unsigned ) const
    {
        itr_=0;
    }

    bool hit_test(coord_type x, coord_type y, double tol) const
    {
        if (cont_.size() == 1) {
            // Handle points
            double x0, y0;
            cont_.get_vertex(0, &x0, &y0);
            return distance(x, y, x0, y0) <= fabs(tol);
        } else if (cont_.size() > 1) {
            bool inside=false;
            double x0=0;
            double y0=0;
            rewind(0);
            vertex(&x0, &y0);

            unsigned command;
            double x1,y1;
            while (SEG_END != (command=vertex(&x1, &y1)))
            {
                if (command == SEG_MOVETO)
                {
                    x0 = x1;
                    y0 = y1;
                    continue;
                }
                if ((((y1 <= y) && (y < y0)) ||
                     ((y0 <= y) && (y < y1))) &&
                    ( x < (x0 - x1) * (y - y1)/ (y0 - y1) + x1))
                    inside=!inside;
                x0=x1;
                y0=y1;
            }
            return inside;
        }
        return false;
    }

    void set_capacity(size_t size)
    {
        cont_.set_capacity(size);
    }
};

typedef geometry<double,vertex_vector> geometry_type;
typedef boost::shared_ptr<geometry_type> geometry_ptr;
typedef boost::ptr_vector<geometry_type> geometry_containter;

}

#endif // MAPNIK_GEOMETRY_HPP
<|endoftext|>