<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//------------------------------------------------------------------------------

#include "cling/Utils/AST.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclarationName.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/Lookup.h"

using namespace clang;

namespace cling {
namespace utils {
  Expr* Synthesize::CStyleCastPtrExpr(Sema* S, QualType Ty, uint64_t Ptr) {
    ASTContext& Ctx = S->getASTContext();
    if (!Ty->isPointerType())
      Ty = Ctx.getPointerType(Ty);
    TypeSourceInfo* TSI = Ctx.CreateTypeSourceInfo(Ty);
    const llvm::APInt Addr(8 * sizeof(void *), Ptr);

    Expr* Result = IntegerLiteral::Create(Ctx, Addr, Ctx.UnsignedLongTy,
                                          SourceLocation());
    Result = S->BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(),
                                         Result).take();
    assert(Result && "Cannot create CStyleCastPtrExpr");
    return Result;

  }

  static
  NestedNameSpecifier* GetPartiallyDesugaredNNS(const ASTContext& Ctx,
                                                NestedNameSpecifier* scope,
                            const llvm::SmallSet<const Type*, 4>& TypesToSkip){
    // Desugar the scope qualifier if needed.

    const Type* scope_type = scope->getAsType();
    if (scope_type) {
      // this is not a namespace, so we might need to desugar
      NestedNameSpecifier* outer_scope = scope->getPrefix();
      if (outer_scope) {
        outer_scope = GetPartiallyDesugaredNNS(Ctx, outer_scope, TypesToSkip);
      }

      QualType desugared =
        Transform::GetPartiallyDesugaredType(Ctx,
                                             QualType(scope_type,0),
                                             TypesToSkip,
                                             /*fullyQualify=*/false);
      // NOTE: Should check whether the type has changed or not.
      return NestedNameSpecifier::Create(Ctx,outer_scope,
                                         false /* template keyword wanted */,
                                         desugared.getTypePtr());
    }
    return scope;
  }

  static
  NestedNameSpecifier* CreateNestedNameSpecifier(const ASTContext& Ctx,
                                                 NamespaceDecl* cl) {

     NamespaceDecl* outer
        = llvm::dyn_cast_or_null<NamespaceDecl>(cl->getDeclContext());
     if (outer && outer->getName().size()) {
        NestedNameSpecifier* outerNNS = CreateNestedNameSpecifier(Ctx,outer);
        return NestedNameSpecifier::Create(Ctx,outerNNS,
                                           cl);
     } else {
        return NestedNameSpecifier::Create(Ctx,
                                           0, /* no starting '::'*/
                                           cl);
     }
  }

  static
  NestedNameSpecifier* CreateNestedNameSpecifier(const ASTContext& Ctx,
                                                 TagDecl *cl) {

    NamedDecl* outer = llvm::dyn_cast_or_null<NamedDecl>(cl->getDeclContext());
      if (outer && outer->getName().size()) {
        NestedNameSpecifier *outerNNS;
        if (cl->getDeclContext()->isNamespace()) {
          outerNNS = CreateNestedNameSpecifier(Ctx,
                                       llvm::dyn_cast<NamespaceDecl>(outer));
        } else {
          outerNNS = CreateNestedNameSpecifier(Ctx,
                                          llvm::dyn_cast<TagDecl>(outer));
        }
        return NestedNameSpecifier::Create(Ctx,outerNNS,
                                           false /* template keyword wanted */,
                                      Ctx.getTypeDeclType(cl).getTypePtr());
      } else {
        return NestedNameSpecifier::Create(Ctx,
                                           0, /* no starting '::'*/
                                           false /* template keyword wanted */,
                                      Ctx.getTypeDeclType(cl).getTypePtr());
     }
  }

  static bool ShouldKeepTypedef(QualType QT,
                           const llvm::SmallSet<const Type*, 4>& TypesToSkip)
  {
    // Return true, if we should keep this typedef rather than desugaring it.

    if ( 0 != TypesToSkip.count(QT.getTypePtr()) )
      return true;

    const TypedefType* typedeftype =
       llvm::dyn_cast_or_null<clang::TypedefType>(QT.getTypePtr());
    const TypedefNameDecl* decl = typedeftype ? typedeftype->getDecl() : 0;
    if (decl) {
       const NamedDecl* outer
          = llvm::dyn_cast_or_null<NamedDecl>(decl->getDeclContext());
       while ( outer && outer->getName().size() ) {
        // NOTE: Net is being cast to widely, replace by a lookup.
        if (outer->getName().compare("std") == 0) {
          return true;
        }
        outer = llvm::dyn_cast_or_null<NamedDecl>(outer->getDeclContext());
      }
    }
    return false;
  }

  QualType Transform::GetPartiallyDesugaredType(const ASTContext& Ctx,
                                                QualType QT,
                               const llvm::SmallSet<const Type*, 4>& TypesToSkip,
                                                bool fullyQualify /*=true*/){
    // If there are no constains - use the standard desugaring.
    if (!TypesToSkip.size() && !fullyQualify)
      return QT.getDesugaredType(Ctx);

    // In case of Int_t* we need to strip the pointer first, desugar and attach
    // the pointer once again.
    if (QT->isPointerType()) {
      // Get the qualifiers.
      Qualifiers quals = QT.getQualifiers();
      QT = GetPartiallyDesugaredType(Ctx, QT->getPointeeType(), TypesToSkip,
                                     fullyQualify);
      QT = Ctx.getPointerType(QT);
      // Add back the qualifiers.
      QT = Ctx.getQualifiedType(QT, quals);
      return QT;
    }

    // In case of Int_t& we need to strip the pointer first, desugar and attach
    // the pointer once again.
    if (QT->isReferenceType()) {
      // Get the qualifiers.
      bool isLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
      Qualifiers quals = QT.getQualifiers();
      QT = GetPartiallyDesugaredType(Ctx, QT->getPointeeType(), TypesToSkip,
                                     fullyQualify);
      // Add the r- or l- value reference type back to the desugared one
      if (isLValueRefTy)
        QT = Ctx.getLValueReferenceType(QT);
      else
        QT = Ctx.getRValueReferenceType(QT);
      // Add back the qualifiers.
      QT = Ctx.getQualifiedType(QT, quals);
      return QT;
    }

    // If the type is elaborated, first remove the prefix and then
    // when we are done we will as needed add back the (new) prefix.
    // for example for std::vector<int>::iterator, we work on
    // just 'iterator' (which remember which scope its from)
    // and remove the typedef to get (for example),
    //   __gnu_cxx::__normal_iterator
    // which is *not* in the std::vector<int> scope and it is
    // the __gnu__cxx part we should use as the prefix.
    // NOTE: however we problably want to add the std::vector typedefs
    // to the list of things to skip!

    NestedNameSpecifier* original_prefix = 0;
    clang::Qualifiers prefix_qualifiers;
    const ElaboratedType* etype_input
      = llvm::dyn_cast<ElaboratedType>(QT.getTypePtr());
    if (etype_input) {
      // We have to also desugar the prefix.
      fullyQualify = true;
      original_prefix = etype_input->getQualifier();
      prefix_qualifiers = QT.getLocalQualifiers();
      QT = QualType(etype_input->getNamedType().getTypePtr(),0);
    }

    while(isa<TypedefType>(QT.getTypePtr())) {
      if (!ShouldKeepTypedef(QT,TypesToSkip))
        QT = QT.getSingleStepDesugaredType(Ctx);
      else if (fullyQualify) {
        // We might have stripped the namespace/scope part,
        // se we must go on if fullyQualify is true.
        break;
      } else
        return QT;
    }

    NestedNameSpecifier* prefix = 0;
    const ElaboratedType* etype
      = llvm::dyn_cast<ElaboratedType>(QT.getTypePtr());
    if (etype) {
      // We have to also desugar the prefix.

      prefix = etype->getQualifier();
      if (original_prefix) {
        // We had a scope prefix as input, let see if it is still
        // the same as the scope of the result and if it is, then
        // we use it.
        const clang::Type *newtype = prefix->getAsType();
        if (newtype) {
          // Deal with a class
          const clang::Type *oldtype = original_prefix->getAsType();
          if (oldtype &&
              // NOTE: Should we compare the RecordDecl instead?
              oldtype->getAsCXXRecordDecl() == newtype->getAsCXXRecordDecl())
          {
            // This is the same type, use the original prefix as a starting
            // point.
            prefix = GetPartiallyDesugaredNNS(Ctx,original_prefix,TypesToSkip);
          } else {
            prefix = GetPartiallyDesugaredNNS(Ctx,prefix,TypesToSkip);
          }
        } else {
          // Deal with namespace.  This is mostly about dealing with
          // namespace aliases (i.e. keeping the one the user used).
          const NamespaceDecl *new_ns = prefix->getAsNamespace();
          if (new_ns) {
            new_ns = new_ns->getCanonicalDecl();
          }
          else if (NamespaceAliasDecl *alias = prefix->getAsNamespaceAlias())
          {
            new_ns = alias->getNamespace()->getCanonicalDecl();
          }
          if (new_ns) {
            const NamespaceDecl *old_ns = original_prefix->getAsNamespace();
            if (old_ns) {
              old_ns = old_ns->getCanonicalDecl();
            }
            else if (NamespaceAliasDecl *alias =
                     original_prefix->getAsNamespaceAlias())
            {
              old_ns = alias->getNamespace()->getCanonicalDecl();
            }
            if (old_ns == new_ns) {
              // This is the same namespace, use the original prefix
              // as a starting point.
              prefix = original_prefix;
            }
          }
        }
      }
      prefix_qualifiers.addQualifiers(QT.getLocalQualifiers());
      QT = QualType(etype->getNamedType().getTypePtr(),0);
    } else if (fullyQualify) {
      // Let's check whether this type should have been an elaborated type.
      // in which case we want to add it ... but we can't really preserve
      // the typedef in this case ...

      Decl *decl = 0;
      const TypedefType* typedeftype =
        llvm::dyn_cast_or_null<clang::TypedefType>(QT.getTypePtr());
      if (typedeftype) {
        decl = typedeftype->getDecl();
      } else {
        // There are probably other cases ...
        const TagType* tagdecltype =
           llvm::dyn_cast_or_null<clang::TagType>(QT.getTypePtr());
        if (tagdecltype) {
          decl = tagdecltype->getDecl();
        } else {
          decl = QT->getAsCXXRecordDecl();
        }
      }
      if (decl) {
        NamedDecl* outer
           = llvm::dyn_cast_or_null<NamedDecl>(decl->getDeclContext());
        if (original_prefix) {
          const clang::Type *oldtype = original_prefix->getAsType();
          if (oldtype) {
            if (oldtype->getAsCXXRecordDecl() == outer) {
              // Same type, use the original spelling
              prefix = GetPartiallyDesugaredNNS(Ctx,original_prefix,TypesToSkip);
              outer = 0; // Cancel the later creation.
            }
          } else {
            const NamespaceDecl *old_ns = original_prefix->getAsNamespace();
            if (old_ns) {
              old_ns = old_ns->getCanonicalDecl();
            }
            else if (NamespaceAliasDecl *alias =
                     original_prefix->getAsNamespaceAlias())
            {
              old_ns = alias->getNamespace()->getCanonicalDecl();
            }
            const NamespaceDecl *new_ns = llvm::dyn_cast<NamespaceDecl>(outer);
            if (new_ns) new_ns = new_ns->getCanonicalDecl();
            if (old_ns == new_ns) {
              // This is the same namespace, use the original prefix
              // as a starting point.
              prefix = original_prefix;
              outer = 0; // Cancel the later creation.
            }
          }
        } else { // if (!original_prefix)
           // move the qualifiers on the outer type (avoid 'std::const string'!)
           prefix_qualifiers = QT.getLocalQualifiers();
           QT.setLocalFastQualifiers(0);
        }
        if (outer && outer->getName ().size()) {
          if (decl->getDeclContext()->isNamespace()) {
            prefix = CreateNestedNameSpecifier(Ctx,
                                          llvm::dyn_cast<NamespaceDecl>(outer));
          } else {
            prefix = CreateNestedNameSpecifier(Ctx,
                                          llvm::dyn_cast<TagDecl>(outer));
          }
        }
      }
    }

    // In case of template specializations iterate over the arguments and
    // desugar them as well.
    if(const TemplateSpecializationType* TST
       = dyn_cast<const TemplateSpecializationType>(QT.getTypePtr())) {

      bool mightHaveChanged = false;
      llvm::SmallVector<TemplateArgument, 4> desArgs;
      for(TemplateSpecializationType::iterator I = TST->begin(), E = TST->end();
          I != E; ++I) {
        QualType SubTy = I->getAsType();

        if (SubTy.isNull()) {
           desArgs.push_back(*I);
           continue;
        }

        // Check if the type needs more desugaring and recurse.
        if (isa<TypedefType>(SubTy)
            || isa<TemplateSpecializationType>(SubTy)
            || isa<ElaboratedType>(SubTy)
            || fullyQualify) {
          mightHaveChanged = true;
          desArgs.push_back(TemplateArgument(GetPartiallyDesugaredType(Ctx,
                                                                       SubTy,
                                                                     TypesToSkip,
                                                                 fullyQualify)));
        } else
          desArgs.push_back(*I);
      }

      // If desugaring happened allocate new type in the AST.
      if (mightHaveChanged) {
        unsigned int qualifiers = QT.getLocalFastQualifiers();
        QT = Ctx.getTemplateSpecializationType(TST->getTemplateName(),
                                               desArgs.data(),
                                               desArgs.size(),
                                               TST->getCanonicalTypeInternal());
        QT.setLocalFastQualifiers(qualifiers);
      }
    }
    if (prefix) {
      QT = Ctx.getElaboratedType(ETK_None,prefix,QT);
      QT.setLocalFastQualifiers(prefix_qualifiers.getFastQualifiers()); // Note: Is that copying _all_ the qualifiers?
    }
    return QT;
  }

