<commit_before>#include "gridbuilder.h"

int GridBuilder::currentColor = -1;

GridBuilder::GridBuilder()
{

}

Grid* GridBuilder::buildGrid(Grid* grid, int row, int col)
{
    int** adjacentPathMatrix = new int*[row];
    for(int i = 0; i < row; i++)
    {
        adjacentPathMatrix[i] = new int[col];
    }
    fillAdjacentPathMatrix(grid, adjacentPathMatrix);

    while(!grid->isCompleted())
    {
        QPoint* pos;

        //If there is two adjacent free blocks that only connects to eachother do something
        pos = findPairOfLoneBlocks(grid, adjacentPathMatrix);
        if(pos->x() >= 0)
        {
            //TODO TRY TO FILL PAIR
            //try to fill pair of lone blocks, if you cant, restart
            destroyAdjacentPathMatrix(adjacentPathMatrix, row);
            return grid;
        }
        else
        {
            //If there is a standAlone free block, try to move an adjacent endPoint, otherwise impossible, restart from scratch
            pos = findLoneBlock(grid, adjacentPathMatrix);
            if(pos->x() >= 0)
            {
                //Move adjacent endPoint
                //if success keep on
                //else restart
                destroyAdjacentPathMatrix(adjacentPathMatrix, row);
                return grid;
            }
            else
            {
                //If there is a dead end, make it the start of a path
                pos = findDeadEnd(grid, adjacentPathMatrix);
                if(pos->x() >= 0)
                {
                    buildPathStartingPoint(pos, grid);
                }
                else
                {
                    //Start random path from here
                    QPoint* point = getRandomFreeBlock(grid);
                    if(point->x() < 0) return grid;
                    buildPathStartingPoint(point, grid);
                }
            }
        }
    }

    destroyAdjacentPathMatrix(adjacentPathMatrix, row);

    return grid;
}

Grid* GridBuilder::buildGrid(int row, int col)
{
    std::srand(std::time(0));
    Grid* grid = new Grid(row, col);

    while(!grid->isCompleted())
    {
        currentColor = -1;
        delete grid;
        grid = new Grid(row, col);
        buildGrid(grid, row, col);
    }

    clearPaths(grid);

    return grid;
}

void GridBuilder::clearPaths(Grid* grid)
{
  for (int i = 0; i < grid->getNbRow(); ++i)
  {
      for (int j = 0; j < grid->getNbColumn(); ++j)
      {
          if (grid->getGrid()[j][i].isOrigin())
          {
              grid->getGrid()[j][i].clearOrigin();
          }
          else
          {
              grid->getGrid()[j][i].clear();
          }
      }
  }
}

void GridBuilder::buildPathStartingPoint(QPoint* startingPos, Grid* grid)
{
    currentColor++;
    //Path path = grid->getPath(startingPos->x(), startingPos->y());

    grid->getGrid()[startingPos->x()][startingPos->y()].setCovered(true);
    //path.setCovered(true);

    grid->getGrid()[startingPos->x()][startingPos->y()].setColor(currentColor);

    grid->getGrid()[startingPos->x()][startingPos->y()].setOrigin(true);
    //path.setOrigin(true);

    grid->getGrid()[startingPos->x()][startingPos->y()].setFirstOrigin(true);
    //path.setFirstOrigin(true);

    buildPath(startingPos, grid);
}

//TODO build Path starting at startingPos
void GridBuilder::buildPath(QPoint* startingPos, Grid* grid)
{
    int possibleMoves = numberOfFreeAdjacentPositions(startingPos, grid);
    //Path path = grid->getPath(startingPos->x(), startingPos->y());

    //path.setCovered(true);
    grid->getGrid()[startingPos->x()][startingPos->y()].setCovered(true);

    //setting color
    grid->getGrid()[startingPos->x()][startingPos->y()].setColor(currentColor);

    if(possibleMoves == 0)
    {
        //path.setOrigin(true);
        grid->getGrid()[startingPos->x()][startingPos->y()].setOrigin(true);
        //path.setPathComplete(true);
        grid->getGrid()[startingPos->x()][startingPos->y()].setPathComplete(true);
    }
    else if(possibleMoves == 1)
    {
        QPoint* nextPathPos = getRandomAdjacentFreeBlock(startingPos, grid);
        Cell nextPath = grid->getCell(nextPathPos->x(), nextPathPos->y());
        //nextPath.setCovered(true);
        grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setCovered(true);
        //nextPath.previous[0] = &path;
        grid->getGrid()[nextPathPos->x()][nextPathPos->y()].previous[0] = &(grid->getGrid()[startingPos->x()][startingPos->y()]);

        grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setColor(true);

        //grid->getPath(startingPos->x(), startingPos->y()).next[0] = &nextPath;
        grid->getGrid()[startingPos->x()][startingPos->y()].next[0] = &(grid->getGrid()[nextPathPos->x()][nextPathPos->y()]);

        buildPath(nextPathPos, grid);
    }
    else
    {

        if(grid->getGrid()[startingPos->x()][startingPos->y()].isOrigin() || getRandomNumberFrom0To(grid->getNbColumn() / 2) != 1)
        {

            QPoint* nextPathPos = getRandomAdjacentFreeBlock(startingPos, grid);
            //Path nextPath = grid->getPath(nextPathPos->x(), nextPathPos->y());

            //nextPath.setCovered(true);
            grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setCovered(true);

            //nextPath.previous[0] = &path;
            grid->getGrid()[nextPathPos->x()][nextPathPos->y()].previous[0] = &(grid->getGrid()[startingPos->x()][startingPos->y()]);

            grid->getGrid()[startingPos->x()][startingPos->y()].next[0] = &(grid->getGrid()[nextPathPos->x()][nextPathPos->y()]);
            //grid->getPath(startingPos->x(), startingPos->y()).next[0] = &nextPath;

            grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setColor(currentColor);

            buildPath(nextPathPos, grid);
        }
        else
        {
            grid->getGrid()[startingPos->x()][startingPos->y()].setOrigin(true);
            grid->getGrid()[startingPos->x()][startingPos->y()].setPathComplete(true);
            grid->getGrid()[startingPos->x()][startingPos->y()].setColor(currentColor);
            //path.setOrigin(true);
            //path.setPathComplete(true);
        }
    }

}

QPoint* GridBuilder::findDeadEnd(Grid* grid, int** adjacentPathMatrix)
{
    return findXAdjacentFreeBlocks(grid, 1, adjacentPathMatrix);
}

QPoint*  GridBuilder::findLoneBlock(Grid* grid, int** adjacentPathMatrix)
{
    return findXAdjacentFreeBlocks(grid, 0, adjacentPathMatrix);
}

int GridBuilder::numberOfFreeAdjacentPositions(QPoint* pos, Grid* grid)
{
    int count = 0;

    //up
    if(pos->x() - 1 >= 0 && !grid->getCell(pos->x() - 1, pos->y()).isCovered()) count++;
    //down
    if(pos->x() + 1 <= grid->getNbRow() - 1 && !grid->getCell(pos->x() + 1, pos->y()).isCovered()) count++;
    //left
    if(pos->y() - 1 >= 0 && !grid->getCell(pos->x(), pos->y() - 1).isCovered()) count++;
    //right
    if(pos->y() + 1 <= grid->getNbColumn() - 1 && !grid->getCell(pos->x(), pos->y() + 1).isCovered()) count++;

    return count;
}

QPoint*  GridBuilder::findXAdjacentFreeBlocks(Grid* grid, int x, int** adjacentPathMatrix)
{
    fillAdjacentPathMatrix(grid, adjacentPathMatrix);
    int row = grid->getNbRow();
    int col = grid->getNbColumn();
    for(int i = 0; i < row; i++)
    {
        for(int j = 0; j < col; j++)
        {
            if(adjacentPathMatrix[i][j] == x && !grid->getCell(i,j).isCovered())
            {
                return new QPoint(i,j);
            }
        }
    }
    return new QPoint(-1,-1);
}

void GridBuilder::fillAdjacentPathMatrix(Grid* grid, int** adjacentPathMatrix)
{
    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            QPoint* point = new QPoint(i,j);
            adjacentPathMatrix[i][j] = numberOfFreeAdjacentPositions(point, grid);

        }
    }
}

QPoint* GridBuilder::findPairOfLoneBlocks(Grid* grid, int** adjacentPathMatrix)
{
    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            if(adjacentPathMatrix[i][j] == 1 && !grid->getCell(i,j).isCovered())
            {
                //if there is another single one to the right or under we have a pair
                if((i + 1 < grid->getNbRow() && adjacentPathMatrix[i+1][j] == 1 && !grid->getCell(i+1,j).isCovered())
                        || (j + 1 < grid->getNbColumn() && adjacentPathMatrix[i][j+1] == 1 && !grid->getCell(i,j+1).isCovered()))
                {
                    return new QPoint(i,j);
                }
            }
        }
    }
    return new QPoint(-1,-1);
}

void GridBuilder::destroyAdjacentPathMatrix(int **adjacentPathMatrix, int row)
{
    for(int i = 0; i < row; ++i){
        delete[] adjacentPathMatrix[i];
    }

    delete[] adjacentPathMatrix;
}

QPoint* GridBuilder::getRandomFreeBlock(Grid* grid)
{
    int nbOfFreeBlocks = 0;
    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            if(!grid->getCell(i,j).isCovered()) nbOfFreeBlocks++;
        }
    }

    if(nbOfFreeBlocks == 0) nbOfFreeBlocks++;

    int pos = getRandomNumberFrom0To(nbOfFreeBlocks);

    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            if(!grid->getCell(i,j).isCovered())
            {
                pos--;
                if(pos == 0)
                {
                    return new QPoint(i,j);
                }
            }
        }
    }

    return new QPoint(-1,-1);
}

int GridBuilder::getRandomNumberFrom0To(int max)
{
     // use current time as seed for random generator
    return std::rand() % max;
}

QPoint* GridBuilder::getRandomAdjacentFreeBlock(QPoint* pos, Grid* grid)
{
    QPoint qp = QPoint(pos->x(), pos->y());
    int num = numberOfFreeAdjacentPositions(&qp, grid);
    int direction = getRandomNumberFrom0To(num);

    //up
    if(pos->x() - 1 >= 0 && !grid->getCell(pos->x() - 1, pos->y()).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x() - 1, pos->y());
        --direction;
    }

    //down
    if(pos->x() + 1 <= grid->getNbRow() - 1 && !grid->getCell(pos->x() + 1, pos->y()).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x() + 1, pos->y());
        --direction;
    }
    //left
    if(pos->y() - 1 >= 0 && !grid->getCell(pos->x(), pos->y() - 1).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x(), pos->y() - 1);
        --direction;
    }
    //right
    if(pos->y() + 1 <= grid->getNbColumn() - 1 && !grid->getCell(pos->x(), pos->y() + 1).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x(), pos->y() + 1);
        --direction;
    }

    //SHOULD NEVER HIT THIS
    qDebug() << "ERROR";
    return new QPoint(-1,-1);
}

bool GridBuilder::moveAdjacentEndPoint(QPoint* pos, Grid* grid)
{
    Cell adjacentOrigin;
    //up
    if(pos->x() - 1 >= 0 && grid->getCell(pos->x() - 1, pos->y()).isOrigin())
    {
        adjacentOrigin = grid->getCell(pos->x()-1, pos->y());
    }
    //down
    else if(pos->x() + 1 <= grid->getNbRow() - 1 && grid->getCell(pos->x() + 1, pos->y()).isOrigin())
    {
        adjacentOrigin = grid->getCell(pos->x() + 1, pos->y());
    }
    //left
    else if(pos->y() - 1 >= 0 && grid->getCell(pos->x(), pos->y() - 1).isOrigin())
    {
        adjacentOrigin = grid->getCell(pos->x(), pos->y() - 1);
    }
    //right
    else if(pos->y() + 1 <= grid->getNbColumn() - 1 && grid->getCell(pos->x(), pos->y() + 1).isOrigin())
    {
        adjacentOrigin = grid->getCell(pos->x(), pos->y() + 1);
    }
    else
    {
        return false;
    }

    Cell cell = grid->getCell(pos->x(), pos->y());
    cell.setOrigin(true);
    adjacentOrigin.setOrigin(false);
    adjacentOrigin.setPathComplete(false);
    if(adjacentOrigin.next == NULL)
    {
        cell.setPathComplete(true);
        cell.previous[0] = &adjacentOrigin;
        adjacentOrigin.next[0] = &cell;
    }
    else
    {
        adjacentOrigin.previous[0] = &cell;
        cell.next[0] = &adjacentOrigin;
    }

    return true;
}
<commit_msg>Cleaned gridbuilder.cpp comments<commit_after>#include "gridbuilder.h"

int GridBuilder::currentColor = -1;

GridBuilder::GridBuilder()
{

}

