<commit_before>#include "Claw.hpp"

#ifndef M_PI
#define M_PI 3.14159265
#endif

#include <Solenoid.h>
#include <DriverStationLCD.h>

Claw::Claw(unsigned int clawRotatePort, unsigned int clawWheelPort,
        unsigned int zeroSwitchPort, unsigned int haveBallPort) :
        m_settings( "RobotSettings.txt" )
        {
    m_clawRotator = new GearBox<Talon>( 0 , 7 , 8 , clawRotatePort );
    m_intakeWheel = new GearBox<Talon>( 0 , 0 , 0 , clawWheelPort );

    // Sets degrees rotated per pulse of encoder
    m_clawRotator->setDistancePerPulse( (1.0/71.0f)*14.0 /44.0 );
    m_clawRotator->setReversed(true);

    m_ballShooter.push_back( new Solenoid( 1 ) );
    m_ballShooter.push_back( new Solenoid( 2 ) );
    m_ballShooter.push_back( new Solenoid( 3 ) );
    m_ballShooter.push_back( new Solenoid( 4 ) );

    m_zeroSwitch = new DigitalInput(zeroSwitchPort);
    m_haveBallSwitch = new DigitalInput(haveBallPort);

    // Set up interrupt for encoder reset
    m_zeroSwitch->RequestInterrupts( Claw::ResetClawEncoder , this );
    m_zeroSwitch->SetUpSourceEdge( true , true );
    m_zeroSwitch->EnableInterrupts();

    // Set up interrupt for catching ball
    m_haveBallSwitch->RequestInterrupts( Claw::CloseClaw , this );
    m_haveBallSwitch->SetUpSourceEdge( false , true );
    //m_haveBallSwitch->EnableInterrupts();

    //magical values found using empirical testing don't change.
    setK(0.238f);
    m_l = 69.0f;

    m_collectorArm = new Solenoid(5);
    m_vacuum = new Solenoid (6);

    ReloadPID();
    m_shooterStates = SHOOTER_IDLE;
}

Claw::~Claw(){
    // Free solenoids
    for ( unsigned int i = 0 ; i < m_ballShooter.size() ; i++ ) {
        delete m_ballShooter[i];
    }

    delete m_collectorArm;

    m_zeroSwitch->DisableInterrupts();
    delete m_zeroSwitch;

    m_haveBallSwitch->DisableInterrupts();
    delete m_haveBallSwitch;

    delete m_vacuum;
    m_ballShooter.clear();
}

void Claw::SetAngle(float shooterAngle){
    m_clawRotator->setSetpoint( shooterAngle );
    m_setpoint = shooterAngle;
}

void Claw::ManualSetAngle(float value) {
	if((!m_zeroSwitch->Get() && value > 0) || m_zeroSwitch->Get())
	{
		m_clawRotator->setManual(value);

	}

}

double Claw::GetTargetAngle() const {
    return m_clawRotator->getSetpoint();
}

double Claw::GetAngle()
{
	return m_clawRotator->getDistance();

}

void Claw::SetWheelSetpoint( float speed ) {
    m_intakeWheel->setSetpoint( speed );
}

void Claw::SetWheelManual( float speed ) {
    m_intakeWheel->setManual( speed );
}

void Claw::ResetEncoders() {
    m_clawRotator->resetEncoder();
    m_intakeWheel->resetEncoder();
}

void Claw::ReloadPID() {
    m_settings.update();

    float p = 0.f;
    float i = 0.f;
    float d = 0.f;

    // Set shooter rotator PID
    p = atof( m_settings.getValueFor( "PID_ARM_ROTATE_P" ).c_str() );
    i = atof( m_settings.getValueFor( "PID_ARM_ROTATE_I" ).c_str() );
    d = atof( m_settings.getValueFor( "PID_ARM_ROTATE_D" ).c_str() );
    m_clawRotator->setPID( p , i , d );
}

void Claw::Shoot() {
	if (m_shooterStates == SHOOTER_IDLE){
		m_collectorArm->Set(true);
		m_shooterStates = SHOOTER_ARMISLIFTING;
		m_shootTimer.Start();
		m_shootTimer.Reset();
	}

}

void Claw::SetCollectorMode(bool collectorMode){
    m_collectorArm->Set(collectorMode);
}
bool Claw::GetCollectorMode(){
	return m_collectorArm->Get();
}

void Claw::Update() {
	if (m_shooterStates == SHOOTER_ARMISLIFTING && m_shootTimer.HasPeriodPassed(0.5)){
		for ( unsigned int i = 0 ; i < m_ballShooter.size() ; i++ ) {
		    m_ballShooter[i]->Set( true );
		}
		m_shootTimer.Reset();
		m_shooterStates = SHOOTER_SHOOTING;
	}
	if (m_shooterStates == SHOOTER_SHOOTING && m_shootTimer.HasPeriodPassed(2.0)){
		for ( unsigned int i = 0 ; i < m_ballShooter.size() ; i++ ) {
		     m_ballShooter[i]->Set( false );
		}
		m_vacuum->Set(true);
		m_shootTimer.Reset();
		m_shooterStates = SHOOTER_VACUUMING;
	}
	if (m_shooterStates == SHOOTER_VACUUMING && m_shootTimer.HasPeriodPassed(1.5)){
		m_vacuum->Set(false);
		m_collectorArm->Set (false);

		m_shootTimer.Reset();
		m_shooterStates = SHOOTER_IDLE;
	}
	if (!m_zeroSwitch->Get()){
		ResetEncoders();
	}

	setF(calcF());

	// Spins intake wheel to keep ball in while rotating claw at high speeds
	if ( fabs(m_clawRotator->getRate()) > 35.f ) {
        SetWheelManual( -1.f );
	}

	/* Fixes arm, when at reset angle, not touching zeroSwitch due to gradual
	 * encoder error. If limit switch isn't pressed but arm is supposedly at
	 * zeroing point or farther:
	 */
	if ( m_zeroSwitch->Get() && GetTargetAngle() <= 1.f &&
            m_clawRotator->onTarget() ) {
        m_clawRotator->setSetpoint( GetTargetAngle() - 5.f );
    }

    DriverStationLCD::GetInstance()->PrintfLine(DriverStationLCD::kUser_Line1, "Angle: %f", m_clawRotator->getDistance());
    DriverStationLCD::GetInstance()->PrintfLine(DriverStationLCD::kUser_Line2, "A Setpt: %f", GetTargetAngle());
    DriverStationLCD::GetInstance()->PrintfLine(DriverStationLCD::kUser_Line3, "Limit On: %u", !m_zeroSwitch->Get());
    DriverStationLCD::GetInstance()->PrintfLine(DriverStationLCD::kUser_Line4, "OnTarget: %u", static_cast<unsigned int>(m_clawRotator->onTarget()));
    DriverStationLCD::GetInstance()->PrintfLine(DriverStationLCD::kUser_Line5, "A Rate: %f", m_clawRotator->getRate());
    DriverStationLCD::GetInstance()->UpdateLCD();

}

void Claw::setF(float f)
{
	m_clawRotator->setF(f);

}

void Claw::setK(float k)
{
	m_k = k;

}

float Claw::calcF()
{
	if(GetTargetAngle() == 0)
	{
		return 0.0f;

	}

	return m_k*cos((GetAngle()+m_l)*M_PI/180.0f)/GetTargetAngle();

}

bool Claw::IsShooting() const {
    if (m_shooterStates != SHOOTER_IDLE){
    	return true;
    }
    else{
    	return false;
    }
}

void Claw::ResetClawEncoder( long unsigned int interruptAssertedMask, void* obj ) {
    Claw* claw = static_cast<Claw*>(obj);

    if ( claw->GetTargetAngle() <= 0.0 ) {
        claw->m_clawRotator->resetPID();
        claw->m_clawRotator->resetEncoder();
        claw->m_clawRotator->setSetpoint( 0.f );
    }
}

void Claw::CloseClaw( long unsigned int interruptAssertedMask, void* obj ) {
    std::cout << "CloseClaw INTERRUPT\n";
    Claw* claw = static_cast<Claw*>(obj);

    if ( !claw->IsShooting() ) {
        claw->SetCollectorMode( false );
    }
}
<commit_msg>Enabled ball switch interrupts<commit_after>#include "Claw.hpp"

#ifndef M_PI
#define M_PI 3.14159265
#endif

#include <Solenoid.h>
#include <DriverStationLCD.h>

Claw::Claw(unsigned int clawRotatePort, unsigned int clawWheelPort,
        unsigned int zeroSwitchPort, unsigned int haveBallPort) :
        m_settings( "RobotSettings.txt" )
        {
    m_clawRotator = new GearBox<Talon>( 0 , 7 , 8 , clawRotatePort );
    m_intakeWheel = new GearBox<Talon>( 0 , 0 , 0 , clawWheelPort );

    // Sets degrees rotated per pulse of encoder
    m_clawRotator->setDistancePerPulse( (1.0/71.0f)*14.0 /44.0 );
    m_clawRotator->setReversed(true);

    m_ballShooter.push_back( new Solenoid( 1 ) );
    m_ballShooter.push_back( new Solenoid( 2 ) );
    m_ballShooter.push_back( new Solenoid( 3 ) );
    m_ballShooter.push_back( new Solenoid( 4 ) );

    m_zeroSwitch = new DigitalInput(zeroSwitchPort);
    m_haveBallSwitch = new DigitalInput(haveBallPort);

    // Set up interrupt for encoder reset
    m_zeroSwitch->RequestInterrupts( Claw::ResetClawEncoder , this );
    m_zeroSwitch->SetUpSourceEdge( true , true );
    m_zeroSwitch->EnableInterrupts();

    // Set up interrupt for catching ball
    m_haveBallSwitch->RequestInterrupts( Claw::CloseClaw , this );
    m_haveBallSwitch->SetUpSourceEdge( false , true );
    m_haveBallSwitch->EnableInterrupts();

    //magical values found using empirical testing don't change.
    setK(0.238f);
    m_l = 69.0f;

    m_collectorArm = new Solenoid(5);
    m_vacuum = new Solenoid (6);

    ReloadPID();
    m_shooterStates = SHOOTER_IDLE;
}

Claw::~Claw(){
    // Free solenoids
    for ( unsigned int i = 0 ; i < m_ballShooter.size() ; i++ ) {
        delete m_ballShooter[i];
    }

    delete m_collectorArm;

    m_zeroSwitch->DisableInterrupts();
    delete m_zeroSwitch;

    m_haveBallSwitch->DisableInterrupts();
    delete m_haveBallSwitch;

    delete m_vacuum;
    m_ballShooter.clear();
}

void Claw::SetAngle(float shooterAngle){
    m_clawRotator->setSetpoint( shooterAngle );
    m_setpoint = shooterAngle;
}

void Claw::ManualSetAngle(float value) {
	if((!m_zeroSwitch->Get() && value > 0) || m_zeroSwitch->Get())
	{
		m_clawRotator->setManual(value);

	}

}

double Claw::GetTargetAngle() const {
    return m_clawRotator->getSetpoint();
}

double Claw::GetAngle()
{
	return m_clawRotator->getDistance();

}

void Claw::SetWheelSetpoint( float speed ) {
    m_intakeWheel->setSetpoint( speed );
}

void Claw::SetWheelManual( float speed ) {
    m_intakeWheel->setManual( speed );
}

void Claw::ResetEncoders() {
    m_clawRotator->resetEncoder();
    m_intakeWheel->resetEncoder();
}

