text:
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//

#ifndef BOOST_BEAST_DETAIL_IMPL_READ_HPP
#define BOOST_BEAST_DETAIL_IMPL_READ_HPP

#include <boost/beast/core/bind_handler.hpp>
#include <boost/beast/core/async_base.hpp>
#include <boost/beast/core/flat_static_buffer.hpp>
#include <boost/asio/basic_stream_socket.hpp>
#include <boost/asio/coroutine.hpp>
#include <boost/throw_exception.hpp>

namespace boost {
namespace beast {
namespace detail {

// The number of bytes in the stack buffer when using non-blocking.
static std::size_t constexpr default_max_stack_buffer = 16384;

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

struct dynamic_read_ops
{

// read into a dynamic buffer until the
// condition is met or an error occurs
template<
    class Stream,
    class DynamicBuffer,
    class Condition,
    class Handler>
class read_op
    : public net::coroutine
    , public async_base<
        Handler, beast::executor_type<Stream>>
{
    Stream& s_;
    DynamicBuffer& b_;
    Condition cond_;
    error_code ec_;
    std::size_t total_ = 0;

public:
    read_op(read_op&&) = default;

    template<class Handler_, class Condition_>
    read_op(
        Handler_&& h,
        Stream& s,
        DynamicBuffer& b,
        Condition_&& cond)
        : async_base<Handler,
            beast::executor_type<Stream>>(
                std::forward<Handler_>(h),
                    s.get_executor())
        , s_(s)
        , b_(b)
        , cond_(std::forward<Condition_>(cond))
    {
        (*this)({}, 0, false);
    }

    void
    operator()(
        error_code ec,
        std::size_t bytes_transferred,
        bool cont = true)
    {
        std::size_t max_size;
        std::size_t max_prepare;
        BOOST_ASIO_CORO_REENTER(*this)
        {
            for(;;)
            {
                max_size = cond_(ec, total_, b_);
                max_prepare = std::min<std::size_t>(
                    std::max<std::size_t>(
                        512, b_.capacity() - b_.size()),
                    std::min<std::size_t>(
                        max_size, b_.max_size() - b_.size()));
                if(max_prepare == 0)
                    break;
                BOOST_ASIO_CORO_YIELD
                s_.async_read_some(
                    b_.prepare(max_prepare), std::move(*this));
                b_.commit(bytes_transferred);
                total_ += bytes_transferred;
            }
            if(! cont)
            {
                // run this handler "as-if" using net::post
                // to reduce template instantiations
                ec_ = ec;
                BOOST_ASIO_CORO_YIELD
                s_.async_read_some(
                    b_.prepare(0), std::move(*this));
                ec = ec_;
            }
            this->complete_now(ec, total_);
        }
    }
};

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

struct run_read_op
{
    template<
        class AsyncReadStream,
        class DynamicBuffer,
        class Condition,
        class ReadHandler>
    void
    operator()(
        ReadHandler&& h,
        AsyncReadStream* s,
        DynamicBuffer* b,
        Condition&& c)
    {
        // If you get an error on the following line it means
        // that your handler does not meet the documented type
        // requirements for the handler.

        static_assert(
            beast::detail::is_invocable<ReadHandler,
            void(error_code, std::size_t)>::value,
            "ReadHandler type requirements not met");

        read_op<
            AsyncReadStream,
            DynamicBuffer,
            typename std::decay<Condition>::type,
            typename std::decay<ReadHandler>::type>(
                std::forward<ReadHandler>(h),
                *s,
                *b,
                std::forward<Condition>(c));
    }

};

};

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

template<
    class SyncReadStream,
    class DynamicBuffer,
    class CompletionCondition,
    class>
std::size_t
read(
    SyncReadStream& stream,
    DynamicBuffer& buffer,
    CompletionCondition cond)
{
    static_assert(is_sync_read_stream<SyncReadStream>::value,
        "SyncReadStream type requirements not met");
    static_assert(
        net::is_dynamic_buffer<DynamicBuffer>::value,
        "DynamicBuffer type requirements not met");
    static_assert(
        detail::is_invocable<CompletionCondition,
            void(error_code&, std::size_t, DynamicBuffer&)>::value,
        "CompletionCondition type requirements not met");
    error_code ec;
    auto const bytes_transferred = detail::read(
        stream, buffer, std::move(cond), ec);
    if(ec)
        BOOST_THROW_EXCEPTION(system_error{ec});
    return bytes_transferred;
}

template<
    class SyncReadStream,
    class DynamicBuffer,
    class CompletionCondition,
    class>
std::size_t
read(
    SyncReadStream& stream,
    DynamicBuffer& buffer,
    CompletionCondition cond,
    error_code& ec)
{
    static_assert(is_sync_read_stream<SyncReadStream>::value,
        "SyncReadStream type requirements not met");
    static_assert(
        net::is_dynamic_buffer<DynamicBuffer>::value,
        "DynamicBuffer type requirements not met");
    static_assert(
        detail::is_invocable<CompletionCondition,
            void(error_code&, std::size_t, DynamicBuffer&)>::value,
        "CompletionCondition type requirements not met");
    ec = {};
    std::size_t total = 0;
    std::size_t max_size;
    std::size_t max_prepare;
    for(;;)
    {
        max_size = cond(ec, total, buffer);
        max_prepare = std::min<std::size_t>(
            std::max<std::size_t>(
                512, buffer.capacity() - buffer.size()),
            std::min<std::size_t>(
                max_size, buffer.max_size() - buffer.size()));
        if(max_prepare == 0)
            break;
        std::size_t const bytes_transferred =
            stream.read_some(buffer.prepare(max_prepare), ec);
        buffer.commit(bytes_transferred);
        total += bytes_transferred;
    }
    return total;
}

template<
    class AsyncReadStream,
    class DynamicBuffer,
    class CompletionCondition,
    class ReadHandler,
    class>
BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
async_read(
    AsyncReadStream& stream,
    DynamicBuffer& buffer,
    CompletionCondition&& cond,
    ReadHandler&& handler)
{
    static_assert(is_async_read_stream<AsyncReadStream>::value,
        "AsyncReadStream type requirements not met");
    static_assert(
        net::is_dynamic_buffer<DynamicBuffer>::value,
        "DynamicBuffer type requirements not met");
    static_assert(
        detail::is_invocable<CompletionCondition,
            void(error_code&, std::size_t, DynamicBuffer&)>::value,
        "CompletionCondition type requirements not met");
    return net::async_initiate<
        ReadHandler,
        void(error_code, std::size_t)>(
            typename dynamic_read_ops::run_read_op{},
            handler,
            &stream,
            &buffer,
            std::forward<CompletionCondition>(cond));
}

} // detail
} // beast
} // boost

#endif

ext: hpp

max_stars_repo_name: RomanWlm/lib-ledger-core

max_issues_repo_name: RomanWlm/lib-ledger-core

max_forks_repo_name: RomanWlm/lib-ledger-core


text:
#include "mPlace.h"
#include "circuit.h"
#include "lefdefIO.h"
#include "partition.h"

#include <boost/icl/interval_map.hpp>
#include <boost/icl/closed_interval.hpp>

using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::pair;
using std::unordered_map;
using std::unordered_set;
using MacroNetlist::Partition;
using namespace MacroNetlist;
using namespace boost::icl;

typedef vector<pair<Partition, Partition>> TwoPartitions;

void CutRoundUp( CircuitInfo& cInfo, double& cutLine, bool isHorizontal ) {
  if( isHorizontal ) {
    int integer = (1.0* cutLine / cInfo.siteSizeX) + 0.5f;
    cutLine = integer * cInfo.siteSizeX;
    cutLine = (cutLine > cInfo.ux)? cInfo.ux : cutLine;
    cutLine = (cutLine < cInfo.lx)? cInfo.lx : cutLine;
  }
  else {
    int integer = (1.0* cutLine / cInfo.siteSizeY) + 0.5f;
    cutLine = integer * cInfo.siteSizeY;
    cutLine = (cutLine > cInfo.uy)? cInfo.uy : cutLine;
    cutLine = (cutLine < cInfo.ly)? cInfo.ly : cutLine;
  }
}

//
void PrintAllSets(FILE* fp, CircuitInfo& cInfo,
    vector< vector<Partition> >& allSets) {
  cout << "Writing sets file... ";
  for(auto& curSet : allSets) {
    fprintf(fp,"BEGIN SET ;\n" );
    fprintf(fp,"  WIDTH %f ;\n", cInfo.ux - cInfo.lx );
    fprintf(fp,"  HEIGHT %f ;\n", cInfo.uy - cInfo.ly );
    for(auto& curSlice : curSet) {
      if( curSlice.macroStor.size() == 0) {
        continue;
      }
      curSlice.PrintSetFormat(fp);
    }
    fprintf(fp,"END SET ;\n");
  }
  fflush(fp);
  cout << "Done!" << endl;
}