Grid* GridBuilder::buildGrid(Grid* grid, int row, int col)
{
    int** adjacentPathMatrix = new int*[row];
    for(int i = 0; i < row; i++)
    {
        adjacentPathMatrix[i] = new int[col];
    }
    fillAdjacentPathMatrix(grid, adjacentPathMatrix);

    while(!grid->isCompleted())
    {
        QPoint* pos;

        //If there is two adjacent free blocks that only connects to eachother do something
        pos = findPairOfLoneBlocks(grid, adjacentPathMatrix);
        if(pos->x() >= 0)
        {
            //try to fill pair of lone blocks, if you cant, restart
            destroyAdjacentPathMatrix(adjacentPathMatrix, row);
            return grid;
        }
        else
        {
            //If there is a standAlone free block, try to move an adjacent endPoint, otherwise impossible, restart from scratch
            pos = findLoneBlock(grid, adjacentPathMatrix);
            if(pos->x() >= 0)
            {
                //Move adjacent endPoint
                //if success keep on
                //else restart
                destroyAdjacentPathMatrix(adjacentPathMatrix, row);
                return grid;
            }
            else
            {
                //If there is a dead end, make it the start of a path
                pos = findDeadEnd(grid, adjacentPathMatrix);
                if(pos->x() >= 0)
                {
                    buildPathStartingPoint(pos, grid);
                }
                else
                {
                    //Start random path from here
                    QPoint* point = getRandomFreeBlock(grid);
                    if(point->x() < 0) return grid;
                    buildPathStartingPoint(point, grid);
                }
            }
        }
    }

    destroyAdjacentPathMatrix(adjacentPathMatrix, row);

    return grid;
}

Grid* GridBuilder::buildGrid(int row, int col)
{
    std::srand(std::time(0));
    Grid* grid = new Grid(row, col);

    while(!grid->isCompleted())
    {
        currentColor = -1;
        delete grid;
        grid = new Grid(row, col);
        buildGrid(grid, row, col);
    }

    clearPaths(grid);

    return grid;
}

void GridBuilder::clearPaths(Grid* grid)
{
  for (int i = 0; i < grid->getNbRow(); ++i)
  {
      for (int j = 0; j < grid->getNbColumn(); ++j)
      {
          if (grid->getGrid()[j][i].isOrigin())
          {
              grid->getGrid()[j][i].clearOrigin();
          }
          else
          {
              grid->getGrid()[j][i].clear();
          }
      }
  }
}

void GridBuilder::buildPathStartingPoint(QPoint* startingPos, Grid* grid)
{
    currentColor++;

    grid->getGrid()[startingPos->x()][startingPos->y()].setCovered(true);

    grid->getGrid()[startingPos->x()][startingPos->y()].setColor(currentColor);

    grid->getGrid()[startingPos->x()][startingPos->y()].setOrigin(true);

    grid->getGrid()[startingPos->x()][startingPos->y()].setFirstOrigin(true);

    buildPath(startingPos, grid);
}

void GridBuilder::buildPath(QPoint* startingPos, Grid* grid)
{
    int possibleMoves = numberOfFreeAdjacentPositions(startingPos, grid);

    grid->getGrid()[startingPos->x()][startingPos->y()].setCovered(true);

    grid->getGrid()[startingPos->x()][startingPos->y()].setColor(currentColor);

    if(possibleMoves == 0)
    {
        grid->getGrid()[startingPos->x()][startingPos->y()].setOrigin(true);
        grid->getGrid()[startingPos->x()][startingPos->y()].setPathComplete(true);
    }
    else if(possibleMoves == 1)
    {
        QPoint* nextPathPos = getRandomAdjacentFreeBlock(startingPos, grid);
        Cell nextPath = grid->getCell(nextPathPos->x(), nextPathPos->y());

        grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setCovered(true);

        grid->getGrid()[nextPathPos->x()][nextPathPos->y()].previous[0] = &(grid->getGrid()[startingPos->x()][startingPos->y()]);

        grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setColor(true);

        grid->getGrid()[startingPos->x()][startingPos->y()].next[0] = &(grid->getGrid()[nextPathPos->x()][nextPathPos->y()]);

        buildPath(nextPathPos, grid);
    }
    else
    {

        if(grid->getGrid()[startingPos->x()][startingPos->y()].isOrigin() || getRandomNumberFrom0To(grid->getNbColumn() / 2) != 1)
        {

            QPoint* nextPathPos = getRandomAdjacentFreeBlock(startingPos, grid);

            grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setCovered(true);

            grid->getGrid()[nextPathPos->x()][nextPathPos->y()].previous[0] = &(grid->getGrid()[startingPos->x()][startingPos->y()]);

            grid->getGrid()[startingPos->x()][startingPos->y()].next[0] = &(grid->getGrid()[nextPathPos->x()][nextPathPos->y()]);

            grid->getGrid()[nextPathPos->x()][nextPathPos->y()].setColor(currentColor);

            buildPath(nextPathPos, grid);
        }
        else
        {
            grid->getGrid()[startingPos->x()][startingPos->y()].setOrigin(true);
            grid->getGrid()[startingPos->x()][startingPos->y()].setPathComplete(true);
            grid->getGrid()[startingPos->x()][startingPos->y()].setColor(currentColor);
        }
    }

}

QPoint* GridBuilder::findDeadEnd(Grid* grid, int** adjacentPathMatrix)
{
    return findXAdjacentFreeBlocks(grid, 1, adjacentPathMatrix);
}

QPoint*  GridBuilder::findLoneBlock(Grid* grid, int** adjacentPathMatrix)
{
    return findXAdjacentFreeBlocks(grid, 0, adjacentPathMatrix);
}

int GridBuilder::numberOfFreeAdjacentPositions(QPoint* pos, Grid* grid)
{
    int count = 0;

    //up
    if(pos->x() - 1 >= 0 && !grid->getCell(pos->x() - 1, pos->y()).isCovered()) count++;
    //down
    if(pos->x() + 1 <= grid->getNbRow() - 1 && !grid->getCell(pos->x() + 1, pos->y()).isCovered()) count++;
    //left
    if(pos->y() - 1 >= 0 && !grid->getCell(pos->x(), pos->y() - 1).isCovered()) count++;
    //right
    if(pos->y() + 1 <= grid->getNbColumn() - 1 && !grid->getCell(pos->x(), pos->y() + 1).isCovered()) count++;

    return count;
}

QPoint*  GridBuilder::findXAdjacentFreeBlocks(Grid* grid, int x, int** adjacentPathMatrix)
{
    fillAdjacentPathMatrix(grid, adjacentPathMatrix);
    int row = grid->getNbRow();
    int col = grid->getNbColumn();
    for(int i = 0; i < row; i++)
    {
        for(int j = 0; j < col; j++)
        {
            if(adjacentPathMatrix[i][j] == x && !grid->getCell(i,j).isCovered())
            {
                return new QPoint(i,j);
            }
        }
    }
    return new QPoint(-1,-1);
}

void GridBuilder::fillAdjacentPathMatrix(Grid* grid, int** adjacentPathMatrix)
{
    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            QPoint* point = new QPoint(i,j);
            adjacentPathMatrix[i][j] = numberOfFreeAdjacentPositions(point, grid);

        }
    }
}

QPoint* GridBuilder::findPairOfLoneBlocks(Grid* grid, int** adjacentPathMatrix)
{
    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            if(adjacentPathMatrix[i][j] == 1 && !grid->getCell(i,j).isCovered())
            {
                //if there is another single one to the right or under we have a pair
                if((i + 1 < grid->getNbRow() && adjacentPathMatrix[i+1][j] == 1 && !grid->getCell(i+1,j).isCovered())
                        || (j + 1 < grid->getNbColumn() && adjacentPathMatrix[i][j+1] == 1 && !grid->getCell(i,j+1).isCovered()))
                {
                    return new QPoint(i,j);
                }
            }
        }
    }
    return new QPoint(-1,-1);
}

void GridBuilder::destroyAdjacentPathMatrix(int **adjacentPathMatrix, int row)
{
    for(int i = 0; i < row; ++i){
        delete[] adjacentPathMatrix[i];
    }

    delete[] adjacentPathMatrix;
}

QPoint* GridBuilder::getRandomFreeBlock(Grid* grid)
{
    int nbOfFreeBlocks = 0;
    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            if(!grid->getCell(i,j).isCovered()) nbOfFreeBlocks++;
        }
    }

    if(nbOfFreeBlocks == 0) nbOfFreeBlocks++;

    int pos = getRandomNumberFrom0To(nbOfFreeBlocks);

    for(int i = 0; i < grid->getNbRow(); i++)
    {
        for(int j = 0; j < grid->getNbColumn(); j++)
        {
            if(!grid->getCell(i,j).isCovered())
            {
                pos--;
                if(pos == 0)
                {
                    return new QPoint(i,j);
                }
            }
        }
    }

    return new QPoint(-1,-1);
}

int GridBuilder::getRandomNumberFrom0To(int max)
{
     // use current time as seed for random generator
    return std::rand() % max;
}

QPoint* GridBuilder::getRandomAdjacentFreeBlock(QPoint* pos, Grid* grid)
{
    QPoint qp = QPoint(pos->x(), pos->y());
    int num = numberOfFreeAdjacentPositions(&qp, grid);
    int direction = getRandomNumberFrom0To(num);

    //up
    if(pos->x() - 1 >= 0 && !grid->getCell(pos->x() - 1, pos->y()).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x() - 1, pos->y());
        --direction;
    }

    //down
    if(pos->x() + 1 <= grid->getNbRow() - 1 && !grid->getCell(pos->x() + 1, pos->y()).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x() + 1, pos->y());
        --direction;
    }
    //left
    if(pos->y() - 1 >= 0 && !grid->getCell(pos->x(), pos->y() - 1).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x(), pos->y() - 1);
        --direction;
    }
    //right
    if(pos->y() + 1 <= grid->getNbColumn() - 1 && !grid->getCell(pos->x(), pos->y() + 1).isCovered())
    {
        if(direction == 0) return new QPoint(pos->x(), pos->y() + 1);
        --direction;
    }

    return new QPoint(-1,-1);
}

bool GridBuilder::moveAdjacentEndPoint(QPoint* pos, Grid* grid)
{
    Cell adjacentOrigin;
    //up
    if(pos->x() - 1 >= 0 && grid->getCell(pos->x() - 1, pos->y()).isOrigin())
    {
        adjacentOrigin = grid->getCell(pos->x()-1, pos->y());
    }
    //down
    else if(pos->x() + 1 <= grid->getNbRow() - 1 && grid->getCell(pos->x() + 1, pos->y()).isOrigin())
    {
        adjacentOrigin = grid->getCell(pos->x() + 1, pos->y());
    }
    //left
    else if(pos->y() - 1 >= 0 && grid->getCell(pos->x(), pos->y() - 1).isOrigin())
    {
        adjacentOrigin = grid->getCell(pos->x(), pos->y() - 1);
    }
    //right
    else if(pos->y() + 1 <= grid->getNbColumn() - 1 && grid->getCell(pos->x(), pos->y() + 1).isOrigin())
    {
        adjacentOrigin = grid->getCell(pos->x(), pos->y() + 1);
    }
    else
    {
        return false;
    }

    Cell cell = grid->getCell(pos->x(), pos->y());
    cell.setOrigin(true);
    adjacentOrigin.setOrigin(false);
    adjacentOrigin.setPathComplete(false);
    if(adjacentOrigin.next == NULL)
    {
        cell.setPathComplete(true);
        cell.previous[0] = &adjacentOrigin;
        adjacentOrigin.next[0] = &cell;
    }
    else
    {
        adjacentOrigin.previous[0] = &cell;
        cell.next[0] = &adjacentOrigin;
    }

    return true;
}
<|endoftext|>


<commit_before>#ifndef INC_AL_CONTROL_NAV_HPP
#define INC_AL_CONTROL_NAV_HPP

#include "allocore/io/al_Window.hpp"
#include "allocore/spatial/al_CoordinateFrame.hpp"

namespace al {

/// Mapping from keyboard and mouse controls to a Nav object
struct NavInputControl : public InputEventHandler {

	NavInputControl(Nav * nav, double vscale = 0.125, double tscale = 2.)
	: mNav(nav), mVScale(vscale), mTScale(tscale) {}
	virtual ~NavInputControl() {}

	void nav(Nav * v){ mNav=v; }

	virtual bool onKeyDown(const Keyboard& k){

		double vs = nav().velScale();
		double a = mTScale * vs;	// rotational speed: degrees per update
		double v = mVScale * vs;	// speed: units per update

		switch(k.key()){
			case '`':			nav().halt().home(); return false;
			case 's':			nav().halt(); return false;
			case Key::Up:		nav().spinR(-a); return false;
			case Key::Down:		nav().spinR( a); return false;
			case Key::Right:	nav().spinU( a); return false;
			case Key::Left:		nav().spinU(-a); return false;
			case 'q':			nav().spinF( a); return false;
			case 'z':			nav().spinF(-a); return false;
			case 'a':			nav().moveR(-v); return false;
			case 'd':			nav().moveR( v); return false;
			case 'e':			nav().moveU( v); return false;
			case 'c':			nav().moveU(-v); return false;
			case 'x':			nav().moveF(-v); return false;
			case 'w':			nav().moveF( v); return false;
			default:;
		}
		return true;
	}
	virtual bool onKeyUp(const Keyboard& k) {
		switch (k.key()) {
			case Key::Up:
			case Key::Down:		nav().spinR(0); return false;
			case Key::Right:
			case Key::Left:		nav().spinU(0); return false;
			case 'q':
			case 'z':			nav().spinF(0); return false;
			case 'a':
			case 'd':			nav().moveR(0); return false;
			case 'e':
			case 'c':			nav().moveU(0); return false;
			case 'x':
			case 'w':			nav().moveF(0); return false;
			default:;
		}
		return true;
	}

