<commit_before>/*************************************************************************
 *
 *  $RCSfile: Query.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-27 18:07:34 $
 *
 *  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 _XMLSEARCH_QE_QUERY_HXX_
#include <qe/Query.hxx>
#endif
#ifndef _XMLSEARCH_QE_XMLINDEX_HXX_
#include <qe/XmlIndex.hxx>
#endif
#ifndef _XMLSEARCH_QE_CONCEPTDATA_HXX_
#include <qe/ConceptData.hxx>
#endif
#ifndef _XMLSEARCH_QE_QUERYPROCESSOR_HXX_
#include <qe/QueryProcessor.hxx>
#endif
#ifndef _XMLSEARCH_QE_CONTEXTTABLES_HXX_
#include <qe/ContextTables.hxx>
#endif

using namespace xmlsearch::qe;

sal_Int32* QueryHit::getMatches( sal_Int32& matchesL )
{
    matchesL = matchesL_;
    return matches_;
}

/******************************************************************************/
/*                                                                            */
/*                     HitStore                                               */
/*                                                                            */
/******************************************************************************/

HitStore::HitStore( double initialStandard,sal_Int32 limit,sal_Int32 nColumns )
    : standard_( initialStandard ),
      limit_( limit ),
      heap_( limit ),
      nColumns_( nColumns ),
      free_( 0 ),
      index_( 0 )
{
    for( sal_uInt32 i = 0; i < heap_.size(); ++i )
        heap_[i] = 0;
}

HitStore::~HitStore()
{
    for( sal_uInt32 i = 0; i < heap_.size(); ++i )
        delete heap_[i];
}

bool HitStore::goodEnough( double penalty, sal_Int32 begin, sal_Int32 end )
{
    return free_ == limit_ ? heap_[0]->worseThan( penalty,begin,end ) : true;
}

QueryHit* HitStore::createQueryHit( double penalty,sal_Int32 doc,sal_Int32 begin,sal_Int32 end )
{
    QueryHit* hit = new QueryHit( nColumns_,penalty,doc,begin,end );
    if( free_ == limit_ )
    { // goodEnough'ness checked already
        delete heap_[0];
        heap_[0] = hit;
        heapify( 0 );
        standard_ = heap_[0]->getPenalty();
    }
    else if( free_ < limit_ )
    {
        heap_[ free_++ ] = hit;
        if( free_ == limit_ )
        { // we have the needed number
            for( sal_Int32 i = free_/2; i >= 0; --i ) // build heap
                heapify( i );
            standard_ = heap_[0]->getPenalty();
        }
    }
    return hit;
}

struct CompareQueryHit
{
    bool operator()( const QueryHit* l,const QueryHit* r )
    {
        return l->compareTo( r );
    }
};

#include <stl/algorithm>

QueryHit* HitStore::firstBestQueryHit()
{
    if( free_ > 0)
    {
        CompareQueryHit bla;
        heap_.resize( free_ );
          std::stable_sort( heap_.begin(),heap_.end(),bla );
        index_ = 0;
        return nextBestQueryHit();
    }
    else
        return 0;
}

QueryHit* HitStore::nextBestQueryHit()
{
    return index_ < free_ ? heap_[ index_++ ] : 0;
}

void HitStore::heapify( sal_Int32 i )
{
    for( sal_Int32 r,l,worst; ; )
    {
        r = (i + 1) << 1; l = r - 1;
        worst = l < free_ && heap_[i]->betterThan( heap_[l] ) ? l : i;
        if( r < free_ && heap_[ worst ]->betterThan( heap_[r] ) )
            worst = r;
        if (worst != i)
        {
            QueryHit* temp = heap_[ worst ];
            heap_[ worst ] = heap_[ i ];
            heap_[i] = temp;
            i = worst;      // continue
        }
        else
            break;
    }
}

//  sal_Int32 HitStore::partition( sal_Int32 p,sal_Int32 r )
//  {
//      QueryHit* x = heap_[ ((p + r) >> 1) & 0x7FFFFFFF ];
//      sal_Int32 i = p - 1, j = r + 1;
//      while( true )
//      {
//          while( x->compareTo( heap_[--j] ) )
//              ;
//          while( heap_[++i]->compareTo( x ) )
//              ;
//          if( i < j )
//          {
//              QueryHit* t = heap_[i];
//              heap_[i] = heap_[j];
//              heap_[j] = t;
//          }
//          else
//              return j;
//      }
//  }

//  void HitStore::quicksort( sal_Int32 p,sal_Int32 r )
//  {
//      while( p < r )
//      {
//          sal_Int32 q = partition( p,r );
//          quicksort(p, q);
//          p = q + 1;
//      }
//  }

/******************************************************************************/
/*                                                                            */
/*                                 Query                                      */
/*                                                                            */
/******************************************************************************/

#define MissingTermPenalty 10.0

Query::Query( XmlIndex* env,
              sal_Int32 nColumns,
              sal_Int32 nHits,
              sal_Int32 missingPenaltiesL,
              double* missingPenalties )
    : env_( env ),
      ctx_( env ? env->getContextInfo() : 0 ),
      nColumns_( nColumns ),
      nHitsRequested_( nHits ),
      missingPenaltyL_( nColumns ),
      missingPenalty_( new double[ nColumns ] ),
      upperboundTemplateL_( nColumns ),
      upperboundTemplate_( new double[ nColumns ] ),
      penaltiesL_( missingPenaltiesL ),
      penalties_( missingPenalties ),
      currentStandard_( nColumns * MissingTermPenalty - 0.0001 ),
      missingTermsPenalty_( 0.0 ),
      store_( nColumns * MissingTermPenalty - 0.0001,nHits,nColumns ),
      ignoredElementsL_( 0 ),
      ignoredElements_( 0 )
{
    // for the EmptyQuery case (awaits arch improvement pass)

    if( missingPenalties )
        for( sal_Int32 i = 0;i < nColumns_; ++i )
            missingPenalty_[i] = missingPenalties[i];
    else
        for( sal_Int32 i = 0;i < nColumns_; ++i )
            missingPenalty_[i] = MissingTermPenalty;

    makePenaltiesTable();
    //  _roleFillerList = RoleFiller.STOP;
}

Query::~Query()
{
    delete[] missingPenalty_;
    delete[] upperboundTemplate_;
    delete[] penalties_;
    delete[] ignoredElements_;
}

void Query::setIgnoredElements( const sal_Int32 ignoredElementsL,const rtl::OUString* ignoredElements )
{
    if( ctx_ )
        ignoredElements_ = ctx_->getIgnoredElementsSet( ignoredElementsL_,
                                                        ignoredElementsL,ignoredElements );

    if( ! ctx_ )
    {
        ignoredElementsL_ = 0;
        ignoredElements_   = 0;
    }
}

void Query::missingTerms( sal_Int32 nMissingTerms )
{
    missingTermsPenalty_ = MissingTermPenalty * nMissingTerms;
}

ConceptData* Query::makeConceptData( sal_Int32 col,sal_Int32 concept,double penalty,sal_Int32 queryNo )
{
    return new ConceptData( concept,col,penalty,queryNo,nColumns_,env_->getContextInfo() );;
}

void Query::getHits( std::vector< QueryHitData* >& data,sal_Int32 n )
{
    if( n <= 0 )
        return;

    QueryHit* qh = store_.firstBestQueryHit();

    while( qh )
    {
        data.push_back( env_->hitToData( qh ) );
        qh = data.size() < sal_uInt32( n ) ? store_.nextBestQueryHit() : 0;
    }
}

QueryHit* Query::maybeCreateQueryHit( double penalty,
                                      sal_Int32 doc, sal_Int32 begin, sal_Int32 end, sal_Int32 parentContext )
{
    // hits are located using only terms actually present in text
    // if B is not present, the query A B C reduces to A C and penalties
    // are computed as if B did not occur in query
    // to meaningfully merge results from different servers, some of which
    // may have B, penalty has to be normalized to the common computing scheme

    QueryHit* res =
        ( store_.goodEnough( penalty += missingTermsPenalty_,begin,end )
          && ( ! ignoredElements_ || ctx_->notIgnored( parentContext,ignoredElementsL_,ignoredElements_ ) ) )
        ?
        store_.createQueryHit( penalty,doc,begin,end )
        :
        0;
    return res;
}

void Query::makePenaltiesTable()
{
    sal_Int32 nPatterns = 1 << nColumns_;
    delete[] penalties_;
    penalties_ = new double[ penaltiesL_ = nPatterns ];
    for (sal_Int32 i = 0; i < nPatterns; ++i )
        penalties_[i] = computePenalty(i);
}

double Query::computePenalty( sal_Int32 n )
{
    double penalty = 0.0;
    for( sal_Int32 i = 0; i < nColumns_; ++i )
        if( ( n & 1 << i ) == 0 )
            penalty += missingPenalty_[i];
    return penalty;
}

void Query::resetForNextDocument()
{
    currentStandard_ = store_.getCurrentStandard();
    // "everything's missing"
    for( sal_Int32 i = 0; i < nColumns_; i++ )
        upperboundTemplate_[i] = missingPenalty_[i];
    vote_ = false;
}

bool Query::vote()
{
    double sum = 0.0;
    for( sal_Int32 i = 0; i < nColumns_; i++ )
        sum += upperboundTemplate_[i];
    return vote_ = (sum <= currentStandard_ );
}

void Query::updateEstimate( sal_Int32 role,double penalty )
{
    if( penalty < upperboundTemplate_[ role ] )
        upperboundTemplate_[ role ] = penalty;
}

/******************************************************************************/
/*                                                                            */
/*                         QueryHitIterator                                   */
/*                                                                            */
/******************************************************************************/

QueryHitIterator::QueryHitIterator( const QueryResults* result )
    : result_( result ),
      index_( -1 )
{
}

QueryHitIterator::~QueryHitIterator()
{
    delete result_;
}

bool QueryHitIterator::next()
{
    return accessible_ = ( ++index_ < sal_Int32( result_->queryHits_.size() ) );
}

QueryHitData* QueryHitIterator::getHit( const PrefixTranslator* ) const
{
    if( accessible_ )
        return result_->queryHits_[index_];
    else
        return 0;
}

double QueryHitIterator::getPenalty()
{
    if( accessible_ )
        return result_->queryHits_[index_]->getPenalty();
    else
        return 1.0E30;
}

<commit_msg>INTEGRATION: CWS geordi2q11 (1.7.44); FILE MERGED 2003/12/17 11:38:29 hr 1.7.44.1: #111934#: join CWS ooo111fix1<commit_after>/*************************************************************************
 *
 *  $RCSfile: Query.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: vg $ $Date: 2003-12-17 16:20:30 $
 *
 *  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 _XMLSEARCH_QE_QUERY_HXX_
#include <qe/Query.hxx>
#endif
#ifndef _XMLSEARCH_QE_XMLINDEX_HXX_
#include <qe/XmlIndex.hxx>
#endif
#ifndef _XMLSEARCH_QE_CONCEPTDATA_HXX_
#include <qe/ConceptData.hxx>
#endif
#ifndef _XMLSEARCH_QE_QUERYPROCESSOR_HXX_
#include <qe/QueryProcessor.hxx>
#endif
#ifndef _XMLSEARCH_QE_CONTEXTTABLES_HXX_
#include <qe/ContextTables.hxx>
#endif

using namespace xmlsearch::qe;

sal_Int32* QueryHit::getMatches( sal_Int32& matchesL )
{
    matchesL = matchesL_;
    return matches_;
}

/******************************************************************************/
/*                                                                            */
/*                     HitStore                                               */
/*                                                                            */
/******************************************************************************/