  NamespaceDecl* Lookup::Namespace(Sema* S, const char* Name,
                                   DeclContext* Within) {
    DeclarationName DName = &S->Context.Idents.get(Name);
    LookupResult R(*S, DName, SourceLocation(),
                   Sema::LookupNestedNameSpecifierName);
    if (!Within)
      S->LookupName(R, S->TUScope);
    else
      S->LookupQualifiedName(R, Within);

    if (R.empty())
      return 0;

    R.resolveKind();

    return dyn_cast<NamespaceDecl>(R.getFoundDecl());
  }

  NamedDecl* Lookup::Named(Sema* S, const char* Name, DeclContext* Within) {
    DeclarationName DName = &S->Context.Idents.get(Name);

    LookupResult R(*S, DName, SourceLocation(), Sema::LookupOrdinaryName,
                   Sema::ForRedeclaration);
    if (!Within)
      S->LookupName(R, S->TUScope);
    else
      S->LookupQualifiedName(R, Within);

    if (R.empty())
      return 0;

    R.resolveKind();

    return R.getFoundDecl();

  }
} // end namespace utils
} // end namespace cling
<commit_msg>Fix the handling of B<const Double32_t, const int><commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//------------------------------------------------------------------------------

#include "cling/Utils/AST.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclarationName.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/Lookup.h"

using namespace clang;

namespace cling {
namespace utils {
  Expr* Synthesize::CStyleCastPtrExpr(Sema* S, QualType Ty, uint64_t Ptr) {
    ASTContext& Ctx = S->getASTContext();
    if (!Ty->isPointerType())
      Ty = Ctx.getPointerType(Ty);
    TypeSourceInfo* TSI = Ctx.CreateTypeSourceInfo(Ty);
    const llvm::APInt Addr(8 * sizeof(void *), Ptr);

    Expr* Result = IntegerLiteral::Create(Ctx, Addr, Ctx.UnsignedLongTy,
                                          SourceLocation());
    Result = S->BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(),
                                         Result).take();
    assert(Result && "Cannot create CStyleCastPtrExpr");
    return Result;

  }

  static
  NestedNameSpecifier* GetPartiallyDesugaredNNS(const ASTContext& Ctx,
                                                NestedNameSpecifier* scope,
                            const llvm::SmallSet<const Type*, 4>& TypesToSkip){
    // Desugar the scope qualifier if needed.

    const Type* scope_type = scope->getAsType();
    if (scope_type) {
      // this is not a namespace, so we might need to desugar
      NestedNameSpecifier* outer_scope = scope->getPrefix();
      if (outer_scope) {
        outer_scope = GetPartiallyDesugaredNNS(Ctx, outer_scope, TypesToSkip);
      }

      QualType desugared =
        Transform::GetPartiallyDesugaredType(Ctx,
                                             QualType(scope_type,0),
                                             TypesToSkip,
                                             /*fullyQualify=*/false);
      // NOTE: Should check whether the type has changed or not.
      return NestedNameSpecifier::Create(Ctx,outer_scope,
                                         false /* template keyword wanted */,
                                         desugared.getTypePtr());
    }
    return scope;
  }

  static
  NestedNameSpecifier* CreateNestedNameSpecifier(const ASTContext& Ctx,
                                                 NamespaceDecl* cl) {

     NamespaceDecl* outer
        = llvm::dyn_cast_or_null<NamespaceDecl>(cl->getDeclContext());
     if (outer && outer->getName().size()) {
        NestedNameSpecifier* outerNNS = CreateNestedNameSpecifier(Ctx,outer);
        return NestedNameSpecifier::Create(Ctx,outerNNS,
                                           cl);
     } else {
        return NestedNameSpecifier::Create(Ctx,
                                           0, /* no starting '::'*/
                                           cl);
     }
  }

  static
  NestedNameSpecifier* CreateNestedNameSpecifier(const ASTContext& Ctx,
                                                 TagDecl *cl) {

    NamedDecl* outer = llvm::dyn_cast_or_null<NamedDecl>(cl->getDeclContext());
      if (outer && outer->getName().size()) {
        NestedNameSpecifier *outerNNS;
        if (cl->getDeclContext()->isNamespace()) {
          outerNNS = CreateNestedNameSpecifier(Ctx,
                                       llvm::dyn_cast<NamespaceDecl>(outer));
        } else {
          outerNNS = CreateNestedNameSpecifier(Ctx,
                                          llvm::dyn_cast<TagDecl>(outer));
        }
        return NestedNameSpecifier::Create(Ctx,outerNNS,
                                           false /* template keyword wanted */,
                                      Ctx.getTypeDeclType(cl).getTypePtr());
      } else {
        return NestedNameSpecifier::Create(Ctx,
                                           0, /* no starting '::'*/
                                           false /* template keyword wanted */,
                                      Ctx.getTypeDeclType(cl).getTypePtr());
     }
  }

  static bool ShouldKeepTypedef(QualType QT,
                           const llvm::SmallSet<const Type*, 4>& TypesToSkip)
  {
    // Return true, if we should keep this typedef rather than desugaring it.

    if ( 0 != TypesToSkip.count(QT.getTypePtr()) )
      return true;

    const TypedefType* typedeftype =
       llvm::dyn_cast_or_null<clang::TypedefType>(QT.getTypePtr());
    const TypedefNameDecl* decl = typedeftype ? typedeftype->getDecl() : 0;
    if (decl) {
       const NamedDecl* outer
          = llvm::dyn_cast_or_null<NamedDecl>(decl->getDeclContext());
       while ( outer && outer->getName().size() ) {
        // NOTE: Net is being cast to widely, replace by a lookup.
        if (outer->getName().compare("std") == 0) {
          return true;
        }
        outer = llvm::dyn_cast_or_null<NamedDecl>(outer->getDeclContext());
      }
    }
    return false;
  }