	virtual bool onMouseDrag(const Mouse& m){
		if(m.left()){
			nav().turnU(m.dx() * 0.2);
			nav().turnR(m.dy() * 0.2);
		}
		else if(m.right()){
			nav().turnF(m.dx() * 0.2);
			//incBehind(m.dy()*0.005);
		}
		return false;
	}

	Nav& nav(){ return *mNav; }

protected:
	Nav * mNav;
	double mVScale, mTScale;
};

struct NavInputControlCosm : public NavInputControl {

	NavInputControlCosm(Nav * nav, double vscale = 0.125, double tscale = 2.): NavInputControl(nav, vscale, tscale){}
	virtual ~NavInputControlCosm() {}

	virtual bool onKeyDown(const Keyboard& k){

		double vs = nav().velScale();
		double a = mTScale * vs;	// rotational speed: degrees per update
		double v = mVScale * vs;	// speed: units per update

		switch(k.key()){
			case '`':			nav().halt().home(); return false;
			case 'w':			nav().spinR(-a); return false;
			case 'x':			nav().spinR( a); return false;
			case Key::Right:	nav().spinU( a); return false;
			case Key::Left:		nav().spinU(-a); return false;
			case 'a':			nav().spinF( a); return false;
			case 'd':			nav().spinF(-a); return false;
			case ',':			nav().moveR(-v); return false;
			case '.':			nav().moveR( v); return false;
			case '\'':			nav().moveU( v); return false;
			case '/':			nav().moveU(-v); return false;
			case Key::Up:		nav().moveF( v); return false;
			case Key::Down:		nav().moveF(-v); return false;
			default:;
		}
		return true;
	}

	virtual bool onKeyUp(const Keyboard& k) {
		switch (k.key()) {
			case 'w':
			case 'x':			nav().spinR(0); return false;
			case Key::Right:
			case Key::Left:		nav().spinU(0); return false;
			case 'a':
			case 'd':			nav().spinF(0); return false;
			case ',':
			case '.':			nav().moveR(0); return false;
			case '\'':
			case '/':			nav().moveU(0); return false;
			case Key::Up:
			case Key::Down:		nav().moveF(0); return false;
			default:;
		}
		return true;
	}

	virtual bool onMouseDrag(const Mouse& m){ return true; }
};

} // al::

#endif
<commit_msg>accessors for controlNav<commit_after>#ifndef INC_AL_CONTROL_NAV_HPP
#define INC_AL_CONTROL_NAV_HPP

#include "allocore/io/al_Window.hpp"
#include "allocore/spatial/al_CoordinateFrame.hpp"

namespace al {

/// Mapping from keyboard and mouse controls to a Nav object
struct NavInputControl : public InputEventHandler {

	NavInputControl(Nav * nav, double vscale = 0.125, double tscale = 2.)
	: mNav(nav), mVScale(vscale), mTScale(tscale) {}
	virtual ~NavInputControl() {}

	void nav(Nav * v){ mNav=v; }

	virtual bool onKeyDown(const Keyboard& k){

		double vs = nav().velScale();
		double a = mTScale * vs;	// rotational speed: degrees per update
		double v = mVScale * vs;	// speed: units per update

		switch(k.key()){
			case '`':			nav().halt().home(); return false;
			case 's':			nav().halt(); return false;
			case Key::Up:		nav().spinR(-a); return false;
			case Key::Down:		nav().spinR( a); return false;
			case Key::Right:	nav().spinU( a); return false;
			case Key::Left:		nav().spinU(-a); return false;
			case 'q':			nav().spinF( a); return false;
			case 'z':			nav().spinF(-a); return false;
			case 'a':			nav().moveR(-v); return false;
			case 'd':			nav().moveR( v); return false;
			case 'e':			nav().moveU( v); return false;
			case 'c':			nav().moveU(-v); return false;
			case 'x':			nav().moveF(-v); return false;
			case 'w':			nav().moveF( v); return false;
			default:;
		}
		return true;
	}
	virtual bool onKeyUp(const Keyboard& k) {
		switch (k.key()) {
			case Key::Up:
			case Key::Down:		nav().spinR(0); return false;
			case Key::Right:
			case Key::Left:		nav().spinU(0); return false;
			case 'q':
			case 'z':			nav().spinF(0); return false;
			case 'a':
			case 'd':			nav().moveR(0); return false;
			case 'e':
			case 'c':			nav().moveU(0); return false;
			case 'x':
			case 'w':			nav().moveF(0); return false;
			default:;
		}
		return true;
	}

	virtual bool onMouseDrag(const Mouse& m){
		if(m.left()){
			nav().turnU(m.dx() * 0.2);
			nav().turnR(m.dy() * 0.2);
		}
		else if(m.right()){
			nav().turnF(m.dx() * 0.2);
			//incBehind(m.dy()*0.005);
		}
		return false;
	}

	Nav& nav(){ return *mNav; }

	double vscale() { return mVScale; }
	NavInputControl& vscale(double v) { mVScale=v; return *this; }

	double tscale() { return mTScale; }
	NavInputControl& tscale(double v) { mTScale=v; return *this; }

protected:
	Nav * mNav;
	double mVScale, mTScale;
};

struct NavInputControlCosm : public NavInputControl {

	NavInputControlCosm(Nav * nav, double vscale = 0.125, double tscale = 2.): NavInputControl(nav, vscale, tscale){}
	virtual ~NavInputControlCosm() {}

	virtual bool onKeyDown(const Keyboard& k){

		double vs = nav().velScale();
		double a = mTScale * vs;	// rotational speed: degrees per update
		double v = mVScale * vs;	// speed: units per update

		switch(k.key()){
			case '`':			nav().halt().home(); return false;
			case 'w':			nav().spinR(-a); return false;
			case 'x':			nav().spinR( a); return false;
			case Key::Right:	nav().spinU( a); return false;
			case Key::Left:		nav().spinU(-a); return false;
			case 'a':			nav().spinF( a); return false;
			case 'd':			nav().spinF(-a); return false;
			case ',':			nav().moveR(-v); return false;
			case '.':			nav().moveR( v); return false;
			case '\'':			nav().moveU( v); return false;
			case '/':			nav().moveU(-v); return false;
			case Key::Up:		nav().moveF( v); return false;
			case Key::Down:		nav().moveF(-v); return false;
			default:;
		}
		return true;
	}

	virtual bool onKeyUp(const Keyboard& k) {
		switch (k.key()) {
			case 'w':
			case 'x':			nav().spinR(0); return false;
			case Key::Right:
			case Key::Left:		nav().spinU(0); return false;
			case 'a':
			case 'd':			nav().spinF(0); return false;
			case ',':
			case '.':			nav().moveR(0); return false;
			case '\'':
			case '/':			nav().moveU(0); return false;
			case Key::Up:
			case Key::Down:		nav().moveF(0); return false;
			default:;
		}
		return true;
	}

	virtual bool onMouseDrag(const Mouse& m){ return true; }
};

} // al::

#endif
<|endoftext|>


<commit_before>#ifndef ENGINE_API_NEAREST_API_HPP
#define ENGINE_API_NEAREST_API_HPP

#include "engine/api/base_api.hpp"
#include "engine/api/nearest_parameters.hpp"

#include "engine/api/json_factory.hpp"
#include "engine/phantom_node.hpp"

#include <boost/assert.hpp>

#include <vector>

namespace osrm
{
namespace engine
{
namespace api
{

class NearestAPI final : public BaseAPI
{
  public:
    NearestAPI(const datafacade::BaseDataFacade &facade_, const NearestParameters &parameters_)
        : BaseAPI(facade_, parameters_), parameters(parameters_)
    {
    }

    void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes,
                      osrm::engine::api::ResultT &response) const
    {
        BOOST_ASSERT(phantom_nodes.size() == 1);
        BOOST_ASSERT(parameters.coordinates.size() == 1);

        if (response.is<flatbuffers::FlatBufferBuilder>())
        {
            auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
            MakeResponse(phantom_nodes, fb_result);
        }
        else
        {
            auto &json_result = response.get<util::json::Object>();
            MakeResponse(phantom_nodes, json_result);
        }
    }

    void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes,
                      flatbuffers::FlatBufferBuilder &fb_result) const
    {
        auto data_timestamp = facade.GetTimestamp();
        boost::optional<flatbuffers::Offset<flatbuffers::String>> data_version_string = boost::none;
        if (!data_timestamp.empty())
        {
            data_version_string = fb_result.CreateString(data_timestamp);
        }

        std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
        waypoints.resize(phantom_nodes.front().size());
        std::transform(phantom_nodes.front().begin(),
                       phantom_nodes.front().end(),
                       waypoints.begin(),
                       [this, &fb_result](const PhantomNodeWithDistance &phantom_with_distance) {
                           auto &phantom_node = phantom_with_distance.phantom_node;

                           auto node_values = MakeNodes(phantom_node);
                           fbresult::Uint64Pair nodes{node_values.first, node_values.second};

                           auto waypoint = MakeWaypoint(fb_result, phantom_node);
                           waypoint.add_nodes(&nodes);

                           return waypoint.Finish();
                       });

        auto waypoints_vector = fb_result.CreateVector(waypoints);
        fbresult::FBResultBuilder response(fb_result);
        response.add_waypoints(waypoints_vector);
        if (data_version_string)
        {
            response.add_data_version(*data_version_string);
        }
        fb_result.Finish(response.Finish());
    }
    void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes,
                      util::json::Object &response) const
    {
        util::json::Array waypoints;
        waypoints.values.resize(phantom_nodes.front().size());
        std::transform(phantom_nodes.front().begin(),
                       phantom_nodes.front().end(),
                       waypoints.values.begin(),
                       [this](const PhantomNodeWithDistance &phantom_with_distance) {
                           auto &phantom_node = phantom_with_distance.phantom_node;
                           auto waypoint = MakeWaypoint(phantom_node);

                           util::json::Array nodes;

                           auto node_values = MakeNodes(phantom_node);

                           nodes.values.push_back(node_values.first);
                           nodes.values.push_back(node_values.second);
                           waypoint.values["nodes"] = std::move(nodes);

                           return waypoint;
                       });

        response.values["code"] = "Ok";
        response.values["waypoints"] = std::move(waypoints);
    }

    const NearestParameters &parameters;

  protected:
    std::pair<uint64_t, uint64_t> MakeNodes(const PhantomNode &phantom_node) const
    {
        std::uint64_t from_node = 0;
        std::uint64_t to_node = 0;

        datafacade::BaseDataFacade::NodeForwardRange forward_geometry;
        if (phantom_node.forward_segment_id.enabled)
        {
            auto segment_id = phantom_node.forward_segment_id.id;
            const auto geometry_id = facade.GetGeometryIndex(segment_id).id;
            forward_geometry = facade.GetUncompressedForwardGeometry(geometry_id);

            auto osm_node_id =
                facade.GetOSMNodeIDOfNode(forward_geometry(phantom_node.fwd_segment_position));
            to_node = static_cast<std::uint64_t>(osm_node_id);
        }

        if (phantom_node.reverse_segment_id.enabled)
        {
            auto segment_id = phantom_node.reverse_segment_id.id;
            const auto geometry_id = facade.GetGeometryIndex(segment_id).id;
            const auto geometry = facade.GetUncompressedForwardGeometry(geometry_id);
            auto osm_node_id =
                facade.GetOSMNodeIDOfNode(geometry(phantom_node.fwd_segment_position + 1));
            from_node = static_cast<std::uint64_t>(osm_node_id);
        }
        else if (phantom_node.forward_segment_id.enabled && phantom_node.fwd_segment_position > 0)
        {
            // In the case of one way, rely on forward segment only
            auto osm_node_id =
                facade.GetOSMNodeIDOfNode(forward_geometry(phantom_node.fwd_segment_position - 1));
            from_node = static_cast<std::uint64_t>(osm_node_id);
        }

        return std::make_pair(from_node, to_node);
    }
};

} // ns api
} // ns engine
} // ns osrm

#endif
<commit_msg>Implemented 'skip_waypoints' for the 'Nearest' service.<commit_after>#ifndef ENGINE_API_NEAREST_API_HPP
#define ENGINE_API_NEAREST_API_HPP

#include "engine/api/base_api.hpp"
#include "engine/api/nearest_parameters.hpp"

#include "engine/api/json_factory.hpp"
#include "engine/phantom_node.hpp"
#include "base_result.hpp"

#include <boost/assert.hpp>

#include <vector>

namespace osrm
{
namespace engine
{
namespace api
{

class NearestAPI final : public BaseAPI
{
  public:
    NearestAPI(const datafacade::BaseDataFacade &facade_, const NearestParameters &parameters_)
        : BaseAPI(facade_, parameters_), parameters(parameters_)
    {
    }

    void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes,
                      osrm::engine::api::ResultT &response) const
    {
        BOOST_ASSERT(phantom_nodes.size() == 1);
        BOOST_ASSERT(parameters.coordinates.size() == 1);

        if (response.is<flatbuffers::FlatBufferBuilder>())
        {
            auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
            MakeResponse(phantom_nodes, fb_result);
        }
        else
        {
            auto &json_result = response.get<util::json::Object>();
            MakeResponse(phantom_nodes, json_result);
        }
    }

