<commit_before>#ifndef ALEPH_TOPOLOGY_IO_ADJACENCY_MATRIX_HH__
#define ALEPH_TOPOLOGY_IO_ADJACENCY_MATRIX_HH__

#include <aleph/utilities/String.hh>

#include <aleph/topology/filtrations/Data.hh>

#include <algorithm>
#include <fstream>
#include <istream>
#include <string>
#include <unordered_map>
#include <vector>

#include <cmath>

namespace aleph
{

namespace topology
{

namespace io
{

/**
  @class AdjacencyMatrixReader
  @brief Reads square adjacency matrices in text format

  This reader class is meant to load square adjacency matrices (square)
  in text format. Entry (i,j) in the matrix contains the edge weight of
  the (unique) edge connecting nodes i and j.

  Depending on the configuration of the class, cells with a pre-defined
  weight (usually zero) are taken to indicate missing edges.

  The number of rows and columns must not vary over the file. An *empty*
  line is permitted, though. Likewise, lines starting with `#` will just
  be ignored. An example of a 3-by-3 matrix follows:

  \code
  0 1 2
  3 4 5
  2 1 7
  \endcode

  All simplicial complexes created by this class will be reported
  in filtration order, following the detected weights. This class
  offers the option to supply an *optional* functor for modifying
  the weights of the matrix. This can be useful when edge weights
  are supposed to be negated, for example.
*/

class AdjacencyMatrixReader
{
public:

  enum class VertexWeightAssignmentStrategy
  {
    AssignGlobalMinimum, // assigns the global minimum weight
    AssignZero           // assigns zero
  };

  /**
    Reads a simplicial complex from a file.

    @param filename Input filename
    @param  K       Simplicial complex
  */

  template <class SimplicialComplex> void operator()( const std::string& filename, SimplicialComplex& K )
  {
    using Simplex    = typename SimplicialComplex::ValueType;
    using DataType   = typename Simplex::DataType;

    this->operator()(
      filename,
      K,
      // Use the identity functor so that weights are not changed at all
      // and just stored as-is.
      [] ( DataType /* a */, DataType /* b */, DataType x ) { return x; }
    );
  }

  template <class SimplicialComplex, class Functor> void operator()( const std::string& filename, SimplicialComplex& K, Functor f )
  {
    std::ifstream in( filename );
    if( !in )
      throw std::runtime_error( "Unable to read input file" );

    this->operator()(
      in,
      K,
      f
    );
  }

  /** @overload operator()( const std::string&, SimplicialComplex& ) */
  template <class SimplicialComplex, class Functor> void operator()( std::istream& in, SimplicialComplex& K, Functor f )
  {
    using Simplex    = typename SimplicialComplex::ValueType;
    using DataType   = typename Simplex::DataType;
    using VertexType = typename Simplex::VertexType;

    auto position    = in.tellg();
    std::size_t n    = 0;

    // An 'unrolled' version of all edge weights that can be read from
    // the file. They are supposed to correspond to a matrix with some
    // number of columns and some number of rows.
    std::vector<DataType> values;

    using namespace aleph::utilities;

    {
      std::string line;
      while( std::getline( in, line ) )
      {
        // Skip empty lines and comments as promised
        if( line.empty() || line.front() == '#' )
          continue;

        ++n;
      }

      in.clear();
      in.seekg( position );
    }

    // FIXME: this will not work in case comments are part of the file.
    // Drat---should probably rewrite it.
    std::copy( std::istream_iterator<DataType>( in ), std::istream_iterator<DataType>(),
               std::back_inserter( values ) );

    // We cannot fill an empty simplicial complex. It might be useful to
    // throw an error here, though.
    if( values.empty() )
      return;

    _dimension = n;

    if( values.size() != _dimension * _dimension )
      throw std::runtime_error( "Format error: number of columns must not vary" );

    std::vector<Simplex> simplices;

    // First part of that equation reserves $n$ nodes, where $n$ is the
    // dimension of the matrix, followed by at most $n^2$ edges. Notice
    // that this assumes that *all* edges are defined.
    simplices.reserve( _dimension + ( _dimension * _dimension ) );

    DataType minWeight = DataType();
    DataType maxWeight = DataType();

    {
      auto minmax = std::minmax_element( values.begin(), values.end() );
      minWeight   = *minmax.first;
      maxWeight   = *minmax.second;
    }

    // Edges -----------------------------------------------------------
    //
    // Create the edges first and update information about their weights
    // along with them.

    for( std::size_t y = 0; y < _dimension; y++ )
    {
      // The way this loop is set up avoids the calculation of
      // self-edges. Also, it looks at weights from a *single*
      // direction only. Essentially, half of the data set may
      // not be considered here.
      for( std::size_t x = y + 1; x < _dimension; x++ )
      {
        auto i = static_cast<VertexType>( _dimension * y + x   );
        auto w = values[i];

        // Map matrix indices to the corresponding vertex indices as
        // outlined above.
        auto u = VertexType(y);
        auto v = VertexType(x + _dimension);

        if( _ignoreNaNs && std::isnan( w ) )
          continue;

        if( _ignoreZeroWeights && w == DataType() )
          continue;

        // Apply the client-specified functor here and store the
        // resulting simplex in the complex.
        simplices.push_back( Simplex( {u,v}, f( maxWeight, minWeight, w ) ) );
      }
    }

    // Vertices --------------------------------------------------------
    //
    // Create a vertex for every node in the input data. This will use
    // the minimum weight detected in the file.

    for( std::size_t i = 0; i < _dimension; i++ )
    {
      DataType weight = DataType();

      if( _vertexWeightAssignmentStrategy == VertexWeightAssignmentStrategy::AssignGlobalMinimum )
      {
        // This weight selection strategy requires applying the functor
        // because the weight might be anything, whereas the zero-based
        // initialization uses a *fixed* weight.
        weight = f( maxWeight, minWeight, minWeight );
      }
      else if( _vertexWeightAssignmentStrategy == VertexWeightAssignmentStrategy::AssignZero )
        weight = DataType();
      else
        throw std::runtime_error( "Unknown vertex weight assignment strategy" );

      simplices.push_back(
        Simplex( VertexType( i ), weight )
      );
    }

    K = SimplicialComplex( simplices.begin(), simplices.end() );

    // Establish filtration order based on weights. There does not seem
    // to be much of a point to make this configurable; the edge weight
    // is a given property of the data.
    K.sort(
      filtrations::Data<Simplex>()
    );
  }

  /** @returns Dimension of matrix that was read last */
  std::size_t dimension() const noexcept { return _dimension; }

  void setIgnoreNaNs( bool value = true ) noexcept
  {
    _ignoreNaNs = value;
  }

  void setIgnoreZeroWeights( bool value = true ) noexcept
  {
    _ignoreZeroWeights = value;
  }

  void setVertexWeightAssignmentStrategy( VertexWeightAssignmentStrategy strategy ) noexcept
  {
    _vertexWeightAssignmentStrategy = strategy;
  }

private:

  // Dimension of the matrix that was read last by this reader; this
  // will only be set if the matrix is actually square.
  std::size_t _dimension = 0;

  // If set, NaNs are ignored by the reader and treated as a missing
  // edge of the graph.
  bool _ignoreNaNs = false;

  // If set, zero weights are ignored by the reader and treated as
  // a missing edge of the graph.
  // a missing edge.
  bool _ignoreZeroWeights = false;

  // Strategy/policy for assigning vertex weights. Can be either one of
  // the options outlined in the enumeration class above. By default, a
  // global minimum weight is identified and assigned.
  VertexWeightAssignmentStrategy _vertexWeightAssignmentStrategy =
    VertexWeightAssignmentStrategy::AssignGlobalMinimum;
};

} // namespace io

} // namespace topology

} // namespace aleph

#endif
<commit_msg>Fixed missing overload for adjacency matrix reader<commit_after>#ifndef ALEPH_TOPOLOGY_IO_ADJACENCY_MATRIX_HH__
#define ALEPH_TOPOLOGY_IO_ADJACENCY_MATRIX_HH__

#include <aleph/utilities/String.hh>

#include <aleph/topology/filtrations/Data.hh>

#include <algorithm>
#include <fstream>
#include <istream>
#include <string>
#include <unordered_map>
#include <vector>

#include <cmath>

namespace aleph
{

namespace topology
{

namespace io
{

/**
  @class AdjacencyMatrixReader
  @brief Reads square adjacency matrices in text format

  This reader class is meant to load square adjacency matrices (square)
  in text format. Entry (i,j) in the matrix contains the edge weight of
  the (unique) edge connecting nodes i and j.

  Depending on the configuration of the class, cells with a pre-defined
  weight (usually zero) are taken to indicate missing edges.

  The number of rows and columns must not vary over the file. An *empty*
  line is permitted, though. Likewise, lines starting with `#` will just
  be ignored. An example of a 3-by-3 matrix follows:

  \code
  0 1 2
  3 4 5
  2 1 7
  \endcode

  All simplicial complexes created by this class will be reported
  in filtration order, following the detected weights. This class
  offers the option to supply an *optional* functor for modifying
  the weights of the matrix. This can be useful when edge weights
  are supposed to be negated, for example.
*/

class AdjacencyMatrixReader
{
public:

  enum class VertexWeightAssignmentStrategy
  {
    AssignGlobalMinimum, // assigns the global minimum weight
    AssignZero           // assigns zero
  };

  /**
    Reads a simplicial complex from a file.

    @param filename Input filename
    @param  K       Simplicial complex
  */

  template <class SimplicialComplex> void operator()( const std::string& filename, SimplicialComplex& K )
  {
    using Simplex    = typename SimplicialComplex::ValueType;
    using DataType   = typename Simplex::DataType;

    this->operator()(
      filename,
      K,
      // Use the identity functor so that weights are not changed at all
      // and just stored as-is.
      [] ( DataType /* a */, DataType /* b */, DataType x ) { return x; }
    );
  }

  template <class SimplicialComplex, class Functor> void operator()( const std::string& filename, SimplicialComplex& K, Functor f )
  {
    std::ifstream in( filename );
    if( !in )
      throw std::runtime_error( "Unable to read input file" );

    this->operator()(
      in,
      K,
      f
    );
  }

  /** @overload operator()( const std::string&, SimplicialComplex& ) */
  template <class SimplicialComplex> void operator()( std::istream& in, SimplicialComplex& K )
  {
    using Simplex    = typename SimplicialComplex::ValueType;
    using DataType   = typename Simplex::DataType;

    this->operator()(
      in,
      K,
      // Use the identity functor so that weights are not changed at all
      // and just stored as-is.
      [] ( DataType /* a */, DataType /* b */, DataType x ) { return x; }
    );
  }