HitStore::HitStore( double initialStandard,sal_Int32 limit,sal_Int32 nColumns )
    : standard_( initialStandard ),
      limit_( limit ),
      heap_( limit ),
      nColumns_( nColumns ),
      free_( 0 ),
      index_( 0 )
{
    for( sal_uInt32 i = 0; i < heap_.size(); ++i )
        heap_[i] = 0;
}

HitStore::~HitStore()
{
    for( sal_uInt32 i = 0; i < heap_.size(); ++i )
        delete heap_[i];
}

bool HitStore::goodEnough( double penalty, sal_Int32 begin, sal_Int32 end )
{
    return free_ == limit_ ? heap_[0]->worseThan( penalty,begin,end ) : true;
}

QueryHit* HitStore::createQueryHit( double penalty,sal_Int32 doc,sal_Int32 begin,sal_Int32 end )
{
    QueryHit* hit = new QueryHit( nColumns_,penalty,doc,begin,end );
    if( free_ == limit_ )
    { // goodEnough'ness checked already
        delete heap_[0];
        heap_[0] = hit;
        heapify( 0 );
        standard_ = heap_[0]->getPenalty();
    }
    else if( free_ < limit_ )
    {
        heap_[ free_++ ] = hit;
        if( free_ == limit_ )
        { // we have the needed number
            for( sal_Int32 i = free_/2; i >= 0; --i ) // build heap
                heapify( i );
            standard_ = heap_[0]->getPenalty();
        }
    }
    return hit;
}

struct CompareQueryHit
{
    bool operator()( const QueryHit* l,const QueryHit* r )
    {
        return l->compareTo( r );
    }
};

#include <algorithm>

QueryHit* HitStore::firstBestQueryHit()
{
    if( free_ > 0)
    {
        CompareQueryHit bla;
        heap_.resize( free_ );
          std::stable_sort( heap_.begin(),heap_.end(),bla );
        index_ = 0;
        return nextBestQueryHit();
    }
    else
        return 0;
}

QueryHit* HitStore::nextBestQueryHit()
{
    return index_ < free_ ? heap_[ index_++ ] : 0;
}

void HitStore::heapify( sal_Int32 i )
{
    for( sal_Int32 r,l,worst; ; )
    {
        r = (i + 1) << 1; l = r - 1;
        worst = l < free_ && heap_[i]->betterThan( heap_[l] ) ? l : i;
        if( r < free_ && heap_[ worst ]->betterThan( heap_[r] ) )
            worst = r;
        if (worst != i)
        {
            QueryHit* temp = heap_[ worst ];
            heap_[ worst ] = heap_[ i ];
            heap_[i] = temp;
            i = worst;      // continue
        }
        else
            break;
    }
}

//  sal_Int32 HitStore::partition( sal_Int32 p,sal_Int32 r )
//  {
//      QueryHit* x = heap_[ ((p + r) >> 1) & 0x7FFFFFFF ];
//      sal_Int32 i = p - 1, j = r + 1;
//      while( true )
//      {
//          while( x->compareTo( heap_[--j] ) )
//              ;
//          while( heap_[++i]->compareTo( x ) )
//              ;
//          if( i < j )
//          {
//              QueryHit* t = heap_[i];
//              heap_[i] = heap_[j];
//              heap_[j] = t;
//          }
//          else
//              return j;
//      }
//  }

//  void HitStore::quicksort( sal_Int32 p,sal_Int32 r )
//  {
//      while( p < r )
//      {
//          sal_Int32 q = partition( p,r );
//          quicksort(p, q);
//          p = q + 1;
//      }
//  }

/******************************************************************************/
/*                                                                            */
/*                                 Query                                      */
/*                                                                            */
/******************************************************************************/

#define MissingTermPenalty 10.0

Query::Query( XmlIndex* env,
              sal_Int32 nColumns,
              sal_Int32 nHits,
              sal_Int32 missingPenaltiesL,
              double* missingPenalties )
    : env_( env ),
      ctx_( env ? env->getContextInfo() : 0 ),
      nColumns_( nColumns ),
      nHitsRequested_( nHits ),
      missingPenaltyL_( nColumns ),
      missingPenalty_( new double[ nColumns ] ),
      upperboundTemplateL_( nColumns ),
      upperboundTemplate_( new double[ nColumns ] ),
      penaltiesL_( missingPenaltiesL ),
      penalties_( missingPenalties ),
      currentStandard_( nColumns * MissingTermPenalty - 0.0001 ),
      missingTermsPenalty_( 0.0 ),
      store_( nColumns * MissingTermPenalty - 0.0001,nHits,nColumns ),
      ignoredElementsL_( 0 ),
      ignoredElements_( 0 )
{
    // for the EmptyQuery case (awaits arch improvement pass)

    if( missingPenalties )
        for( sal_Int32 i = 0;i < nColumns_; ++i )
            missingPenalty_[i] = missingPenalties[i];
    else
        for( sal_Int32 i = 0;i < nColumns_; ++i )
            missingPenalty_[i] = MissingTermPenalty;

    makePenaltiesTable();
    //  _roleFillerList = RoleFiller.STOP;
}

Query::~Query()
{
    delete[] missingPenalty_;
    delete[] upperboundTemplate_;
    delete[] penalties_;
    delete[] ignoredElements_;
}

void Query::setIgnoredElements( const sal_Int32 ignoredElementsL,const rtl::OUString* ignoredElements )
{
    if( ctx_ )
        ignoredElements_ = ctx_->getIgnoredElementsSet( ignoredElementsL_,
                                                        ignoredElementsL,ignoredElements );

    if( ! ctx_ )
    {
        ignoredElementsL_ = 0;
        ignoredElements_   = 0;
    }
}

void Query::missingTerms( sal_Int32 nMissingTerms )
{
    missingTermsPenalty_ = MissingTermPenalty * nMissingTerms;
}

ConceptData* Query::makeConceptData( sal_Int32 col,sal_Int32 concept,double penalty,sal_Int32 queryNo )
{
    return new ConceptData( concept,col,penalty,queryNo,nColumns_,env_->getContextInfo() );;
}

void Query::getHits( std::vector< QueryHitData* >& data,sal_Int32 n )
{
    if( n <= 0 )
        return;

    QueryHit* qh = store_.firstBestQueryHit();

    while( qh )
    {
        data.push_back( env_->hitToData( qh ) );
        qh = data.size() < sal_uInt32( n ) ? store_.nextBestQueryHit() : 0;
    }
}

QueryHit* Query::maybeCreateQueryHit( double penalty,
                                      sal_Int32 doc, sal_Int32 begin, sal_Int32 end, sal_Int32 parentContext )
{
    // hits are located using only terms actually present in text
    // if B is not present, the query A B C reduces to A C and penalties
    // are computed as if B did not occur in query
    // to meaningfully merge results from different servers, some of which
    // may have B, penalty has to be normalized to the common computing scheme

    QueryHit* res =
        ( store_.goodEnough( penalty += missingTermsPenalty_,begin,end )
          && ( ! ignoredElements_ || ctx_->notIgnored( parentContext,ignoredElementsL_,ignoredElements_ ) ) )
        ?
        store_.createQueryHit( penalty,doc,begin,end )
        :
        0;
    return res;
}

void Query::makePenaltiesTable()
{
    sal_Int32 nPatterns = 1 << nColumns_;
    delete[] penalties_;
    penalties_ = new double[ penaltiesL_ = nPatterns ];
    for (sal_Int32 i = 0; i < nPatterns; ++i )
        penalties_[i] = computePenalty(i);
}

double Query::computePenalty( sal_Int32 n )
{
    double penalty = 0.0;
    for( sal_Int32 i = 0; i < nColumns_; ++i )
        if( ( n & 1 << i ) == 0 )
            penalty += missingPenalty_[i];
    return penalty;
}

void Query::resetForNextDocument()
{
    currentStandard_ = store_.getCurrentStandard();
    // "everything's missing"
    for( sal_Int32 i = 0; i < nColumns_; i++ )
        upperboundTemplate_[i] = missingPenalty_[i];
    vote_ = false;
}

bool Query::vote()
{
    double sum = 0.0;
    for( sal_Int32 i = 0; i < nColumns_; i++ )
        sum += upperboundTemplate_[i];
    return vote_ = (sum <= currentStandard_ );
}

void Query::updateEstimate( sal_Int32 role,double penalty )
{
    if( penalty < upperboundTemplate_[ role ] )
        upperboundTemplate_[ role ] = penalty;
}

/******************************************************************************/
/*                                                                            */
/*                         QueryHitIterator                                   */
/*                                                                            */
/******************************************************************************/

QueryHitIterator::QueryHitIterator( const QueryResults* result )
    : result_( result ),
      index_( -1 )
{
}

QueryHitIterator::~QueryHitIterator()
{
    delete result_;
}

bool QueryHitIterator::next()
{
    return accessible_ = ( ++index_ < sal_Int32( result_->queryHits_.size() ) );
}

QueryHitData* QueryHitIterator::getHit( const PrefixTranslator* ) const
{
    if( accessible_ )
        return result_->queryHits_[index_];
    else
        return 0;
}

double QueryHitIterator::getPenalty()
{
    if( accessible_ )
        return result_->queryHits_[index_]->getPenalty();
    else
        return 1.0E30;
}

<|endoftext|>


<commit_before>#include <SFML/Audio/Sound.hpp>
#include <beatwave/player.hpp>
#include <beatwave/config.hpp>
#include <core/util.hpp>
#include <core/dsl.hpp>

Player::Player(const sf::Vector2f &position):
    m_circle(config::PLAYER_INIT_RADIUS,
             position,
             config::PLAYER_INIT_COLOR),
    m_splat(20),
    m_dead(false)
{}

void Player::tick(int32_t deltaTime)
{
    m_circle.tick(deltaTime);
    m_splat.tick(deltaTime);
}

void Player::render(sf::RenderTarget *renderTarget) const
{
    m_circle.render(renderTarget);
    m_splat.render(renderTarget);
}

void Player::step(const sf::Color &flashColor,
                  const sf::Vector2f direction,
                  sf::Sound *sound)
{
    using namespace dsl;

    if (!m_dead) {
        m_circle.animate<Circle::Color>(from(flashColor)
                                        .to(config::PLAYER_INIT_COLOR)
                                        .during(config::COLOR_TIME));

        m_circle.animate<Circle::Position>(from(m_circle.value<Circle::Position>())
                                           .by(direction)
                                           .during(config::MOVE_TIME));

        sound->play();
    } else {
        reset();
    }
}

void Player::centerView(sf::RenderTarget *renderTarget) const
{
    renderTarget->setView(sf::View(m_circle.value<Circle::Position>(), renderTarget->getView().getSize()));
}

void Player::reset()
{
    using namespace dsl;

    m_circle.animate<Circle::Position>(set(config::PLAYER_INIT_POSITION));
    m_circle.animate<Circle::Color>(set(config::PLAYER_INIT_COLOR));
    m_circle.animate<Circle::Radius>(set(config::PLAYER_INIT_RADIUS));
    m_dead = false;
}

void Player::kill()
{
    if (!m_dead) {
        m_circle.stop();
        m_dead = true;

        using namespace dsl;

        const int COLLAPSE_TIME = 100;
        m_circle.animate<Circle::Radius>(from(config::PLAYER_INIT_RADIUS).to(0.0f).during(COLLAPSE_TIME));
        m_splat.splat(m_circle.value<Circle::Position>(), 500.0);
    }
}