vector< vector<Partition> >
PlaceMacros(EnvFile& env, Circuit::Circuit& ckt, MacroCircuit& mckt) {

  //env.Print();

  cout << "PROC: LEF/DEF Parsing... ";
  ckt.Init(env.lefStor, env.def);
  env.design = ckt.defDesignName;
  cout << "Done!" << endl;

  double defScale = ckt.defUnit;
  defiPoints points = ckt.defDieArea.getPoint();
  if( points.numPoints != 2) {
    cout << "ERROR: The Layout must be rectangle..! "<< endl;
    exit(1);
  }

  if( ckt.defRowStor.size() == 0) {
    cout << "ERROR: DEF must contain ROW"<< endl;
    exit(1);
  }

  string siteName(ckt.defRowStor[0].macro());
  auto sitePtr = ckt.lefSiteMap.find( siteName );
  if( sitePtr == ckt.lefSiteMap.end()) {
    cout << "ERROR: SITE " << siteName << " not exists in LEF." << endl;
    exit(1);
  }

  double siteSizeX = ckt.lefSiteStor[sitePtr->second].sizeX();
  double siteSizeY = ckt.lefSiteStor[sitePtr->second].sizeY();

  CircuitInfo cInfo( 1.0*points.x[0]/defScale,
        1.0*points.y[0]/defScale,
        1.0*points.x[1]/defScale,
        1.0*points.y[1]/defScale,
        siteSizeX, siteSizeY );

  cout << endl;

  cout << "DieBBox: (" << cInfo.lx << " " << cInfo.ly << ") - ("
    << cInfo.ux << " " << cInfo.uy << ")" << endl;
//  cout << "Layout Information" << endl;
//  for(int i=0; i<points.numPoints; i++) {
//    cout << 1.0*points.x[i]/defScale << " ";
//    cout << 1.0*points.y[i]/defScale << endl;
//  }

//  cout << "Original Macro List" << endl;

//  MacroCircuit mckt(ckt, env, cInfo);
  mckt.Init(&ckt, &env, &cInfo);

  //  RandomPlace for special needs.
  //  Really not recommended to execute this functioning
  if( env.isRandomPlace == true ) {
    double snapGrid = 0.02f;
    mckt.StubPlacer(snapGrid);
  }

//  mckt.GetMacroStor(ckt);

//  for(auto& curMacro: mckt.macroStor) {
//    curMacro.Dump();
//  }

  bool isHorizontal = (cInfo.ux-cInfo.lx) > (cInfo.uy-cInfo.ly);

  Partition layout(PartClass::ALL,
      cInfo.lx, cInfo.ly, cInfo.ux-cInfo.lx, cInfo.uy-cInfo.ly);
  layout.macroStor = mckt.macroStor;

  cout << "PROC: Begin One Level Partition ... " << endl;
  TwoPartitions oneLevelPart = GetPart(cInfo, layout, isHorizontal);
  cout << "PROC: End One Level Partition" << endl << endl;
  TwoPartitions eastStor, westStor;

  vector< vector<Partition> > allSets;

  // Fill the MacroNetlist for ALL circuits
  unordered_map< PartClass, vector<int>,
    MyHash<PartClass>> globalMacroPartMap;
  UpdateMacroPartMap( mckt, layout, globalMacroPartMap );
  layout.FillNetlistTable( mckt, globalMacroPartMap );
  mckt.UpdateNetlist(layout);

  // push to the outer vector
  vector<Partition> layoutSet;
  layoutSet.push_back(layout);

  // push
  allSets.push_back(layoutSet);

  for(auto& curSet : oneLevelPart ) {
    if( isHorizontal ) {
      cout << "PROC: Begin Horizontal Cuts" << endl;
      CircuitInfo eastInfo(cInfo, curSet.first);
      CircuitInfo westInfo(cInfo, curSet.second);

      cout << "PROC: Begin 1st Second Level Partition" << endl;
      TwoPartitions eastStor = GetPart(eastInfo, curSet.first, !isHorizontal);
      cout << "PROC: End 1st Second Level Partition" << endl << endl;

      cout << "PROC: Begin 2nd Second Level Partition" << endl;
      TwoPartitions westStor = GetPart(westInfo, curSet.second, !isHorizontal);
      cout << "PROC: End 2nd Second Level Partition" << endl << endl;

      // Zero case handling when eastStor = 0
      if( eastStor.size() == 0 && westStor.size() != 0 ) {
        for(size_t i=0; i<westStor.size(); i++) {
          vector<Partition> oneSet;

          // one set is composed of two subblocks
          oneSet.push_back( westStor[i].first );
          oneSet.push_back( westStor[i].second );

          // Fill Macro Netlist
          // update macroPartMap
          unordered_map< PartClass, vector<int>,
            MyHash<PartClass>> macroPartMap;
          for(auto& curSet: oneSet) {
            UpdateMacroPartMap( mckt, curSet, macroPartMap );
          }

          for(auto& curSet: oneSet) {
            curSet.FillNetlistTable( mckt, macroPartMap );
          }

          allSets.push_back( oneSet );
        }
      }
      // Zero case handling when westStor = 0
      else if( eastStor.size() != 0 && westStor.size() == 0 ) {
        for(size_t i=0; i<eastStor.size(); i++) {
          vector<Partition> oneSet;

          // one set is composed of two subblocks
          oneSet.push_back( eastStor[i].first );
          oneSet.push_back( eastStor[i].second );

          // Fill Macro Netlist
          // update macroPartMap
          unordered_map< PartClass, vector<int>,
            MyHash<PartClass>> macroPartMap;
          for(auto& curSet: oneSet) {
            UpdateMacroPartMap( mckt, curSet, macroPartMap );
          }

          for(auto& curSet: oneSet) {
            curSet.FillNetlistTable( mckt, macroPartMap );
          }

          allSets.push_back( oneSet );
        }
      }
      else {
        // for all possible combinations in partitions
        for(size_t i=0; i<eastStor.size(); i++) {
          for(size_t j=0; j<westStor.size(); j++) {

            vector<Partition> oneSet;

            // one set is composed of four subblocks
            oneSet.push_back( eastStor[i].first );
            oneSet.push_back( eastStor[i].second );
            oneSet.push_back( westStor[j].first );
            oneSet.push_back( westStor[j].second );

            // Fill Macro Netlist
            // update macroPartMap
            unordered_map< PartClass, vector<int>,
              MyHash<PartClass>> macroPartMap;
            for(auto& curSet: oneSet) {
              UpdateMacroPartMap( mckt, curSet, macroPartMap );
            }

            for(auto& curSet: oneSet) {
              curSet.FillNetlistTable( mckt, macroPartMap );
            }

            allSets.push_back( oneSet );
          }
        }
      }
    }
    else {
      cout << "PROC: Vertical Cuts" << endl;
    }
  }
  cout << "INFO: Total Extracted Sets = " << allSets.size() << endl << endl;

  return allSets;

  // Legalize macro on global Structure
//  double snapGrid = 0.002f;

  // TopLevel Macro Location Update
  // For each possible full-layout

  /*
  int setCnt = 0;
  int bestSetIdx = 0;
  double bestWwl = DBL_MIN;
  for(auto& curSet: allSets) {

    // skip for top-layout partition
    if( curSet.size() == 1) {
      continue;
    }

    // For each partitions (four partition)
//    cout << "curSet.size: " << curSet.size() << endl;
    for(auto& curPart : curSet) {
      // Annealing based on ParquetFP Engine
      curPart.DoAnneal();
      // Update mckt frequently
      mckt.UpdateMacroCoordi(curPart);
    }

    // update partitons' macro info
    for(auto& curPart : curSet) {
      curPart.UpdateMacroCoordi(mckt);
    }

    if( env.generateAll ) {
      // update ckt structure
      UpdateCircuitCoordi(env, mckt, ckt);

      // check plotting
      if( env.isPlot ) {
        mckt.Plot(env.output + "_" + std::to_string(setCnt) + ".plt", curSet);
      }

      // top-level layout print
      FILE* fp =
        fopen(string(env.output + "_"
              + std::to_string(setCnt) + ".def").c_str(), "w");

      if( fp == NULL) {
        cout << "ERROR: cannot open " << env.output << " to write output file" << endl;
        exit(1);
      }

      ckt.WriteDef( fp );
      fclose(fp);
    }
    else {
      double curWwl = mckt.GetWeightedWL();
      cout << "Set " << &curSet - &allSets[0] << ": WWL = " << curWwl << endl;

      if( curWwl > bestWwl ) {
        bestWwl = curWwl;
        bestSetIdx = &curSet - &allSets[0];
      }
    }
    setCnt ++;
  }

  // bestset DEF writing
  vector<Partition> bestSet = allSets[bestSetIdx];
  if( !env.generateAll ) {
    for(auto& curPart : bestSet) {
      curPart.UpdateMacroCoordi(mckt);
    }

    UpdateCircuitCoordi(env, mckt, ckt);

    // check plotting
    if( env.isPlot ) {
      mckt.Plot(env.output + "_best.plt", bestSet );
    }

    // top-level layout print
    FILE* fp =
      fopen(string(env.output + "_best.def").c_str(), "w");

    if( fp == NULL) {
      cout << "ERROR: cannot open " << env.output << " to write output file" << endl;
      exit(1);
    }

    ckt.WriteDef( fp );
    fclose(fp);
  }
   */

  /*
  // Writing functions for Sets file
  FILE* fp = fopen(_env.output.c_str(), "w");
  if( fp == NULL) {
    cout << "ERROR: cannot open " << _env.output << " to write output file" << endl;
    exit(1);
  }

  // Generate *.sets file
  PrintAllSets(fp, cInfo, allSets);
  fclose(fp);
  */

  // ParquetFormat print
  // only top-level formats
//  layout.PrintParquetFormat(_env.output);

  cout << "PROC: End TritonMacroPlacer" << endl;

  // All Edges...
//  for(int i=1; i<=numEdge; i++) {
//    sta::Edge* edge = _sta->graph()->edge(i);
//    cout << edge->from(_sta->graph())->name(_sta->network()) <<
//      " -> " << edge->to(_sta->graph())->name(_sta->network()) << endl;
//  }

//  PinSeq pinStor;
//  pinStor.push_back( );

//  for(auto& curSet : allSets) {
//    for(auto& curPart : curSet) {
//      for(auto& curMacro : curPart.macroStor) {
//        cout << curMacro.name << endl;
//        Pin* curPin = _sta->network()->findPin(curMacro.name.c_str());
//      }
//    }
//  }

  /*
  // vertex
  sta::VertexIterator vertIter(_sta->graph());
  while( vertIter.hasNext()) {
    sta::Vertex* vertex = vertIter.next();
//    if( vertex->isRoot() ) {
//     if ( vertex->isCheckClk() || vertex->isGatedClkEnable() || vertex->isRegClk() ) {
//    if( _sta->network()->isTopLevelPort(vertex->pin())) {
//      cout << vertex->name(_sta->network()) << endl;
//    }
  }

  for(int i=1; i<=numEdge; i++) {
    sta::Edge* edge = _sta->graph()->edge(i);
//    cout << edge->from(_sta->graph())->name(_sta->network()) <<
//      " -> " << edge->to(_sta->graph())->name(_sta->network()) << endl;
  }

  LeafInstanceIterator* leafInstanceIter = _sta->network()->leafInstanceIterator();
  while( leafInstanceIter->hasNext() ) {
    Instance* instance = leafInstanceIter->next();
//    cout << _sta->network()->name(instance) << "/";
    InstancePinIterator* instancePinIter = _sta->network()->pinIterator(instance);
    while( instancePinIter->hasNext()) {
      sta::Pin* pin = instancePinIter->next();
      if( _sta->network()->isDriver(pin) ) {
        cout << "D: ";
      }
      else if( _sta->network()->isLoad(pin) ) {
        cout << "L: ";
      }
      cout << _sta->network()->name(pin) << endl ;
    }
    cout <<endl;
  }
  */

//  cout << "top: " << _sta->network()->name(_sta->network()->topInstance()) << endl;
}