  /** @overload operator()( const std::string&, SimplicialComplex& ) */
  template <class SimplicialComplex, class Functor> void operator()( std::istream& in, SimplicialComplex& K, Functor f )
  {
    using Simplex    = typename SimplicialComplex::ValueType;
    using DataType   = typename Simplex::DataType;
    using VertexType = typename Simplex::VertexType;

    auto position    = in.tellg();
    std::size_t n    = 0;

    // An 'unrolled' version of all edge weights that can be read from
    // the file. They are supposed to correspond to a matrix with some
    // number of columns and some number of rows.
    std::vector<DataType> values;

    using namespace aleph::utilities;

    {
      std::string line;
      while( std::getline( in, line ) )
      {
        // Skip empty lines and comments as promised
        if( line.empty() || line.front() == '#' )
          continue;

        ++n;
      }

      in.clear();
      in.seekg( position );
    }

    // FIXME: this will not work in case comments are part of the file.
    // Drat---should probably rewrite it.
    std::copy( std::istream_iterator<DataType>( in ), std::istream_iterator<DataType>(),
               std::back_inserter( values ) );

    // We cannot fill an empty simplicial complex. It might be useful to
    // throw an error here, though.
    if( values.empty() )
      return;

    _dimension = n;

    if( values.size() != _dimension * _dimension )
      throw std::runtime_error( "Format error: number of columns must not vary" );

    std::vector<Simplex> simplices;

    // First part of that equation reserves $n$ nodes, where $n$ is the
    // dimension of the matrix, followed by at most $n^2$ edges. Notice
    // that this assumes that *all* edges are defined.
    simplices.reserve( _dimension + ( _dimension * _dimension ) );

    DataType minWeight = DataType();
    DataType maxWeight = DataType();

    {
      auto minmax = std::minmax_element( values.begin(), values.end() );
      minWeight   = *minmax.first;
      maxWeight   = *minmax.second;
    }

    // Edges -----------------------------------------------------------
    //
    // Create the edges first and update information about their weights
    // along with them.

    for( std::size_t y = 0; y < _dimension; y++ )
    {
      // The way this loop is set up avoids the calculation of
      // self-edges. Also, it looks at weights from a *single*
      // direction only. Essentially, half of the data set may
      // not be considered here.
      for( std::size_t x = y + 1; x < _dimension; x++ )
      {
        auto i = static_cast<VertexType>( _dimension * y + x   );
        auto w = values[i];

        // Map matrix indices to the corresponding vertex indices as
        // outlined above.
        auto u = VertexType(y);
        auto v = VertexType(x + _dimension);

        if( _ignoreNaNs && std::isnan( w ) )
          continue;

        if( _ignoreZeroWeights && w == DataType() )
          continue;

        // Apply the client-specified functor here and store the
        // resulting simplex in the complex.
        simplices.push_back( Simplex( {u,v}, f( maxWeight, minWeight, w ) ) );
      }
    }

    // Vertices --------------------------------------------------------
    //
    // Create a vertex for every node in the input data. This will use
    // the minimum weight detected in the file.

    for( std::size_t i = 0; i < _dimension; i++ )
    {
      DataType weight = DataType();

      if( _vertexWeightAssignmentStrategy == VertexWeightAssignmentStrategy::AssignGlobalMinimum )
      {
        // This weight selection strategy requires applying the functor
        // because the weight might be anything, whereas the zero-based
        // initialization uses a *fixed* weight.
        weight = f( maxWeight, minWeight, minWeight );
      }
      else if( _vertexWeightAssignmentStrategy == VertexWeightAssignmentStrategy::AssignZero )
        weight = DataType();
      else
        throw std::runtime_error( "Unknown vertex weight assignment strategy" );

      simplices.push_back(
        Simplex( VertexType( i ), weight )
      );
    }

    K = SimplicialComplex( simplices.begin(), simplices.end() );

    // Establish filtration order based on weights. There does not seem
    // to be much of a point to make this configurable; the edge weight
    // is a given property of the data.
    K.sort(
      filtrations::Data<Simplex>()
    );
  }

  /** @returns Dimension of matrix that was read last */
  std::size_t dimension() const noexcept { return _dimension; }

  void setIgnoreNaNs( bool value = true ) noexcept
  {
    _ignoreNaNs = value;
  }

  void setIgnoreZeroWeights( bool value = true ) noexcept
  {
    _ignoreZeroWeights = value;
  }

  void setVertexWeightAssignmentStrategy( VertexWeightAssignmentStrategy strategy ) noexcept
  {
    _vertexWeightAssignmentStrategy = strategy;
  }

private:

  // Dimension of the matrix that was read last by this reader; this
  // will only be set if the matrix is actually square.
  std::size_t _dimension = 0;

  // If set, NaNs are ignored by the reader and treated as a missing
  // edge of the graph.
  bool _ignoreNaNs = false;

  // If set, zero weights are ignored by the reader and treated as
  // a missing edge of the graph.
  // a missing edge.
  bool _ignoreZeroWeights = false;

  // Strategy/policy for assigning vertex weights. Can be either one of
  // the options outlined in the enumeration class above. By default, a
  // global minimum weight is identified and assigned.
  VertexWeightAssignmentStrategy _vertexWeightAssignmentStrategy =
    VertexWeightAssignmentStrategy::AssignGlobalMinimum;
};

} // namespace io

} // namespace topology

} // namespace aleph

#endif
<|endoftext|>


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

#include "src/trace_processor/thread_table.h"

#include "perfetto/base/logging.h"
#include "src/trace_processor/query_constraints.h"
#include "src/trace_processor/sqlite_utils.h"

namespace perfetto {
namespace trace_processor {

namespace {

using namespace sqlite_utils;

}  // namespace

ThreadTable::ThreadTable(sqlite3*, const TraceStorage* storage)
    : storage_(storage) {}

void ThreadTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
  Table::Register<ThreadTable>(db, storage, "thread");
}

base::Optional<Table::Schema> ThreadTable::Init(int, const char* const*) {
  return Schema(
      {
          Table::Column(Column::kUtid, "utid", ColumnType::kInt),
          Table::Column(Column::kUpid, "upid", ColumnType::kInt),
          Table::Column(Column::kName, "name", ColumnType::kString),
          Table::Column(Column::kTid, "tid", ColumnType::kInt),
      },
      {Column::kUtid});
}

std::unique_ptr<Table::Cursor> ThreadTable::CreateCursor(
    const QueryConstraints& qc,
    sqlite3_value** argv) {
  return std::unique_ptr<Table::Cursor>(new Cursor(storage_, qc, argv));
}

int ThreadTable::BestIndex(const QueryConstraints& qc, BestIndexInfo* info) {
  info->estimated_cost = static_cast<uint32_t>(storage_->thread_count());

  // If the query has a constraint on the |utid| field, return a reduced cost
  // because we can do that filter efficiently.
  const auto& constraints = qc.constraints();
  if (constraints.size() == 1 && constraints.front().iColumn == Column::kUtid) {
    info->estimated_cost = IsOpEq(constraints.front().op) ? 1 : 10;
  }

  return SQLITE_OK;
}

ThreadTable::Cursor::Cursor(const TraceStorage* storage,
                            const QueryConstraints& qc,
                            sqlite3_value** argv)
    : storage_(storage) {
  min = 0;
  max = static_cast<uint32_t>(storage_->thread_count());
  desc = false;
  current = min;
  for (size_t j = 0; j < qc.constraints().size(); j++) {
    const auto& cs = qc.constraints()[j];
    if (cs.iColumn == Column::kUtid) {
      UniqueTid constraint_utid =
          static_cast<UniqueTid>(sqlite3_value_int(argv[j]));
      // Filter the range of utids that we are interested in, based on the
      // constraints in the query. Everything between min and max (inclusive)
      // will be returned.
      if (IsOpEq(cs.op)) {
        min = constraint_utid;
        max = constraint_utid;
      } else if (IsOpGe(cs.op) || IsOpGt(cs.op)) {
        min = IsOpGt(cs.op) ? constraint_utid + 1 : constraint_utid;
      } else if (IsOpLe(cs.op) || IsOpLt(cs.op)) {
        max = IsOpLt(cs.op) ? constraint_utid - 1 : constraint_utid;
      }
    }
  }
  for (const auto& ob : qc.order_by()) {
    if (ob.iColumn == Column::kUtid) {
      desc = ob.desc;
      current = desc ? max : min;
    }
  }
}

int ThreadTable::Cursor::Column(sqlite3_context* context, int N) {
  const auto& thread = storage_->GetThread(current);
  switch (N) {
    case Column::kUtid: {
      sqlite3_result_int64(context, current);
      break;
    }
    case Column::kUpid: {
      sqlite3_result_int64(context, thread.upid.value_or(0));
      break;
    }
    case Column::kName: {
      const auto& name = storage_->GetString(thread.name_id);
      sqlite3_result_text(context, name.c_str(),
                          static_cast<int>(name.length()), kSqliteStatic);
      break;
    }
    case Column::kTid: {
      sqlite3_result_int64(context, thread.tid);
      break;
    }
    default: {
      PERFETTO_FATAL("Unknown column %d", N);
      break;
    }
  }
  return SQLITE_OK;
}

int ThreadTable::Cursor::Next() {
  if (desc) {
    --current;
  } else {
    ++current;
  }
  return SQLITE_OK;
}

int ThreadTable::Cursor::Eof() {
  return desc ? current < min : current > max;
}
}  // namespace trace_processor
}  // namespace perfetto
<commit_msg>trace_processor: fix null vs 0 bug in thread table am: 1aa852a0ca am: b0a6e82b0e<commit_after>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/trace_processor/thread_table.h"

#include "perfetto/base/logging.h"
#include "src/trace_processor/query_constraints.h"
#include "src/trace_processor/sqlite_utils.h"

namespace perfetto {
namespace trace_processor {

namespace {

using namespace sqlite_utils;

}  // namespace

ThreadTable::ThreadTable(sqlite3*, const TraceStorage* storage)
    : storage_(storage) {}

void ThreadTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
  Table::Register<ThreadTable>(db, storage, "thread");
}

base::Optional<Table::Schema> ThreadTable::Init(int, const char* const*) {
  return Schema(
      {
          Table::Column(Column::kUtid, "utid", ColumnType::kInt),
          Table::Column(Column::kUpid, "upid", ColumnType::kInt),
          Table::Column(Column::kName, "name", ColumnType::kString),
          Table::Column(Column::kTid, "tid", ColumnType::kInt),
      },
      {Column::kUtid});
}

std::unique_ptr<Table::Cursor> ThreadTable::CreateCursor(
    const QueryConstraints& qc,
    sqlite3_value** argv) {
  return std::unique_ptr<Table::Cursor>(new Cursor(storage_, qc, argv));
}

int ThreadTable::BestIndex(const QueryConstraints& qc, BestIndexInfo* info) {
  info->estimated_cost = static_cast<uint32_t>(storage_->thread_count());

  // If the query has a constraint on the |utid| field, return a reduced cost
  // because we can do that filter efficiently.
  const auto& constraints = qc.constraints();
  if (constraints.size() == 1 && constraints.front().iColumn == Column::kUtid) {
    info->estimated_cost = IsOpEq(constraints.front().op) ? 1 : 10;
  }

  return SQLITE_OK;
}

ThreadTable::Cursor::Cursor(const TraceStorage* storage,
                            const QueryConstraints& qc,
                            sqlite3_value** argv)
    : storage_(storage) {
  min = 0;
  max = static_cast<uint32_t>(storage_->thread_count());
  desc = false;
  current = min;
  for (size_t j = 0; j < qc.constraints().size(); j++) {
    const auto& cs = qc.constraints()[j];
    if (cs.iColumn == Column::kUtid) {
      UniqueTid constraint_utid =
          static_cast<UniqueTid>(sqlite3_value_int(argv[j]));
      // Filter the range of utids that we are interested in, based on the
      // constraints in the query. Everything between min and max (inclusive)
      // will be returned.
      if (IsOpEq(cs.op)) {
        min = constraint_utid;
        max = constraint_utid;
      } else if (IsOpGe(cs.op) || IsOpGt(cs.op)) {
        min = IsOpGt(cs.op) ? constraint_utid + 1 : constraint_utid;
      } else if (IsOpLe(cs.op) || IsOpLt(cs.op)) {
        max = IsOpLt(cs.op) ? constraint_utid - 1 : constraint_utid;
      }
    }
  }
  for (const auto& ob : qc.order_by()) {
    if (ob.iColumn == Column::kUtid) {
      desc = ob.desc;
      current = desc ? max : min;
    }
  }
}

int ThreadTable::Cursor::Column(sqlite3_context* context, int N) {
  const auto& thread = storage_->GetThread(current);
  switch (N) {
    case Column::kUtid: {
      sqlite3_result_int64(context, current);
      break;
    }
    case Column::kUpid: {
      if (thread.upid.has_value()) {
        sqlite3_result_int64(context, thread.upid.value());
      } else {
        sqlite3_result_null(context);
      }
      break;
    }
    case Column::kName: {
      const auto& name = storage_->GetString(thread.name_id);
      sqlite3_result_text(context, name.c_str(),
                          static_cast<int>(name.length()), kSqliteStatic);
      break;
    }
    case Column::kTid: {
      sqlite3_result_int64(context, thread.tid);
      break;
    }
    default: {
      PERFETTO_FATAL("Unknown column %d", N);
      break;
    }
  }
  return SQLITE_OK;
}

int ThreadTable::Cursor::Next() {
  if (desc) {
    --current;
  } else {
    ++current;
  }
  return SQLITE_OK;
}

int ThreadTable::Cursor::Eof() {
  return desc ? current < min : current > max;
}
}  // namespace trace_processor
}  // namespace perfetto
<|endoftext|>