  QualType Transform::GetPartiallyDesugaredType(const ASTContext& Ctx,
                                                QualType QT,
                               const llvm::SmallSet<const Type*, 4>& TypesToSkip,
                                                bool fullyQualify /*=true*/){
    // If there are no constains - use the standard desugaring.
    if (!TypesToSkip.size() && !fullyQualify)
      return QT.getDesugaredType(Ctx);

    // In case of Int_t* we need to strip the pointer first, desugar and attach
    // the pointer once again.
    if (QT->isPointerType()) {
      // Get the qualifiers.
      Qualifiers quals = QT.getQualifiers();
      QT = GetPartiallyDesugaredType(Ctx, QT->getPointeeType(), TypesToSkip,
                                     fullyQualify);
      QT = Ctx.getPointerType(QT);
      // Add back the qualifiers.
      QT = Ctx.getQualifiedType(QT, quals);
      return QT;
    }

    // In case of Int_t& we need to strip the pointer first, desugar and attach
    // the pointer once again.
    if (QT->isReferenceType()) {
      // Get the qualifiers.
      bool isLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
      Qualifiers quals = QT.getQualifiers();
      QT = GetPartiallyDesugaredType(Ctx, QT->getPointeeType(), TypesToSkip,
                                     fullyQualify);
      // Add the r- or l- value reference type back to the desugared one
      if (isLValueRefTy)
        QT = Ctx.getLValueReferenceType(QT);
      else
        QT = Ctx.getRValueReferenceType(QT);
      // Add back the qualifiers.
      QT = Ctx.getQualifiedType(QT, quals);
      return QT;
    }

    // If the type is elaborated, first remove the prefix and then
    // when we are done we will as needed add back the (new) prefix.
    // for example for std::vector<int>::iterator, we work on
    // just 'iterator' (which remember which scope its from)
    // and remove the typedef to get (for example),
    //   __gnu_cxx::__normal_iterator
    // which is *not* in the std::vector<int> scope and it is
    // the __gnu__cxx part we should use as the prefix.
    // NOTE: however we problably want to add the std::vector typedefs
    // to the list of things to skip!

    NestedNameSpecifier* original_prefix = 0;
    clang::Qualifiers prefix_qualifiers;
    const ElaboratedType* etype_input
      = llvm::dyn_cast<ElaboratedType>(QT.getTypePtr());
    if (etype_input) {
      // We have to also desugar the prefix.
      fullyQualify = true;
      original_prefix = etype_input->getQualifier();
      prefix_qualifiers = QT.getLocalQualifiers();
      QT = QualType(etype_input->getNamedType().getTypePtr(),0);
    }

    while(isa<TypedefType>(QT.getTypePtr())) {
      if (!ShouldKeepTypedef(QT,TypesToSkip))
        QT = QT.getSingleStepDesugaredType(Ctx);
      else if (fullyQualify) {
        // We might have stripped the namespace/scope part,
        // se we must go on if fullyQualify is true.
        break;
      } else
        return QT;
    }

    NestedNameSpecifier* prefix = 0;
    const ElaboratedType* etype
      = llvm::dyn_cast<ElaboratedType>(QT.getTypePtr());
    if (etype) {
      // We have to also desugar the prefix.

      prefix = etype->getQualifier();
      if (original_prefix) {
        // We had a scope prefix as input, let see if it is still
        // the same as the scope of the result and if it is, then
        // we use it.
        const clang::Type *newtype = prefix->getAsType();
        if (newtype) {
          // Deal with a class
          const clang::Type *oldtype = original_prefix->getAsType();
          if (oldtype &&
              // NOTE: Should we compare the RecordDecl instead?
              oldtype->getAsCXXRecordDecl() == newtype->getAsCXXRecordDecl())
          {
            // This is the same type, use the original prefix as a starting
            // point.
            prefix = GetPartiallyDesugaredNNS(Ctx,original_prefix,TypesToSkip);
          } else {
            prefix = GetPartiallyDesugaredNNS(Ctx,prefix,TypesToSkip);
          }
        } else {
          // Deal with namespace.  This is mostly about dealing with
          // namespace aliases (i.e. keeping the one the user used).
          const NamespaceDecl *new_ns = prefix->getAsNamespace();
          if (new_ns) {
            new_ns = new_ns->getCanonicalDecl();
          }
          else if (NamespaceAliasDecl *alias = prefix->getAsNamespaceAlias())
          {
            new_ns = alias->getNamespace()->getCanonicalDecl();
          }
          if (new_ns) {
            const NamespaceDecl *old_ns = original_prefix->getAsNamespace();
            if (old_ns) {
              old_ns = old_ns->getCanonicalDecl();
            }
            else if (NamespaceAliasDecl *alias =
                     original_prefix->getAsNamespaceAlias())
            {
              old_ns = alias->getNamespace()->getCanonicalDecl();
            }
            if (old_ns == new_ns) {
              // This is the same namespace, use the original prefix
              // as a starting point.
              prefix = original_prefix;
            }
          }
        }
      }
      prefix_qualifiers.addQualifiers(QT.getLocalQualifiers());
      QT = QualType(etype->getNamedType().getTypePtr(),0);
    } else if (fullyQualify) {
      // Let's check whether this type should have been an elaborated type.
      // in which case we want to add it ... but we can't really preserve
      // the typedef in this case ...

      Decl *decl = 0;
      const TypedefType* typedeftype =
        llvm::dyn_cast_or_null<clang::TypedefType>(QT.getTypePtr());
      if (typedeftype) {
        decl = typedeftype->getDecl();
      } else {
        // There are probably other cases ...
        const TagType* tagdecltype =
           llvm::dyn_cast_or_null<clang::TagType>(QT.getTypePtr());
        if (tagdecltype) {
          decl = tagdecltype->getDecl();
        } else {
          decl = QT->getAsCXXRecordDecl();
        }
      }
      if (decl) {
        NamedDecl* outer
           = llvm::dyn_cast_or_null<NamedDecl>(decl->getDeclContext());
        if (outer && outer->getName ().size()) {
          if (original_prefix) {
            const clang::Type *oldtype = original_prefix->getAsType();
            if (oldtype) {
              if (oldtype->getAsCXXRecordDecl() == outer) {
                // Same type, use the original spelling
                prefix = GetPartiallyDesugaredNNS(Ctx,original_prefix,TypesToSkip);
                outer = 0; // Cancel the later creation.
              }
            } else {
              const NamespaceDecl *old_ns = original_prefix->getAsNamespace();
              if (old_ns) {
                old_ns = old_ns->getCanonicalDecl();
              }
              else if (NamespaceAliasDecl *alias =
                       original_prefix->getAsNamespaceAlias())
              {
                old_ns = alias->getNamespace()->getCanonicalDecl();
              }
              const NamespaceDecl *new_ns = llvm::dyn_cast<NamespaceDecl>(outer);
              if (new_ns) new_ns = new_ns->getCanonicalDecl();
              if (old_ns == new_ns) {
                // This is the same namespace, use the original prefix
                // as a starting point.
                prefix = original_prefix;
                outer = 0; // Cancel the later creation.
              }
            }
          } else { // if (!original_prefix)
            // move the qualifiers on the outer type (avoid 'std::const string'!)
            prefix_qualifiers = QT.getLocalQualifiers();
            QT = QualType(QT.getTypePtr(),0);
          }
          if (outer) {
            if (decl->getDeclContext()->isNamespace()) {
              prefix = CreateNestedNameSpecifier(Ctx,
                                          llvm::dyn_cast<NamespaceDecl>(outer));
            } else {
              prefix = CreateNestedNameSpecifier(Ctx,
                                          llvm::dyn_cast<TagDecl>(outer));
            }
          }
        }
      }
    }

    // In case of template specializations iterate over the arguments and
    // desugar them as well.
    if(const TemplateSpecializationType* TST
       = dyn_cast<const TemplateSpecializationType>(QT.getTypePtr())) {

      bool mightHaveChanged = false;
      llvm::SmallVector<TemplateArgument, 4> desArgs;
      for(TemplateSpecializationType::iterator I = TST->begin(), E = TST->end();
          I != E; ++I) {
        QualType SubTy = I->getAsType();

        if (SubTy.isNull()) {
           desArgs.push_back(*I);
           continue;
        }

        // Check if the type needs more desugaring and recurse.
        if (isa<TypedefType>(SubTy)
            || isa<TemplateSpecializationType>(SubTy)
            || isa<ElaboratedType>(SubTy)
            || fullyQualify) {
          mightHaveChanged = true;
          desArgs.push_back(TemplateArgument(GetPartiallyDesugaredType(Ctx,
                                                                       SubTy,
                                                                     TypesToSkip,
                                                                 fullyQualify)));
        } else
          desArgs.push_back(*I);
      }

      // If desugaring happened allocate new type in the AST.
      if (mightHaveChanged) {
        Qualifiers qualifiers = QT.getLocalQualifiers();
        QT = Ctx.getTemplateSpecializationType(TST->getTemplateName(),
                                               desArgs.data(),
                                               desArgs.size(),
                                               TST->getCanonicalTypeInternal());
        QT = Ctx.getQualifiedType(QT, qualifiers);
      }
    }
    if (prefix) {
      QT = Ctx.getElaboratedType(ETK_None,prefix,QT);
      QT = Ctx.getQualifiedType(QT, prefix_qualifiers);
    }
    return QT;
  }

  NamespaceDecl* Lookup::Namespace(Sema* S, const char* Name,
                                   DeclContext* Within) {
    DeclarationName DName = &S->Context.Idents.get(Name);
    LookupResult R(*S, DName, SourceLocation(),
                   Sema::LookupNestedNameSpecifierName);
    if (!Within)
      S->LookupName(R, S->TUScope);
    else
      S->LookupQualifiedName(R, Within);

    if (R.empty())
      return 0;

    R.resolveKind();

    return dyn_cast<NamespaceDecl>(R.getFoundDecl());
  }

  NamedDecl* Lookup::Named(Sema* S, const char* Name, DeclContext* Within) {
    DeclarationName DName = &S->Context.Idents.get(Name);

    LookupResult R(*S, DName, SourceLocation(), Sema::LookupOrdinaryName,
                   Sema::ForRedeclaration);
    if (!Within)
      S->LookupName(R, S->TUScope);
    else
      S->LookupQualifiedName(R, Within);

    if (R.empty())
      return 0;

    R.resolveKind();

    return R.getFoundDecl();

  }
} // end namespace utils
} // end namespace cling
<|endoftext|>


<commit_before>#include <pcl/kdtree/kdtree_flann.h>
#include "CompetitionController.h"

using namespace IGVC::Sensors;
using namespace std;

namespace IGVC
{
namespace Control
{

CompetitionController::CompetitionController(IGVC::Sensors::GPS* gps,
                                            Event<pcl::PointCloud<pcl::PointXYZ> >* mapSource,
                                            WaypointReader* waypointReader,
                                            MotorDriver* driver,
                                            string fileName)
    : _hasAllData(false),
      GPS_BUFFER_SIZE(5),
      LOnNewGPSData(this),
      LOnNewIMUData(this),
      LOnNewMapFrame(this),
      _viewer("Map and Path"),
      _logFile()
{
    _gps = gps;
    if(_gps)
        _gps->onNewData += &LOnNewGPSData;
    else
        _hasAllData = true;
    _waypointReader = waypointReader;
    _waypointReader->Next();
    _currentHeading = 0;
    _driver = driver;

    (*mapSource) += &LOnNewMapFrame;

    _logFile.open(fileName.c_str());

    MaxW = 0.8;
    DeltaT = 1.5;
}

bool CompetitionController::isRunning()
{
    return true;
}

void CompetitionController::OnNewGPSData(GPSData data)
{
    std::cout << "Compcon gps" << std::endl;
    if(_gpsBuffer.size() >= GPS_BUFFER_SIZE)
    {
        _gpsBuffer.push_back(data);
        GPSData last = _gpsBuffer.back();
        _currentAvgGPS.Lat(_currentAvgGPS.Lat() - ( last.Lat() / GPS_BUFFER_SIZE ));
        _currentAvgGPS.Long(_currentAvgGPS.Long() - ( last.Long() / GPS_BUFFER_SIZE ));
        _currentAvgGPS.Heading(_currentAvgGPS.Heading() - ( last.Heading() / GPS_BUFFER_SIZE ));
        _currentAvgGPS.Speed(_currentAvgGPS.Speed() - ( last.Speed() / GPS_BUFFER_SIZE ));
        _gpsBuffer.erase(_gpsBuffer.begin());
    }
    else
    {
        _gpsBuffer.push_back(data);
    }
    _currentAvgGPS.Lat(_currentAvgGPS.Lat() + ( data.Lat() / GPS_BUFFER_SIZE ));
    _currentAvgGPS.Long(_currentAvgGPS.Long() + ( data.Long() / GPS_BUFFER_SIZE ));
    _currentAvgGPS.Heading(_currentAvgGPS.Heading() + ( data.Heading() / GPS_BUFFER_SIZE ));
    _currentAvgGPS.Speed(_currentAvgGPS.Speed() + ( data.Speed() / GPS_BUFFER_SIZE ));
    _hasAllData = true;
}

void CompetitionController::OnNewIMUData(IMURawData data)
{
    std::cout << "Compcon imu" << std::endl;
    _currentHeading = data.heading;
}

/*
void CompetitionController::OnNewMapFrame(pcl::PointCloud<pcl::PointXYZ> mapFrame)
{
    cout << mapFrame.points.size() << " points recieved." << endl;
    if(!_hasAllData)
        return;
    _viewer.removeAllPointClouds(0);
    _viewer.removeAllShapes();
    _viewer.addPointCloud(mapFrame.makeShared(), "map");
    _viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "map");
    _viewer.spin();
    std::cout << "Compcon newMap" << std::endl;
    vector< pair<double, double> > available_actions;

    using namespace std;
    cout << "Loading possible actions" << endl;

    double v = 0.4;
    for(double w = -MaxW; w <= MaxW; w += 0.5)
    {
        pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;
        kdtree.setInputCloud(mapFrame.makeShared());
        pair<double, double> end = result(w,v);
        pcl::PointXYZ searchPoint(end.first, end.second, 0);
        std::vector<int> pointIdxRadiusSearch;
        std::vector<float> pointRadiusSquaredDistance;
        if(kdtree.radiusSearch(searchPoint, 0.01, pointIdxRadiusSearch, pointRadiusSquaredDistance) == 0)
        {
            available_actions.push_back(pair<double,double>(v, w));
        }
    }

    cout << "Checking possible actions..." << endl;

    pair<double, double> minPair;
    double minDist = -1;

    for(vector< pair<double, double> >::iterator iter = available_actions.begin(); iter != available_actions.end(); iter++)
    {
        pair<double, double> action = (*iter);

        cout << "Action done" << endl;

        pair<double, double> waypointCoords;

        cout << _waypointReader->Current().Lat() << endl;

        waypointCoords.first = GPSdX(_currentAvgGPS, _waypointReader->Current());
        waypointCoords.second = GPSdY(_currentAvgGPS, _waypointReader->Current());

        cout << "loaded" << endl;

        pair<double, double> endLoc = result(action.second, action.first);

        cout << "resulted" << endl;

        double dist = distBetween(waypointCoords, endLoc);

        cout << "dist" << endl;

        if(minDist == -1 || dist < minDist)
        {
            minPair = action;
            minDist = dist;
        }
    }

    cout << "Computing velocities..." << endl;

    double Baseline = Robot::CurrentRobot().Baseline();
    double Vr = minPair.first + (Baseline/2.0)*minPair.second;
    double Vl = minPair.first - (Baseline/2.0)*minPair.second;

    cout << "Decided on Vl=" << Vl << " and Vr=" << Vr << endl;

    _driver->setVelocities(Vl, Vr);

}
*/

double CompetitionController::weighting(double delta)
{
  if (delta !=0 )
  {
    //return 1/pow(delta,2);
    return 1/delta;
  }
  else
  {
    std::cout << "input to weighting function was 0. This should not have happened" << std::endl;
    return 0;
  }
}

void CompetitionController::OnNewMapFrame(pcl::PointCloud<pcl::PointXYZ> mapFrame)
{
    //cout << mapFrame.points.size() << " points recieved." << endl;
    //Bunch of Visualization stuff
    if(!_hasAllData)
        return;
    _viewer.removeAllPointClouds(0);
    _viewer.removeAllShapes();
    _viewer.addPointCloud(mapFrame.makeShared(), "map");
    _viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "map");
    _viewer.spinOnce();
    std::cout << "Compcon newMap" << std::endl;
    vector< pair<double, double> > available_actions;