// Two partitioning functions:
// first : lower part
// second : upper part
//
// cutLine is sweeping from lower to upper coordinates in x / y
vector<pair<Partition, Partition>> GetPart(
    CircuitInfo &cInfo,
    Partition& partition,
    bool isHorizontal ) {
  cout << "PROC: Begin Partition ... " << endl;
  cout << "INFO: Partitions' #Macro = " << partition.macroStor.size() << endl;

  // Return vector
  vector<pair<Partition, Partition>> ret;

  typedef std::set<int> MacroSetT;
  interval_map<double, MacroSetT> macroMap;

  double maxWidth = DBL_MIN;
  double maxHeight = DBL_MIN;

  // in parent partition, traverse macros
  //
  for(auto& curMacro: partition.macroStor) {
    MacroSetT macroInfo;
    macroInfo.insert( &curMacro - &partition.macroStor[0]);

    macroMap.add(
        make_pair(
          interval<double>::closed(
            (isHorizontal)? curMacro.lx : curMacro.ly,
            (isHorizontal)? curMacro.lx + curMacro.w :
                curMacro.ly + curMacro.h ), macroInfo));
    maxWidth = ( maxWidth < curMacro.w)? curMacro.w: maxWidth;
    maxHeight = ( maxHeight < curMacro.h)? curMacro.h: maxHeight;
  }

  double cutLineLimit = (isHorizontal)? maxWidth * 0.25 : maxHeight * 0.25;

  double prevPushLimit = DBL_MIN;
  bool isFirst = true;
  vector<double> cutLineStor;

  // less than 4
  if( partition.macroStor.size() <= 4 ) {
    for( interval_map<double, MacroSetT>::iterator
        it = macroMap.begin();
        it != macroMap.end(); *it++) {
      interval<double>::type macroInterval = it->first;
      MacroSetT result = it->second;

      if( isFirst ) {
        cutLineStor.push_back( macroInterval.lower() );
        prevPushLimit = macroInterval.lower();
        isFirst = false;
      }
      else if( abs(macroInterval.lower()-prevPushLimit) > cutLineLimit ) {
        cutLineStor.push_back( macroInterval.lower() );
        prevPushLimit = macroInterval.lower();
      }
    }
  }
  // more than 4
  else {
    int hardLimit = int( sqrt( 1.0*partition.macroStor.size()/3.0 ) + 0.5f);
    for(int i=0; i<=hardLimit; i++) {
      cutLineStor.push_back( (isHorizontal)?
          cInfo.lx + 1.0*(cInfo.ux - cInfo.lx)/hardLimit * i :
          cInfo.ly + 1.0*(cInfo.uy - cInfo.ly)/hardLimit * i );
    }
  }
  cout << "INFO: NumCutline = " << cutLineStor.size() << endl;

  // Macro checker array
  // 0 for uninitialize
  // 1 for lower
  // 2 for upper
  // 3 for both
  int* chkArr = new int[partition.macroStor.size()];

  for(auto& cutLine : cutLineStor ) {
    cout << "INFO: CutLine = " << cutLine << endl;
    CutRoundUp(cInfo, cutLine, isHorizontal);
    cout << "INFO: Updated CutLine = " << cutLine << endl;

    // chkArr initialize
    for(size_t i=0; i<partition.macroStor.size(); i++) {
      chkArr[i] = 0;
    }

    bool isImpossible = false;
    for(auto& curMacro : partition.macroStor) {
      int i = &curMacro - &partition.macroStor[0];
      if( isHorizontal ) {
        // lower is possible
        if( curMacro.w <= cutLine ) {
          chkArr[i] += 1;
        }
        // upper is possible
        if ( curMacro.w <= partition.width - cutLine) {
          chkArr[i] += 2;
        }
        // none of them
        if( chkArr[i] == 0 ) {
          isImpossible = true;
          break;
        }
      }
      else {
        // lower is possible
        if( curMacro.h <= cutLine ) {
          chkArr[i] += 1;
        }
        // upper is possible
        if (curMacro.h <= partition.height - cutLine) {
          chkArr[i] += 2;
        }
        // none of
        if( chkArr[i] == 0 ) {
          isImpossible = true;
          break;
        }
      }
    }
    // impossible cuts, then skip
    if( isImpossible ) {
      continue;
    }

    // Fill in the Partitioning information
    PartClass lClass = None, uClass = None;
    if( partition.partClass == ALL ) {
      lClass = (isHorizontal)? W : S;
      uClass = (isHorizontal)? E : N;
    }

    if( partition.partClass == W) {
      lClass = SW;
      uClass = NW;

    }
    if( partition.partClass == E) {
      lClass = SE;
      uClass = NE;
    }

    if( partition.partClass == N) {
      lClass = NW;
      uClass = NE;
    }

    if( partition.partClass == S) {
      lClass = SW;
      uClass = SE;
    }

    Partition lowerPart( lClass,
      partition.lx,
      partition.ly,
      (isHorizontal)? cutLine - partition.lx : partition.width,
      (isHorizontal)? partition.height : cutLine - partition.ly);

    Partition upperPart( uClass,
      (isHorizontal)? cutLine : partition.lx,
      (isHorizontal)? partition.ly :cutLine,
      (isHorizontal)? partition.lx + partition.width - cutLine : partition.width,
      (isHorizontal)? partition.height : partition.ly + partition.height - cutLine);

    // cout << it->first << " " << it->second << endl;
    //
    // Fill in child partitons' macroStor
    for(auto& curMacro : partition.macroStor) {
      int i=&curMacro - &partition.macroStor[0];
      if( chkArr[i] == 1 ) {
        lowerPart.macroStor.push_back(
            Macro( curMacro.name, curMacro.type,
              curMacro.lx, curMacro.ly,
              curMacro.w, curMacro.h,
              curMacro.haloX, curMacro.haloY,
              curMacro.channelX, curMacro.channelY,
              curMacro.ptr, curMacro.instPtr )) ;
      }
      else if( chkArr[i] == 2 ) {
        upperPart.macroStor.push_back(
            Macro( curMacro.name, curMacro.type,
              (isHorizontal)? curMacro.lx-cutLine : curMacro.lx,
              (isHorizontal)? curMacro.ly : curMacro.ly-cutLine,
              curMacro.w, curMacro.h,
              curMacro.haloX, curMacro.haloY,
              curMacro.channelX, curMacro.channelY,
              curMacro.ptr, curMacro.instPtr));
      }
      else if( chkArr[i] == 3 ) {
        double centerPoint =
          (isHorizontal)?
          curMacro.lx + curMacro.w/2.0 :
          curMacro.ly + curMacro.h/2.0;

        if( centerPoint < cutLine ) {
          lowerPart.macroStor.push_back(
              Macro( curMacro.name, curMacro.type,
                curMacro.lx, curMacro.ly,
                curMacro.w, curMacro.h,
                curMacro.haloX, curMacro.haloY,
                curMacro.channelX, curMacro.channelY,
                curMacro.ptr, curMacro.instPtr )) ;

        }
        else {
          upperPart.macroStor.push_back(
              Macro( curMacro.name, curMacro.type,
                (isHorizontal)? curMacro.lx-cutLine : curMacro.lx,
                (isHorizontal)? curMacro.ly : curMacro.ly-cutLine,
                curMacro.w, curMacro.h,
                curMacro.haloX, curMacro.haloY,
                curMacro.channelX, curMacro.channelY,
                curMacro.ptr, curMacro.instPtr));
        }
      }
    }

    double lowerArea = lowerPart.width * lowerPart.height;
    double upperArea = upperPart.width * upperPart.height;

    double upperMacroArea = 0.0f;
    double lowerMacroArea = 0.0f;

    for(auto& curMacro : upperPart.macroStor) {
      upperMacroArea += curMacro.w * curMacro.h;
    }
    for(auto& curMacro : lowerPart.macroStor) {
      lowerMacroArea += curMacro.w * curMacro.h;
    }
//    cout << upperMacroArea << " " << upperArea << endl;
//    cout << lowerMacroArea << " " << lowerArea << endl;
    // impossible partitioning
    if( upperMacroArea > upperArea || lowerMacroArea > lowerArea) {
      cout << "PROC: Impossible partition, continue" << endl;
      continue;
    }

// Previous code
//    if( partition.partClass == N ||
//        partition.partClass == E ||
//        partition.partClass == W ||
//        partition.partClass == S ) {
//      lowerPart.FillNetlistTable();
//      upperPart.FillNetlistTable();
//    }

    pair<Partition, Partition> curPart( lowerPart, upperPart );

    cout << "INFO: NumMacro in LowerPart[" << ret.size() << "] = "
      << lowerPart.macroStor.size() << endl;
    cout << "INFO: NumMacro in UpperPart[" << ret.size() << "] = "
      << upperPart.macroStor.size() << endl;

    ret.push_back( curPart );
  }
  delete[] chkArr;
  cout << "PROC: End Partition " << endl << endl;

  return ret;
}

// using mckt.macroInstMap and partition,
// fill in macroPartMap
//
// macroPartMap will contain
//
// first: macro partition class info
// second: macro candidates.
void UpdateMacroPartMap(
    MacroCircuit& mckt,
    MacroNetlist::Partition& part,
    unordered_map<MacroNetlist::PartClass, vector<int>,
    MyHash<MacroNetlist::PartClass>>& macroPartMap ) {

  auto mpPtr = macroPartMap.find( part.partClass );
  if( mpPtr == macroPartMap.end() ) {
    vector<int> curMacroStor;
    // convert macro Information into macroIdx
    for(auto& curMacro: part.macroStor) {
      auto miPtr = mckt.macroInstMap.find( curMacro.instPtr );
      if( miPtr == mckt.macroInstMap.end() ) {
        cout << "ERROR: macro " << curMacro.name
          << " not exists in macroInstMap: " << curMacro.instPtr << endl;
        exit(1);
      }
      curMacroStor.push_back( miPtr->second) ;
    }
    macroPartMap[ part.partClass ] = curMacroStor;
  }
  else {
    cout << "ERROR: Partition- " << part.partClass
      << " already updated (UpdateMacroPartMap)" << endl;
    exit(1);
  }
}

//
// update ckt class from mckt, env.
//
void UpdateCircuitCoordi(EnvFile& env, MacroCircuit& mckt, Circuit::Circuit& ckt) {
  unordered_set<int> macroIdxMap;
  double defScale = ckt.defUnit;

  // update ckt structure
  for(auto& curMacro : mckt.macroStor) {
    auto cPtr = ckt.defComponentMap.find( curMacro.name );
    if( cPtr == ckt.defComponentMap.end()) {
      cout << "ERROR: Cannot find " << curMacro.name
        << " in defiComponentMap" << endl;
      exit(1);
    }
    int cIdx = cPtr->second;
    macroIdxMap.insert(cIdx);
    int lx = int(curMacro.lx * defScale + 0.5f);
    int ly = int(curMacro.ly * defScale + 0.5f);

    int orient = -1;
    if( ckt.defComponentStor[cIdx].placementStatus() != 0
        && ckt.defComponentStor[cIdx].placementStatus() != DEFI_COMPONENT_UNPLACED ) {
      // Follow original orient
      orient = ckt.defComponentStor[cIdx].placementOrient();
    }
    else {
      // Default is North
      orient = 0;
    }

    if( env.isWestFix ) {
      orient = 1;
    }

    ckt.defComponentStor[cIdx].
      setPlacementLocation(lx, ly, orient);

    ckt.defComponentStor[cIdx].
      setPlacementStatus(DEFI_COMPONENT_FIXED);
  }

  // reset other cells's location not to have bug in other tools
  for(size_t i=0; i<ckt.defComponentStor.size(); i++) {
    // continue for MacroIndex
    if( macroIdxMap.find(i) != macroIdxMap.end() ) {
      continue;
    }

    ckt.defComponentStor[i].setPlacementStatus(0);
    ckt.defComponentStor[i].setPlacementLocation(-1,-1,-1);
  }
}

ext: cpp

max_stars_repo_name: ilesser/TritonMacroPlace

max_issues_repo_name: abk-openroad/TritonMacroPlace

max_forks_repo_name: abk-openroad/TritonMacroPlace


text:
#include <algorithm>
#include <array>
#include <iostream>
#include <random>
#include <string>
#include <tuple>
#include <vector>

#include <boost/timer.hpp>

constexpr int kana_num = 44;
constexpr int value_max = 100000;

using table = std::array<std::array<int, kana_num>, kana_num>;
using sumt = std::array<int, kana_num>;

table input() {
  table tb;
  for (int i = 0; i < kana_num; ++i)
    for (int j = 0; j < kana_num; ++j)
      std::cin >> tb[i][j];
  return tb;
}

table erase_loop(table tb) {
  for (int i = 0; i < kana_num; ++i) {
    for (int j = 0; j < kana_num; ++j) {
      if (i != j) {
        int diff = std::min(tb[i][j], tb[j][i]);
        tb[i][j] -= diff;
        tb[j][i] -= diff;
      } else {
        tb[i][i] = tb[i][i] % 2;
      }
    }
  }
  return tb;
}

sumt sum_table(table tb) {
  sumt s;
  std::fill(std::begin(s), std::end(s), 0);
  for (int i = 0; i < kana_num; ++i)
    for (int j = 0; j < kana_num; ++j)
      s[i] += tb[i][j];
  return s;
}

int score(const sumt &st, int pos, int) {
  return st[pos] ? 0 : -value_max;
}

int score2(const sumt &st, int pos, int co_depth) {
  return (st[pos] ? 0 : -value_max) * std::pow(0.99, (double)co_depth);
}

template <typename Func>
int alphabeta(const table &tb, const sumt &st, int pos, int depth,
    int alpha, int beta, Func func, int co_depth = 0) {
  if (depth == 0) return func(st, pos, co_depth);
  for (int i = 0; i < kana_num; ++i) {
    if (tb[pos][i] != 0) {
      auto cp = tb;
      auto cps = st;
      --cp[pos][i];
      --cps[pos];
      alpha = std::max(alpha,
          -alphabeta(cp, cps, i, depth - 1, -beta, -alpha, func, co_depth + 1));
      if (alpha >= beta) return alpha;
    }
  }
  return alpha;
}

template <typename Func>
int alphabeta2(const table &tb, const sumt &st, int pos, int depth,
    int alpha, int beta, Func func, int co_depth = 0) {
  if (depth == 0) return func(st, pos, co_depth);
  bool is_lose = true;
  for (int i = 0; i < kana_num; ++i) {
    if (tb[pos][i] != 0) {
      auto cp = tb;
      auto cps = st;
      is_lose = false;
      --cp[pos][i];
      --cps[pos];
      alpha = std::max(alpha,
          -alphabeta2(cp, cps, i, depth - 1, -beta, -alpha,
              func, co_depth + 1));
      if (alpha >= beta) return alpha;
    }
  }
  if (is_lose)
    return std::max(alpha,
        int(-value_max * std::pow(0.99, (double)co_depth)));
  else
    return alpha;
}

std::vector<int> mate_or_escape(const table &tb, const sumt &st, int pos) {
  std::vector<int> next_pos;
  boost::timer tm;
  for (int depth = 0; depth < 800 && tm.elapsed() < 1.0; ++depth) {
    next_pos.clear();
    int alpha = -value_max;
    for (int i = 0; i < kana_num; ++i) {
      if (tb[pos][i] != 0) {
        auto cp = tb;
        auto cps = st;
        --cp[pos][i];
        --cps[pos];
        int s = -alphabeta2(cp, cps, i, depth, -value_max, value_max, score2);
        if (s >= alpha) {
          if (s > alpha) {
            alpha = s;
            next_pos.clear();
          }
          next_pos.push_back(i);
        }
      }
    }
    std::cerr << "depth: " << depth << ", score: " << alpha << std::endl;
  }
  return next_pos;
}

int main(int argc, char **argv) {
  std::random_device rd;
  std::mt19937 mt(rd());
  int pos;
  std::cin >> pos;
  auto tb = input();
  auto st = sum_table(tb);
  auto el = erase_loop(tb);
  auto es = sum_table(el);
  std::vector<int> next_pos;
  boost::timer tm;
  bool to_mate = false;
  for (int depth = 0; depth < 800 && tm.elapsed() < 1.0; ++depth) {
    next_pos.clear();
    int alpha = -value_max;
    for (int i = 0; i < kana_num; ++i) {
      if (tb[pos][i] != 0) {
        auto cp = el;
        auto cps = es;
        if (cp[pos][i]) {
          --cp[pos][i];
          --cps[pos];
        } else {
          ++cp[i][pos];
          ++cps[i];
        }
        int s = -alphabeta(cp, cps, i, depth, -value_max, value_max, score);
        if (s >= alpha) {
          if (s > alpha) {
            alpha = s;
            next_pos.clear();
          }
          next_pos.push_back(i);
        }
      }
    }
    std::cerr << "depth: " << depth << ", score: " << alpha << std::endl;
    if (alpha == -value_max)
      to_mate = true;
  }
  if (to_mate)
    next_pos = mate_or_escape(tb, st, pos);
  std::uniform_int_distribution<> dis(0, next_pos.size() - 1);
  std::cout << next_pos[dis(mt)] << std::endl;
  return 0;
}