<commit_before>// FbRun.cc
// Copyright (c) 2002-2003 Henrik Kinnunen (fluxgen<at>users.sourceforge.net)
//
// 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.

// $Id: FbRun.cc,v 1.23 2003/12/31 01:34:33 fluxgen Exp $

#include "FbRun.hh"

#include "App.hh"
#include "EventManager.hh"
#include "Color.hh"
#include "KeyUtil.hh"

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif // HAVE_CONFIG_H

#ifdef HAVE_XPM
#include <X11/xpm.h>
#include "fbrun.xpm"
#endif // HAVE_XPM

#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>

#include <unistd.h>

#include <iostream>
#include <iterator>
#include <fstream>
#include <cassert>

using namespace std;
FbRun::FbRun(int x, int y, size_t width):
    FbTk::TextBox(DefaultScreen(FbTk::App::instance()->display()),
                  m_font, ""),
    m_font("fixed"),
    m_display(FbTk::App::instance()->display()),
    m_bevel(4),
    m_gc(*this),
    m_end(false),
    m_current_history_item(0),
    m_cursor(XCreateFontCursor(FbTk::App::instance()->display(), XC_xterm)) {

    setGC(m_gc.gc());
    setCursor(m_cursor);
    // setting nomaximize in local resize
    resize(width, font().height() + m_bevel);

    // setup class name
    XClassHint *class_hint = XAllocClassHint();
    if (class_hint == 0)
        throw string("Out of memory");
    class_hint->res_name = "fbrun";
    class_hint->res_class = "FbRun";
    XSetClassHint(m_display, window(), class_hint);

    XFree(class_hint);
#ifdef HAVE_XPM
    Pixmap mask = 0;
    Pixmap pm;
    XpmCreatePixmapFromData(m_display,
                            window(),
                            fbrun_xpm,
                            &pm,
                            &mask,
                            0); // attribs
    if (mask != 0)
        XFreePixmap(m_display, mask);

    m_pixmap = pm;
#endif // HAVE_XPM

    if (m_pixmap.drawable()) {
        XWMHints wmhints;
        wmhints.flags = IconPixmapHint;
        wmhints.icon_pixmap = m_pixmap.drawable();
        XSetWMHints(m_display, window(), &wmhints);
    }
}

FbRun::~FbRun() {
    hide();
}

void FbRun::run(const std::string &command) {
    FbTk::App::instance()->end(); // end application
    m_end = true; // mark end of processing

    // fork and execute program
    if (!fork()) {
        setsid();
        execl("/bin/sh", "/bin/sh", "-c", command.c_str(), 0);
        exit(0); //exit child
    }

    hide(); // hide gui

    // save command history to file
    if (text().size() != 0) { // no need to save empty command

        // don't allow duplicates into the history file, first
        // look for a duplicate
        if (m_current_history_item < m_history.size()
            && text() == m_history[m_current_history_item]) {
            // m_current_history_item is the duplicate
        } else {
            m_current_history_item = 0;
            for (; m_current_history_item < m_history.size();
                 ++m_current_history_item) {
                if (m_history[m_current_history_item] == text())
                    break;
            }
        }

        // now m_current_history_item points at the duplicate, or
        // at m_history.size() if no duplicate
        fstream inoutfile(m_history_file.c_str(), ios::in|ios::out);
        if (inoutfile) {
            int i = 0;
            // read past history items before current
            for (string line; !inoutfile.eof() && i < m_current_history_item; i++)
                getline(inoutfile, line);
            // write the history items that come after current
            for (i++; i < m_history.size(); i++)
                inoutfile<<m_history[i]<<endl;

            // and append the current one back to the end
            inoutfile<<text()<<endl;
        } else
            cerr<<"FbRun Warning: Can't write command history to file: "<<m_history_file<<endl;
    }

}

bool FbRun::loadHistory(const char *filename) {
    if (filename == 0)
        return false;
    ifstream infile(filename);
    if (!infile) {
        //even though we fail to load file, we should try save to it
        m_history_file = filename;
        return false;
    }
    // clear old history and load new one from file
    m_history.clear();
    // each line is a command
    string line;
    while (!infile.eof()) {
        getline(infile, line);
        if (line.size()) // don't add empty lines
            m_history.push_back(line);
    }
    // set no current histor to display
    m_current_history_item = m_history.size();
    // set history file
    m_history_file = filename;
    return true;
}

bool FbRun::loadFont(const string &fontname) {
    if (!m_font.load(fontname.c_str()))
        return false;

    // resize to fit new font height
    resize(width(), font().height() + m_bevel);
    return true;
}

void FbRun::setForegroundColor(const FbTk::Color &color) {
    m_gc.setForeground(color);
}

void FbRun::setTitle(const string &title) {
    setName(title.c_str());
}

void FbRun::resize(unsigned int width, unsigned int height) {
    FbTk::TextBox::resize(width, height);
    setNoMaximize();
}

void FbRun::redrawLabel() {
    clear();
}

void FbRun::keyPressEvent(XKeyEvent &ke) {
    // strip numlock, capslock and scrolllock mask
    ke.state = FbTk::KeyUtil::instance().cleanMods(ke.state);

    FbTk::TextBox::keyPressEvent(ke);
    KeySym ks;
    char keychar[1];
    XLookupString(&ke, keychar, 1, &ks, 0);
    // a modifier key by itself doesn't do anything
    if (IsModifierKey(ks)) return;

    if (ke.state) { // a modifier key is down
        if (ke.state == ControlMask) {
            switch (ks) {
            case XK_p:
                prevHistoryItem();
                break;
            case XK_n:
                nextHistoryItem();
                break;
            }
        } else if (ke.state == (Mod1Mask | ShiftMask)) {
            switch (ks) {
            case XK_less:
                firstHistoryItem();
                break;
            case XK_greater:
                lastHistoryItem();
                break;
            }
        }
    } else { // no modifier key
        switch (ks) {
        case XK_Escape:
            m_end = true;
            hide();
            FbTk::App::instance()->end(); // end program
            break;
        case XK_Return:
            run(text());
            break;
        case XK_Up:
            prevHistoryItem();
            break;
        case XK_Down:
            nextHistoryItem();
            break;
        case XK_Tab:
            tabCompleteHistory();
            break;
        }
    }
    clear();
}

void FbRun::setNoMaximize() {
    // we don't need to maximize this window
    XSizeHints sh;
    sh.flags = PMaxSize | PMinSize;
    sh.max_width = width();
    sh.max_height = height();
    sh.min_width = width();
    sh.min_height = height();
    XSetWMNormalHints(m_display, window(), &sh);
}

void FbRun::prevHistoryItem() {
    if (m_history.size() == 0 || m_current_history_item == 0) {
        XBell(m_display, 0);
    } else {
        m_current_history_item--;
        setText(m_history[m_current_history_item]);
    }
}

void FbRun::nextHistoryItem() {
    if (m_current_history_item == m_history.size()) {
        XBell(m_display, 0);
    } else {
        m_current_history_item++;
        if (m_current_history_item == m_history.size()) {
            m_current_history_item = m_history.size();
            setText("");
         } else
            setText(m_history[m_current_history_item]);
    }
}

void FbRun::firstHistoryItem() {
    if (m_history.size() == 0 || m_current_history_item == 0) {
        XBell(m_display, 0);
    } else {
        m_current_history_item = 0;
        setText(m_history[m_current_history_item]);
    }
}

void FbRun::lastHistoryItem() {
    // actually one past the end
    if (m_history.size() == 0) {
        XBell(m_display, 0);
    } else {
        m_current_history_item = m_history.size();
        setText("");
    }
}

void FbRun::tabCompleteHistory() {
    if (m_current_history_item == 0) {
        XBell(m_display, 0);
    } else {
        int history_item = m_current_history_item - 1;
        string prefix = text().substr(0, cursorPosition());
        while (history_item > - 1) {
            if (m_history[history_item].find(prefix) == 0) {
                m_current_history_item = history_item;
                setText(m_history[m_current_history_item]);
                break;
            }
            history_item--;
        }
        if (history_item == -1) XBell(m_display, 0);
    }
}

void FbRun::insertCharacter(char keychar) {
    char val[2] = {keychar, 0};
    insertText(val);
}

<commit_msg>cycle tabcompletion, patch from Mathias Gumz<commit_after>// FbRun.cc
// Copyright (c) 2002-2003 Henrik Kinnunen (fluxgen<at>users.sourceforge.net)
//
// 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.

// $Id: FbRun.cc,v 1.24 2004/02/25 18:37:47 fluxgen Exp $

#include "FbRun.hh"

#include "App.hh"
#include "EventManager.hh"
#include "Color.hh"
#include "KeyUtil.hh"

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif // HAVE_CONFIG_H

#ifdef HAVE_XPM
#include <X11/xpm.h>
#include "fbrun.xpm"
#endif // HAVE_XPM

#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>

#include <unistd.h>

#include <iostream>
#include <iterator>
#include <fstream>
#include <cassert>

using namespace std;
FbRun::FbRun(int x, int y, size_t width):
    FbTk::TextBox(DefaultScreen(FbTk::App::instance()->display()),
                  m_font, ""),
    m_font("fixed"),
    m_display(FbTk::App::instance()->display()),
    m_bevel(4),
    m_gc(*this),
    m_end(false),
    m_current_history_item(0),
    m_cursor(XCreateFontCursor(FbTk::App::instance()->display(), XC_xterm)) {

    setGC(m_gc.gc());
    setCursor(m_cursor);
    // setting nomaximize in local resize
    resize(width, font().height() + m_bevel);

    // setup class name
    XClassHint *class_hint = XAllocClassHint();
    if (class_hint == 0)
        throw string("Out of memory");
    class_hint->res_name = "fbrun";
    class_hint->res_class = "FbRun";
    XSetClassHint(m_display, window(), class_hint);

    XFree(class_hint);
#ifdef HAVE_XPM
    Pixmap mask = 0;
    Pixmap pm;
    XpmCreatePixmapFromData(m_display,
                            window(),
                            fbrun_xpm,
                            &pm,
                            &mask,
                            0); // attribs
    if (mask != 0)
        XFreePixmap(m_display, mask);

    m_pixmap = pm;
#endif // HAVE_XPM

    if (m_pixmap.drawable()) {
        XWMHints wmhints;
        wmhints.flags = IconPixmapHint;
        wmhints.icon_pixmap = m_pixmap.drawable();
        XSetWMHints(m_display, window(), &wmhints);
    }
}

FbRun::~FbRun() {
    hide();
}

void FbRun::run(const std::string &command) {
    FbTk::App::instance()->end(); // end application
    m_end = true; // mark end of processing

    // fork and execute program
    if (!fork()) {
        setsid();
        execl("/bin/sh", "/bin/sh", "-c", command.c_str(), 0);
        exit(0); //exit child
    }

    hide(); // hide gui

    // save command history to file
    if (text().size() != 0) { // no need to save empty command

        // don't allow duplicates into the history file, first
        // look for a duplicate
        if (m_current_history_item < m_history.size()
            && text() == m_history[m_current_history_item]) {
            // m_current_history_item is the duplicate
        } else {
            m_current_history_item = 0;
            for (; m_current_history_item < m_history.size();
                 ++m_current_history_item) {
                if (m_history[m_current_history_item] == text())
                    break;
            }
        }

        // now m_current_history_item points at the duplicate, or
        // at m_history.size() if no duplicate
        fstream inoutfile(m_history_file.c_str(), ios::in|ios::out);
        if (inoutfile) {
            int i = 0;
            // read past history items before current
            for (string line; !inoutfile.eof() && i < m_current_history_item; i++)
                getline(inoutfile, line);
            // write the history items that come after current
            for (i++; i < m_history.size(); i++)
                inoutfile<<m_history[i]<<endl;

            // and append the current one back to the end
            inoutfile<<text()<<endl;
        } else
            cerr<<"FbRun Warning: Can't write command history to file: "<<m_history_file<<endl;
    }

}