void Claw::ReloadPID() {
    m_settings.update();

    float p = 0.f;
    float i = 0.f;
    float d = 0.f;

    // Set shooter rotator PID
    p = atof( m_settings.getValueFor( "PID_ARM_ROTATE_P" ).c_str() );
    i = atof( m_settings.getValueFor( "PID_ARM_ROTATE_I" ).c_str() );
    d = atof( m_settings.getValueFor( "PID_ARM_ROTATE_D" ).c_str() );
    m_clawRotator->setPID( p , i , d );
}

void Claw::Shoot() {
	if (m_shooterStates == SHOOTER_IDLE){
		m_collectorArm->Set(true);
		m_shooterStates = SHOOTER_ARMISLIFTING;
		m_shootTimer.Start();
		m_shootTimer.Reset();
	}

}

void Claw::SetCollectorMode(bool collectorMode){
    m_collectorArm->Set(collectorMode);
}
bool Claw::GetCollectorMode(){
	return m_collectorArm->Get();
}

void Claw::Update() {
	if (m_shooterStates == SHOOTER_ARMISLIFTING && m_shootTimer.HasPeriodPassed(0.5)){
		for ( unsigned int i = 0 ; i < m_ballShooter.size() ; i++ ) {
		    m_ballShooter[i]->Set( true );
		}
		m_shootTimer.Reset();
		m_shooterStates = SHOOTER_SHOOTING;
	}
	if (m_shooterStates == SHOOTER_SHOOTING && m_shootTimer.HasPeriodPassed(2.0)){
		for ( unsigned int i = 0 ; i < m_ballShooter.size() ; i++ ) {
		     m_ballShooter[i]->Set( false );
		}
		m_vacuum->Set(true);
		m_shootTimer.Reset();
		m_shooterStates = SHOOTER_VACUUMING;
	}
	if (m_shooterStates == SHOOTER_VACUUMING && m_shootTimer.HasPeriodPassed(1.5)){
		m_vacuum->Set(false);
		m_collectorArm->Set (false);

		m_shootTimer.Reset();
		m_shooterStates = SHOOTER_IDLE;
	}

	setF(calcF());

	// Spins intake wheel to keep ball in while rotating claw at high speeds
	if ( fabs(m_clawRotator->getRate()) > 35.f ) {
        SetWheelManual( -1.f );
	}

	/* Fixes arm, when at reset angle, not touching zeroSwitch due to gradual
	 * encoder error. If limit switch isn't pressed but arm is supposedly at
	 * zeroing point or farther:
	 */
	if ( m_zeroSwitch->Get() && GetTargetAngle() <= 1.f &&
            m_clawRotator->onTarget() ) {
        m_clawRotator->setSetpoint( GetTargetAngle() - 5.f );
    }

    DriverStationLCD::GetInstance()->PrintfLine(DriverStationLCD::kUser_Line1, "Angle: %f", m_clawRotator->getDistance());
    DriverStationLCD::GetInstance()->PrintfLine(DriverStationLCD::kUser_Line2, "A Setpt: %f", GetTargetAngle());
    DriverStationLCD::GetInstance()->PrintfLine(DriverStationLCD::kUser_Line3, "Limit On: %u", !m_zeroSwitch->Get());
    DriverStationLCD::GetInstance()->PrintfLine(DriverStationLCD::kUser_Line4, "OnTarget: %u", static_cast<unsigned int>(m_clawRotator->onTarget()));
    DriverStationLCD::GetInstance()->PrintfLine(DriverStationLCD::kUser_Line5, "A Rate: %f", m_clawRotator->getRate());
    DriverStationLCD::GetInstance()->UpdateLCD();

}

void Claw::setF(float f)
{
	m_clawRotator->setF(f);

}

void Claw::setK(float k)
{
	m_k = k;

}

float Claw::calcF()
{
	if(GetTargetAngle() == 0)
	{
		return 0.0f;

	}

	return m_k*cos((GetAngle()+m_l)*M_PI/180.0f)/GetTargetAngle();

}

bool Claw::IsShooting() const {
    if (m_shooterStates != SHOOTER_IDLE){
    	return true;
    }
    else{
    	return false;
    }
}

void Claw::ResetClawEncoder( long unsigned int interruptAssertedMask, void* obj ) {
    Claw* claw = static_cast<Claw*>(obj);

    if ( claw->GetTargetAngle() <= 0.0 ) {
        claw->m_clawRotator->resetPID();
        claw->m_clawRotator->resetEncoder();
        claw->m_clawRotator->setSetpoint( 0.f );
    }
}

void Claw::CloseClaw( long unsigned int interruptAssertedMask, void* obj ) {
    std::cout << "CloseClaw INTERRUPT\n";
    Claw* claw = static_cast<Claw*>(obj);

    if ( !claw->IsShooting() ) {
        claw->SetCollectorMode( false );
    }
}
<|endoftext|>


<commit_before>// vim:filetype=cpp:textwidth=80:shiftwidth=2:softtabstop=2:expandtab
// Copyright 2014 schwering@kbsg.rwth-aachen.de

#include <cassert>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <map>
#include <random>
#include <string>
#include <sstream>
#include <vector>
#include <./formula.h>
#include <./maybe.h>

using namespace lela;

struct Point {
  Point() {}
  Point(size_t x, size_t y) : x(x), y(y) {}

  bool operator<(const Point& p) const {
    return x < p.x || (x == p.x && y < p.y);
  }

  std::set<Point> Neighbors() const {
    std::set<Point> s;
    s.insert(Point(x-1, y-1));
    s.insert(Point(x-1, y  ));
    s.insert(Point(x-1, y+1));
    s.insert(Point(x  , y-1));
    s.insert(Point(x  , y+1));
    s.insert(Point(x+1, y-1));
    s.insert(Point(x+1, y  ));
    s.insert(Point(x+1, y+1));
    return s;
  }

  size_t x;
  size_t y;
};

namespace util {

template<class T>
void Subsets(const typename std::set<T>::const_iterator first,
             const typename std::set<T>::const_iterator last,
             const size_t n,
             const std::set<T>& current,
             std::set<std::set<T>>& subsets) {
  if (current.size() == n) {
    subsets.insert(current);
    return;
  }
  if (first == last ||
      current.size() + static_cast<ssize_t>(std::distance(first, last)) < n) {
    return;
  }
  Subsets(std::next(first), last, n, current, subsets);
  std::set<T> current1 = current;
  current1.insert(*first);
  Subsets(std::next(first), last, n, current1, subsets);
}

template<class T>
std::set<std::set<T>> Subsets(const std::set<T>& s, size_t n) {
  std::set<std::set<T>> ss;
  Subsets(s.begin(), s.end(), n, {}, ss);
  return ss;
}

}  // namespace util

class Field {
 public:
  static constexpr int UNEXPLORED = -2;
  static constexpr int HIT_MINE = -1;

  Field(const size_t dimen, const size_t n_mines)
      : dimen_(dimen),
        distribution_(0, dimen_ - 1) {
    mines_.resize(dimen_ * dimen_, false);
    picks_.resize(dimen_ * dimen_, false);
    assert(mines_.size() == dimen_ * dimen_);
    assert(n_mines <= dimen_ * dimen_);
    for (n_mines_ = 0; n_mines_ < n_mines; ) {
      Point p;
      p.x = distribution_(generator_);
      p.y = distribution_(generator_);
      if (!mine(p)) {
        set_mine(p, true);
        ++n_mines_;
      }
    }
    assert(n_mines == n_mines_);
  }

  size_t dimension() const { return dimen_; }
  size_t n_mines() const { return n_mines_; }

  std::set<Point> NeighborsOf(Point p) const {
    return FilterNeighborsOf(p, [](const Point& p) { return true; });
  }

  template<class UnaryPredicate>
  std::set<Point> FilterNeighborsOf(Point p, UnaryPredicate pred) const {
    std::set<Point> s = p.Neighbors();
    for (auto it = s.begin(); it != s.end(); ) {
      if (!valid(*it) || !pred(*it)) {
        it = s.erase(it);
      } else {
        ++it;
      }
    }
    return s;
  }

  Point toPoint(size_t index) const {
    Point p(index / dimen_, index % dimen_);
    assert(dimen_ * p.x + p.y == index);
    return p;
  }

  bool valid(Point p) const {
    return p.x < dimen_ && p.y < dimen_;
  }

  void set_mine(Point p, bool is_mine) {
    assert(valid(p));
    mines_[dimen_ * p.x + p.y] = is_mine;
  }

  bool mine(Point p) const {
    assert(valid(p));
    return mines_[dimen_ * p.x + p.y];
  }

  bool picked(Point p) const {
    assert(valid(p));
    return picks_[dimen_ * p.x + p.y];
  }

  int PickRandom() {
    Point p;
    p.x = distribution_(generator_);
    p.y = distribution_(generator_);
    return Pick(p);
  }

  int Pick(Point p) {
    assert(!picked(p));
    picks_[dimen_ * p.x + p.y] = true;
    assert(picked(p));
    return state(p);
  }

  int PickWithFrontier(Point p) {
    int s = Pick(p);
    if (s == 0) {
      for (const Point q : NeighborsOf(p)) {
        if (!picked(q)) {
          PickWithFrontier(q);
        }
      }
    }
    return s;
  }

  int state(Point p) const {
    if (!picked(p)) {
      return UNEXPLORED;
    }
    if (mine(p)) {
      return HIT_MINE;
    }
    const Field* self = this;
    return FilterNeighborsOf(p, [self](const Point& q) { return self->mine(q); }).size();
  }

  bool all_explored() const {
    for (size_t x = 0; x < dimen_; ++x) {
      for (size_t y = 0; y < dimen_; ++y) {
        if (!picked(Point(x, y)) && !mine(Point(x, y))) {
          return false;
        }
      }
    }
    return true;
  }

 private:
  std::vector<bool> mines_;
  std::vector<bool> picks_;
  size_t dimen_;
  size_t n_mines_;
  std::default_random_engine generator_;
  std::uniform_int_distribution<size_t> distribution_;
};

class Printer {
 public:
  void Print(std::ostream& os, const Field& f) {
    const int width = 3;
    os << std::setw(width) << "";
    for (size_t x = 0; x < f.dimension(); ++x) {
      os << std::setw(width) << x;
    }
    os << std::endl;
    for (size_t y = 0; y < f.dimension(); ++y) {
      os << std::setw(width) << y;
      for (size_t x = 0; x < f.dimension(); ++x) {
        os << std::setw(width) << label(f, Point(x, y));
      }
      os << std::endl;
    }
  }

  virtual std::string label(const Field& f, Point p) = 0;
};

class OmniscientPrinter : public Printer {
 public:
  std::string label(const Field& f, Point p) {
    return f.mine(p) ? "X" : "";
  }
};

class SimplePrinter : public Printer {
 public:
  std::string label(const Field& f, Point p) override {
    switch (f.state(p)) {
      case Field::UNEXPLORED: return "";
      case Field::HIT_MINE:   return "X";
      case 0:                 return ".";
      default: {
        std::stringstream ss;
        ss << f.state(p);
        return ss.str();
      }
    }
  }
};

class SetupPrinter : public Printer {
 public:
  SetupPrinter(const Field* f) : f_(f) {
    processed_.resize(f_->dimension() * f_->dimension(), false);
  }

  Literal MineLit(bool is, Point p) {
    return Literal({}, is, p.x * f_->dimension() + p.y, {});
  }

  Clause MineClause(bool sign, const std::set<Point> ns) {
    SimpleClause c;
    for (const Point p : ns) {
      c.insert(MineLit(sign, p));
    }
    return Clause(Ewff::TRUE, c);
  }