max_stars_repo_name: kmc-jp/PokemonShiritoriAIServer

max_issues_repo_name: kmc-jp/PokemonShiritoriAIServer

max_forks_repo_name: kmc-jp/PokemonShiritoriAIServer


text:
/* CirKit: A circuit toolkit
 * Copyright (C) 2009-2015  University of Bremen
 * Copyright (C) 2015-2017  EPFL
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * @file truth_table.hpp
 *
 * @brief Class for truth table representation
 *
 * @author Mathias Soeken
 * @author Stefan Frehse
 *
 * @since 1.0
 */

#ifndef TRUTH_TABLE_HPP
#define TRUTH_TABLE_HPP

#include <iostream>
#include <iterator>
#include <vector>

#include <boost/iterator/counting_iterator.hpp>
#include <boost/iterator/permutation_iterator.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/optional.hpp>

#include <reversible/circuit.hpp>

namespace cirkit
{

  /** @cond */
  template<typename T>
  struct transform_cube;
  /** @endcond */

  /**
   * @brief Represents a  truth table
   *
   * This class helps mapping input assignments
   * to their corresponding output assignments.
   *
   * Assignments are thereby cubes (type truth_table<T>::cube_type)
   * are vectors of values T, which type is given as
   * template parameter to the class.
   *
   * For the tristate value 1, 0, and don't care the
   * type \ref binary_truth_table is predefined with
   * T = boost::optional<bool>.
   *
   * You can use read_specification(binary_truth_table&, const std::string&, std::string*)
   * for reading a RevLib specification file into a truth_table.
   *
   * @section sec_example_iterate_through_truth_table Example
   * This example shows how to iterate through the values of a \ref binary_truth_table, which is not that convenient on the first sight.
   * This code works also for a generic \ref truth_table.
   * @code
   * binary_truth_table tt = // obtained from somewhere
   *
   * for ( binary_truth_table::const_iterator it = tt.begin(); it != tt.end(); ++it )
   * {
   *   // iterate through input cube (bit by bit)
   *   for ( const auto& in_bit : boost::make_iterator_range( it->first ) )
   *   {
   *     // do something with in_bit
   *   }
   *
   *   // iterate through output cube (bit by bit)
   *   for ( const auto& out_bit : boost::make_iterator_range( it->second ) )
   *   {
   *     // do something with out_bit
   *   }
   * }
   * @endcode
   *
   * @since  1.0
   */
  template<typename T>
  class truth_table
  {
  public:
    /**
     * @brief Typedef reference to the given template type
     *
     * @since  1.0
     */
    using value_type = T;

    /**
     * @brief Type representing a cube
     *
     * Implemented as a vector over the basic type T
     *
     * @since  1.0
     */
    using cube_type = std::vector<T>;

    /**
     * @brief Represents a map from input to output cube
     *
     * Implemented as a tuple
     *
     * @since  1.0
     */
    using cube_vector = std::map<cube_type, cube_type>;

    /**
     * @brief Constant Iterator of input cubes
     *
     * Default constant iterator is used.
     *
     * @since  1.0
     */
    using in_const_iterator = typename cube_type::const_iterator;

    /**
     * @brief Constant Iterator of output cubes
     *
     * A permutation iterator from Boost.Iterators is used which makes use of the truth table's permutation.
     *
     * @since  1.0
     */
    using out_const_iterator = boost::permutation_iterator<typename cube_type::const_iterator, std::vector<unsigned>::const_iterator>;

    /**
     * @brief Truth Table's constant iterator
     *
     * A transform iterator which transforms the cube_tuple objects to a pair of iterator pairs of each input and output cube.
     *
     * @since  1.0
     */
    using const_iterator = boost::transform_iterator<transform_cube<T>, typename cube_vector::const_iterator>;

    /**
     * @brief Truth Table's iterator
     *
     * @since  2.0
     */
    using iterator = boost::transform_iterator<transform_cube<T>, typename cube_vector::iterator>;

    /**
     * @brief Returns the number of inputs
     *
     * If the truth table contains no cube tuple,
     * then 0 is returned, otherwise the length of the
     * first input assignment is returned.
     *
     * @return Number of inputs
     *
     * @since  1.0
     */
    unsigned num_inputs() const
    {
      if ( _cubes.size() )
      {
        return _cubes.begin()->first.size();
      }
      else
      {
        return 0;
      }
    }

    /**
     * @brief Returns the number of outputs
     *
     * If the truth table contains no cube tuple,
     * then 0 is returned, otherwise the length of the
     * first output assignment is returned.
     *
     * @return Number of outputs
     *
     * @since  1.0
     */
    unsigned num_outputs() const
    {
      if ( _cubes.size() )
      {
        return _cubes.begin()->second.size();
      }
      else
      {
        return 0;
      }
    }

    /**
     * @brief Returns constant begin iterator of the cube list
     *
     * @return Constant begin iterator of the cube list
     *
     * @since  1.0
     */
    const_iterator begin() const
    {
      return boost::make_transform_iterator( _cubes.begin(), transform_cube<T>( _permutation ) );
    }

    /**
     * @brief Returns constant end iterator of the cube list
     *
     * @return Constant end iterator of the cube list
     *
     * @since  1.0
     */
    const_iterator end() const
    {
      return boost::make_transform_iterator( _cubes.end(), transform_cube<T>( _permutation ) );
    }

    /**
     * @brief Returns begin iterator of the cube list
     *
     * @return begin iterator of the cube list
     *
     * @since  2.0
     */
    iterator begin()
    {
      return boost::make_transform_iterator( _cubes.begin(), transform_cube<T>( _permutation ) );
    }

    /**
     * @brief Returns end iterator of the cube list
     *
     * @return end iterator of the cube list
     *
     * @since  2.0
     */
    iterator end()
    {
      return boost::make_transform_iterator( _cubes.end(), transform_cube<T>( _permutation ) );
    }

    /**
     * @brief Adds a new entry to the truth table
     *
     * With adding the first entry the dimension of inputs
     * and outputs is set. When adding further entries
     * it has to make sure that the dimensions fit, else
     * an assertion is thrown and false is returned.
     *
     * @param input Input assignment
     * @param output Output assignment
     * @return Returns whether the assignment could be added or not
     *
     * @since  1.0
     */
    bool add_entry( const cube_type& input, const cube_type& output )
    {
      if ( _cubes.size() &&
           ( input.size() != _cubes.begin()->first.size() ||
             output.size() != _cubes.begin()->second.size() ) )
      {
        assert( false );
        return false;
      }

      if ( !_cubes.size() && !_permutation.size() )
      {
        /* first entry -> create permutation */
        std::copy( boost::counting_iterator<unsigned>( 0 ),
                   boost::counting_iterator<unsigned>( output.size() ),
                   std::back_inserter( _permutation ) );

        _constants.resize( input.size(), constant() );
        _garbage.resize( output.size(), false );
      }

      _cubes.insert( std::make_pair( input, output ) );
      return true;
    }

    /**
     * @brief Removes an entry
     *
     * @since  2.0
     */
    void remove_entry( iterator entry )
    {
      _cubes.erase( entry.base() );
    }

    /**
     * @brief Clears the truth table
     *
     * Clears the truth table, as well as the current permutation and constant
     * and garbage information.
     *
     * @since  1.0
     */
    void clear()
    {
      _cubes.clear();
      _permutation.clear();
      _constants.clear();
      _garbage.clear();
    }

    /**
     * @brief Returns current permutation
     *
     * The permutation is initializes when the first entry is added
     * to the truth table and is initially the sequence from 0 to \e n - 1,
     * where \e n is the size of the output cubes.
     *
     * @return Current permutation
     *
     * @since  1.0
     */
    const std::vector<unsigned>& permutation() const
    {
      return _permutation;
    }

    /**
     * @brief Sets the permutation
     *
     * This method can set a specific permutation. This method should not be used
     * in combination with permute which provides a dynamic change of the permutation.
     *
     * @param perm New permutation
     * @return True, if successful. It can be unsuccessful, when the size of perm is not suitable.
     *
     * @since  1.0
     */
    bool set_permutation( const std::vector<unsigned>& perm )
    {
      if ( perm.size() == _permutation.size() )
      {
        std::copy( perm.begin(), perm.end(), _permutation.begin() );
        return true;
      }
      else
      {
        return false;
      }
    }

    /**
     * @brief Permutes the current permutation
     *
     * This methods calls <tt>std::next_permutation</tt> on the current permutation.
     * It returns false, when all permutations were considered.
     *
     * @return False, when all permutations were considered, true otherwise.
     *
     * @since  1.0
     */
    bool permute()
    {
      return std::next_permutation( _permutation.begin(), _permutation.end() );
    }

    /**
     * @brief Sets the inputs of the specification
     *
     * Use \ref copy_metadata to assign specification meta-data to a circuit.
     *
     * @param ins Vector of input names
     *
     * @since  1.0
     */
    void set_inputs( const std::vector<std::string>& ins )
    {
      _inputs = ins;
    }

    /**
     * @brief Returns the inputs of the specification
     *
     * Use \ref copy_metadata to assign specification meta-data to a circuit.
     *
     * @return Vector of input names
     *
     * @since  1.0
     */
    const std::vector<std::string>& inputs() const
    {
      return _inputs;
    }

    /**
     * @brief Sets the outputs of the specification
     *
     * Use \ref copy_metadata to assign specification meta-data to a circuit.
     *
     * @param outs Vector of output names
     *
     * @since  1.0
     */
    void set_outputs( const std::vector<std::string>& outs )
    {
      _outputs = outs;
    }

    /**
     * @brief Returns the outputs of the specification
     *
     * The outputs are permuted in respect to the current permutation.
     *
     * Use \ref copy_metadata to assign specification meta-data to a circuit.
     *
     * @return Vector of output names
     *
     * @since  1.0
     */
    std::vector<std::string> outputs() const
    {
      if ( _outputs.size() == _permutation.size() )
      {
        // permute outputs first
        return std::vector<std::string>( boost::make_permutation_iterator( _outputs.begin(), _permutation.begin() ), boost::make_permutation_iterator( _outputs.begin(), _permutation.end() ) );
      }
      else
      {
        return _outputs;
      }
    }

    /**
     * @brief Sets the constant lines of the specification
     *
     * Use \ref copy_metadata to assign specification meta-data to a circuit.
     *
     * @param constants Vector of constant values
     *
     * @since  1.0
     */
    void set_constants( const std::vector<constant>& constants )
    {
      _constants = constants;
      _constants.resize( num_inputs(), constant() );
    }

    /**
     * @brief Returns the constant line information of the specification
     *
     * Use \ref copy_metadata to assign specification meta-data to a circuit.
     *
     * @return Vector of constant line information
     *
     * @since  1.0
     */
    const std::vector<constant>& constants() const
    {
      return _constants;
    }

    /**
     * @brief Sets the garbage lines of the specification
     *
     * Use \ref copy_metadata to assign specification meta-data to a circuit.
     *
     * @param garbage Vector of garbage values
     *
     * @since  1.0
     */
    void set_garbage( const std::vector<bool>& garbage )
    {
      _garbage = garbage;
      _garbage.resize( num_outputs(), false );
    }

    /**
     * @brief Returns the garbage line information of the specification
     *
     * The garbage line information is permuted in respect to the current permutation.
     *
     * Use \ref copy_metadata to assign specification meta-data to a circuit.
     *
     * @return Vector of garbage line information
     *
     * @since  1.0
     */
    std::vector<bool> garbage() const
    {
      if ( _garbage.size() == _permutation.size() )
      {
        // permute outputs first
        return std::vector<bool>( boost::make_permutation_iterator( _garbage.begin(), _permutation.begin() ), boost::make_permutation_iterator( _garbage.begin(), _permutation.end() ) );
      }
      else
      {
        return _garbage;
      }
    }

  private:
    /** @cond */
    cube_vector _cubes;
    std::vector<unsigned> _permutation;
    std::vector<std::string> _inputs;
    std::vector<std::string> _outputs;
    std::vector<constant> _constants;
    std::vector<bool> _garbage;
    /** @endcond */
  };

  /** @cond */
  template<typename T>
  struct transform_cube
  {
    explicit transform_cube( const std::vector<unsigned>& permutation ) : permutation( permutation ) {}