    void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes,
                      flatbuffers::FlatBufferBuilder &fb_result) const
    {
        auto data_timestamp = facade.GetTimestamp();
        boost::optional<flatbuffers::Offset<flatbuffers::String>> data_version_string = boost::none;
        if (!data_timestamp.empty())
        {
            data_version_string = fb_result.CreateString(data_timestamp);
        }

        flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>> waypoints_vector;
        if (!parameters.skip_waypoints) {
            std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
            waypoints.resize(phantom_nodes.front().size());
            std::transform(phantom_nodes.front().begin(),
                           phantom_nodes.front().end(),
                           waypoints.begin(),
                           [this, &fb_result](const PhantomNodeWithDistance &phantom_with_distance) {
                               auto &phantom_node = phantom_with_distance.phantom_node;

                               auto node_values = MakeNodes(phantom_node);
                               fbresult::Uint64Pair nodes{node_values.first, node_values.second};

                               auto waypoint = MakeWaypoint(fb_result, phantom_node);
                               waypoint.add_nodes(&nodes);

                               return waypoint.Finish();
                           });

            waypoints_vector = fb_result.CreateVector(waypoints);
        }

        fbresult::FBResultBuilder response(fb_result);

        response.add_waypoints(waypoints_vector);
        if (data_version_string)
        {
            response.add_data_version(*data_version_string);
        }
        fb_result.Finish(response.Finish());
    }
    void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes,
                      util::json::Object &response) const
    {
        if (!parameters.skip_waypoints) {
            util::json::Array waypoints;
            waypoints.values.resize(phantom_nodes.front().size());
            std::transform(phantom_nodes.front().begin(),
                           phantom_nodes.front().end(),
                           waypoints.values.begin(),
                           [this](const PhantomNodeWithDistance &phantom_with_distance) {
                               auto &phantom_node = phantom_with_distance.phantom_node;
                               auto waypoint = MakeWaypoint(phantom_node);

                               util::json::Array nodes;

                               auto node_values = MakeNodes(phantom_node);

                               nodes.values.push_back(node_values.first);
                               nodes.values.push_back(node_values.second);
                               waypoint.values["nodes"] = std::move(nodes);

                               return waypoint;
                           });
            response.values["waypoints"] = std::move(waypoints);
        }

        response.values["code"] = "Ok";
    }

    const NearestParameters &parameters;

  protected:
    std::pair<uint64_t, uint64_t> MakeNodes(const PhantomNode &phantom_node) const
    {
        std::uint64_t from_node = 0;
        std::uint64_t to_node = 0;

        datafacade::BaseDataFacade::NodeForwardRange forward_geometry;
        if (phantom_node.forward_segment_id.enabled)
        {
            auto segment_id = phantom_node.forward_segment_id.id;
            const auto geometry_id = facade.GetGeometryIndex(segment_id).id;
            forward_geometry = facade.GetUncompressedForwardGeometry(geometry_id);

            auto osm_node_id =
                facade.GetOSMNodeIDOfNode(forward_geometry(phantom_node.fwd_segment_position));
            to_node = static_cast<std::uint64_t>(osm_node_id);
        }

        if (phantom_node.reverse_segment_id.enabled)
        {
            auto segment_id = phantom_node.reverse_segment_id.id;
            const auto geometry_id = facade.GetGeometryIndex(segment_id).id;
            const auto geometry = facade.GetUncompressedForwardGeometry(geometry_id);
            auto osm_node_id =
                facade.GetOSMNodeIDOfNode(geometry(phantom_node.fwd_segment_position + 1));
            from_node = static_cast<std::uint64_t>(osm_node_id);
        }
        else if (phantom_node.forward_segment_id.enabled && phantom_node.fwd_segment_position > 0)
        {
            // In the case of one way, rely on forward segment only
            auto osm_node_id =
                facade.GetOSMNodeIDOfNode(forward_geometry(phantom_node.fwd_segment_position - 1));
            from_node = static_cast<std::uint64_t>(osm_node_id);
        }

        return std::make_pair(from_node, to_node);
    }
};

} // ns api
} // ns engine
} // ns osrm

#endif
<|endoftext|>


<commit_before>#pragma once
#ifndef OPENGM_POTTS_FUNCTION_HXX
#define OPENGM_POTTS_FUNCTION_HXX

#include <algorithm>
#include <vector>
#include <cmath>

#include "opengm/opengm.hxx"
#include "opengm/functions/function_registration.hxx"
#include "opengm/functions/function_properties_base.hxx"

namespace opengm {

/// Potts function for two variables
///
/// \ingroup functions
template<class T, class I = size_t, class L = size_t>
class PottsFunction
: public FunctionBase<PottsFunction<T, I, L>, T, size_t, size_t>
{
public:
   typedef T ValueType;
   typedef L LabelType;
   typedef I IndexType;

   PottsFunction(const LabelType = 2, const LabelType = 2,
                 const ValueType = ValueType(), const ValueType = ValueType());
   LabelType shape(const size_t) const;
   size_t size() const;
   size_t dimension() const;
   template<class ITERATOR> ValueType operator()(ITERATOR) const;
   bool operator==(const PottsFunction& ) const;
   ValueType valueEqual() const;
   ValueType valueNotEqual() const;
   IndexType numberOfWeights() const;
   ValueType parameter(const size_t index) const;
   ValueType& parameter(const size_t index);

   // specializations
   bool isPotts() const;
   bool isGeneralizedPotts() const;
   ValueType min() const;
   ValueType max() const;
   ValueType sum() const;
   ValueType product() const;
   MinMaxFunctor<ValueType> minMax() const;

private:
   LabelType numberOfLabels1_;
   LabelType numberOfLabels2_;
   ValueType valueEqual_;
   ValueType valueNotEqual_;

friend class FunctionSerialization<PottsFunction<T, I, L> > ;
};

/// \cond HIDDEN_SYMBOLS
/// FunctionRegistration
template<class T, class I, class L>
struct FunctionRegistration<PottsFunction<T, I, L> > {
   enum ID {
      Id = opengm::FUNCTION_TYPE_ID_OFFSET + 6
   };
};

/// FunctionSerialization
template<class T, class I, class L>
class FunctionSerialization<PottsFunction<T, I, L> > {
public:
   typedef typename PottsFunction<T, I, L>::ValueType ValueType;

