<commit_before>//== BodyFarm.cpp  - Factory for conjuring up fake bodies ----------*- C++ -*-//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// BodyFarm is a factory for creating faux implementations for functions/methods
// for analysis purposes.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringSwitch.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Decl.h"
#include "BodyFarm.h"

using namespace clang;

//===----------------------------------------------------------------------===//
// Helper creation functions for constructing faux ASTs.
//===----------------------------------------------------------------------===//

static bool isDispatchBlock(QualType Ty) {
  // Is it a block pointer?
  const BlockPointerType *BPT = Ty->getAs<BlockPointerType>();
  if (!BPT)
    return false;

  // Check if the block pointer type takes no arguments and
  // returns void.
  const FunctionProtoType *FT =
  BPT->getPointeeType()->getAs<FunctionProtoType>();
  if (!FT || !FT->getResultType()->isVoidType()  ||
      FT->getNumArgs() != 0)
    return false;

  return true;
}

namespace {
class ASTMaker {
public:
  ASTMaker(ASTContext &C) : C(C) {}

  /// Create a new DeclRefExpr for the referenced variable.
  DeclRefExpr *makeDeclRefExpr(const VarDecl *D);

  /// Create an implicit cast for an integer conversion.
  ImplicitCastExpr *makeIntegralCast(const Expr *Arg, QualType Ty);

  // Create an implicit cast for lvalue-to-rvaluate conversions.
  ImplicitCastExpr *makeLvalueToRvalue(const Expr *Arg, QualType Ty);

private:
  ASTContext &C;
};
}

DeclRefExpr *ASTMaker::makeDeclRefExpr(const VarDecl *D) {
  DeclRefExpr *DR =
    DeclRefExpr::Create(/* Ctx = */ C,
                        /* QualifierLoc = */ NestedNameSpecifierLoc(),
                        /* TemplateKWLoc = */ SourceLocation(),
                        /* D = */ const_cast<VarDecl*>(D),
                        /* isEnclosingLocal = */ false,
                        /* NameLoc = */ SourceLocation(),
                        /* T = */ D->getType(),
                        /* VK = */ VK_LValue);
  return DR;
}

ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) {
  return ImplicitCastExpr::Create(C, Ty, CK_LValueToRValue,
                                  const_cast<Expr*>(Arg), 0, VK_RValue);
}

ImplicitCastExpr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) {
  return ImplicitCastExpr::Create(C, Ty, CK_IntegralCast,
                                  const_cast<Expr*>(Arg), 0, VK_RValue);
}

//===----------------------------------------------------------------------===//
// Creation functions for faux ASTs.
//===----------------------------------------------------------------------===//

typedef Stmt *(*FunctionFarmer)(ASTContext &C, const FunctionDecl *D);

/// Create a fake body for dispatch_once.
static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
  // Check if we have at least two parameters.
  if (D->param_size() != 2)
    return 0;

  // Check if the first parameter is a pointer to integer type.
  const ParmVarDecl *Predicate = D->getParamDecl(0);
  QualType PredicateQPtrTy = Predicate->getType();
  const PointerType *PredicatePtrTy = PredicateQPtrTy->getAs<PointerType>();
  if (!PredicatePtrTy)
    return 0;
  QualType PredicateTy = PredicatePtrTy->getPointeeType();
  if (!PredicateTy->isIntegerType())
    return 0;

  // Check if the second parameter is the proper block type.
  const ParmVarDecl *Block = D->getParamDecl(1);
  QualType Ty = Block->getType();
  if (!isDispatchBlock(Ty))
    return 0;

  // Everything checks out.  Create a fakse body that checks the predicate,
  // sets it, and calls the block.  Basically, an AST dump of:
  //
  // void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) {
  //  if (!*predicate) {
  //    *predicate = 1;
  //    block();
  //  }
  // }

  ASTMaker M(C);

  // (1) Create the call.
  DeclRefExpr *DR = M.makeDeclRefExpr(Block);
  ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
  CallExpr *CE = new (C) CallExpr(C, ICE, ArrayRef<Expr*>(), C.VoidTy,
                                  VK_RValue, SourceLocation());

  // (2) Create the assignment to the predicate.
  IntegerLiteral *IL =
    IntegerLiteral::Create(C, llvm::APInt(C.getTypeSize(C.IntTy), (uint64_t) 1),
                           C.IntTy, SourceLocation());
  ICE = M.makeIntegralCast(IL, PredicateTy);
  DR = M.makeDeclRefExpr(Predicate);
  ImplicitCastExpr *LValToRval = M.makeLvalueToRvalue(DR, PredicateQPtrTy);
  UnaryOperator *UO = new (C) UnaryOperator(LValToRval, UO_Deref, PredicateTy,
                                            VK_LValue, OK_Ordinary,
                                            SourceLocation());
  BinaryOperator *B = new (C) BinaryOperator(UO, ICE, BO_Assign,
                                             PredicateTy, VK_RValue,
                                             OK_Ordinary,
                                             SourceLocation());
  // (3) Create the compound statement.
  Stmt *Stmts[2];
  Stmts[0] = B;
  Stmts[1] = CE;
  CompoundStmt *CS = new (C) CompoundStmt(C, Stmts, 2, SourceLocation(),
                                          SourceLocation());

  // (4) Create the 'if' condition.
  DR = M.makeDeclRefExpr(Predicate);
  LValToRval = M.makeLvalueToRvalue(DR, PredicateQPtrTy);
  UO = new (C) UnaryOperator(LValToRval, UO_Deref, PredicateTy,
                             VK_LValue, OK_Ordinary,
                             SourceLocation());
  LValToRval = M.makeLvalueToRvalue(UO, PredicateTy);
  UO = new (C) UnaryOperator(LValToRval, UO_LNot, C.IntTy,
                             VK_RValue, OK_Ordinary, SourceLocation());

  // (5) Create the 'if' statement.
  IfStmt *If = new (C) IfStmt(C, SourceLocation(), 0, UO, CS);
  return If;
}

/// Create a fake body for dispatch_sync.
static Stmt *create_dispatch_sync(ASTContext &C, const FunctionDecl *D) {
  // Check if we have at least two parameters.
  if (D->param_size() != 2)
    return 0;

  // Check if the second parameter is a block.
  const ParmVarDecl *PV = D->getParamDecl(1);
  QualType Ty = PV->getType();
  if (!isDispatchBlock(Ty))
    return 0;

  // Everything checks out.  Create a fake body that just calls the block.
  // This is basically just an AST dump of:
  //
  // void dispatch_sync(dispatch_queue_t queue, void (^block)(void)) {
  //   block();
  // }
  //
  ASTMaker M(C);
  DeclRefExpr *DR = M.makeDeclRefExpr(PV);
  ImplicitCastExpr *ICE = ImplicitCastExpr::Create(C, Ty, CK_LValueToRValue,
                                                   DR, 0, VK_RValue);
  CallExpr *CE = new (C) CallExpr(C, ICE, ArrayRef<Expr*>(), C.VoidTy,
                                  VK_RValue, SourceLocation());
  return CE;
}

Stmt *BodyFarm::getBody(const FunctionDecl *D) {
  D = D->getCanonicalDecl();

  llvm::Optional<Stmt *> &Val = Bodies[D];
  if (Val.hasValue())
    return Val.getValue();

  Val = 0;

  if (D->getIdentifier() == 0)
    return 0;

  StringRef Name = D->getName();
  if (Name.empty())
    return 0;

  FunctionFarmer FF =
    llvm::StringSwitch<FunctionFarmer>(Name)
      .Case("dispatch_sync", create_dispatch_sync)
      .Case("dispatch_once", create_dispatch_once)
      .Default(NULL);

  if (FF) {
    Val = FF(C, D);
  }

  return Val.getValue();
}

<commit_msg>Add helper method in BodyFarm to create unary dereferences.<commit_after>//== BodyFarm.cpp  - Factory for conjuring up fake bodies ----------*- C++ -*-//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// BodyFarm is a factory for creating faux implementations for functions/methods
// for analysis purposes.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringSwitch.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Decl.h"
#include "BodyFarm.h"

using namespace clang;

//===----------------------------------------------------------------------===//
// Helper creation functions for constructing faux ASTs.
//===----------------------------------------------------------------------===//

static bool isDispatchBlock(QualType Ty) {
  // Is it a block pointer?
  const BlockPointerType *BPT = Ty->getAs<BlockPointerType>();
  if (!BPT)
    return false;

  // Check if the block pointer type takes no arguments and
  // returns void.
  const FunctionProtoType *FT =
  BPT->getPointeeType()->getAs<FunctionProtoType>();
  if (!FT || !FT->getResultType()->isVoidType()  ||
      FT->getNumArgs() != 0)
    return false;

  return true;
}

namespace {
class ASTMaker {
public:
  ASTMaker(ASTContext &C) : C(C) {}

  /// Create a new DeclRefExpr for the referenced variable.
  DeclRefExpr *makeDeclRefExpr(const VarDecl *D);

  /// Create a new UnaryOperator representing a dereference.
  UnaryOperator *makeDereference(const Expr *Arg, QualType Ty);

  /// Create an implicit cast for an integer conversion.
  ImplicitCastExpr *makeIntegralCast(const Expr *Arg, QualType Ty);

  // Create an implicit cast for lvalue-to-rvaluate conversions.
  ImplicitCastExpr *makeLvalueToRvalue(const Expr *Arg, QualType Ty);

private:
  ASTContext &C;
};
}

DeclRefExpr *ASTMaker::makeDeclRefExpr(const VarDecl *D) {
  DeclRefExpr *DR =
    DeclRefExpr::Create(/* Ctx = */ C,
                        /* QualifierLoc = */ NestedNameSpecifierLoc(),
                        /* TemplateKWLoc = */ SourceLocation(),
                        /* D = */ const_cast<VarDecl*>(D),
                        /* isEnclosingLocal = */ false,
                        /* NameLoc = */ SourceLocation(),
                        /* T = */ D->getType(),
                        /* VK = */ VK_LValue);
  return DR;
}

UnaryOperator *ASTMaker::makeDereference(const Expr *Arg, QualType Ty) {
  return new (C) UnaryOperator(const_cast<Expr*>(Arg), UO_Deref, Ty,
                               VK_LValue, OK_Ordinary, SourceLocation());
}

ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) {
  return ImplicitCastExpr::Create(C, Ty, CK_LValueToRValue,
                                  const_cast<Expr*>(Arg), 0, VK_RValue);
}

ImplicitCastExpr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) {
  return ImplicitCastExpr::Create(C, Ty, CK_IntegralCast,
                                  const_cast<Expr*>(Arg), 0, VK_RValue);
}

//===----------------------------------------------------------------------===//
// Creation functions for faux ASTs.
//===----------------------------------------------------------------------===//

typedef Stmt *(*FunctionFarmer)(ASTContext &C, const FunctionDecl *D);