    //cout << "Loading possible actions" << endl;

    //Find Potential Routes
    double v = 0.4; //meters per second

    double wInc = 0.05; //step size between possible omegas
    int i=0; //servers as an iterator for scores so the desired index doesnt have to be rederied from w
    double deltaDeltaT=0.1;

    const int nPaths = floor((2*MaxW)/wInc);
    std::vector<double> scores;
    scores.assign(nPaths,0);

    double minDeltaT = Robot::CurrentRobot().Dist2Front()/v;

    for(double w = -MaxW; w <= MaxW; w += wInc)
    {
      for(double T = deltaDeltaT;T<=DeltaT;T+=deltaDeltaT)
      {
        pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;
        kdtree.setInputCloud(mapFrame.makeShared());
        pair<double, double> end = result(w,v,T);
        pcl::PointXYZ searchPoint(end.first, end.second, 0);
        std::vector<int> pointIdxRadiusSearch;
        std::vector<float> pointRadiusSquaredDistance;
        if(kdtree.radiusSearch(searchPoint, 0.1, pointIdxRadiusSearch, pointRadiusSquaredDistance) == 0)
        {
        }
        else
        {
          cout << "object found!" << endl;
          scores[i]+=weighting(T);
        }
      }
      i++;
    }

    int minArg = 0;
    int secondMinArg = 0;
    int min = 50000;
    int currentScore;
    for(int j=0;j<nPaths;j++)
    {
      currentScore = scores[j];
      if (currentScore<min)
      {
        secondMinArg = minArg;
        minArg = j;
        min = currentScore;
      }
    }

    cout << "minArg is" << minArg<< endl;
    cout << "This means the robot wants to travel at" << -MaxW + wInc*minArg << endl;
    cout << "largest distractor is " << MaxW + wInc*secondMinArg << endl;
    _logFile << -MaxW + wInc*minArg << endl;
    //available_actions.push_back(pair<double,double>(v, w));

    pair<double, double> minPair;
    minPair.first = v;
    minPair.second = -MaxW+wInc*minArg;

    cout << "Computing velocities..." << endl;

    double Baseline = Robot::CurrentRobot().Baseline();
    double Vr = minPair.first + (Baseline/2.0)*minPair.second;
    double Vl = minPair.first - (Baseline/2.0)*minPair.second;

    cout << "Decided on Vl=" << Vl << " and Vr=" << Vr << endl;

    if(_driver)
        _driver->setVelocities(Vl, Vr);

    /*
    double minDist = -1;

    for(vector< pair<double, double> >::iterator iter = available_actions.begin(); iter != available_actions.end(); iter++)
    {
        pair<double, double> action = (*iter);

        cout << "Action done" << endl;

        pair<double, double> waypointCoords;

        cout << _waypointReader->Current().Lat() << endl;

        waypointCoords.first = GPSdX(_currentAvgGPS, _waypointReader->Current());
        waypointCoords.second = GPSdY(_currentAvgGPS, _waypointReader->Current());

        cout << "loaded" << endl;

        pair<double, double> endLoc = result(action.second, action.first);

        cout << "resulted" << endl;

        double dist = distBetween(waypointCoords, endLoc);

        cout << "dist" << endl;

        if(minDist == -1 || dist < minDist)
        {
            minPair = action;
            minDist = dist;
        }
    }

    cout << "Computing velocities..." << endl;

    double Baseline = Robot::CurrentRobot().Baseline();
    double Vr = minPair.first + (Baseline/2.0)*minPair.second;
    double Vl = minPair.first - (Baseline/2.0)*minPair.second;

    cout << "Decided on Vl=" << Vl << " and Vr=" << Vr << endl;

    _driver->setVelocities(Vl, Vr);
    */
}

double CompetitionController::headingFromAToB(GPSData A, GPSData B)
{
    double dy = B.Lat() - A.Lat();
    double dx = cos(M_PI/180.0*A.Lat())*(B.Long() - A.Long());
    return atan2(dy, dx);
}

double CompetitionController::distBetween(GPSData A, GPSData B)
{
    double dy = B.Lat() - A.Lat();
    double dx = cos(M_PI/180.0*A.Lat())*(B.Long() - A.Long());
    return sqrt(dx*dx + dy*dy);
}

double CompetitionController::distBetween(pair<double, double> A, pair<double, double> B)
{
    double dy = B.second - A.second;
    double dx = B.first - A.first;
    return sqrt(dx*dx + dy*dy);
}

double CompetitionController::GPSdX(GPSData A, GPSData B)
{
    return cos(M_PI/180.0*A.Lat())*(B.Long() - A.Long());
}

double CompetitionController::GPSdY(GPSData A, GPSData B)
{
    return B.Lat() - A.Lat();
}

pair<double, double> CompetitionController::result(double W, double V)
{
    Eigen::Vector3d endLocation;
    if(W != 0)
    {
        double R = V / W;
        double ICCx = cos(- M_PI/2.0) * R;
        double ICCy = sin(- M_PI/2.0) * R;
        using namespace Eigen;
        Matrix3d T;
        double wdt = W*DeltaT;
        T << cos(wdt), -sin(wdt), 0, sin(wdt), cos(wdt), 0, 0, 0, 1;
        Vector3d a(-ICCx, -ICCy, 0);
        Vector3d b(ICCx, ICCy, wdt);
        endLocation = T * a + b;
    }
    else
    {
        endLocation[0] = 0;
        endLocation[1] = V * DeltaT;
    }
    return pair<double, double> (endLocation[0], endLocation[1]);
}

pair<double, double> CompetitionController::result(double W, double V, double dt)
{
    Eigen::Vector3d endLocation;
    if(W != 0)
    {
        double R = V / W;
        double ICCx = cos(- M_PI/2.0) * R;
        double ICCy = sin(- M_PI/2.0) * R;
        using namespace Eigen;
        Matrix3d T;
        double wdt = W*dt;
        T << cos(wdt), -sin(wdt), 0, sin(wdt), cos(wdt), 0, 0, 0, 1;
        Vector3d a(-ICCx, -ICCy, 0);
        Vector3d b(ICCx, ICCy, wdt);
        endLocation = T * a + b;
    }
    else
    {
        endLocation[0] = 0;
        endLocation[1] = V * dt;
    }
    return pair<double, double> (endLocation[0], endLocation[1]);
}
CompetitionController::~CompetitionController()
{
    if(_gps)
        _gps->onNewData -= &LOnNewGPSData;
}

}
}
<commit_msg>Things started working.<commit_after>#include <pcl/kdtree/kdtree_flann.h>
#include "CompetitionController.h"
#include <sstream>

using namespace IGVC::Sensors;
using namespace std;

namespace IGVC
{
namespace Control
{

CompetitionController::CompetitionController(IGVC::Sensors::GPS* gps,
                                            Event<pcl::PointCloud<pcl::PointXYZ> >* mapSource,
                                            WaypointReader* waypointReader,
                                            MotorDriver* driver,
                                            string fileName)
    : _hasAllData(false),
      GPS_BUFFER_SIZE(5),
      LOnNewGPSData(this),
      LOnNewIMUData(this),
      LOnNewMapFrame(this),
      _viewer("Map and Path"),
      _logFile()
{
    _gps = gps;
    if(_gps)
        _gps->onNewData += &LOnNewGPSData;
    else
        _hasAllData = true;
    _waypointReader = waypointReader;
    _waypointReader->Next();
    _currentHeading = 0;
    _driver = driver;

    (*mapSource) += &LOnNewMapFrame;

    _logFile.open(fileName.c_str());

    MaxW = 0.8;
    DeltaT = 7;
}

bool CompetitionController::isRunning()
{
    return true;
}

void CompetitionController::OnNewGPSData(GPSData data)
{
    std::cout << "Compcon gps" << std::endl;
    if(_gpsBuffer.size() >= GPS_BUFFER_SIZE)
    {
        _gpsBuffer.push_back(data);
        GPSData last = _gpsBuffer.back();
        _currentAvgGPS.Lat(_currentAvgGPS.Lat() - ( last.Lat() / GPS_BUFFER_SIZE ));
        _currentAvgGPS.Long(_currentAvgGPS.Long() - ( last.Long() / GPS_BUFFER_SIZE ));
        _currentAvgGPS.Heading(_currentAvgGPS.Heading() - ( last.Heading() / GPS_BUFFER_SIZE ));
        _currentAvgGPS.Speed(_currentAvgGPS.Speed() - ( last.Speed() / GPS_BUFFER_SIZE ));
        _gpsBuffer.erase(_gpsBuffer.begin());
    }
    else
    {
        _gpsBuffer.push_back(data);
    }
    _currentAvgGPS.Lat(_currentAvgGPS.Lat() + ( data.Lat() / GPS_BUFFER_SIZE ));
    _currentAvgGPS.Long(_currentAvgGPS.Long() + ( data.Long() / GPS_BUFFER_SIZE ));
    _currentAvgGPS.Heading(_currentAvgGPS.Heading() + ( data.Heading() / GPS_BUFFER_SIZE ));
    _currentAvgGPS.Speed(_currentAvgGPS.Speed() + ( data.Speed() / GPS_BUFFER_SIZE ));
    _hasAllData = true;
}

void CompetitionController::OnNewIMUData(IMURawData data)
{
    std::cout << "Compcon imu" << std::endl;
    _currentHeading = data.heading;
}

/*
void CompetitionController::OnNewMapFrame(pcl::PointCloud<pcl::PointXYZ> mapFrame)
{
    cout << mapFrame.points.size() << " points recieved." << endl;
    if(!_hasAllData)
        return;
    _viewer.removeAllPointClouds(0);
    _viewer.removeAllShapes();
    _viewer.addPointCloud(mapFrame.makeShared(), "map");
    _viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "map");
    _viewer.spin();
    std::cout << "Compcon newMap" << std::endl;
    vector< pair<double, double> > available_actions;

    using namespace std;
    cout << "Loading possible actions" << endl;

    double v = 0.4;
    for(double w = -MaxW; w <= MaxW; w += 0.5)
    {
        pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;
        kdtree.setInputCloud(mapFrame.makeShared());
        pair<double, double> end = result(w,v);
        pcl::PointXYZ searchPoint(end.first, end.second, 0);
        std::vector<int> pointIdxRadiusSearch;
        std::vector<float> pointRadiusSquaredDistance;
        if(kdtree.radiusSearch(searchPoint, 0.01, pointIdxRadiusSearch, pointRadiusSquaredDistance) == 0)
        {
            available_actions.push_back(pair<double,double>(v, w));
        }
    }

    cout << "Checking possible actions..." << endl;

    pair<double, double> minPair;
    double minDist = -1;

    for(vector< pair<double, double> >::iterator iter = available_actions.begin(); iter != available_actions.end(); iter++)
    {
        pair<double, double> action = (*iter);

        cout << "Action done" << endl;

        pair<double, double> waypointCoords;

        cout << _waypointReader->Current().Lat() << endl;

        waypointCoords.first = GPSdX(_currentAvgGPS, _waypointReader->Current());
        waypointCoords.second = GPSdY(_currentAvgGPS, _waypointReader->Current());

        cout << "loaded" << endl;

        pair<double, double> endLoc = result(action.second, action.first);

        cout << "resulted" << endl;

        double dist = distBetween(waypointCoords, endLoc);

        cout << "dist" << endl;

        if(minDist == -1 || dist < minDist)
        {
            minPair = action;
            minDist = dist;
        }
    }

    cout << "Computing velocities..." << endl;

    double Baseline = Robot::CurrentRobot().Baseline();
    double Vr = minPair.first + (Baseline/2.0)*minPair.second;
    double Vl = minPair.first - (Baseline/2.0)*minPair.second;

    cout << "Decided on Vl=" << Vl << " and Vr=" << Vr << endl;

    _driver->setVelocities(Vl, Vr);

}
*/

double CompetitionController::weighting(double delta)
{
  if (delta !=0 )
  {
    //return 1/pow(delta,2);
    return 1/delta;
  }
  else
  {
    std::cout << "input to weighting function was 0. This should not have happened" << std::endl;
    return 0;
  }
}

void CompetitionController::OnNewMapFrame(pcl::PointCloud<pcl::PointXYZ> mapFrame)
{
    //cout << mapFrame.points.size() << " points recieved." << endl;
    //Bunch of Visualization stuff
    if(!_hasAllData)
        return;
    _viewer.removeAllPointClouds(0);
    _viewer.removeAllShapes();
    _viewer.addPointCloud(mapFrame.makeShared(), "map");
    _viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "map");
    _viewer.spinOnce();
    std::cout << "Compcon newMap" << std::endl;
    vector< pair<double, double> > available_actions;