bool Player::fits(const sf::FloatRect &rect) const
{
    const auto center = m_circle.value<Circle::Position>();

    const std::array<float, 4> ds = {
        std::abs(rect.top - center.y),
        std::abs(rect.top + rect.height - 1 - center.y),
        std::abs(rect.left - center.x),
        std::abs(rect.left + rect.width - 1 - center.x)
    };

    return rect.contains(center) && std::all_of(ds.begin(), ds.end(), [this](float d) {
            return m_circle.value<Circle::Radius>() < d;
    });
}

bool Player::isDead() const
{
    return m_dead;
}
<commit_msg>Implement gamma correction for player<commit_after>#include <SFML/Audio/Sound.hpp>
#include <beatwave/player.hpp>
#include <beatwave/config.hpp>
#include <core/util.hpp>
#include <core/dsl.hpp>

Player::Player(const sf::Vector2f &position):
    m_circle(config::PLAYER_INIT_RADIUS,
             position,
             config::PLAYER_INIT_COLOR),
    m_splat(20),
    m_dead(false)
{}

void Player::tick(int32_t deltaTime)
{
    m_circle.tick(deltaTime);
    m_splat.tick(deltaTime);
}

void Player::render(sf::RenderTarget *renderTarget) const
{
    m_circle.render(renderTarget);
    m_splat.render(renderTarget);
}

void Player::step(const sf::Color &flashColor,
                  const sf::Vector2f direction,
                  sf::Sound *sound)
{
    using namespace dsl;

    if (!m_dead) {
        m_circle.animate<Circle::Color>(
            map<FloatColor, sf::Color>(from(uncompressColor(flashColor))
                                       .to(uncompressColor(config::PLAYER_INIT_COLOR))
                                       .during(config::COLOR_TIME),
                                       compressColor, uncompressColor));

        m_circle.animate<Circle::Position>(from(m_circle.value<Circle::Position>())
                                           .by(direction)
                                           .during(config::MOVE_TIME));

        sound->play();
    } else {
        reset();
    }
}

void Player::centerView(sf::RenderTarget *renderTarget) const
{
    renderTarget->setView(sf::View(m_circle.value<Circle::Position>(), renderTarget->getView().getSize()));
}

void Player::reset()
{
    using namespace dsl;

    m_circle.animate<Circle::Position>(set(config::PLAYER_INIT_POSITION));
    m_circle.animate<Circle::Color>(set(config::PLAYER_INIT_COLOR));
    m_circle.animate<Circle::Radius>(set(config::PLAYER_INIT_RADIUS));
    m_dead = false;
}

void Player::kill()
{
    if (!m_dead) {
        m_circle.stop();
        m_dead = true;

        using namespace dsl;

        const int COLLAPSE_TIME = 100;
        m_circle.animate<Circle::Radius>(from(config::PLAYER_INIT_RADIUS).to(0.0f).during(COLLAPSE_TIME));
        m_splat.splat(m_circle.value<Circle::Position>(), 500.0);
    }
}

bool Player::fits(const sf::FloatRect &rect) const
{
    const auto center = m_circle.value<Circle::Position>();

    const std::array<float, 4> ds = {
        std::abs(rect.top - center.y),
        std::abs(rect.top + rect.height - 1 - center.y),
        std::abs(rect.left - center.x),
        std::abs(rect.left + rect.width - 1 - center.x)
    };

    return rect.contains(center) && std::all_of(ds.begin(), ds.end(), [this](float d) {
            return m_circle.value<Circle::Radius>() < d;
    });
}

bool Player::isDead() const
{
    return m_dead;
}
<|endoftext|>


<commit_before>
#include "vtrc-asio.h"

#include "vtrc-application.h"

#include "vtrc-common/vtrc-connection-list.h"

#include "vtrc-common/vtrc-enviroment.h"
#include "vtrc-common/vtrc-rpc-service-wrapper.h"
#include "vtrc-common/vtrc-pool-pair.h"

namespace vtrc { namespace server {

    namespace {
        namespace gpb = google::protobuf;
        static
        vtrc::shared_ptr<gpb::Service>
        default_factory( common::connection_iface *, const std::string & )
        {
            return vtrc::shared_ptr<gpb::Service>( );
        }

        typedef common::protocol_iface::call_type call_type;
    }

    struct application::impl {

        common::enviroment         env_;
        VTRC_ASIO::io_service     *ios_;
        const bool                 own_ios_;

        VTRC_ASIO::io_service     *rpc_ios_;
        const bool                 own_rpc_ios_;

        vtrc::shared_ptr<common::connection_list> clients_;

        service_factory_type        factory_;

        impl( const impl & );
        impl & operator = ( const impl & );

        impl( )
            :ios_(new VTRC_ASIO::io_service)
            ,own_ios_(true)
            ,rpc_ios_(ios_)
            ,own_rpc_ios_(false)
            ,clients_(common::connection_list::create( ))
            ,factory_(&default_factory)
        { }

        impl( VTRC_ASIO::io_service *ios )
            :ios_(ios)
            ,own_ios_(false)
            ,rpc_ios_(ios)
            ,own_rpc_ios_(false)
            ,clients_(common::connection_list::create( ))
            ,factory_(&default_factory)
        { }

        impl( VTRC_ASIO::io_service *ios, VTRC_ASIO::io_service *rpc_ios )
            :ios_(ios)
            ,own_ios_(false)
            ,rpc_ios_(rpc_ios)
            ,own_rpc_ios_(false)
            ,clients_(common::connection_list::create( ))
            ,factory_(&default_factory)
        { }

        static bool close_all_connection( common::connection_iface_sptr next )
        {
            next->close( );
            return true;
        }

        void stop_all_clients( )
        {
            clients_->foreach_while( close_all_connection );
        }

        ~impl( )
        { try {

            stop_all_clients( );
            clients_->clear( );

            if( own_ios_ )     delete ios_;
            if( own_rpc_ios_ ) delete rpc_ios_;

        } catch ( ... ) {
            ;;;
        } }

        common::enviroment &get_enviroment( )
        {
            return env_;
        }

        VTRC_ASIO::io_service &get_io_service( )
        {
            return *ios_;
        }

        VTRC_ASIO::io_service &get_rpc_service( )
        {
            return *rpc_ios_;
        }

        vtrc::shared_ptr<common::connection_list> get_clients( )
        {
            return clients_;
        }

    };

    application::application(  )
        :impl_(new impl)
    { }

    application::application(common::pool_pair &pools)
        :impl_(new impl(&pools.get_io_service( ), &pools.get_rpc_service( )))
    {

    }

    application::application( VTRC_ASIO::io_service &ios )
        :impl_(new impl(&ios))
    { }

    application::application( VTRC_ASIO::io_service &ios,
                              VTRC_ASIO::io_service &rpc_ios)
        :impl_(new impl(&ios, &rpc_ios))
    { }

    application::~application( )
    {
        delete impl_;
    }

    void application::stop_all_clients( )
    {
        impl_->stop_all_clients( );
    }

    common::enviroment &application::get_enviroment( )
    {
        return impl_->get_enviroment( );
    }

    VTRC_ASIO::io_service &application::get_io_service( )
    {
        return impl_->get_io_service( );
    }

    VTRC_ASIO::io_service &application::get_rpc_service( )
    {
        return impl_->get_rpc_service( );
    }

    const common::enviroment &application::get_enviroment( )  const
    {
        return impl_->get_enviroment( );
    }
1
    const VTRC_ASIO::io_service &application::get_io_service( )  const
    {
        return impl_->get_io_service( );
    }

    const VTRC_ASIO::io_service &application::get_rpc_service( ) const
    {
        return impl_->get_rpc_service( );
    }

    vtrc::shared_ptr<common::connection_list> application::get_clients()
    {
        return impl_->get_clients( );
    }

    void application::execute( common::protocol_iface::call_type call )
    {
        impl_->rpc_ios_->post( call );
    }

    void application::assign_service_factory( service_factory_type factory )
    {
        impl_->factory_ = factory ? factory : &default_factory;
    }

    void application::configure_session( common::connection_iface *  /*c*/,
                                         rpc::session_options & /*opts*/ )
    {
        /// use default settings
    }

    common::rpc_service_wrapper_sptr application::get_service_by_name(
                                    common::connection_iface * connection,
                                    const std::string &        service_name)
    {
        vtrc::shared_ptr<gpb::Service> svc =
                     impl_->factory_( connection, service_name );
        return svc ? vtrc::make_shared<common::rpc_service_wrapper>( svc )
                   : common::rpc_service_wrapper_sptr( );
    }

    std::string application::get_session_key(common::connection_iface * /*c*/,
                                             const std::string & /*id*/ )
    {
        return std::string( );
    }

    bool application::session_key_required( common::connection_iface * /*conn*/,
                                            const std::string & /*id*/)
    {
        return false;
    }

}}
<commit_msg>FAIL BUILD test<commit_after>
#include "vtrc-asio.h"

#include "vtrc-application.h"

#include "vtrc-common/vtrc-connection-list.h"

#include "vtrc-common/vtrc-enviroment.h"
#include "vtrc-common/vtrc-rpc-service-wrapper.h"
#include "vtrc-common/vtrc-pool-pair.h"

namespace vtrc { namespace server {

    namespace {
        namespace gpb = google::protobuf;
        static
        vtrc::shared_ptr<gpb::Service>
        default_factory( common::connection_iface *, const std::string & )
        {
            return vtrc::shared_ptr<gpb::Service>( );
        }

        typedef common::protocol_iface::call_type call_type;
    }

    struct application::impl {

        common::enviroment         env_;
        VTRC_ASIO::io_service     *ios_;
        const bool                 own_ios_;

        VTRC_ASIO::io_service     *rpc_ios_;
        const bool                 own_rpc_ios_;

        vtrc::shared_ptr<common::connection_list> clients_;

        service_factory_type        factory_;

        impl( const impl & );
        impl & operator = ( const impl & );

        impl( )
            :ios_(new VTRC_ASIO::io_service)
            ,own_ios_(true)
            ,rpc_ios_(ios_)
            ,own_rpc_ios_(false)
            ,clients_(common::connection_list::create( ))
            ,factory_(&default_factory)
        { }

        impl( VTRC_ASIO::io_service *ios )
            :ios_(ios)
            ,own_ios_(false)
            ,rpc_ios_(ios)
            ,own_rpc_ios_(false)
            ,clients_(common::connection_list::create( ))
            ,factory_(&default_factory)
        { }

        impl( VTRC_ASIO::io_service *ios, VTRC_ASIO::io_service *rpc_ios )
            :ios_(ios)
            ,own_ios_(false)
            ,rpc_ios_(rpc_ios)
            ,own_rpc_ios_(false)
            ,clients_(common::connection_list::create( ))
            ,factory_(&default_factory)
        { }

        static bool close_all_connection( common::connection_iface_sptr next )
        {
            next->close( );
            return true;
        }

        void stop_all_clients( )
        {
            clients_->foreach_while( close_all_connection );
        }

        ~impl( )
        { try {

            stop_all_clients( );
            clients_->clear( );

            if( own_ios_ )     delete ios_;
            if( own_rpc_ios_ ) delete rpc_ios_;

        } catch ( ... ) {
            ;;;
        } }

        common::enviroment &get_enviroment( )
        {
            return env_;
        }

        VTRC_ASIO::io_service &get_io_service( )
        {
            return *ios_;
        }

        VTRC_ASIO::io_service &get_rpc_service( )
        {
            return *rpc_ios_;
        }

        vtrc::shared_ptr<common::connection_list> get_clients( )
        {
            return clients_;
        }

    };

    application::application(  )
        :impl_(new impl)
    { }

    application::application(common::pool_pair &pools)
        :impl_(new impl(&pools.get_io_service( ), &pools.get_rpc_service( )))
    {

    }

    application::application( VTRC_ASIO::io_service &ios )
        :impl_(new impl(&ios))
    { }