    using in_const_iterator_pair  = std::pair<typename truth_table<T>::in_const_iterator, typename truth_table<T>::in_const_iterator>;
    using out_const_iterator_pair = std::pair<typename truth_table<T>::out_const_iterator, typename truth_table<T>::out_const_iterator>;
    using result_type = std::pair<in_const_iterator_pair, out_const_iterator_pair>;

    result_type operator()( const typename truth_table<T>::cube_vector::value_type& ct ) const
    {
      return std::make_pair(
               std::make_pair( ct.first.begin(), ct.first.end() ),
               std::make_pair(
                 boost::make_permutation_iterator( ct.second.begin(), permutation.begin() ),
                 boost::make_permutation_iterator( ct.second.end(), permutation.end() )
               )
             );
    }

  private:
    const std::vector<unsigned>& permutation;
  };
  /** @endcond */

  /**
   * @brief A predefined truth table for specifications using binary values as in specifications for reversible circuits
   *
   * As template type boost::optional<bool> is used, which
   * represents 0, 1, and a don't care value.
   *
   * *

     *

     *     Description
     *     Char representation
     *     Typed value
     *

     *

     *     No constant input line
     *     '-'
     *     @code boost::optional<bool>() @endcode
     *

     *

     *     Constant input line with value 0
     *     '0'
     *     @code boost::optional<bool>( 0 ) @endcode
     *

     *

     *     Constant input line with value 1
     *     '1'
     *     @code boost::optional<bool>( 1 ) @endcode
     *

     *

   */
  using binary_truth_table = truth_table<boost::optional<bool>>;

  /**
   * @brief Outputs a truth table
   *
   * Prints the input and output cubes of a binary truth table
   *
   * @param os The output stream
   * @param spec The truth table
   * @return The output stream \p os
   *
   * @since  1.0
   */
  std::ostream& operator<<( std::ostream& os, const binary_truth_table& spec );

  /**
   * @brief Converts a truth table cube to a number
   *
   * The first element in the cube (at index 0) is thereby the most significant bit.
   *
   * @param cube The cube to be converted
   * @return The \p cube in numerical representation
   *
   * @since  1.0
   */
  unsigned truth_table_cube_to_number( const binary_truth_table::cube_type& cube );

  /**
   * @brief Converts a number to a cube of a fixed bitwidth
   *
   * The first element in the cube (at index 0) is thereby the most significant bit.
   *
   * @param number Number to be converted as a cube
   * @param bw Bit-width of the cube
   * @return The number as cube
   *
   * @since  1.0
   */
  binary_truth_table::cube_type number_to_truth_table_cube( unsigned number, unsigned bw );

}

#endif /* TRUTH_TABLE_HPP */

// Local Variables:
// c-basic-offset: 2
// eval: (c-set-offset 'substatement-open 0)
// eval: (c-set-offset 'innamespace 0)
// End:

max_stars_repo_name: eletesta/cirkit

max_issues_repo_name: eletesta/cirkit

max_forks_repo_name: eletesta/cirkit


text:
/*
* LEGAL NOTICE
* This computer software was prepared by Battelle Memorial Institute,
* hereinafter the Contractor, under Contract No. DE-AC05-76RL0 1830
* with the Department of Energy (DOE). NEITHER THE GOVERNMENT NOR THE
* CONTRACTOR MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY
* LIABILITY FOR THE USE OF THIS SOFTWARE. This notice including this
* sentence must appear on any copies of this computer software.
*
* EXPORT CONTROL
* User agrees that the Software will not be shipped, transferred or
* exported into any country or used in any manner prohibited by the
* United States Export Administration Act or any other applicable
* export laws, restrictions or regulations (collectively the "Export Laws").
* Export of the Software may require some form of license or other
* authority from the U.S. Government, and failure to obtain such
* export control license may result in criminal liability under
* U.S. laws. In addition, if the Software is identified as export controlled
* items under the Export Laws, User represents and warrants that User
* is not a citizen, or otherwise located within, an embargoed nation
* (including without limitation Iran, Syria, Sudan, Cuba, and North Korea)
*     and that User is not otherwise prohibited
* under the Export Laws from receiving the Software.
*
* Copyright 2011 Battelle Memorial Institute.  All Rights Reserved.
* Distributed as open-source under the terms of the Educational Community
* License version 2.0 (ECL 2.0). http://www.opensource.org/licenses/ecl2.php
*
* For further details, see: http://www.globalchange.umd.edu/models/gcam/
*
*/

/*!
* \file atom.cpp
* \ingroup Util
* \brief objects::Atom class source file.
* \author Josh Lurz
*/

#include "util/base/include/definitions.h"
#include <string>
#include <iostream>
#include "util/base/include/atom.h"
#include "util/base/include/atom_registry.h"
#include <boost/functional/hash/hash.hpp>

using namespace std;

namespace objects {
	/*! \brief Constructor which registers the Atom with the AtomRegistry so that it
	*          can be located from throughout the model and deallocated
	*          automatically.
	*/
	Atom::Atom( const string& aUniqueID ):mUniqueID( aUniqueID ){
		// Register the atom. The registry checks for uniqueness and handles
		// deallocation.
		AtomRegistry::getInstance()->registerAtom( this );

		// Compute the hash used for storage of atoms within maps.
		boost::hash<std::string> hashFunction;
		mHashCode = hashFunction( aUniqueID );
	}

	/*! \brief Destructor
	* \details The destructor checks if the AtomRegistry is currently deallocating
	*          Atoms, and if prints a warning if it is not. This would mean that the
	*          Atom was allocated incorrectly.
	*/
	Atom::~Atom(){
		if( !AtomRegistry::getInstance()->isCurrentlyDeallocating() ){
			cout << "Atom is being deallocated before the AtomRegistry deleted it." << endl;
		}
	}
}

max_stars_repo_name: cmcormack/gcam-core

max_issues_repo_name: cmcormack/gcam-core

max_forks_repo_name: cmcormack/gcam-core


text:
#include <iostream>
#include <boost/any.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
using namespace std;
using boost::bind;
using boost::any;

int f(int a, int b)
{
    return a + b;
}
int g(int a, int b)
{
    return a - b;
}
void p(int a)
{
    cout << a << endl;
}

struct node
{
   int operator()(int x, int y)
   {
       return x + y;
   }
   long long operator()(long long x, long long y)
   {
       return x - y;
   }
   long long operator()(long long x, int y)
   {
       return x * y;
   }
   int check(int x)
   {
       return x > 0;
   }
};
node nn;

int main()
{
    boost::function<int(int, int)>ff = f;
    p(f(1, 2));
    boost::function<int(node*, int)>gg = &node::check;
    p(gg(&nn, -2));
    return 0;
}


text:
#include <utility>
#include <vector>
#include <boost/filesystem.hpp>
#include <boost/regex.hpp>
#include "CreatureGenerationValues.hpp"
#include "DisplayTile.hpp"
#include "Setting.hpp"
#include "XMLMapReaders.hpp"
#include "XMLConfigurationReader.hpp"

using namespace std;
using namespace boost::filesystem;

XMLConfigurationReader::XMLConfigurationReader(const string& xml_filename, const string& cr_filename, const string& it_filename)
: filename(xml_filename), creatures_filename(cr_filename), items_filename(it_filename)
{
  XML::initialize();

  // Generally, this will always be provided, but to prevent unnecessary loading
  // in MapTester, it may also be empty.
  if (!xml_filename.empty())
  {
    initialize_parser(xml_filename);
  }
}

XMLConfigurationReader::~XMLConfigurationReader()
{
  XML::tear_down();
}

DeityMap XMLConfigurationReader::get_deities()
{
  XMLNode deities_node = XMLUtils::get_next_element_by_local_name(root, "Deities");
  DeityMap deities = deities_reader.get_deities(deities_node);
  return deities;
}

ClassMap XMLConfigurationReader::get_classes()
{
  XMLNode classes_node = XMLUtils::get_next_element_by_local_name(root, "Classes");
  ClassMap classes = classes_reader.get_classes(classes_node);
  return classes;
}

map<int, CalendarDay> XMLConfigurationReader::get_calendar_days()
{
  XMLNode calendar_node = XMLUtils::get_next_element_by_local_name(root, "Calendar");
  return calendar_reader.get_calendar_days(calendar_node);
}

StartingLocationMap XMLConfigurationReader::get_starting_locations()
{
  XMLNode starting_locations_node = XMLUtils::get_next_element_by_local_name(root, "StartingLocations");
  return sl_reader.get_starting_locations(starting_locations_node);
}

pair<CreatureMap, CreatureGenerationValuesMap> XMLConfigurationReader::get_creatures()
{
  XMLNode prev_config = root;
  initialize_parser(creatures_filename);
  XMLNode creatures_node = XMLUtils::get_next_element_by_local_name(root, "Creatures");
  pair<CreatureMap, CreatureGenerationValuesMap> creatures = creatures_reader.get_creatures(creatures_node);
  root = prev_config;

  return creatures;
}

SpellMap XMLConfigurationReader::get_spells()
{
  XMLNode spells_node = XMLUtils::get_next_element_by_local_name(root, "Spells");
  SpellMap spells = spells_reader.get_spells(spells_node);
  return spells;
}

map<string, pair<string, unordered_map<string, Coordinate>>> XMLConfigurationReader::get_spritesheets()
{
  XMLNode spritesheets_node = XMLUtils::get_next_element_by_local_name(root, "Spritesheets");
  map<string, pair<string, unordered_map<string, Coordinate>>> spritesheets = spritesheets_reader.get_spritesheets(spritesheets_node);
  return spritesheets;
}

pair<ItemMap, GenerationValuesMap> XMLConfigurationReader::get_items()
{
  XMLNode prev_config = root;
  initialize_parser(items_filename);
  XMLNode items_node = XMLUtils::get_next_element_by_local_name(root, "Items");
  pair<ItemMap, GenerationValuesMap> items = items_reader.get_items(items_node);
  root = prev_config;

  return items;
}

FeatureSymbolMap XMLConfigurationReader::get_feature_symbols()
{
  XMLNode features_node = XMLUtils::get_next_element_by_local_name(root, "AllFeatures");
  XMLNode base_features_node = XMLUtils::get_next_element_by_local_name(features_node, "BaseFeatures");
  FeatureSymbolMap fsm = bf_reader.get_feature_symbols(base_features_node);

  return fsm;
}

FeatureMap XMLConfigurationReader::get_configurable_features()
{
  XMLNode features_node = XMLUtils::get_next_element_by_local_name(root, "AllFeatures");
  XMLNode config_features_node = XMLUtils::get_next_element_by_local_name(features_node, "ConfigurableFeatures");
  FeatureMap cfm = cf_reader.get_configurable_features(config_features_node);

  return cfm;
}

map<string, string> XMLConfigurationReader::get_scripts()
{
  XMLNode scripts_node = XMLUtils::get_next_element_by_local_name(root, "Scripts");
  map<string, string> scripts = scripts_reader.get_scripts(scripts_node);
  return scripts;
}

RaceMap XMLConfigurationReader::get_races()
{
  XMLNode races_node = XMLUtils::get_next_element_by_local_name(root, "Races");
  RaceMap races = races_reader.get_races(races_node);
  return races;
}

vector<DisplayTile> XMLConfigurationReader::get_tile_info()
{
  XMLNode tiles_node = XMLUtils::get_next_element_by_local_name(root, "Tiles");
  vector<DisplayTile> tile_info = tiles_reader.get_tiles(tiles_node);
  return tile_info;
}

vector<TrapPtr> XMLConfigurationReader::get_trap_info()
{
  XMLNode traps_node = XMLUtils::get_next_element_by_local_name(root, "Traps");
  vector<TrapPtr> trap_info = traps_reader.get_traps(traps_node);
  return trap_info;
}

vector<MapPtr> XMLConfigurationReader::get_custom_maps(const string& directory, const string& filename_pattern)
{
  vector<MapPtr> custom_maps;
  XMLMapReader map_reader;

  directory_iterator end_it;
  boost::regex e(filename_pattern);

  for (directory_iterator d_it(directory); d_it != end_it; d_it++)
  {
    string filename = d_it->path().string();

    if (boost::regex_search(filename, e))
    {
      initialize_parser(filename);

      if (!root.is_null())
      {
        string xmlns = XMLUtils::get_attribute_value(root, "xmlns");
        XML::set_namespace(xmlns); // these use a different ns than the main shadow of the wyrm xml.
      }

      MapPtr custom_map = map_reader.get_custom_map(root);

      if (custom_map)
      {
        custom_maps.push_back(custom_map);
      }
    }
  }

  return custom_maps;
}

void XMLConfigurationReader::set_new_file(const string& xml_filename)
{
  initialize_parser(xml_filename);
}