  std::string label(const Field& f, Point p) override {
    assert(&f == f_);
    UpdateKb();
    switch (f.state(p)) {
      case Field::UNEXPLORED: {
        SimpleClause yes_mine({MineLit(true, p)});
        SimpleClause no_mine({MineLit(false, p)});
        for (Setup::split_level k = 0; k < 3; ++k) {
          if (s_.Entails(yes_mine, k)) {
            assert(f_->mine(p));
            return "X";
          } else if (s_.Entails(no_mine, k)) {
            assert(!f_->mine(p));
            return "$";
          }
        }
        return "";
      }
      case Field::HIT_MINE: {
        return "X";
      }
      default: {
        const int m = f.state(p);
        if (m == 0) {
          return ".";
        }
        std::stringstream ss;
        ss << m;
        return ss.str();
      }
    }
  }

  const Setup& setup() const { return s_; }

 private:
  void UpdateKb() {
    for (size_t index = 0; index < f_->dimension() * f_->dimension(); ++index) {
      if (!processed_[index]) {
        processed_[index] = UpdateKb(f_->toPoint(index));
      }
    }
  }

  bool UpdateKb(Point p) {
    const int m = f_->state(p);
    switch (m) {
      case Field::UNEXPLORED: {
        return false;
      }
      case Field::HIT_MINE: {
        s_.AddClause(Clause(Ewff::TRUE, {MineLit(true, p)}));
        return true;
      }
      default: {
        std::set<Point> ns = f_->NeighborsOf(p);
        const int n = ns.size();
        //std::cerr << "n = " << n << ", m = " << m << std::endl;
        for (const std::set<Point>& ps : util::Subsets(ns, n - m + 1)) {
          s_.AddClause(MineClause(true, ps));
        }
        for (const std::set<Point>& ps : util::Subsets(ns, m + 1)) {
          s_.AddClause(MineClause(false, ps));
        }
        s_.AddClause(Clause(Ewff::TRUE, {MineLit(false, p)}));
        return true;
      }
    }
  }

  const Field* f_;
  Setup s_;
  std::vector<bool> processed_;
};

int main(int argc, char *argv[]) {
  size_t dimen = 9;
  size_t n_mines = 10;
  if (argc >= 2) {
    dimen = atoi(argv[1]);
    n_mines = dimen + 1;
  }
  if (argc >= 3) {
    n_mines = atoi(argv[2]);
  }
  Field f(dimen, n_mines);
  SetupPrinter printer(&f);
  printer.Print(std::cout, f);
  std::cout << std::endl;
  std::cout << std::endl;
  if (argv[argc - 1] == std::string("play")) {
    int s;
    do {
      Point p;
      std::cout << "X and Y coordinates: ";
      std::cin >> p.x >> p.y;
      if (!f.valid(p) && f.picked(p)) {
        std::cout << "Invalid coordinates, repeat" << std::endl;
        continue;
      }
      s = f.PickWithFrontier(p);
      printer.Print(std::cout, f);
      std::cout << std::endl;
      std::cout << std::endl;
    } while (s != Field::HIT_MINE && !f.all_explored());
    OmniscientPrinter().Print(std::cout, f);
    std::cout << std::endl;
    std::cout << std::endl;
    if (s == Field::HIT_MINE) {
      std::cout << "You loose :-(" << std::endl;
    } else {
      std::cout << "You win :-)" << std::endl;
    }
  }
  return 0;
}

#if 0
class MwBat : public Bat {
 public:
  virtual Maybe<Formula::ObjPtr> RegressOneStep(const Atom& a) = 0;

  void GuaranteeConsistency(split_level k) override {
    s_.GuaranteeConsistency(k);
  }

  void AddClause(const Clause& c) override {
    s_.AddClause(c);
    names_init_ = false;
  }

  bool InconsistentAt(belief_level p, split_level k) const override {
    assert(p == 0);
    return s_.Inconsistent(k);
  }

  bool EntailsClauseAt(belief_level p,
                       const SimpleClause& c,
                       split_level k) const override {
    assert(p == 0);
    return s_.Entails(c, k);
  }

  size_t n_levels() const override { return 1; }

  const StdName::SortedSet& names() const override {
    if (!names_init_) {
      names_ = s_.hplus().WithoutPlaceholders();
      names_init_ = true;
    }
    return names_;
  }

 private:
  Setup s_;
  mutable StdName::SortedSet names_;
  mutable bool names_init_ = false;
};
#endif

<commit_msg>Minesweeper now has colorful output.<commit_after>// vim:filetype=cpp:textwidth=80:shiftwidth=2:softtabstop=2:expandtab
// Copyright 2014 schwering@kbsg.rwth-aachen.de

#include <cassert>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <map>
#include <random>
#include <string>
#include <sstream>
#include <vector>
#include <./formula.h>
#include <./maybe.h>

using namespace lela;

struct Point {
  Point() {}
  Point(size_t x, size_t y) : x(x), y(y) {}

  bool operator<(const Point& p) const {
    return x < p.x || (x == p.x && y < p.y);
  }

  std::set<Point> Neighbors() const {
    std::set<Point> s;
    s.insert(Point(x-1, y-1));
    s.insert(Point(x-1, y  ));
    s.insert(Point(x-1, y+1));
    s.insert(Point(x  , y-1));
    s.insert(Point(x  , y+1));
    s.insert(Point(x+1, y-1));
    s.insert(Point(x+1, y  ));
    s.insert(Point(x+1, y+1));
    return s;
  }

  size_t x;
  size_t y;
};

namespace util {

template<class T>
void Subsets(const typename std::set<T>::const_iterator first,
             const typename std::set<T>::const_iterator last,
             const size_t n,
             const std::set<T>& current,
             std::set<std::set<T>>& subsets) {
  if (current.size() == n) {
    subsets.insert(current);
    return;
  }
  if (first == last ||
      current.size() + static_cast<ssize_t>(std::distance(first, last)) < n) {
    return;
  }
  Subsets(std::next(first), last, n, current, subsets);
  std::set<T> current1 = current;
  current1.insert(*first);
  Subsets(std::next(first), last, n, current1, subsets);
}

template<class T>
std::set<std::set<T>> Subsets(const std::set<T>& s, size_t n) {
  std::set<std::set<T>> ss;
  Subsets(s.begin(), s.end(), n, {}, ss);
  return ss;
}

}  // namespace util

class Field {
 public:
  static constexpr int UNEXPLORED = -2;
  static constexpr int HIT_MINE = -1;

  Field(const size_t dimen, const size_t n_mines)
      : dimen_(dimen),
        distribution_(0, dimen_ - 1) {
    mines_.resize(dimen_ * dimen_, false);
    picks_.resize(dimen_ * dimen_, false);
    assert(mines_.size() == dimen_ * dimen_);
    assert(n_mines <= dimen_ * dimen_);
    for (n_mines_ = 0; n_mines_ < n_mines; ) {
      Point p;
      p.x = distribution_(generator_);
      p.y = distribution_(generator_);
      if (!mine(p)) {
        set_mine(p, true);
        ++n_mines_;
      }
    }
    assert(n_mines == n_mines_);
  }

  size_t dimension() const { return dimen_; }
  size_t n_mines() const { return n_mines_; }

  std::set<Point> NeighborsOf(Point p) const {
    return FilterNeighborsOf(p, [](const Point& p) { return true; });
  }

  template<class UnaryPredicate>
  std::set<Point> FilterNeighborsOf(Point p, UnaryPredicate pred) const {
    std::set<Point> s = p.Neighbors();
    for (auto it = s.begin(); it != s.end(); ) {
      if (!valid(*it) || !pred(*it)) {
        it = s.erase(it);
      } else {
        ++it;
      }
    }
    return s;
  }

  Point toPoint(size_t index) const {
    Point p(index / dimen_, index % dimen_);
    assert(dimen_ * p.x + p.y == index);
    return p;
  }

  bool valid(Point p) const {
    return p.x < dimen_ && p.y < dimen_;
  }

  void set_mine(Point p, bool is_mine) {
    assert(valid(p));
    mines_[dimen_ * p.x + p.y] = is_mine;
  }

  bool mine(Point p) const {
    assert(valid(p));
    return mines_[dimen_ * p.x + p.y];
  }

  bool picked(Point p) const {
    assert(valid(p));
    return picks_[dimen_ * p.x + p.y];
  }

  int PickRandom() {
    Point p;
    p.x = distribution_(generator_);
    p.y = distribution_(generator_);
    return Pick(p);
  }

  int Pick(Point p) {
    assert(!picked(p));
    picks_[dimen_ * p.x + p.y] = true;
    assert(picked(p));
    return state(p);
  }

  int PickWithFrontier(Point p) {
    int s = Pick(p);
    if (s == 0) {
      for (const Point q : NeighborsOf(p)) {
        if (!picked(q)) {
          PickWithFrontier(q);
        }
      }
    }
    return s;
  }

  int state(Point p) const {
    if (!picked(p)) {
      return UNEXPLORED;
    }
    if (mine(p)) {
      return HIT_MINE;
    }
    const Field* self = this;
    return FilterNeighborsOf(p, [self](const Point& q) { return self->mine(q); }).size();
  }

  bool all_explored() const {
    for (size_t x = 0; x < dimen_; ++x) {
      for (size_t y = 0; y < dimen_; ++y) {
        if (!picked(Point(x, y)) && !mine(Point(x, y))) {
          return false;
        }
      }
    }
    return true;
  }

 private:
  std::vector<bool> mines_;
  std::vector<bool> picks_;
  size_t dimen_;
  size_t n_mines_;
  std::default_random_engine generator_;
  std::uniform_int_distribution<size_t> distribution_;
};

class Printer {
 public:
  static constexpr int RESET = 0;
  static constexpr int BRIGHT = 1;
  static constexpr int DIM = 2;
  static constexpr int BLACK = 30;
  static constexpr int RED = 31;
  static constexpr int GREEN = 32;

  void Print(std::ostream& os, const Field& f) {
    const int width = 3;
    os << std::setw(width) << "";
    for (size_t x = 0; x < f.dimension(); ++x) {
      os << std::setw(width) << x;
    }
    os << std::endl;
    for (size_t y = 0; y < f.dimension(); ++y) {
      os << std::setw(width) << y;
      for (size_t x = 0; x < f.dimension(); ++x) {
        std::pair<int, std::string> l = label(f, Point(x, y));
        os << "\033[" << l.first << "m" << std::setw(width) << l.second << "\033[0m";
      }
      os << std::endl;
    }
  }

  virtual std::pair<int, std::string> label(const Field&, Point) = 0;
};

class OmniscientPrinter : public Printer {
 public:
  std::pair<int, std::string> label(const Field& f, Point p) {
    return f.mine(p) ? std::make_pair(RED, "X") : std::make_pair(RESET, "");
  }
};

class SimplePrinter : public Printer {
 public:
  std::pair<int, std::string> label(const Field& f, Point p) override {
    switch (f.state(p)) {
      case Field::UNEXPLORED: return std::make_pair(RESET, "");
      case Field::HIT_MINE:   return std::make_pair(RED, "X");
      case 0:                 return std::make_pair(DIM, ".");
      default: {
        std::stringstream ss;
        ss << f.state(p);
        return std::make_pair(RESET, ss.str());
      }
    }
  }
};

class SetupPrinter : public Printer {
 public:
  SetupPrinter(const Field* f) : f_(f) {
    processed_.resize(f_->dimension() * f_->dimension(), false);
  }