    //cout << "Loading possible actions" << endl;

    //Find Potential Routes
    double v = 0.4; //meters per second

    double wInc = 0.1; //step size between possible omegas
    int i=0; //servers as an iterator for scores so the desired index doesnt have to be rederied from w
    double deltaDeltaT=0.5;

    const int nPaths = floor((2*MaxW)/wInc);
    std::vector<double> scores;
    scores.assign(nPaths,0);

    double minDeltaT = Robot::CurrentRobot().Dist2Front()/v;

    for(double w = -MaxW; w <= MaxW; w += wInc)
    {
      for(double T = deltaDeltaT;T<=DeltaT;T+=deltaDeltaT)
      {
        pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;
        kdtree.setInputCloud(mapFrame.makeShared());
        pair<double, double> end = result(w,v,T);
        /*stringstream name;
        name << "Sphere" << w << T;
        _viewer.addSphere(pcl::PointXYZ(end.first, end.second, 0), 0.1, name.str(), 0);*/
        pcl::PointXYZ searchPoint(end.first, end.second, 0);
        std::vector<int> pointIdxRadiusSearch;
        std::vector<float> pointRadiusSquaredDistance;
        if(kdtree.radiusSearch(searchPoint, 0.1, pointIdxRadiusSearch, pointRadiusSquaredDistance) == 0)
        {
        }
        else
        {
          cout << "object found!" << endl;
          scores[i]+=weighting(T);
        }
      }
      i++;
    }

    //_viewer.spin();

    int minArg = 0;
    int secondMinArg = 0;
    int min = scores[0];
    int currentScore;

    for(int j=0;j<nPaths;j++)
    {
      currentScore = scores[j];
      if (currentScore<min)
      {
        secondMinArg = minArg;
        minArg = j;
        min = currentScore;
      }
    }

    cout << "minArg is" << minArg<< endl;
    cout << "This means the robot wants to travel at" << -MaxW + wInc*minArg << endl;
    cout << "largest distractor is " << -MaxW + wInc*secondMinArg << endl;
    _logFile << -MaxW + wInc*minArg << endl;
    //available_actions.push_back(pair<double,double>(v, w));

    pair<double, double> minPair;
    minPair.first = v;
    minPair.second = -MaxW+wInc*minArg;

    cout << "Computing velocities..." << endl;

    double Baseline = Robot::CurrentRobot().Baseline();
    double Vr = minPair.first + (Baseline/2.0)*minPair.second;
    double Vl = minPair.first - (Baseline/2.0)*minPair.second;

    cout << "Decided on Vl=" << Vl << " and Vr=" << Vr << endl;

    if(_driver)
        _driver->setVelocities(Vl, Vr);

    /*
    double minDist = -1;

    for(vector< pair<double, double> >::iterator iter = available_actions.begin(); iter != available_actions.end(); iter++)
    {
        pair<double, double> action = (*iter);

        cout << "Action done" << endl;

        pair<double, double> waypointCoords;

        cout << _waypointReader->Current().Lat() << endl;

        waypointCoords.first = GPSdX(_currentAvgGPS, _waypointReader->Current());
        waypointCoords.second = GPSdY(_currentAvgGPS, _waypointReader->Current());

        cout << "loaded" << endl;

        pair<double, double> endLoc = result(action.second, action.first);

        cout << "resulted" << endl;

        double dist = distBetween(waypointCoords, endLoc);

        cout << "dist" << endl;

        if(minDist == -1 || dist < minDist)
        {
            minPair = action;
            minDist = dist;
        }
    }

    cout << "Computing velocities..." << endl;

    double Baseline = Robot::CurrentRobot().Baseline();
    double Vr = minPair.first + (Baseline/2.0)*minPair.second;
    double Vl = minPair.first - (Baseline/2.0)*minPair.second;

    cout << "Decided on Vl=" << Vl << " and Vr=" << Vr << endl;

    _driver->setVelocities(Vl, Vr);
    */
}

double CompetitionController::headingFromAToB(GPSData A, GPSData B)
{
    double dy = B.Lat() - A.Lat();
    double dx = cos(M_PI/180.0*A.Lat())*(B.Long() - A.Long());
    return atan2(dy, dx);
}

double CompetitionController::distBetween(GPSData A, GPSData B)
{
    double dy = B.Lat() - A.Lat();
    double dx = cos(M_PI/180.0*A.Lat())*(B.Long() - A.Long());
    return sqrt(dx*dx + dy*dy);
}

double CompetitionController::distBetween(pair<double, double> A, pair<double, double> B)
{
    double dy = B.second - A.second;
    double dx = B.first - A.first;
    return sqrt(dx*dx + dy*dy);
}

double CompetitionController::GPSdX(GPSData A, GPSData B)
{
    return cos(M_PI/180.0*A.Lat())*(B.Long() - A.Long());
}

double CompetitionController::GPSdY(GPSData A, GPSData B)
{
    return B.Lat() - A.Lat();
}

pair<double, double> CompetitionController::result(double W, double V)
{
    Eigen::Vector3d endLocation;
    if(W != 0)
    {
        double R = V / W;
        double ICCx = cos(- M_PI/2.0) * R;
        double ICCy = sin(- M_PI/2.0) * R;
        using namespace Eigen;
        Matrix3d T;
        double wdt = W*DeltaT;
        T << cos(wdt), -sin(wdt), 0, sin(wdt), cos(wdt), 0, 0, 0, 1;
        Vector3d a(-ICCx, -ICCy, 0);
        Vector3d b(ICCx, ICCy, wdt);
        endLocation = T * a + b;
    }
    else
    {
        endLocation[0] = 0;
        endLocation[1] = V * DeltaT;
    }
    return pair<double, double> (-endLocation[0], endLocation[1]);
}

pair<double, double> CompetitionController::result(double W, double V, double dt)
{
    Eigen::Vector3d endLocation;
    if(W != 0)
    {
        double R = V / W;
        double ICCx = cos(- M_PI/2.0) * R;
        double ICCy = sin(- M_PI/2.0) * R;
        using namespace Eigen;
        Matrix3d T;
        double wdt = W*dt;
        T << cos(wdt), -sin(wdt), 0, sin(wdt), cos(wdt), 0, 0, 0, 1;
        Vector3d a(-ICCx, -ICCy, 0);
        Vector3d b(ICCx, ICCy, wdt);
        endLocation = T * a + b;
    }
    else
    {
        endLocation[0] = 0;
        endLocation[1] = V * dt;
    }
    return pair<double, double> (-endLocation[0], endLocation[1]);
}
CompetitionController::~CompetitionController()
{
    if(_gps)
        _gps->onNewData -= &LOnNewGPSData;
}

}
}
<|endoftext|>


<commit_before>#ifndef __STOUT_STOPWATCH_HPP__
#define __STOUT_STOPWATCH_HPP__

#include <time.h>

#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#endif // __MACH__

#include <sys/time.h>

#include "duration.hpp"

class Stopwatch
{
public:
  Stopwatch() : running(false) { started.tv_sec = 0; started.tv_nsec = 0; }

  void start()
  {
    started = now();
    running = true;
  }

  void stop()
  {
    stopped = now();
    running = false;
  }

  Nanoseconds elapsed()
  {
    if (!running) {
      return Nanoseconds(diff(stopped, started));
    }

    return Nanoseconds(diff(now(), started));
  }

private:
  static timespec now()
  {
    timespec ts;
#ifdef __MACH__
    // OS X does not have clock_gettime, use clock_get_time.
    clock_serv_t cclock;
    mach_timespec_t mts;
    host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
    clock_get_time(cclock, &mts);
    mach_port_deallocate(mach_task_self(), cclock);
    ts.tv_sec = mts.tv_sec;
    ts.tv_nsec = mts.tv_nsec;
#else
    clock_gettime(CLOCK_REALTIME, &ts);
#endif // __MACH__
    return ts;
  }

  static uint64_t diff(const timespec& from, const timespec& to)
  {
    return ((from.tv_sec - to.tv_sec) * 1000000000LL)
      + (from.tv_nsec - to.tv_nsec);
  }

  bool running;
  timespec started, stopped;
};

#endif // __STOUT_STOPWATCH_HPP__
<commit_msg>Fixed a compilation issue with Stopwatch on Linux.<commit_after>#ifndef __STOUT_STOPWATCH_HPP__
#define __STOUT_STOPWATCH_HPP__

#include <time.h>

#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#endif // __MACH__

#include <sys/time.h>

#include "duration.hpp"

class Stopwatch
{
public:
  Stopwatch()
    : running(false)
  {
    started.tv_sec = 0;
    started.tv_nsec = 0;
    stopped.tv_sec = 0;
    stopped.tv_nsec = 0;
  }

  void start()
  {
    started = now();
    running = true;
  }

  void stop()
  {
    stopped = now();
    running = false;
  }

  Nanoseconds elapsed()
  {
    if (!running) {
      return Nanoseconds(diff(stopped, started));
    }

    return Nanoseconds(diff(now(), started));
  }

private:
  static timespec now()
  {
    timespec ts;
#ifdef __MACH__
    // OS X does not have clock_gettime, use clock_get_time.
    clock_serv_t cclock;
    mach_timespec_t mts;
    host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
    clock_get_time(cclock, &mts);
    mach_port_deallocate(mach_task_self(), cclock);
    ts.tv_sec = mts.tv_sec;
    ts.tv_nsec = mts.tv_nsec;
#else
    clock_gettime(CLOCK_REALTIME, &ts);
#endif // __MACH__
    return ts;
  }

  static uint64_t diff(const timespec& from, const timespec& to)
  {
    return ((from.tv_sec - to.tv_sec) * 1000000000LL)
      + (from.tv_nsec - to.tv_nsec);
  }

  bool running;
  timespec started, stopped;
};

#endif // __STOUT_STOPWATCH_HPP__
<|endoftext|>


<commit_before>#include "merlin_image.h":