    application::application( VTRC_ASIO::io_service &ios,
                              VTRC_ASIO::io_service &rpc_ios)
        :impl_(new impl(&ios, &rpc_ios))
    { }

    application::~application( )
    {
        delete impl_;
    }

    void application::stop_all_clients( )
    {
        impl_->stop_all_clients( );
    }

    common::enviroment &application::get_enviroment( )
    {
        return impl_->get_enviroment( );
    }

    VTRC_ASIO::io_service &application::get_io_service( )
    {
        return impl_->get_io_service( );
    }

    VTRC_ASIO::io_service &application::get_rpc_service( )
    {
        return impl_->get_rpc_service( );
    }

    const common::enviroment &application::get_enviroment( )  const
    {
        return impl_->get_enviroment( );
    }

    const VTRC_ASIO::io_service &application::get_io_service( )  const
    {
        return impl_->get_io_service( );
    }

    const VTRC_ASIO::io_service &application::get_rpc_service( ) const
    {
        return impl_->get_rpc_service( );
    }

    vtrc::shared_ptr<common::connection_list> application::get_clients()
    {
        return impl_->get_clients( );
    }

    void application::execute( common::protocol_iface::call_type call )
    {
        impl_->rpc_ios_->post( call );
    }

    void application::assign_service_factory( service_factory_type factory )
    {
        impl_->factory_ = factory ? factory : &default_factory;
    }

    void application::configure_session( common::connection_iface *  /*c*/,
                                         rpc::session_options & /*opts*/ )
    {
        /// use default settings
    }

    common::rpc_service_wrapper_sptr application::get_service_by_name(
                                    common::connection_iface * connection,
                                    const std::string &        service_name)
    {
        vtrc::shared_ptr<gpb::Service> svc =
                     impl_->factory_( connection, service_name );
        return svc ? vtrc::make_shared<common::rpc_service_wrapper>( svc )
                   : common::rpc_service_wrapper_sptr( );
    }

    std::string application::get_session_key(common::connection_iface * /*c*/,
                                             const std::string & /*id*/ )
    {
        return std::string( );
    }

    bool application::session_key_required( common::connection_iface * /*conn*/,
                                            const std::string & /*id*/)
    {
        return false;
    }

}}
<|endoftext|>


<commit_before>// See copyright notice in file Copyright in the root directory of this archive.

#include "warped.h"
#include "Application.h"
#include "WarpedMain.h"
#include "SimulationConfiguration.h"
#include "Simulation.h"
#include "Spinner.h"
#include <string>
#include <fstream>
#include <iostream>
#include <unistd.h>
#include <sstream>
#include <cstdio>
#include <algorithm>

// We need these to register their deserializers
#include "CirculateInitializationMessage.h"
#include "DeserializerManager.h"
#include "EventMessage.h"
#include "GVTUpdateMessage.h"
#include "InitializationMessage.h"
#include "IntVTime.h"
#include "MatternGVTMessage.h"
#include "NegativeEventMessage.h"
#include "NegativeEvent.h"
#include "RestoreCkptMessage.h"
#include "StartMessage.h"
#include "TerminateToken.h"
#include "WarpedMain.h"

using std::string;
using std::fstream;
using std::ofstream;
using std::ifstream;
using std::istringstream;
using std::cout;
using std::cerr;
using std::cin;
using std::endl;

// maximum length of command line arguments
#define MAX_COMMAND_LINE_LENGTH 256

ArgumentParser::ArgRecord *
WarpedMain::getArgumentList( WarpedMain &main ) {
  static ArgumentParser::ArgRecord args[] = {
    {"-configuration", "specify configuration file", &main.configurationFileName,
     ArgumentParser::STRING, false},
    {"-simulateUntil", "specify a simulation end time", &main.simulateUntil,
     ArgumentParser::STRING, false},
    {"-debug", "display debug messages", &main.debugFlag,
     ArgumentParser::BOOLEAN, false},
    {"", ""}
  };

  return args;
};

WarpedMain::WarpedMain( Application *initApplication ) :
  errors( 0 ),
  warnings( 0 ),
  configurationFileName( "" ),
  debugFlag( false ),
  simulateUntil( "" ),
  myApplication( initApplication ),
  mySimulation( 0 ){}

WarpedMain::~WarpedMain()
{
	delete mySimulation;
	delete myApplication;
}

void
WarpedMain::displayParameters( string executableName ){
  ArgumentParser ap( getArgumentList( *this ) );
  ap.printUsage( executableName, cerr );
}

bool
WarpedMain::checkConfigFile( string configFileName ){
  string choice;
  if( configFileName == "" ){
    cerr << "A Simulation Configuration File has not been specified" << endl;
    cerr << "Shall I create a default configuration: [y/n]: ";
    cin >> choice;
    // we are going to uppercase whatever the choice is ...
    string upChoice = choice;
    std::transform(upChoice.begin(), upChoice.end(), upChoice.begin(),(int(*)(int)) std::toupper);

    if( upChoice == "Y" ){
      cerr << "Creating default configuration file: simulation.conf"
	   << endl;
      cerr << "This has not been implemented yet ..." << endl;
      exit(-1);
    }
  }
  return true;
}

void
WarpedMain::registerKernelDeserializers(){
  CirculateInitializationMessage::registerDeserializer();
  EventMessage::registerDeserializer();
  GVTUpdateMessage::registerDeserializer();
  InitializationMessage::registerDeserializer();
  IntVTime::registerDeserializer();
  MatternGVTMessage::registerDeserializer();
  NegativeEvent::registerDeserializer();
  NegativeEventMessage::registerDeserializer();
  RestoreCkptMessage::registerDeserializer();
  StartMessage::registerDeserializer();
  TerminateToken::registerDeserializer();
}

vector<string>
WarpedMain::buildArgumentVector( int argc, char **argv ){
  vector<string> retval;
  for( int i = 0; i < argc; i++ ){
    retval.push_back( string( argv[i] ) );
  }
  return retval;
}

SimulationConfiguration *
WarpedMain::readConfiguration( const string &configurationFileName,
			       const vector<string> &argumentVector ){
  SimulationConfiguration *configuration = 0;
  if( configurationFileName != "" ){
    if( checkConfigFile( configurationFileName ) == false ){
      cerr << "Can't read configuration file " << configurationFileName << endl;
      exit( -1 );
    }
    configuration = SimulationConfiguration::parseConfiguration( configurationFileName,
								 argumentVector );
    if( configuration == 0 ){
      cerr << "There was a problem parsing configuration " << configurationFileName
	   << ", exiting." << endl;
      exit( -1 );
    } else {
      cerr << "Using configuration file: " << configurationFileName << endl;
    }
  }
  return configuration;
}

void
WarpedMain::initializeSimulation( vector<string> &commandLineArgs ){
  registerKernelDeserializers();
  myApplication->registerDeserializers();

  ArgumentParser ap( getArgumentList( *this ));
  ap.checkArgs( commandLineArgs, false );

  if( debugFlag == true ){
    utils::enableDebug();
    utils::debug << "Debug output enabled with -debug" << endl;
  }

  SimulationConfiguration *configuration =
          readConfiguration( configurationFileName, commandLineArgs );

  if( configuration != 0 ){
    Spinner::spinIfRequested( "SpinBeforeConfiguration", *configuration );
  }
  // We have to let the application initialize before we can do much else.
  myApplication->initialize( commandLineArgs );

  // else, configuration is NULL, and we'll run with a default configuration
  mySimulation = Simulation::instance( configuration, myApplication );
  mySimulation->initialize();

  delete configuration;
}

void
WarpedMain::simulate( const VTime &simulateUntil ){
  mySimulation->simulate( simulateUntil );
}

bool
WarpedMain::simulationComplete( ){
  return mySimulation->simulationComplete();
}

void
WarpedMain::finalize(){
  mySimulation->finalize();
}

const VTime &
WarpedMain::getCommittedTime(){
  return mySimulation->getCommittedTime();
}

const VTime &
WarpedMain::getNextEventTime(){
  return mySimulation->getNextEventTime();
}

int
WarpedMain::main( int argc, char **argv ){
  vector<string> args = buildArgumentVector( argc, argv );
  initializeSimulation( args );

  if (simulateUntil == "") {
    simulate( myApplication->getPositiveInfinity() );
  }
  else {
    simulate( myApplication->getTime(simulateUntil));
  }

  finalize();

  return errors;
}
<commit_msg>fixing TCPSelect<commit_after>// See copyright notice in file Copyright in the root directory of this archive.

#include "warped.h"
#include "Application.h"
#include "WarpedMain.h"
#include "SimulationConfiguration.h"
#include "Simulation.h"
#include "Spinner.h"
#include <string>
#include <fstream>
#include <iostream>
#include <unistd.h>
#include <sstream>
#include <cstdio>
#include <algorithm>

// We need these to register their deserializers
#include "CirculateInitializationMessage.h"
#include "DeserializerManager.h"
#include "EventMessage.h"
#include "GVTUpdateMessage.h"
#include "InitializationMessage.h"
#include "IntVTime.h"
#include "MatternGVTMessage.h"
#include "NegativeEventMessage.h"
#include "NegativeEvent.h"
#include "RestoreCkptMessage.h"
#include "StartMessage.h"
#include "TerminateToken.h"
#include "WarpedMain.h"

using std::string;
using std::fstream;
using std::ofstream;
using std::ifstream;
using std::istringstream;
using std::cout;
using std::cerr;
using std::cin;
using std::endl;

// maximum length of command line arguments
#define MAX_COMMAND_LINE_LENGTH 256

ArgumentParser::ArgRecord *
WarpedMain::getArgumentList( WarpedMain &main ) {
  static ArgumentParser::ArgRecord args[] = {
    {"-configuration", "specify configuration file", &main.configurationFileName,
     ArgumentParser::STRING, false},
    {"-simulateUntil", "specify a simulation end time", &main.simulateUntil,
     ArgumentParser::STRING, false},
    {"-debug", "display debug messages", &main.debugFlag,
     ArgumentParser::BOOLEAN, false},
    {"", ""}
  };

  return args;
};

WarpedMain::WarpedMain( Application *initApplication ) :
  errors( 0 ),
  warnings( 0 ),
  configurationFileName( "" ),
  debugFlag( false ),
  simulateUntil( "" ),
  myApplication( initApplication ),
  mySimulation( 0 ){}

WarpedMain::~WarpedMain()
{
	delete mySimulation;
	delete myApplication;
}

void
WarpedMain::displayParameters( string executableName ){
  ArgumentParser ap( getArgumentList( *this ) );
  ap.printUsage( executableName, cerr );
}

bool
WarpedMain::checkConfigFile( string configFileName ){
  string choice;
  if( configFileName == "" ){
    cerr << "A Simulation Configuration File has not been specified" << endl;
    cerr << "Shall I create a default configuration: [y/n]: ";
    cin >> choice;
    // we are going to uppercase whatever the choice is ...
    string upChoice = choice;
    std::transform(upChoice.begin(), upChoice.end(), upChoice.begin(),(int(*)(int)) std::toupper);

    if( upChoice == "Y" ){
      cerr << "Creating default configuration file: simulation.conf"
	   << endl;
      cerr << "This has not been implemented yet ..." << endl;
      exit(-1);
    }
  }
  return true;
}

void
WarpedMain::registerKernelDeserializers(){
  CirculateInitializationMessage::registerDeserializer();
  EventMessage::registerDeserializer();
  GVTUpdateMessage::registerDeserializer();
  InitializationMessage::registerDeserializer();
  IntVTime::registerDeserializer();
  MatternGVTMessage::registerDeserializer();
  NegativeEvent::registerDeserializer();
  NegativeEventMessage::registerDeserializer();
  RestoreCkptMessage::registerDeserializer();
  StartMessage::registerDeserializer();
  TerminateToken::registerDeserializer();
}