void XMLConfigurationReader::initialize_parser(const string& xml_filename)
{
  XMLFileReader reader;
  root = reader.get_xml_from_file(xml_filename);
}

max_stars_repo_name: prolog/shadow-of-the-wyrm

max_issues_repo_name: prolog/shadow-of-the-wyrm

max_forks_repo_name: prolog/shadow-of-the-wyrm


text:
#ifndef TASK_HPP
#define TASK_HPP

#include <list>
#include <memory>
#include <functional>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

#include "source.hpp"
#include "command.hpp"

typedef std::function<void(bool)> task_finish_handler;

struct task_settings
{
    std::string name;
    source_wptr src;
    bool has_source;
    std::list<command_wptr> command_list;
    boost::posix_time::time_duration duration;
    bool start_at_load = false;
};

class task
{
public:
    explicit task(boost::asio::io_service &service, const task_settings &settings, const boost::filesystem::path &workspaces_path);

    boost::asio::io_service &get_service() const;
    boost::posix_time::time_duration get_duration() const;
    bool is_start_at_load() const;

    void execute(task_finish_handler finish_handler);

private:
    void execute_command(const boost::filesystem::path &workspace_path, std::list<command_wptr>::iterator &it, task_finish_handler finish_handler);

private:
    boost::asio::io_service &_service;
    task_settings _settings;
    boost::filesystem::path _workspaces_path;
    params_map _context_params;
};

typedef std::shared_ptr<task> task_ptr;

#endif // TASK_HPP

max_stars_repo_name: pozitiffcat/build-disp

max_issues_repo_name: pozitiffcat/build-disp

max_forks_repo_name: pozitiffcat/build-disp


text:
#include <frovedis.hpp>
#include <frovedis/matrix/pblas_wrapper.hpp>

#define BOOST_TEST_MODULE FrovedisTest
#include <boost/test/unit_test.hpp>

using namespace frovedis;
using namespace std;

BOOST_AUTO_TEST_CASE( frovedis_test )
{
    int argc = 1;
    char** argv = NULL;
    use_frovedis use(argc, argv);

    // copying two distributed std::vectors'
    std::vector<float> x = {1,2,3,4};
    std::vector<float> y = {0,0,0,0};
    auto xbm = vec_to_bcm<float> (x); // distributed vector x
    auto ybm = vec_to_bcm<float> (y); // distrubuted vector y
    copy<float> (xbm,ybm); // ybm = xbm;
    BOOST_CHECK (xbm.moveto_vector() == ybm.moveto_vector());

    auto bm = make_blockcyclic_matrix_load<float> ("./sample_4x4");

    // checking copy() operation
    auto row1 = make_row_vector<float> (bm,1);
    auto row2 = make_row_vector<float> (bm,2);
    copy<float>(row1,row2); // row2 = row1
    bm.save("./out_4x4");

    // checking whether the above operation successfully taken place
    BOOST_CHECK (system("diff ./out_4x4 ./ref_4x4") == 0);
    system("rm -f ./out_4x4");
}

ext: cc

max_stars_repo_name: XpressAI/frovedis

max_issues_repo_name: XpressAI/frovedis

max_forks_repo_name: XpressAI/frovedis


text:
#pragma once

#include "iterate_struct.hpp"
#include "JsonValue_fwd.hpp"

#include <vector>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/join.hpp>

namespace silver_bullets {
namespace iterate_struct {

class struct_paths_collector
{
public:
    explicit struct_paths_collector(bool leavesOnly) :
        m_leavesOnly(leavesOnly)
    {}

    template<class T>
    inline void operator()(T& value, const char *name) const
    {
        m_current_path_items.push_back(name);
        collect_priv(value);
        m_current_path_items.pop_back();
    }

    template<class T>
    static std::vector<std::string> collect(const T& value, bool leavesOnly)
    {
        struct_paths_collector collector(leavesOnly);
        collector.collect_priv(value);
        return collector.m_paths;
    }

private:
    bool m_leavesOnly;

    template <
            class T,
            std::enable_if_t<
                std::is_integral_v<T> ||
                std::is_enum_v<T> ||
                std::is_floating_point_v<T> ||
                std::is_same_v<T, std::string>, int> = 0>
    void collect_priv(const T&) const {
        m_paths.push_back(current_path());
    }

    template <class T, std::enable_if_t<iterate_struct::has_iterate_struct_helper_v<T>, int> = 0>
    void collect_priv(const T& x) const
    {
        if (!m_leavesOnly)
            m_paths.push_back(current_path());
        for_each(x, *this);
    }

    template<class T>
    void collect_priv(const std::vector<T>& x) const
    {
        if (!m_leavesOnly)
            m_paths.push_back(current_path());
        for (std::size_t i=0, n=x.size(); i<n; ++i) {
            m_current_path_items.push_back(boost::lexical_cast<std::string>(i));
            collect_priv(x[i]);
            m_current_path_items.pop_back();
        }
    }

    template<class T1, class T2>
    void collect_priv(const std::pair<T1, T2>& x) const
    {
        if (!m_leavesOnly)
            m_paths.push_back(current_path());
        m_current_path_items.push_back("0");
        collect_priv(x.first);
        m_current_path_items.pop_back();
        m_current_path_items.push_back("1");
        collect_priv(x.second);
        m_current_path_items.pop_back();
    }

    template<class T1, class T2>
    void collect_priv(const std::map<T1, T2>& x) const
    {
        if (!m_leavesOnly)
            m_paths.push_back(current_path());
        for (auto& item : x) {
            m_current_path_items.push_back(boost::lexical_cast<std::string>(item.first));
            collect_priv(item.second);
            m_current_path_items.pop_back();
        }
    }

    void collect_priv(const JsonValue& x) const {
        m_paths.push_back(current_path());  // TODO better: expand JSON value
    }

    std::string current_path() const {
        return std::string("/") + boost::join(m_current_path_items, "/");
    }

    mutable std::vector<std::string> m_current_path_items;
    mutable std::vector<std::string> m_paths;
};

template<class T, std::enable_if_t<iterate_struct::has_iterate_struct_helper_v<T>, int> = 0>
inline std::vector<std::string> collect_paths(const T& value, bool leavesOnly) {
    return struct_paths_collector::collect(value, leavesOnly);
}

} // namespace iterate_struct
} // namespace silver_bullets


text:
#include "Analyzer.h"
#include "MeshSampling.h"
#include "Computation.h"
#include "Globals.h"
#include "SmartStreamBuffer.h"

#include <pcl/filters/uniform_sampling.h>
#include <pcl/registration/transformation_estimation_svd_scale.h>
#include <pcl/registration/gicp.h>
#include <pcl/surface/convex_hull.h>
#include <pcl/filters/filter.h>
#include <pcl/surface/gp3.h>
#include <pcl/features/normal_3d.h>
#include <Eigen/Dense>
#include <chrono>
#include <ostream>
#include <functional>

namespace ASE
{
    shared_ptr<SmartStreamBuffer> voutBuffer = make_shared<SmartStreamBuffer>(6);
    ostream vout(voutBuffer.get());

    typedef PointCloud<PointXYZ> Cloud;

    Analyzer::Analyzer(const AnalyzerConfig& config) : _config(config), _viewer(new Viewer(config)), _feedback(config.enableViewer && config.forceUserFeedback), _stopWatch(new StopWatch)
    {
    }

    Analyzer::~Analyzer()
    {
    }

    AnalysisResult Analyzer::run(pcl::PointCloud<pcl::PointXYZ>& backgroundScene, pcl::PointCloud<pcl::PointXYZ>& objectScene, pcl::PolygonMesh& referenceModel)
    {
        _setupViewer();

        vout << "preparing clouds..." << endl;

        _stopWatch->start();
        auto sceneCloud = backgroundScene.makeShared();
        auto objectCloud = objectScene.makeShared();
        auto referenceCloud = _setupModel(referenceModel);
        vector<int> dummy;

        vout << "resampling background scene from " << sceneCloud->size() << " to ";
        //resampleCloud<PointXYZ>(sceneCloud);
        removeNaNFromPointCloud(*sceneCloud, *sceneCloud, dummy);
        vout << sceneCloud->size() << " points" << endl;

        vout << "resampling object scene from " << objectCloud->size() << " to ";
        //resampleCloud<PointXYZ>(objectCloud);
        removeNaNFromPointCloud(*objectCloud, *objectCloud, dummy);
        vout << objectCloud->size() << " points" << endl;

        _stopWatch->stop();
        // position clouds next to each other, just for esthetical reasons
        if (_config.enableViewer)
            _positionClouds(sceneCloud, objectCloud, referenceCloud);
        _stopWatch->start();

        _viewer->addCloud(sceneCloud, "scene", _config.visualizer.pointSize, _config.visualizer.cloudOpacity);
        _viewer->addCloud(objectCloud, "object", _config.visualizer.pointSize, _config.visualizer.cloudOpacity);
        _viewer->addCloud(referenceCloud, "reference", _config.visualizer.pointSize, _config.visualizer.cloudOpacity);

        _wait();

        _alignScenes(sceneCloud, objectCloud);

        _wait();

        _extractObject(sceneCloud, objectCloud);

        _wait();

        _alignObjects(objectCloud, referenceCloud);
        auto result = _computeResult(objectCloud, referenceCloud, referenceModel);

        _wait("press a key to exit...");

        return result;
    }

    pcl::PointCloud<pcl::PointXYZ>::Ptr Analyzer::_setupModel(pcl::PolygonMesh& mesh) const
    {
        MeshSampling sampling;
        return sampling.sample(mesh, _config.preprocess.referenceCloudSamplingSize, _config.preprocess.referenceCloudGridFilterSize);
    }

    void Analyzer::_setupViewer()
    {
        if (_config.enableViewer)
        {
            _viewer->start();
            _feedback.setViewer(_viewer);
        }
    }

    void Analyzer::_positionClouds(Cloud::Ptr& scene, Cloud::Ptr& object, Cloud::Ptr& reference)
    {
        if (!_config.enableViewer)
            return;

        Affine3f m = Affine3f::Identity();
        auto bbScene = computeAABB<PointXYZ>(scene);
        m.translation() << -bbScene.sizeX / 2 * 1.2 , 0 , -bbScene.cloud->at(0).z;
        transformPointCloud(*scene, *scene, m);

        m = Affine3f::Identity();
        auto bbObj = computeAABB<PointXYZ>(object);
        m.translation() << bbObj.sizeX / 2 * 1.2 , 0 , -bbObj.cloud->at(0).z;
        transformPointCloud(*object, *object, m);
    }

    void Analyzer::_alignScenes(pcl::PointCloud<pcl::PointXYZ>::Ptr& scene, pcl::PointCloud<pcl::PointXYZ>::Ptr& object)
    {
        Cloud::Ptr sceneKeys(new Cloud);
        Cloud::Ptr objKeys(new Cloud);
        double ls = _config.preprocess.keypointsLeafSize;

        vout << "computing key points: background... ";

        UniformSampling<PointXYZ> sampling;
        sampling.setInputCloud(scene);
        sampling.setRadiusSearch(ls);
        sampling.filter(*sceneKeys);

        vout << "done (" << sceneKeys->size() << " points), foreground... ";

        sampling.setInputCloud(object);
        sampling.filter(*objKeys);

        vout << "done (" << objKeys->size() << " points)" << endl;

        _viewer->addCloud(sceneKeys, "scene_keys", _config.visualizer.keyPointSize, _config.visualizer.cloudOpacity);
        _viewer->addCloud(objKeys, "object_keys", _config.visualizer.keyPointSize, _config.visualizer.cloudOpacity);

        _wait();

        vout << "aligning key points... ";

        auto keypointsIcpCallback = [this, &sceneKeys, &scene](int n, double fitness, Matrix4f transform)
            {
                transformPointCloud(*scene, *scene, transform);
                _viewer->updateCloud(sceneKeys);
                _viewer->updateCloud(scene);
                return true;
            };

        runIcp(sceneKeys, objKeys, _config.preprocess.icpEpsilon, _config.preprocess.icpMaxIterations, _config.preprocess.icpStep, keypointsIcpCallback);

        vout << "done" << endl << "aligning scenes... ";

        auto fullCloudIcpCallback = [this, &sceneKeys, &scene](int n, double fitness, Matrix4f transform)
            {
                transformPointCloud(*sceneKeys, *sceneKeys, transform);
                _viewer->updateCloud(sceneKeys);
                _viewer->updateCloud(scene);
                return true;
            };

        runIcp(scene, object, _config.preprocess.icpEpsilon, _config.preprocess.icpMaxIterations, _config.preprocess.icpStep, fullCloudIcpCallback);

        vout << "done" << endl;

        _viewer->removeCloud(sceneKeys);
        _viewer->removeCloud(objKeys);
    }