bool FbRun::loadHistory(const char *filename) {
    if (filename == 0)
        return false;
    ifstream infile(filename);
    if (!infile) {
        //even though we fail to load file, we should try save to it
        m_history_file = filename;
        return false;
    }
    // clear old history and load new one from file
    m_history.clear();
    // each line is a command
    string line;
    while (!infile.eof()) {
        getline(infile, line);
        if (line.size()) // don't add empty lines
            m_history.push_back(line);
    }
    // set no current histor to display
    m_current_history_item = m_history.size();
    // set history file
    m_history_file = filename;
    return true;
}

bool FbRun::loadFont(const string &fontname) {
    if (!m_font.load(fontname.c_str()))
        return false;

    // resize to fit new font height
    resize(width(), font().height() + m_bevel);
    return true;
}

void FbRun::setForegroundColor(const FbTk::Color &color) {
    m_gc.setForeground(color);
}

void FbRun::setTitle(const string &title) {
    setName(title.c_str());
}

void FbRun::resize(unsigned int width, unsigned int height) {
    FbTk::TextBox::resize(width, height);
    setNoMaximize();
}

void FbRun::redrawLabel() {
    clear();
}

void FbRun::keyPressEvent(XKeyEvent &ke) {
    // strip numlock, capslock and scrolllock mask
    ke.state = FbTk::KeyUtil::instance().cleanMods(ke.state);

    int cp= cursorPosition();
    FbTk::TextBox::keyPressEvent(ke);
    KeySym ks;
    char keychar[1];
    XLookupString(&ke, keychar, 1, &ks, 0);
    // a modifier key by itself doesn't do anything
    if (IsModifierKey(ks)) return;

    if (ke.state) { // a modifier key is down
        if (ke.state == ControlMask) {
            switch (ks) {
            case XK_p:
                prevHistoryItem();
                break;
            case XK_n:
                nextHistoryItem();
                break;
            }
        } else if (ke.state == (Mod1Mask | ShiftMask)) {
            switch (ks) {
            case XK_less:
                firstHistoryItem();
                break;
            case XK_greater:
                lastHistoryItem();
                break;
            }
        }
    } else { // no modifier key
        switch (ks) {
        case XK_Escape:
            m_end = true;
            hide();
            FbTk::App::instance()->end(); // end program
            break;
        case XK_Return:
            run(text());
            break;
        case XK_Up:
            prevHistoryItem();
            break;
        case XK_Down:
            nextHistoryItem();
            break;
        case XK_Tab:
            tabCompleteHistory();
            setCursorPosition(cp);
            break;
        }
    }
    clear();
}

void FbRun::setNoMaximize() {
    // we don't need to maximize this window
    XSizeHints sh;
    sh.flags = PMaxSize | PMinSize;
    sh.max_width = width();
    sh.max_height = height();
    sh.min_width = width();
    sh.min_height = height();
    XSetWMNormalHints(m_display, window(), &sh);
}

void FbRun::prevHistoryItem() {
    if (m_history.size() == 0 || m_current_history_item == 0) {
        XBell(m_display, 0);
    } else {
        m_current_history_item--;
        setText(m_history[m_current_history_item]);
    }
}

void FbRun::nextHistoryItem() {
    if (m_current_history_item == m_history.size()) {
        XBell(m_display, 0);
    } else {
        m_current_history_item++;
        if (m_current_history_item == m_history.size()) {
            m_current_history_item = m_history.size();
            setText("");
         } else
            setText(m_history[m_current_history_item]);
    }
}

void FbRun::firstHistoryItem() {
    if (m_history.size() == 0 || m_current_history_item == 0) {
        XBell(m_display, 0);
    } else {
        m_current_history_item = 0;
        setText(m_history[m_current_history_item]);
    }
}

void FbRun::lastHistoryItem() {
    // actually one past the end
    if (m_history.size() == 0) {
        XBell(m_display, 0);
    } else {
        m_current_history_item = m_history.size();
        setText("");
    }
}

void FbRun::tabCompleteHistory() {
    if (m_current_history_item == 0) {
        XBell(m_display, 0);
    } else {
        int history_item = m_current_history_item - 1;
        string prefix = text().substr(0, cursorPosition());
        while (history_item != m_current_history_item ) {
            if (history_item == -1 )
                history_item+= m_history.size();
            if (m_history[history_item].find(prefix) == 0) {
                m_current_history_item = history_item;
                setText(m_history[m_current_history_item]);
                break;
            }
            history_item--;
        }
        if (history_item == m_current_history_item) XBell(m_display, 0);
    }
}

void FbRun::insertCharacter(char keychar) {
    char val[2] = {keychar, 0};
    insertText(val);
}

<|endoftext|>


<commit_before>#ifndef _LAPACK_WRAP_HPP_
#define _LAPACK_WRAP_HPP_

#include "mkl.h"

#include <stdexcept>

extern "C" {
  void dgemm_(char *transa, char *transb, int *m, int *n, int *k,
			  double *alpha, double *a, int *lda, double *b, int *ldb,
			  double *beta, double *c, int *ldc);
  void sgemm_(char *transa, char *transb, int *m, int *n, int *k,
			  float *alpha, float *a, int *lda, float *b, int *ldb,
			  float *beta, float *c, int *ldc);

  void daxpy_(int *n, double *alpha, double *A, int *incx, double *C, int *incy);
  void saxpy_(int *n, float *alpha, float *A, int *incx, float *C, int *incy);

  void dtrsm_(char *side, char *uplo, char *transa, char *diag, int *m, int *n,
			  double *alpha, double *A, int *lda, double *B, int *ldb);
  void strsm_(char *side, char *uplo, char *transa, char *diag, int *m, int *n,
			  float *alpha, float *A, int *lda, float *B, int *ldb);

  void dtrmm_(char *side, char *uplo, char *transt, char *diag, int *m, int *n,
			  double *alpha, double *T, int *ldt, double *B, int *ldb);
  void strmm_(char *side, char *uplo, char *transt, char *diag, int *m, int *n,
			  float *alpha, float *T, int *ldt, float *B, int *ldb);

  //  void dlaswp_(int *N, double *A, int *lda, int *K1, int *K2, int *ipiv, int *incx);
  //  void slaswp_(int *N, float *A, int *lda, int *K1, int *K2, int *ipiv, int *incx);
}

// These are wrappers around lapack routines.

namespace lapack {

  void Trmm(char side, char uplo, char transt, char diag, int m, int n,
			double alpha, double *T, int ldt, double *B, int ldb) {
	dtrmm_(&side, &uplo, &transt, &diag, &m, &n, &alpha, T, &ldt, B, &ldb);
  }

  void Trmm(char side, char uplo, char transt, char diag, int m, int n,
			float alpha, float *T, int ldt, float *B, int ldb) {
	strmm_(&side, &uplo, &transt, &diag, &m, &n, &alpha, T, &ldt, B, &ldb);
  }

  void Larft(char direct, char storev, int m, int n, double *V, int ldv,
			 double *tau, double *T, int ldt) {
	dlarft_(&direct, &storev, &m, &n, V, &ldv, tau, T, &ldt);
  }

  void Larft(char direct, char storev, int m, int n, float *V, int ldv,
			 float *tau, float *T, int ldt) {
	slarft_(&direct, &storev, &m, &n, V, &ldv, tau, T, &ldt);
  }

  void Geqrf(int m, int n, float *A, int lda, float *tau) {
	// First perform the workspace query.
	float *work = new float[1];
	int lwork = -1;
	int info;
	sgeqrf_(&m, &n, A, &lda, tau, work, &lwork, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad sgeqrf_ call");
	}

	// Now allocate the work array.
	lwork = static_cast<int>(work[0]);
	delete [] work;
	work = new float[lwork];

	// QR routine that does the work.
	sgeqrf_(&m, &n, A, &lda, tau, work, &lwork, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad sgeqrf_ call");
	}
	delete [] work;
  }

  void Geqrf(int m, int n, double *A, int lda, double *tau) {
	// First perform the workspace query.
	double *work = new double[1];
	int lwork = -1;
	int info;
	dgeqrf_(&m, &n, A, &lda, tau, work, &lwork, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad dgeqrf_ call");
	}

	// Now allocate the work array.
	lwork = static_cast<int>(work[0]);
	delete [] work;
	work = new double[lwork];

	// QR routine that does the work.
	dgeqrf_(&m, &n, A, &lda, tau, work, &lwork, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad dgeqrf_ call");
	}
	delete [] work;
  }

  void Getrf(double *data, int m, int n, int lda, int *pivots) {
	int info;
	dgetrf_(&m, &n, data, &lda, pivots, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad dgetrf_ call");
	}
  }

  void Getrf(float *data, int m, int n, int lda, int *pivots) {
	int info;
	sgetrf_(&m, &n, data, &lda, pivots, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad sgetrf_ call");
	}
  }

  void Laswp(int num_cols, double *data, int lda, int piv_start, int piv_end,
			 int *pivots, int incx) {
	dlaswp_(&num_cols, data, &lda,  &piv_start, &piv_end, pivots, &incx);
  }

  void Laswp(int num_cols, float *data, int lda, int piv_start, int piv_end,
			 int *pivots, int incx) {
	slaswp_(&num_cols, data, &lda,  &piv_start, &piv_end, pivots, &incx);
  }

  void Trsm(char side, char uplo, char transa, char diag, int m, int n,
			double alpha, double *A, int lda, double *B, int ldb) {
	dtrsm_(&side, &uplo, &transa, &diag, &m, &n, &alpha, A, &lda, B, &ldb);
  }

  void Trsm(char side, char uplo, char transa, char diag, int m, int n,
			float alpha, float *A, int lda, float *B, int ldb) {
	strsm_(&side, &uplo, &transa, &diag, &m, &n, &alpha, A, &lda, B, &ldb);
  }

  void Getrs(char trans, int n, int nrhs, double *A, int lda, int *ipiv, double *b, int ldb) {
	int info;
	dgetrs_(&trans, &n, &nrhs, A, &lda, ipiv, b, &ldb, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad dgetrs_ call");
	}
  }

  void Getrs(char trans, int n, int nrhs, float *A, int lda, int *ipiv, float *b, int ldb) {
	int info;
	sgetrs_(&trans, &n, &nrhs, A, &lda, ipiv, b, &ldb, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad sgetrs_ call");
	}
  }

}  // end namespace lapack

#endif  // _LAPACK_WRAP_HPP_
<commit_msg>More wrapper functions...<commit_after>#ifndef _LAPACK_WRAP_HPP_
#define _LAPACK_WRAP_HPP_

#include "mkl.h"

#include <functional>
#include <stdexcept>

extern "C" {
  void dgemm_(char *transa, char *transb, int *m, int *n, int *k,
			  double *alpha, double *a, int *lda, double *b, int *ldb,
			  double *beta, double *c, int *ldc);
  void sgemm_(char *transa, char *transb, int *m, int *n, int *k,
			  float *alpha, float *a, int *lda, float *b, int *ldb,
			  float *beta, float *c, int *ldc);

  void daxpy_(int *n, double *alpha, double *A, int *incx, double *C, int *incy);
  void saxpy_(int *n, float *alpha, float *A, int *incx, float *C, int *incy);

  void dtrsm_(char *side, char *uplo, char *transa, char *diag, int *m, int *n,
			  double *alpha, double *A, int *lda, double *B, int *ldb);
  void strsm_(char *side, char *uplo, char *transa, char *diag, int *m, int *n,
			  float *alpha, float *A, int *lda, float *B, int *ldb);

  void dtrmm_(char *side, char *uplo, char *transt, char *diag, int *m, int *n,
			  double *alpha, double *T, int *ldt, double *B, int *ldb);
  void strmm_(char *side, char *uplo, char *transt, char *diag, int *m, int *n,
			  float *alpha, float *T, int *ldt, float *B, int *ldb);

  //  void dlaswp_(int *N, double *A, int *lda, int *K1, int *K2, int *ipiv, int *incx);
  //  void slaswp_(int *N, float *A, int *lda, int *K1, int *K2, int *ipiv, int *incx);
}