vector<string>
WarpedMain::buildArgumentVector( int argc, char **argv ){
  vector<string> retval;
  for( int i = 0; i < argc; i++ ){
    retval.push_back( string( argv[i] ) );
  }
  return retval;
}

SimulationConfiguration *
WarpedMain::readConfiguration( const string &configurationFileName,
			       const vector<string> &argumentVector ){
  SimulationConfiguration *configuration = 0;
  if( configurationFileName != "" ){
    if( checkConfigFile( configurationFileName ) == false ){
      cerr << "Can't read configuration file " << configurationFileName << endl;
      exit( -1 );
    }
    configuration = SimulationConfiguration::parseConfiguration( configurationFileName,
								 argumentVector );
    if( configuration == 0 ){
      cerr << "There was a problem parsing configuration " << configurationFileName
	   << ", exiting." << endl;
      exit( -1 );
    } else {
      cerr << "Using configuration file: " << configurationFileName << endl;
    }
  }
  return configuration;
}

void
WarpedMain::initializeSimulation( vector<string> &commandLineArgs ){
  registerKernelDeserializers();
  myApplication->registerDeserializers();

  // need to save this this for TCPSelect before ArgumentParser cannibalizes it.
  // TCPSelect uses it to build the argument list for ssh when launching
  // "slave" simulation managers
  vector<string> argsCopy(commandLineArgs);

  ArgumentParser ap( getArgumentList( *this ));
  ap.checkArgs( commandLineArgs, false );

  if( debugFlag == true ){
    utils::enableDebug();
    utils::debug << "Debug output enabled with -debug" << endl;
  }

  SimulationConfiguration *configuration =
          readConfiguration( configurationFileName, argsCopy );

  if( configuration != 0 ){
    Spinner::spinIfRequested( "SpinBeforeConfiguration", *configuration );
  }
  // We have to let the application initialize before we can do much else.
  myApplication->initialize( commandLineArgs );

  // else, configuration is NULL, and we'll run with a default configuration
  mySimulation = Simulation::instance( configuration, myApplication );
  mySimulation->initialize();

  delete configuration;
}

void
WarpedMain::simulate( const VTime &simulateUntil ){
  mySimulation->simulate( simulateUntil );
}

bool
WarpedMain::simulationComplete( ){
  return mySimulation->simulationComplete();
}

void
WarpedMain::finalize(){
  mySimulation->finalize();
}

const VTime &
WarpedMain::getCommittedTime(){
  return mySimulation->getCommittedTime();
}

const VTime &
WarpedMain::getNextEventTime(){
  return mySimulation->getNextEventTime();
}

int
WarpedMain::main( int argc, char **argv ){
  vector<string> args = buildArgumentVector( argc, argv );
  initializeSimulation( args );

  if (simulateUntil == "") {
    simulate( myApplication->getPositiveInfinity() );
  }
  else {
    simulate( myApplication->getTime(simulateUntil));
  }

  finalize();

  return errors;
}
<|endoftext|>


<commit_before>#ifndef ASSIGNEMENTBO_HH
#define ASSIGNEMENTBO_HH
#include <tr1/unordered_set>
using namespace std::tr1;

class ProcessBO;
class MachineBO;

class AssignementBO{
    private:
        unordered_map<ProcessBO*, MachineBO*> assignement_m;
};

#endif
<commit_msg>Suppression de l'entete de AssignementBO, car cette classe est definitivement inutile<commit_after><|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _MSC_VER
#pragma warning( 4: 4786)
#endif

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

#include "BZAdminClient.h"
#include "BZAdminUI.h"
#include "OptionParser.h"
#include "UIMap.h"

// causes persistent rebuilding to obtain build versioning
#include "version.h"

int debugLevel = 0;

#ifdef _WIN32
void Player::setDeadReckoning()
{
}
#endif
/** @file
    This is the main file for bzadmin, the bzflag text client.
*/

int main(int argc, char** argv) {
  bool earlyQuit = false;

  // FIXME - build this into OptionParser (VariableSimple parser?)
  if ((argc > 1) && (strcmp (argv[1], "-q") == 0)) {
    earlyQuit = true;
    argv[1] = argv[0]; // eat the option
    argv++;
    argc--;
  }

#ifdef _WIN32
  // startup winsock
  {
    static const int major = 2, minor = 2;
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(major, minor), &wsaData)) {
      return 1;
    }
    if (LOBYTE(wsaData.wVersion) != major ||
	HIBYTE(wsaData.wVersion) != minor) {
      WSACleanup();
      return 1;
    }
  }
#endif
  // command line options
  std::string uiName("curses");
  std::vector<std::string> visibleMsgs;
  std::vector<std::string> invisibleMsgs;

  // no curses, use stdboth as default instead
  const UIMap& interfaces = UIMap::instance();
  if (interfaces.find("curses") == interfaces.end())
    uiName = "stdboth";

  // build a usage string with all interfaces
  UIMap::const_iterator uiIter;
  std::string uiUsage;
  for (uiIter = interfaces.begin(); uiIter != interfaces.end(); ++uiIter)
    uiUsage += uiIter->first + '|';
  uiUsage = std::string("[-ui ") + uiUsage.substr(0, uiUsage.size() - 1) + ']';

  // register and parse command line arguments
  OptionParser op(std::string("bzadmin ") + getAppVersion(),
		  "CALLSIGN@HOST[:PORT] [COMMAND] [COMMAND] ...");
  const std::string uiOption("ui");
  const std::string uiMsg = "choose a user interface";
  op.registerVariable(uiOption, uiName, uiUsage, uiMsg);
  op.registerVector("show", visibleMsgs, "[-show msgtype{,msgtype}*]",
		      "tell bzadmin to show these message types");
  op.registerVector("hide", invisibleMsgs, "[-hide msgtype{,msgtype}*]",
		      "tell bzadmin not to show these message types");
  if (!op.parse(argc, argv))
    return 1;

  // check that we have callsign and host in the right format and extract them
  int atPos;
  std::string name = "", host = "";
  if (!(op.getParameters().size() > 0 &&
	(atPos = op.getParameters()[0].find('@')) > 0)) {
    // input callsign and host interactively
    std::cout << "No callsign@host specified.  Please input them" << std::endl;
    std::cout << "Callsign: ";
    std::cin >> name;
    if (name.size() <= 1) {
      std::cerr << "You must specify a callsign.  Exiting." << std::endl;
      return 1;
    }
    std::cout << "Server to connect to: ";
    std::cin >> host;
    if (host.size() <= 1) {
      std::cerr << "You must specify a host name to connect to.  Exiting." << std::endl;
      return 1;
    }
  } else { // callsign/host on command line
    name = op.getParameters()[0].substr(0, atPos);
    host = op.getParameters()[0].substr(atPos + 1);
  }

  int port = ServerPort;
  int cPos = host.find(':');
  if (cPos != -1) {
    port = atoi(host.substr(cPos + 1).c_str());
    host = host.substr(0, cPos);
  }

  // check that the ui is valid
  uiIter = UIMap::instance().find(uiName);
  if (uiIter == UIMap::instance().end()) {
    std::cerr<<"There is no interface called \""<<uiName<<"\"."<<std::endl;
    return 1;
  }

  // try to connect
  BZAdminClient client(name, host, port);
  if (!client.isValid())
    return 1;
  unsigned int i;
  for (i = 0; i < visibleMsgs.size(); ++i)
    client.showMessageType(visibleMsgs[i]);
  for (i = 0; i < invisibleMsgs.size(); ++i)
    client.ignoreMessageType(invisibleMsgs[i]);

  // if we got commands as arguments, send them and exit
  if (op.getParameters().size() > 1) {
    for (unsigned int i = 1; i < op.getParameters().size(); ++i)
      client.sendMessage(op.getParameters()[i], AllPlayers);

    if (earlyQuit) {
      client.waitForServer();
      return 0;
    }
  }

  // Print a friendly warning
  if (earlyQuit)
    std::cout << "WARNING: didn't quit early, no command line commands" << std::endl;

  // create UI and run the main loop
  BZAdminUI*  ui = uiIter->second(client);
  client.setUI(ui);
  client.runLoop();
  delete ui;

  return 0;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>removed the C hack, just use /quit to leave early<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _MSC_VER
#pragma warning( 4: 4786)
#endif

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

#include "BZAdminClient.h"
#include "BZAdminUI.h"
#include "OptionParser.h"
#include "UIMap.h"

// causes persistent rebuilding to obtain build versioning
#include "version.h"

int debugLevel = 0;

#ifdef _WIN32
void Player::setDeadReckoning()
{
}
#endif
/** @file
    This is the main file for bzadmin, the bzflag text client.
*/

int main(int argc, char** argv) {

#ifdef _WIN32
  // startup winsock
  {
    static const int major = 2, minor = 2;
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(major, minor), &wsaData)) {
      return 1;
    }
    if (LOBYTE(wsaData.wVersion) != major ||
	HIBYTE(wsaData.wVersion) != minor) {
      WSACleanup();
      return 1;
    }
  }
#endif
  // command line options
  std::string uiName("curses");
  std::vector<std::string> visibleMsgs;
  std::vector<std::string> invisibleMsgs;

  // no curses, use stdboth as default instead
  const UIMap& interfaces = UIMap::instance();
  if (interfaces.find("curses") == interfaces.end())
    uiName = "stdboth";

  // build a usage string with all interfaces
  UIMap::const_iterator uiIter;
  std::string uiUsage;
  for (uiIter = interfaces.begin(); uiIter != interfaces.end(); ++uiIter)
    uiUsage += uiIter->first + '|';
  uiUsage = std::string("[-ui ") + uiUsage.substr(0, uiUsage.size() - 1) + ']';

  // register and parse command line arguments
  OptionParser op(std::string("bzadmin ") + getAppVersion(),
		  "CALLSIGN@HOST[:PORT] [COMMAND] [COMMAND] ...");
  const std::string uiOption("ui");
  const std::string uiMsg = "choose a user interface";
  op.registerVariable(uiOption, uiName, uiUsage, uiMsg);
  op.registerVector("show", visibleMsgs, "[-show msgtype{,msgtype}*]",
		      "tell bzadmin to show these message types");
  op.registerVector("hide", invisibleMsgs, "[-hide msgtype{,msgtype}*]",
		      "tell bzadmin not to show these message types");
  if (!op.parse(argc, argv))
    return 1;

  // check that we have callsign and host in the right format and extract them
  int atPos;
  std::string name = "", host = "";
  if (!(op.getParameters().size() > 0 &&
	(atPos = op.getParameters()[0].find('@')) > 0)) {
    // input callsign and host interactively
    std::cout << "No callsign@host specified.  Please input them" << std::endl;
    std::cout << "Callsign: ";
    std::cin >> name;
    if (name.size() <= 1) {
      std::cerr << "You must specify a callsign.  Exiting." << std::endl;
      return 1;
    }
    std::cout << "Server to connect to: ";
    std::cin >> host;
    if (host.size() <= 1) {
      std::cerr << "You must specify a host name to connect to.  Exiting." << std::endl;
      return 1;
    }
  } else { // callsign/host on command line
    name = op.getParameters()[0].substr(0, atPos);
    host = op.getParameters()[0].substr(atPos + 1);
  }

  int port = ServerPort;
  int cPos = host.find(':');
  if (cPos != -1) {
    port = atoi(host.substr(cPos + 1).c_str());
    host = host.substr(0, cPos);
  }

  // check that the ui is valid
  uiIter = UIMap::instance().find(uiName);
  if (uiIter == UIMap::instance().end()) {
    std::cerr<<"There is no interface called \""<<uiName<<"\"."<<std::endl;
    return 1;
  }

  // try to connect
  BZAdminClient client(name, host, port);
  if (!client.isValid())
    return 1;
  unsigned int i;
  for (i = 0; i < visibleMsgs.size(); ++i)
    client.showMessageType(visibleMsgs[i]);
  for (i = 0; i < invisibleMsgs.size(); ++i)
    client.ignoreMessageType(invisibleMsgs[i]);

  // if we got commands as arguments, send them and exit
  if (op.getParameters().size() > 1) {
    for (unsigned int i = 1; i < op.getParameters().size(); ++i) {
      if (op.getParameters()[i] == "/quit") {
        client.waitForServer();
        return 0;
      }
      client.sendMessage(op.getParameters()[i], AllPlayers);
    }
  }

  // create UI and run the main loop
  BZAdminUI*  ui = uiIter->second(client);
  client.setUI(ui);
  client.runLoop();
  delete ui;

  return 0;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "common.h"