    void Analyzer::_extractObject(pcl::PointCloud<pcl::PointXYZ>::Ptr& scene, pcl::PointCloud<pcl::PointXYZ>::Ptr& object)
    {
        vout << "extracting target object... " << endl << "subtracting (tolerance=" << _config.objectExtraction.subtractionTolerance * 1000 << "mm)... ";
        auto result = subtract(object, scene, _config.objectExtraction.subtractionTolerance);
        vout << "done" << endl;

        _viewer->removeCloud(scene);
        _viewer->removeCloud(object);
        _viewer->addCloud(result, "object_noisy");

        _wait();

        vout << "applying noise filter: K=" << _config.objectExtraction.noiseFilterK << " StdDevMul=" << _config.objectExtraction.noiseStdDevMul << "... ";
        auto tmp = applyNoiseFilter(result, _config.objectExtraction.noiseFilterK, _config.objectExtraction.noiseStdDevMul);
        vout << "done" << endl;
        vout << "finding clusters: Tolerance=" << _config.objectExtraction.clusterTolerance << " MinSize=" << _config.objectExtraction.clusterMinSize
            << " MaxSize=" << _config.objectExtraction.clusterMaxSize << "... ";
        tmp = applyClusterFilter(tmp, _config.objectExtraction.clusterTolerance, _config.objectExtraction.clusterMinSize, _config.objectExtraction.clusterMaxSize);
        vout << "done" << endl;

        object = tmp;
        _viewer->removeCloud(result);
        _viewer->addCloud(object, "object", _config.visualizer.pointSize, _config.visualizer.cloudOpacity);
    }

    void Analyzer::_alignObjects(pcl::PointCloud<pcl::PointXYZ>::Ptr& object, pcl::PointCloud<pcl::PointXYZ>::Ptr& reference)
    {
        vout << "aligning object to reference..." << endl;
        int iterCnt = 0;
        double fitness = 0;

        centerClouds(*object, *reference);

        auto icpcb = [this, &object, &iterCnt, &fitness](int n, double f, Matrix4f transform)
            {
                fitness = f;
                iterCnt = n;
                _viewer->updateCloud(object);
                return true;
            };

        GeneralizedIterativeClosestPoint<PointXYZ, PointXYZ> icpg;

        if (_config.objectAlignment.prealignToBoundingBox)
        {
            vout << "performing ICP at bounding boxes of target object and reference model... ";
            auto obbRef = computeOBB<PointXYZ>(reference).cloud;
            auto obbObj = computeOBB<PointXYZ>(object).cloud;

            auto cb = [this, &object, &iterCnt, &fitness](int n, double f, Matrix4f transform)
                {
                    fitness = f;
                    iterCnt = n;
                    transformPointCloud(*object, *object, transform);
                    _viewer->updateCloud(object);
                    return true;
                };

            runIcp(obbObj, obbRef, _config.objectAlignment.icpgEpsilon, _config.objectAlignment.icpMaxIterations, _config.objectAlignment.icpStep, cb);
            vout << "done (iterations=" << iterCnt << " fitness=" << fitness * 1000 << "mm)" << endl;
        }

        if (_config.objectAlignment.prealignToConvexHull)
        {
            vout << "performing generalized ICP at target object and convex hull of reference model... ";
            auto convexHull = boost::make_shared<Cloud>();
            ConvexHull<PointXYZ> hull;
            hull.setInputCloud(reference);
            hull.reconstruct(*convexHull);
            runIcp(icpg, object, convexHull, _config.objectAlignment.icpgEpsilon, _config.objectAlignment.icpMaxIterations, _config.objectAlignment.icpStep, icpcb);
            vout << "done (iterations=" << iterCnt << " fitness=" << fitness * 1000 << "mm)" << endl;
        }

        vout << "performing generalized ICP at target object and reference model... ";
        runIcp(icpg, object, reference, _config.objectAlignment.icpgEpsilon, _config.objectAlignment.icpMaxIterations, _config.objectAlignment.icpStep, icpcb);
        vout << "done (iterations=" << iterCnt << " fitness=" << fitness * 1000 << "mm)" << endl;

        if (_config.objectAlignment.postalignByScale)
        {
            auto initialBB = computeOBB<PointXYZ>(object);

            IterativeClosestPoint<PointXYZ, PointXYZ> icp;
            auto te = boost::make_shared<registration::TransformationEstimationSVDScale<PointXYZ, PointXYZ>>();
            icp.setTransformationEstimation(te);

            vout << "performing scale invariant ICP at target object and reference model... ";
            runIcp(icp, object, reference, _config.objectAlignment.icpEpsilon, _config.objectAlignment.icpMaxIterations, _config.objectAlignment.icpStep, icpcb);
            auto bb = computeOBB<PointXYZ>(object);
            _finalScale = (bb.sizeX / initialBB.sizeX + bb.sizeY / initialBB.sizeY + bb.sizeZ / initialBB.sizeZ) / 3;
            vout << "done (iterations=" << iterCnt << " fitness=" << fitness * 1000 << "mm, scale=" << _finalScale << ")" << endl;
        }
    }

    AnalysisResult Analyzer::_computeResult(pcl::PointCloud<pcl::PointXYZ>::Ptr& object, pcl::PointCloud<pcl::PointXYZ>::Ptr& reference, const PolygonMesh& referenceMesh)
    {
        vout << "computing distances... ";
        search::KdTree<PointXYZ> kdTree;
        kdTree.setInputCloud(reference);
        vector<float> distances(object->size());

        for (int i = 0; i < object->size(); i++)
        {
            vector<float> dist(1);
            vector<int> idx(1);
            kdTree.nearestKSearch(object->at(i), 1, idx, dist);
            distances[i] = sqrt(dist[0]);
        }

        auto resultCloudWithDistance = boost::make_shared<PointCloud<PointXYZRGB>>();
        double maxDist = 0;

        for (auto d : distances)
            if (d > maxDist)
                maxDist = d;

        for (int i = 0; i < object->size(); i++)
        {
            PointXYZRGB p;
            auto r = object->at(i);
            p.x = r.x;
            p.y = r.y;
            p.z = r.z;
            p.r = min(distances[i] / maxDist * 255, 255.0);
            p.b = 255 - min(distances[i] / maxDist * 255, 255.0);
            resultCloudWithDistance->push_back(p);
        }

        _viewer->removeCloud(object);
        //_viewer->lock();
        //auto viewer = _viewer->getViewer();
        //viewer->addPointCloud(resultCloudWithDistance, "final_result");
        //viewer->setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_POINT_SIZE, 2, "final_result");
        //viewer->setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_OPACITY, 0.4, "reference");
        //_viewer->unlock();

        vout << "done" << endl;

        // compute area
        boost::shared_ptr<Cloud> meshCloud(new Cloud);
        fromPCLPointCloud2(referenceMesh.cloud, *meshCloud);
        double refArea = 0;

        vout << "computing area of reference model...";

        for (auto triangle : referenceMesh.polygons)
        {
            auto a = meshCloud->at(triangle.vertices[0]),
                b = meshCloud->at(triangle.vertices[1]),
                c = meshCloud->at(triangle.vertices[2]);

            Vector3f v1(a.x, a.y, a.z),
                v2(b.x, b.y, b.z),
                v3(c.x, c.y, c.z);

            // compute size of triangle http://mathworld.wolfram.com/TriangleArea.html (division by 2 follows at the end)
            refArea += (v2 - v1).cross(v1 - v3).norm();
        }
        refArea /= 2;

        vout << "done (area=" << refArea * 1e6 << "sqmm)" << endl;
        vout << "triangulating object cloud...";

        PointCloud<PointNormal>::Ptr normalCloud(new PointCloud<PointNormal>);
        NormalEstimation<PointXYZ, PointNormal> normals;
        normals.setInputCloud(object);
        //normals.setKSearch(_config.analysis.objectNormalEstimationK);
        normals.setRadiusSearch(_config.analysis.objectNormalEstimationRadius);
        normals.compute(*normalCloud);

        pcl::concatenateFields(*object, *normalCloud, *normalCloud);

        vector<Vertices> polygon;
        GreedyProjectionTriangulation<PointNormal> triangulation;
        triangulation.setInputCloud(normalCloud);
        triangulation.setMu(_config.analysis.objectTriangulationKMultiplier);
        triangulation.setNormalConsistency(false);
        triangulation.setSearchRadius(_config.analysis.objectTriangulationSearchRadius);
        triangulation.reconstruct(polygon);

        vout << "done" << endl;

        if (_config.enableViewer)
        {
            _viewer->lock();
            auto viewer = _viewer->getViewer();
            //viewer->addPointCloudNormals<PointNormal>(normalCloud, 30, 0.03, "result_normals");
            viewer->addPolygonMesh<PointXYZRGB>(resultCloudWithDistance, polygon, "meshed_result");
            _viewer->unlock();
        }

        vout << "computing area of object's triangulation... ";

        double objArea = 0;

        for (auto triangle : polygon)
        {
            auto a = object->at(triangle.vertices[0]),
                b = object->at(triangle.vertices[1]),
                c = object->at(triangle.vertices[2]);

            Vector3f v1(a.x, a.y, a.z),
                v2(b.x, b.y, b.z),
                v3(c.x, c.y, c.z);

            // compute size of triangle http://mathworld.wolfram.com/TriangleArea.html (division by 2 follows at the end)
            objArea += (v2 - v1).cross(v1 - v3).norm();
        }
        objArea /= 2;

        vout << "done (area=" << objArea * 1e6 << "sqmm)" << endl;
        _stopWatch->stop();

        double time = _stopWatch->getTime().count() * 1e-9;

        AnalysisResult result(object, reference, distances, _finalScale, objArea, refArea, time);
        return result;
    }

    void Analyzer::_wait(const std::string& msg)
    {
        _stopWatch->stop();
        _feedback.wait(msg);
        _stopWatch->start();
    }
}


text:
/***************************************************************************
 * Copyright 1998-2017 by authors (see AUTHORS.txt)                        *
 *                                                                         *
 *   This file is part of LuxRender.                                       *
 *                                                                         *
 * Licensed under the Apache License, Version 2.0 (the "License");         *
 * you may not use this file except in compliance with the License.        *
 * You may obtain a copy of the License at                                 *
 *                                                                         *
 *     http://www.apache.org/licenses/LICENSE-2.0                          *
 *                                                                         *
 * Unless required by applicable law or agreed to in writing, software     *
 * distributed under the License is distributed on an "AS IS" BASIS,       *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*
 * See the License for the specific language governing permissions and     *
 * limitations under the License.                                          *
 ***************************************************************************/

#if !defined(LUXRAYS_DISABLE_OPENCL)

#include <iosfwd>
#include <limits>

#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

#include "slg/engines/pathoclbase/compiledscene.h"
#include "slg/kernels/kernels.h"

using namespace std;
using namespace luxrays;
using namespace slg;

static bool MeshPtrCompare(Mesh *p0, Mesh *p1) {
	return p0 < p1;
}