// These are wrappers around lapack routines.
namespace lapack {
  // This is a wrapper around workspace queries.  The query function takes
  // the work, lwork, and info variables and performs a workspace query.
  // After the query, the work array is allocated.
  template <typename Scalar>
  void WorkspaceQueryAndAlloc(std::function<void (Scalar* &, int&, int&)> query_func,
							  Scalar* &work, int& lwork, int& info) {
	work = new Scalar[1];
	lwork = -1;
	query_func(work, lwork, info);
	if (info != 0) {
	  throw std::runtime_error("Bad workspace query");
	}

	// Now allocate the work array.
	lwork = static_cast<int>(work[0]);
	delete [] work;
	work = new Scalar[lwork];
  }

  void Trmm(char side, char uplo, char transt, char diag, int m, int n,
			double alpha, double *T, int ldt, double *B, int ldb) {
	dtrmm_(&side, &uplo, &transt, &diag, &m, &n, &alpha, T, &ldt, B, &ldb);
  }

  void Trmm(char side, char uplo, char transt, char diag, int m, int n,
			float alpha, float *T, int ldt, float *B, int ldb) {
	strmm_(&side, &uplo, &transt, &diag, &m, &n, &alpha, T, &ldt, B, &ldb);
  }

  void Larft(char direct, char storev, int m, int n, double *V, int ldv,
			 double *tau, double *T, int ldt) {
	dlarft_(&direct, &storev, &m, &n, V, &ldv, tau, T, &ldt);
  }

  void Larft(char direct, char storev, int m, int n, float *V, int ldv,
			 float *tau, float *T, int ldt) {
	slarft_(&direct, &storev, &m, &n, V, &ldv, tau, T, &ldt);
  }

  void Geqrf(int m, int n, float *A, int lda, float *tau) {
	// First perform the workspace query.
	std::function<void (float* &, int&, int&)> query = [&] (float *work,
															int& lwork,
															int& info) {
	  sgeqrf_(&m, &n, A, &lda, tau, work, &lwork, &info);
	};
	float *work;
	int lwork;
	int info;
	WorkspaceQueryAndAlloc(query, work, lwork, info);

	// QR routine that does the work.
	sgeqrf_(&m, &n, A, &lda, tau, work, &lwork, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad sgeqrf_ call");
	}
	delete [] work;
  }

  void Geqrf(int m, int n, double *A, int lda, double *tau) {
	// First perform the workspace query.
	std::function<void (double* &, int&, int&)> query = [&] (double *work,
															 int& lwork,
															 int& info) {
	  dgeqrf_(&m, &n, A, &lda, tau, work, &lwork, &info);
	};
	double *work;
	int lwork;
	int info;
	WorkspaceQueryAndAlloc(query, work, lwork, info);

	// QR routine that does the work.
	dgeqrf_(&m, &n, A, &lda, tau, work, &lwork, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad dgeqrf_ call");
	}
	delete [] work;
  }

  void Getrf(double *data, int m, int n, int lda, int *pivots) {
	int info;
	dgetrf_(&m, &n, data, &lda, pivots, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad dgetrf_ call");
	}
  }

  void Getrf(float *data, int m, int n, int lda, int *pivots) {
	int info;
	sgetrf_(&m, &n, data, &lda, pivots, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad sgetrf_ call");
	}
  }

  void Laswp(int num_cols, double *data, int lda, int piv_start, int piv_end,
			 int *pivots, int incx) {
	dlaswp_(&num_cols, data, &lda,  &piv_start, &piv_end, pivots, &incx);
  }

  void Laswp(int num_cols, float *data, int lda, int piv_start, int piv_end,
			 int *pivots, int incx) {
	slaswp_(&num_cols, data, &lda,  &piv_start, &piv_end, pivots, &incx);
  }

  void Trsm(char side, char uplo, char transa, char diag, int m, int n,
			double alpha, double *A, int lda, double *B, int ldb) {
	dtrsm_(&side, &uplo, &transa, &diag, &m, &n, &alpha, A, &lda, B, &ldb);
  }

  void Trsm(char side, char uplo, char transa, char diag, int m, int n,
			float alpha, float *A, int lda, float *B, int ldb) {
	strsm_(&side, &uplo, &transa, &diag, &m, &n, &alpha, A, &lda, B, &ldb);
  }

  void Getrs(char trans, int n, int nrhs, double *A, int lda, int *ipiv, double *b, int ldb) {
	int info;
	dgetrs_(&trans, &n, &nrhs, A, &lda, ipiv, b, &ldb, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad dgetrs_ call");
	}
  }

  void Getrs(char trans, int n, int nrhs, float *A, int lda, int *ipiv, float *b, int ldb) {
	int info;
	sgetrs_(&trans, &n, &nrhs, A, &lda, ipiv, b, &ldb, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad sgetrs_ call");
	}
  }

  void Ormqr(char side, char trans, int m, int n, int k, double *A, int lda,
			 double *tau, double *C, int ldc) {
	std::function<void (double* &, int&, int&)> query = [&] (double *work,
															 int& lwork,
															 int& info) {
	  dormqr_(&side, &trans, &m, &n, &k, A, &lda, tau, C, &ldc,
			  work, &lwork, &info);
	};
	double *work;
	int lwork;
	int info;
	WorkspaceQueryAndAlloc(query, work, lwork, info);

	dormqr_(&side, &trans, &m, &n, &k, A, &lda, tau, C, &ldc,
			work, &lwork, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad dormqr_ call");
	}
	delete [] work;
  }

  void Ormqr(char side, char trans, int m, int n, int k, float *A, int lda,
			 float *tau, float *C, int ldc) {
	std::function<void (float* &, int&, int&)> query = [&] (float *work,
															 int& lwork,
															 int& info) {
	  sormqr_(&side, &trans, &m, &n, &k, A, &lda, tau, C, &ldc,
			  work, &lwork, &info);
	};
	float *work;
	int lwork;
	int info;
	WorkspaceQueryAndAlloc(query, work, lwork, info);

	sormqr_(&side, &trans, &m, &n, &k, A, &lda, tau, C, &ldc,
			work, &lwork, &info);
	if (info != 0) {
	  throw std::runtime_error("Bad dormqr_ call");
	}
	delete [] work;
  }
}  // end namespace lapack

#endif  // _LAPACK_WRAP_HPP_
<|endoftext|>


<commit_before>// Base header file.  Must be first.
#include <Include/PlatformDefinitions.hpp>

#include <cassert>
#include <fstream>
#include <iostream>
#include <strstream>

#include <util/PlatformUtils.hpp>

#include <XalanTransformer/XalanTransformer.hpp>

//This is here for the Windows threads.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winbase.h>
#define THREADFUNCTIONRETURN DWORD WINAPI

#if !defined(XALAN_NO_NAMESPACES)
	using std::cerr;
	using std::cout;
	using std::endl;
	using std::ifstream;
	using std::ios_base;
	using std::ostrstream;
	using std::string;
#endif

// Used to hold compiled stylesheet and XML source document.
const XalanCompiledStylesheet*	glbCompiledStylesheet = 0;
const XalanParsedSource*		glbParsedSource = 0;
int								glbError = 0;

// Print messages tracking the progress of each thread, and the
// beginning and end of the entire operation.
void
outputMessage(
			DWORD		id,
			const char	msg[])
{
	ostrstream threadMsg;

	threadMsg << "\n" << msg << " Thread: " << id << '\0';

	cout << threadMsg.str();

	threadMsg.freeze(false);
}

THREADFUNCTIONRETURN
theThread(LPVOID	param)
{
// This routine uses a compiled stylesheet (glbCompiledStylesheet),
// and a binary source tree (glbParsedSource) to perform the
// transformation.

	int	theResult = 0;

	const int	number = reinterpret_cast<int>(param);

	const DWORD		theThreadID = GetCurrentThreadId();

	outputMessage(theThreadID, "Starting ");

	// Create a XalanTransformer.
	XalanTransformer	theXalanTransformer;

	// Generate the output file name for this thread.
    ostrstream	theFormatterOut;
    theFormatterOut << "birds" << number << ".out" << '\0';

	// Generate the XML output object.
	const XSLTResultTarget	theResultTarget(XalanDOMString(theFormatterOut.str()));

	// Unfreeze the ostrstream, so memory is returned...
	theFormatterOut.freeze(false);

	outputMessage(theThreadID, "Transforming");

 	// Do the transform.
	theResult = theXalanTransformer.transform(*glbParsedSource, glbCompiledStylesheet, theResultTarget);

	if(theResult != 0)
	{
		cerr << "ThreadSafe Error: \n" << theXalanTransformer.getLastError()
			 << endl
			 << endl;

		glbError = theResult;
	}

	outputMessage(theThreadID, "Finishing");

	return (theResult);
}

// Create and run the threads...
// Print messages tracking the progress of each thread and of the
// overall operation...
void
doThreads(int	nThreads)
{
#if !defined(XALAN_NO_NAMESPACES)
	using std::vector;
#endif

	vector<HANDLE>	hThreads;

	hThreads.reserve(nThreads);

	cout << endl << "Clock before starting threads: " << clock() << endl;

	int		i = 0;

	for (; i < nThreads; ++i)
	{
		DWORD  threadID;

		const HANDLE	hThread = CreateThread(
				0,
				4096,							// Stack size for thread.
				theThread,						// pointer to thread function
				reinterpret_cast<LPVOID>(i),	// argument for new thread
				0,								// creation flags
				&threadID);

		assert(hThread != 0);

		hThreads.push_back(hThread);
	}

	WaitForMultipleObjects(hThreads.size(), &hThreads[0], TRUE, INFINITE);

	cout << endl << "Clock after threads: " << clock() << endl;

	for (i = 0; i < nThreads; ++i)
	{
		CloseHandle(hThreads[i]);
	}
}

int
main(
			int				argc,
			const char*		/* argv */[])
{
	if (argc != 1)
	{
		cerr << "Usage: ThreadTest"
			 << endl
			 << endl;
	}
	else
	{
		// Call the static initializer for Xerces.
		XMLPlatformUtils::Initialize();

		// Initialize Xalan.
		XalanTransformer::initialize();

		{
			// Create a XalanTransformer.  We won't actually use this to transform --
			// it's just acting likely a factory for the compiled stylesheet and
			// pre-parsed source.
			XalanTransformer	theXalanTransformer;

			glbError = theXalanTransformer.compileStylesheet("birds.xsl", glbCompiledStylesheet);

			if (glbError != 0)
			{
				cerr << "ThreadSafe Error: \n" << theXalanTransformer.getLastError()
					 << endl
					 << endl;
			}
			else
			{
				assert(glbCompiledStylesheet != 0);

				// Compile the XML source document as well. All threads will use
				// this binary representation of the source tree.
				glbError = theXalanTransformer.parseSource("birds.xml", glbParsedSource);

				if (glbError != 0)
				{
					cerr << "ThreadSafe Error: \n" << theXalanTransformer.getLastError()
						 << endl
						 << endl;
				}
				else
				{
					assert(glbParsedSource != 0);

					// Create and run the threads...
					// Each thread uses the same document and
					// stylesheet to perform a transformation.
					doThreads(10);
				}
			}
		}

		// Terminate Xalan.
		XalanTransformer::terminate();

		// Call the static terminator for Xerces.
		XMLPlatformUtils::Terminate();
	}

	return glbError;
}
<commit_msg>Added missing include file.<commit_after>// Base header file.  Must be first.
#include <Include/PlatformDefinitions.hpp>

#include <cassert>
#include <ctime>
#include <fstream>
#include <iostream>
#include <strstream>

#include <util/PlatformUtils.hpp>

#include <XalanTransformer/XalanTransformer.hpp>

//This is here for the Windows threads.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winbase.h>
#define THREADFUNCTIONRETURN DWORD WINAPI

#if !defined(XALAN_NO_NAMESPACES)
	using std::cerr;
	using std::cout;
	using std::endl;
	using std::ifstream;
	using std::ios_base;
	using std::ostrstream;
	using std::string;
#endif

// Used to hold compiled stylesheet and XML source document.
const XalanCompiledStylesheet*	glbCompiledStylesheet = 0;
const XalanParsedSource*		glbParsedSource = 0;
int								glbError = 0;