  Literal MineLit(bool is, Point p) {
    return Literal({}, is, p.x * f_->dimension() + p.y, {});
  }

  Clause MineClause(bool sign, const std::set<Point> ns) {
    SimpleClause c;
    for (const Point p : ns) {
      c.insert(MineLit(sign, p));
    }
    return Clause(Ewff::TRUE, c);
  }

  std::pair<int, std::string> label(const Field& f, Point p) override {
    assert(&f == f_);
    UpdateKb();
    switch (f.state(p)) {
      case Field::UNEXPLORED: {
        SimpleClause yes_mine({MineLit(true, p)});
        SimpleClause no_mine({MineLit(false, p)});
        for (Setup::split_level k = 0; k < 2; ++k) {
          if (s_.Entails(yes_mine, k)) {
            assert(f_->mine(p));
            return std::make_pair(RED, "X");
          } else if (s_.Entails(no_mine, k)) {
            assert(!f_->mine(p));
            return std::make_pair(GREEN, "$");
          }
        }
        return std::make_pair(RESET, "");
      }
      case Field::HIT_MINE: {
        return std::make_pair(RED, "X");
      }
      default: {
        const int m = f.state(p);
        if (m == 0) {
          return std::make_pair(DIM, ".");
        }
        std::stringstream ss;
        ss << m;
        return std::make_pair(RESET, ss.str());
      }
    }
  }

  const Setup& setup() const { return s_; }

 private:
  void UpdateKb() {
    for (size_t index = 0; index < f_->dimension() * f_->dimension(); ++index) {
      if (!processed_[index]) {
        processed_[index] = UpdateKb(f_->toPoint(index));
      }
    }
  }

  bool UpdateKb(Point p) {
    const int m = f_->state(p);
    switch (m) {
      case Field::UNEXPLORED: {
        return false;
      }
      case Field::HIT_MINE: {
        s_.AddClause(Clause(Ewff::TRUE, {MineLit(true, p)}));
        return true;
      }
      default: {
        std::set<Point> ns = f_->NeighborsOf(p);
        const int n = ns.size();
        //std::cerr << "n = " << n << ", m = " << m << std::endl;
        for (const std::set<Point>& ps : util::Subsets(ns, n - m + 1)) {
          s_.AddClause(MineClause(true, ps));
        }
        for (const std::set<Point>& ps : util::Subsets(ns, m + 1)) {
          s_.AddClause(MineClause(false, ps));
        }
        s_.AddClause(Clause(Ewff::TRUE, {MineLit(false, p)}));
        return true;
      }
    }
  }

  const Field* f_;
  Setup s_;
  std::vector<bool> processed_;
};

int main(int argc, char *argv[]) {
  size_t dimen = 9;
  size_t n_mines = 10;
  if (argc >= 2) {
    dimen = atoi(argv[1]);
    n_mines = dimen + 1;
  }
  if (argc >= 3) {
    n_mines = atoi(argv[2]);
  }
  Field f(dimen, n_mines);
  SetupPrinter printer(&f);
  printer.Print(std::cout, f);
  std::cout << std::endl;
  std::cout << std::endl;
  if (argv[argc - 1] == std::string("play")) {
    int s;
    do {
      Point p;
      std::cout << "X and Y coordinates: ";
      std::cin >> p.x >> p.y;
      if (!f.valid(p) && f.picked(p)) {
        std::cout << "Invalid coordinates, repeat" << std::endl;
        continue;
      }
      s = f.PickWithFrontier(p);
      printer.Print(std::cout, f);
      std::cout << std::endl;
      std::cout << std::endl;
    } while (s != Field::HIT_MINE && !f.all_explored());
    OmniscientPrinter().Print(std::cout, f);
    std::cout << std::endl;
    std::cout << std::endl;
    if (s == Field::HIT_MINE) {
      std::cout << "You loose :-(" << std::endl;
    } else {
      std::cout << "You win :-)" << std::endl;
    }
  }
  return 0;
}

#if 0
class MwBat : public Bat {
 public:
  virtual Maybe<Formula::ObjPtr> RegressOneStep(const Atom& a) = 0;

  void GuaranteeConsistency(split_level k) override {
    s_.GuaranteeConsistency(k);
  }

  void AddClause(const Clause& c) override {
    s_.AddClause(c);
    names_init_ = false;
  }

  bool InconsistentAt(belief_level p, split_level k) const override {
    assert(p == 0);
    return s_.Inconsistent(k);
  }

  bool EntailsClauseAt(belief_level p,
                       const SimpleClause& c,
                       split_level k) const override {
    assert(p == 0);
    return s_.Entails(c, k);
  }

  size_t n_levels() const override { return 1; }

  const StdName::SortedSet& names() const override {
    if (!names_init_) {
      names_ = s_.hplus().WithoutPlaceholders();
      names_init_ = true;
    }
    return names_;
  }

 private:
  Setup s_;
  mutable StdName::SortedSet names_;
  mutable bool names_init_ = false;
};
#endif

<|endoftext|>


<commit_before>#include "BigFix/Error.h"
#include "BigFix/DataRef.h"
#include "BigFix/Number.h"
#include <gtest/gtest.h>

using namespace BigFix;

TEST( NumberTest, Read4ByteIntger )
{
  uint8_t number[4] = { 0x01, 0x02, 0x03, 0x04 };

  EXPECT_EQ( 67305985, ReadLittleEndian( DataRef( number, number + 4 ) ) );
}

TEST( NumberTest, Read8ByteIntger )
{
  uint8_t number[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };

  EXPECT_EQ( 578437695752307201,
             ReadLittleEndian( DataRef( number, number + 8 ) ) );
}

TEST( NumberTest, Write4ByteInteger )
{
  uint8_t number[4];
  WriteLittleEndian( 67305985, number, 4 );

  EXPECT_EQ( 1, number[0] );
  EXPECT_EQ( 2, number[1] );
  EXPECT_EQ( 3, number[2] );
  EXPECT_EQ( 4, number[3] );
}

TEST( NumberTest, Write8ByteInteger )
{
  uint8_t number[8];
  WriteLittleEndian( 578437695752307201, number, 8 );

  EXPECT_EQ( 1, number[0] );
  EXPECT_EQ( 2, number[1] );
  EXPECT_EQ( 3, number[2] );
  EXPECT_EQ( 4, number[3] );
  EXPECT_EQ( 5, number[4] );
  EXPECT_EQ( 6, number[5] );
  EXPECT_EQ( 7, number[6] );
  EXPECT_EQ( 8, number[7] );
}
<commit_msg>Add tests for ReadAsciiNumber<commit_after>#include "BigFix/Error.h"
#include "BigFix/DataRef.h"
#include "BigFix/Number.h"
#include <gtest/gtest.h>

using namespace BigFix;

TEST( NumberTest, Read4ByteIntger )
{
  uint8_t number[4] = { 0x01, 0x02, 0x03, 0x04 };

  EXPECT_EQ( 67305985, ReadLittleEndian( DataRef( number, number + 4 ) ) );
}

TEST( NumberTest, Read8ByteIntger )
{
  uint8_t number[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };

  EXPECT_EQ( 578437695752307201,
             ReadLittleEndian( DataRef( number, number + 8 ) ) );
}

TEST( NumberTest, Write4ByteInteger )
{
  uint8_t number[4];
  WriteLittleEndian( 67305985, number, 4 );

  EXPECT_EQ( 1, number[0] );
  EXPECT_EQ( 2, number[1] );
  EXPECT_EQ( 3, number[2] );
  EXPECT_EQ( 4, number[3] );
}

TEST( NumberTest, Write8ByteInteger )
{
  uint8_t number[8];
  WriteLittleEndian( 578437695752307201, number, 8 );

  EXPECT_EQ( 1, number[0] );
  EXPECT_EQ( 2, number[1] );
  EXPECT_EQ( 3, number[2] );
  EXPECT_EQ( 4, number[3] );
  EXPECT_EQ( 5, number[4] );
  EXPECT_EQ( 6, number[5] );
  EXPECT_EQ( 7, number[6] );
  EXPECT_EQ( 8, number[7] );
}

TEST( NumberTest, ReadAsciiNumber )
{
  EXPECT_EQ( 42, ReadAsciiNumber<uint8_t>( DataRef( "42" ) ) );
  EXPECT_EQ( 1970, ReadAsciiNumber<int32_t>( DataRef( "1970" ) ) );
  EXPECT_THROW( ReadAsciiNumber<uint8_t>( DataRef( "hello" ) ), Error );
}
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright RTK Consortium
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/

#ifndef rtkImportImageFilter_hxx
#define rtkImportImageFilter_hxx

#include "rtkImportImageFilter.h"
#include "itkObjectFactory.h"

namespace rtk
{
/**
 *
 */
template< typename TImage >
ImportImageFilter< TImage >
::ImportImageFilter()
{
  unsigned int idx;

  for ( idx = 0; idx < TImage::ImageDimension; ++idx )
    {
    m_Spacing[idx] = 1.0;
    m_Origin[idx] = 0.0;
    }
  m_Direction.SetIdentity();

  m_ImportPointer = ITK_NULLPTR;
  m_FilterManageMemory = false;
  m_Size = 0;
}

/**
 *
 */
template< typename TImage >
ImportImageFilter< TImage >
::~ImportImageFilter()
{
  if ( m_ImportPointer && m_FilterManageMemory )
    {
    delete[] m_ImportPointer;
    }
}

/**
 *
 */
template< typename TImage >
void
ImportImageFilter< TImage >
::PrintSelf(std::ostream & os, itk::Indent indent) const
{
  int i;

  this->Superclass::PrintSelf(os, indent);

  if ( m_ImportPointer )
    {
    os << indent << "Imported pointer: (" << m_ImportPointer  << ")" << std::endl;
    }
  else
    {
    os << indent << "Imported pointer: (None)" << std::endl;
    }
  os << indent << "Import buffer size: " << m_Size << std::endl;
  os << indent << "Import buffer size: " << m_Size << std::endl;
  os << indent << "Filter manages memory: " << ( m_FilterManageMemory ? "true" : "false" ) << std::endl;

  os << indent << "Spacing: [";
  for ( i = 0; i < static_cast< int >( TImage::ImageDimension ) - 1; i++ )
    {
    os << m_Spacing[i] << ", ";
    }
  os << m_Spacing[i] << "]" << std::endl;

  os << indent << "Origin: [";
  for ( i = 0; i < static_cast< int >( TImage::ImageDimension ) - 1; i++ )
    {
    os << m_Origin[i] << ", ";
    }
  os << m_Origin[i] << "]" << std::endl;
  os << indent << "Direction: " << std::endl << this->GetDirection() << std::endl;
}

/**
 *
 */
template< typename TImage >
void
ImportImageFilter< TImage >
::SetImportPointer(PixelType *ptr, SizeValueType num, bool LetFilterManageMemory)
{
  if ( ptr != m_ImportPointer )
    {
    if ( m_ImportPointer && m_FilterManageMemory )
      {
      delete[] m_ImportPointer;
      }
    m_ImportPointer = ptr;
    this->Modified();
    }
  m_FilterManageMemory = LetFilterManageMemory;
  m_Size = num;
}

/**
 *
 */
template< typename TImage >
typename TImage::PixelType *
ImportImageFilter< TImage >
::GetImportPointer()
{
  return m_ImportPointer;
}

/**
 *
 */
template< typename TImage >
void
ImportImageFilter< TImage >
::EnlargeOutputRequestedRegion(itk::DataObject *output)
{
  // call the superclass' implementation of this method
  Superclass::EnlargeOutputRequestedRegion(output);

  // get pointer to the output
  OutputImagePointer outputPtr = this->GetOutput();

  // set the requested region to the largest possible region (in this case
  // the amount of data that we have)
  outputPtr->SetRequestedRegion( outputPtr->GetLargestPossibleRegion() );
}

/**
 *
 */
template< typename TImage >
void
ImportImageFilter< TImage >
::GenerateOutputInformation()
{
  // call the superclass' implementation of this method
  Superclass::GenerateOutputInformation();

  // get pointer to the output
  OutputImagePointer outputPtr = this->GetOutput();

  // we need to compute the output spacing, the output origin, the
  // output image size, and the output image start index
  outputPtr->SetSpacing(m_Spacing);
  outputPtr->SetOrigin(m_Origin);
  outputPtr->SetDirection(m_Direction);
  outputPtr->SetLargestPossibleRegion(m_Region);
}

/**
 *
 */
template< typename TImage >
void
ImportImageFilter< TImage >
::GenerateData()
{
  // Normally, GenerateData() allocates memory.  However, the application
  // provides the memory for this filter via the SetImportPointer() method.
  // Therefore, this filter does not call outputPtr->Allocate().

  // get pointer to the output
  OutputImagePointer outputPtr = this->GetOutput();

  // the output buffer size is set to the size specified by the user via the
  // SetRegion() method.
  outputPtr->SetBufferedRegion( outputPtr->GetLargestPossibleRegion() );

  // pass the pointer down to the container during each Update() since
  // a call to Initialize() causes the container to forget the
  // pointer.  Note that we tell the container NOT to manage the
  // memory itself.  This filter will properly manage the memory (as
  // opposed to the container) if the user wants it to.
  outputPtr->GetPixelContainer()->SetImportPointer(m_ImportPointer,
                                                   m_Size, false);
}

//----------------------------------------------------------------------------
template< typename TImage >
void
ImportImageFilter< TImage >
::SetDirection(const DirectionType & direction)
{
  bool modified = false;

  for ( unsigned int r = 0; r < TImage::ImageDimension; r++ )
    {
    for ( unsigned int c = 0; c < TImage::ImageDimension; c++ )
      {
      if ( m_Direction[r][c] != direction[r][c] )
        {
        m_Direction[r][c] = direction[r][c];
        modified = true;
        }
      }
    }
  if ( modified )
    {
    this->Modified();
    }
}
} // end namespace itk