#include "CustomZone.h"

/* system headers */
#include <sstream>
#include "math.h"

/* local implementation headers */
#include "EntryZones.h"
#include "Flag.h"
#include "Team.h"

CustomZone::CustomZone()
{
  pos[0] = pos[1] = pos[2] = 0.0f;
  rotation = 0.0f;
  size[0] = size[1] = size[2] = 1.0f;
}

bool CustomZone::read(const char *cmd, std::istream& input) {
  if (strcmp(cmd, "flag") == 0) {
    std::string args, flag;

    std::getline(input, args);
    std::istringstream  parms(args);

    while (parms >> flag) {
      FlagType *type;

      if (flag == "good") {
        FlagSet &fs = Flag::getGoodFlags();
	for (FlagSet::iterator it = fs.begin(); it != fs.end(); ++it) {
	  FlagType *f = *it;
	  if (f->endurance != FlagNormal) { // Null and Team flags
	    qualifiers.push_back(f->flagAbbv);
	  }
	}
      }
      else if (flag == "bad") {
	FlagSet &fs = Flag::getBadFlags();
	for (FlagSet::iterator it = fs.begin(); it != fs.end(); ++it) {
	  FlagType *f = *it;
	  if (f->endurance != FlagNormal) { // Null and Team flags
	    qualifiers.push_back(f->flagAbbv);
	  }
	}
      }
      else {
        type = Flag::getDescFromAbbreviation(flag.c_str());
        if (type == Flags::Null)
          return false;
        qualifiers.push_back(flag);
      }
    }
    input.putback('\n');
    if (qualifiers.size() == 0)
      return false;
  }
  else if ((strcmp(cmd, "team") == 0) || (strcmp(cmd, "safety") == 0)) {
    std::string args;
    int color;

    std::getline(input, args);
    std::istringstream  parms(args);

    while (parms >> color) {
      if ((color < 0) || (color >= CtfTeams))
        return false;
      std::string qual = std::string(Team::getName((TeamColor)color));
      if (strcmp(cmd, "safety") == 0) {
        qual = EntryZones::getSafetyPrefix() + qual;
      }
      qualifiers.push_back(qual);
    }
    input.putback('\n');
    if (qualifiers.size() == 0)
      return false;
  }
  else if (!WorldFileLocation::read(cmd, input))
      return false;

  return true;
}

void CustomZone::write(WorldInfo* worldInfo) const
{
  worldInfo->addZone( this );
}

void CustomZone::getRandomPoint(float *pt) const
{
  float x = (float)((bzfrand() * (2.0f * size[0])) - size[0]);
  float y = (float)((bzfrand() * (2.0f * size[1])) - size[1]);
  pt[2] = (float)(bzfrand() * size[2]);

  pt[0] = x * cosf(rotation) - y * sinf(rotation);
  pt[1] = x * sinf(rotation) + y * cosf(rotation);

  pt[0] += pos[0];
  pt[1] += pos[1];
  pt[2] += pos[2];
}

float CustomZone::getDistToPoint (const float *_pos) const
{
  // FIXME - should use proper minimum distance from
  // the zone edge, and maybe -1.0f if its inside the zone
  float v[3], dist;
  v[0] = _pos[0] - pos[0];
  v[1] = _pos[1] - pos[1];
  v[2] = _pos[2] - pos[2];
  dist = sqrtf (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);

  return dist;
}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>math.h isn't a bzflag file.<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "CustomZone.h"
#include "common.h"

/* system headers */
#include <sstream>
#include <math.h>

/* local implementation headers */
#include "EntryZones.h"
#include "Flag.h"
#include "Team.h"

CustomZone::CustomZone()
{
  pos[0] = pos[1] = pos[2] = 0.0f;
  rotation = 0.0f;
  size[0] = size[1] = size[2] = 1.0f;
}

bool CustomZone::read(const char *cmd, std::istream& input) {
  if (strcmp(cmd, "flag") == 0) {
    std::string args, flag;

    std::getline(input, args);
    std::istringstream  parms(args);

    while (parms >> flag) {
      FlagType *type;

      if (flag == "good") {
        FlagSet &fs = Flag::getGoodFlags();
	for (FlagSet::iterator it = fs.begin(); it != fs.end(); ++it) {
	  FlagType *f = *it;
	  if (f->endurance != FlagNormal) { // Null and Team flags
	    qualifiers.push_back(f->flagAbbv);
	  }
	}
      }
      else if (flag == "bad") {
	FlagSet &fs = Flag::getBadFlags();
	for (FlagSet::iterator it = fs.begin(); it != fs.end(); ++it) {
	  FlagType *f = *it;
	  if (f->endurance != FlagNormal) { // Null and Team flags
	    qualifiers.push_back(f->flagAbbv);
	  }
	}
      }
      else {
        type = Flag::getDescFromAbbreviation(flag.c_str());
        if (type == Flags::Null)
          return false;
        qualifiers.push_back(flag);
      }
    }
    input.putback('\n');
    if (qualifiers.size() == 0)
      return false;
  }
  else if ((strcmp(cmd, "team") == 0) || (strcmp(cmd, "safety") == 0)) {
    std::string args;
    int color;

    std::getline(input, args);
    std::istringstream  parms(args);

    while (parms >> color) {
      if ((color < 0) || (color >= CtfTeams))
        return false;
      std::string qual = std::string(Team::getName((TeamColor)color));
      if (strcmp(cmd, "safety") == 0) {
        qual = EntryZones::getSafetyPrefix() + qual;
      }
      qualifiers.push_back(qual);
    }
    input.putback('\n');
    if (qualifiers.size() == 0)
      return false;
  }
  else if (!WorldFileLocation::read(cmd, input))
      return false;

  return true;
}

void CustomZone::write(WorldInfo* worldInfo) const
{
  worldInfo->addZone( this );
}

void CustomZone::getRandomPoint(float *pt) const
{
  float x = (float)((bzfrand() * (2.0f * size[0])) - size[0]);
  float y = (float)((bzfrand() * (2.0f * size[1])) - size[1]);
  pt[2] = (float)(bzfrand() * size[2]);

  pt[0] = x * cosf(rotation) - y * sinf(rotation);
  pt[1] = x * sinf(rotation) + y * cosf(rotation);

  pt[0] += pos[0];
  pt[1] += pos[1];
  pt[2] += pos[2];
}

float CustomZone::getDistToPoint (const float *_pos) const
{
  // FIXME - should use proper minimum distance from
  // the zone edge, and maybe -1.0f if its inside the zone
  float v[3], dist;
  v[0] = _pos[0] - pos[0];
  v[1] = _pos[1] - pos[1];
  v[2] = _pos[2] - pos[2];
  dist = sqrtf (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);

  return dist;
}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/******************************************************************************\

          This file is part of the C! library.  A.K.A the cbang library.

              Copyright (c) 2003-2015, Cauldron Development LLC
                 Copyright (c) 2003-2015, Stanford University
                             All rights reserved.

        The C! library is free software: you can redistribute it and/or
        modify it under the terms of the GNU Lesser General Public License
        as published by the Free Software Foundation, either version 2.1 of
        the License, or (at your option) any later version.

        The C! 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 the C! library.  If not, see
        <http://www.gnu.org/licenses/>.

        In addition, BSD licensing may be granted on a case by case basis
        by written permission from at least one of the copyright holders.
        You may request written permission by emailing the authors.

                For information regarding this software email:
                               Joseph Coffland
                        joseph@cauldrondevelopment.com

\******************************************************************************/

#include "Thread.h"

#include "ThreadLocalStorage.h"
#include "SysError.h"
#include "SystemUtilities.h"

#include <cbang/Exception.h>

#include <cbang/util/DefaultCatch.h>
#include <cbang/log/Logger.h>
#include <cbang/debug/Debugger.h>

#include <exception>

#ifdef _WIN32
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>

#else // pthreads
#include <signal.h>
#include <pthread.h>
#include <errno.h>
#endif

#ifdef __APPLE__
#include <sched.h>
#endif // __APPLE__

#ifdef HAVE_VALGRIND
#include <valgrind/drd.h>
#include <valgrind/helgrind.h>
#endif

using namespace std;
using namespace cb;

namespace cb {
  struct Thread::private_t {
#ifdef _WIN32
    HANDLE h;
    DWORD id;

#else // pthreads
    pthread_t thread;
#endif
  };
};

#ifdef _WIN32
static DWORD WINAPI start_func(LPVOID t) {
  ((Thread *)t)->starter();
  return 0;
}

#else // pthreads
static void *start_func(void *t) {
  ((Thread *)t)->starter();
  return 0;
}
#endif

ThreadLocalStorage<Thread *> Thread::threads;

Thread::Thread(bool destroy) :
  p(new Thread::private_t), state(THREAD_STOPPED), shutdown(false),
  destroy(destroy), id(getNextID()), exitStatus(0) {

  threads.set(this);

#ifdef HAVE_VALGRIND
  VALGRIND_HG_DISABLE_CHECKING(state, sizeof(state));
  DRD_IGNORE_VAR((const state_t &)state);
  VALGRIND_HG_DISABLE_CHECKING(shutdown, sizeof(shutdown));
  DRD_IGNORE_VAR((const bool &)shutdown);
#endif // HAVE_VALGRIND
}

Thread::~Thread() {
  if (state != THREAD_STOPPED)
    LOG_ERROR(Exception(SSTR("Thread " << getID()
                             << " deallocated while still active")));

  if (p) {
    delete p;
    p = 0;
  }
}

bool Thread::isRunning() const {
  return state == THREAD_STARTING || state == THREAD_RUNNING;
}

void Thread::start() {
  if (state != THREAD_STOPPED) join();

  state = THREAD_STARTING;
  exitStatus = 0;
  shutdown = false;

#ifdef _WIN32
  p->h = CreateThread(0, 0, start_func, this, 0, &p->id);
  int error = !p->h;

#else // pthreads
  int error = pthread_create(&p->thread, 0, start_func, this);
#endif

  if (error) {
    state = THREAD_STOPPED;

    string msg = "Unknown error";

#ifdef _WIN32
    msg = SysError().toString();

#else
    switch (error) {
    case EAGAIN: msg = "Insufficient resources"; break;
    case EINVAL: msg = "Invalid setting"; break;
    case EPERM: msg = "Permission denied"; break;
    }
#endif

    THROWS("Error creating thread: " << msg);
  }
}

void Thread::stop() {
  shutdown = true;
}

void Thread::join() {
  if (state == THREAD_STOPPED) return;

  if (!shutdown) stop();
  wait();
}