/// Create a fake body for dispatch_once.
static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
  // Check if we have at least two parameters.
  if (D->param_size() != 2)
    return 0;

  // Check if the first parameter is a pointer to integer type.
  const ParmVarDecl *Predicate = D->getParamDecl(0);
  QualType PredicateQPtrTy = Predicate->getType();
  const PointerType *PredicatePtrTy = PredicateQPtrTy->getAs<PointerType>();
  if (!PredicatePtrTy)
    return 0;
  QualType PredicateTy = PredicatePtrTy->getPointeeType();
  if (!PredicateTy->isIntegerType())
    return 0;

  // Check if the second parameter is the proper block type.
  const ParmVarDecl *Block = D->getParamDecl(1);
  QualType Ty = Block->getType();
  if (!isDispatchBlock(Ty))
    return 0;

  // Everything checks out.  Create a fakse body that checks the predicate,
  // sets it, and calls the block.  Basically, an AST dump of:
  //
  // void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) {
  //  if (!*predicate) {
  //    *predicate = 1;
  //    block();
  //  }
  // }

  ASTMaker M(C);

  // (1) Create the call.
  DeclRefExpr *DR = M.makeDeclRefExpr(Block);
  ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
  CallExpr *CE = new (C) CallExpr(C, ICE, ArrayRef<Expr*>(), C.VoidTy,
                                  VK_RValue, SourceLocation());

  // (2) Create the assignment to the predicate.
  IntegerLiteral *IL =
    IntegerLiteral::Create(C, llvm::APInt(C.getTypeSize(C.IntTy), (uint64_t) 1),
                           C.IntTy, SourceLocation());
  ICE = M.makeIntegralCast(IL, PredicateTy);
  DR = M.makeDeclRefExpr(Predicate);
  ImplicitCastExpr *LValToRval = M.makeLvalueToRvalue(DR, PredicateQPtrTy);
  UnaryOperator *UO = M.makeDereference(LValToRval, PredicateTy);
  BinaryOperator *B = new (C) BinaryOperator(UO, ICE, BO_Assign,
                                             PredicateTy, VK_RValue,
                                             OK_Ordinary,
                                             SourceLocation());
  // (3) Create the compound statement.
  Stmt *Stmts[2];
  Stmts[0] = B;
  Stmts[1] = CE;
  CompoundStmt *CS = new (C) CompoundStmt(C, Stmts, 2, SourceLocation(),
                                          SourceLocation());

  // (4) Create the 'if' condition.
  DR = M.makeDeclRefExpr(Predicate);
  LValToRval = M.makeLvalueToRvalue(DR, PredicateQPtrTy);
  UO = M.makeDereference(LValToRval, PredicateTy);
  LValToRval = M.makeLvalueToRvalue(UO, PredicateTy);
  UO = new (C) UnaryOperator(LValToRval, UO_LNot, C.IntTy,
                             VK_RValue, OK_Ordinary, SourceLocation());

  // (5) Create the 'if' statement.
  IfStmt *If = new (C) IfStmt(C, SourceLocation(), 0, UO, CS);
  return If;
}

/// Create a fake body for dispatch_sync.
static Stmt *create_dispatch_sync(ASTContext &C, const FunctionDecl *D) {
  // Check if we have at least two parameters.
  if (D->param_size() != 2)
    return 0;

  // Check if the second parameter is a block.
  const ParmVarDecl *PV = D->getParamDecl(1);
  QualType Ty = PV->getType();
  if (!isDispatchBlock(Ty))
    return 0;

  // Everything checks out.  Create a fake body that just calls the block.
  // This is basically just an AST dump of:
  //
  // void dispatch_sync(dispatch_queue_t queue, void (^block)(void)) {
  //   block();
  // }
  //
  ASTMaker M(C);
  DeclRefExpr *DR = M.makeDeclRefExpr(PV);
  ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
  CallExpr *CE = new (C) CallExpr(C, ICE, ArrayRef<Expr*>(), C.VoidTy,
                                  VK_RValue, SourceLocation());
  return CE;
}

Stmt *BodyFarm::getBody(const FunctionDecl *D) {
  D = D->getCanonicalDecl();

  llvm::Optional<Stmt *> &Val = Bodies[D];
  if (Val.hasValue())
    return Val.getValue();

  Val = 0;

  if (D->getIdentifier() == 0)
    return 0;

  StringRef Name = D->getName();
  if (Name.empty())
    return 0;

  FunctionFarmer FF =
    llvm::StringSwitch<FunctionFarmer>(Name)
      .Case("dispatch_sync", create_dispatch_sync)
      .Case("dispatch_once", create_dispatch_once)
      .Default(NULL);

  if (FF) {
    Val = FF(C, D);
  }

  return Val.getValue();
}

<|endoftext|>


<commit_before>//!
//! @author     Yue Wang
//! @date       19 Sep 2014
//!
//! ex2.4.1.c
//! parse
//!         S -> 0S1 | 01
//!
//! sample inputs : 01  0011    000111  00001111, etc
//!

#include <iostream>
#include <string>
#include <functional>

namespace dragon {namespace ch2 {

/**
 * @brief parse_241c
 * @param first
 * @param last
 * @return  true if legal, false otherwise.
 *
 * @complexity  O(n)
 */
template<typename Iter>
bool parse_241c(Iter first, Iter last)
{
    //! ensure "01" can be dereferenced safely
    if(last - first < 2)
        return false;

    bool is_legal = true;

    //! define lambda s for real work
    std::function<Iter(Iter)> s = [&](Iter curr) -> Iter
    {
        if(curr >= last)
        {
            is_legal = false;
            return curr;
        }

        if(*curr == '0'  && *(curr + 1) =='1')
            return curr + 2;
        else if(*curr == '0')
        {
            Iter tail = s(curr + 1);
            is_legal =  *tail == '1';
            return tail + 1;
        }
        else
        {
            is_legal = false;
            return last;
        }
    };

    //! call lambda and return
    s(first);
    return is_legal;
}
}}//namespace

int main()
{
    std::cout << "pls enter, using grammar : S -> 0S1 | 01\n";

    for(std::string buff; std::cin >> buff; /* */)
    {
        bool is_legal = dragon::ch2::parse_241c(buff.begin(),buff.end());
        std::cout << "@parser ex2.4.1.c --> "
                  << (is_legal?     "legal\n"     :   "syntax error\n");
    }

    return 0;
}
<commit_msg>add range checking and fix bug 	modified:   ex2_4_1c.cpp         note : s(first) == last must be checked.<commit_after>//!
//! @author     Yue Wang
//! @date       19 Sep 2014
//!
//! ex2.4.1.c
//! parse
//!         S -> 0S1 | 01
//!
//! sample inputs : 01  0011    000111  00001111, etc
//!

#include <iostream>
#include <string>
#include <functional>

namespace dragon {namespace ch2 {

/**
 * @brief parse_241c
 * @param first
 * @param last
 * @return  true if legal, false otherwise.
 *
 * @complexity  O(n)
 */
template<typename Iter>
bool parse_241c(Iter first, Iter last)
{
    //! ensure "01" can be dereferenced safely
  //    if(last - first < 2)
  //      return false;

    bool is_legal = true;

    //! define lambda s for real work
    std::function<Iter(Iter)> s = [&](Iter curr) -> Iter
    {
        if(last - curr < 2)
        {
            is_legal = false;
            return curr;
        }

        if(*curr == '0'  && *(curr + 1) =='1')
            return curr + 2;
        else if(*curr == '0')
        {
            Iter tail = s(curr + 1);
            is_legal =  *tail == '1';
            return tail + 1;
        }
        else
        {
            is_legal = false;
            return last;
        }
    };

    //! call lambda s
    return s(first) == last     &&  is_legal;
}
}}//namespace