#endif
<commit_msg>Fixed bug in rtkImportImageFilter: the CudaImageDataManager did not correctly allocate the GPU buffer<commit_after>/*=========================================================================
 *
 *  Copyright RTK Consortium
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/

#ifndef rtkImportImageFilter_hxx
#define rtkImportImageFilter_hxx

#include "rtkImportImageFilter.h"
#include "itkObjectFactory.h"

namespace rtk
{
/**
 *
 */
template< typename TImage >
ImportImageFilter< TImage >
::ImportImageFilter()
{
  unsigned int idx;

  for ( idx = 0; idx < TImage::ImageDimension; ++idx )
    {
    m_Spacing[idx] = 1.0;
    m_Origin[idx] = 0.0;
    }
  m_Direction.SetIdentity();

  m_ImportPointer = ITK_NULLPTR;
  m_FilterManageMemory = false;
  m_Size = 0;
}

/**
 *
 */
template< typename TImage >
ImportImageFilter< TImage >
::~ImportImageFilter()
{
  if ( m_ImportPointer && m_FilterManageMemory )
    {
    delete[] m_ImportPointer;
    }
}

/**
 *
 */
template< typename TImage >
void
ImportImageFilter< TImage >
::PrintSelf(std::ostream & os, itk::Indent indent) const
{
  int i;

  this->Superclass::PrintSelf(os, indent);

  if ( m_ImportPointer )
    {
    os << indent << "Imported pointer: (" << m_ImportPointer  << ")" << std::endl;
    }
  else
    {
    os << indent << "Imported pointer: (None)" << std::endl;
    }
  os << indent << "Import buffer size: " << m_Size << std::endl;
  os << indent << "Import buffer size: " << m_Size << std::endl;
  os << indent << "Filter manages memory: " << ( m_FilterManageMemory ? "true" : "false" ) << std::endl;

  os << indent << "Spacing: [";
  for ( i = 0; i < static_cast< int >( TImage::ImageDimension ) - 1; i++ )
    {
    os << m_Spacing[i] << ", ";
    }
  os << m_Spacing[i] << "]" << std::endl;

  os << indent << "Origin: [";
  for ( i = 0; i < static_cast< int >( TImage::ImageDimension ) - 1; i++ )
    {
    os << m_Origin[i] << ", ";
    }
  os << m_Origin[i] << "]" << std::endl;
  os << indent << "Direction: " << std::endl << this->GetDirection() << std::endl;
}

/**
 *
 */
template< typename TImage >
void
ImportImageFilter< TImage >
::SetImportPointer(PixelType *ptr, SizeValueType num, bool LetFilterManageMemory)
{
  if ( ptr != m_ImportPointer )
    {
    if ( m_ImportPointer && m_FilterManageMemory )
      {
      delete[] m_ImportPointer;
      }
    m_ImportPointer = ptr;
    this->Modified();
    }
  m_FilterManageMemory = LetFilterManageMemory;
  m_Size = num;
}

/**
 *
 */
template< typename TImage >
typename TImage::PixelType *
ImportImageFilter< TImage >
::GetImportPointer()
{
  return m_ImportPointer;
}

/**
 *
 */
template< typename TImage >
void
ImportImageFilter< TImage >
::EnlargeOutputRequestedRegion(itk::DataObject *output)
{
  // call the superclass' implementation of this method
  Superclass::EnlargeOutputRequestedRegion(output);

  // get pointer to the output
  OutputImagePointer outputPtr = this->GetOutput();

  // set the requested region to the largest possible region (in this case
  // the amount of data that we have)
  outputPtr->SetRequestedRegion( outputPtr->GetLargestPossibleRegion() );
}

/**
 *
 */
template< typename TImage >
void
ImportImageFilter< TImage >
::GenerateOutputInformation()
{
  // call the superclass' implementation of this method
  Superclass::GenerateOutputInformation();

  // get pointer to the output
  OutputImagePointer outputPtr = this->GetOutput();

  // we need to compute the output spacing, the output origin, the
  // output image size, and the output image start index
  outputPtr->SetSpacing(m_Spacing);
  outputPtr->SetOrigin(m_Origin);
  outputPtr->SetDirection(m_Direction);
  outputPtr->SetLargestPossibleRegion(m_Region);
}

/**
 *
 */
template< typename TImage >
void
ImportImageFilter< TImage >
::GenerateData()
{
  // Normally, GenerateData() allocates memory.  However, the application
  // provides the memory for this filter via the SetImportPointer() method.
  // Therefore, this filter does not call outputPtr->Allocate().

  // get pointer to the output
  OutputImagePointer outputPtr = this->GetOutput();

  // the output buffer size is set to the size specified by the user via the
  // SetRegion() method.
  outputPtr->SetBufferedRegion( outputPtr->GetLargestPossibleRegion() );

  // pass the pointer down to the container during each Update() since
  // a call to Initialize() causes the container to forget the
  // pointer.  Note that we tell the container NOT to manage the
  // memory itself.  This filter will properly manage the memory (as
  // opposed to the container) if the user wants it to.
  outputPtr->GetPixelContainer()->SetImportPointer(m_ImportPointer,
                                                   m_Size, false);

#ifdef RTK_USE_CUDA
  typedef itk::CudaImage<typename TImage::PixelType, TImage::ImageDimension> TCudaImage;
  if (TCudaImage* cudaOutputPtr = dynamic_cast<TCudaImage*>(outputPtr.GetPointer()))
    {
    cudaOutputPtr->GetDataManager()->SetBufferSize(m_Size * sizeof(typename OutputImageType::PixelType));
    cudaOutputPtr->GetDataManager()->SetImagePointer(outputPtr);
    cudaOutputPtr->GetDataManager()->SetCPUBufferPointer(m_ImportPointer);
    cudaOutputPtr->GetDataManager()->SetGPUDirtyFlag(true);
    cudaOutputPtr->GetDataManager()->SetCPUDirtyFlag(false);
    cudaOutputPtr->GetDataManager()->SetTimeStamp(outputPtr->GetPixelContainer()->GetTimeStamp());
    }
#endif
}

//----------------------------------------------------------------------------
template< typename TImage >
void
ImportImageFilter< TImage >
::SetDirection(const DirectionType & direction)
{
  bool modified = false;

  for ( unsigned int r = 0; r < TImage::ImageDimension; r++ )
    {
    for ( unsigned int c = 0; c < TImage::ImageDimension; c++ )
      {
      if ( m_Direction[r][c] != direction[r][c] )
        {
        m_Direction[r][c] = direction[r][c];
        modified = true;
        }
      }
    }
  if ( modified )
    {
    this->Modified();
    }
}
} // end namespace itk

#endif
<|endoftext|>


<commit_before>#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <cstring>
#include <iostream>

extern "C" struct sockaddr_in;

using namespace std;

int main(int argc, char *argv[])
{
	int sockfd;
	struct sockaddr_in my_addr;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (errno) {
		cerr << "Failed to call socket()" << endl;
		exit(1);
	}

	my_addr.sin_family = AF_INET; // AF_INET means we want to send stuff via IP
	my_addr.sin_port = 0; // Choose the port automatically
	my_addr.sin_addr.s_addr = INADDR_ANY; // Choose this machine's IP address
	memset(&(my_addr.sin_zero), 0x00, 8);

	bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
	return 0;
}
<commit_msg>timefetch: finish adding socket code, work on getting the server's response<commit_after>#include <arpa/inet.h>

#include <sys/socket.h>
#include <sys/types.h>

#include <netdb.h>
#include <unistd.h>

#include <cstring>
#include <iostream>

extern "C" {
	struct sockaddr_in;
	struct addrinfo;

	typedef struct {

		unsigned li   : 2;       // Only two bits. Leap indicator.
		unsigned vn   : 3;       // Only three bits. Version number of the protocol.
		unsigned mode : 3;       // Only three bits. Mode. Client will pick mode 3 for client.

		uint8_t stratum;         // Eight bits. Stratum level of the local clock.
		uint8_t poll;            // Eight bits. Maximum interval between successive messages.
		uint8_t precision;       // Eight bits. Precision of the local clock.

		uint32_t rootDelay;      // 32 bits. Total round trip delay time.
		uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source.
		uint32_t refId;          // 32 bits. Reference clock identifier.

		uint32_t refTm_s;        // 32 bits. Reference time-stamp seconds.
		uint32_t refTm_f;        // 32 bits. Reference time-stamp fraction of a second.

		uint32_t origTm_s;       // 32 bits. Originate time-stamp seconds.
		uint32_t origTm_f;       // 32 bits. Originate time-stamp fraction of a second.

		uint32_t rxTm_s;         // 32 bits. Received time-stamp seconds.
		uint32_t rxTm_f;         // 32 bits. Received time-stamp fraction of a second.

		uint32_t txTm_s;         // 32 bits and the most important field the client cares about. Transmit time-stamp seconds.
		uint32_t txTm_f;         // 32 bits. Transmit time-stamp fraction of a second.

	} ntp_packet;              // Total: 384 bits or 48 bytes.
};

using namespace std;