// Print messages tracking the progress of each thread, and the
// beginning and end of the entire operation.
void
outputMessage(
			DWORD		id,
			const char	msg[])
{
	ostrstream threadMsg;

	threadMsg << "\n" << msg << " Thread: " << id << '\0';

	cout << threadMsg.str();

	threadMsg.freeze(false);
}

THREADFUNCTIONRETURN
theThread(LPVOID	param)
{
// This routine uses a compiled stylesheet (glbCompiledStylesheet),
// and a binary source tree (glbParsedSource) to perform the
// transformation.

	int	theResult = 0;

	const int	number = reinterpret_cast<int>(param);

	const DWORD		theThreadID = GetCurrentThreadId();

	outputMessage(theThreadID, "Starting ");

	// Create a XalanTransformer.
	XalanTransformer	theXalanTransformer;

	// Generate the output file name for this thread.
    ostrstream	theFormatterOut;
    theFormatterOut << "birds" << number << ".out" << '\0';

	// Generate the XML output object.
	const XSLTResultTarget	theResultTarget(XalanDOMString(theFormatterOut.str()));

	// Unfreeze the ostrstream, so memory is returned...
	theFormatterOut.freeze(false);

	outputMessage(theThreadID, "Transforming");

 	// Do the transform.
	theResult = theXalanTransformer.transform(*glbParsedSource, glbCompiledStylesheet, theResultTarget);

	if(theResult != 0)
	{
		cerr << "ThreadSafe Error: \n" << theXalanTransformer.getLastError()
			 << endl
			 << endl;

		glbError = theResult;
	}

	outputMessage(theThreadID, "Finishing");

	return (theResult);
}

// Create and run the threads...
// Print messages tracking the progress of each thread and of the
// overall operation...
void
doThreads(int	nThreads)
{
#if !defined(XALAN_NO_NAMESPACES)
	using std::vector;
#endif

	vector<HANDLE>	hThreads;

	hThreads.reserve(nThreads);

	cout << endl << "Clock before starting threads: " << clock() << endl;

	int		i = 0;

	for (; i < nThreads; ++i)
	{
		DWORD  threadID;

		const HANDLE	hThread = CreateThread(
				0,
				4096,							// Stack size for thread.
				theThread,						// pointer to thread function
				reinterpret_cast<LPVOID>(i),	// argument for new thread
				0,								// creation flags
				&threadID);

		assert(hThread != 0);

		hThreads.push_back(hThread);
	}

	WaitForMultipleObjects(hThreads.size(), &hThreads[0], TRUE, INFINITE);

	cout << endl << "Clock after threads: " << clock() << endl;

	for (i = 0; i < nThreads; ++i)
	{
		CloseHandle(hThreads[i]);
	}
}

int
main(
			int				argc,
			const char*		/* argv */[])
{
	if (argc != 1)
	{
		cerr << "Usage: ThreadTest"
			 << endl
			 << endl;
	}
	else
	{
		// Call the static initializer for Xerces.
		XMLPlatformUtils::Initialize();

		// Initialize Xalan.
		XalanTransformer::initialize();

		{
			// Create a XalanTransformer.  We won't actually use this to transform --
			// it's just acting likely a factory for the compiled stylesheet and
			// pre-parsed source.
			XalanTransformer	theXalanTransformer;

			glbError = theXalanTransformer.compileStylesheet("birds.xsl", glbCompiledStylesheet);

			if (glbError != 0)
			{
				cerr << "ThreadSafe Error: \n" << theXalanTransformer.getLastError()
					 << endl
					 << endl;
			}
			else
			{
				assert(glbCompiledStylesheet != 0);

				// Compile the XML source document as well. All threads will use
				// this binary representation of the source tree.
				glbError = theXalanTransformer.parseSource("birds.xml", glbParsedSource);

				if (glbError != 0)
				{
					cerr << "ThreadSafe Error: \n" << theXalanTransformer.getLastError()
						 << endl
						 << endl;
				}
				else
				{
					assert(glbParsedSource != 0);

					// Create and run the threads...
					// Each thread uses the same document and
					// stylesheet to perform a transformation.
					doThreads(10);
				}
			}
		}

		// Terminate Xalan.
		XalanTransformer::terminate();

		// Call the static terminator for Xerces.
		XMLPlatformUtils::Terminate();
	}

	return glbError;
}
<|endoftext|>


<commit_before>#pragma once
#include "depthai-shared/common/Extrinsics.hpp"

namespace dai {

struct CameraInfo {
    CameraInfo() : width(0), height(0), measuredFovDeg(0) {}
    uint16_t width, height;
    std::vector<std::vector<float>> intrinsicMatrix;
    std::vector<float> distortionCoeff;
    Extrinsics extrinsics;
    double measuredFovDeg;  // fov in deg
    // TODO(sachin): Should I add type of distortion model here ?
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(CameraInfo, intrinsicMatrix, width, height, distortionCoeff, extrinsics, measuredFovDeg);
};

}  // namespace dai<commit_msg>changed fov to float<commit_after>#pragma once
#include "depthai-shared/common/Extrinsics.hpp"

namespace dai {

struct CameraInfo {
    CameraInfo() : width(0), height(0), measuredFovDeg(0) {}
    uint16_t width, height;
    std::vector<std::vector<float>> intrinsicMatrix;
    std::vector<float> distortionCoeff;
    Extrinsics extrinsics;
    float measuredFovDeg;  // fov in deg
    // TODO(sachin): Should I add type of distortion model here ?
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(CameraInfo, intrinsicMatrix, width, height, distortionCoeff, extrinsics, measuredFovDeg);
};

}  // namespace dai<|endoftext|>


<commit_before>#include "trajopt/configuration_space.hpp"
#include <boost/foreach.hpp>
#include "trajopt/rave_utils.hpp"
#include "utils/math.hpp"
using namespace OpenRAVE;
using namespace util;

// TODO: configuration should know something about what dofs are part of SO(1), SO(2) etc for functions like RandomDOFValues

namespace trajopt {

void RobotAndDOF::SetDOFValues(const DblVec& dofs) {
  if (affinedofs != 0) {
    OR::Transform T;
    OR::RaveGetTransformFromAffineDOFValues(T, dofs.begin()+joint_inds.size(), affinedofs, rotationaxis, true);
    robot->SetTransform(T);
    robot->SetDOFValues(dofs, false, joint_inds);
  }
  else {
    robot->SetDOFValues(dofs, false, joint_inds);
  }
}

DblVec RobotAndDOF::GetDOFValues() {
  DblVec out;
  robot->GetDOFValues(out, joint_inds);
  if (affinedofs != 0) {
    out.resize(GetDOF());
    OR::Transform T = robot->GetTransform();
    OR::RaveGetAffineDOFValuesFromTransform(out.begin() + joint_inds.size(), T, affinedofs, rotationaxis);
  }
  return out;
}

void RobotAndDOF::SetRobotActiveDOFs()  {
  RobotBasePtr robot1 = boost::dynamic_pointer_cast<RobotBase>(robot); // since robot is just a kinbody
  vector<int> current_active = robot1->GetActiveDOFIndices();
  if (robot1->GetActiveDOF() != GetDOF() || !std::equal(current_active.begin(), current_active.end(), joint_inds.begin()))
    robot1->SetActiveDOFs(joint_inds, affinedofs);
}

void RobotAndDOF::GetDOFLimits(DblVec& lower, DblVec& upper) const {
  robot->GetDOFLimits(lower, upper, joint_inds);
  const int translation_dofs[3] = {DOF_X, DOF_Y, DOF_Z};
  for (int i=0; i < 3; ++i) {
    if (affinedofs & translation_dofs[i]) {
      lower.push_back(-INFINITY);
      upper.push_back(INFINITY);
    }
  }
  if (affinedofs & DOF_RotationMask) {
    if (affinedofs & DOF_RotationAxis) {
      lower.push_back(-INFINITY);
      upper.push_back(INFINITY);
    }
    else if (affinedofs & DOF_Rotation3D) {
      for (int i=0; i < 3; ++i) {
        lower.push_back(-INFINITY);
        upper.push_back(INFINITY);
      }
    }
    else if (affinedofs & DOF_Rotation3D) {
      for (int i=0; i < 3; ++i) {
        lower.push_back(-INFINITY);
        upper.push_back(INFINITY);
      }
    }
    else if (affinedofs & DOF_RotationQuat) {
      for (int i=0; i < 4; ++i) {
        lower.push_back(-1);
        upper.push_back(1);
      }
    }
    else throw OR::openrave_exception("invalid rotation dofs", ORE_InvalidArguments);
  }
}
int RobotAndDOF::GetDOF() const {
  return joint_inds.size() + RaveGetAffineDOF(affinedofs);
}
DblMatrix RobotAndDOF::PositionJacobian(int link_ind, const OR::Vector& pt) const {
  Configuration::SaverPtr saver = const_cast<RobotAndDOF*>(this)->Save();
  const_cast<RobotAndDOF*>(this)->SetRobotActiveDOFs();
  vector<double> jacdata;
  boost::dynamic_pointer_cast<RobotBase>(robot)->CalculateActiveJacobian(link_ind, pt, jacdata);
  return Eigen::Map<DblMatrix>(jacdata.data(), 3, GetDOF());
}
DblMatrix RobotAndDOF::RotationJacobian(int link_ind) const {
  Configuration::SaverPtr saver = const_cast<RobotAndDOF*>(this)->Save();
  const_cast<RobotAndDOF*>(this)->SetRobotActiveDOFs();
  vector<double> jacdata;
  boost::dynamic_pointer_cast<RobotBase>(robot)->ComputeJacobianAxisAngle(link_ind, jacdata);
  return Eigen::Map<DblMatrix>(jacdata.data(), 3, GetDOF());
}
bool RobotAndDOF::DoesAffect(const KinBody::Link& link) {
  if (affinedofs > 0) return true;
  else if (link.GetParent() == GetRobot()) return trajopt::DoesAffect(*GetRobot(), joint_inds, GetRobotLinkIndex(*GetRobot(), link));
  else return false;
}

std::vector<KinBody::LinkPtr> RobotAndDOF::GetAffectedLinks() {
  vector<int> inds;
  std::vector<KinBody::LinkPtr> out;
  GetAffectedLinks(out,false,inds);
  return out;
}

void RobotAndDOF::GetAffectedLinks(std::vector<KinBody::LinkPtr>& links, bool only_with_geom, vector<int>& link_inds) {
  links.clear();
  link_inds.clear();
  BOOST_FOREACH(const KinBody::LinkPtr& link, GetRobot()->GetLinks()) {
    if (this->DoesAffect(*link) && !(only_with_geom && link->GetGeometries().empty())) {
      links.push_back(link);
      link_inds.push_back(link->GetIndex());
    }
  }

  vector<KinBodyPtr> grabbed;
  boost::dynamic_pointer_cast<RobotBase>(robot)->GetGrabbed(grabbed);
  BOOST_FOREACH(const KinBodyPtr& body, grabbed) {
    KinBody::LinkPtr grabberLink = boost::dynamic_pointer_cast<RobotBase>(robot)->IsGrabbing(body);
    assert(grabberLink);
    BOOST_FOREACH(const KinBody::LinkPtr& link, body->GetLinks()) {
      if (link->GetGeometries().size() > 0) {
        links.push_back(link);
        link_inds.push_back(grabberLink->GetIndex());
      }
    }
  }

}

vector<KinBodyPtr> RobotAndDOF::GetBodies() {
  std::set<KinBodyPtr> bodies;
  robot->GetAttached(bodies);
  return vector<KinBodyPtr> (bodies.begin(), bodies.end());
}

DblVec RobotAndDOF::RandomDOFValues() {
  int ndof = GetDOF();
  DblVec lower, upper;
  GetDOFLimits(lower, upper);
  DblVec out(ndof);
  for (int i=0; i < ndof; ++i) {
    // TODO this is only right for a circular joint!!
    lower[i] = fmax(lower[i], -2*M_PI);
    upper[i] = fmin(upper[i], 2*M_PI);
    out[i] = lower[i] + randf() * (upper[i] - lower[i]);
  }
  return out;
}

}
<commit_msg>Fixed bug that broke base only planning<commit_after>#include "trajopt/configuration_space.hpp"
#include <boost/foreach.hpp>
#include "trajopt/rave_utils.hpp"
#include "utils/math.hpp"
using namespace OpenRAVE;
using namespace util;