namespace merlin {

Persistent<FunctionTemplate> MerlinImage::constructor_template;

Handle<Value>
MerlinImage::New(const Arguments& args) {
    HandleScope scope;
    node::Buffer *buf = ObjectWrap::Unwrap<node::Buffer>(args[0]->ToObject());
    MerlinImage* img = new MerlinImage(buf);
    img->Wrap(args.This());
    return scope.Close(args.This());
}

Handle<Value>
MerlinImage::GetBuffer(const Arguments& args) {
    HandleScope scope;

    MerlinImage *img = ObjectWrap::Unwrap<MerlinImage>(args.This());
    Handle<Value> buf = img->buffer->handle_;

    return scope.Close(buf);
}

Handle<Value>
MerlinImage::CropImage(const Arguments& args) {
    HandleScope scope;

    MerlinImage *img = ObjectWrap::Unwrap<MerlinImage>(args.This());
    MagickCropImage(img->wand, 20, 20, 20, 20);
    size_t length;
    unsigned char* data = MagickGetImageBlob(img->wand, length);
    fprintf(stderr, "%i\n", length);
    Handle<String> str = String::New((const char*) data, *length);
    fprintf(stderr, "%s\n", data);
    return scope.Close(str);
}

void
MerlinImage::Initialize(Handle<Object> target) {
    HandleScope scope;

    Handle<FunctionTemplate> f = FunctionTemplate::New(MerlinImage::New);
    constructor_template = Persistent<FunctionTemplate>::New(f);
    constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
    constructor_template->SetClassName(String::NewSymbol("MerlinImage"));

    NODE_SET_PROTOTYPE_METHOD(constructor_template, "cropImage", MerlinImage::CropImage);
    NODE_SET_PROTOTYPE_METHOD(constructor_template, "getBuffer", MerlinImage::GetBuffer);

    target->Set(String::NewSymbol("MerlinImage"), constructor_template->GetFunction());
}

MerlinImage::MerlinImage(node::Buffer *buffer) :
    buffer(buffer)
{
    wand = NewMagickWand();
}

MerlinImage::~MerlinImage() {
    delete buffer;
    wand = DestroyMagickWand(wand);
}

}
<commit_msg>whoops, length isn't a pointer<commit_after>#include "merlin_image.h":

namespace merlin {

Persistent<FunctionTemplate> MerlinImage::constructor_template;

Handle<Value>
MerlinImage::New(const Arguments& args) {
    HandleScope scope;
    node::Buffer *buf = ObjectWrap::Unwrap<node::Buffer>(args[0]->ToObject());
    MerlinImage* img = new MerlinImage(buf);
    img->Wrap(args.This());
    return scope.Close(args.This());
}

Handle<Value>
MerlinImage::GetBuffer(const Arguments& args) {
    HandleScope scope;

    MerlinImage *img = ObjectWrap::Unwrap<MerlinImage>(args.This());
    Handle<Value> buf = img->buffer->handle_;

    return scope.Close(buf);
}

Handle<Value>
MerlinImage::CropImage(const Arguments& args) {
    HandleScope scope;

    MerlinImage *img = ObjectWrap::Unwrap<MerlinImage>(args.This());
    MagickCropImage(img->wand, 20, 20, 20, 20);
    size_t length;
    unsigned char* data = MagickGetImageBlob(img->wand, length);
    fprintf(stderr, "%i\n", length);
    Handle<String> str = String::New((const char*) data, length);
    //fprintf(stderr, "%s\n", data);
    return scope.Close(str);
}

void
MerlinImage::Initialize(Handle<Object> target) {
    HandleScope scope;

    Handle<FunctionTemplate> f = FunctionTemplate::New(MerlinImage::New);
    constructor_template = Persistent<FunctionTemplate>::New(f);
    constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
    constructor_template->SetClassName(String::NewSymbol("MerlinImage"));

    NODE_SET_PROTOTYPE_METHOD(constructor_template, "cropImage", MerlinImage::CropImage);
    NODE_SET_PROTOTYPE_METHOD(constructor_template, "getBuffer", MerlinImage::GetBuffer);

    target->Set(String::NewSymbol("MerlinImage"), constructor_template->GetFunction());
}

MerlinImage::MerlinImage(node::Buffer *buffer) :
    buffer(buffer)
{
    wand = NewMagickWand();
}

MerlinImage::~MerlinImage() {
    delete buffer;
    wand = DestroyMagickWand(wand);
}

}
<|endoftext|>


<commit_before>/***
 *

Problem Statement

You are a student advisor at TopCoder University (TCU). The graduation
requirements at TCU are somewhat complicated. Each requirement states that a
student must take some number of classes from some set, and all requirements
must be satisfied for a student to graduate. Each class is represented as a
single distinct character. For example, one requirement might be "Take any 2
classes of B, C, D, or F." Further complicating the matter is the fact that no
class can be used to satisfy more than one requirement. And so students come to
you all the time, dazed and confused, because they don't know how close they
are to satisfying the requirements so that they can graduate!

Each class is represented as a distinct single character whose ASCII value is
between 33 and 126, inclusive, but is also not a numeric character ('0'-'9').
You will be given a string classesTaken, which represents the classes that a
given student has taken. You will also be given a vector <string> requirements,
which lists the requirements needed to graduate. Each string in requirements
will start with a positive integer, followed by some number of classes. For
example, the requirement "Take any 2 classes from B, C, D, or F" would be
represented in requirements as "2BCDF".

Your method should return a String representing the classes that the student
needs to take in order to graduate, in ASCII order. Classes may not be taken
more than once. If there is more than one set that will allow the student to
graduate, return the smallest set. If there are multiple smallest sets, return
the lexicographically smallest of these. Finally, if there is no set that will
enable this student to graduate, return "0".

Definition

Class: Graduation
Method: moreClasses
Parameters: string, vector <string>
Returns: string
Method signature:

string moreClasses(string classesTaken, vector <string> requirements)

Notes

	- Classes may not be taken more than once.

Constraints

- classesTaken will be between 0 and 50 characters in length, inclusive.
- each character in classesTaken will be a valid class (ASCII value between 33
to 126 inclusive and not a digit).

- there will be no duplicate classes in classesTaken.

- requirements will contain between 1 and 50 elements, inclusive.

- each element of requirements will contain a positive integer with no leading
zeros between 1 and 100, inclusive, followed by some number of valid classes.

- each element of requirements will be between 1 and 50 characters in length, inclusive.

- there will be no duplicate classes in any given element of requirements

Examples

0)

"A"
{"2ABC","2CDE"}

Returns: "BCD"

The student must take two classes from {A,B,C}, and two from {C,D,E}. He has already taken A.

1)
"+/NAMT"
{"3NAMT","2+/","1M"}
Returns: ""

The student has already fulfilled all the requirements - you should congratulate him for his achievement!

2)
"A"
{"100%*Klju"}
Returns: "0"
No matter how hard you try, you can't take 100 classes out of 6. TCU had better fix their policies quick.

3)
""
{"5ABCDE","1BCDE,"}
Returns: ",ABCDE"

4)
"CDH"
{"2AP", "3CDEF", "1CDEFH"}

Returns: "AEP"

	This problem statement is the exclusive and proprietary property of
	TopCoder, Inc. Any unauthorized use or reproduction of this information
	without the prior written consent of TopCoder, Inc. is strictly
	prohibited. (c)2003, TopCoder, Inc. All rights reserved.
**/

#include <vector>
#include <iostream>
#include <typeinfo>
#include <cstdlib>
#include <stdio.h>
#include <ctype.h>
#include <queue>

using namespace std;

int taken[128];

int bipartitematch(const vector <vector <int> > &m, int max=128) // Why is &m here?
{
	int elemno;
	int retn=0;
	int y,j;
	//mat and ret vector.
	vector <int> mat(max, -1); // mat is like the residual network Keeps track of edges super source to set A.
	vector <int> ret(m.size(), -1); //  ret is residual network keeps track of edges from B to sink.

	for(int i=0; i < m.size(); i++)
	{
		queue<int> q;
		vector<int> pred(m.size(), -1); // to keep track of elements.
		q.push(i);
		pred[i] = -2;  // mark the elem as visited.
		while (!q.empty())
		{
			elemno = q.front(); q.pop();
			for (j=0; j < m[elemno].size(); j++)
				if (taken[m[elemno][j]]) // If the individual class is taken.
				{
					y = mat[m[elemno][j]]; // Have we marked the path?
					if (y == -1)  // Not yet.
						goto found;
					if (pred[y] != -1) // already visited.
						continue;
					pred[y] = elemno; // BFS
					q.push(y); // BFS
				}
		}
		continue;
		found:  y = m[elemno][j];
			retn++;
			while( elemno != -2)
			{
				mat[y] = elemno; // Mark the Path.
				swap(ret[elemno], y);  // Mark the Path.
				elemno = pred[elemno]; // Is it visited or not?
			}
	}
		return retn;
}

class Graduation
{
	public:
		string moreClasses(string classesTaken, vector <string> requirements)
		{
			vector <vector <int> > m; // [[]]
			int remaining,paths;
			int nextclass;
			string ret="";

			for (int ct=0; ct<classesTaken.size();ct++)
				taken[classesTaken[ct]] = 1;

			for (int i=0;i<requirements.size();i++)
			{
				int num = atoi(requirements[i].c_str());
				for (int choice=0; choice<num;choice++)
				{
					m.push_back(vector<int>());
					for (int j=0; j < requirements[i].size(); j++)
						if (isalpha(requirements[i][j]))
							m.back().push_back(requirements[i][j]);
				}
			}

			if (m.size() > 128) return "0";
			remaining = m.size()-bipartitematch(m);
			nextclass=33;
			while(remaining)
			{
				if (nextclass >= 128) return "0";
				if (taken[nextclass])
				{
					nextclass++;
					continue;
				}
				taken[nextclass] = 1;
				paths = m.size() - bipartitematch(m);
				if (paths == remaining)
					taken[nextclass] = 0;
				else
				{
					ret += nextclass;
					remaining = paths;
				}
				nextclass++;

			}

			return ret;

		}
};

int main(int argc, char *argv[])
{
	Graduation combination;
	vector<string> requirement;
	requirement.push_back("2ABC");
	requirement.push_back("2CDE");
	cout<<combination.moreClasses("A",requirement)<<endl;

}
<commit_msg>Graduation problem clarification.<commit_after>/***
 *

Problem Statement

You are a student advisor at TopCoder University (TCU). The graduation
requirements at TCU are somewhat complicated. Each requirement states that a
student must take some number of classes from some set, and all requirements
must be satisfied for a student to graduate. Each class is represented as a
single distinct character. For example, one requirement might be "Take any 2
classes of B, C, D, or F." Further complicating the matter is the fact that no
class can be used to satisfy more than one requirement. And so students come to
you all the time, dazed and confused, because they don't know how close they
are to satisfying the requirements so that they can graduate!

Each class is represented as a distinct single character whose ASCII value is
between 33 and 126, inclusive, but is also not a numeric character ('0'-'9').
You will be given a string classesTaken, which represents the classes that a
given student has taken. You will also be given a vector <string> requirements,
which lists the requirements needed to graduate. Each string in requirements
will start with a positive integer, followed by some number of classes. For
example, the requirement "Take any 2 classes from B, C, D, or F" would be
represented in requirements as "2BCDF".

Your method should return a String representing the classes that the student
needs to take in order to graduate, in ASCII order. Classes may not be taken
more than once. If there is more than one set that will allow the student to
graduate, return the smallest set. If there are multiple smallest sets, return
the lexicographically smallest of these. Finally, if there is no set that will
enable this student to graduate, return "0".

Definition

Class: Graduation
Method: moreClasses
Parameters: string, vector <string>
Returns: string
Method signature:

string moreClasses(string classesTaken, vector <string> requirements)

Notes

	- Classes may not be taken more than once.

Constraints

- classesTaken will be between 0 and 50 characters in length, inclusive.
- each character in classesTaken will be a valid class (ASCII value between 33
to 126 inclusive and not a digit).

- there will be no duplicate classes in classesTaken.

- requirements will contain between 1 and 50 elements, inclusive.

- each element of requirements will contain a positive integer with no leading
zeros between 1 and 100, inclusive, followed by some number of valid classes.

- each element of requirements will be between 1 and 50 characters in length, inclusive.

- there will be no duplicate classes in any given element of requirements

Examples

0)

"A"
{"2ABC","2CDE"}

Returns: "BCD"

The student must take two classes from {A,B,C}, and two from {C,D,E}. He has already taken A.

1)
"+/NAMT"
{"3NAMT","2+/","1M"}
Returns: ""

The student has already fulfilled all the requirements - you should congratulate him for his achievement!

2)
"A"
{"100%*Klju"}
Returns: "0"
No matter how hard you try, you can't take 100 classes out of 6. TCU had better fix their policies quick.

3)
""
{"5ABCDE","1BCDE,"}
Returns: ",ABCDE"

4)
"CDH"
{"2AP", "3CDEF", "1CDEFH"}

Returns: "AEP"

	This problem statement is the exclusive and proprietary property of
	TopCoder, Inc. Any unauthorized use or reproduction of this information
	without the prior written consent of TopCoder, Inc. is strictly
	prohibited. (c)2003, TopCoder, Inc. All rights reserved.
**/