int main(int argc, char *argv[])
{
	int sockfd, retval = 0;
	ssize_t sendto_retval, recv_retval;

	string address;

	ntp_packet packet = {};
	packet.vn = 3;
	packet.mode = 3;

	struct addrinfo *result, *resp_node;

	struct addrinfo hints = {};
	hints.ai_family = AF_UNSPEC; // IPv4 and v6 are allowed
	hints.ai_socktype = SOCK_DGRAM;

	if (argc != 2) {
		address = "pool.ntp.org";
		cerr << "Wrong number of arguments, using the default server "
		     << '"' << address << '"' << endl;
	} else {
		address = argv[1];
	}

	if (int e = getaddrinfo(address.c_str(), "123", &hints, &result)) {
		cerr << "getaddrinfo() failed with" << e << endl;
		exit(1);
	}

	for (resp_node = result; resp_node != nullptr; resp_node = resp_node->ai_next) {
		sockfd = socket(resp_node->ai_family, resp_node->ai_socktype, resp_node->ai_protocol);

		if (sockfd == -1)
			continue;

		if (connect(sockfd, resp_node->ai_addr, resp_node->ai_addrlen) == 0)
			break;

		close(sockfd);
	}

	if (resp_node == nullptr) {
		cerr << "Could not connect() to any of the results" << endl;
		exit(1);
	}

	struct sockaddr_in *addr = (sockaddr_in *)resp_node->ai_addr;
	cout << "Connected to " << inet_ntoa(addr->sin_addr) << endl;

	sendto_retval = send(sockfd, &packet, sizeof(packet), 0);
	if (sendto_retval != -1) {
		cout << "Successfuly sent " << sendto_retval << " bytes"
		     << endl;
	} else {
		cerr << "Failed to send the NTP packet" << endl;
		cerr << "Errno: " << gai_strerror(errno) << endl;
		retval = 1;
		goto fini;
	}

	recv_retval = recv(sockfd, &packet, sizeof(packet), 0);
	if (recv_retval != -1) {
		cout << "Successfuly received " << recv_retval << " bytes"
		     << endl;
	} else {
		cerr << "Failed to receive the NTP packet" << endl;
		retval = 1;
		goto fini;
	}

fini:
	close(sockfd);

	return retval;
}
<|endoftext|>


<commit_before>#include <libport/unit-test.hh>
#include <libport/sysexits.hh>
using libport::test_suite;

#ifndef LIBPORT_NO_SSL
# define LIBPORT_NO_SSL
#endif

#include <libport/asio.hh>
#include <libport/utime.hh>
#include <libport/unistd.h>

bool abort_ctor = false;

const char* msg = "coincoin\n";

// On OSX:
//   listen            connect        status
// "127.0.0.1"       "127.0.0.1"       PASS
// "localhost"       "localhost"       PASS
// ""                "localhost"       PASS
// ""                "127.0.0.1"       FAIL
static const char* listen_host = "";
static const char* connect_host = "localhost";

template<class T>
void
hold_for(T, libport::utime_t duration)
{
  usleep(duration);
  BOOST_TEST_MESSAGE("Done holding your T");
}

void
delayed_response(boost::shared_ptr<libport::UDPLink> l,
                 libport::utime_t duration)
{
  usleep(duration);
  l->reply("hop hop\n");
}

// Hack until we can kill listenig sockets.
static bool enable_delay = false;
void reply_delay(const void*, int,
                 boost::shared_ptr<libport::UDPLink> l,
                 libport::utime_t duration)
{
  libport::startThread(boost::bind(&delayed_response, l, duration));
}

void echo(const void* d, int s, boost::shared_ptr<libport::UDPLink> l)
{
  if (enable_delay)
    reply_delay(d, s, l, 500000);
  else
    l->reply(d, s);
}

class TestSocket: public libport::Socket
{
  public:
  TestSocket()
    : nRead(0), echo(false), dump(false)
    {
      BOOST_CHECK(!abort_ctor);
      nInstance++;
    }
  TestSocket(bool echo, bool dump)
    : nRead(0), echo(echo), dump(dump)
    {
      BOOST_CHECK(!abort_ctor);
      nInstance++;
    }
  virtual ~TestSocket()
  {
    nInstance--;
    //BOOST_TEST_MESSAGE(this <<" dying, in " << K_get() << " lasterror=" << lastError.message());
    //assert(false);
  }

  int onRead(const void* data, size_t size)
  {
    nRead++;
    //BOOST_TEST_MESSAGE(this << " read " << size);
    if (echo)
      write(data, size);
    if (dump)
      received += std::string((const char*)data, size);
    return size;
  }

  void onError(boost::system::error_code erc)
  {
    lastError = erc;
    destroy();
  }
  // Number of times read callback was called
  int nRead;
  // Echo back what is received.
  bool echo;
  // Store what is received in received.
  bool dump;
  std::string received;
  boost::system::error_code lastError;
  static TestSocket* factory()
    {
      return lastInstance = new TestSocket();
    }
  static TestSocket* factoryEx(bool echo, bool dump)
    {
      return lastInstance = new TestSocket(echo, dump);
    }
  static int nInstance;
  // Last factory-created instance.
  static TestSocket* lastInstance;
};

int TestSocket::nInstance = 0;
TestSocket* TestSocket::lastInstance = 0;

// Delay in microseconds used to sleep when something asynchronous
// is happening.
static const int delay = 200000;

static const int AVAIL_PORT = 7890;
static const std::string S_AVAIL_PORT = "7890";

void test_one(bool proto)
{
  TestSocket* client = new TestSocket(false, true);
  boost::system::error_code err
    = client->connect(connect_host, S_AVAIL_PORT, proto);
  BOOST_REQUIRE_MESSAGE(!err, err.message());
  BOOST_CHECK_NO_THROW(client->send(msg));
  usleep(delay);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, proto ? 1 : 2);
  BOOST_CHECK_EQUAL(client->received, msg);
  if (!proto)
    BOOST_CHECK_EQUAL(TestSocket::lastInstance->received,
                      msg);
  BOOST_CHECK_EQUAL(client->getRemotePort(), AVAIL_PORT);
  if (!proto)
    BOOST_CHECK_EQUAL(TestSocket::lastInstance->getLocalPort(),
                      AVAIL_PORT);
  if (!proto)
    BOOST_CHECK_EQUAL(TestSocket::lastInstance->getRemotePort(),
                      client->getLocalPort());
  // Close client-end. Should send error both ways and destroy all sockets.
  client->close();
  usleep(delay);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);
}

#define RESOLVE()                                                       \
  do {                                                                  \
    libport::resolve<boost::asio::ip::tcp>(connect_host,                \
                                           S_AVAIL_PORT, err);          \
    BOOST_TEST_MESSAGE("Resolve: " + err.message());                    \
  } while (0)

static
void
test()
{
  // Basic TCP
  BOOST_TEST_MESSAGE("##Safe destruction");
  boost::system::error_code err;
  TestSocket* s = new TestSocket(false, false);
  s->connect(connect_host, S_AVAIL_PORT, false);
  s->destroy();
  usleep(delay);
  RESOLVE();
  libport::Socket* h = new libport::Socket();
  err = h->listen(boost::bind(&TestSocket::factoryEx, true, true),
                  listen_host, S_AVAIL_PORT, false);
  BOOST_CHECK_MESSAGE(!err, err.message());
  BOOST_CHECK_EQUAL(h->getLocalPort(), AVAIL_PORT);

  BOOST_TEST_MESSAGE("##One client");
  RESOLVE();
  RESOLVE();
  RESOLVE();
  RESOLVE();
  std::cerr << "BEFORE TEST_ONE" << std::endl;
  test_one(false);
  BOOST_CHECK_EQUAL(h->getLocalPort(), AVAIL_PORT);
  std::cerr << "AFTER TEST_ONE" << std::endl;
  RESOLVE();
  test_one(false);
  BOOST_CHECK_EQUAL(h->getLocalPort(), AVAIL_PORT);
  RESOLVE();
  test_one(false);
  BOOST_TEST_MESSAGE("Socket on stack");
  {
    TestSocket s(false, true);
    err = s.connect(connect_host, S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    s.send(msg);
    usleep(delay);
  }
  usleep(delay*2);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);

  test_one(false);
  BOOST_TEST_MESSAGE("##many clients");
  std::vector<TestSocket*> clients;
  for (int i=0; i<10; i++)
  {
    TestSocket* client = new TestSocket(false, true);
    err = client->connect(connect_host, S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    client->send(msg);
    clients.push_back(client);
  }
  usleep(delay*3);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 20);
  foreach(TestSocket* s, clients)
  {
    BOOST_CHECK_EQUAL(s->received, msg);
    s->close();
  }
  usleep(delay*3);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);

  BOOST_TEST_MESSAGE("##Failing connections");
  {
    TestSocket* client = new TestSocket();
    err = client->connect("auunsinsr.nosuch.hostaufisgiu.com.", "20000", false);
    BOOST_CHECK_MESSAGE(err, err.message());

    err = client->connect(connect_host, "nosuchport", false);
    BOOST_CHECK_MESSAGE(err, err.message());

    // Try to reuse that wasted socket.
    err = client->connect(connect_host, S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    // Destroy without closing.
    client->destroy();
    usleep(delay);
    BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);
  }

  // Timeout
  BOOST_TEST_MESSAGE("##Timeout connect");
  {
    TestSocket* client = new TestSocket();
    libport::utime_t start = libport::utime();
    err = client->connect("1.1.1.1", "10000", false, 1000000);
    BOOST_CHECK_MESSAGE(err, err.message());
    libport::utime_t timeout = libport::utime() - start;
    // Give it a good margin.
    BOOST_CHECK_LT(timeout, 1400000);
    client->destroy();
  }

  BOOST_TEST_MESSAGE("##Destruction locking");
  {
    TestSocket* client = new TestSocket();
    err = client->connect(connect_host, S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    usleep(delay);
    libport::startThread(
      boost::bind(&hold_for<libport::Destructible::DestructionLock>,
                  client->getDestructionLock(),
                  1000000));
    client->destroy();
    usleep(500000);
    // There can be 1 or 2 sockets at this point. Client must be still
    // alive because of the lock, but server might have died.
    BOOST_CHECK_MESSAGE(TestSocket::nInstance, TestSocket::nInstance);
    usleep(500000+delay);
    BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);
  }

  BOOST_TEST_MESSAGE("Destroy listener");
  {
    h->close();
    usleep(delay);
    TestSocket* client = new TestSocket();
    abort_ctor = true;
    err = client->connect(connect_host, S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(err, err.message());
    client->destroy();
    h->destroy();
    usleep(delay);
    abort_ctor = false;
  }

  BOOST_TEST_MESSAGE("##UDP");
  {
    libport::Socket::Handle hu =
      libport::Socket::listenUDP(listen_host, S_AVAIL_PORT, &echo, err);
    (void)hu;
    BOOST_CHECK_MESSAGE(!err, err.message());
    test_one(true);
    usleep(delay);
    test_one(true);

    TestSocket* client = new TestSocket();
    err = client->connect("auunsinsr.nosuch.hostaufisgiu.com.", "20000", true);
    BOOST_CHECK_MESSAGE(err, err.message());

    err = client->connect(connect_host, "nosuchport", true);
    BOOST_CHECK_MESSAGE(err, err.message());

    // Try to reuse that wasted socket.
    err = client->connect(connect_host, S_AVAIL_PORT, true);
    BOOST_CHECK_MESSAGE(!err, err.message());
    // Destroy without closing.
    client->destroy();
    usleep(delay);
    BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);

    // Check one-write-one-packet semantic
    client = new TestSocket(false, true);
    err = client->connect(connect_host, S_AVAIL_PORT, true);
    BOOST_CHECK_MESSAGE(!err, err.message());
    client->send("coin");
    client->send("pan");
    usleep(delay*2);
    BOOST_CHECK_EQUAL(client->received, "coinpan");
    BOOST_CHECK_EQUAL(client->nRead, 2);

    enable_delay = true;
    client = new TestSocket(false, true);
    err = client->connect(connect_host, S_AVAIL_PORT, true);
    BOOST_CHECK_MESSAGE(!err, err.message());
    client->send("coin");
    usleep(500000+delay);
    BOOST_CHECK_EQUAL(client->received, "hop hop\n");
  }
}