// TODO: configuration should know something about what dofs are part of SO(1), SO(2) etc for functions like RandomDOFValues

namespace trajopt {

void RobotAndDOF::SetDOFValues(const DblVec& dofs) {
  if (affinedofs != 0) {
    OR::Transform T;
    OR::RaveGetTransformFromAffineDOFValues(T, dofs.begin()+joint_inds.size(), affinedofs, rotationaxis, true);
    robot->SetTransform(T);
    if (joint_inds.size() > 0)
      robot->SetDOFValues(dofs, false, joint_inds);
  }
  else {
    robot->SetDOFValues(dofs, false, joint_inds);
  }
}

DblVec RobotAndDOF::GetDOFValues() {
  DblVec out;
  if (joint_inds.size() > 0):
    robot->GetDOFValues(out, joint_inds);
  if (affinedofs != 0) {
    out.resize(GetDOF());
    OR::Transform T = robot->GetTransform();
    OR::RaveGetAffineDOFValuesFromTransform(out.begin() + joint_inds.size(), T, affinedofs, rotationaxis);
  }
  return out;
}

void RobotAndDOF::SetRobotActiveDOFs()  {
  RobotBasePtr robot1 = boost::dynamic_pointer_cast<RobotBase>(robot); // since robot is just a kinbody
  vector<int> current_active = robot1->GetActiveDOFIndices();
  if (robot1->GetActiveDOF() != GetDOF() || !std::equal(current_active.begin(), current_active.end(), joint_inds.begin()))
    robot1->SetActiveDOFs(joint_inds, affinedofs);
}

void RobotAndDOF::GetDOFLimits(DblVec& lower, DblVec& upper) const {
  if (joint_inds.size() > 0)
    robot->GetDOFLimits(lower, upper, joint_inds);
  const int translation_dofs[3] = {DOF_X, DOF_Y, DOF_Z};
  for (int i=0; i < 3; ++i) {
    if (affinedofs & translation_dofs[i]) {
      lower.push_back(-INFINITY);
      upper.push_back(INFINITY);
    }
  }
  if (affinedofs & DOF_RotationMask) {
    if (affinedofs & DOF_RotationAxis) {
      lower.push_back(-INFINITY);
      upper.push_back(INFINITY);
    }
    else if (affinedofs & DOF_Rotation3D) {
      for (int i=0; i < 3; ++i) {
        lower.push_back(-INFINITY);
        upper.push_back(INFINITY);
      }
    }
    else if (affinedofs & DOF_Rotation3D) {
      for (int i=0; i < 3; ++i) {
        lower.push_back(-INFINITY);
        upper.push_back(INFINITY);
      }
    }
    else if (affinedofs & DOF_RotationQuat) {
      for (int i=0; i < 4; ++i) {
        lower.push_back(-1);
        upper.push_back(1);
      }
    }
    else throw OR::openrave_exception("invalid rotation dofs", ORE_InvalidArguments);
  }
}
int RobotAndDOF::GetDOF() const {
  return joint_inds.size() + RaveGetAffineDOF(affinedofs);
}
DblMatrix RobotAndDOF::PositionJacobian(int link_ind, const OR::Vector& pt) const {
  Configuration::SaverPtr saver = const_cast<RobotAndDOF*>(this)->Save();
  const_cast<RobotAndDOF*>(this)->SetRobotActiveDOFs();
  vector<double> jacdata;
  boost::dynamic_pointer_cast<RobotBase>(robot)->CalculateActiveJacobian(link_ind, pt, jacdata);
  return Eigen::Map<DblMatrix>(jacdata.data(), 3, GetDOF());
}
DblMatrix RobotAndDOF::RotationJacobian(int link_ind) const {
  Configuration::SaverPtr saver = const_cast<RobotAndDOF*>(this)->Save();
  const_cast<RobotAndDOF*>(this)->SetRobotActiveDOFs();
  vector<double> jacdata;
  boost::dynamic_pointer_cast<RobotBase>(robot)->ComputeJacobianAxisAngle(link_ind, jacdata);
  return Eigen::Map<DblMatrix>(jacdata.data(), 3, GetDOF());
}
bool RobotAndDOF::DoesAffect(const KinBody::Link& link) {
  if (affinedofs > 0) return true;
  else if (link.GetParent() == GetRobot()) return trajopt::DoesAffect(*GetRobot(), joint_inds, GetRobotLinkIndex(*GetRobot(), link));
  else return false;
}

std::vector<KinBody::LinkPtr> RobotAndDOF::GetAffectedLinks() {
  vector<int> inds;
  std::vector<KinBody::LinkPtr> out;
  GetAffectedLinks(out,false,inds);
  return out;
}

void RobotAndDOF::GetAffectedLinks(std::vector<KinBody::LinkPtr>& links, bool only_with_geom, vector<int>& link_inds) {
  links.clear();
  link_inds.clear();
  BOOST_FOREACH(const KinBody::LinkPtr& link, GetRobot()->GetLinks()) {
    if (this->DoesAffect(*link) && !(only_with_geom && link->GetGeometries().empty())) {
      links.push_back(link);
      link_inds.push_back(link->GetIndex());
    }
  }

  vector<KinBodyPtr> grabbed;
  boost::dynamic_pointer_cast<RobotBase>(robot)->GetGrabbed(grabbed);
  BOOST_FOREACH(const KinBodyPtr& body, grabbed) {
    KinBody::LinkPtr grabberLink = boost::dynamic_pointer_cast<RobotBase>(robot)->IsGrabbing(body);
    assert(grabberLink);
    BOOST_FOREACH(const KinBody::LinkPtr& link, body->GetLinks()) {
      if (link->GetGeometries().size() > 0) {
        links.push_back(link);
        link_inds.push_back(grabberLink->GetIndex());
      }
    }
  }

}

vector<KinBodyPtr> RobotAndDOF::GetBodies() {
  std::set<KinBodyPtr> bodies;
  robot->GetAttached(bodies);
  return vector<KinBodyPtr> (bodies.begin(), bodies.end());
}

DblVec RobotAndDOF::RandomDOFValues() {
  int ndof = GetDOF();
  DblVec lower, upper;
  GetDOFLimits(lower, upper);
  DblVec out(ndof);
  for (int i=0; i < ndof; ++i) {
    // TODO this is only right for a circular joint!!
    lower[i] = fmax(lower[i], -2*M_PI);
    upper[i] = fmin(upper[i], 2*M_PI);
    out[i] = lower[i] + randf() * (upper[i] - lower[i]);
  }
  return out;
}

}
<|endoftext|>


<commit_before>// ---------------------------------------------------------------------
//
// Copyright (C) 2017 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, redistribute
// it, and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE at
// the top level of the deal.II distribution.
//
// ---------------------------------------------------------------------

// The test is used to check the restriction_is_additive flags. The
// face degrees of freedom of a BDM element must be non-additive as
// they have continuity requirements, however the interior DOFs must
// be additive, e.g. for order 1 elements all DOFs are non-additive,
// while for the order 2 element in 2d we have 12 non-additive face DOFs
// and 2 additive interior ones. The test should output a vector
// consisting of faces_per_cell * dofs_per_face zeros, followed by
// interior_dofs ones.

#include "../tests.h"
#include <deal.II/base/logstream.h>
#include <deal.II/fe/fe_bdm.h>

#include <fstream>
#include <string>

std::ofstream logfile ("output");

template<int dim>
void
test (const unsigned int degree)
{
  FE_BDM<dim> fe_bdm(degree);

  deallog << "Degree=" << degree
          << ", restriction is additive flags:"
          << std::endl;

  for (unsigned int i=0; i<fe_bdm.dofs_per_cell; ++i)
    std::cout << fe_bdm.restriction_is_additive(i) << " ";

  deallog << std::endl;
}

int
main()
{
  initlog();

  deallog << "Dimension 2: " << std::endl;
  for (unsigned int i=1; i<4; ++i)
    test<2>(i);

  deallog << "Dimension 3: " << std::endl;
  for (unsigned int i=1; i<4; ++i)
    test<3>(i);

  return 0;
}

<commit_msg>fix tests/fe/bdm_16<commit_after>// ---------------------------------------------------------------------
//
// Copyright (C) 2017 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, redistribute
// it, and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE at
// the top level of the deal.II distribution.
//
// ---------------------------------------------------------------------

// The test is used to check the restriction_is_additive flags. The
// face degrees of freedom of a BDM element must be non-additive as
// they have continuity requirements, however the interior DOFs must
// be additive, e.g. for order 1 elements all DOFs are non-additive,
// while for the order 2 element in 2d we have 12 non-additive face DOFs
// and 2 additive interior ones. The test should output a vector
// consisting of faces_per_cell * dofs_per_face zeros, followed by
// interior_dofs ones.

#include "../tests.h"
#include <deal.II/base/logstream.h>
#include <deal.II/fe/fe_bdm.h>

#include <fstream>
#include <string>

std::ofstream logfile ("output");

template<int dim>
void
test (const unsigned int degree)
{
  FE_BDM<dim> fe_bdm(degree);

  deallog << "Degree=" << degree
          << ", restriction is additive flags:"
          << std::endl;

  for (unsigned int i=0; i<fe_bdm.dofs_per_cell; ++i)
    deallog << fe_bdm.restriction_is_additive(i) << " ";

  deallog << std::endl;
}

int
main()
{
  initlog();

  deallog << "Dimension 2: " << std::endl;
  for (unsigned int i=1; i<4; ++i)
    test<2>(i);

  deallog << "Dimension 3: " << std::endl;
  for (unsigned int i=1; i<4; ++i)
    test<3>(i);

  return 0;
}

<|endoftext|>


<commit_before>#include "../sys_uniform_value.hpp"
#include "screen.hpp"
#include "../glx_if.hpp"
#include "../systeminfo.hpp"
#include "../sys_uniform.hpp"

namespace rs {
	namespace util {
		const IdValue PostEffect::U_RectScale = IEffect::GlxId::GenUnifId("u_rectScale");
		// --------------------- PostEffect ---------------------
		PostEffect::PostEffect(IdValue idTech, rs::Priority dprio):
			_idTech(idTech)
		{
			_dtag.priority = dprio;
			setRect({-1,1,-1,1});
		}
		void PostEffect::setTechPassId(IdValue idTech) {
			_idTech = idTech;
		}
		void PostEffect::_applyParam(IEffect& e) const {
			for(auto& p : _param)
				p.second(e);
		}
		void PostEffect::setParamFunc(IdValue id, const ParamF& f) {
			auto itr = std::find_if(_param.begin(), _param.end(), [id](auto& p){
				return p.first == id;
			});
			if(itr == _param.end())
				_param.emplace_back(id, f);
			else
				*itr = std::make_pair(id, f);
		}
		void PostEffect::clearParam() {
			_param.clear();
		}
		void PostEffect::setRect(const spn::RectF& r) {
			_drawRect = r;
		}
		void PostEffect::onDraw(IEffect& e) const {
			e.setTechPassId(_idTech);
			_applyParam(e);
			e.setVDecl(DrawDecl<vdecl::screen>::GetVDecl());
			e.setVStream(_rect11.getVertex(), 0);
			auto ib = _rect11.getIndex();
			e.setIStream(ib);
			e.setUniform(U_RectScale, spn::Vec4{
					(_drawRect.x0+_drawRect.x1)/2,
					(_drawRect.y0+_drawRect.y1)/2,
					_drawRect.width()/2,
					_drawRect.height()/2});
			// 重ねて描画
			e.drawIndexed(GL_TRIANGLES, ib->get()->getNElem(), 0);
		}

		// --------------------- Viewport ---------------------
		Viewport::Viewport(Priority dprio) {
			_dtag.priority = dprio;
			setByRatio({0,1,0,1});
		}
		void Viewport::setByRatio(const spn::RectF& r) {
			_bPixel = false;
			_rect = r;
		}
		void Viewport::setByPixel(const spn::RectF& r) {
			_bPixel = true;
			_rect = r;
		}
		void Viewport::onDraw(IEffect& e) const {
			e.setViewport(_bPixel, _rect);
		}