void Thread::wait() {
  if (state == THREAD_STOPPED) return;

#ifdef _WIN32
  WaitForSingleObject(p->h, INFINITE);
  CloseHandle(p->h);

#else // pthreads
  pthread_join(p->thread, 0);
#endif

  state = THREAD_STOPPED;
}

void Thread::cancel() {
  stop();

#ifdef _WIN32
  if (TerminateThread(p->h, 0)) state = THREAD_DONE;

#else // pthreads
  if (pthread_cancel(p->thread) == 0) state = THREAD_DONE;
#endif
}

void Thread::kill(int signal) {
#ifdef _WIN32
  TerminateThread(p->h, -1);
#else
  pthread_kill(p->thread, signal);
#endif
}

void Thread::yield() {
#ifdef _WIN32
  SwitchToThread();
#elif defined(__APPLE__)
  sched_yield();
#else
  pthread_yield();
#endif
}

uint64_t Thread::self() {
#ifdef _WIN32
  return (uint64_t)GetCurrentThreadId();
#else
  return (uint64_t)pthread_self();
#endif
}

Thread &Thread::current() {
  return *threads.get();
}

void Thread::starter() {
  state = THREAD_RUNNING;

  try {
    Logger::instance().setThreadID(getID());
    LOG_INFO(5, "Started thread " << getID() << " on PID "
             << SystemUtilities::getPID());
    run();
    done();
    return;

  } CATCH(LOG_ERROR_LEVEL, ": In thread " << id);

  exitStatus = -1;
  done();
}

void Thread::done() {
  state = THREAD_DONE;

  if (destroy) {
    state = THREAD_STOPPED;

#ifdef _WIN32
    CloseHandle(p->h);
#endif

    try {
      delete this;
    } CATCH_ERROR;
  }
}
<commit_msg>Posix thread which destroys itself must call pthread_detach()<commit_after>/******************************************************************************\

          This file is part of the C! library.  A.K.A the cbang library.

              Copyright (c) 2003-2015, Cauldron Development LLC
                 Copyright (c) 2003-2015, Stanford University
                             All rights reserved.

        The C! library is free software: you can redistribute it and/or
        modify it under the terms of the GNU Lesser General Public License
        as published by the Free Software Foundation, either version 2.1 of
        the License, or (at your option) any later version.

        The C! 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 the C! library.  If not, see
        <http://www.gnu.org/licenses/>.

        In addition, BSD licensing may be granted on a case by case basis
        by written permission from at least one of the copyright holders.
        You may request written permission by emailing the authors.

                For information regarding this software email:
                               Joseph Coffland
                        joseph@cauldrondevelopment.com

\******************************************************************************/

#include "Thread.h"

#include "ThreadLocalStorage.h"
#include "SysError.h"
#include "SystemUtilities.h"

#include <cbang/Exception.h>

#include <cbang/util/DefaultCatch.h>
#include <cbang/log/Logger.h>
#include <cbang/debug/Debugger.h>

#include <exception>

#ifdef _WIN32
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>

#else // pthreads
#include <signal.h>
#include <pthread.h>
#include <errno.h>
#endif

#ifdef __APPLE__
#include <sched.h>
#endif // __APPLE__

#ifdef HAVE_VALGRIND
#include <valgrind/drd.h>
#include <valgrind/helgrind.h>
#endif

using namespace std;
using namespace cb;

namespace cb {
  struct Thread::private_t {
#ifdef _WIN32
    HANDLE h;
    DWORD id;

#else // pthreads
    pthread_t thread;
#endif
  };
};

#ifdef _WIN32
static DWORD WINAPI start_func(LPVOID t) {
  ((Thread *)t)->starter();
  return 0;
}

#else // pthreads
static void *start_func(void *t) {
  ((Thread *)t)->starter();
  return 0;
}
#endif

ThreadLocalStorage<Thread *> Thread::threads;

Thread::Thread(bool destroy) :
  p(new Thread::private_t), state(THREAD_STOPPED), shutdown(false),
  destroy(destroy), id(getNextID()), exitStatus(0) {

  threads.set(this);

#ifdef HAVE_VALGRIND
  VALGRIND_HG_DISABLE_CHECKING(state, sizeof(state));
  DRD_IGNORE_VAR((const state_t &)state);
  VALGRIND_HG_DISABLE_CHECKING(shutdown, sizeof(shutdown));
  DRD_IGNORE_VAR((const bool &)shutdown);
#endif // HAVE_VALGRIND
}

Thread::~Thread() {
  if (state != THREAD_STOPPED)
    LOG_ERROR(Exception(SSTR("Thread " << getID()
                             << " deallocated while still active")));

  if (p) {
    delete p;
    p = 0;
  }
}

bool Thread::isRunning() const {
  return state == THREAD_STARTING || state == THREAD_RUNNING;
}

void Thread::start() {
  if (state != THREAD_STOPPED) join();

  state = THREAD_STARTING;
  exitStatus = 0;
  shutdown = false;

#ifdef _WIN32
  p->h = CreateThread(0, 0, start_func, this, 0, &p->id);
  int error = !p->h;

#else // pthreads
  int error = pthread_create(&p->thread, 0, start_func, this);
#endif

  if (error) {
    state = THREAD_STOPPED;

    string msg = "Unknown error";

#ifdef _WIN32
    msg = SysError().toString();

#else
    switch (error) {
    case EAGAIN: msg = "Insufficient resources"; break;
    case EINVAL: msg = "Invalid setting"; break;
    case EPERM: msg = "Permission denied"; break;
    }
#endif

    THROWS("Error creating thread: " << msg);
  }
}

void Thread::stop() {
  shutdown = true;
}

void Thread::join() {
  if (state == THREAD_STOPPED) return;

  if (!shutdown) stop();
  wait();
}

void Thread::wait() {
  if (state == THREAD_STOPPED) return;

#ifdef _WIN32
  WaitForSingleObject(p->h, INFINITE);
  CloseHandle(p->h);

#else // pthreads
  pthread_join(p->thread, 0);
#endif

  state = THREAD_STOPPED;
}

void Thread::cancel() {
  stop();

#ifdef _WIN32
  if (TerminateThread(p->h, 0)) state = THREAD_DONE;

#else // pthreads
  if (pthread_cancel(p->thread) == 0) state = THREAD_DONE;
#endif
}

void Thread::kill(int signal) {
#ifdef _WIN32
  TerminateThread(p->h, -1);
#else
  pthread_kill(p->thread, signal);
#endif
}

void Thread::yield() {
#ifdef _WIN32
  SwitchToThread();
#elif defined(__APPLE__)
  sched_yield();
#else
  pthread_yield();
#endif
}

uint64_t Thread::self() {
#ifdef _WIN32
  return (uint64_t)GetCurrentThreadId();
#else
  return (uint64_t)pthread_self();
#endif
}

Thread &Thread::current() {
  return *threads.get();
}

void Thread::starter() {
  state = THREAD_RUNNING;

  try {
    Logger::instance().setThreadID(getID());
    LOG_INFO(5, "Started thread " << getID() << " on PID "
             << SystemUtilities::getPID());
    run();
    done();
    return;

  } CATCH(LOG_ERROR_LEVEL, ": In thread " << id);

  exitStatus = -1;
  done();
}

void Thread::done() {
  state = THREAD_DONE;

  if (destroy) {
    state = THREAD_STOPPED;

#ifdef _WIN32
    CloseHandle(p->h);
#else
    pthread_detach(p->thread);
#endif

    try {
      delete this;
    } CATCH_ERROR;
  }
}
<|endoftext|>


<commit_before>#pragma once
/*
* Covariant Mozart Utility Library: Traits
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2016 Michael Lee(李登淳)
* Email: China-LDC@outlook.com
* Github: https://github.com/mikecovlee
* Website: http://ldc.atd3.cn
*
* Version: 17.2.0
*/
#include <utility>
namespace cov {
	template < typename T, typename X > struct is_same_type {
		static constexpr bool value=false;
	};
	template < typename T > struct is_same_type<T,T> {
		static constexpr bool value=true;
	};
	template < typename T > struct is_constant {
		static constexpr bool value=false;
	};
	template < typename T > struct is_constant<T const> {
		static constexpr bool value=true;
	};
	template < typename _Tp > struct add_reference {
		typedef _Tp& type;
	};
	template < typename _Tp > struct add_reference<_Tp&> {
		typedef _Tp& type;
	};
	template < typename _Tp > struct add_reference<_Tp&&> {
		typedef _Tp&& type;
	};
	template < typename _Tp > struct add_reference<_Tp*> {
		typedef _Tp* type;
	};
	template < typename _Tp > struct add_constant_reference {
		typedef const _Tp& type;
	};
	template < typename _Tp > struct add_constant_reference<_Tp&> {
		typedef const _Tp& type;
	};
	template < typename _Tp > struct add_constant_reference<const _Tp&> {
		typedef const _Tp& type;
	};
	template < typename _Tp > struct add_constant_reference<_Tp&&> {
		typedef const _Tp&& type;
	};
	template < typename _Tp > struct add_constant_reference<const _Tp&&> {
		typedef const _Tp&& type;
	};
	template < typename _Tp > struct add_constant_reference<_Tp*> {
		typedef _Tp* type;
	};
	template < typename _Tp > struct add_constant_reference<const _Tp*> {
		typedef const _Tp* type;
	};
	template<bool factor,typename Tx,typename Ty>struct replace_if;
	template<typename Tx,typename Ty>struct replace_if<true,Tx,Ty> {
		using result=Ty;
	};
	template<typename Tx,typename Ty>struct replace_if<false,Tx,Ty> {
		using result=Tx;
	};
	template<typename _Tp,typename _dT>
	class castable final {
		template<typename T>static constexpr bool helper(T*)
		{
			return false;
		}
		template<typename T>static constexpr bool helper(decltype(static_cast<_Tp>(std::declval<T>()))*)
		{
			return true;
		}
	public:
		static constexpr bool value=helper<_dT>(nullptr);
	};
}<commit_msg>完善cov::castable<commit_after>#pragma once
/*
* Covariant Mozart Utility Library: Traits
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2016 Michael Lee(李登淳)
* Email: China-LDC@outlook.com
* Github: https://github.com/mikecovlee
* Website: http://ldc.atd3.cn
*
* Version: 17.2.0
*/
#include <utility>
namespace cov {
	template < typename T, typename X > struct is_same_type {
		static constexpr bool value=false;
	};
	template < typename T > struct is_same_type<T,T> {
		static constexpr bool value=true;
	};
	template < typename T > struct is_constant {
		static constexpr bool value=false;
	};
	template < typename T > struct is_constant<T const> {
		static constexpr bool value=true;
	};
	template < typename _Tp > struct add_reference {
		typedef _Tp& type;
	};
	template < typename _Tp > struct add_reference<_Tp&> {
		typedef _Tp& type;
	};
	template < typename _Tp > struct add_reference<_Tp&&> {
		typedef _Tp&& type;
	};
	template < typename _Tp > struct add_reference<_Tp*> {
		typedef _Tp* type;
	};
	template < typename _Tp > struct add_constant_reference {
		typedef const _Tp& type;
	};
	template < typename _Tp > struct add_constant_reference<_Tp&> {
		typedef const _Tp& type;
	};
	template < typename _Tp > struct add_constant_reference<const _Tp&> {
		typedef const _Tp& type;
	};
	template < typename _Tp > struct add_constant_reference<_Tp&&> {
		typedef const _Tp&& type;
	};
	template < typename _Tp > struct add_constant_reference<const _Tp&&> {
		typedef const _Tp&& type;
	};
	template < typename _Tp > struct add_constant_reference<_Tp*> {
		typedef _Tp* type;
	};
	template < typename _Tp > struct add_constant_reference<const _Tp*> {
		typedef const _Tp* type;
	};
	template<bool factor,typename Tx,typename Ty>struct replace_if;
	template<typename Tx,typename Ty>struct replace_if<true,Tx,Ty> {
		using result=Ty;
	};
	template<typename Tx,typename Ty>struct replace_if<false,Tx,Ty> {
		using result=Tx;
	};
	template<typename From,typename To>
	class castable final {
		template<typename To1>static void test(To1);
		template<typename From1,typename To1>static constexpr bool helper(...)
		{
			return false;
		}
		template<typename From1,typename To1,typename=decltype(test<To1>(std::declval<From1>()))>
		static constexpr bool helper(int)
		{
			return true;
		}
	public:
		static constexpr bool value=helper<From,To>(0);
	};
}
<|endoftext|>