test_suite*
init_test_suite()
{
  // This test cannot run properly with current versions of WineHQ,
  // because they only provide a stub for acceptex.
  const char* running_wine = getenv("RUNNING_WINE");
  const char* running_qemu = getenv("RUNNING_QEMU");
  if ((running_wine && *running_wine) || (running_qemu && *running_qemu))
    std::cerr << "running under Wine, skipping this test"
              << std::endl
              << libport::exit(EX_SKIP);

  test_suite* suite = BOOST_TEST_SUITE("libport::asio test suite");
  suite->add(BOOST_TEST_CASE(test));
  return suite;
}
<commit_msg>Liport.Asio: Fix test.<commit_after>#include <libport/unit-test.hh>
#include <libport/sysexits.hh>
using libport::test_suite;

#ifndef LIBPORT_NO_SSL
# define LIBPORT_NO_SSL
#endif

#include <libport/asio.hh>
#include <libport/utime.hh>
#include <libport/unistd.h>

bool abort_ctor = false;

const char* msg = "coincoin\n";

// On OSX:
//   listen            connect        status
// "127.0.0.1"       "127.0.0.1"       PASS  IPv4
// "localhost"       "localhost"       PASS  IPv6
// ""                "localhost"       PASS  IPv6
// ""                "127.0.0.1"       FAIL
// ""                ""                PASS  IPv6
static const char* listen_host = "127.0.0.1";
static const char* connect_host = "127.0.0.1";

template<class T>
void
hold_for(T, libport::utime_t duration)
{
  usleep(duration);
  BOOST_TEST_MESSAGE("Done holding your T");
}

void
delayed_response(boost::shared_ptr<libport::UDPLink> l,
                 libport::utime_t duration)
{
  usleep(duration);
  l->reply("hop hop\n");
}

// Hack until we can kill listenig sockets.
static bool enable_delay = false;
void reply_delay(const void*, int,
                 boost::shared_ptr<libport::UDPLink> l,
                 libport::utime_t duration)
{
  libport::startThread(boost::bind(&delayed_response, l, duration));
}

void echo(const void* d, int s, boost::shared_ptr<libport::UDPLink> l)
{
  if (enable_delay)
    reply_delay(d, s, l, 500000);
  else
    l->reply(d, s);
}

class TestSocket: public libport::Socket
{
  public:
  TestSocket()
    : nRead(0), echo(false), dump(false)
    {
      BOOST_CHECK(!abort_ctor);
      nInstance++;
    }
  TestSocket(bool echo, bool dump)
    : nRead(0), echo(echo), dump(dump)
    {
      BOOST_CHECK(!abort_ctor);
      nInstance++;
    }
  virtual ~TestSocket()
  {
    nInstance--;
    //BOOST_TEST_MESSAGE(this <<" dying, in " << K_get() << " lasterror=" << lastError.message());
    //assert(false);
  }

  int onRead(const void* data, size_t size)
  {
    nRead++;
    //BOOST_TEST_MESSAGE(this << " read " << size);
    if (echo)
      write(data, size);
    if (dump)
      received += std::string((const char*)data, size);
    return size;
  }

  void onError(boost::system::error_code erc)
  {
    lastError = erc;
    destroy();
  }
  // Number of times read callback was called
  int nRead;
  // Echo back what is received.
  bool echo;
  // Store what is received in received.
  bool dump;
  std::string received;
  boost::system::error_code lastError;
  static TestSocket* factory()
    {
      return lastInstance = new TestSocket();
    }
  static TestSocket* factoryEx(bool echo, bool dump)
    {
      return lastInstance = new TestSocket(echo, dump);
    }
  static int nInstance;
  // Last factory-created instance.
  static TestSocket* lastInstance;
};

int TestSocket::nInstance = 0;
TestSocket* TestSocket::lastInstance = 0;

// Delay in microseconds used to sleep when something asynchronous
// is happening.
static const int delay = 200000;

static const int AVAIL_PORT = 7890;
static const std::string S_AVAIL_PORT = "7890";

void test_one(bool proto)
{
  TestSocket* client = new TestSocket(false, true);
  boost::system::error_code err
    = client->connect(connect_host, S_AVAIL_PORT, proto);
  BOOST_REQUIRE_MESSAGE(!err, err.message());
  BOOST_CHECK_NO_THROW(client->send(msg));
  usleep(delay);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, proto ? 1 : 2);
  BOOST_CHECK_EQUAL(client->received, msg);
  if (!proto)
    BOOST_CHECK_EQUAL(TestSocket::lastInstance->received,
                      msg);
  BOOST_CHECK_EQUAL(client->getRemotePort(), AVAIL_PORT);
  if (!proto)
    BOOST_CHECK_EQUAL(TestSocket::lastInstance->getLocalPort(),
                      AVAIL_PORT);
  if (!proto)
    BOOST_CHECK_EQUAL(TestSocket::lastInstance->getRemotePort(),
                      client->getLocalPort());
  // Close client-end. Should send error both ways and destroy all sockets.
  client->close();
  usleep(delay);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);
}

#define RESOLVE()                                                       \
  do {                                                                  \
    libport::resolve<boost::asio::ip::tcp>(connect_host,                \
                                           S_AVAIL_PORT, err);          \
    BOOST_TEST_MESSAGE("Resolve: " + err.message());                    \
  } while (0)

static
void
test()
{
  // Basic TCP
  BOOST_TEST_MESSAGE("##Safe destruction");
  boost::system::error_code err;
  TestSocket* s = new TestSocket(false, false);
  s->connect(connect_host, S_AVAIL_PORT, false);
  s->destroy();
  usleep(delay);
  RESOLVE();
  libport::Socket* h = new libport::Socket();
  err = h->listen(boost::bind(&TestSocket::factoryEx, true, true),
                  listen_host, S_AVAIL_PORT, false);
  BOOST_CHECK_MESSAGE(!err, err.message());
  BOOST_CHECK_EQUAL(h->getLocalPort(), AVAIL_PORT);

  BOOST_TEST_MESSAGE("##One client");
  RESOLVE();
  RESOLVE();
  RESOLVE();
  RESOLVE();
  test_one(false);
  BOOST_CHECK_EQUAL(h->getLocalPort(), AVAIL_PORT);
  RESOLVE();
  test_one(false);
  BOOST_CHECK_EQUAL(h->getLocalPort(), AVAIL_PORT);
  RESOLVE();
  test_one(false);
  BOOST_TEST_MESSAGE("Socket on stack");
  {
    TestSocket s(false, true);
    err = s.connect(connect_host, S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    s.send(msg);
    usleep(delay);
  }
  usleep(delay*2);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);

  test_one(false);
  BOOST_TEST_MESSAGE("##many clients");
  std::vector<TestSocket*> clients;
  for (int i=0; i<10; i++)
  {
    TestSocket* client = new TestSocket(false, true);
    err = client->connect(connect_host, S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    client->send(msg);
    clients.push_back(client);
  }
  usleep(delay*3);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 20);
  foreach(TestSocket* s, clients)
  {
    BOOST_CHECK_EQUAL(s->received, msg);
    s->close();
  }
  usleep(delay*3);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);

  BOOST_TEST_MESSAGE("##Failing connections");
  {
    TestSocket* client = new TestSocket();
    err = client->connect("auunsinsr.nosuch.hostaufisgiu.com.", "20000", false);
    BOOST_CHECK_MESSAGE(err, err.message());

    err = client->connect(connect_host, "nosuchport", false);
    BOOST_CHECK_MESSAGE(err, err.message());

    // Try to reuse that wasted socket.
    err = client->connect(connect_host, S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    // Destroy without closing.
    client->destroy();
    usleep(delay);
    BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);
  }

  // Timeout
  BOOST_TEST_MESSAGE("##Timeout connect");
  {
    TestSocket* client = new TestSocket();
    libport::utime_t start = libport::utime();
    err = client->connect("1.1.1.1", "10000", false, 1000000);
    BOOST_CHECK_MESSAGE(err, err.message());
    libport::utime_t timeout = libport::utime() - start;
    // Give it a good margin.
    BOOST_CHECK_LT(timeout, 1400000);
    client->destroy();
  }

  BOOST_TEST_MESSAGE("##Destruction locking");
  {
    TestSocket* client = new TestSocket();
    err = client->connect(connect_host, S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    usleep(delay);
    libport::startThread(
      boost::bind(&hold_for<libport::Destructible::DestructionLock>,
                  client->getDestructionLock(),
                  1000000));
    client->destroy();
    usleep(500000);
    // There can be 1 or 2 sockets at this point. Client must be still
    // alive because of the lock, but server might have died.
    BOOST_CHECK_MESSAGE(TestSocket::nInstance, TestSocket::nInstance);
    usleep(500000+delay);
    BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);
  }

  BOOST_TEST_MESSAGE("Destroy listener");
  {
    h->close();
    usleep(delay);
    TestSocket* client = new TestSocket();
    abort_ctor = true;
    err = client->connect(connect_host, S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(err, err.message());
    client->destroy();
    h->destroy();
    usleep(delay);
    abort_ctor = false;
  }

  BOOST_TEST_MESSAGE("##UDP");
  {
    libport::Socket::Handle hu =
      libport::Socket::listenUDP(listen_host, S_AVAIL_PORT, &echo, err);
    (void)hu;
    BOOST_CHECK_MESSAGE(!err, err.message());
    test_one(true);
    usleep(delay);
    test_one(true);

    TestSocket* client = new TestSocket();
    err = client->connect("auunsinsr.nosuch.hostaufisgiu.com.", "20000", true);
    BOOST_CHECK_MESSAGE(err, err.message());

    err = client->connect(connect_host, "nosuchport", true);
    BOOST_CHECK_MESSAGE(err, err.message());

    // Try to reuse that wasted socket.
    err = client->connect(connect_host, S_AVAIL_PORT, true);
    BOOST_CHECK_MESSAGE(!err, err.message());
    // Destroy without closing.
    client->destroy();
    usleep(delay);
    BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);

    // Check one-write-one-packet semantic
    client = new TestSocket(false, true);
    err = client->connect(connect_host, S_AVAIL_PORT, true);
    BOOST_CHECK_MESSAGE(!err, err.message());
    client->send("coin");
    client->send("pan");
    usleep(delay*2);
    BOOST_CHECK_EQUAL(client->received, "coinpan");
    BOOST_CHECK_EQUAL(client->nRead, 2);

    enable_delay = true;
    client = new TestSocket(false, true);
    err = client->connect(connect_host, S_AVAIL_PORT, true);
    BOOST_CHECK_MESSAGE(!err, err.message());
    client->send("coin");
    usleep(500000+delay);
    BOOST_CHECK_EQUAL(client->received, "hop hop\n");
  }
}