#include <vector>
#include <iostream>
#include <typeinfo>
#include <cstdlib>
#include <stdio.h>
#include <ctype.h>
#include <queue>

using namespace std;

int taken[128];

int bipartitematch(const vector <vector <int> > &m, int max=128) // Why is &m here?
{
	int elemno;
	int retn=0;
	int y,j;
	//mat and ret vector.
	vector <int> mat(max, -1); // mat is like the residual network Keeps track of edges super source to set A.
	vector <int> ret(m.size(), -1); //  ret is residual network keeps track of edges from B to sink.

	for(int i=0; i < m.size(); i++)
	{
		queue<int> q;
		vector<int> pred(m.size(), -1); // to keep track of elements.
		q.push(i);
		pred[i] = -2;  // mark the elem as visited.
		while (!q.empty())
		{
			elemno = q.front(); q.pop();
			for (j=0; j < m[elemno].size(); j++)
				if (taken[m[elemno][j]]) // If the individual class is taken.
				{
					y = mat[m[elemno][j]]; // Have we marked the path?
					if (y == -1)  // Not yet.
						goto found;
					if (pred[y] != -1) // already visited.
						continue;
					pred[y] = elemno; // BFS
					q.push(y); // BFS
				}
		}
		continue;
		found:  y = m[elemno][j];
			retn++;
			while( elemno != -2)
			{
				mat[y] = elemno; // Mark the Path.
				swap(ret[elemno], y);  // Mark the Path.
				elemno = pred[elemno]; // Is it visited or not?
			}
	}
		return retn;
}

class Graduation
{
	public:
		string moreClasses(string classesTaken, vector <string> requirements)
		{
			vector <vector <int> > m; // [[]]
			int remaining,paths;
			int nextclass;
			string ret="";

			for (int ct=0; ct<classesTaken.size();ct++)
				taken[classesTaken[ct]] = 1;

			for (int i=0;i<requirements.size();i++)
			{
				// does it take the first c char and discards the rest?
				int num = atoi(requirements[i].c_str());
				for (int choice=0; choice<num;choice++)
				{
					m.push_back(vector<int>());
					for (int j=0; j < requirements[i].size(); j++)
						if (isalpha(requirements[i][j]))
							m.back().push_back(requirements[i][j]);
				}
			}

			if (m.size() > 128) return "0";

			remaining = m.size()-bipartitematch(m); //BP match

			nextclass=33;
			while(remaining)
			{
				if (nextclass >= 128) return "0";
				if (taken[nextclass])
				{
					nextclass++;
					continue;
				}
				taken[nextclass] = 1;

				paths = m.size() - bipartitematch(m); // BP match

				if (paths == remaining)
					taken[nextclass] = 0;
				else
				{
					ret += nextclass; // is it concatenating str + int and giving str?
					remaining = paths;
				}
				nextclass++;

			}

			return ret;

		}
};

int main(int argc, char *argv[])
{
	Graduation combination;
	vector<string> requirement;
	requirement.push_back("2ABC");
	requirement.push_back("2CDE");
	cout<<combination.moreClasses("A",requirement)<<endl;

}
<|endoftext|>


<commit_before>/*
 * controller_listener.cpp
 *
 *  Created on: Apr 18, 2015
 *      Author: santigarcor
 */

#include "controller_listener.h"

#include "Leap.h"
using namespace Leap;

const std::string fingerNames[] = {"Thumb", "Index", "Middle", "Ring", "Pinky"};
const std::string boneNames[] = {"Metacarpal", "Proximal", "Middle", "Distal"};
const std::string stateNames[] = {"STATE_INVALID", "STATE_START", "STATE_UPDATE", "STATE_END"};

ControllerListener::ControllerListener(float swipeAngle, float screenTapAngle){
	this->screenTapAngle = screenTapAngle;
	this->swipeAngle = swipeAngle;
	this->xdo = xdo_new(NULL);
	this->lastPosX = 0;
	this->lastPosY = 0,
	xdo_get_viewport_dimensions(xdo, &width,&height,0);
}

/*
 * Called when the Controller connects to the Leap Motion and
 * the Leap Motion hardware device is plugged in,
 * or when this listener is added to a Controller that is already connected
 */
void ControllerListener::onConnect(const Controller &controller) {
  std::cout << "onConnect" << std::endl;
  controller.enableGesture(Gesture::TYPE_SCREEN_TAP);
  controller.enableGesture(Gesture::TYPE_SWIPE);
}

/*
 * Called every frame
 */
void ControllerListener::onFrame(const Controller &controller) {
	// Get the most recent frame
	const Frame frame = controller.frame();

	HandList hands = frame.hands();
	for (HandList::const_iterator hl = hands.begin(); hl != hands.end(); hl++) {
		const Hand hand = *hl;
		Vector v = hand.palmPosition();

		if (v[0] < minX){
			v.x = minX;
		}
		if (v[0] > maxX){
			v.x = maxX;
		}
		if (v[1] < minY){
			v.y = minY;
		}
		if (v[1] > maxY){
			v.y = maxY;
		}

		int oldRangeX = maxX - minX;
		int oldRangeY = maxY - minY;
		int newRangeX = width - 0;
		int newRangeY = height - 0;

		int x = (((v[0] - minX) * newRangeX) / oldRangeX) + 0;
		int y = (((v[1] - minY) * newRangeY) / oldRangeY) + 0;
		xdo_move_mouse_relative(xdo, x - lastPosX, lastPosY - y);
		lastPosX = x;
		lastPosY = y;

		FingerList fingers = hand.fingers();

		for (FingerList::const_iterator fl = fingers.begin(); fl != fingers.end(); fl++) {
			Finger finger = *fl;
			Vector direction = finger.direction();
			float fingerAngleY = direction.angleTo(Vector(0,-1,0));
			fingerAngleY = toDegrees(fingerAngleY);
			switch (finger.type()) {
				case Finger::TYPE_INDEX:
					if (fingerAngleY <= 25) {
						std::cout << "clic" << std::endl;
						xdo_mouse_down(xdo, CURRENTWINDOW, 1);
					} else {
						xdo_mouse_up(xdo, CURRENTWINDOW, 1);
					}
					break;
				case Finger::TYPE_MIDDLE:
					if (fingerAngleY <= 25) {
						std::cout << "rclic" << std::endl;
						xdo_mouse_down(xdo, CURRENTWINDOW, 3);
					} else {
						xdo_mouse_up(xdo, CURRENTWINDOW, 3);
					}
					break;
				default:
					break;
			}
		}

		// Get gestures
		const GestureList gestures = frame.gestures();
		for (int g = 0; g < gestures.count(); ++g) {
			Gesture gesture = gestures[g];
			switch (gesture.type()) {
				case Gesture::TYPE_SWIPE:{
					SwipeGesture swipe = gesture;
					float angleRight = swipe.direction().angleTo(Vector(1,0,0));
					float angleLeft = swipe.direction().angleTo(Vector(-1,0,0));
					float angleUp = swipe.direction().angleTo(Vector(0,1,0));
					float angleDown = swipe.direction().angleTo(Vector(0,-1,0));
					angleRight = toDegrees(angleRight);
					angleLeft = toDegrees(angleLeft);
					angleUp = toDegrees(angleUp);
					angleDown = toDegrees(angleDown);

					if(angleRight <= swipeAngle){
						//std::cout <<" direction Right: " << swipe.direction()[0] << std::endl;
						xdo_send_keysequence_window(xdo, CURRENTWINDOW, "ctrl+alt+Left", 0);
						break;
					}else if(angleLeft <= swipeAngle){
						//std::cout <<" direction left: " << swipe.direction()[0] << std::endl;
						xdo_send_keysequence_window(xdo, CURRENTWINDOW, "ctrl+alt+Right", 0);
						break;
					}

					if(angleUp <= swipeAngle){
						//std::cout <<" direction Up: " << swipe.direction()[1] << std::endl;
						xdo_send_keysequence_window(xdo, CURRENTWINDOW, "ctrl+alt+Down", 0);
						break;
					}else if(angleDown <= swipeAngle){
						//std::cout <<" direction down: " << swipe.direction()[1] << std::endl;
						xdo_send_keysequence_window(xdo, CURRENTWINDOW, "ctrl+alt+Up", 0);
						break;
					}
					break;
				}
				case Gesture::TYPE_SCREEN_TAP:{
					ScreenTapGesture screentap = gesture;

					float angle = screentap.direction().angleTo(Vector(0,0,1));
					angle = toDegrees(angle);
					std::cout << angle << std::endl;
					if (angle <= screenTapAngle) {
						xdo_send_keysequence_window(xdo, CURRENTWINDOW, "super+s", 0);
					}

					break;
				}
				default:
					std::cout << "Unknown gesture type." << std::endl;
					break;
			}
		}
	}
}

/*
 * Called when a Leap Motion controller plugged in, unplugged,
 * or the device changes state.
 */
void ControllerListener::onDeviceChange(const Controller &controller) {
  std::cout << "Device Changed" << std::endl;
  const DeviceList devices = controller.devices();

  for (int i = 0; i < devices.count(); ++i) {
    std::cout << "id: " << devices[i].toString() << std::endl;
    std::cout << "  isStreaming: " << (devices[i].isStreaming() ? "true" : "false") << std::endl;
  }
}

float ControllerListener::toDegrees(float radians){
	return radians * 180/3.14159265359f;
}
<commit_msg>Improved mouse movement and clic action<commit_after>/*
 * controller_listener.cpp
 *
 *  Created on: Apr 18, 2015
 *      Author: santigarcor
 */

#include "controller_listener.h"

#include "Leap.h"
using namespace Leap;

const std::string fingerNames[] = {"Thumb", "Index", "Middle", "Ring", "Pinky"};
const std::string boneNames[] = {"Metacarpal", "Proximal", "Middle", "Distal"};
const std::string stateNames[] = {"STATE_INVALID", "STATE_START", "STATE_UPDATE", "STATE_END"};

ControllerListener::ControllerListener(float swipeAngle, float screenTapAngle){
	this->screenTapAngle = screenTapAngle;
	this->swipeAngle = swipeAngle;
	this->xdo = xdo_new(NULL);
	this->lastPosX = 0;
	this->lastPosY = 0,
	xdo_get_viewport_dimensions(xdo, &width,&height,0);
}

/*
 * Called when the Controller connects to the Leap Motion and
 * the Leap Motion hardware device is plugged in,
 * or when this listener is added to a Controller that is already connected
 */
void ControllerListener::onConnect(const Controller &controller) {
  std::cout << "onConnect" << std::endl;
  controller.enableGesture(Gesture::TYPE_SCREEN_TAP);
  controller.enableGesture(Gesture::TYPE_SWIPE);
}

/*
 * Called every frame
 */