		// --------------------- FBSwitch ---------------------
		FBSwitch::FBSwitch(rs::Priority dprio, rs::HFb hFb, const ClearParam_OP& cp):
			_hlFb(hFb),
			_cparam(cp)
		{
			_dtag.priority = dprio;
		}
		void FBSwitch::setClearParam(const ClearParam_OP& p) {
			_cparam = p;
		}
		// これ自体の描画はしない
		void FBSwitch::onDraw(IEffect& e) const {
			if(_hlFb)
				e.setFramebuffer(_hlFb);
			else
				e.resetFramebuffer();
			if(_cparam)
				e.clearFramebuffer(*_cparam);

			// ビューポートはフルスクリーンで初期化
			Viewport(0x0000).onDraw(e);
		}

		// --------------------- FBClear ---------------------
		FBClear::FBClear(rs::Priority dprio,
						const rs::draw::ClearParam& p):
			_param(p)
		{
			_dtag.priority = dprio;
		}
		void FBClear::onDraw(IEffect& e) const {
			e.clearFramebuffer(_param);
		}
	}
}
<commit_msg>PostEffect: 特定のUniform値が宣言されていない場合でも警告を出さない<commit_after>#include "../sys_uniform_value.hpp"
#include "screen.hpp"
#include "../glx_if.hpp"
#include "../systeminfo.hpp"
#include "../sys_uniform.hpp"

namespace rs {
	namespace util {
		const IdValue PostEffect::U_RectScale = IEffect::GlxId::GenUnifId("u_rectScale");
		// --------------------- PostEffect ---------------------
		PostEffect::PostEffect(IdValue idTech, rs::Priority dprio):
			_idTech(idTech)
		{
			_dtag.priority = dprio;
			setRect({-1,1,-1,1});
		}
		void PostEffect::setTechPassId(IdValue idTech) {
			_idTech = idTech;
		}
		void PostEffect::_applyParam(IEffect& e) const {
			for(auto& p : _param)
				p.second(e);
		}
		void PostEffect::setParamFunc(IdValue id, const ParamF& f) {
			auto itr = std::find_if(_param.begin(), _param.end(), [id](auto& p){
				return p.first == id;
			});
			if(itr == _param.end())
				_param.emplace_back(id, f);
			else
				*itr = std::make_pair(id, f);
		}
		void PostEffect::clearParam() {
			_param.clear();
		}
		void PostEffect::setRect(const spn::RectF& r) {
			_drawRect = r;
		}
		void PostEffect::onDraw(IEffect& e) const {
			e.setTechPassId(_idTech);
			_applyParam(e);
			e.setVDecl(DrawDecl<vdecl::screen>::GetVDecl());
			e.setVStream(_rect11.getVertex(), 0);
			auto ib = _rect11.getIndex();
			e.setIStream(ib);
			e.setUniform<false>(U_RectScale, spn::Vec4{
					(_drawRect.x0+_drawRect.x1)/2,
					(_drawRect.y0+_drawRect.y1)/2,
					_drawRect.width()/2,
					_drawRect.height()/2});
			// 重ねて描画
			e.drawIndexed(GL_TRIANGLES, ib->get()->getNElem(), 0);
		}

		// --------------------- Viewport ---------------------
		Viewport::Viewport(Priority dprio) {
			_dtag.priority = dprio;
			setByRatio({0,1,0,1});
		}
		void Viewport::setByRatio(const spn::RectF& r) {
			_bPixel = false;
			_rect = r;
		}
		void Viewport::setByPixel(const spn::RectF& r) {
			_bPixel = true;
			_rect = r;
		}
		void Viewport::onDraw(IEffect& e) const {
			e.setViewport(_bPixel, _rect);
		}

		// --------------------- FBSwitch ---------------------
		FBSwitch::FBSwitch(rs::Priority dprio, rs::HFb hFb, const ClearParam_OP& cp):
			_hlFb(hFb),
			_cparam(cp)
		{
			_dtag.priority = dprio;
		}
		void FBSwitch::setClearParam(const ClearParam_OP& p) {
			_cparam = p;
		}
		// これ自体の描画はしない
		void FBSwitch::onDraw(IEffect& e) const {
			if(_hlFb)
				e.setFramebuffer(_hlFb);
			else
				e.resetFramebuffer();
			if(_cparam)
				e.clearFramebuffer(*_cparam);

			// ビューポートはフルスクリーンで初期化
			Viewport(0x0000).onDraw(e);
		}

		// --------------------- FBClear ---------------------
		FBClear::FBClear(rs::Priority dprio,
						const rs::draw::ClearParam& p):
			_param(p)
		{
			_dtag.priority = dprio;
		}
		void FBClear::onDraw(IEffect& e) const {
			e.clearFramebuffer(_param);
		}
	}
}
<|endoftext|>


<commit_before>#include "../bitmap_content.hpp"

namespace sani {
	namespace resource {

		inline const uint32 BitmapContent::getWidth() const {
			return width;
		}

		inline const uint32 BitmapContent::getHeight() const {
			return height;
		}

		template <class PixelType>
		PixelBitmapContent<PixelType>::PixelBitmapContent(uint32 width, uint32 height)
			: BitmapContent(width, height), pixels(new PixelType[width * height]) {
			tryGetFormat(format);
		}

		template <class PixelType>
		PixelBitmapContent<PixelType>::~PixelBitmapContent() {
			delete[] pixels;
		}

		template <class PixelType>
		void PixelBitmapContent<PixelType>::tryGetFormat(graphics::SurfaceFormat* out) const {
			using namespace sani::math;
			out = nullptr;
			if (typeid(PixelType) == typeid(Vec4f)) {
				*out = SurfaceFormat::ColorRGBA;
			}

		}

	}
}<commit_msg>Set all pixels transparent as default<commit_after>#include "../bitmap_content.hpp"

namespace sani {
	namespace resource {

		inline const uint32 BitmapContent::getWidth() const {
			return width;
		}

		inline const uint32 BitmapContent::getHeight() const {
			return height;
		}

		template <class PixelType>
		PixelBitmapContent<PixelType>::PixelBitmapContent(uint32 width, uint32 height)
			: BitmapContent(width, height), pixels(new PixelType[width * height]) {
			// transparent
			memset(pixels, 0, sizeof(PixelType) * width * height);
			tryGetFormat(format);
		}

		template <class PixelType>
		PixelBitmapContent<PixelType>::~PixelBitmapContent() {
			delete[] pixels;
		}

		template <class PixelType>
		void PixelBitmapContent<PixelType>::tryGetFormat(graphics::SurfaceFormat* out) const {
			using namespace sani::math;
			out = nullptr;
			if (typeid(PixelType) == typeid(Vec4f)) {
				*out = SurfaceFormat::ColorRGBA;
			}

		}

	}
}<|endoftext|>


<commit_before>#pragma once
#include "util.hpp"
#include <utility>
#include <algorithm>
#include <cereal/access.hpp>

namespace spi {
	namespace test {
		//! non-copyableな値
		template <class T>
		class MoveOnly {
			public:
				using value_t = T;
			private:
				value_t		_value;

				// MoveOnlyがネストされていた場合にget()で一括除去
				template <class T2>
				static const T2& _getValue(const T2& t, ...) {
					return t;
				}
				template <class T3>
				static decltype(auto) _getValue(const MoveOnly<T3>& t, ...) {
					return t.getValue();
				}

			public:
				MoveOnly() = default;
				MoveOnly(const value_t& v): _value(v) {}
				MoveOnly(value_t&& v) noexcept: _value(std::move(v)) {}
				MoveOnly(const MoveOnly&) = delete;
				MoveOnly(MoveOnly&&) = default;
				void operator = (const MoveOnly&) = delete;
				MoveOnly& operator = (MoveOnly&&) = default;
				decltype(auto) getValue() const {
					return _getValue(_value, nullptr);
				}
				bool operator == (const MoveOnly& m) const noexcept {
					return getValue() == m.getValue();
				}
				bool operator != (const MoveOnly& m) const noexcept {
					return !(this->operator == (m));
				}
				bool operator < (const MoveOnly& m) const noexcept {
					return getValue() < m.getValue();
				}
				bool operator > (const MoveOnly& m) const noexcept {
					return getValue() > m.getValue();
				}
				bool operator <= (const MoveOnly& m) const noexcept {
					return getValue() <= m.getValue();
				}
				bool operator >= (const MoveOnly& m) const noexcept {
					return getValue() >= m.getValue();
				}
				value_t& get() noexcept {
					return _value;
				}
				const value_t& get() const noexcept {
					return _value;
				}
				template <class Ar>
				void serialize(Ar& ar) {
					ar(_value);
				}
				template <class Ar>
				static void load_and_construct(Ar& ar, cereal::construct<MoveOnly>& cs) {
					value_t val;
					ar(val);
					cs(val);
				}
		};
		template <class T>
		std::ostream& operator << (std::ostream& os, const MoveOnly<T>& m) {
			return os << m.get();
		}

		template <class T>
		void ModifyValue(MoveOnly<T>& t) {
			ModifyValue(t.get());
		}
	}
}
namespace std {
	template <class T>
	struct hash<spi::test::MoveOnly<T>> {
		std::size_t operator()(const spi::test::MoveOnly<T>& m) const noexcept {
			return std::hash<T>()(m.get());
		}
	};
}
<commit_msg>Test: MoveOnly: 値のデリファレンス<commit_after>#pragma once
#include "util.hpp"
#include <utility>
#include <algorithm>
#include <cereal/access.hpp>

namespace spi {
	namespace test {
		//! non-copyableな値
		template <class T>
		class MoveOnly {
			public:
				using value_t = T;
			private:
				value_t		_value;

				// MoveOnlyがネストされていた場合にget()で一括除去
				template <class T2>
				static const T2& _getValue(const T2& t, ...) {
					return t;
				}
				template <class T3>
				static decltype(auto) _getValue(const MoveOnly<T3>& t, ...) {
					return t.getValue();
				}

			public:
				MoveOnly() = default;
				MoveOnly(const value_t& v): _value(v) {}
				MoveOnly(value_t&& v) noexcept: _value(std::move(v)) {}
				MoveOnly(const MoveOnly&) = delete;
				MoveOnly(MoveOnly&&) = default;
				void operator = (const MoveOnly&) = delete;
				MoveOnly& operator = (MoveOnly&&) = default;
				decltype(auto) getValue() const {
					return _getValue(_value, nullptr);
				}
				bool operator == (const MoveOnly& m) const noexcept {
					return getValue() == m.getValue();
				}
				bool operator != (const MoveOnly& m) const noexcept {
					return !(this->operator == (m));
				}
				bool operator < (const MoveOnly& m) const noexcept {
					return getValue() < m.getValue();
				}
				bool operator > (const MoveOnly& m) const noexcept {
					return getValue() > m.getValue();
				}
				bool operator <= (const MoveOnly& m) const noexcept {
					return getValue() <= m.getValue();
				}
				bool operator >= (const MoveOnly& m) const noexcept {
					return getValue() >= m.getValue();
				}
				value_t& get() noexcept {
					return _value;
				}
				const value_t& get() const noexcept {
					return _value;
				}
				template <class Ar>
				void serialize(Ar& ar) {
					ar(_value);
				}
				template <class Ar>
				static void load_and_construct(Ar& ar, cereal::construct<MoveOnly>& cs) {
					value_t val;
					ar(val);
					cs(val);
				}
		};
		template <class T>
		std::ostream& operator << (std::ostream& os, const MoveOnly<T>& m) {
			return os << m.get();
		}
		template <class T>
		decltype(auto) Deref_MoveOnly(const MoveOnly<T>& m) {
			return m.get();
		}
		template <class T>
		decltype(auto) Deref_MoveOnly(const T& t) {
			return t;
		}

		template <class T>
		void ModifyValue(MoveOnly<T>& t) {
			ModifyValue(t.get());
		}
	}
}
namespace std {
	template <class T>
	struct hash<spi::test::MoveOnly<T>> {
		std::size_t operator()(const spi::test::MoveOnly<T>& m) const noexcept {
			return std::hash<T>()(m.get());
		}
	};
}
<|endoftext|>