void CompiledScene::CompileGeometry() {
	SLG_LOG("Compile Geometry");
	wasGeometryCompiled = true;

	const u_int objCount = scene->objDefs.GetSize();

	const double tStart = WallClockTime();

	// Clear vectors
	verts.resize(0);
	normals.resize(0);
	uvs.resize(0);
	cols.resize(0);
	alphas.resize(0);
	tris.resize(0);
	meshDescs.resize(0);

	//--------------------------------------------------------------------------
	// Translate geometry
	//--------------------------------------------------------------------------

	// Not using boost::unordered_map because because the key is an ExtMesh pointer
	map<ExtMesh *, u_int, bool (*)(Mesh *, Mesh *)> definedMeshs(MeshPtrCompare);

	slg::ocl::Mesh newMeshDesc;
	newMeshDesc.vertsOffset = 0;
	newMeshDesc.trisOffset = 0;
	newMeshDesc.normalsOffset = 0;
	newMeshDesc.uvsOffset = 0;
	newMeshDesc.colsOffset = 0;
	newMeshDesc.alphasOffset = 0;
	memcpy(&newMeshDesc.trans.m, &Matrix4x4::MAT_IDENTITY, sizeof(float[4][4]));
	memcpy(&newMeshDesc.trans.mInv, &Matrix4x4::MAT_IDENTITY, sizeof(float[4][4]));

	slg::ocl::Mesh currentMeshDesc;
	for (u_int i = 0; i < objCount; ++i) {
		const ExtMesh *mesh = scene->objDefs.GetSceneObject(i)->GetExtMesh();

		bool isExistingInstance;
		// TODO: Motion blur is not supported here (!)
		if (mesh->GetType() == TYPE_EXT_TRIANGLE_INSTANCE) {
			// It is an instanced mesh
			ExtInstanceTriangleMesh *imesh = (ExtInstanceTriangleMesh *)mesh;

			// Check if is one of the already defined meshes
			map<ExtMesh *, u_int, bool (*)(Mesh *, Mesh *)>::iterator it = definedMeshs.find(imesh->GetExtTriangleMesh());
			if (it == definedMeshs.end()) {
				// It is a new one
				currentMeshDesc = newMeshDesc;

				newMeshDesc.vertsOffset += mesh->GetTotalVertexCount();
				newMeshDesc.trisOffset += mesh->GetTotalTriangleCount();
				if (mesh->HasNormals())
					newMeshDesc.normalsOffset += mesh->GetTotalVertexCount();
				if (mesh->HasUVs())
					newMeshDesc.uvsOffset += mesh->GetTotalVertexCount();
				if (mesh->HasColors())
					newMeshDesc.colsOffset += mesh->GetTotalVertexCount();
				if (mesh->HasAlphas())
					newMeshDesc.alphasOffset += mesh->GetTotalVertexCount();

				isExistingInstance = false;

				const u_int index = meshDescs.size();
				definedMeshs[imesh->GetExtTriangleMesh()] = index;
			} else {
				currentMeshDesc = meshDescs[it->second];

				isExistingInstance = true;
			}

			// Overwrite the only different fields in an instanced mesh
			memcpy(&currentMeshDesc.trans.m, &imesh->GetTransformation().m, sizeof(float[4][4]));
			memcpy(&currentMeshDesc.trans.mInv, &imesh->GetTransformation().mInv, sizeof(float[4][4]));

			// In order to express normals and vertices in local coordinates
			mesh = imesh->GetExtTriangleMesh();
		} else {
			// It is a not instanced mesh
			currentMeshDesc = newMeshDesc;

			newMeshDesc.vertsOffset += mesh->GetTotalVertexCount();
			newMeshDesc.trisOffset += mesh->GetTotalTriangleCount();
			if (mesh->HasNormals())
				newMeshDesc.normalsOffset += mesh->GetTotalVertexCount();
			if (mesh->HasUVs())
				newMeshDesc.uvsOffset += mesh->GetTotalVertexCount();
			if (mesh->HasColors())
				newMeshDesc.colsOffset += mesh->GetTotalVertexCount();
			if (mesh->HasAlphas())
				newMeshDesc.alphasOffset += mesh->GetTotalVertexCount();

			memcpy(&currentMeshDesc.trans.m, &Matrix4x4::MAT_IDENTITY, sizeof(float[4][4]));
			memcpy(&currentMeshDesc.trans.mInv, &Matrix4x4::MAT_IDENTITY, sizeof(float[4][4]));

			isExistingInstance = false;
		}

		if (!isExistingInstance) {
			//------------------------------------------------------------------
			// Translate mesh normals (expressed in local coordinates)
			//------------------------------------------------------------------

			if (mesh->HasNormals()) {
				for (u_int j = 0; j < mesh->GetTotalVertexCount(); ++j)
					normals.push_back(mesh->GetShadeNormal(0.f, j));
			} else
				currentMeshDesc.normalsOffset = NULL_INDEX;

			//------------------------------------------------------------------
			// Translate vertex uvs
			//------------------------------------------------------------------

			if (mesh->HasUVs()) {
				for (u_int j = 0; j < mesh->GetTotalVertexCount(); ++j)
					uvs.push_back(mesh->GetUV(j));
			} else
				currentMeshDesc.uvsOffset = NULL_INDEX;

			//------------------------------------------------------------------
			// Translate vertex colors
			//------------------------------------------------------------------

			if (mesh->HasColors()) {
				for (u_int j = 0; j < mesh->GetTotalVertexCount(); ++j)
					cols.push_back(mesh->GetColor(j));
			} else
				currentMeshDesc.colsOffset = NULL_INDEX;

			//------------------------------------------------------------------
			// Translate vertex alphas
			//------------------------------------------------------------------

			if (mesh->HasAlphas()) {
				for (u_int j = 0; j < mesh->GetTotalVertexCount(); ++j)
					alphas.push_back(mesh->GetAlpha(j));
			} else
				currentMeshDesc.alphasOffset = NULL_INDEX;

			//------------------------------------------------------------------
			// Translate mesh vertices (expressed in local coordinates)
			//------------------------------------------------------------------

			for (u_int j = 0; j < mesh->GetTotalVertexCount(); ++j)
				verts.push_back(mesh->GetVertex(0.f, j));

			//------------------------------------------------------------------
			// Translate mesh indices
			//------------------------------------------------------------------

			Triangle *mtris = mesh->GetTriangles();
			for (u_int j = 0; j < mesh->GetTotalTriangleCount(); ++j)
				tris.push_back(mtris[j]);
		}

		meshDescs.push_back(currentMeshDesc);
	}

	worldBSphere = scene->dataSet->GetBSphere();

	const double tEnd = WallClockTime();
	SLG_LOG("Scene geometry compilation time: " << int((tEnd - tStart) * 1000.0) << "ms");
}

#endif

max_stars_repo_name: LuxRender/LuxRays

max_issues_repo_name: LuxRender/LuxRays

max_forks_repo_name: LuxRender/LuxRays


text:
#include "BinaryMetadataExtractor.h"
#include "FilesystemMetadataExtractor.h"
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/io/coded_stream.h>
#include <boost/filesystem/operations.hpp>
#include <fstream>
#include <unordered_map>

bool ParseFromCodedInputStreamWithDescriptorPool(google::protobuf::FileDescriptorProto& proto, google::protobuf::io::CodedInputStream* decoder)
{
    decoder->SetExtensionRegistry(google::protobuf::DescriptorPool::generated_pool(), google::protobuf::MessageFactory::generated_factory());
    return proto.ParseFromCodedStream(decoder) && decoder->ConsumedEntireMessage();
}

std::unordered_map<std::string, std::pair<google::protobuf::FileDescriptor const*, bool>> fileDescriptorsByName;
google::protobuf::DynamicMessageFactory* dynamicMessageFactory = new google::protobuf::DynamicMessageFactory(); // LEAKED ON PURPOSE, messages generated by this are double registered (and would be double freed)

int main(int argc, char* argv[])
{
    // initialize Descriptor descriptors
    google::protobuf::DescriptorProto().GetMetadata();

    // first collect files
    std::unique_ptr<MetadataExtractor> extractor;
    if (argc > 1)
    {
        // parse protobuf metadata from binary
        extractor = std::make_unique<BinaryMetadataExtractor>();
        extractor->Parse(argv[1]);
    }
    else
    {
        extractor = std::make_unique<FilesystemMetadataExtractor>();
        extractor->Parse(boost::filesystem::current_path());
    }

    // its time to hack private members
    google::protobuf::DescriptorPool* pool = google::protobuf::DescriptorPool::internal_generated_pool();
    void* mutex_ = *reinterpret_cast<char**>(pool);
    void* fallback_database_ = *(reinterpret_cast<void**>(pool) + 1);
    *reinterpret_cast<void**>(pool) = nullptr; // mutex_
    *(reinterpret_cast<void**>(pool) + 1) = nullptr; // fallback_database_

    std::vector<std::pair<google::protobuf::FileDescriptorProto, bool>> descProtos;
    std::set<std::string> parsed;
    std::list<std::string> parsedSorted;
    // then load everything into descriptor pool
    for (size_t i = 0; i < extractor->GetMetadata().size(); ++i)
    {
        for (std::unique_ptr<MetadataExtractor::Metadata> const& meta : extractor->GetMetadata())
        {
            if (parsed.count(meta->GetId()))
                continue;

            std::shared_ptr<google::protobuf::io::CodedInputStream> in = meta->CreateCodedInputStream();
            if (!in)
                continue;

            google::protobuf::FileDescriptorProto fileDescProto;
            bool parseOk = false;
            try
            {
                parseOk = ParseFromCodedInputStreamWithDescriptorPool(fileDescProto, in.get());
            }
            catch (...)
            {
                continue;
            }

            if (parseOk)
            {
                if (google::protobuf::FileDescriptor const* fileDesc = pool->BuildFile(fileDescProto))
                {
                    if (fileDesc->name() != "google/protobuf/descriptor.proto" && fileDescriptorsByName.count(fileDesc->name()) == 0)
                    {
                        auto itr = fileDescriptorsByName.emplace(std::piecewise_construct, std::forward_as_tuple(fileDesc->name()), std::forward_as_tuple(fileDesc, false)).first;
                        google::protobuf::MessageFactory::InternalRegisterGeneratedFile(itr->first.c_str(), [](std::string const& name)
                        {
                            std::pair<google::protobuf::FileDescriptor const*, bool>& p = fileDescriptorsByName[name];
                            if (p.second)
                                return;

                            p.second = true;
                            google::protobuf::FileDescriptor const* desc = p.first;
                            for (int j = 0; j < desc->message_type_count(); ++j)
                                google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(desc->message_type(j), dynamicMessageFactory->GetPrototype(desc->message_type(j)));
                        });
                    }

                    for (int j = 0; j < fileDesc->extension_count(); ++j)
                    {
                        google::protobuf::FieldDescriptor const* extension = fileDesc->extension(j);
                        switch (extension->type())
                        {
                            case google::protobuf::FieldDescriptor::Type::TYPE_ENUM:
                                google::protobuf::internal::ExtensionSet::RegisterEnumExtension(
                                    google::protobuf::MessageFactory::generated_factory()->GetPrototype(extension->containing_type()),
                                    extension->number(),
                                    extension->type(),
                                    extension->is_repeated(),
                                    extension->is_packed(),
                                    [](int){ return true; });
                                break;
                            case google::protobuf::FieldDescriptor::Type::TYPE_MESSAGE:
                            case google::protobuf::FieldDescriptor::Type::TYPE_GROUP:
                                google::protobuf::internal::ExtensionSet::RegisterMessageExtension(
                                    google::protobuf::MessageFactory::generated_factory()->GetPrototype(extension->containing_type()),
                                    extension->number(),
                                    extension->type(),
                                    extension->is_repeated(),
                                    extension->is_packed(),
                                    google::protobuf::MessageFactory::generated_factory()->GetPrototype(extension->message_type()));
                                break;
                            default:
                                google::protobuf::internal::ExtensionSet::RegisterExtension(
                                    google::protobuf::MessageFactory::generated_factory()->GetPrototype(extension->containing_type()),
                                    extension->number(),
                                    extension->type(),
                                    extension->is_repeated(),
                                    extension->is_packed());
                                break;
                        }
                    }

                    parsed.insert(meta->GetId());
                    if (fileDesc->name() != "google/protobuf/descriptor.proto")
                        parsedSorted.push_back(meta->GetId());
                    else
                        parsedSorted.push_front(meta->GetId());
                }
            }
        }
    }

    // and finally rebuild all protos in a new pool with fully resolved dependencies and extensions
    google::protobuf::DescriptorPool* pool2 = new google::protobuf::DescriptorPool();
    for (std::string const& fileName : parsedSorted)
    {
        MetadataExtractor::Metadata const* meta = extractor->GetById(fileName);
        if (!meta)
            continue;

        std::shared_ptr<google::protobuf::io::CodedInputStream> in = meta->CreateCodedInputStream();
        if (!in)
            continue;

        google::protobuf::FileDescriptorProto fileDescProto;
        if (ParseFromCodedInputStreamWithDescriptorPool(fileDescProto, in.get()))
        {
            fileDescProto.mutable_options()->set_optimize_for(google::protobuf::FileOptions_OptimizeMode_SPEED);
            if (google::protobuf::FileDescriptor const* fileDesc = pool2->BuildFile(fileDescProto))
            {
                boost::filesystem::path parentPath = boost::filesystem::path(fileDesc->name()).parent_path();
                if (!parentPath.empty())
                    boost::filesystem::create_directories(parentPath);
                std::ofstream f(fileDesc->name());
                f << fileDesc->DebugString() << std::endl;
                f.close();
            }
        }
    }

    // unhack to free memory
    *reinterpret_cast<void**>(pool) = mutex_;
    *(reinterpret_cast<void**>(pool) + 1) = fallback_database_;

    delete pool2;

    google::protobuf::ShutdownProtobufLibrary();

    return 0;
}

max_stars_repo_name: Shauren/protobuf-decompiler

max_issues_repo_name: Shauren/protobuf-decompiler

max_forks_repo_name: Shauren/protobuf-decompiler