   static size_t indexSequenceSize(const PottsFunction<T, I, L>&);
   static size_t valueSequenceSize(const PottsFunction<T, I, L>&);
   template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR>
      static void serialize(const PottsFunction<T, I, L>&, INDEX_OUTPUT_ITERATOR, VALUE_OUTPUT_ITERATOR);
   template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR>
      static void deserialize( INDEX_INPUT_ITERATOR, VALUE_INPUT_ITERATOR, PottsFunction<T, I, L>&);
};
/// \endcond

/// constructor
/// \param numberOfLabels1 number of labels of the first variable
/// \param numberOfLabels2 number of labels of the second variable
/// \param valueEqual value if the labels of the two variables are equal
/// \param valueNotEqual value if the labels of the two variables are not equal
template <class T, class I, class L>
inline
PottsFunction<T, I, L>::PottsFunction
(
   const L numberOfLabels1,
   const L numberOfLabels2,
   const T valueEqual,
   const T valueNotEqual
)
:  numberOfLabels1_(numberOfLabels1),
   numberOfLabels2_(numberOfLabels2),
   valueEqual_(valueEqual),
   valueNotEqual_(valueNotEqual)
{}

template <class T, class I, class L>
template <class ITERATOR>
inline T
PottsFunction<T, I, L>::operator()
(
   ITERATOR begin
) const {
   return (begin[0]==begin[1] ? valueEqual_ : valueNotEqual_);
}

template <class T, class I, class L>
inline T
PottsFunction<T, I, L>::valueEqual()const {
   return valueEqual_;
}

template <class T, class I, class L>
inline T
PottsFunction<T, I, L>::valueNotEqual()const {
   return valueEqual_;
}

template <class T, class I, class L>
inline L
PottsFunction<T, I, L>::shape
(
   const size_t i
) const {
   OPENGM_ASSERT(i < 2);
   return (i==0 ? numberOfLabels1_ : numberOfLabels2_);
}

template <class T, class I, class L>
inline size_t
PottsFunction<T, I, L>::dimension() const {
   return 2;
}

template <class T, class I, class L>
inline size_t
PottsFunction<T, I, L>::size() const {
   return numberOfLabels1_*numberOfLabels2_;
}

template<class T, class I, class L>
inline size_t
FunctionSerialization<PottsFunction<T, I, L> >::indexSequenceSize
(
   const PottsFunction<T, I, L> & src
) {
   return 2;
}

template<class T, class I, class L>
inline size_t
FunctionSerialization<PottsFunction<T, I, L> >::valueSequenceSize
(
   const PottsFunction<T, I, L> & src
) {
   return 2;
}

template<class T, class I, class L>
template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR >
inline void
FunctionSerialization<PottsFunction<T, I, L> >::serialize
(
   const PottsFunction<T, I, L> & src,
   INDEX_OUTPUT_ITERATOR indexOutIterator,
   VALUE_OUTPUT_ITERATOR valueOutIterator
) {
   *indexOutIterator = src.shape(0);
   ++indexOutIterator;
   *indexOutIterator = src.shape(1);

   *valueOutIterator = src.valueEqual_;
   ++valueOutIterator;
   *valueOutIterator = src.valueNotEqual_;
}

template<class T, class I, class L>
template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR >
inline void
FunctionSerialization<PottsFunction<T, I, L> >::deserialize
(
   INDEX_INPUT_ITERATOR indexInIterator,
   VALUE_INPUT_ITERATOR valueInIterator,
   PottsFunction<T, I, L> & dst
) {
   const size_t shape1=*indexInIterator;
   ++ indexInIterator;
   const size_t shape2=*indexInIterator;
   const ValueType param1=*valueInIterator;
   ++valueInIterator;
   const ValueType param2=*valueInIterator;
   dst=PottsFunction<T, I, L>(shape1, shape2, param1, param2);
}

template<class T, class I, class L>
inline bool
PottsFunction<T, I, L>::operator==
(
   const PottsFunction & fb
   )const{
   return  numberOfLabels1_ == fb.numberOfLabels1_ &&
      numberOfLabels2_ == fb.numberOfLabels2_ &&
      valueEqual_      == fb.valueEqual_      &&
      valueNotEqual_   == fb.valueNotEqual_;
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::IndexType
PottsFunction<T, I, L>::numberOfWeights() const
{
   return 2;
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::ValueType
PottsFunction<T, I, L>::parameter(
   const size_t index
) const
{
   OPENGM_ASSERT(index < 2);
   return index == 0 ? valueEqual_ : valueNotEqual_;
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::ValueType&
PottsFunction<T, I, L>::parameter(
   const size_t index
)
{
   OPENGM_ASSERT(index < 2);
   return index==0 ? valueEqual_:valueNotEqual_;
}

template<class T, class I, class L>
inline bool
PottsFunction<T, I, L>::isPotts() const
{
   return true;
}

template<class T, class I, class L>
inline bool
PottsFunction<T, I, L>::isGeneralizedPotts() const
{
   return true;
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::ValueType
PottsFunction<T, I, L>::min() const
{
   return valueEqual_<valueNotEqual_ ? valueEqual_ :valueNotEqual_;
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::ValueType
PottsFunction<T, I, L>::max() const
{
   return valueNotEqual_>valueEqual_ ? valueNotEqual_ :valueEqual_;
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::ValueType
PottsFunction<T, I, L>::sum() const
{
   const LabelType minLabels = std::min(numberOfLabels1_, numberOfLabels2_);
   return valueNotEqual_ * static_cast<T>(numberOfLabels1_ * numberOfLabels2_ - minLabels)
      + valueEqual_*static_cast<T>(minLabels);
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::ValueType
PottsFunction<T, I, L>::product() const
{
   const LabelType minLabels = std::min(numberOfLabels1_, numberOfLabels2_);
   // TODO: improve this: do not use std::pow, instead write a proper pow functor class for OpenGM
   // the call of std::pow is ambiguous for many common combinations of types. this is just a
   // work-around with possible loss of precision, e.g. if valuesNotEqual_ is a long double
   const double x1 = static_cast<double>(valueNotEqual_);
   const int n1 = static_cast<int>(numberOfLabels1_ * numberOfLabels2_ - minLabels);
   const double x2 = static_cast<double>(valueEqual_);
   const int n2 = static_cast<int>(minLabels);
   return static_cast<T>(std::pow(x1, n1) * std::pow(x2, n2));
}

template<class T, class I, class L>
inline MinMaxFunctor<typename PottsFunction<T, I, L>::ValueType>
PottsFunction<T, I, L>::minMax() const
{
   if(valueEqual_<valueNotEqual_) {
      return MinMaxFunctor<T>(valueEqual_, valueNotEqual_);
   }
   else {
      return MinMaxFunctor<T>(valueNotEqual_, valueEqual_);
   }
}

} // namespace opengm

#endif // #ifndef OPENGM_POTTS_FUNCTION_HXX
<commit_msg>fixed bug in potts function (function was more or less unused)<commit_after>#pragma once
#ifndef OPENGM_POTTS_FUNCTION_HXX
#define OPENGM_POTTS_FUNCTION_HXX

#include <algorithm>
#include <vector>
#include <cmath>

#include "opengm/opengm.hxx"
#include "opengm/functions/function_registration.hxx"
#include "opengm/functions/function_properties_base.hxx"

namespace opengm {

/// Potts function for two variables
///
/// \ingroup functions
template<class T, class I = size_t, class L = size_t>
class PottsFunction
: public FunctionBase<PottsFunction<T, I, L>, T, size_t, size_t>
{
public:
   typedef T ValueType;
   typedef L LabelType;
   typedef I IndexType;

   PottsFunction(const LabelType = 2, const LabelType = 2,
                 const ValueType = ValueType(), const ValueType = ValueType());
   LabelType shape(const size_t) const;
   size_t size() const;
   size_t dimension() const;
   template<class ITERATOR> ValueType operator()(ITERATOR) const;
   bool operator==(const PottsFunction& ) const;
   ValueType valueEqual() const;
   ValueType valueNotEqual() const;
   IndexType numberOfWeights() const;
   ValueType parameter(const size_t index) const;
   ValueType& parameter(const size_t index);

   // specializations
   bool isPotts() const;
   bool isGeneralizedPotts() const;
   ValueType min() const;
   ValueType max() const;
   ValueType sum() const;
   ValueType product() const;
   MinMaxFunctor<ValueType> minMax() const;

private:
   LabelType numberOfLabels1_;
   LabelType numberOfLabels2_;
   ValueType valueEqual_;
   ValueType valueNotEqual_;

friend class FunctionSerialization<PottsFunction<T, I, L> > ;
};

/// \cond HIDDEN_SYMBOLS
/// FunctionRegistration
template<class T, class I, class L>
struct FunctionRegistration<PottsFunction<T, I, L> > {
   enum ID {
      Id = opengm::FUNCTION_TYPE_ID_OFFSET + 6
   };
};

/// FunctionSerialization
template<class T, class I, class L>
class FunctionSerialization<PottsFunction<T, I, L> > {
public:
   typedef typename PottsFunction<T, I, L>::ValueType ValueType;

   static size_t indexSequenceSize(const PottsFunction<T, I, L>&);
   static size_t valueSequenceSize(const PottsFunction<T, I, L>&);
   template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR>
      static void serialize(const PottsFunction<T, I, L>&, INDEX_OUTPUT_ITERATOR, VALUE_OUTPUT_ITERATOR);
   template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR>
      static void deserialize( INDEX_INPUT_ITERATOR, VALUE_INPUT_ITERATOR, PottsFunction<T, I, L>&);
};
/// \endcond

/// constructor
/// \param numberOfLabels1 number of labels of the first variable
/// \param numberOfLabels2 number of labels of the second variable
/// \param valueEqual value if the labels of the two variables are equal
/// \param valueNotEqual value if the labels of the two variables are not equal
template <class T, class I, class L>
inline
PottsFunction<T, I, L>::PottsFunction
(
   const L numberOfLabels1,
   const L numberOfLabels2,
   const T valueEqual,
   const T valueNotEqual
)
:  numberOfLabels1_(numberOfLabels1),
   numberOfLabels2_(numberOfLabels2),
   valueEqual_(valueEqual),
   valueNotEqual_(valueNotEqual)
{}

template <class T, class I, class L>
template <class ITERATOR>
inline T
PottsFunction<T, I, L>::operator()
(
   ITERATOR begin
) const {
   return (begin[0]==begin[1] ? valueEqual_ : valueNotEqual_);
}

template <class T, class I, class L>
inline T
PottsFunction<T, I, L>::valueEqual()const {
   return valueEqual_;
}

template <class T, class I, class L>
inline T
PottsFunction<T, I, L>::valueNotEqual()const {
   return valueNotEqual_;
}

template <class T, class I, class L>
inline L
PottsFunction<T, I, L>::shape
(
   const size_t i
) const {
   OPENGM_ASSERT(i < 2);
   return (i==0 ? numberOfLabels1_ : numberOfLabels2_);
}

template <class T, class I, class L>
inline size_t
PottsFunction<T, I, L>::dimension() const {
   return 2;
}

template <class T, class I, class L>
inline size_t
PottsFunction<T, I, L>::size() const {
   return numberOfLabels1_*numberOfLabels2_;
}

template<class T, class I, class L>
inline size_t
FunctionSerialization<PottsFunction<T, I, L> >::indexSequenceSize
(
   const PottsFunction<T, I, L> & src
) {
   return 2;
}

template<class T, class I, class L>
inline size_t
FunctionSerialization<PottsFunction<T, I, L> >::valueSequenceSize
(
   const PottsFunction<T, I, L> & src
) {
   return 2;
}

template<class T, class I, class L>
template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR >
inline void
FunctionSerialization<PottsFunction<T, I, L> >::serialize
(
   const PottsFunction<T, I, L> & src,
   INDEX_OUTPUT_ITERATOR indexOutIterator,
   VALUE_OUTPUT_ITERATOR valueOutIterator
) {
   *indexOutIterator = src.shape(0);
   ++indexOutIterator;
   *indexOutIterator = src.shape(1);

   *valueOutIterator = src.valueEqual_;
   ++valueOutIterator;
   *valueOutIterator = src.valueNotEqual_;
}

template<class T, class I, class L>
template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR >
inline void
FunctionSerialization<PottsFunction<T, I, L> >::deserialize
(
   INDEX_INPUT_ITERATOR indexInIterator,
   VALUE_INPUT_ITERATOR valueInIterator,
   PottsFunction<T, I, L> & dst
) {
   const size_t shape1=*indexInIterator;
   ++ indexInIterator;
   const size_t shape2=*indexInIterator;
   const ValueType param1=*valueInIterator;
   ++valueInIterator;
   const ValueType param2=*valueInIterator;
   dst=PottsFunction<T, I, L>(shape1, shape2, param1, param2);
}

template<class T, class I, class L>
inline bool
PottsFunction<T, I, L>::operator==
(
   const PottsFunction & fb
   )const{
   return  numberOfLabels1_ == fb.numberOfLabels1_ &&
      numberOfLabels2_ == fb.numberOfLabels2_ &&
      valueEqual_      == fb.valueEqual_      &&
      valueNotEqual_   == fb.valueNotEqual_;
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::IndexType
PottsFunction<T, I, L>::numberOfWeights() const
{
   return 2;
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::ValueType
PottsFunction<T, I, L>::parameter(
   const size_t index
) const
{
   OPENGM_ASSERT(index < 2);
   return index == 0 ? valueEqual_ : valueNotEqual_;
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::ValueType&
PottsFunction<T, I, L>::parameter(
   const size_t index
)
{
   OPENGM_ASSERT(index < 2);
   return index==0 ? valueEqual_:valueNotEqual_;
}

template<class T, class I, class L>
inline bool
PottsFunction<T, I, L>::isPotts() const
{
   return true;
}

template<class T, class I, class L>
inline bool
PottsFunction<T, I, L>::isGeneralizedPotts() const
{
   return true;
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::ValueType
PottsFunction<T, I, L>::min() const
{
   return valueEqual_<valueNotEqual_ ? valueEqual_ :valueNotEqual_;
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::ValueType
PottsFunction<T, I, L>::max() const
{
   return valueNotEqual_>valueEqual_ ? valueNotEqual_ :valueEqual_;
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::ValueType
PottsFunction<T, I, L>::sum() const
{
   const LabelType minLabels = std::min(numberOfLabels1_, numberOfLabels2_);
   return valueNotEqual_ * static_cast<T>(numberOfLabels1_ * numberOfLabels2_ - minLabels)
      + valueEqual_*static_cast<T>(minLabels);
}

template<class T, class I, class L>
inline typename PottsFunction<T, I, L>::ValueType
PottsFunction<T, I, L>::product() const
{
   const LabelType minLabels = std::min(numberOfLabels1_, numberOfLabels2_);
   // TODO: improve this: do not use std::pow, instead write a proper pow functor class for OpenGM
   // the call of std::pow is ambiguous for many common combinations of types. this is just a
   // work-around with possible loss of precision, e.g. if valuesNotEqual_ is a long double
   const double x1 = static_cast<double>(valueNotEqual_);
   const int n1 = static_cast<int>(numberOfLabels1_ * numberOfLabels2_ - minLabels);
   const double x2 = static_cast<double>(valueEqual_);
   const int n2 = static_cast<int>(minLabels);
   return static_cast<T>(std::pow(x1, n1) * std::pow(x2, n2));
}

template<class T, class I, class L>
inline MinMaxFunctor<typename PottsFunction<T, I, L>::ValueType>
PottsFunction<T, I, L>::minMax() const
{
   if(valueEqual_<valueNotEqual_) {
      return MinMaxFunctor<T>(valueEqual_, valueNotEqual_);
   }
   else {
      return MinMaxFunctor<T>(valueNotEqual_, valueEqual_);
   }
}

} // namespace opengm

#endif // #ifndef OPENGM_POTTS_FUNCTION_HXX
<|endoftext|>


<commit_before>// Copyright (C) 2016 Jonathan Müller <jonathanmueller.dev@gmail.com>
// This file is subject to the license terms in the LICENSE file
// found in the top-level directory of this distribution.

#ifndef TYPE_SAFE_OPTIONAL_REF_HPP_INCLUDED
#define TYPE_SAFE_OPTIONAL_REF_HPP_INCLUDED

#include <type_safe/optional.hpp>

namespace type_safe
{
    /// A `StoragePolicy` for [ts::basic_optional]() that allows optional references.
    ///
    /// The actual `value_type` passed to the optional is [std::reference_wrapper<T>](),
    /// but the reference types are normal references, so `value()` will return a `T&`
    /// and `value_or()` takes a fallback reference of the same type and returns one of them.
    /// Assigning an optional will always change the target of the reference.
    /// You cannot pass rvalues.
    ///
    /// If `XValue` is `true`, you still cannot pass rvalues,
    /// but the result of `value()`/`value_or()` will return an rvalue reference,
    /// to allow moving of the stored value into something else.
    ///
    /// Depending on the const-ness of `T` is the reference to `const` or non-const as well,
    /// unless `XValue` is true`, in which case `T` must not be `const`.
    /// \module optional
    template <typename T, bool XValue = false>
    class reference_optional_storage
    {
        static_assert(!std::is_reference<T>::value, "pass the type without reference");
        static_assert(!XValue || !std::is_const<T>::value, "must not be const if xvalue reference");

        using result_type = typename std::conditional<XValue, T&&, T&>::type;

        struct prevent_rvalues
        {
        };

    public:
        using value_type             = std::reference_wrapper<T>;
        using lvalue_reference       = T&;
        using const_lvalue_reference = lvalue_reference;
        using rvalue_reference       = prevent_rvalues;
        using const_rvalue_reference = rvalue_reference;

        template <typename U>
        using rebind = reference_optional_storage<U, XValue>;

        /// \effects Creates it without a bound reference.
        reference_optional_storage() noexcept : pointer_(nullptr)
        {
        }

        /// \effects Binds the reference to `obj`.
        void create_value(lvalue_reference obj) noexcept
        {
            pointer_ = &obj;
        }

        /// \effects Binds the reference to the same reference in `other`.
        void create_value(const reference_optional_storage& other) noexcept
        {
            pointer_ = other.pointer_;
        }

        /// \effects Binds the same target as `const_ref`.
        /// \param 1
        /// \exclude
        template <typename U,
                  typename = typename std::
                      enable_if<std::is_same<U, typename std::remove_const<T>::type>::value>::type>
        void create_value(const basic_optional<reference_optional_storage<U, XValue>>& const_ref)
        {
            pointer_ = const_ref.has_value() ? &const_ref.value() : nullptr;
        }

        /// \effects Same as `destroy_value()`.
        void create_value(std::nullptr_t) noexcept
        {
            destroy_value();
        }

        void create_value(T&&) = delete;

        /// \effects Binds the reference to the same reference in `other`.
        void copy_value(const reference_optional_storage& other) noexcept
        {
            pointer_ = other.pointer_;
        }

        /// \effects Swaps the reference with the reference in `other`,
        /// i.e. rebinds them, no value change.
        void swap_value(reference_optional_storage& other) noexcept
        {
            std::swap(pointer_, other.pointer_);
        }

        /// \effects Unbinds the reference.
        void destroy_value() noexcept
        {
            pointer_ = nullptr;
        }

        /// \returns `true` if the reference is bound, `false` otherwise.
        bool has_value() const noexcept
        {
            return pointer_ != nullptr;
        }

        /// \returns The target of the reference.
        /// Depending on `XValue`, this will either be `T&` or `T&&`.
        result_type get_value() const noexcept
        {
            return static_cast<result_type>(*pointer_);
        }

        /// \returns Either `get_value()` or `other`.
        /// Depending on `XValue`, this will either be `T&` or `T&&`.
        result_type get_value_or(lvalue_reference other) const
        {
            return has_value() ? get_value() : static_cast<result_type>(other);
        }

    private:
        T* pointer_;
    };

    /// A [ts::basic_optional]() that uses [ts::reference_optional_storage]().
    /// It is an optional reference.
    /// \notes `T` is the type without the reference, i.e. `optional_ref<int>`.
    /// \module optional
    template <typename T>
    using optional_ref = basic_optional<reference_optional_storage<T>>;

    /// \returns A [ts::optional_ref<T>]() to the pointee of `ptr` or `nullopt`.
    /// \module optional
    template <typename T>
    optional_ref<T> ref(T* ptr) noexcept
    {
        return ptr ? optional_ref<T>(*ptr) : nullopt;
    }

    /// \returns A [ts::optional_ref<T>]() to `const` to the pointee of `ptr` or `nullopt`.
    /// \module optional
    template <typename T>
    optional_ref<const T> cref(const T* ptr) noexcept
    {
        return ptr ? optional_ref<const T>(*ptr) : nullopt;
    }

    /// A [ts::basic_optional]() that uses [ts::reference_optional_storage]() with `XValue` being `true`.
    /// It is an optional reference to an xvalue,
    /// i.e. an lvalue that can be moved from, like returned by `std::move()`.
    /// \notes `T` is the type without the reference, i.e. `optional_xvalue_ref<int>`.
    /// \module optional
    template <typename T>
    using optional_xvalue_ref = basic_optional<reference_optional_storage<T, true>>;

    /// \returns A [ts::optional_xvalue_ref<T>]() to the pointee of `ptr` or `nullopt`.
    /// \notes The pointee will be moved from when you call `value()`.
    /// \module optional
    template <typename T>
    optional_xvalue_ref<T> xref(T* ptr) noexcept
    {
        return ptr ? optional_xvalue_ref<T>(*ptr) : nullopt;
    }

    /// \returns A [ts::optional<T>]() containing a copy of the value of `ref`
    /// if there is any value.
    /// \requires `T` must be copyable.
    /// \module optional
    template <typename T>
    optional<typename std::remove_const<T>::type> copy(const optional_ref<T>& ref)
    {
        return ref.has_value() ? make_optional(ref.value()) : nullopt;
    }

    /// \returns A [ts::optional<T>]() containing a copy of the value of `ref` created by move constructing
    /// if there is any value.
    /// \requires `T` must be moveable.
    /// \module optional
    template <typename T>
    optional<T> move(const optional_xvalue_ref<T>& ref) noexcept(
        std::is_nothrow_move_constructible<T>::value)
    {
        return ref.has_value() ? make_optional(ref.value()) : nullopt;
    }
} // namespace type_safe

#endif // TYPE_SAFE_OPTIONAL_REF_HPP_INCLUDED
<commit_msg>Add ref/cref/xref taking references<commit_after>// Copyright (C) 2016 Jonathan Müller <jonathanmueller.dev@gmail.com>
// This file is subject to the license terms in the LICENSE file
// found in the top-level directory of this distribution.

#ifndef TYPE_SAFE_OPTIONAL_REF_HPP_INCLUDED
#define TYPE_SAFE_OPTIONAL_REF_HPP_INCLUDED

#include <type_safe/optional.hpp>

namespace type_safe
{
    /// A `StoragePolicy` for [ts::basic_optional]() that allows optional references.
    ///
    /// The actual `value_type` passed to the optional is [std::reference_wrapper<T>](),
    /// but the reference types are normal references, so `value()` will return a `T&`
    /// and `value_or()` takes a fallback reference of the same type and returns one of them.
    /// Assigning an optional will always change the target of the reference.
    /// You cannot pass rvalues.
    ///
    /// If `XValue` is `true`, you still cannot pass rvalues,
    /// but the result of `value()`/`value_or()` will return an rvalue reference,
    /// to allow moving of the stored value into something else.
    ///
    /// Depending on the const-ness of `T` is the reference to `const` or non-const as well,
    /// unless `XValue` is true`, in which case `T` must not be `const`.
    /// \module optional
    template <typename T, bool XValue = false>
    class reference_optional_storage
    {
        static_assert(!std::is_reference<T>::value, "pass the type without reference");
        static_assert(!XValue || !std::is_const<T>::value, "must not be const if xvalue reference");

        using result_type = typename std::conditional<XValue, T&&, T&>::type;

        struct prevent_rvalues
        {
        };

    public:
        using value_type             = std::reference_wrapper<T>;
        using lvalue_reference       = T&;
        using const_lvalue_reference = lvalue_reference;
        using rvalue_reference       = prevent_rvalues;
        using const_rvalue_reference = rvalue_reference;

        template <typename U>
        using rebind = reference_optional_storage<U, XValue>;

        /// \effects Creates it without a bound reference.
        reference_optional_storage() noexcept : pointer_(nullptr)
        {
        }

        /// \effects Binds the reference to `obj`.
        void create_value(lvalue_reference obj) noexcept
        {
            pointer_ = &obj;
        }

        /// \effects Binds the reference to the same reference in `other`.
        void create_value(const reference_optional_storage& other) noexcept
        {
            pointer_ = other.pointer_;
        }

        /// \effects Binds the same target as `const_ref`.
        /// \param 1
        /// \exclude
        template <typename U,
                  typename = typename std::
                      enable_if<std::is_same<U, typename std::remove_const<T>::type>::value>::type>
        void create_value(const basic_optional<reference_optional_storage<U, XValue>>& const_ref)
        {
            pointer_ = const_ref.has_value() ? &const_ref.value() : nullptr;
        }

        /// \effects Same as `destroy_value()`.
        void create_value(std::nullptr_t) noexcept
        {
            destroy_value();
        }

        void create_value(T&&) = delete;

        /// \effects Binds the reference to the same reference in `other`.
        void copy_value(const reference_optional_storage& other) noexcept
        {
            pointer_ = other.pointer_;
        }

        /// \effects Swaps the reference with the reference in `other`,
        /// i.e. rebinds them, no value change.
        void swap_value(reference_optional_storage& other) noexcept
        {
            std::swap(pointer_, other.pointer_);
        }

        /// \effects Unbinds the reference.
        void destroy_value() noexcept
        {
            pointer_ = nullptr;
        }

        /// \returns `true` if the reference is bound, `false` otherwise.
        bool has_value() const noexcept
        {
            return pointer_ != nullptr;
        }

        /// \returns The target of the reference.
        /// Depending on `XValue`, this will either be `T&` or `T&&`.
        result_type get_value() const noexcept
        {
            return static_cast<result_type>(*pointer_);
        }

        /// \returns Either `get_value()` or `other`.
        /// Depending on `XValue`, this will either be `T&` or `T&&`.
        result_type get_value_or(lvalue_reference other) const
        {
            return has_value() ? get_value() : static_cast<result_type>(other);
        }

    private:
        T* pointer_;
    };

    /// A [ts::basic_optional]() that uses [ts::reference_optional_storage]().
    /// It is an optional reference.
    /// \notes `T` is the type without the reference, i.e. `optional_ref<int>`.
    /// \module optional
    template <typename T>
    using optional_ref = basic_optional<reference_optional_storage<T>>;

    /// \returns A [ts::optional_ref<T>]() to the pointee of `ptr` or `nullopt`.
    /// \module optional
    template <typename T>
    optional_ref<T> ref(T* ptr) noexcept
    {
        return ptr ? optional_ref<T>(*ptr) : nullopt;
    }

    /// \returns A [ts::optional_ref<T>]() to `obj`.
    /// \module optional
    template <typename T>
    optional_ref<T> ref(T& obj) noexcept
    {
        return optional_ref<T>(obj);
    }

    /// \returns A [ts::optional_ref<T>]() to `const` to the pointee of `ptr` or `nullopt`.
    /// \module optional
    template <typename T>
    optional_ref<const T> cref(const T* ptr) noexcept
    {
        return ptr ? optional_ref<const T>(*ptr) : nullopt;
    }

    /// \returns A [ts::optional_ref<T>]() to `obj`.
    /// \module optional
    template <typename T>
    optional_ref<const T> cref(const T& obj) noexcept
    {
        return optional_ref<const T>(obj);
    }

    /// A [ts::basic_optional]() that uses [ts::reference_optional_storage]() with `XValue` being `true`.
    /// It is an optional reference to an xvalue,
    /// i.e. an lvalue that can be moved from, like returned by `std::move()`.
    /// \notes `T` is the type without the reference, i.e. `optional_xvalue_ref<int>`.
    /// \module optional
    template <typename T>
    using optional_xvalue_ref = basic_optional<reference_optional_storage<T, true>>;

    /// \returns A [ts::optional_xvalue_ref<T>]() to the pointee of `ptr` or `nullopt`.
    /// \notes The pointee will be moved from when you call `value()`.
    /// \module optional
    template <typename T>
    optional_xvalue_ref<T> xref(T* ptr) noexcept
    {
        return ptr ? optional_xvalue_ref<T>(*ptr) : nullopt;
    }

    /// \returns A [ts::optional_xvalue_ref<T>]() to `obj`.
    /// \notes The object will be moved from when you call `value()`.
    /// \module optional
    template <typename T>
    optional_xvalue_ref<T> xref(T& obj) noexcept
    {
        return optional_xvalue_ref<T>(obj);
    }

    /// \returns A [ts::optional<T>]() containing a copy of the value of `ref`
    /// if there is any value.
    /// \requires `T` must be copyable.
    /// \module optional
    template <typename T>
    optional<typename std::remove_const<T>::type> copy(const optional_ref<T>& ref)
    {
        return ref.has_value() ? make_optional(ref.value()) : nullopt;
    }

    /// \returns A [ts::optional<T>]() containing a copy of the value of `ref` created by move constructing
    /// if there is any value.
    /// \requires `T` must be moveable.
    /// \module optional
    template <typename T>
    optional<T> move(const optional_xvalue_ref<T>& ref) noexcept(
        std::is_nothrow_move_constructible<T>::value)
    {
        return ref.has_value() ? make_optional(ref.value()) : nullopt;
    }
} // namespace type_safe

#endif // TYPE_SAFE_OPTIONAL_REF_HPP_INCLUDED
<|endoftext|>


<commit_before>//============================================================================
// include/vsmc/internal/compiler.hpp
//----------------------------------------------------------------------------
//
//                         vSMC: Scalable Monte Carlo
//
// This file is distribured under the 2-clauses BSD License.
// See LICENSE for details.
//============================================================================

#ifndef VSMC_INTERNAL_COMPILER_HPP
#define VSMC_INTERNAL_COMPILER_HPP

#include <cstddef>

#if defined(__APPLE__) || defined(__MACOSX)
#include <Availability.h>
#define VSMC_MAC_10_0  __MAC_10_0
#define VSMC_MAC_10_1  __MAC_10_1
#define VSMC_MAC_10_2  __MAC_10_2
#define VSMC_MAC_10_3  __MAC_10_3
#define VSMC_MAC_10_4  __MAC_10_4
#define VSMC_MAC_10_5  __MAC_10_5
#define VSMC_MAC_10_6  __MAC_10_6
#define VSMC_MAC_10_7  __MAC_10_7
#define VSMC_MAC_10_8  __MAC_10_8
#define VSMC_MAC_10_9  __MAC_10_9
#define VSMC_MAC_10_10 __MAC_10_10
#define VSMC_MAC_VERSION __MAC_OS_X_VERSION_MIN_REQUIRED
#define VSMC_MAC_VERSION_MIN_REQUIRED(ver) VSMC_MAC_VERSION >= ver
#else
#define VSMC_MAC_VERSION_MIN_REQUIRED(ver) 0
#endif

#if defined(__APPLE__) || defined(__MACOSX)
#if VSMC_MAC_VERSION_MIN_REQUIRED(VSMC_MAC_10_5)
#ifndef VSMC_HAS_POSIX
#define VSMC_HAS_POISX 1
#endif
#endif
#else
#include <stdlib.h>
#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L
#ifndef VSMC_HAS_POSIX
#define VSMC_HAS_POSIX 1
#endif
#endif // _POSIX_C_SOURCE >= 200112L
#if defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600
#ifndef VSMC_HAS_POSIX
#define VSMC_HAS_POSIX 1
#endif
#endif // _XOPEN_SOURCE >= 600
#endif // __APPLE__

#ifndef VSMC_HAS_POSIX
#define VSMC_HAS_POSIX 0
#endif

#if defined(__INTEL_COMPILER)
#include <vsmc/internal/compiler/intel.hpp>
#elif defined(__clang__)
#include <vsmc/internal/compiler/clang.hpp>
#elif defined(__OPEN64__)
#include <vsmc/internal/compiler/open64.hpp>
#elif defined(__SUNPRO_CC)
#include <vsmc/internal/compiler/sunpro.hpp>
#elif defined(__GNUC__)
#include <vsmc/internal/compiler/gcc.hpp>
#elif defined(_MSC_VER)
#include <vsmc/internal/compiler/msvc.hpp>
#endif

//  C++11 language features

#ifndef VSMC_HAS_CXX11_LONG_LONG
#define VSMC_HAS_CXX11_LONG_LONG 0
#endif

#ifndef VSMC_HAS_CXX11_ACCESS_CONTROL_SFINAE
#define VSMC_HAS_CXX11_ACCESS_CONTROL_SFINAE 0
#endif

#ifndef VSMC_HAS_CXX11_ALIAS_TEMPLATES
#define VSMC_HAS_CXX11_ALIAS_TEMPLATES 0
#endif

#ifndef VSMC_HAS_CXX11_ALIGNAS
#define VSMC_HAS_CXX11_ALIGNAS 0
#endif

#ifndef VSMC_HAS_CXX11_ATTRIBUTES
#define VSMC_HAS_CXX11_ATTRIBUTES 0
#endif

#ifndef VSMC_HAS_CXX11_AUTO_TYPE
#define VSMC_HAS_CXX11_AUTO_TYPE 0
#endif

#ifndef VSMC_HAS_CXX11_CONSTEXPR
#define VSMC_HAS_CXX11_CONSTEXPR 0
#endif

#ifndef VSMC_HAS_CXX11_DECLTYPE
#define VSMC_HAS_CXX11_DECLTYPE 0
#endif

#ifndef VSMC_HAS_CXX11_DEFAULT_FUNCTION_TEMPLATE_ARGS
#define VSMC_HAS_CXX11_DEFAULT_FUNCTION_TEMPLATE_ARGS 0
#endif

#ifndef VSMC_HAS_CXX11_DEFAULTED_FUNCTIONS
#define VSMC_HAS_CXX11_DEFAULTED_FUNCTIONS 0
#endif

#ifndef VSMC_HAS_CXX11_DELEGATING_CONSTRUCTORS
#define VSMC_HAS_CXX11_DELEGATING_CONSTRUCTORS 0
#endif

#ifndef VSMC_HAS_CXX11_DELETED_FUNCTIONS
#define VSMC_HAS_CXX11_DELETED_FUNCTIONS 0
#endif

#ifndef VSMC_HAS_CXX11_EXPLICIT_CONVERSIONS
#define VSMC_HAS_CXX11_EXPLICIT_CONVERSIONS 0
#endif

#ifndef VSMC_HAS_CXX11_GENERALIZED_INITIALIZERS
#define VSMC_HAS_CXX11_GENERALIZED_INITIALIZERS 0
#endif

#ifndef VSMC_HAS_CXX11_IMPLICIT_MOVES
#define VSMC_HAS_CXX11_IMPLICIT_MOVES 0
#endif

#ifndef VSMC_HAS_CXX11_INHERITING_CONSTRUCTORS
#define VSMC_HAS_CXX11_INHERITING_CONSTRUCTORS 0
#endif

#ifndef VSMC_HAS_CXX11_INLINE_NAMESPACES
#define VSMC_HAS_CXX11_INLINE_NAMESPACES 0
#endif

#ifndef VSMC_HAS_CXX11_LAMBDAS
#define VSMC_HAS_CXX11_LAMBDAS 0
#endif

#ifndef VSMC_HAS_CXX11_LOCAL_TYPE_TEMPLATE_ARGS
#define VSMC_HAS_CXX11_LOCAL_TYPE_TEMPLATE_ARGS 0
#endif

#ifndef VSMC_HAS_CXX11_NOEXCEPT
#define VSMC_HAS_CXX11_NOEXCEPT 0
#endif

#ifndef VSMC_HAS_CXX11_NONSTATIC_MEMBER_INIT
#define VSMC_HAS_CXX11_NONSTATIC_MEMBER_INIT 0
#endif

#ifndef VSMC_HAS_CXX11_NULLPTR
#define VSMC_HAS_CXX11_NULLPTR 0
#endif

#ifndef VSMC_HAS_CXX11_OVERRIDE_CONTROL
#define VSMC_HAS_CXX11_OVERRIDE_CONTROL 0
#endif

#ifndef VSMC_HAS_CXX11_RANGE_FOR
#define VSMC_HAS_CXX11_RANGE_FOR 0
#endif

#ifndef VSMC_HAS_CXX11_RAW_STRING_LITERALS
#define VSMC_HAS_CXX11_RAW_STRING_LITERALS 0
#endif

#ifndef VSMC_HAS_CXX11_REFERENCE_QUALIFIED_FUNCTIONS
#define VSMC_HAS_CXX11_REFERENCE_QUALIFIED_FUNCTIONS 0
#endif

#ifndef VSMC_HAS_CXX11_RVALUE_REFERENCES
#define VSMC_HAS_CXX11_RVALUE_REFERENCES 0
#endif

#ifndef VSMC_HAS_CXX11_STATIC_ASSERT
#define VSMC_HAS_CXX11_STATIC_ASSERT 0
#endif

#ifndef VSMC_HAS_CXX11_STRONG_ENUMS
#define VSMC_HAS_CXX11_STRONG_ENUMS 0
#endif

#ifndef VSMC_HAS_CXX11_THREAD_LOCAL
#define VSMC_HAS_CXX11_THREAD_LOCAL 0
#endif

#ifndef VSMC_HAS_CXX11_TRAILING_RETURN
#define VSMC_HAS_CXX11_TRAILING_RETURN 0
#endif

#ifndef VSMC_HAS_CXX11_UNICODE_LITERALS
#define VSMC_HAS_CXX11_UNICODE_LITERALS 0
#endif

#ifndef VSMC_HAS_CXX11_UNRESTRICTED_UNIONS
#define VSMC_HAS_CXX11_UNRESTRICTED_UNIONS 0
#endif

#ifndef VSMC_HAS_CXX11_USER_LITERALS
#define VSMC_HAS_CXX11_USER_LITERALS 0
#endif

#ifndef VSMC_HAS_CXX11_VARIADIC_TEMPLATES
#define VSMC_HAS_CXX11_VARIADIC_TEMPLATES 0
#endif

//  C++11 library features

#ifndef VSMC_HAS_CXX11LIB_ALGORITHM
#define VSMC_HAS_CXX11LIB_ALGORITHM 0
#endif

#ifndef VSMC_HAS_CXX11LIB_CHRONO
#define VSMC_HAS_CXX11LIB_CHRONO 0
#endif

#ifndef VSMC_HAS_CXX11LIB_CMATH
#define VSMC_HAS_CXX11LIB_CMATH 0
#endif

#ifndef VSMC_HAS_CXX11LIB_FUNCTIONAL
#define VSMC_HAS_CXX11LIB_FUNCTIONAL 0
#endif

#ifndef VSMC_HAS_CXX11LIB_FUTURE
#define VSMC_HAS_CXX11LIB_FUTURE 0
#endif

#ifndef VSMC_HAS_CXX11LIB_MUTEX
#define VSMC_HAS_CXX11LIB_MUTEX 0
#endif

#ifndef VSMC_HAS_CXX11LIB_RANDOM
#define VSMC_HAS_CXX11LIB_RANDOM 0
#endif

#ifndef VSMC_HAS_CXX11LIB_THREAD
#define VSMC_HAS_CXX11LIB_THREAD 0
#endif

#ifndef VSMC_HAS_CXX11LIB_TUPLE
#define VSMC_HAS_CXX11LIB_TUPLE 0
#endif

#ifndef VSMC_USE_CXX11LIB_FUTURE
#define VSMC_USE_CXX11LIB_FUTURE VSMC_HAS_CXX11LIB_FUTURE
#endif

// C99 library features

#ifndef VSMC_HAS_C99LIB_MATH
#define VSMC_HAS_C99LIB_MATH 0
#endif

// Target specific features

#ifndef VSMC_HAS_INT128
#define VSMC_HAS_INT128 0
#endif

#ifndef VSMC_HAS_AES_NI
#define VSMC_HAS_AES_NI 0
#endif

#ifndef VSMC_HAS_RDRAND
#define VSMC_HAS_RDRAND 0
#endif

#if VSMC_MAC_VERSION_MIN_REQUIRED(VSMC_MAC_10_7)
#ifndef VSMC_HAS_GCD_LION
#define VSMC_HAS_GCD_LION 1
#endif
#endif

#endif // VSMC_INTERNAL_COMPILER_HPP
<commit_msg>Fix Mac POSIX macro typo<commit_after>//============================================================================
// include/vsmc/internal/compiler.hpp
//----------------------------------------------------------------------------
//
//                         vSMC: Scalable Monte Carlo
//
// This file is distribured under the 2-clauses BSD License.
// See LICENSE for details.
//============================================================================

#ifndef VSMC_INTERNAL_COMPILER_HPP
#define VSMC_INTERNAL_COMPILER_HPP

#include <cstddef>

#if defined(__APPLE__) || defined(__MACOSX)
#include <Availability.h>
#define VSMC_MAC_10_0  __MAC_10_0
#define VSMC_MAC_10_1  __MAC_10_1
#define VSMC_MAC_10_2  __MAC_10_2
#define VSMC_MAC_10_3  __MAC_10_3
#define VSMC_MAC_10_4  __MAC_10_4
#define VSMC_MAC_10_5  __MAC_10_5
#define VSMC_MAC_10_6  __MAC_10_6
#define VSMC_MAC_10_7  __MAC_10_7
#define VSMC_MAC_10_8  __MAC_10_8
#define VSMC_MAC_10_9  __MAC_10_9
#define VSMC_MAC_10_10 __MAC_10_10
#define VSMC_MAC_VERSION __MAC_OS_X_VERSION_MIN_REQUIRED
#define VSMC_MAC_VERSION_MIN_REQUIRED(ver) VSMC_MAC_VERSION >= ver
#else
#define VSMC_MAC_VERSION_MIN_REQUIRED(ver) 0
#endif

#if defined(__APPLE__) || defined(__MACOSX)
#if VSMC_MAC_VERSION_MIN_REQUIRED(VSMC_MAC_10_5)
#ifndef VSMC_HAS_POSIX
#define VSMC_HAS_POSIX 1
#endif
#endif
#else
#include <stdlib.h>
#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L
#ifndef VSMC_HAS_POSIX
#define VSMC_HAS_POSIX 1
#endif
#endif // _POSIX_C_SOURCE >= 200112L
#if defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600
#ifndef VSMC_HAS_POSIX
#define VSMC_HAS_POSIX 1
#endif
#endif // _XOPEN_SOURCE >= 600
#endif // __APPLE__

#ifndef VSMC_HAS_POSIX
#define VSMC_HAS_POSIX 0
#endif

#if defined(__INTEL_COMPILER)
#include <vsmc/internal/compiler/intel.hpp>
#elif defined(__clang__)
#include <vsmc/internal/compiler/clang.hpp>
#elif defined(__OPEN64__)
#include <vsmc/internal/compiler/open64.hpp>
#elif defined(__SUNPRO_CC)
#include <vsmc/internal/compiler/sunpro.hpp>
#elif defined(__GNUC__)
#include <vsmc/internal/compiler/gcc.hpp>
#elif defined(_MSC_VER)
#include <vsmc/internal/compiler/msvc.hpp>
#endif

//  C++11 language features

#ifndef VSMC_HAS_CXX11_LONG_LONG
#define VSMC_HAS_CXX11_LONG_LONG 0
#endif

#ifndef VSMC_HAS_CXX11_ACCESS_CONTROL_SFINAE
#define VSMC_HAS_CXX11_ACCESS_CONTROL_SFINAE 0
#endif

#ifndef VSMC_HAS_CXX11_ALIAS_TEMPLATES
#define VSMC_HAS_CXX11_ALIAS_TEMPLATES 0
#endif

#ifndef VSMC_HAS_CXX11_ALIGNAS
#define VSMC_HAS_CXX11_ALIGNAS 0
#endif

#ifndef VSMC_HAS_CXX11_ATTRIBUTES
#define VSMC_HAS_CXX11_ATTRIBUTES 0
#endif

#ifndef VSMC_HAS_CXX11_AUTO_TYPE
#define VSMC_HAS_CXX11_AUTO_TYPE 0
#endif

#ifndef VSMC_HAS_CXX11_CONSTEXPR
#define VSMC_HAS_CXX11_CONSTEXPR 0
#endif

#ifndef VSMC_HAS_CXX11_DECLTYPE
#define VSMC_HAS_CXX11_DECLTYPE 0
#endif

#ifndef VSMC_HAS_CXX11_DEFAULT_FUNCTION_TEMPLATE_ARGS
#define VSMC_HAS_CXX11_DEFAULT_FUNCTION_TEMPLATE_ARGS 0
#endif

#ifndef VSMC_HAS_CXX11_DEFAULTED_FUNCTIONS
#define VSMC_HAS_CXX11_DEFAULTED_FUNCTIONS 0
#endif

#ifndef VSMC_HAS_CXX11_DELEGATING_CONSTRUCTORS
#define VSMC_HAS_CXX11_DELEGATING_CONSTRUCTORS 0
#endif

#ifndef VSMC_HAS_CXX11_DELETED_FUNCTIONS
#define VSMC_HAS_CXX11_DELETED_FUNCTIONS 0
#endif

#ifndef VSMC_HAS_CXX11_EXPLICIT_CONVERSIONS
#define VSMC_HAS_CXX11_EXPLICIT_CONVERSIONS 0
#endif

#ifndef VSMC_HAS_CXX11_GENERALIZED_INITIALIZERS
#define VSMC_HAS_CXX11_GENERALIZED_INITIALIZERS 0
#endif

#ifndef VSMC_HAS_CXX11_IMPLICIT_MOVES
#define VSMC_HAS_CXX11_IMPLICIT_MOVES 0
#endif

#ifndef VSMC_HAS_CXX11_INHERITING_CONSTRUCTORS
#define VSMC_HAS_CXX11_INHERITING_CONSTRUCTORS 0
#endif

#ifndef VSMC_HAS_CXX11_INLINE_NAMESPACES
#define VSMC_HAS_CXX11_INLINE_NAMESPACES 0
#endif

#ifndef VSMC_HAS_CXX11_LAMBDAS
#define VSMC_HAS_CXX11_LAMBDAS 0
#endif

#ifndef VSMC_HAS_CXX11_LOCAL_TYPE_TEMPLATE_ARGS
#define VSMC_HAS_CXX11_LOCAL_TYPE_TEMPLATE_ARGS 0
#endif

#ifndef VSMC_HAS_CXX11_NOEXCEPT
#define VSMC_HAS_CXX11_NOEXCEPT 0
#endif

#ifndef VSMC_HAS_CXX11_NONSTATIC_MEMBER_INIT
#define VSMC_HAS_CXX11_NONSTATIC_MEMBER_INIT 0
#endif

#ifndef VSMC_HAS_CXX11_NULLPTR
#define VSMC_HAS_CXX11_NULLPTR 0
#endif

#ifndef VSMC_HAS_CXX11_OVERRIDE_CONTROL
#define VSMC_HAS_CXX11_OVERRIDE_CONTROL 0
#endif

#ifndef VSMC_HAS_CXX11_RANGE_FOR
#define VSMC_HAS_CXX11_RANGE_FOR 0
#endif

#ifndef VSMC_HAS_CXX11_RAW_STRING_LITERALS
#define VSMC_HAS_CXX11_RAW_STRING_LITERALS 0
#endif

#ifndef VSMC_HAS_CXX11_REFERENCE_QUALIFIED_FUNCTIONS
#define VSMC_HAS_CXX11_REFERENCE_QUALIFIED_FUNCTIONS 0
#endif

#ifndef VSMC_HAS_CXX11_RVALUE_REFERENCES
#define VSMC_HAS_CXX11_RVALUE_REFERENCES 0
#endif

#ifndef VSMC_HAS_CXX11_STATIC_ASSERT
#define VSMC_HAS_CXX11_STATIC_ASSERT 0
#endif

#ifndef VSMC_HAS_CXX11_STRONG_ENUMS
#define VSMC_HAS_CXX11_STRONG_ENUMS 0
#endif

#ifndef VSMC_HAS_CXX11_THREAD_LOCAL
#define VSMC_HAS_CXX11_THREAD_LOCAL 0
#endif

#ifndef VSMC_HAS_CXX11_TRAILING_RETURN
#define VSMC_HAS_CXX11_TRAILING_RETURN 0
#endif

#ifndef VSMC_HAS_CXX11_UNICODE_LITERALS
#define VSMC_HAS_CXX11_UNICODE_LITERALS 0
#endif

#ifndef VSMC_HAS_CXX11_UNRESTRICTED_UNIONS
#define VSMC_HAS_CXX11_UNRESTRICTED_UNIONS 0
#endif

#ifndef VSMC_HAS_CXX11_USER_LITERALS
#define VSMC_HAS_CXX11_USER_LITERALS 0
#endif

#ifndef VSMC_HAS_CXX11_VARIADIC_TEMPLATES
#define VSMC_HAS_CXX11_VARIADIC_TEMPLATES 0
#endif

//  C++11 library features

#ifndef VSMC_HAS_CXX11LIB_ALGORITHM
#define VSMC_HAS_CXX11LIB_ALGORITHM 0
#endif

#ifndef VSMC_HAS_CXX11LIB_CHRONO
#define VSMC_HAS_CXX11LIB_CHRONO 0
#endif

#ifndef VSMC_HAS_CXX11LIB_CMATH
#define VSMC_HAS_CXX11LIB_CMATH 0
#endif

#ifndef VSMC_HAS_CXX11LIB_FUNCTIONAL
#define VSMC_HAS_CXX11LIB_FUNCTIONAL 0
#endif

#ifndef VSMC_HAS_CXX11LIB_FUTURE
#define VSMC_HAS_CXX11LIB_FUTURE 0
#endif

#ifndef VSMC_HAS_CXX11LIB_MUTEX
#define VSMC_HAS_CXX11LIB_MUTEX 0
#endif

#ifndef VSMC_HAS_CXX11LIB_RANDOM
#define VSMC_HAS_CXX11LIB_RANDOM 0
#endif

#ifndef VSMC_HAS_CXX11LIB_THREAD
#define VSMC_HAS_CXX11LIB_THREAD 0
#endif

#ifndef VSMC_HAS_CXX11LIB_TUPLE
#define VSMC_HAS_CXX11LIB_TUPLE 0
#endif

#ifndef VSMC_USE_CXX11LIB_FUTURE
#define VSMC_USE_CXX11LIB_FUTURE VSMC_HAS_CXX11LIB_FUTURE
#endif

// C99 library features

#ifndef VSMC_HAS_C99LIB_MATH
#define VSMC_HAS_C99LIB_MATH 0
#endif

// Target specific features

#ifndef VSMC_HAS_INT128
#define VSMC_HAS_INT128 0
#endif

#ifndef VSMC_HAS_AES_NI
#define VSMC_HAS_AES_NI 0
#endif

#ifndef VSMC_HAS_RDRAND
#define VSMC_HAS_RDRAND 0
#endif

#if VSMC_MAC_VERSION_MIN_REQUIRED(VSMC_MAC_10_7)
#ifndef VSMC_HAS_GCD_LION
#define VSMC_HAS_GCD_LION 1
#endif
#endif

#endif // VSMC_INTERNAL_COMPILER_HPP
<|endoftext|>


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

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */

//Iterative Solution.
class Solution {
    queue<TreeLinkNode*> memory;
public:
    void connect(TreeLinkNode *root) {
        if(!root)
            return;

        memory.push(root);

        TreeLinkNode *front;

        while(!memory.empty())
        {
            front = memory.front();
            memory.pop();

            if(front->left)
            {
                front->left->next = front->right;
                memory.push(front->left);
            }

            if(front->next && front->right)
                front->right->next = front->next->left;

            if(front->right)
                memory.push(front->right);
        }
    }
};

//Recursive Solution.
class Solution {
public:
    void connect(TreeLinkNode *root) {
        if(!root)
            return;

        if(root->left)
            root->left->next = root->right;

        if(root->next && root->right)
            root->right->next = root->next->left;

        connect(root->left);
        connect(root->right);
    }
};

//One More Recursive Solution - Works for any tree. O(N) - Time, O(H) - Space (Except Recursion Stack).
class Solution {
    void connect(TreeLinkNode* root, unordered_map<int, TreeLinkNode*>& memory, int level)
    {
        if(root == nullptr)
            return;

        if(memory.find(level) != memory.end())
            memory[level]->next = root;

        memory[level] = root;

        connect(root->left, memory, level+1);
        connect(root->right, memory, level+1);

        return;
    }
public:
    void connect(TreeLinkNode *root) {
        if(root == nullptr)
            return;

        unordered_map<int, TreeLinkNode*> memory;
        connect(root, memory, 0);

        return;
    }
};

//One More Iterative Solution - Works for any tree. Time - O(N), Space - O(1).
class Solution {
    TreeLinkNode* getNext(TreeLinkNode *root)
    {
        root = root->next;

        while(root)
        {
            if(root->left)
                return root->left;

            if(root->right)
                return root->right;

            root = root->next;
        }

        return NULL;
    }
public:
    void connect(TreeLinkNode *root) {
        if(root == NULL)
            return;

        root->next = NULL;

        TreeLinkNode *ptr1, *ptr2;

        ptr1 = root;

        while(ptr1)
        {
            ptr2 = ptr1;

            while(ptr2)
            {
                if(ptr2->left)
                {
                    if(ptr2->right)
                        ptr2->left->next = ptr2->right;
                    else
                        ptr2->left->next = getNext(ptr2);
                }

                if(ptr2->right)
                    ptr2->right->next = getNext(ptr2);

                ptr2 = ptr2->next;
            }

            if(ptr1->left)
                ptr1 = ptr1->left;
            else if(ptr1->right)
                ptr1 = ptr1->right;
            else
                ptr1 = getNext(ptr1);
        }

        return;
    }
};

/*
 * One More Recursive Solution - Works for any tree. Time - O(N), Space - O(1) [Except Recursion Stack].
 * For some input, It would be TLE, as the problem assumes complete binary tree, it expects to be run on less time.
 * As this does more work even for complete tree or any tree. So TLE.
 */
class Solution {
    TreeLinkNode* getNext(TreeLinkNode *root)
    {
        root = root->next;

        while(root)
        {
            if(root->left)
                return root->left;

            if(root->right)
                return root->right;

            root = root->next;
        }

        return NULL;
    }

    void connectUtil(TreeLinkNode *root)
    {
        if(root == NULL)
            return;

        if(root->left)
        {
            if(root->right)
                root->left->next = root->right;
            else
                root->left->next = getNext(root);
        }

        if(root->right)
            root->right->next = getNext(root);

        connectUtil(root->next);
        connectUtil(root->left);
        connectUtil(root->right);

        return;
    }
public:
    void connect(TreeLinkNode *root) {
        if(root == NULL)
            return;

        root->next = NULL;

        connectUtil(root);

        return;
    }
};<commit_msg>116. Populating Next Right Pointers in Each Node - NULL->nullptr<commit_after>/*
 * Written by Nitin Kumar Maharana
 * nitin.maharana@gmail.com
 */

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */

//Iterative Solution.
class Solution {
    queue<TreeLinkNode*> memory;
public:
    void connect(TreeLinkNode *root) {
        if(root == nullptr)
            return;

        memory.push(root);

        TreeLinkNode *front;

        while(!memory.empty())
        {
            front = memory.front();
            memory.pop();

            if(front->left)
            {
                front->left->next = front->right;
                memory.push(front->left);
            }

            if(front->next && front->right)
                front->right->next = front->next->left;

            if(front->right)
                memory.push(front->right);
        }
    }
};

//Recursive Solution.
class Solution {
public:
    void connect(TreeLinkNode *root) {
        if(root == nullptr)
            return;

        if(root->left)
            root->left->next = root->right;

        if(root->next && root->right)
            root->right->next = root->next->left;

        connect(root->left);
        connect(root->right);
    }
};

//One More Recursive Solution - Works for any tree. O(N) - Time, O(H) - Space (Except Recursion Stack).
class Solution {
    void connect(TreeLinkNode* root, unordered_map<int, TreeLinkNode*>& memory, int level)
    {
        if(root == nullptr)
            return;

        if(memory.find(level) != memory.end())
            memory[level]->next = root;

        memory[level] = root;

        connect(root->left, memory, level+1);
        connect(root->right, memory, level+1);

        return;
    }
public:
    void connect(TreeLinkNode *root) {
        if(root == nullptr)
            return;

        unordered_map<int, TreeLinkNode*> memory;
        connect(root, memory, 0);

        return;
    }
};

//One More Iterative Solution - Works for any tree. Time - O(N), Space - O(1).
class Solution {
    TreeLinkNode* getNext(TreeLinkNode *root)
    {
        root = root->next;

        while(root)
        {
            if(root->left)
                return root->left;

            if(root->right)
                return root->right;

            root = root->next;
        }

        return nullptr;
    }
public:
    void connect(TreeLinkNode *root) {
        if(root == nullptr)
            return;

        root->next = nullptr;

        TreeLinkNode *ptr1, *ptr2;

        ptr1 = root;

        while(ptr1)
        {
            ptr2 = ptr1;

            while(ptr2)
            {
                if(ptr2->left)
                {
                    if(ptr2->right)
                        ptr2->left->next = ptr2->right;
                    else
                        ptr2->left->next = getNext(ptr2);
                }

                if(ptr2->right)
                    ptr2->right->next = getNext(ptr2);

                ptr2 = ptr2->next;
            }

            if(ptr1->left)
                ptr1 = ptr1->left;
            else if(ptr1->right)
                ptr1 = ptr1->right;
            else
                ptr1 = getNext(ptr1);
        }

        return;
    }
};

/*
 * One More Recursive Solution - Works for any tree. Time - O(N), Space - O(1) [Except Recursion Stack].
 * For some input, It would be TLE, as the problem assumes complete binary tree, it expects to be run on less time.
 * As this does more work even for complete tree or any tree. So TLE.
 */
class Solution {
    TreeLinkNode* getNext(TreeLinkNode *root)
    {
        root = root->next;

        while(root)
        {
            if(root->left)
                return root->left;

            if(root->right)
                return root->right;

            root = root->next;
        }

        return nullptr;
    }

    void connectUtil(TreeLinkNode *root)
    {
        if(root == nullptr)
            return;

        if(root->left)
        {
            if(root->right)
                root->left->next = root->right;
            else
                root->left->next = getNext(root);
        }

        if(root->right)
            root->right->next = getNext(root);

        connectUtil(root->next);
        connectUtil(root->left);
        connectUtil(root->right);

        return;
    }
public:
    void connect(TreeLinkNode *root) {
        if(root == nullptr)
            return;

        root->next = nullptr;

        connectUtil(root);

        return;
    }
};<|endoftext|>