test_suite*
init_test_suite()
{
  // This test cannot run properly with current versions of WineHQ,
  // because they only provide a stub for acceptex.
  const char* running_wine = getenv("RUNNING_WINE");
  const char* running_qemu = getenv("RUNNING_QEMU");
  if ((running_wine && *running_wine) || (running_qemu && *running_qemu))
    std::cerr << "running under Wine, skipping this test"
              << std::endl
              << libport::exit(EX_SKIP);

  test_suite* suite = BOOST_TEST_SUITE("libport::asio test suite");
  suite->add(BOOST_TEST_CASE(test));
  return suite;
}
<|endoftext|>


<commit_before>// RUN: %check_clang_tidy %s hicpp-signed-bitwise %t -- -- -std=c++11 -target x86_64-unknown-unknown

// These could cause false positives and should not be considered.
struct StreamClass {
};
StreamClass &operator<<(StreamClass &os, unsigned int i) {
  return os;
}
StreamClass &operator<<(StreamClass &os, int i) {
  return os;
}
StreamClass &operator>>(StreamClass &os, unsigned int i) {
  return os;
}
StreamClass &operator>>(StreamClass &os, int i) {
  return os;
}
struct AnotherStream {
  AnotherStream &operator<<(unsigned char c) { return *this; }
  AnotherStream &operator<<(signed char c) { return *this; }

  AnotherStream &operator>>(unsigned char c) { return *this; }
  AnotherStream &operator>>(signed char c) { return *this; }
};

void binary_bitwise() {
  int SValue = 42;
  int SResult;

  unsigned int UValue = 42;
  unsigned int UResult;

  SResult = SValue & 1;
  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
  SResult = SValue & -1;
  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
  SResult = SValue & SValue;
  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator

  UResult = SValue & 1;
  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
  UResult = SValue & -1;
  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator

  UResult = UValue & 1u;     // Ok
  UResult = UValue & UValue; // Ok

  unsigned char UByte1 = 0u;
  unsigned char UByte2 = 16u;
  signed char SByte1 = 0;
  signed char SByte2 = 16;

  UByte1 = UByte1 & UByte2; // Ok
  UByte1 = SByte1 & UByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
  UByte1 = SByte1 & SByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
  SByte1 = SByte1 & SByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator

  // More complex expressions.
  UResult = UValue & (SByte1 + (SByte1 | SByte2));
  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: use of a signed integer operand with a binary bitwise operator

  // The rest is to demonstrate functionality but all operators are matched equally.
  // Therefore functionality is the same for all binary operations.
  UByte1 = UByte1 | UByte2; // Ok
  UByte1 = UByte1 | SByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator

  UByte1 = UByte1 ^ UByte2; // Ok
  UByte1 = UByte1 ^ SByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator

  UByte1 = UByte1 >> UByte2; // Ok
  UByte1 = UByte1 >> SByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator

  UByte1 = UByte1 << UByte2; // Ok
  UByte1 = UByte1 << SByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator

  int SignedInt1 = 1 << 12;
  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
  int SignedInt2 = 1u << 12;
  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
}

void f1(unsigned char c) {}
void f2(signed char c) {}
void f3(int c) {}

void unary_bitwise() {
  unsigned char UByte1 = 0u;
  signed char SByte1 = 0;

  UByte1 = ~UByte1; // Ok
  SByte1 = ~UByte1;
  SByte1 = ~SByte1;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a unary bitwise operator
  UByte1 = ~SByte1;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a unary bitwise operator

  unsigned int UInt = 0u;
  int SInt = 0;

  f1(~UByte1); // Ok
  f1(~SByte1);
  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
  f1(~UInt);
  f1(~SInt);
  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
  f2(~UByte1);
  f2(~SByte1);
  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
  f2(~UInt);
  f2(~SInt);
  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
  f3(~UByte1); // Ok
  f3(~SByte1);
  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
}

/// HICPP uses these examples to demonstrate the rule.
void standard_examples() {
  int i = 3;
  unsigned int k = 0u;

  int r = i << -1; // Emits -Wshift-count-negative from clang
  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
  r = i << 1;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator

  r = -1 >> -1; // Emits -Wshift-count-negative from clang
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
  r = -1 >> 1;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator

  r = -1 >> i;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
  r = -1 >> -i;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator

  r = ~0;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
  r = ~0u; // Ok
  k = ~k;  // Ok

  unsigned int u = (-1) & 2u;
  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
  u = (-1) | 1u;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
  u = (-1) ^ 1u;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
}

void streams_should_work() {
  StreamClass s;
  s << 1u; // Ok
  s << 1;  // Ok
  s >> 1;  // Ok
  s >> 1u; // Ok

  AnotherStream as;
  unsigned char uc = 1u;
  signed char sc = 1;
  as << uc; // Ok
  as << sc; // Ok
  as >> uc; // Ok
  as >> sc; // Ok
}

enum OldEnum {
  ValueOne,
  ValueTwo,
};

enum OldSigned : int {
  IntOne,
  IntTwo,
};

void classicEnums() {
  OldEnum e1 = ValueOne, e2 = ValueTwo;
  int e3;                   // Using the enum type, results in an error.
  e3 = ValueOne | ValueTwo; // Ok
  e3 = ValueOne & ValueTwo; // Ok
  e3 = ValueOne ^ ValueTwo; // Ok
  e3 = e1 | e2;             // Ok
  e3 = e1 & e2;             // Ok
  e3 = e1 ^ e2;             // Ok

  OldSigned s1 = IntOne, s2 = IntTwo;
  int s3;
  s3 = IntOne | IntTwo; // Signed
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
  s3 = IntOne & IntTwo; // Signed
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
  s3 = IntOne ^ IntTwo; // Signed
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
  s3 = s1 | s2; // Signed
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
  s3 = s1 & s2; // Signed
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
  s3 = s1 ^ s2; // Signed
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
}

enum EnumConstruction {
  one = 1,
  two = 2,
  test1 = 1 << 12,
  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
  test2 = one << two,
  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
  test3 = 1u << 12,
  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
};
<commit_msg>[clang-tidy] Remove target specification hicpp-signed-bitwise<commit_after>// RUN: %check_clang_tidy %s hicpp-signed-bitwise %t -- -- -std=c++11

// These could cause false positives and should not be considered.
struct StreamClass {
};
StreamClass &operator<<(StreamClass &os, unsigned int i) {
  return os;
}
StreamClass &operator<<(StreamClass &os, int i) {
  return os;
}
StreamClass &operator>>(StreamClass &os, unsigned int i) {
  return os;
}
StreamClass &operator>>(StreamClass &os, int i) {
  return os;
}
struct AnotherStream {
  AnotherStream &operator<<(unsigned char c) { return *this; }
  AnotherStream &operator<<(signed char c) { return *this; }

  AnotherStream &operator>>(unsigned char c) { return *this; }
  AnotherStream &operator>>(signed char c) { return *this; }
};

void binary_bitwise() {
  int SValue = 42;
  int SResult;

  unsigned int UValue = 42;
  unsigned int UResult;

  SResult = SValue & 1;
  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
  SResult = SValue & -1;
  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
  SResult = SValue & SValue;
  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator

  UResult = SValue & 1;
  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
  UResult = SValue & -1;
  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator

  UResult = UValue & 1u;     // Ok
  UResult = UValue & UValue; // Ok

  unsigned char UByte1 = 0u;
  unsigned char UByte2 = 16u;
  signed char SByte1 = 0;
  signed char SByte2 = 16;

  UByte1 = UByte1 & UByte2; // Ok
  UByte1 = SByte1 & UByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
  UByte1 = SByte1 & SByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
  SByte1 = SByte1 & SByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator

  // More complex expressions.
  UResult = UValue & (SByte1 + (SByte1 | SByte2));
  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: use of a signed integer operand with a binary bitwise operator

  // The rest is to demonstrate functionality but all operators are matched equally.
  // Therefore functionality is the same for all binary operations.
  UByte1 = UByte1 | UByte2; // Ok
  UByte1 = UByte1 | SByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator

  UByte1 = UByte1 ^ UByte2; // Ok
  UByte1 = UByte1 ^ SByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator

  UByte1 = UByte1 >> UByte2; // Ok
  UByte1 = UByte1 >> SByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator

  UByte1 = UByte1 << UByte2; // Ok
  UByte1 = UByte1 << SByte2;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator

  int SignedInt1 = 1 << 12;
  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
  int SignedInt2 = 1u << 12;
  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
}

void f1(unsigned char c) {}
void f2(signed char c) {}
void f3(int c) {}

void unary_bitwise() {
  unsigned char UByte1 = 0u;
  signed char SByte1 = 0;

  UByte1 = ~UByte1; // Ok
  SByte1 = ~UByte1;
  SByte1 = ~SByte1;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a unary bitwise operator
  UByte1 = ~SByte1;
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a unary bitwise operator

  unsigned int UInt = 0u;
  int SInt = 0;

  f1(~UByte1); // Ok
  f1(~SByte1);
  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
  f1(~UInt);
  f1(~SInt);
  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
  f2(~UByte1);
  f2(~SByte1);
  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
  f2(~UInt);
  f2(~SInt);
  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
  f3(~UByte1); // Ok
  f3(~SByte1);
  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
}

/// HICPP uses these examples to demonstrate the rule.
void standard_examples() {
  int i = 3;
  unsigned int k = 0u;

  int r = i << -1; // Emits -Wshift-count-negative from clang
  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
  r = i << 1;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator

  r = -1 >> -1; // Emits -Wshift-count-negative from clang
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
  r = -1 >> 1;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator

  r = -1 >> i;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
  r = -1 >> -i;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator

  r = ~0;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
  r = ~0u; // Ok
  k = ~k;  // Ok

  unsigned int u = (-1) & 2u;
  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
  u = (-1) | 1u;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
  u = (-1) ^ 1u;
  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
}

void streams_should_work() {
  StreamClass s;
  s << 1u; // Ok
  s << 1;  // Ok
  s >> 1;  // Ok
  s >> 1u; // Ok

  AnotherStream as;
  unsigned char uc = 1u;
  signed char sc = 1;
  as << uc; // Ok
  as << sc; // Ok
  as >> uc; // Ok
  as >> sc; // Ok
}

enum OldEnum {
  ValueOne,
  ValueTwo,
};

enum OldSigned : int {
  IntOne,
  IntTwo,
};

void classicEnums() {
  OldEnum e1 = ValueOne, e2 = ValueTwo;
  int e3;                   // Using the enum type, results in an error.
  e3 = ValueOne | ValueTwo; // Ok
  e3 = ValueOne & ValueTwo; // Ok
  e3 = ValueOne ^ ValueTwo; // Ok
  e3 = e1 | e2;             // Ok
  e3 = e1 & e2;             // Ok
  e3 = e1 ^ e2;             // Ok

  OldSigned s1 = IntOne, s2 = IntTwo;
  int s3;
  s3 = IntOne | IntTwo; // Signed
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
  s3 = IntOne & IntTwo; // Signed
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
  s3 = IntOne ^ IntTwo; // Signed
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
  s3 = s1 | s2; // Signed
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
  s3 = s1 & s2; // Signed
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
  s3 = s1 ^ s2; // Signed
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
}

enum EnumConstruction {
  one = 1,
  two = 2,
  test1 = 1 << 12,
  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
  test2 = one << two,
  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
  test3 = 1u << 12,
  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
};
<|endoftext|>