<commit_before>#include <rabit.h>
#include "../io/io.h"

int main(int argc, char *argv[]) {
  using namespace rabit::io;
  if (argc < 2) {
    // intialize rabit engine
    rabit::Init(argc, argv);
    if (rabit::GetRank() == 0) {
      rabit::TrackerPrintf("Usage: <data_in> param=val\n");
    }
    rabit::Finalize();
    return 0;
  }
  rabit::Init(argc, argv);
  int n = 0;
  InputSplit *in = CreateInputSplit(argv[1],
                                    rabit::GetRank(),
                                    rabit::GetWorldSize());
  std::string line;
  while (in->NextLine(&line)) {
    if (n % 100 == 0) {
      rabit::TrackerPrintf("[%d] finishes loading %d lines\n",
                           rabit::GetRank(), n);
    }
    n++;
  }
  delete in;
  rabit::TrackerPrintf("[%d] finishes loading %d lines\n",
                       rabit::GetRank(), n);
  rabit::Finalize();
  return 0;
}
<commit_msg>add debug<commit_after>#include <rabit.h>
#include "../io/io.h"

int main(int argc, char *argv[]) {
  using namespace rabit::io;
  if (argc < 2) {
    // intialize rabit engine
    rabit::Init(argc, argv);
    if (rabit::GetRank() == 0) {
      rabit::TrackerPrintf("Usage: <data_in> param=val\n");
    }
    rabit::Finalize();
    return 0;
  }
  rabit::Init(argc, argv);
  int n = 0;
  InputSplit *in = CreateInputSplit(argv[1],
                                    rabit::GetRank(),
                                    rabit::GetWorldSize());
  std::string line;
  while (in->NextLine(&line)) {
    if (n % 100 == 0) {
      rabit::TrackerPrintf("[%d] finishes loading %d lines\n",
                           rabit::GetRank(), n);
    }
    n++;
  }
  delete in;
  rabit::TrackerPrintf("[%d] ALL finishes loading %d lines\n",
                       rabit::GetRank(), n);
  rabit::Finalize();
  return 0;
}
<|endoftext|>


<commit_before>/*
    Immediately one may notice that (a, b) will repeat across different values
    of n. For example,

        1 / 1 + 1 / 1 = 20 / 10 = 200 / 100 = 2000 / 1000 = ...

    It turns out that each contributes as a distinct solution and we need solutions
    in (a, b, p, n).

    Firstly, we manipulate the given equation to get

        1 / a + 1 / b = p / 10^n
        1 / a = (pb - 10^n) / (10^n * b)        1/b = (pa - 10^n) / (10^n * a)
        (pb - 10^n)a = 10^n * b                 (pb - 10^n)b = 10^n * a

    Multiplying both together, we have

        (pb - 10^n)(pb - 10^n)ab = 10^{2n} * ab
        (pb - 10^n)(pb - 10^n) = 10^{2n}

    Let pb - 10^n = x and pb - 10^n = y so that x <= y and xy = 10^{2n}. In
    principle since n <= 9, then 10^{2n} <= 10^18 = (2^18)(5^18) so the number
    of (x, y) pairs is at most 19 * 19 = 361.

    Next,

        pa = 10^n + x   pb = 10^n + y
        pa / pb = (10^n + x) / (10^n + y)
        a / b = (10^n + x) / (10^n + y)

    For each pair of (x, y), let d = GCD(10^n + x, 10^n + y). Then indeed we have
    solutions (a, b, p, n) can be generated by a positive integer k:

        (a, b, p, n) = ((k / d)(10^n + x), (k / d)(10^n + y), d / k, n)

    We need k | d for p to be a positive integer. Notice that we only need
    to search up to k^2 <= d, because for every k <= d we have two solutions,
    one characterized by k and the other by d / k >= k.

    We collect solutions in (a, b, p, n) across (x, y) across n in an std::set
    to remove any duplicates. Probably the only time this happens is when
    k * k = d, for which both k, d / k characterizes the same solution.
*/

#include <iostream>
#include <utility>
#include <vector>
#include <set>
#include "number_util.h"
#include "prime_util.h"

typedef unsigned long long ull;

std::vector<ull> primes = { 2 };

std::vector<std::pair<ull, ull>> get_factors(int n)
{
    std::vector<std::pair<ull, ull>> pairs;

    // std::pow returns a double with mantissa 53 bits effective which I don't
    // think has enough precision for 10^{2n} <= 10^{18}.
    ull p = util::mpz_to<ull>(util::pow(10, 2 * n));

    for (ull e2 = 0, p2 = 1; e2 <= 2 * n; e2++, p2 *= 2)
        for (ull e5 = 0, p5 = 1; p2 * p5 <= p / (p2 * p5); e5++, p5 *= 5)
            pairs.emplace_back(p2 * p5, p / (p2 * p5));

    return pairs;
}

void get_solutions(int n, std::set<std::vector<ull>> &solutions)
{
    for (std::pair<ull, ull> &factor : get_factors(n))
    {
        ull f = util::mpz_to<ull>(util::pow(10, n)) + factor.first;
        ull g = util::mpz_to<ull>(util::pow(10, n)) + factor.second;
        ull d = util::gcd(f, g);
        ull step_a = f / d, step_b = g / d;

        ull k = 0;
        while ((++k) * k <= d)
        {
            if (d % k == 0)
            {
                solutions.emplace(std::vector<ull>{ k * step_a, k * step_b, d / k, ull(n) });
                solutions.emplace(std::vector<ull>{ (d / k) * step_a, (d / k) * step_b, k, ull(n) });
            }
        }
    }
}

int main()
{
    std::set<std::vector<ull>> solutions;

    for (int n = 1; n <= 9; n++)
        get_solutions(n, solutions);

    std::cout << solutions.size();
}
<commit_msg>Fixed 157 explanation.<commit_after>/*
    Immediately one may notice that (a, b) will repeat across different values
    of n. For example,

        1 / 1 + 1 / 1 = 20 / 10 = 200 / 100 = 2000 / 1000 = ...

    It turns out that each contributes as a distinct solution and we need solutions
    in (a, b, p, n).

    Firstly, we manipulate the given equation to get

        1 / a + 1 / b = p / 10^n
        1 / a = (pb - 10^n) / (10^n * b)        1/b = (pa - 10^n) / (10^n * a)
        (pb - 10^n)a = 10^n * b                 (pb - 10^n)b = 10^n * a

    Multiplying both together, we have

        (pb - 10^n)(pb - 10^n)ab = 10^{2n} * ab
        (pb - 10^n)(pb - 10^n) = 10^{2n}

    Let pb - 10^n = x and pb - 10^n = y so that x <= y and xy = 10^{2n}. In
    principle since n <= 9, then 10^{2n} <= 10^18 = (2^18)(5^18) so the number
    of (x, y) pairs is at most 19 * 19 = 361.

    Next,

        pa = 10^n + x   pb = 10^n + y
        pa / pb = (10^n + x) / (10^n + y)
        a / b = (10^n + x) / (10^n + y)

    For each pair of (x, y), let d = GCD(10^n + x, 10^n + y). Then indeed we have
    solutions (a, b, p, n) can be generated by a positive integer k:

        (a, b, p, n) = ((k / d)(10^n + x), (k / d)(10^n + y), d / k, n)

    We need k | d for p to be a positive integer. Notice that we only need
    to search up to k^2 <= d, because for every k^2 <= d we have two solutions,
    one characterized by k and the other by d / k >= k.

    We collect solutions in (a, b, p, n) across (x, y) across n in an std::set
    to remove any duplicates. Probably the only time this happens is when
    k * k = d, for which both k, d / k characterizes the same solution.
*/

#include <iostream>
#include <utility>
#include <vector>
#include <set>
#include "number_util.h"
#include "prime_util.h"

typedef unsigned long long ull;

std::vector<ull> primes = { 2 };

std::vector<std::pair<ull, ull>> get_factors(int n)
{
    std::vector<std::pair<ull, ull>> pairs;

    // std::pow returns a double with mantissa 53 bits effective which I don't
    // think has enough precision for 10^{2n} <= 10^{18}.
    ull p = util::mpz_to<ull>(util::pow(10, 2 * n));

    for (ull e2 = 0, p2 = 1; e2 <= 2 * n; e2++, p2 *= 2)
        for (ull e5 = 0, p5 = 1; p2 * p5 <= p / (p2 * p5); e5++, p5 *= 5)
            pairs.emplace_back(p2 * p5, p / (p2 * p5));

    return pairs;
}

void get_solutions(int n, std::set<std::vector<ull>> &solutions)
{
    for (std::pair<ull, ull> &factor : get_factors(n))
    {
        ull f = util::mpz_to<ull>(util::pow(10, n)) + factor.first;
        ull g = util::mpz_to<ull>(util::pow(10, n)) + factor.second;
        ull d = util::gcd(f, g);
        ull step_a = f / d, step_b = g / d;

        ull k = 0;
        while ((++k) * k <= d)
        {
            if (d % k == 0)
            {
                solutions.emplace(std::vector<ull>{ k * step_a, k * step_b, d / k, ull(n) });
                solutions.emplace(std::vector<ull>{ (d / k) * step_a, (d / k) * step_b, k, ull(n) });
            }
        }
    }
}

int main()
{
    std::set<std::vector<ull>> solutions;

    for (int n = 1; n <= 9; n++)
        get_solutions(n, solutions);

    std::cout << solutions.size();
}<|endoftext|>


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

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

//Iterative Solution.
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        int mn, mx;

        mn = min(p->val, q->val);
        mx = p->val + q->val - mn;

        while(root)
        {
            if(root->val < mn)
                root = root->right;
            else if(root->val > mx)
                root = root->left;
            else
                return root;
        }

        return root;
    }
};

//Recursive Solution.
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root)
            return root;

        if((root->val >= p->val && root->val <= q->val) || (root->val >= q->val && root->val <= p->val))
            return root;

        if(root->val < p->val || root->val < q->val)
            return lowestCommonAncestor(root->right, p, q);
        else
            return lowestCommonAncestor(root->left, p, q);
    }
};
<commit_msg>235. Lowest Common Ancestor of a Binary Search Tree - Optimized<commit_after>/*
 * Written by Nitin Kumar Maharana
 * nitin.maharana@gmail.com
 */

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

//Iterative Solution.
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        int mn, mx;

        mn = min(p->val, q->val);
        mx = max(p->val, q->val);

        while(root)
        {
            if(root->val < mn)
                root = root->right;
            else if(root->val > mx)
                root = root->left;
            else
                return root;
        }
    }
};

//Recursive Solution.
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == p || root == q)
            return root;

        if(root->val < p->val && root->val < q->val)
            return lowestCommonAncestor(root->right, p, q);

        if(root->val > p->val && root->val > q->val)
            return lowestCommonAncestor(root->left, p, q);

        return root;
    }
};
<|endoftext|>