int main()
{
    std::cout << "pls enter, using grammar : S -> 0S1 | 01\n";

    for(std::string buff; std::cin >> buff; /* */)
    {
        bool is_legal = dragon::ch2::parse_241c(buff.begin(),buff.end());
        std::cout << "@parser ex2.4.1.c --> "
                  << (is_legal?     "legal\n"     :   "syntax error\n");
    }

    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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.
 */

#include "src/android_internal/incident_service.h"

#include <android/os/IIncidentManager.h>
#include <android/os/IncidentReportArgs.h>
#include <binder/IBinder.h>
#include <binder/IServiceManager.h>
#include <binder/Status.h>
#include <stddef.h>
#include <stdint.h>

#include <string>

namespace perfetto {
namespace android_internal {

bool StartIncidentReport(const char* dest_pkg,
                         const char* dest_class,
                         int privacy_level) {
  android::os::IncidentReportArgs incidentReport;
  incidentReport.addSection(3026);  // system_trace only

  if (privacy_level != android::os::PRIVACY_POLICY_AUTOMATIC &&
      privacy_level != android::os::PRIVACY_POLICY_EXPLICIT) {
    return false;
  }
  incidentReport.setPrivacyPolicy(privacy_level);

  std::string pkg(dest_pkg);
  std::string cls(dest_class);
  if (pkg.size() == 0 || cls.size() == 0) {
    return false;
  }
  incidentReport.setReceiverPkg(pkg);
  incidentReport.setReceiverCls(cls);

  android::sp<android::os::IIncidentManager> service =
      android::interface_cast<android::os::IIncidentManager>(
          android::defaultServiceManager()->getService(
              android::String16("incident")));

  if (!service) {
    return false;
  }
  android::binder::Status s = service->reportIncident(incidentReport);
  return s.isOk();
}

}  // namespace android_internal
}  // namespace perfetto
<commit_msg>Update perfetto to use the new stable C API for libincident<commit_after>/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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.
 */

#include "src/android_internal/incident_service.h"

#include <binder/IBinder.h>
#include <binder/IServiceManager.h>
#include <binder/Status.h>
#include <incident/incident_report.h>
#include <stddef.h>
#include <stdint.h>

#include <string>

namespace perfetto {
namespace android_internal {

bool StartIncidentReport(const char* dest_pkg,
                         const char* dest_class,
                         int privacy_level) {
  android::os::IncidentReportRequest incidentReport;
  incidentReport.addSection(3026);  // system_trace only

  if (privacy_level != INCIDENT_REPORT_PRIVACY_POLICY_AUTOMATIC &&
      privacy_level != INCIDENT_REPORT_PRIVACY_POLICY_EXPLICIT) {
    return false;
  }
  incidentReport.setPrivacyPolicy(privacy_level);

  std::string pkg(dest_pkg);
  std::string cls(dest_class);
  if (pkg.size() == 0 || cls.size() == 0) {
    return false;
  }
  incidentReport.setReceiverPackage(pkg);
  incidentReport.setReceiverClass(cls);

  return incidentReport.takeReport() == 0;
}

}  // namespace android_internal
}  // namespace perfetto
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: list.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 20:04:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef __LISTEN_123456__
#define __LISTEN_123456__

#include <string.h>
#include <iostream>
#include <stdlib.h>

template <class XX>
class List
{
  public :
    typedef XX *        iterator;
    typedef const XX *  const_iterator;

    // LIFECYCLE
                        List();
    virtual             ~List() { }

    // OPERATORS
    const XX &          operator[](
                            unsigned            n) const
                                                { return elem(n); }
    XX &                operator[](
                            unsigned            n)
                                                { return elem(n); }
    // OPERATIONS
    void                reserve(
                            unsigned            i_nSize )
                                                { alloc(i_nSize,true); }
    virtual void        insert(
                            unsigned            pos,
                            const XX &          elem );
    void                push_back(
                            const XX &          elem_)
                                                { insert(size(),elem_); }

    virtual void        remove(
                            unsigned            pos );
    void                pop_back()              { remove(size()-1); }
    void                erase_all()             { while (size()) remove(size()-1); }

    // INQUIRY
    const XX &          front() const           { return elem(0); }
    const XX &          back() const            { return elem(len-1); }

    unsigned            size() const            { return len; }
    unsigned            space() const           { return allocated; }
    bool                is_valid_index(
                            unsigned            n) const
                                                { return n < len; }
    // ACCESS
    XX &                front()                 { return elem(0); }
    XX &                back()                  { return elem(len-1); }

  protected:
    void                checkSize(
                            unsigned            newLength);
    void                alloc(
                            unsigned            newSpace,
                            bool                re = false );

    const XX &          elem(
                            unsigned            n ) const
                                                { return inhalt[n]; }
    XX &                elem(
                            unsigned            n )
                                                { return inhalt[n]; }
  // DATA
    XX *                inhalt;
    unsigned            len;
    unsigned            allocated;

  private:
    // forbidden functions
                        List(const List<XX> & L);
    List<XX> &          operator=(
                            const List<XX> &    L);

};

template <class XY>
class DynamicList : public List<XY*>
{
  public:
    virtual             ~DynamicList();

    virtual void        insert(
                            unsigned            pos,
                            XY * const &        elem );
    virtual void        remove(
                            unsigned            pos );
};

template <class XX>
List<XX>::List()
    :   inhalt(0),
        len(0),
        allocated(0)

{
    alloc(1);
}

template <class XX>
void
List<XX>::insert(unsigned pos, const XX & elem_)
{
    if ( pos > len )
      return;

    checkSize(len+2);
    for ( unsigned p = len; p > pos; --p)
    {
        inhalt[p] = inhalt[p-1];
    }
    inhalt[pos] = elem_;
    len++;
}

template <class XX>
void
List<XX>::remove(unsigned pos)
{
    if ( pos >= len )
      return;
    len--;
    for ( unsigned p = pos; p < len; ++p)
    {
        inhalt[p] = inhalt[p+1];
    }
}

// Protected:
template <class XX>
void
List<XX>::checkSize(unsigned newLength)
{
   // neuen Platzbedarf pruefen:
   unsigned newSpace = space();
   if (newLength > newSpace)
   {
      if (!newSpace)
         newSpace = 1;
      const unsigned nBorder = 65536 / 2;
      while(newLength > newSpace)
      {
        if (newSpace < nBorder)
            newSpace <<= 1;
        else
        {
            std::cerr << "List becomes too big" << std::endl;
            exit(1);
        }
      }
   }

   // Veraenderung ?:
   if (newSpace != space())
      alloc(newSpace,true);
}

template <class XX>
void
List<XX>::alloc( unsigned           newSpace,
                 bool               re )
{
    XX * pNew = new XX[newSpace];

    if (inhalt != 0)
    {
        if (re)
        {
            for (unsigned i = 0; i < len; ++i)
            {
                pNew[i] = inhalt[i];
            }  // end for
        }
        delete [] inhalt;
    }

    inhalt = pNew;
    allocated = newSpace;
}

template <class XY>
DynamicList<XY>::~DynamicList()
{
    this->erase_all();
}

template <class XY>
void
DynamicList<XY>::insert(unsigned pos, XY * const & elem_)
{
    if ( pos > this->len )
      return;

    checkSize(this->len+2);
    memmove(this->inhalt[pos+1], this->inhalt[pos], (this->len-pos) * sizeof(XY*) );
    this->inhalt[pos] = elem_;
    this->len++;
}

template <class XY>
void
DynamicList<XY>::remove( unsigned           pos )
{
    if (!this->is_valid_index(pos) )
        return;
    this->len--;
    delete this->inhalt[pos];
    memmove(this->inhalt[pos], this->inhalt[pos+1], (this->len-pos) * sizeof(XY*) );
}

#endif

<commit_msg>INTEGRATION: CWS mh23 (1.9.20); FILE MERGED 2007/07/12 13:01:45 mh 1.9.20.1: xml2cmp: the List allocs but never deletes it, #i79210#<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: list.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: obo $ $Date: 2007-07-18 15:03:29 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef __LISTEN_123456__
#define __LISTEN_123456__

#include <string.h>
#include <iostream>
#include <stdlib.h>

template <class XX>
class List
{
  public :
    typedef XX *        iterator;
    typedef const XX *  const_iterator;

    // LIFECYCLE
                        List();
    virtual             ~List() { delete [] inhalt; }

    // OPERATORS
    const XX &          operator[](
                            unsigned            n) const
                                                { return elem(n); }
    XX &                operator[](
                            unsigned            n)
                                                { return elem(n); }
    // OPERATIONS
    void                reserve(
                            unsigned            i_nSize )
                                                { alloc(i_nSize,true); }
    virtual void        insert(
                            unsigned            pos,
                            const XX &          elem );
    void                push_back(
                            const XX &          elem_)
                                                { insert(size(),elem_); }

    virtual void        remove(
                            unsigned            pos );
    void                pop_back()              { remove(size()-1); }
    void                erase_all()             { while (size()) remove(size()-1); }

    // INQUIRY
    const XX &          front() const           { return elem(0); }
    const XX &          back() const            { return elem(len-1); }

    unsigned            size() const            { return len; }
    unsigned            space() const           { return allocated; }
    bool                is_valid_index(
                            unsigned            n) const
                                                { return n < len; }
    // ACCESS
    XX &                front()                 { return elem(0); }
    XX &                back()                  { return elem(len-1); }

  protected:
    void                checkSize(
                            unsigned            newLength);
    void                alloc(
                            unsigned            newSpace,
                            bool                re = false );

    const XX &          elem(
                            unsigned            n ) const
                                                { return inhalt[n]; }
    XX &                elem(
                            unsigned            n )
                                                { return inhalt[n]; }
  // DATA
    XX *                inhalt;
    unsigned            len;
    unsigned            allocated;

  private:
    // forbidden functions
                        List(const List<XX> & L);
    List<XX> &          operator=(
                            const List<XX> &    L);

};

template <class XY>
class DynamicList : public List<XY*>
{
  public:
    virtual             ~DynamicList();

    virtual void        insert(
                            unsigned            pos,
                            XY * const &        elem );
    virtual void        remove(
                            unsigned            pos );
};

template <class XX>
List<XX>::List()
    :   inhalt(0),
        len(0),
        allocated(0)

{
    alloc(1);
}

template <class XX>
void
List<XX>::insert(unsigned pos, const XX & elem_)
{
    if ( pos > len )
      return;

    checkSize(len+2);
    for ( unsigned p = len; p > pos; --p)
    {
        inhalt[p] = inhalt[p-1];
    }
    inhalt[pos] = elem_;
    len++;
}

template <class XX>
void
List<XX>::remove(unsigned pos)
{
    if ( pos >= len )
      return;
    len--;
    for ( unsigned p = pos; p < len; ++p)
    {
        inhalt[p] = inhalt[p+1];
    }
}

// Protected:
template <class XX>
void
List<XX>::checkSize(unsigned newLength)
{
   // neuen Platzbedarf pruefen:
   unsigned newSpace = space();
   if (newLength > newSpace)
   {
      if (!newSpace)
         newSpace = 1;
      const unsigned nBorder = 65536 / 2;
      while(newLength > newSpace)
      {
        if (newSpace < nBorder)
            newSpace <<= 1;
        else
        {
            std::cerr << "List becomes too big" << std::endl;
            exit(1);
        }
      }
   }

   // Veraenderung ?:
   if (newSpace != space())
      alloc(newSpace,true);
}

template <class XX>
void
List<XX>::alloc( unsigned           newSpace,
                 bool               re )
{
    XX * pNew = new XX[newSpace];

    if (inhalt != 0)
    {
        if (re)
        {
            for (unsigned i = 0; i < len; ++i)
            {
                pNew[i] = inhalt[i];
            }  // end for
        }
        delete [] inhalt;
    }

    inhalt = pNew;
    allocated = newSpace;
}

template <class XY>
DynamicList<XY>::~DynamicList()
{
    this->erase_all();
}

template <class XY>
void
DynamicList<XY>::insert(unsigned pos, XY * const & elem_)
{
    if ( pos > this->len )
      return;

    checkSize(this->len+2);
    memmove(this->inhalt[pos+1], this->inhalt[pos], (this->len-pos) * sizeof(XY*) );
    this->inhalt[pos] = elem_;
    this->len++;
}

template <class XY>
void
DynamicList<XY>::remove( unsigned           pos )
{
    if (!this->is_valid_index(pos) )
        return;
    this->len--;
    delete this->inhalt[pos];
    memmove(this->inhalt[pos], this->inhalt[pos+1], (this->len-pos) * sizeof(XY*) );
}

#endif

<|endoftext|>


<commit_before>/**
 * Created by Jian Chen
 * @since  2015.07.29
 * @author Jian Chen <admin@chensoft.com>
 * @link   http://chensoft.com
 */
#include "str.hpp"
#include <functional>
#include <cstdarg>

using namespace chen;

// -----------------------------------------------------------------------------
// str
std::string str::format(const char *fmt, ...)
{
    va_list v1, v2;

    va_start(v1, fmt);
    va_copy(v2, v1);

    auto len = std::vsnprintf(nullptr, 0, fmt, v1);
    if (len <= 0)
        return "";

    std::string ret(len + 1, '\0');
    std::vsnprintf(&ret[0], ret.size(), fmt, v2);

    va_end(v1);
    va_end(v2);

    return ret;
}

bool str::equal(const char *str1, std::size_t size1,
                const char *str2, std::size_t size2)
{
    if (size1 != size2)
        return false;

    for (std::size_t i = 0; i < size1; ++i)
    {
        if (str1[i] != str2[i])
            return false;
    }

    return true;
}

// trim
void str::trim(std::string &text)
{
    str::ltrim(text);
    str::rtrim(text);
}

void str::ltrim(std::string &text)
{
    text.erase(text.begin(), std::find_if(text.begin(), text.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
}

void str::rtrim(std::string &text)
{
    text.erase(std::find_if(text.rbegin(), text.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), text.end());
}

// levenshtein
std::size_t str::levenshtein(const char *s, std::size_t len_s, const char *t, std::size_t len_t)
{
    // copy from https://en.wikipedia.org/wiki/Levenshtein_distance
    std::size_t cost = 0;

    /* base case: empty strings */
    if (len_s == 0)
        return len_t;

    if (len_t == 0)
        return len_s;

    /* test if last characters of the strings match */
    if (s[len_s-1] == t[len_t-1])
        cost = 0;
    else
        cost = 1;

    /* return minimum of delete char from s, delete char from t, and delete char from both */
    return std::min({str::levenshtein(s, len_s - 1, t, len_t    ) + 1,
                     str::levenshtein(s, len_s    , t, len_t - 1) + 1,
                     str::levenshtein(s, len_s - 1, t, len_t - 1) + cost});
}<commit_msg>str: remove the redundant zero char<commit_after>/**
 * Created by Jian Chen
 * @since  2015.07.29
 * @author Jian Chen <admin@chensoft.com>
 * @link   http://chensoft.com
 */
#include "str.hpp"
#include <functional>
#include <cstdarg>

using namespace chen;

// -----------------------------------------------------------------------------
// str
std::string str::format(const char *fmt, ...)
{
    va_list v1, v2;

    va_start(v1, fmt);
    va_copy(v2, v1);

    auto len = std::vsnprintf(nullptr, 0, fmt, v1);
    if (len <= 0)
        return "";

    std::string ret(len + 1, '\0');
    std::vsnprintf(&ret[0], ret.size(), fmt, v2);
    ret.erase(ret.begin() + len);  // remove the redundant '\0'

    va_end(v1);
    va_end(v2);

    return ret;
}

bool str::equal(const char *str1, std::size_t size1,
                const char *str2, std::size_t size2)
{
    if (size1 != size2)
        return false;

    for (std::size_t i = 0; i < size1; ++i)
    {
        if (str1[i] != str2[i])
            return false;
    }

    return true;
}

// trim
void str::trim(std::string &text)
{
    str::ltrim(text);
    str::rtrim(text);
}

void str::ltrim(std::string &text)
{
    text.erase(text.begin(), std::find_if(text.begin(), text.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
}

void str::rtrim(std::string &text)
{
    text.erase(std::find_if(text.rbegin(), text.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), text.end());
}

// levenshtein
std::size_t str::levenshtein(const char *s, std::size_t len_s, const char *t, std::size_t len_t)
{
    // copy from https://en.wikipedia.org/wiki/Levenshtein_distance
    std::size_t cost = 0;

    /* base case: empty strings */
    if (len_s == 0)
        return len_t;

    if (len_t == 0)
        return len_s;

    /* test if last characters of the strings match */
    if (s[len_s-1] == t[len_t-1])
        cost = 0;
    else
        cost = 1;

    /* return minimum of delete char from s, delete char from t, and delete char from both */
    return std::min({str::levenshtein(s, len_s - 1, t, len_t    ) + 1,
                     str::levenshtein(s, len_s    , t, len_t - 1) + 1,
                     str::levenshtein(s, len_s - 1, t, len_t - 1) + cost});
}<|endoftext|>


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

#ifndef _XMLOFF_XIMPSHOW_HXX
#define _XMLOFF_XIMPSHOW_HXX

#ifndef _XMLOFF_XMLICTXT_HXX
#include "xmlictxt.hxx"
#endif

#ifndef _SDXMLIMP_IMPL_HXX
#include "sdxmlimp_impl.hxx"
#endif

class ShowsImpImpl;

//////////////////////////////////////////////////////////////////////////////
// presentations:animations

class SdXMLShowsContext : public SvXMLImportContext
{
    ShowsImpImpl*   mpImpl;

public:
    TYPEINFO();

    SdXMLShowsContext( SdXMLImport& rImport,
        sal_uInt16 nPrfx,
        const rtl::OUString& rLocalName,
        const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList);
    virtual ~SdXMLShowsContext();

    virtual SvXMLImportContext * CreateChildContext( USHORT nPrefix, const ::rtl::OUString& rLocalName,
        const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList );
};

#endif  //  _XMLOFF_XIMPSHOW_HXX

<commit_msg>INTEGRATION: CWS ooo19126 (1.1.646); FILE MERGED 2005/09/05 14:38:52 rt 1.1.646.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ximpshow.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 14:01:37 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLOFF_XIMPSHOW_HXX
#define _XMLOFF_XIMPSHOW_HXX

#ifndef _XMLOFF_XMLICTXT_HXX
#include "xmlictxt.hxx"
#endif

#ifndef _SDXMLIMP_IMPL_HXX
#include "sdxmlimp_impl.hxx"
#endif

class ShowsImpImpl;

//////////////////////////////////////////////////////////////////////////////
// presentations:animations

class SdXMLShowsContext : public SvXMLImportContext
{
    ShowsImpImpl*   mpImpl;

public:
    TYPEINFO();

    SdXMLShowsContext( SdXMLImport& rImport,
        sal_uInt16 nPrfx,
        const rtl::OUString& rLocalName,
        const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList);
    virtual ~SdXMLShowsContext();

    virtual SvXMLImportContext * CreateChildContext( USHORT nPrefix, const ::rtl::OUString& rLocalName,
        const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList );
};

#endif  //  _XMLOFF_XIMPSHOW_HXX

<|endoftext|>


<commit_before>
/*
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * ``The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is SimpleAmqpClient for RabbitMQ.
 *
 * The Initial Developer of the Original Code is Alan Antonuk.
 * Original code is Copyright (C) Alan Antonuk.
 *
 * All Rights Reserved.
 *
 * Contributor(s): ______________________________________.
 *
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU General Public License Version 2 or later (the "GPL"), in
 * which case the provisions of the GPL are applicable instead of those
 * above. If you wish to allow use of your version of this file only
 * under the terms of the GPL, and not to allow others to use your
 * version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the
 * notice and other provisions required by the GPL. If you do not
 * delete the provisions above, a recipient may use your version of
 * this file under the terms of any one of the MPL or the GPL.
 *
 * ***** END LICENSE BLOCK *****
 */

#include "Channel.h"

#include "Util.h"

#include <amqp_framing.h>

#include <stdexcept>

// This will get us the posix version of strerror_r() on linux
#define _XOPEN_SOURCE 600
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>

namespace AmqpClient {

const amqp_table_t Channel::EMPTY_TABLE = { 0, NULL };
const std::string Channel::EXCHANGE_TYPE_DIRECT("amq.direct");
const std::string Channel::EXCHANGE_TYPE_FANOUT("fanout");
const std::string Channel::EXCHANGE_TYPE_TOPIC("topic");

Channel::Channel(const std::string& host,
                 int port,
                 const std::string& username,
                 const std::string& password,
                 const std::string& vhost,
                 int frame_max) :
    m_channel(DEFAULT_CHANNEL)
{
    m_connection = amqp_new_connection();

    int sock = amqp_open_socket(host.c_str(), port);
    Util::CheckForError(sock, "Channel::Channel amqp_open_socket");

    amqp_set_sockfd(m_connection, sock);

    Util::CheckRpcReply(amqp_login(m_connection, vhost.c_str(), 2,
                                   frame_max, BROKER_HEARTBEAT, AMQP_SASL_METHOD_PLAIN,
                                   username.c_str(), password.c_str()), "Amqp Login");

    amqp_channel_open(m_connection, m_channel);
    Util::CheckLastRpcReply(m_connection, "Channel::Channel creating default channel");
}

Channel::~Channel()
{
    amqp_channel_close(m_connection, m_channel, AMQP_REPLY_SUCCESS);
    amqp_connection_close(m_connection, AMQP_REPLY_SUCCESS);
    amqp_destroy_connection(m_connection);
}

void Channel::DeclareExchange(const std::string& exchange_name,
                              const std::string& exchange_type,
                              bool passive,
                              bool durable,
                              bool auto_delete)
{
    amqp_exchange_declare(m_connection, m_channel,
                          amqp_cstring_bytes(exchange_name.c_str()),
                          amqp_cstring_bytes(exchange_type.c_str()),
                          passive,
                          durable,
                          auto_delete,
                          EMPTY_TABLE);
	Util::CheckLastRpcReply(m_connection, "Declaring exchange");
}

void Channel::DeleteExchange(const std::string& exchange_name,
                             bool if_unused,
                             bool nowait)
{
	amqp_method_number_t replies[2] = { AMQP_EXCHANGE_DELETE_OK_METHOD, 0 };
	amqp_exchange_delete_t req;
	req.exchange = amqp_cstring_bytes(exchange_name.c_str());
	req.if_unused = if_unused;
	req.nowait = nowait;

	Util::CheckRpcReply(amqp_simple_rpc(m_connection, m_channel,
				AMQP_EXCHANGE_DELETE_METHOD,
				replies, &req), "Delete Exchange");
}

std::string Channel::DeclareQueue(const std::string& queue_name,
          		                  bool passive,
								  bool durable,
								  bool exclusive,
								  bool auto_delete)
{

    amqp_queue_declare_ok_t* queue_declare =
			amqp_queue_declare(m_connection, m_channel,
								amqp_cstring_bytes(queue_name.c_str()),
								passive,
								durable,
								exclusive,
								auto_delete,
								EMPTY_TABLE);

	Util::CheckLastRpcReply(m_connection, "Declaring queue");

	return std::string((char*)queue_declare->queue.bytes,
			queue_declare->queue.len);
}

void Channel::DeleteQueue(const std::string& queue_name,
                          bool if_unused,
                          bool if_empty)
{
    amqp_queue_delete(m_connection, m_channel,
                      amqp_cstring_bytes(queue_name.c_str()),
                      if_unused,
                      if_empty);

	Util::CheckLastRpcReply(m_connection, "Deleting Queue");
}

void Channel::BindQueue(const std::string& queue_name,
                        const std::string& exchange_name,
                        const std::string& routing_key)
{
    amqp_queue_bind(m_connection, m_channel,
                    amqp_cstring_bytes(queue_name.c_str()),
                    amqp_cstring_bytes(exchange_name.c_str()),
                    amqp_cstring_bytes(routing_key.c_str()),
                    EMPTY_TABLE);

	Util::CheckLastRpcReply(m_connection, "Binding queue");
}

void Channel::UnbindQueue(const std::string& queue_name,
                          const std::string& exchange_name,
                          const std::string& binding_key)
{
    amqp_queue_unbind(m_connection, m_channel,
                      amqp_cstring_bytes(queue_name.c_str()),
                      amqp_cstring_bytes(exchange_name.c_str()),
                      amqp_cstring_bytes(binding_key.c_str()),
                      EMPTY_TABLE);

	Util::CheckLastRpcReply(m_connection, "Unbinding queue");
}

void Channel::BasicAck(const BasicMessage::ptr_t message)
{
	BasicAck(message->DeliveryTag());
}

void Channel::BasicAck(uint64_t delivery_tag)
{
	Util::CheckForError(amqp_basic_ack(m_connection, m_channel,
			delivery_tag,
			false), "Ack");

}
void Channel::BasicPublish(const std::string& exchange_name,
                           const std::string& routing_key,
                           const BasicMessage::ptr_t message,
                           bool mandatory,
                           bool immediate)
{
    amqp_basic_publish(m_connection, m_channel,
                       amqp_cstring_bytes(exchange_name.c_str()),
                       amqp_cstring_bytes(routing_key.c_str()),
                       mandatory,
                       immediate,
                       message->getAmqpProperties(),
                       message->getAmqpBody());

	Util::CheckLastRpcReply(m_connection, "Publishing to queue");
}

void Channel::BasicConsume(const std::string& queue,
						   const std::string& consumer_tag,
						   bool no_local,
						   bool no_ack,
						   bool exclusive)
{
	amqp_basic_consume(m_connection, m_channel,
			amqp_cstring_bytes(queue.c_str()),
			amqp_cstring_bytes(consumer_tag.c_str()),
			no_local,
			no_ack,
			exclusive);

	Util::CheckLastRpcReply(m_connection, "Basic Consume");
}

void Channel::BasicCancel(const std::string& consumer_tag)
{
	amqp_method_number_t replies[2] = { AMQP_BASIC_CANCEL_OK_METHOD, 0 };
	amqp_basic_cancel_t req;
	req.consumer_tag = amqp_cstring_bytes(consumer_tag.c_str());
	req.nowait = 0;

	Util::CheckRpcReply(amqp_simple_rpc(m_connection, m_channel,
				AMQP_BASIC_CANCEL_METHOD,
				replies, &req), "Basic Cancel");
}

BasicMessage::ptr_t Channel::BasicConsumeMessage()
{
	BasicMessage::ptr_t returnval;
	BasicConsumeMessage(returnval, 0);
	return returnval;
}

bool Channel::BasicConsumeMessage(BasicMessage::ptr_t& message, int timeout)
{

	int socketno = amqp_get_sockfd(m_connection);

	struct timeval tv_timeout;
	memset(&tv_timeout, 0, sizeof(tv_timeout));
	tv_timeout.tv_sec = timeout;

	struct timeval tv_zero;
	memset(&tv_zero, 0, sizeof(tv_zero));
	tv_zero.tv_sec = 0;

	while (true)
	{
		amqp_frame_t frame;
		amqp_maybe_release_buffers(m_connection);

		// Possibly set a timeout on receiving
		// We only do this on the first frame otherwise we'd confuse
		// This function if it immediately turns around and gets called again
		if (timeout > 0)
		{
			if (setsockopt(socketno, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv_timeout, sizeof(tv_timeout)))
			{
				const int BUFFER_LENGTH = 256;
				char error_string_buffer[BUFFER_LENGTH] = {0};
				strerror_r(errno, error_string_buffer, BUFFER_LENGTH);

				std::string error_string = "Setting socket timeout failed (setsockopt) ";
				error_string += error_string_buffer;

				throw std::runtime_error(error_string.c_str());
			}
		}

		int ret = amqp_simple_wait_frame(m_connection, &frame);
		// Save errno as it might be overwritten by setsockopt
		int errno_save = errno;

		setsockopt(socketno, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv_zero, sizeof(tv_zero));

		if (ret != 0 && (errno_save == EAGAIN || errno_save == EWOULDBLOCK))
		{
			return false;
		}

		Util::CheckForError(ret, "Consume Message: method frame");

		if (frame.frame_type != AMQP_FRAME_METHOD || frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD)
			continue;

		amqp_basic_deliver_t* deliver_method = reinterpret_cast<amqp_basic_deliver_t*>(frame.payload.method.decoded);

		// Wait for frame #2, the header frame which contains body size
		Util::CheckForError(amqp_simple_wait_frame(m_connection, &frame), "Consume Message: header frame");

		if (frame.frame_type != AMQP_FRAME_HEADER)
			throw std::runtime_error("Channel::BasicConsumeMessage: receieved unexpected frame type (was expected AMQP_FRAME_HEADER)");

		amqp_basic_properties_t* properties = reinterpret_cast<amqp_basic_properties_t*>(frame.payload.properties.decoded);

		size_t body_size = frame.payload.properties.body_size;
		size_t received_size = 0;
		amqp_bytes_t body = amqp_bytes_malloc(body_size);

		// frame #3 and up:
		while (received_size < body_size)
		{
			Util::CheckForError(amqp_simple_wait_frame(m_connection, &frame), "Consume Message: body frame");

			if (frame.frame_type != AMQP_FRAME_BODY)
				throw std::runtime_error("Channel::BasicConsumeMessge: received unexpected frame type (was expecting AMQP_FRAME_BODY)");

			void* body_ptr = reinterpret_cast<char*>(body.bytes) + received_size;
			memcpy(body_ptr, frame.payload.body_fragment.bytes, frame.payload.body_fragment.len);
			received_size += frame.payload.body_fragment.len;
		}

		message = BasicMessage::Create(body, properties, deliver_method->delivery_tag);
		return true;
	}
}

} // namespace AmqpClient
<commit_msg>Adding BasicConsume with Timeout to SimpleAmqpClient<commit_after>
/*
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * ``The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is SimpleAmqpClient for RabbitMQ.
 *
 * The Initial Developer of the Original Code is Alan Antonuk.
 * Original code is Copyright (C) Alan Antonuk.
 *
 * All Rights Reserved.
 *
 * Contributor(s): ______________________________________.
 *
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU General Public License Version 2 or later (the "GPL"), in
 * which case the provisions of the GPL are applicable instead of those
 * above. If you wish to allow use of your version of this file only
 * under the terms of the GPL, and not to allow others to use your
 * version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the
 * notice and other provisions required by the GPL. If you do not
 * delete the provisions above, a recipient may use your version of
 * this file under the terms of any one of the MPL or the GPL.
 *
 * ***** END LICENSE BLOCK *****
 */

#include "Channel.h"

#include "Util.h"

#include <amqp_framing.h>

#include <stdexcept>

// This will get us the posix version of strerror_r() on linux
#define _XOPEN_SOURCE 600
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>

namespace AmqpClient {

const amqp_table_t Channel::EMPTY_TABLE = { 0, NULL };
const std::string Channel::EXCHANGE_TYPE_DIRECT("amq.direct");
const std::string Channel::EXCHANGE_TYPE_FANOUT("fanout");
const std::string Channel::EXCHANGE_TYPE_TOPIC("topic");

Channel::Channel(const std::string& host,
                 int port,
                 const std::string& username,
                 const std::string& password,
                 const std::string& vhost,
                 int frame_max) :
    m_channel(DEFAULT_CHANNEL)
{
    m_connection = amqp_new_connection();

    int sock = amqp_open_socket(host.c_str(), port);
    Util::CheckForError(sock, "Channel::Channel amqp_open_socket");

    amqp_set_sockfd(m_connection, sock);

    Util::CheckRpcReply(amqp_login(m_connection, vhost.c_str(), 2,
                                   frame_max, BROKER_HEARTBEAT, AMQP_SASL_METHOD_PLAIN,
                                   username.c_str(), password.c_str()), "Amqp Login");

    amqp_channel_open(m_connection, m_channel);
    Util::CheckLastRpcReply(m_connection, "Channel::Channel creating default channel");
}

Channel::~Channel()
{
    amqp_channel_close(m_connection, m_channel, AMQP_REPLY_SUCCESS);
    amqp_connection_close(m_connection, AMQP_REPLY_SUCCESS);
    amqp_destroy_connection(m_connection);
}

void Channel::DeclareExchange(const std::string& exchange_name,
                              const std::string& exchange_type,
                              bool passive,
                              bool durable,
                              bool auto_delete)
{
    amqp_exchange_declare(m_connection, m_channel,
                          amqp_cstring_bytes(exchange_name.c_str()),
                          amqp_cstring_bytes(exchange_type.c_str()),
                          passive,
                          durable,
                          auto_delete,
                          EMPTY_TABLE);
	Util::CheckLastRpcReply(m_connection, "Declaring exchange");
}

void Channel::DeleteExchange(const std::string& exchange_name,
                             bool if_unused,
                             bool nowait)
{
	amqp_method_number_t replies[2] = { AMQP_EXCHANGE_DELETE_OK_METHOD, 0 };
	amqp_exchange_delete_t req;
	req.exchange = amqp_cstring_bytes(exchange_name.c_str());
	req.if_unused = if_unused;
	req.nowait = nowait;

	Util::CheckRpcReply(amqp_simple_rpc(m_connection, m_channel,
				AMQP_EXCHANGE_DELETE_METHOD,
				replies, &req), "Delete Exchange");
}

std::string Channel::DeclareQueue(const std::string& queue_name,
          		                  bool passive,
								  bool durable,
								  bool exclusive,
								  bool auto_delete)
{

    amqp_queue_declare_ok_t* queue_declare =
			amqp_queue_declare(m_connection, m_channel,
								amqp_cstring_bytes(queue_name.c_str()),
								passive,
								durable,
								exclusive,
								auto_delete,
								EMPTY_TABLE);

	Util::CheckLastRpcReply(m_connection, "Declaring queue");

	return std::string((char*)queue_declare->queue.bytes,
			queue_declare->queue.len);
}

void Channel::DeleteQueue(const std::string& queue_name,
                          bool if_unused,
                          bool if_empty)
{
    amqp_queue_delete(m_connection, m_channel,
                      amqp_cstring_bytes(queue_name.c_str()),
                      if_unused,
                      if_empty);

	Util::CheckLastRpcReply(m_connection, "Deleting Queue");
}

void Channel::BindQueue(const std::string& queue_name,
                        const std::string& exchange_name,
                        const std::string& routing_key)
{
    amqp_queue_bind(m_connection, m_channel,
                    amqp_cstring_bytes(queue_name.c_str()),
                    amqp_cstring_bytes(exchange_name.c_str()),
                    amqp_cstring_bytes(routing_key.c_str()),
                    EMPTY_TABLE);

	Util::CheckLastRpcReply(m_connection, "Binding queue");
}

void Channel::UnbindQueue(const std::string& queue_name,
                          const std::string& exchange_name,
                          const std::string& binding_key)
{
    amqp_queue_unbind(m_connection, m_channel,
                      amqp_cstring_bytes(queue_name.c_str()),
                      amqp_cstring_bytes(exchange_name.c_str()),
                      amqp_cstring_bytes(binding_key.c_str()),
                      EMPTY_TABLE);

	Util::CheckLastRpcReply(m_connection, "Unbinding queue");
}

void Channel::BasicAck(const BasicMessage::ptr_t message)
{
	BasicAck(message->DeliveryTag());
}

void Channel::BasicAck(uint64_t delivery_tag)
{
	Util::CheckForError(amqp_basic_ack(m_connection, m_channel,
			delivery_tag,
			false), "Ack");

}
void Channel::BasicPublish(const std::string& exchange_name,
                           const std::string& routing_key,
                           const BasicMessage::ptr_t message,
                           bool mandatory,
                           bool immediate)
{
    amqp_basic_publish(m_connection, m_channel,
                       amqp_cstring_bytes(exchange_name.c_str()),
                       amqp_cstring_bytes(routing_key.c_str()),
                       mandatory,
                       immediate,
                       message->getAmqpProperties(),
                       message->getAmqpBody());

	Util::CheckLastRpcReply(m_connection, "Publishing to queue");
}

void Channel::BasicConsume(const std::string& queue,
						   const std::string& consumer_tag,
						   bool no_local,
						   bool no_ack,
						   bool exclusive)
{
	amqp_basic_consume(m_connection, m_channel,
			amqp_cstring_bytes(queue.c_str()),
			amqp_cstring_bytes(consumer_tag.c_str()),
			no_local,
			no_ack,
			exclusive);

	Util::CheckLastRpcReply(m_connection, "Basic Consume");
}

void Channel::BasicCancel(const std::string& consumer_tag)
{
	amqp_method_number_t replies[2] = { AMQP_BASIC_CANCEL_OK_METHOD, 0 };
	amqp_basic_cancel_t req;
	req.consumer_tag = amqp_cstring_bytes(consumer_tag.c_str());
	req.nowait = 0;

	Util::CheckRpcReply(amqp_simple_rpc(m_connection, m_channel,
				AMQP_BASIC_CANCEL_METHOD,
				replies, &req), "Basic Cancel");
}

BasicMessage::ptr_t Channel::BasicConsumeMessage()
{
	BasicMessage::ptr_t returnval;
	BasicConsumeMessage(returnval, 0);
	return returnval;
}

bool Channel::BasicConsumeMessage(BasicMessage::ptr_t& message, int timeout)
{

	int socketno = amqp_get_sockfd(m_connection);

	struct timeval tv_timeout;
	memset(&tv_timeout, 0, sizeof(tv_timeout));
	tv_timeout.tv_sec = timeout;

	struct timeval tv_zero;
	memset(&tv_zero, 0, sizeof(tv_zero));
	tv_zero.tv_sec = 0;

	while (true)
	{
		amqp_frame_t frame;
		amqp_maybe_release_buffers(m_connection);

		// Possibly set a timeout on receiving
		// We only do this on the first frame otherwise we'd confuse
		// This function if it immediately turns around and gets called again
		if (timeout > 0)
		{
			if (setsockopt(socketno, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv_timeout, sizeof(tv_timeout)))
			{
				const int BUFFER_LENGTH = 256;
				char error_string_buffer[BUFFER_LENGTH] = {0};
				strerror_r(errno, error_string_buffer, BUFFER_LENGTH);

				std::string error_string = "Setting socket timeout failed (setsockopt) ";
				error_string += error_string_buffer;

				throw std::runtime_error(error_string.c_str());
			}
		}

		int ret = amqp_simple_wait_frame(m_connection, &frame);
		// Save errno as it might be overwritten by setsockopt
		int errno_save = errno;

		setsockopt(socketno, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv_zero, sizeof(tv_zero));

		if (ret != 0)
		{
			// Interrupted system call, just loop around and try it again
			if (errno_save == EINTR)
			{
				continue;
			}
			else if (errno_save == EAGAIN || errno_save == EWOULDBLOCK)
			{
				return false;
			}
		}

		Util::CheckForError(ret, "Consume Message: method frame");

		if (frame.frame_type != AMQP_FRAME_METHOD || frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD)
			continue;

		amqp_basic_deliver_t* deliver_method = reinterpret_cast<amqp_basic_deliver_t*>(frame.payload.method.decoded);

		// Wait for frame #2, the header frame which contains body size
		Util::CheckForError(amqp_simple_wait_frame(m_connection, &frame), "Consume Message: header frame");

		if (frame.frame_type != AMQP_FRAME_HEADER)
			throw std::runtime_error("Channel::BasicConsumeMessage: receieved unexpected frame type (was expected AMQP_FRAME_HEADER)");

		amqp_basic_properties_t* properties = reinterpret_cast<amqp_basic_properties_t*>(frame.payload.properties.decoded);

		size_t body_size = frame.payload.properties.body_size;
		size_t received_size = 0;
		amqp_bytes_t body = amqp_bytes_malloc(body_size);

		// frame #3 and up:
		while (received_size < body_size)
		{
			Util::CheckForError(amqp_simple_wait_frame(m_connection, &frame), "Consume Message: body frame");

			if (frame.frame_type != AMQP_FRAME_BODY)
				throw std::runtime_error("Channel::BasicConsumeMessge: received unexpected frame type (was expecting AMQP_FRAME_BODY)");

			void* body_ptr = reinterpret_cast<char*>(body.bytes) + received_size;
			memcpy(body_ptr, frame.payload.body_fragment.bytes, frame.payload.body_fragment.len);
			received_size += frame.payload.body_fragment.len;
		}

		message = BasicMessage::Create(body, properties, deliver_method->delivery_tag);
		return true;
	}
}

} // namespace AmqpClient
<|endoftext|>


<commit_before><commit_msg>interview question, dist between nodes in bstree<commit_after><|endoftext|>


<commit_before>/*
  Test Simple Logger for Qt

  Mario Ban, 05.2015

*/

#include "task.h"
#include "simpleQtLogger.h"

#include <QTimer>
#include <QtDebug>

// -------------------------------------------------------------------------------------------------

Task::Task(QObject *parent)
  : QObject(parent)
{
  L_FUNC("");
  qDebug("Task::Task"); // TODO comment this
}

Task::~Task()
{
  L_FUNC("");
  qDebug("Task::~Task"); // TODO comment this
}

void Task::init()
{
  L_FUNC("");

  L_INFO("+++ test Logger");
  L_FATAL("L_FATAL");
  L_ERROR("L_ERROR");
  L_WARN("L_WARN");
  L_INFO("L_INFO");
  L_DEBUG("L_DEBUG");
  L_INFO("--- test Logger");

  L_INFO(QString()); // --> "?"
  L_INFO(" \n Trimmed \n\n"); // --> whitespace removed from start and end

  QString formattedOutput1 = "JSON output 1:\n"
    "{\n"
    "  \"firstName\": \"Mario\",\n"
    "  \"age\": 44\n"
    "}"
  ;
  L_INFO(formattedOutput1);

  QString formattedOutput2 = "{
  \"firstName\": \"Mario\",
  \"age\": 44
}";
  L_INFO(formattedOutput2.prepend("JSON output 2:
").replace("
", "\n"));

  QTimer::singleShot(100, this, SLOT(slotRun()));
  QTimer::singleShot(7000, this, SLOT(theEnd()));
}

void Task::theEnd()
{
  L_FUNC("");
  L_INFO("Bye bye");
  emit finished();
}

void Task::slotRun()
{
  L_FUNC("");

  L_INFO(QString("Calculate: 6! = %1").arg(factorial(6)));

  QTimer::singleShot(3000, this, SLOT(slotRun()));
}

unsigned int Task::factorial(unsigned int n) const
{
  L_FUNC(QString("n=%1").arg(n));

  if(n > 2) {
    return n * factorial(n-1);
  }
  return n;
}
<commit_msg>Log current thread-id<commit_after>/*
  Test Simple Logger for Qt

  Mario Ban, 05.2015

*/

#include "task.h"
#include "simpleQtLogger.h"

#include <QTimer>
#include <QThread>
#include <QtDebug>

// -------------------------------------------------------------------------------------------------

Task::Task(QObject *parent)
  : QObject(parent)
{
  L_FUNC("");
  qDebug("Task::Task"); // TODO comment this
}

Task::~Task()
{
  L_FUNC("");
  qDebug("Task::~Task"); // TODO comment this
}

void Task::init()
{
  L_FUNC("");

  L_INFO("+++ test Logger");
  L_FATAL("L_FATAL");
  L_ERROR("L_ERROR");
  L_WARN("L_WARN");
  L_INFO("L_INFO");
  L_DEBUG("L_DEBUG");
  L_INFO("--- test Logger");

  L_INFO(QString()); // --> "?"
  L_INFO(" \n Trimmed \n\n"); // --> whitespace removed from start and end
  L_INFO(QString("[%1]").arg((unsigned long int)QThread::currentThreadId(),8,16,QLatin1Char('0'))); // field-with just for 32bit

  QString formattedOutput1 = "JSON output 1:\n"
    "{\n"
    "  \"firstName\": \"Mario\",\n"
    "  \"age\": 44\n"
    "}"
  ;
  L_INFO(formattedOutput1);

  QString formattedOutput2 = "{
  \"firstName\": \"Mario\",
  \"age\": 44
}";
  L_INFO(formattedOutput2.prepend("JSON output 2:
").replace("
", "\n"));

  QTimer::singleShot(100, this, SLOT(slotRun()));
  QTimer::singleShot(7000, this, SLOT(theEnd()));
}

void Task::theEnd()
{
  L_FUNC("");
  L_INFO("Bye bye");
  emit finished();
}

void Task::slotRun()
{
  L_FUNC("");

  L_INFO(QString("Calculate: 6! = %1").arg(factorial(6)));

  QTimer::singleShot(3000, this, SLOT(slotRun()));
}

unsigned int Task::factorial(unsigned int n) const
{
  L_FUNC(QString("n=%1").arg(n));

  if(n > 2) {
    return n * factorial(n-1);
  }
  return n;
}
<|endoftext|>


<commit_before>/** @file
    @brief Implementation

    @date 2014

    @author
    Ryan Pavlik
    <ryan@sensics.com>
    <http://sensics.com>
*/

// Copyright 2014 Sensics, Inc.
//
// All rights reserved.
//
// (Final version intended to be licensed under
// the Apache License, Version 2.0)

// Internal Includes
#include <osvr/ClientKit/ContextC.h>
#include <osvr/ClientKit/InterfaceC.h>
#include <osvr/ClientKit/InterfaceCallbackC.h>

// Library/third-party includes
// - none

// Standard includes
#include <iostream>

void myTrackerCallback(void * /*userdata*/,
                       const OSVR_TimeValue * /*timestamp*/,
                       const OSVR_PoseReport *report) {
    std::cout << "Got report: Position = (" << report->pose.translation.data[0]
              << ", " << report->pose.translation.data[1] << ", "
              << report->pose.translation.data[2] << "), orientation = ("
              << osvrQuatGetW(&(report->pose.rotation)) << ", ("
              << osvrQuatGetX(&(report->pose.rotation)) << ", "
              << osvrQuatGetY(&(report->pose.rotation)) << ", "
              << osvrQuatGetZ(&(report->pose.rotation)) << ")" << std::endl;
}

int main() {
    OSVR_ClientContext ctx =
        osvrClientInit("org.opengoggles.exampleclients.TrackerCallback");

    OSVR_ClientInterface lefthand = NULL;
    // This is just one of the paths. You can also use:
    // /me/hands/right
    // /me/head
    osvrClientGetInterface(ctx, "/me/hands/left", &lefthand);

    // The coordinate system is right-handed, with X to the right, Y up, and Z near.
    osvrRegisterPoseCallback(lefthand, &myTrackerCallback, NULL);

    // Pretend that this is your application's mainloop.
    for (int i = 0; i < 1000000; ++i) {
        osvrClientUpdate(ctx);
    }

    osvrClientShutdown(ctx);
    std::cout << "Library shut down, exiting." << std::endl;
    return 0;
}
<commit_msg>Add coordinate system mention to the tracker example.<commit_after>/** @file
    @brief Implementation

    @date 2014

    @author
    Ryan Pavlik
    <ryan@sensics.com>
    <http://sensics.com>
*/

// Copyright 2014 Sensics, Inc.
//
// All rights reserved.
//
// (Final version intended to be licensed under
// the Apache License, Version 2.0)

// Internal Includes
#include <osvr/ClientKit/ContextC.h>
#include <osvr/ClientKit/InterfaceC.h>
#include <osvr/ClientKit/InterfaceCallbackC.h>

// Library/third-party includes
// - none

// Standard includes
#include <iostream>

void myTrackerCallback(void * /*userdata*/,
                       const OSVR_TimeValue * /*timestamp*/,
                       const OSVR_PoseReport *report) {
    std::cout << "Got report: Position = (" << report->pose.translation.data[0]
              << ", " << report->pose.translation.data[1] << ", "
              << report->pose.translation.data[2] << "), orientation = ("
              << osvrQuatGetW(&(report->pose.rotation)) << ", ("
              << osvrQuatGetX(&(report->pose.rotation)) << ", "
              << osvrQuatGetY(&(report->pose.rotation)) << ", "
              << osvrQuatGetZ(&(report->pose.rotation)) << ")" << std::endl;
}

int main() {
    OSVR_ClientContext ctx =
        osvrClientInit("org.opengoggles.exampleclients.TrackerCallback");

    OSVR_ClientInterface lefthand = NULL;
    // This is just one of the paths. You can also use:
    // /me/hands/right
    // /me/head
    osvrClientGetInterface(ctx, "/me/hands/left", &lefthand);

    // The coordinate system is right-handed, with X to the right, Y up, and Z
    // near.
    osvrRegisterPoseCallback(lefthand, &myTrackerCallback, NULL);

    // Pretend that this is your application's mainloop.
    for (int i = 0; i < 1000000; ++i) {
        osvrClientUpdate(ctx);
    }

    osvrClientShutdown(ctx);
    std::cout << "Library shut down, exiting." << std::endl;
    return 0;
}
<|endoftext|>


<commit_before>#ifndef _SDD_MEM_UNIQUE_TABLE_HH_
#define _SDD_MEM_UNIQUE_TABLE_HH_

#include <cassert>

#include "sdd/mem/hash_table.hh"
#include "sdd/util/boost_flat_map_no_warnings.hh"

namespace sdd { namespace mem {

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief A table to unify data.
template <typename Unique>
class unique_table
{
  // Can't copy a unique_table.
  unique_table(const unique_table&) = delete;
  unique_table& operator=(const unique_table&) = delete;

public:

  /// @brief Some statistics.
  struct statistics
  {
    /// @brief The actual number of unified elements.
    std::size_t size;

    /// @brief The actual load factor.
    double load_factor;

    /// @brief The total number of access.
    std::size_t access;

    /// @brief The number of hits.
    std::size_t hit;

    /// @brief The number of misses.
    std::size_t miss;

    /// @brief The number of rehash.
    std::size_t rehash;
  };

private:

  /// @brief The actual container of unified data.
  mem::hash_table<Unique> set_;

  /// @brief The statistics of this unique_table.
  mutable statistics stats_;

  /// @brief Index re-usable memory blocks by size.
  boost::container::flat_multimap<std::size_t, char*> blocks_;

  /// @brief The number of re-usable memory blocks to keep.
  static constexpr std::size_t nb_blocks = 4096;

public:

  /// @brief Constructor.
  /// @param initial_size Initial capacity of the container.
  unique_table(std::size_t initial_size)
    : set_(initial_size)
    , stats_()
    , blocks_()
  {
    blocks_.reserve(nb_blocks);
  }

  /// @brief Destructor.
  ~unique_table()
  {
    for (auto& b : blocks_)
    {
      delete[] b.second;
    }
  }

  /// @brief Unify a data.
  /// @param ptr A pointer to a data constructed with a placement new into the storage returned by
  /// allocate().
  /// @return A reference to the unified data.
  Unique&
  operator()(Unique* ptr)
  {
    ++stats_.access;

    auto insertion = set_.insert(*ptr);
    if (not insertion.second)
    {
      // The inserted Unique already exists. We keep its allocated memory to avoid deallocating
      // memory each time there is a hit.
      ++stats_.hit;
      const std::size_t size = sizeof(Unique) + ptr->extra_bytes();
      ptr->~Unique();
      if (blocks_.size() == nb_blocks)
      {
        // Erase last block (the biggest one).
        auto it = blocks_.end() - 1;
        delete[] it->second;
        blocks_.erase(it);
      }
      blocks_.emplace(size, reinterpret_cast<char*>(ptr));
    }
    else
    {
      ++stats_.miss;
    }
    return *insertion.first;
  }

  /// @brief Allocate a memory block large enough for the given size.
  char*
  allocate(std::size_t extra_bytes)
  {
    const std::size_t size = sizeof(Unique) + extra_bytes;
    const auto it = blocks_.lower_bound(size);
    if (it != blocks_.end() and it->first <= (2 * size))
    {
      // re-use allocated blocks
      char* addr = it->second;
      blocks_.erase(it);
      return addr;
    }
    else
    {
      return new char[size];
    }
  }

  /// @brief Erase the given unified data.
  ///
  /// All subsequent uses of the erased data are invalid.
  void
  erase(const Unique& x)
  noexcept
  {
    assert(x.is_not_referenced() && "Unique still referenced");
    const auto cit = set_.find(x);
    assert(cit != set_.end() && "Unique not found");
    set_.erase(cit);
    delete &x;
  }

  /// @brief Get the load factor of the internal hash table.
  double
  load_factor()
  const noexcept
  {
    return static_cast<double>(set_.size()) / static_cast<double>(set_.bucket_count());
  }

  /// @brief Get the statistics of this unique_table.
  statistics
  stats()
  const noexcept
  {
    stats_.size = set_.size();
    stats_.load_factor = load_factor();
    return stats_;
  }
};

/*------------------------------------------------------------------------------------------------*/

}} // namespace sdd::mem

#endif // _SDD_MEM_UNIQUE_TABLE_HH_
<commit_msg>Fixed a mismatched new char[]/delete, detected by Valgrind on Linux. No memory leaks were possible as the correct destructor was called, but it avoid spurious warnings.<commit_after>#ifndef _SDD_MEM_UNIQUE_TABLE_HH_
#define _SDD_MEM_UNIQUE_TABLE_HH_

#include <cassert>

#include "sdd/mem/hash_table.hh"
#include "sdd/util/boost_flat_map_no_warnings.hh"

namespace sdd { namespace mem {

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief A table to unify data.
template <typename Unique>
class unique_table
{
  // Can't copy a unique_table.
  unique_table(const unique_table&) = delete;
  unique_table& operator=(const unique_table&) = delete;

public:

  /// @brief Some statistics.
  struct statistics
  {
    /// @brief The actual number of unified elements.
    std::size_t size;

    /// @brief The actual load factor.
    double load_factor;

    /// @brief The total number of access.
    std::size_t access;

    /// @brief The number of hits.
    std::size_t hit;

    /// @brief The number of misses.
    std::size_t miss;

    /// @brief The number of rehash.
    std::size_t rehash;
  };

private:

  /// @brief The actual container of unified data.
  mem::hash_table<Unique> set_;

  /// @brief The statistics of this unique_table.
  mutable statistics stats_;

  /// @brief Index re-usable memory blocks by size.
  boost::container::flat_multimap<std::size_t, char*> blocks_;

  /// @brief The number of re-usable memory blocks to keep.
  static constexpr std::size_t nb_blocks = 4096;

public:

  /// @brief Constructor.
  /// @param initial_size Initial capacity of the container.
  unique_table(std::size_t initial_size)
    : set_(initial_size)
    , stats_()
    , blocks_()
  {
    blocks_.reserve(nb_blocks);
  }

  /// @brief Destructor.
  ~unique_table()
  {
    for (auto& b : blocks_)
    {
      delete[] b.second;
    }
  }

  /// @brief Unify a data.
  /// @param ptr A pointer to a data constructed with a placement new into the storage returned by
  /// allocate().
  /// @return A reference to the unified data.
  Unique&
  operator()(Unique* ptr)
  {
    ++stats_.access;

    auto insertion = set_.insert(*ptr);
    if (not insertion.second)
    {
      // The inserted Unique already exists. We keep its allocated memory to avoid deallocating
      // memory each time there is a hit.
      ++stats_.hit;
      const std::size_t size = sizeof(Unique) + ptr->extra_bytes();
      ptr->~Unique();
      if (blocks_.size() == nb_blocks)
      {
        // Erase last block (the biggest one).
        auto it = blocks_.end() - 1;
        delete[] it->second;
        blocks_.erase(it);
      }
      blocks_.emplace(size, reinterpret_cast<char*>(ptr));
    }
    else
    {
      ++stats_.miss;
    }
    return *insertion.first;
  }

  /// @brief Allocate a memory block large enough for the given size.
  char*
  allocate(std::size_t extra_bytes)
  {
    const std::size_t size = sizeof(Unique) + extra_bytes;
    const auto it = blocks_.lower_bound(size);
    if (it != blocks_.end() and it->first <= (2 * size))
    {
      // re-use allocated blocks
      char* addr = it->second;
      blocks_.erase(it);
      return addr;
    }
    else
    {
      return new char[size];
    }
  }

  /// @brief Erase the given unified data.
  ///
  /// All subsequent uses of the erased data are invalid.
  void
  erase(const Unique& x)
  noexcept
  {
    assert(x.is_not_referenced() && "Unique still referenced");
    const auto cit = set_.find(x);
    assert(cit != set_.end() && "Unique not found");
    set_.erase(cit);
    x.~Unique();
    delete[] reinterpret_cast<const char*>(&x); // match new char[] of allocate().
  }

  /// @brief Get the load factor of the internal hash table.
  double
  load_factor()
  const noexcept
  {
    return static_cast<double>(set_.size()) / static_cast<double>(set_.bucket_count());
  }

  /// @brief Get the statistics of this unique_table.
  statistics
  stats()
  const noexcept
  {
    stats_.size = set_.size();
    stats_.load_factor = load_factor();
    return stats_;
  }
};

/*------------------------------------------------------------------------------------------------*/

}} // namespace sdd::mem

#endif // _SDD_MEM_UNIQUE_TABLE_HH_
<|endoftext|>


<commit_before>#ifndef _SDD_MEM_UNIQUE_TABLE_HH_
#define _SDD_MEM_UNIQUE_TABLE_HH_

#include <cassert>

#include <boost/container/flat_map.hpp>
#include <boost/intrusive/unordered_set.hpp>

namespace sdd { namespace mem {

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief A table to unify data.
template <typename Unique>
class unique_table
{
  // Can't copy a unique_table.
  unique_table(const unique_table&) = delete;
  unique_table& operator=(const unique_table&) = delete;

public:

  /// @brief Some statistics.
  struct statistics
  {
    /// @brief The actual number of unified elements.
    std::size_t size;

    /// @brief The actual load factor.
    double load_factor;

    /// @brief The total number of access.
    std::size_t access;

    /// @brief The number of hits.
    std::size_t hit;

    /// @brief The number of misses.
    std::size_t miss;

    /// @brief The number of rehash.
    std::size_t rehash;

#ifdef LIBSDD_PROFILE
    /// @brief The number of collisions during the whole life of this unique_table.
    std::size_t total_collisions;

    /// @brief The actual number of collisions.
    std::size_t collisions;
#endif // LIBSDD_PROFILE
  };

private:

  /// @brief We choose a faster, unsafe mode.
  typedef boost::intrusive::link_mode<boost::intrusive::normal_link> link_mode;

  /// @brief Tell Boost.Intrusive how to access to the member hook.
  typedef boost::intrusive::member_hook< Unique
                                       , boost::intrusive::unordered_set_member_hook<link_mode>
                                       , &Unique::member_hook_>
          member_hook;

  /// @brief Tell Boost.Intrusive we want to use the standard hash mechanism.
  typedef boost::intrusive::hash<std::hash<Unique>> hash_option;

  /// @brief The type of the set that helps to unify data.
  typedef typename boost::intrusive::make_unordered_set<Unique, member_hook, hash_option>::type
          set_type;

  /// @brief A type needed by Boost.Intrusive.
  typedef typename set_type::bucket_type bucket_type;

  /// @brief A type needed by Boost.Intrusive.
  typedef typename set_type::bucket_traits bucket_traits;

  /// @brief The buckets needed by Boost.Intrusive.
  bucket_type* buckets_;

  /// @brief The actual container of unified data.
  set_type* set_;

  /// @brief The statistics of this unique_table.
  mutable statistics stats_;

  /// The number of re-usable memory blocks to keep.
  static constexpr std::size_t nb_blocks = 4096;

  /// Index re-usable memory blocks by size.
  boost::container::flat_multimap<std::size_t, char*> blocks_;

public:

  /// @brief Constructor.
  /// @param initial_size Initial capacity of the container.
  unique_table(std::size_t initial_size)
  	: buckets_(new bucket_type[set_type::suggested_upper_bucket_count(initial_size)])
    , set_(new set_type(bucket_traits( buckets_
                                     , set_type::suggested_upper_bucket_count(initial_size))))
    , stats_()
    , blocks_()
  {
    blocks_.reserve(nb_blocks);
  }

  /// @brief Destructor.
  ~unique_table()
  {
    delete set_;
    delete[] buckets_;
    for (auto& b : blocks_)
    {
      delete[] b.second;
    }
  }

  /// @brief Unify a data.
  /// @param ptr A pointer to a data constructed with a placement new into the storage returned by
  /// allocate().
  /// @return A reference to the unified data.
  const Unique&
  operator()(Unique* ptr)
  {
    ++stats_.access;

    if (load_factor() >= 0.9)
    {
      rehash();
    }

    auto insertion = set_->insert(*ptr);
    if (not insertion.second)
    {
      // The inserted Unique already exists. We keep its allocated memory to avoid deallocating
      // memory each time there is a hit.
      ++stats_.hit;
      const std::size_t size = sizeof(Unique) + ptr->extra_bytes();
      ptr->~Unique();
      if (blocks_.size() == nb_blocks)
      {
        // Erase last block (the biggest one).
        auto it = blocks_.end() - 1;
        delete[] it->second;
        blocks_.erase(it);
      }
      blocks_.emplace(size, reinterpret_cast<char*>(ptr));
    }
    else
    {
      ++stats_.miss;
#ifdef LIBSDD_PROFILE
      if (set_->bucket_size(set_->bucket(*ptr)) > 1)
      {
        ++stats_.total_collisions;
      }
#endif // LIBSDD_PROFILE
    }
    return *insertion.first;
  }

  /// @brief Allocate a memory block large enough for the given size.
  char*
  allocate(std::size_t extra_bytes)
  {
    const std::size_t size = sizeof(Unique) + extra_bytes;
    const auto it = blocks_.lower_bound(size);
    if (it != blocks_.end() and it->first <= (2 * size))
    {
      // re-use allocated blocks
      char* addr = it->second;
      blocks_.erase(it);
      return addr;
    }
    else
    {
      return new char[size];
    }
  }

  /// @brief Erase the given unified data.
  ///
  /// All subsequent uses of the erased data are invalid.
  void
  erase(const Unique& x)
  noexcept
  {
    assert(x.is_not_referenced() && "Unique still referenced");
    set_->erase_and_dispose(x, [](const Unique* ptr){delete ptr;});
  }

  /// @brief Get the load factor of the internal hash table.
  double
  load_factor()
  const noexcept
  {
    return static_cast<double>(set_->size()) / static_cast<double>(set_->bucket_count());
  }

  /// @brief Get the statistics of this unique_table.
  statistics
  stats()
  const noexcept
  {
    stats_.size = set_->size();
    stats_.load_factor = load_factor();
    stats_.collisions = 0;
    for (std::size_t nb = 0; nb < set_->bucket_count(); ++nb)
    {
      if (set_->bucket_size(nb) > 1)
      {
        ++stats_.collisions;
      }
    }
    return stats_;
  }

private:

  /// @brief Rehash the internal hash table.
  void
  rehash()
  {
    ++stats_.rehash;
    const std::size_t new_size = set_type::suggested_upper_bucket_count(set_->bucket_count() * 2);
    bucket_type* new_buckets = new bucket_type[new_size];
    set_->rehash(bucket_traits(new_buckets, new_size));
    delete[] buckets_;
    buckets_ = new_buckets;
  }
};

/*------------------------------------------------------------------------------------------------*/

}} // namespace sdd::mem

#endif // _SDD_MEM_UNIQUE_TABLE_HH_
<commit_msg>Add missing #ifdef ... #endif<commit_after>#ifndef _SDD_MEM_UNIQUE_TABLE_HH_
#define _SDD_MEM_UNIQUE_TABLE_HH_

#include <cassert>

#include <boost/container/flat_map.hpp>
#include <boost/intrusive/unordered_set.hpp>

namespace sdd { namespace mem {

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief A table to unify data.
template <typename Unique>
class unique_table
{
  // Can't copy a unique_table.
  unique_table(const unique_table&) = delete;
  unique_table& operator=(const unique_table&) = delete;

public:

  /// @brief Some statistics.
  struct statistics
  {
    /// @brief The actual number of unified elements.
    std::size_t size;

    /// @brief The actual load factor.
    double load_factor;

    /// @brief The total number of access.
    std::size_t access;

    /// @brief The number of hits.
    std::size_t hit;

    /// @brief The number of misses.
    std::size_t miss;

    /// @brief The number of rehash.
    std::size_t rehash;

#ifdef LIBSDD_PROFILE
    /// @brief The number of collisions during the whole life of this unique_table.
    std::size_t total_collisions;

    /// @brief The actual number of collisions.
    std::size_t collisions;
#endif // LIBSDD_PROFILE
  };

private:

  /// @brief We choose a faster, unsafe mode.
  typedef boost::intrusive::link_mode<boost::intrusive::normal_link> link_mode;

  /// @brief Tell Boost.Intrusive how to access to the member hook.
  typedef boost::intrusive::member_hook< Unique
                                       , boost::intrusive::unordered_set_member_hook<link_mode>
                                       , &Unique::member_hook_>
          member_hook;

  /// @brief Tell Boost.Intrusive we want to use the standard hash mechanism.
  typedef boost::intrusive::hash<std::hash<Unique>> hash_option;

  /// @brief The type of the set that helps to unify data.
  typedef typename boost::intrusive::make_unordered_set<Unique, member_hook, hash_option>::type
          set_type;

  /// @brief A type needed by Boost.Intrusive.
  typedef typename set_type::bucket_type bucket_type;

  /// @brief A type needed by Boost.Intrusive.
  typedef typename set_type::bucket_traits bucket_traits;

  /// @brief The buckets needed by Boost.Intrusive.
  bucket_type* buckets_;

  /// @brief The actual container of unified data.
  set_type* set_;

  /// @brief The statistics of this unique_table.
  mutable statistics stats_;

  /// The number of re-usable memory blocks to keep.
  static constexpr std::size_t nb_blocks = 4096;

  /// Index re-usable memory blocks by size.
  boost::container::flat_multimap<std::size_t, char*> blocks_;

public:

  /// @brief Constructor.
  /// @param initial_size Initial capacity of the container.
  unique_table(std::size_t initial_size)
  	: buckets_(new bucket_type[set_type::suggested_upper_bucket_count(initial_size)])
    , set_(new set_type(bucket_traits( buckets_
                                     , set_type::suggested_upper_bucket_count(initial_size))))
    , stats_()
    , blocks_()
  {
    blocks_.reserve(nb_blocks);
  }

  /// @brief Destructor.
  ~unique_table()
  {
    delete set_;
    delete[] buckets_;
    for (auto& b : blocks_)
    {
      delete[] b.second;
    }
  }

  /// @brief Unify a data.
  /// @param ptr A pointer to a data constructed with a placement new into the storage returned by
  /// allocate().
  /// @return A reference to the unified data.
  const Unique&
  operator()(Unique* ptr)
  {
    ++stats_.access;

    if (load_factor() >= 0.9)
    {
      rehash();
    }

    auto insertion = set_->insert(*ptr);
    if (not insertion.second)
    {
      // The inserted Unique already exists. We keep its allocated memory to avoid deallocating
      // memory each time there is a hit.
      ++stats_.hit;
      const std::size_t size = sizeof(Unique) + ptr->extra_bytes();
      ptr->~Unique();
      if (blocks_.size() == nb_blocks)
      {
        // Erase last block (the biggest one).
        auto it = blocks_.end() - 1;
        delete[] it->second;
        blocks_.erase(it);
      }
      blocks_.emplace(size, reinterpret_cast<char*>(ptr));
    }
    else
    {
      ++stats_.miss;
#ifdef LIBSDD_PROFILE
      if (set_->bucket_size(set_->bucket(*ptr)) > 1)
      {
        ++stats_.total_collisions;
      }
#endif // LIBSDD_PROFILE
    }
    return *insertion.first;
  }

  /// @brief Allocate a memory block large enough for the given size.
  char*
  allocate(std::size_t extra_bytes)
  {
    const std::size_t size = sizeof(Unique) + extra_bytes;
    const auto it = blocks_.lower_bound(size);
    if (it != blocks_.end() and it->first <= (2 * size))
    {
      // re-use allocated blocks
      char* addr = it->second;
      blocks_.erase(it);
      return addr;
    }
    else
    {
      return new char[size];
    }
  }

  /// @brief Erase the given unified data.
  ///
  /// All subsequent uses of the erased data are invalid.
  void
  erase(const Unique& x)
  noexcept
  {
    assert(x.is_not_referenced() && "Unique still referenced");
    set_->erase_and_dispose(x, [](const Unique* ptr){delete ptr;});
  }

  /// @brief Get the load factor of the internal hash table.
  double
  load_factor()
  const noexcept
  {
    return static_cast<double>(set_->size()) / static_cast<double>(set_->bucket_count());
  }

  /// @brief Get the statistics of this unique_table.
  statistics
  stats()
  const noexcept
  {
    stats_.size = set_->size();
    stats_.load_factor = load_factor();
#ifdef LIBSDD_PROFILE
    stats_.collisions = 0;
    for (std::size_t nb = 0; nb < set_->bucket_count(); ++nb)
    {
      if (set_->bucket_size(nb) > 1)
      {
        ++stats_.collisions;
      }
    }
#endif // LIBSDD_PROFILE
    return stats_;
  }

private:

  /// @brief Rehash the internal hash table.
  void
  rehash()
  {
    ++stats_.rehash;
    const std::size_t new_size = set_type::suggested_upper_bucket_count(set_->bucket_count() * 2);
    bucket_type* new_buckets = new bucket_type[new_size];
    set_->rehash(bucket_traits(new_buckets, new_size));
    delete[] buckets_;
    buckets_ = new_buckets;
  }
};

/*------------------------------------------------------------------------------------------------*/

}} // namespace sdd::mem

#endif // _SDD_MEM_UNIQUE_TABLE_HH_
<|endoftext|>