void ControllerListener::onFrame(const Controller &controller) {
	// Get the most recent frame
	const Frame frame = controller.frame();

	HandList hands = frame.hands();
	for (HandList::const_iterator hl = hands.begin(); hl != hands.end(); hl++) {
		const Hand hand = *hl;
		Vector v = hand.stabilizedPalmPosition();

		if (v[0] < minX){
			v.x = minX;
		}
		if (v[0] > maxX){
			v.x = maxX;
		}
		if (v[1] < minY){
			v.y = minY;
		}
		if (v[1] > maxY){
			v.y = maxY;
		}

		int oldRangeX = maxX - minX;
		int oldRangeY = maxY - minY;
		int newRangeX = width - 0;
		int newRangeY = height - 0;

		int x = (((v[0] - minX) * newRangeX) / oldRangeX) + 0;
		int y = (((v[1] - minY) * newRangeY) / oldRangeY) + 0;
		xdo_move_mouse_relative(xdo, x - lastPosX, lastPosY - y);
		lastPosX = x;
		lastPosY = y;

		FingerList fingers = hand.fingers();

		Vector indexD, middleD, thumbD;

		bool index = false, middle = false, thumb = false;

		for (FingerList::const_iterator fl = fingers.begin(); fl != fingers.end(); fl++) {
			Finger finger = *fl;
			Vector direction = finger.direction();
			float fingerAngleY = direction.angleTo(Vector(0,-1,0));
			fingerAngleY = toDegrees(fingerAngleY);
			switch (finger.type()) {
				case Finger::TYPE_INDEX:
					indexD = finger.tipPosition();
					if (!finger.isExtended()){
						index = true;
					}
					break;
				case Finger::TYPE_MIDDLE:
					middleD = finger.tipPosition();
					if (!finger.isExtended()){
						middle = true;
					}
					break;
				case Finger::TYPE_THUMB:
					thumbD = finger.tipPosition();
					if (!finger.isExtended()){
						thumb = true;
					}
					break;
				default:
					break;
			}
		}

		if (indexD.distanceTo(thumbD) <= 30){
			xdo_mouse_down(xdo, CURRENTWINDOW, 1);
		}else{
			xdo_mouse_up(xdo, CURRENTWINDOW, 1);
		}

		if (indexD.distanceTo(thumbD) <= 30) {
			xdo_mouse_down(xdo, CURRENTWINDOW, 3);
		} else {
			xdo_mouse_up(xdo, CURRENTWINDOW, 3);
		}

		// Get gestures
		const GestureList gestures = frame.gestures();
		for (int g = 0; g < gestures.count(); ++g) {
			Gesture gesture = gestures[g];
			switch (gesture.type()) {
				case Gesture::TYPE_SWIPE:{
					SwipeGesture swipe = gesture;
					float angleRight = swipe.direction().angleTo(Vector(1,0,0));
					float angleLeft = swipe.direction().angleTo(Vector(-1,0,0));
					float angleUp = swipe.direction().angleTo(Vector(0,1,0));
					float angleDown = swipe.direction().angleTo(Vector(0,-1,0));
					angleRight = toDegrees(angleRight);
					angleLeft = toDegrees(angleLeft);
					angleUp = toDegrees(angleUp);
					angleDown = toDegrees(angleDown);

					if(angleRight <= swipeAngle){
						//std::cout <<" direction Right: " << swipe.direction()[0] << std::endl;
						xdo_send_keysequence_window(xdo, CURRENTWINDOW, "ctrl+alt+Left", 0);
						break;
					}else if(angleLeft <= swipeAngle){
						//std::cout <<" direction left: " << swipe.direction()[0] << std::endl;
						xdo_send_keysequence_window(xdo, CURRENTWINDOW, "ctrl+alt+Right", 0);
						break;
					}

					if(angleUp <= swipeAngle){
						//std::cout <<" direction Up: " << swipe.direction()[1] << std::endl;
						xdo_send_keysequence_window(xdo, CURRENTWINDOW, "ctrl+alt+Down", 0);
						break;
					}else if(angleDown <= swipeAngle){
						//std::cout <<" direction down: " << swipe.direction()[1] << std::endl;
						xdo_send_keysequence_window(xdo, CURRENTWINDOW, "ctrl+alt+Up", 0);
						break;
					}
					break;
				}
				case Gesture::TYPE_SCREEN_TAP:{
					ScreenTapGesture screentap = gesture;

					float angle = screentap.direction().angleTo(Vector(0,0,1));
					angle = toDegrees(angle);
					std::cout << angle << std::endl;
					if (angle <= screenTapAngle) {
						xdo_send_keysequence_window(xdo, CURRENTWINDOW, "super+s", 0);
					}

					break;
				}
				default:
					std::cout << "Unknown gesture type." << std::endl;
					break;
			}
		}
	}
}

/*
 * Called when a Leap Motion controller plugged in, unplugged,
 * or the device changes state.
 */
void ControllerListener::onDeviceChange(const Controller &controller) {
  std::cout << "Device Changed" << std::endl;
  const DeviceList devices = controller.devices();

  for (int i = 0; i < devices.count(); ++i) {
    std::cout << "id: " << devices[i].toString() << std::endl;
    std::cout << "  isStreaming: " << (devices[i].isStreaming() ? "true" : "false") << std::endl;
  }
}

float ControllerListener::toDegrees(float radians){
	return radians * 180/3.14159265359f;
}
<|endoftext|>


<commit_before>///
/// @file  pmath.cpp
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <pmath.hpp>

#include <stdint.h>
#include <algorithm>
#include <limits>
#include <vector>

using namespace std;

namespace primecount {

/// Generate a vector with Möbius function values.
/// This implementation is based on code by Rick Sladkey
/// posted here: http://mathoverflow.net/a/99545
///
vector<int32_t> make_moebius(int64_t max)
{
  vector<int32_t> mu(max + 1, 1);

  for (int32_t i = 2; i * i <= max; i++)
  {
    if (mu[i] == 1)
    {
      for (int32_t j = i; j <= max; j += i)
        mu[j] *= -i;
      for (int32_t j = i * i; j <= max; j += i * i)
        mu[j] = 0;
    }
  }

  for (int32_t i = 2; i <= max; i++)
  {
    if (mu[i] == i)
      mu[i] = 1;
    else if (mu[i] == -i)
      mu[i] = -1;
    else if (mu[i] < 0)
      mu[i] = 1;
    else if (mu[i] > 0)
      mu[i] = -1;
  }

  return mu;
}

/// Generate a vector with the least prime
/// factors of the integers <= max.
///
vector<int32_t> make_least_prime_factor(int64_t max)
{
  vector<int32_t> lpf(max + 1, 1);

  // phi(x / 1, c) contributes to the sum, thus
  // set lpf[1] = MAX in order to pass
  // if (lpf[1] > primes[c])
  if (lpf.size() > 1)
    lpf[1] = numeric_limits<int32_t>::max();

  for (int32_t i = 2; i * i <= max; i++)
    if (lpf[i] == 1)
      for (int32_t j = i * 2; j <= max; j += i)
        if (lpf[j] == 1)
          lpf[j] = i;

  for (int32_t i = 2; i <= max; i++)
    if (lpf[i] == 1)
      lpf[i] = i;

  return lpf;
}

/// Generate a vector with the prime counts below max
/// using the sieve of Eratosthenes.
///
vector<int32_t> make_pi(int64_t max)
{
  vector<char> is_prime(max + 1, 1);

  for (int64_t i = 2; i * i <= max; i++)
    if (is_prime[i])
      for (int64_t j = i * i; j <= max; j += i)
        is_prime[j] = 0;

  vector<int32_t> pi(max + 1, 0);
  int32_t pix = 0;

  for (int64_t x = 2; x <= max; x++)
  {
    pix += is_prime[x];
    pi[x] = pix;
  }

  return pi;
}

/// Generate vectors containing n values which satisfy:
/// is_square_free(n) && && !is_prime(n) && primes[i] < least_prime_factor[n].
///
vector<vector<int32_t> >
generate_square_free_candidates(int64_t c,
                                int64_t y,
                                vector<int32_t>& lpf,
                                vector<int32_t>& mu,
                                vector<int32_t>& pi,
                                vector<int32_t>& primes)
{
  int64_t sqrty = isqrt(y);
  int64_t start = primes[min<int64_t>(c + 1, primes.size() - 1)];
  vector<vector<int32_t> > square_free_candidates(pi[sqrty], vector<int32_t>(1, 0));

  for (int32_t n = start; n <= y; n++)
    if (mu[n] != 0 && n != primes[pi[n]] && lpf[n] < sqrty)
      for (int32_t i = pi[lpf[n]] - 1; i > c; i--)
        square_free_candidates[i].push_back(n);

  return square_free_candidates;
}

} // namespace
<commit_msg>Fix segmentation fault<commit_after>///
/// @file  pmath.cpp
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <pmath.hpp>

#include <stdint.h>
#include <algorithm>
#include <limits>
#include <vector>

using namespace std;

namespace primecount {

/// Generate a vector with Möbius function values.
/// This implementation is based on code by Rick Sladkey
/// posted here: http://mathoverflow.net/a/99545
///
vector<int32_t> make_moebius(int64_t max)
{
  vector<int32_t> mu(max + 1, 1);

  for (int32_t i = 2; i * i <= max; i++)
  {
    if (mu[i] == 1)
    {
      for (int32_t j = i; j <= max; j += i)
        mu[j] *= -i;
      for (int32_t j = i * i; j <= max; j += i * i)
        mu[j] = 0;
    }
  }

  for (int32_t i = 2; i <= max; i++)
  {
    if (mu[i] == i)
      mu[i] = 1;
    else if (mu[i] == -i)
      mu[i] = -1;
    else if (mu[i] < 0)
      mu[i] = 1;
    else if (mu[i] > 0)
      mu[i] = -1;
  }

  return mu;
}

/// Generate a vector with the least prime
/// factors of the integers <= max.
///
vector<int32_t> make_least_prime_factor(int64_t max)
{
  vector<int32_t> lpf(max + 1, 1);

  // phi(x / 1, c) contributes to the sum, thus
  // set lpf[1] = MAX in order to pass
  // if (lpf[1] > primes[c])
  if (lpf.size() > 1)
    lpf[1] = numeric_limits<int32_t>::max();

  for (int32_t i = 2; i * i <= max; i++)
    if (lpf[i] == 1)
      for (int32_t j = i * 2; j <= max; j += i)
        if (lpf[j] == 1)
          lpf[j] = i;

  for (int32_t i = 2; i <= max; i++)
    if (lpf[i] == 1)
      lpf[i] = i;

  return lpf;
}

/// Generate a vector with the prime counts below max
/// using the sieve of Eratosthenes.
///
vector<int32_t> make_pi(int64_t max)
{
  vector<char> is_prime(max + 1, 1);

  for (int64_t i = 2; i * i <= max; i++)
    if (is_prime[i])
      for (int64_t j = i * i; j <= max; j += i)
        is_prime[j] = 0;

  vector<int32_t> pi(max + 1, 0);
  int32_t pix = 0;

  for (int64_t x = 2; x <= max; x++)
  {
    pix += is_prime[x];
    pi[x] = pix;
  }

  return pi;
}

/// Generate vectors containing n values which satisfy:
/// is_square_free(n) && && !is_prime(n) && primes[i] < least_prime_factor[n].
///
vector<vector<int32_t> >
generate_square_free_candidates(int64_t c,
                                int64_t y,
                                vector<int32_t>& lpf,
                                vector<int32_t>& mu,
                                vector<int32_t>& pi,
                                vector<int32_t>& primes)
{
  int64_t pi_sqrty = pi[isqrt(y)];
  vector<vector<int32_t> > square_free_candidates(pi_sqrty, vector<int32_t>(1, 0));

  for (int32_t n = 2; n <= y; n++)
    if (mu[n] != 0 && n != primes[pi[n]])
      for (int32_t i = pi[lpf[n]] - 1; i > c; i--)
        square_free_candidates[i].push_back(n);

  return square_free_candidates;
}

} // namespace
<|endoftext|>