<commit_before>#include "window.h"
#include "map_window.h"
#include "inspection_window.h"
#include "equipment_window.h"
#include "gameengine.h"
#include "event.h"

void MapWindow::gainFocus ()
{
    std::string l_mapName ("");
    getEngine()->loadMap(l_mapName);

    setTitle ("Map");

    m_mapXOffset = 1;
    m_mapYOffset = 9;
    m_mapStartX = 0;
    m_mapStartY = 0;
    m_mapWidth  = 20;
    m_mapHeight = 25;
    m_sidebarWidth = 20;
    m_sidebarXOffset = getWidth() - m_sidebarWidth;

    m_action = 'm';
}

void MapWindow::redraw() {
    drawSeparators();
    drawMap();
    drawMessages();
    drawSidebar();
}

void MapWindow::resize() {
    setDimensions (0, 0, getEngine()->getGraphics()->getScreenWidth(), getEngine()->getGraphics()->getScreenHeight());
    m_sidebarXOffset = getWidth() - m_sidebarWidth - 1;
    m_mapWidth  = getWidth() - m_mapXOffset - m_sidebarWidth - 1;
    m_mapHeight = getHeight() - m_mapYOffset - 1;
}

void MapWindow::keyDown (unsigned char key) {
    Window::keyDown (key);

    if (key == 'w' || key == 'a' || key == 's' || key == 'd') {
        DIRECTION l_dir = Direction::None;
        switch (key) {
            case 'w': l_dir = Direction::North; break;
            case 'a': l_dir = Direction::West;  break;
            case 's': l_dir = Direction::South; break;
            case 'd': l_dir = Direction::East;  break;
        }

        if (m_action == 'm') {
            MoveEntityEvent* l_event = new MoveEntityEvent;
            l_event->entity = getEngine()->getEntities()->getPlayer();
            l_event->direction = l_dir;
            getEngine()->raiseEvent (l_event);
        }
        if (m_action == 'k') {
            AttackEntityEvent* l_event = new AttackEntityEvent;
            l_event->entity = getEngine()->getEntities()->getPlayer();
            l_event->direction = l_dir;
            getEngine()->raiseEvent (l_event);
        }
        if (m_action == 'i') {
            std::vector<EntityId> l_entities = getEngine()->getEntities()->findEntitiesToThe(l_dir, getEngine()->getEntities()->getPlayer());
            if (l_entities.size() > 0) {
                EntityId* l_target = new EntityId(l_entities[0]);

                InspectionWindow* l_win = new InspectionWindow();
                l_win->initialise(getEngine(), l_target);
                getEngine()->getWindows()->pushWindow (l_win);
            }
        }
        if (m_action != 'i') getEngine()->swapTurn();
        m_action = 'm';
    }
    if (key == 27) {
        getEngine()->quit();
    }
    if (key == 'm' ||
        key == 'k' ||
        key == 'i') {
        m_action = key;
    }
    if (key == '.') {
        getEngine()->swapTurn();
    }
    if (key == 'p') {
        LocationComponent* l_playerLoc = getEngine()->getEntities()->getLocations()->get (getEngine()->getEntities()->getPlayer());
        std::vector<EntityId> l_entities = getEngine()->getEntities()->findEntitiesAt (l_playerLoc->x, l_playerLoc->y);
        bool foundSomethingAlready = false;
        for (size_t ii = 0; ii < l_entities.size(); ii++) {
            DroppableComponent* droppable = getEngine()->getEntities()->getDroppables()->get(l_entities[ii]);
            if (droppable) {
                if (!foundSomethingAlready) {
                    PickupEquipmentEvent* event = new PickupEquipmentEvent();
                    event->entity = getEngine()->getEntities()->getPlayer();
                    event->item = l_entities[ii];
                    getEngine()->raiseEvent (event);
                    foundSomethingAlready = true;
                } else {
                    getEngine()->addMessage(INFO, "There's something else here...");
                    break;
                }
            }
        }

    }
    if (key == 'E') {
        EquipmentWindow* l_win = new EquipmentWindow();
        l_win->initialise(getEngine());
        getEngine()->getWindows()->pushWindow (l_win);
    }
}

void MapWindow::drawSeparators() {
    getEngine()->getGraphics()->drawBorder (m_mapYOffset-1, m_mapXOffset-1, m_mapHeight, m_mapWidth);
    getEngine()->getGraphics()->drawBorder (0, m_sidebarXOffset, getHeight()-2, m_sidebarWidth-1);
}

void MapWindow::drawMap() {

    std::map<EntityId, SpriteComponent>& l_sprites = getEngine()->getEntities()->getSprites()->getAll();
    std::map<EntityId, SpriteComponent>::iterator it = l_sprites.begin();
    LocationComponent* l_player = getEngine()->getEntities()->getLocations()->get (getEngine()->getEntities()->getPlayer());
    if (l_player) {
        m_mapStartX = l_player->x - (m_mapWidth/2);
        m_mapStartY = l_player->y - (m_mapHeight/2);
    }
    for (; it != l_sprites.end(); it++) {
        SpriteComponent& l_sprite = it->second;
        LocationComponent* l_location = getEngine()->getEntities()->getLocations()->get (it->first);
        int x = l_location->x;
        int y = l_location->y;
        int xWidth = m_mapStartX + m_mapWidth;
        int yWidth = m_mapStartY + m_mapHeight;
        if (x >= m_mapStartX && x < xWidth &&
            y >= m_mapStartY && y < yWidth &&
            l_location->z == getEngine()->getLevel()) {

            drawTile (  l_location->y + m_mapYOffset - m_mapStartY,
                        l_location->x + m_mapXOffset - m_mapStartX,
                        l_sprite.sprite,
                        l_sprite.fgColor,
                        l_sprite.bgColor);
        }
    }
}

void MapWindow::drawMessages()
{
    std::vector<Message>& l_messages = getEngine()->getMessages();
    size_t ii = l_messages.size();
    size_t hh = m_mapYOffset-2;

    for (; ii > 0 && hh > 0; hh--, ii--) {
        Color fg;
        switch (l_messages[ii-1].severity) {
            case INFO: fg = Color (WHITE); break;
            case WARN: fg = Color (RED); break;
            case GOOD: fg = Color (GREEN); break;
            case CRIT: fg = Color (BLUE); break;
        }
        drawString (hh, 1, l_messages[ii-1].message.c_str(), fg);
    }
}

void MapWindow::drawSidebar ()
{
    // Current health
    drawString (2, m_sidebarXOffset+2, "Health:");
    EntityId player = getEngine()->getEntities()->getPlayer();
    HealthComponent* l_health = getEngine()->getEntities()->getHealths()->get(player);
    if (l_health) {
        drawProgressBar (m_sidebarXOffset+10, 2, l_health->health);

    }

    // Actions to take
    drawString (getHeight()-7, m_sidebarXOffset+2, "move (wasd)");
    drawString (getHeight()-7, m_sidebarXOffset+2, "m", Color (GREEN));
    if (m_action == 'm') drawString (getHeight()-7, m_sidebarXOffset+1, ">", Color (RED));

    drawString (getHeight()-6, m_sidebarXOffset+2, "attack (wasd)");
    drawString (getHeight()-6, m_sidebarXOffset+7, "k", Color (GREEN));
    if (m_action == 'k') drawString (getHeight()-6, m_sidebarXOffset+1, ">", Color (RED));

    drawString (getHeight()-5, m_sidebarXOffset+2, "inspect (wasd)");
    drawString (getHeight()-5, m_sidebarXOffset+2, "i", Color (GREEN));
    if (m_action == 'i') drawString (getHeight()-5, m_sidebarXOffset+1, ">", Color (RED));

    drawString (getHeight()-4, m_sidebarXOffset+2, "skip turn (.)");
    drawString (getHeight()-4, m_sidebarXOffset+13, ".", Color (GREEN));

    drawString (getHeight()-2, m_sidebarXOffset+2, "View Equipment");
    drawString (getHeight()-2, m_sidebarXOffset+7, "E", Color (GREEN));
}

void MapWindow::drawProgressBar (int x, int y, int value)
{
    float l_value = (float) value;
    Color l_color ((1.0f-(l_value/10.0f)), l_value/10.0f, 0);

    for (int xx = 0; xx < value; xx++) {
        drawTile (y, x+xx, 178, l_color, Color(BLACK));
    }
}
<commit_msg>Added command to sidebar and message if nothing is found to be picked up<commit_after>#include "window.h"
#include "map_window.h"
#include "inspection_window.h"
#include "equipment_window.h"
#include "gameengine.h"
#include "event.h"

void MapWindow::gainFocus ()
{
    std::string l_mapName ("");
    getEngine()->loadMap(l_mapName);

    setTitle ("Map");

    m_mapXOffset = 1;
    m_mapYOffset = 9;
    m_mapStartX = 0;
    m_mapStartY = 0;
    m_mapWidth  = 20;
    m_mapHeight = 25;
    m_sidebarWidth = 20;
    m_sidebarXOffset = getWidth() - m_sidebarWidth;

    m_action = 'm';
}

void MapWindow::redraw() {
    drawSeparators();
    drawMap();
    drawMessages();
    drawSidebar();
}

void MapWindow::resize() {
    setDimensions (0, 0, getEngine()->getGraphics()->getScreenWidth(), getEngine()->getGraphics()->getScreenHeight());
    m_sidebarXOffset = getWidth() - m_sidebarWidth - 1;
    m_mapWidth  = getWidth() - m_mapXOffset - m_sidebarWidth - 1;
    m_mapHeight = getHeight() - m_mapYOffset - 1;
}

void MapWindow::keyDown (unsigned char key) {
    Window::keyDown (key);

    if (key == 'w' || key == 'a' || key == 's' || key == 'd') {
        DIRECTION l_dir = Direction::None;
        switch (key) {
            case 'w': l_dir = Direction::North; break;
            case 'a': l_dir = Direction::West;  break;
            case 's': l_dir = Direction::South; break;
            case 'd': l_dir = Direction::East;  break;
        }

        if (m_action == 'm') {
            MoveEntityEvent* l_event = new MoveEntityEvent;
            l_event->entity = getEngine()->getEntities()->getPlayer();
            l_event->direction = l_dir;
            getEngine()->raiseEvent (l_event);
        }
        if (m_action == 'k') {
            AttackEntityEvent* l_event = new AttackEntityEvent;
            l_event->entity = getEngine()->getEntities()->getPlayer();
            l_event->direction = l_dir;
            getEngine()->raiseEvent (l_event);
        }
        if (m_action == 'i') {
            std::vector<EntityId> l_entities = getEngine()->getEntities()->findEntitiesToThe(l_dir, getEngine()->getEntities()->getPlayer());
            if (l_entities.size() > 0) {
                EntityId* l_target = new EntityId(l_entities[0]);

                InspectionWindow* l_win = new InspectionWindow();
                l_win->initialise(getEngine(), l_target);
                getEngine()->getWindows()->pushWindow (l_win);
            }
        }
        if (m_action != 'i') getEngine()->swapTurn();
        m_action = 'm';
    }
    if (key == 27) {
        getEngine()->quit();
    }
    if (key == 'm' ||
        key == 'k' ||
        key == 'i') {
        m_action = key;
    }
    if (key == '.') {
        getEngine()->swapTurn();
    }
    if (key == 'p') {
        LocationComponent* l_playerLoc = getEngine()->getEntities()->getLocations()->get (getEngine()->getEntities()->getPlayer());
        std::vector<EntityId> l_entities = getEngine()->getEntities()->findEntitiesAt (l_playerLoc->x, l_playerLoc->y);
        bool foundSomethingAlready = false;
        for (size_t ii = 0; ii < l_entities.size(); ii++) {
            DroppableComponent* droppable = getEngine()->getEntities()->getDroppables()->get(l_entities[ii]);
            if (droppable) {
                if (!foundSomethingAlready) {
                    PickupEquipmentEvent* event = new PickupEquipmentEvent();
                    event->entity = getEngine()->getEntities()->getPlayer();
                    event->item = l_entities[ii];
                    getEngine()->raiseEvent (event);
                    foundSomethingAlready = true;
                } else {
                    getEngine()->addMessage(INFO, "There's something else here...");
                    break;
                }
            }
        }
        if (!foundSomethingAlready) {
            getEngine()->addMessage(INFO, "There's nothing here...");
        }
    }
    if (key == 'E') {
        EquipmentWindow* l_win = new EquipmentWindow();
        l_win->initialise(getEngine());
        getEngine()->getWindows()->pushWindow (l_win);
    }
}

void MapWindow::drawSeparators() {
    getEngine()->getGraphics()->drawBorder (m_mapYOffset-1, m_mapXOffset-1, m_mapHeight, m_mapWidth);
    getEngine()->getGraphics()->drawBorder (0, m_sidebarXOffset, getHeight()-2, m_sidebarWidth-1);
}

void MapWindow::drawMap() {

    std::map<EntityId, SpriteComponent>& l_sprites = getEngine()->getEntities()->getSprites()->getAll();
    std::map<EntityId, SpriteComponent>::iterator it = l_sprites.begin();
    LocationComponent* l_player = getEngine()->getEntities()->getLocations()->get (getEngine()->getEntities()->getPlayer());
    if (l_player) {
        m_mapStartX = l_player->x - (m_mapWidth/2);
        m_mapStartY = l_player->y - (m_mapHeight/2);
    }
    for (; it != l_sprites.end(); it++) {
        SpriteComponent& l_sprite = it->second;
        LocationComponent* l_location = getEngine()->getEntities()->getLocations()->get (it->first);
        int x = l_location->x;
        int y = l_location->y;
        int xWidth = m_mapStartX + m_mapWidth;
        int yWidth = m_mapStartY + m_mapHeight;
        if (x >= m_mapStartX && x < xWidth &&
            y >= m_mapStartY && y < yWidth &&
            l_location->z == getEngine()->getLevel()) {

            drawTile (  l_location->y + m_mapYOffset - m_mapStartY,
                        l_location->x + m_mapXOffset - m_mapStartX,
                        l_sprite.sprite,
                        l_sprite.fgColor,
                        l_sprite.bgColor);
        }
    }
}

void MapWindow::drawMessages()
{
    std::vector<Message>& l_messages = getEngine()->getMessages();
    size_t ii = l_messages.size();
    size_t hh = m_mapYOffset-2;

    for (; ii > 0 && hh > 0; hh--, ii--) {
        Color fg;
        switch (l_messages[ii-1].severity) {
            case INFO: fg = Color (WHITE); break;
            case WARN: fg = Color (RED); break;
            case GOOD: fg = Color (GREEN); break;
            case CRIT: fg = Color (BLUE); break;
        }
        drawString (hh, 1, l_messages[ii-1].message.c_str(), fg);
    }
}

void MapWindow::drawSidebar ()
{
    // Current health
    drawString (2, m_sidebarXOffset+2, "Health:");
    EntityId player = getEngine()->getEntities()->getPlayer();
    HealthComponent* l_health = getEngine()->getEntities()->getHealths()->get(player);
    if (l_health) {
        drawProgressBar (m_sidebarXOffset+10, 2, l_health->health);

    }

    // Actions to take
    drawString (getHeight()-8, m_sidebarXOffset+2, "pickup Items");
    drawString (getHeight()-8, m_sidebarXOffset+2, "p", Color (GREEN));

    drawString (getHeight()-7, m_sidebarXOffset+2, "move (wasd)");
    drawString (getHeight()-7, m_sidebarXOffset+2, "m", Color (GREEN));
    if (m_action == 'm') drawString (getHeight()-7, m_sidebarXOffset+1, ">", Color (RED));

    drawString (getHeight()-6, m_sidebarXOffset+2, "attack (wasd)");
    drawString (getHeight()-6, m_sidebarXOffset+7, "k", Color (GREEN));
    if (m_action == 'k') drawString (getHeight()-6, m_sidebarXOffset+1, ">", Color (RED));

    drawString (getHeight()-5, m_sidebarXOffset+2, "inspect (wasd)");
    drawString (getHeight()-5, m_sidebarXOffset+2, "i", Color (GREEN));
    if (m_action == 'i') drawString (getHeight()-5, m_sidebarXOffset+1, ">", Color (RED));

    drawString (getHeight()-4, m_sidebarXOffset+2, "skip turn (.)");
    drawString (getHeight()-4, m_sidebarXOffset+13, ".", Color (GREEN));

    drawString (getHeight()-2, m_sidebarXOffset+2, "View Equipment");
    drawString (getHeight()-2, m_sidebarXOffset+7, "E", Color (GREEN));
}

void MapWindow::drawProgressBar (int x, int y, int value)
{
    float l_value = (float) value;
    Color l_color ((1.0f-(l_value/10.0f)), l_value/10.0f, 0);

    for (int xx = 0; xx < value; xx++) {
        drawTile (y, x+xx, 178, l_color, Color(BLACK));
    }
}
<|endoftext|>


<commit_before>// http://lgecodejam.com
// lge code jam June, 2014
// problem.3
// hyungyu.jang@lge.com

#if defined _EXTERNAL_DEBUGGER && defined _DEBUG
    #include <trace/trace.h>
    #include <intrin.h>
#else
    #define trace printf
#endif

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <functional>
#include <algorithm>

using namespace std;

enum { X = 0, Y, }; // for indexing
typedef unsigned int uint32;

class Point { public:
    Point() : x(0), y(0) {}
    Point(int x_, int y_) : x(x_), y(y_) {}
    ~Point() {}
    bool operator <(const Point& p) const {
        return x == p.x ? y < p.y : x < p.x;
    }
    bool operator >(const Point& p) const {
        return x == p.x ? y > p.y : x > p.x;
    }
    int x, y;
};

typedef multiset<Point> MinSet;
typedef multiset<Point, greater<Point> > MaxSet;

int n;
MinSet min_xy, min_yx;
MaxSet max_xy, max_yx;

template<typename T>
void remove(T &s, const Point p) {
    typename T::iterator i = s.begin();
    for (; i != s.end(); i++) {
        if (i->x == p.x && i->y == p.y) {
            s.erase(i);
            return;
        }
    }
}

int simulation(int left, int right, int top, int bottom) {
    MinSet min_xy_(min_xy);
    MinSet min_yx_(min_yx);
    MaxSet max_xy_(max_xy);
    MaxSet max_yx_(max_yx);
    int i;
    for (i = 0; i < left; i++) {
        Point p = *min_xy_.begin();
        Point q(p.y, p.x);
        remove<MinSet>(min_yx_, q);
        remove<MaxSet>(max_yx_, q);
        min_xy_.erase(min_xy_.begin());
    }
    for (i = 0; i < right; i++) {
        Point p = *max_xy_.begin();
        Point q(p.y, p.x);
        remove<MinSet>(min_yx_, q);
        remove<MaxSet>(max_yx_, q);
        max_xy_.erase(max_xy_.begin());
    }
    for (i = 0; i < bottom; i++) {
        Point p = *min_yx_.begin();
        Point q(p.y, p.x);
        remove<MinSet>(min_xy_, q);
        remove<MaxSet>(max_xy_, q);
        min_yx_.erase(min_yx_.begin());
    }
    for (i = 0; i < top; i++) {
        Point p = *max_yx_.begin();
        Point q(p.y, p.x);
        remove<MinSet>(min_xy_, q);
        remove<MaxSet>(max_xy_, q);
        max_yx_.erase(max_yx_.begin());
    }

    return max(max_xy_.begin()->x - min_xy_.begin()->x, max_yx_.begin()->x - min_yx_.begin()->x);
}

void solve() {
    min_xy.clear();
    min_yx.clear();
    max_xy.clear();
    max_yx.clear();
    scanf("%d", &n);
    int i, x, y;
    for (i = 0; i < 4; i++) {
        scanf("%d %d", &x, &y);
        min_xy.insert(Point(x, y));
        max_xy.insert(Point(x, y));
        min_yx.insert(Point(y, x));
        max_yx.insert(Point(y, x));
    }

    for (; i < n; i++) {
        scanf("%d %d", &x, &y);
        min_xy.insert(Point(x, y));
        max_xy.insert(Point(x, y));
        min_yx.insert(Point(y, x));
        max_yx.insert(Point(y, x));
        min_xy.erase(--min_xy.rbegin().base());
        min_yx.erase(--min_yx.rbegin().base());
        max_xy.erase(--max_xy.rbegin().base());
        max_yx.erase(--max_yx.rbegin().base());
    }

    // for all cases
    int solution = 0x7FFFFFFF;
    int direct[4]; // left, right, top, bottom
    for (int a = 1; a <= 8; a <<= 1) {
        for (int b = 1; b <= 8; b <<= 1) {
            for (int c = 1; c <= 8; c <<= 1) {
                memset(direct, 0, sizeof(int) * 4);
#ifdef WIN32
                unsigned long res;
                _BitScanForward(&res, a); direct[res]++;
                _BitScanForward(&res, b); direct[res]++;
                _BitScanForward(&res, c); direct[res]++;
#else // __linux__
                direct[__builtin_ctz(a)]++;
                direct[__builtin_ctz(b)]++;
                direct[__builtin_ctz(c)]++;
#endif
                //static int k = 1;
                //trace("%d) %d %d %d %d (%d)\n", k++, direct[0], direct[1], direct[2], direct[3], direct[0] + direct[1] + direct[2] + direct[3]);
                solution = min(solution, simulation(direct[0], direct[1], direct[2], direct[3]));
            }
        }
    }
    trace("%d\n", solution);
}

int main(int, char*[]) {
    int num;
    scanf("%d", &num);
    for (int i = 0; i < num; i++) {solve();}
    return 0;
}

<commit_msg>removed duplication in loop<commit_after>// http://lgecodejam.com
// lge code jam June, 2014
// problem.3
// hyungyu.jang@lge.com

#if defined _EXTERNAL_DEBUGGER && defined _DEBUG
    #include <trace/trace.h>
    #include <intrin.h>
#else
    #define trace printf
#endif

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <functional>
#include <algorithm>

using namespace std;

enum { X = 0, Y, }; // for indexing
typedef unsigned int uint32;

class Point { public:
    Point() : x(0), y(0) {}
    Point(int x_, int y_) : x(x_), y(y_) {}
    ~Point() {}
    bool operator <(const Point& p) const {
        return x == p.x ? y < p.y : x < p.x;
    }
    bool operator >(const Point& p) const {
        return x == p.x ? y > p.y : x > p.x;
    }
    int x, y;
};

typedef multiset<Point> MinSet;
typedef multiset<Point, greater<Point> > MaxSet;

int n;
MinSet min_xy, min_yx;
MaxSet max_xy, max_yx;

template<typename T>
void remove(T &s, const Point p) {
    typename T::iterator i = s.begin();
    for (; i != s.end(); i++) {
        if (i->x == p.x && i->y == p.y) {
            s.erase(i);
            return;
        }
    }
}

int simulation(int left, int right, int top, int bottom) {
    MinSet min_xy_(min_xy);
    MinSet min_yx_(min_yx);
    MaxSet max_xy_(max_xy);
    MaxSet max_yx_(max_yx);
    int i;
    for (i = 0; i < left; i++) {
        Point p = *min_xy_.begin();
        Point q(p.y, p.x);
        remove<MinSet>(min_yx_, q);
        remove<MaxSet>(max_yx_, q);
        min_xy_.erase(min_xy_.begin());
    }
    for (i = 0; i < right; i++) {
        Point p = *max_xy_.begin();
        Point q(p.y, p.x);
        remove<MinSet>(min_yx_, q);
        remove<MaxSet>(max_yx_, q);
        max_xy_.erase(max_xy_.begin());
    }
    for (i = 0; i < bottom; i++) {
        Point p = *min_yx_.begin();
        Point q(p.y, p.x);
        remove<MinSet>(min_xy_, q);
        remove<MaxSet>(max_xy_, q);
        min_yx_.erase(min_yx_.begin());
    }
    for (i = 0; i < top; i++) {
        Point p = *max_yx_.begin();
        Point q(p.y, p.x);
        remove<MinSet>(min_xy_, q);
        remove<MaxSet>(max_xy_, q);
        max_yx_.erase(max_yx_.begin());
    }

    return max(max_xy_.begin()->x - min_xy_.begin()->x, max_yx_.begin()->x - min_yx_.begin()->x);
}

void solve() {
    min_xy.clear();
    min_yx.clear();
    max_xy.clear();
    max_yx.clear();
    scanf("%d", &n);
    int i, x, y;
    for (i = 0; i < 4; i++) {
        scanf("%d %d", &x, &y);
        min_xy.insert(Point(x, y));
        max_xy.insert(Point(x, y));
        min_yx.insert(Point(y, x));
        max_yx.insert(Point(y, x));
    }

    for (; i < n; i++) {
        scanf("%d %d", &x, &y);
        min_xy.insert(Point(x, y));
        max_xy.insert(Point(x, y));
        min_yx.insert(Point(y, x));
        max_yx.insert(Point(y, x));
        min_xy.erase(--min_xy.rbegin().base());
        min_yx.erase(--min_yx.rbegin().base());
        max_xy.erase(--max_xy.rbegin().base());
        max_yx.erase(--max_yx.rbegin().base());
    }

    // for all cases
    int solution = 0x7FFFFFFF;
    int direct[4]; // left, right, top, bottom
    for (i = 0; i < 4; i++) {
        memset(direct, 0, sizeof(int) * 4);
        direct[i] = 3;
        solution = min(solution, simulation(direct[0], direct[1], direct[2], direct[3]));
        direct[0] = direct[1] = direct[2] = direct[3] = 1;
        direct[i] = 0;
        solution = min(solution, simulation(direct[0], direct[1], direct[2], direct[3]));
    }
    for (i = 0; i < 4; i++) {
        memset(direct, 0, sizeof(int) * 4);
        direct[i] = 2;
        for (int j = 0; j < 3; j++) {
            direct[(i+j+1)%4] = 1;
            solution = min(solution, simulation(direct[0], direct[1], direct[2], direct[3]));
            direct[(i+j+1)%4] = 0;
        }
    }

    trace("%d\n", solution);
}

int main(int, char*[]) {
    int num;
    scanf("%d", &num);
    for (int i = 0; i < num; i++) {solve();}
    return 0;
}

<|endoftext|>


<commit_before>// balb_assertiontrackersingleton.t.cpp                               -*-C++-*-

#include <balb_assertiontrackersingleton.h>
#include <balb_assertiontracker.h>

#include <bdlf_bind.h>
#include <bdlf_placeholder.h>

#include <bslim_testutil.h>

#include <bslma_defaultallocatorguard.h>
#include <bslma_testallocator.h>

#include <bsl_cstdlib.h>
#include <bsl_iostream.h>
#include <bsl_sstream.h>
#include <bsl_utility.h>

using namespace BloombergLP;
using namespace bsl;  // automatically added by script

// ============================================================================
//                             TEST PLAN
// ----------------------------------------------------------------------------
//                             Overview
//                             --------
// Test this thing.
// ----------------------------------------------------------------------------
// CLASS METHODS
// CREATORS
// MANIPULATORS
// ACCESSORS
// ----------------------------------------------------------------------------
// [ 1] void failTracker(const char *, const char *, int);
// [ 1] TRACKER *singleton(bslma::Allocator * = 0);
// [ 2] USAGE EXAMPLE

// ============================================================================
//                     STANDARD BDE ASSERT TEST FUNCTION
// ----------------------------------------------------------------------------

namespace {

int testStatus = 0;

void aSsErT(bool condition, const char *message, int line)
{
    if (condition) {
        cout << "Error " __FILE__ "(" << line << "): " << message
             << "    (failed)" << endl;

        if (0 <= testStatus && testStatus <= 100) {
            ++testStatus;
        }
    }
}

}  // close unnamed namespace

// ============================================================================
//               STANDARD BDE TEST DRIVER MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ASSERT BSLIM_TESTUTIL_ASSERT
#define ASSERTV BSLIM_TESTUTIL_ASSERTV

#define LOOP_ASSERT BSLIM_TESTUTIL_LOOP_ASSERT
#define LOOP0_ASSERT BSLIM_TESTUTIL_LOOP0_ASSERT
#define LOOP1_ASSERT BSLIM_TESTUTIL_LOOP1_ASSERT
#define LOOP2_ASSERT BSLIM_TESTUTIL_LOOP2_ASSERT
#define LOOP3_ASSERT BSLIM_TESTUTIL_LOOP3_ASSERT
#define LOOP4_ASSERT BSLIM_TESTUTIL_LOOP4_ASSERT
#define LOOP5_ASSERT BSLIM_TESTUTIL_LOOP5_ASSERT
#define LOOP6_ASSERT BSLIM_TESTUTIL_LOOP6_ASSERT

#define Q BSLIM_TESTUTIL_Q    // Quote identifier literally.
#define P BSLIM_TESTUTIL_P    // Print identifier and value.
#define P_ BSLIM_TESTUTIL_P_  // P(X) without '\n'.
#define T_ BSLIM_TESTUTIL_T_  // Print a tab (w/o newline).
#define L_ BSLIM_TESTUTIL_L_  // current Line number

// ============================================================================
//            GLOBAL TYPES, CONSTANTS, AND VARIABLES FOR TESTING
// ----------------------------------------------------------------------------

typedef balb::AssertionTrackerSingleton<balb::AssertionTracker> Obj;

int id(int i)
    // Return the specified 'i'.
{
    return i;
}

void trigger1()
    // Invoke assertion type 1.
{
    BSLS_ASSERT_ASSERT(0 && "assert 1");
}

void trigger2()
    // Invoke assertion type 2.
{
    BSLS_ASSERT_ASSERT(0 && "assert 2");
}

void trigger3()
    // Report assertion type 3.
{
    Obj::failTracker("0 && \"assert 3\"", __FILE__, __LINE__);
}

// Try to scotch inlining and loop unrolling
int  (*volatile id_p)(int)    = id;
void (*volatile trigger1_p)() = trigger1;
void (*volatile trigger2_p)() = trigger2;
void (*volatile trigger3_p)() = trigger3;

///Usage
///-----
// This section illustrates intended use of this component.
//
///Example 1: Count Number of Assertions Triggered
///- - - - - - - - - - - - - - - - - - - - - - - -
// We wish to count how many times assertions trigger, doing no other handling
// and allowing the program to continue running (note that this is normally
// forbidden in production).  We can use 'AssertionTrackerSingleton' to set up
// an assertion handler to do this.
//
// First, we create a class to do the counting.
//..
    class AssertionCounter {
        // PRIVATE DATA
        int d_assertion_counter;  // Number of assertions seen.

      public:
        // PUBLIC CREATORS
        explicit AssertionCounter(bsls::Assert::Handler = 0, void * = 0);
            // Create an 'AssertionCounter' object.  We ignore the fallback
            // handler and optional allocator parameters.

        // PUBLIC MANIPULATORS
        void operator()(const char *, const char *, int);
            // Function called when assertion failure occurs.  We ignore the
            // text, file, and line parameters.

        // PUBLIC ACCESSORS
        int getAssertionCount() const;
            // Return the number of assertions we have seen.
    };
//..
// Then, we implement the member functions of the 'AssertionCounter' class.
//..
    AssertionCounter::AssertionCounter(bsls::Assert::Handler, void *)
    : d_assertion_counter(0)
    {
    }

    void AssertionCounter::operator()(const char *, const char *, int)
    {
        ++d_assertion_counter;
    }

    int AssertionCounter::getAssertionCount() const
    {
        return d_assertion_counter;
    }
//..

// ============================================================================
//                               MAIN PROGRAM
// ----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
    int                 test = (argc > 1) ? atoi(argv[1]) : 1;
    bool             verbose = (argc > 2); (void)verbose;
    bool         veryVerbose = (argc > 3); (void)veryVerbose;
    bool     veryVeryVerbose = (argc > 4); (void)veryVeryVerbose;
    bool veryVeryVeryVerbose = (argc > 5); (void)veryVeryVeryVerbose;

    cout << "TEST " << __FILE__ << " CASE " << test << endl;

    switch (test) { case 0:
      case 2: {
        // --------------------------------------------------------------------
        // USAGE EXAMPLE
        //   Extracted from component header file.
        //
        // Concerns:
        //: 1 The usage example provided in the component header file compiles,
        //:   links, and runs as shown.
        //
        // Plan:
        //: 1 Incorporate usage example from header into test driver, remove
        //:   leading comment characters, and replace 'assert' with 'ASSERT'.
        //:   (C-1)
        //
        // Testing:
        //   USAGE EXAMPLE
        // --------------------------------------------------------------------

        if (verbose) cout << "\nUSAGE EXAMPLE"
                             "\n=============\n";
// Next, we set up an instance of this class to be the installed assertion
// using 'AssertionTrackerSingleton'.  Note that this needs to be done early in
// 'main()' before any other handlers are installed.  If another handler has
// already been installed, a null pointer will be returned, and we assert that
// this does not happen.
//..
    AssertionCounter *ac_p =
        balb::AssertionTrackerSingleton<AssertionCounter>::singleton();
    ASSERT(ac_p);
//..
// Finally, we will trigger some assertions and verify that we are counting
// them correctly.
//..
    BSLS_ASSERT_ASSERT(0 && "assertion 1");
    BSLS_ASSERT_ASSERT(0 && "assertion 2");
    ASSERT(ac_p->getAssertionCount() == 2);
//..
      } break;
      case 1: {
        // --------------------------------------------------------------------
        // BREATHING TEST
        //   This case exercises (but does not fully test) basic functionality.
        //
        // Concerns:
        //: 1 The class is sufficiently functional to install an assertion
        //:   handler and process assertions.
        //
        // Plan:
        //: 1 Create a singleton 'AssertionTracker' object, trigger some
        //:   assertions, and verify that they are noticed by having the
        //:   assertion handler write them to a string stream and then
        //:   examining the contents of the stream.
        //
        // Testing:
        //   void failTracker(const char *, const char *, int);
        //   TRACKER *singleton(bslma::Allocator * = 0);
        // --------------------------------------------------------------------

        if (verbose)
            cout << "BREATHING TEST\n"
                    "==============\n";
        {
            bsl::ostringstream      os;
            balb::AssertionTracker *at_p = Obj::singleton();

            ASSERT(at_p);
            at_p->setReportingCallback(
                bdlf::BindUtil::bind(&balb::AssertionTracker::reportAssertion,
                                     &os,
                                     bdlf::PlaceHolders::_1,
                                     bdlf::PlaceHolders::_2,
                                     bdlf::PlaceHolders::_3,
                                     bdlf::PlaceHolders::_4,
                                     bdlf::PlaceHolders::_5));
            os << "\n";
            volatile int i, j;
            i = id_p(0);
            do {
                if (veryVeryVerbose) {
                    P_(i) Q("assert 1")
                }
                trigger1_p();
                j = id_p(0);
                do {
                    if (veryVeryVerbose) {
                        P_(i) P_(j) Q("assert 2")
                    }
                    trigger2_p();
                    j = id_p(j) + id_p(1);
                } while (id_p(j) < id_p(10));
                i = id_p(i) + id_p(1);
            } while (id_p(i) < id_p(10));
            i = id_p(0);
            do {
                if (veryVeryVerbose) {
                    P_(i) Q("assert 3")
                }
                trigger3_p();
                i = id_p(i) + id_p(1);
            } while (id_p(i) < id_p(2));

            bsl::string s = os.str();

            ASSERTV(s, s.npos != s.find(__FILE__));

            ASSERTV(s, s.npos != s.find(":1:0 && \"assert 1\":"))
            ASSERTV(s, s.npos != s.find(":1:0 && \"assert 2\":"))
            ASSERTV(s, s.npos != s.find(":1:0 && \"assert 3\":"))

            os.str("");
            at_p->reportAllStackTraces();
            s = os.str();

#ifdef BSLS_PLATFORM_OS_WINDOWS
            // In some Windows builds the stack traces appear to be split, with
            // a each assertion appearing twice with different stack traces. I
            // have seen this with cl-18, while cl-19 seems to work properly.
            // For now, just test that the assertions show up at all.
            ASSERTV(s, s.npos != s.find(":0 && \"assert 1\":"))
            ASSERTV(s, s.npos != s.find(":0 && \"assert 2\":"))
            ASSERTV(s, s.npos != s.find(":0 && \"assert 3\":"))
#else
            ASSERTV(s, s.npos != s.find(":10:0 && \"assert 1\":"))
            ASSERTV(s, s.npos != s.find(":100:0 && \"assert 2\":"))
            ASSERTV(s, s.npos != s.find(":2:0 && \"assert 3\":"))
#endif
        }
      } break;
      default: {
        cerr << "WARNING: CASE `" << test << "' NOT FOUND." << endl;
        testStatus = -1;
      }
    }

    if (testStatus > 0) {
        cerr << "Error, non-zero test status = " << testStatus << "." << endl;
    }
    return testStatus;
}

// ----------------------------------------------------------------------------
// Copyright 2017 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
<commit_msg>Undo the volatile stuff which didn't help with Windows<commit_after>// balb_assertiontrackersingleton.t.cpp                               -*-C++-*-

#include <balb_assertiontrackersingleton.h>
#include <balb_assertiontracker.h>

#include <bdlf_bind.h>
#include <bdlf_placeholder.h>

#include <bslim_testutil.h>

#include <bslma_defaultallocatorguard.h>
#include <bslma_testallocator.h>

#include <bsl_cstdlib.h>
#include <bsl_iostream.h>
#include <bsl_sstream.h>
#include <bsl_utility.h>

using namespace BloombergLP;
using namespace bsl;  // automatically added by script

// ============================================================================
//                             TEST PLAN
// ----------------------------------------------------------------------------
//                             Overview
//                             --------
// Test this thing.
// ----------------------------------------------------------------------------
// CLASS METHODS
// CREATORS
// MANIPULATORS
// ACCESSORS
// ----------------------------------------------------------------------------
// [ 1] void failTracker(const char *, const char *, int);
// [ 1] TRACKER *singleton(bslma::Allocator * = 0);
// [ 2] USAGE EXAMPLE

// ============================================================================
//                     STANDARD BDE ASSERT TEST FUNCTION
// ----------------------------------------------------------------------------

namespace {

int testStatus = 0;

void aSsErT(bool condition, const char *message, int line)
{
    if (condition) {
        cout << "Error " __FILE__ "(" << line << "): " << message
             << "    (failed)" << endl;

        if (0 <= testStatus && testStatus <= 100) {
            ++testStatus;
        }
    }
}

}  // close unnamed namespace

// ============================================================================
//               STANDARD BDE TEST DRIVER MACRO ABBREVIATIONS
// ----------------------------------------------------------------------------

#define ASSERT BSLIM_TESTUTIL_ASSERT
#define ASSERTV BSLIM_TESTUTIL_ASSERTV

#define LOOP_ASSERT BSLIM_TESTUTIL_LOOP_ASSERT
#define LOOP0_ASSERT BSLIM_TESTUTIL_LOOP0_ASSERT
#define LOOP1_ASSERT BSLIM_TESTUTIL_LOOP1_ASSERT
#define LOOP2_ASSERT BSLIM_TESTUTIL_LOOP2_ASSERT
#define LOOP3_ASSERT BSLIM_TESTUTIL_LOOP3_ASSERT
#define LOOP4_ASSERT BSLIM_TESTUTIL_LOOP4_ASSERT
#define LOOP5_ASSERT BSLIM_TESTUTIL_LOOP5_ASSERT
#define LOOP6_ASSERT BSLIM_TESTUTIL_LOOP6_ASSERT

#define Q BSLIM_TESTUTIL_Q    // Quote identifier literally.
#define P BSLIM_TESTUTIL_P    // Print identifier and value.
#define P_ BSLIM_TESTUTIL_P_  // P(X) without '\n'.
#define T_ BSLIM_TESTUTIL_T_  // Print a tab (w/o newline).
#define L_ BSLIM_TESTUTIL_L_  // current Line number

// ============================================================================
//            GLOBAL TYPES, CONSTANTS, AND VARIABLES FOR TESTING
// ----------------------------------------------------------------------------

typedef balb::AssertionTrackerSingleton<balb::AssertionTracker> Obj;

///Usage
///-----
// This section illustrates intended use of this component.
//
///Example 1: Count Number of Assertions Triggered
///- - - - - - - - - - - - - - - - - - - - - - - -
// We wish to count how many times assertions trigger, doing no other handling
// and allowing the program to continue running (note that this is normally
// forbidden in production).  We can use 'AssertionTrackerSingleton' to set up
// an assertion handler to do this.
//
// First, we create a class to do the counting.
//..
    class AssertionCounter {
        // PRIVATE DATA
        int d_assertion_counter;  // Number of assertions seen.

      public:
        // PUBLIC CREATORS
        explicit AssertionCounter(bsls::Assert::Handler = 0, void * = 0);
            // Create an 'AssertionCounter' object.  We ignore the fallback
            // handler and optional allocator parameters.

        // PUBLIC MANIPULATORS
        void operator()(const char *, const char *, int);
            // Function called when assertion failure occurs.  We ignore the
            // text, file, and line parameters.

        // PUBLIC ACCESSORS
        int getAssertionCount() const;
            // Return the number of assertions we have seen.
    };
//..
// Then, we implement the member functions of the 'AssertionCounter' class.
//..
    AssertionCounter::AssertionCounter(bsls::Assert::Handler, void *)
    : d_assertion_counter(0)
    {
    }

    void AssertionCounter::operator()(const char *, const char *, int)
    {
        ++d_assertion_counter;
    }

    int AssertionCounter::getAssertionCount() const
    {
        return d_assertion_counter;
    }
//..

// ============================================================================
//                               MAIN PROGRAM
// ----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
    int                 test = (argc > 1) ? atoi(argv[1]) : 1;
    bool             verbose = (argc > 2); (void)verbose;
    bool         veryVerbose = (argc > 3); (void)veryVerbose;
    bool     veryVeryVerbose = (argc > 4); (void)veryVeryVerbose;
    bool veryVeryVeryVerbose = (argc > 5); (void)veryVeryVeryVerbose;

    cout << "TEST " << __FILE__ << " CASE " << test << endl;

    switch (test) { case 0:
      case 2: {
        // --------------------------------------------------------------------
        // USAGE EXAMPLE
        //   Extracted from component header file.
        //
        // Concerns:
        //: 1 The usage example provided in the component header file compiles,
        //:   links, and runs as shown.
        //
        // Plan:
        //: 1 Incorporate usage example from header into test driver, remove
        //:   leading comment characters, and replace 'assert' with 'ASSERT'.
        //:   (C-1)
        //
        // Testing:
        //   USAGE EXAMPLE
        // --------------------------------------------------------------------

        if (verbose) cout << "\nUSAGE EXAMPLE"
                             "\n=============\n";
// Next, we set up an instance of this class to be the installed assertion
// using 'AssertionTrackerSingleton'.  Note that this needs to be done early in
// 'main()' before any other handlers are installed.  If another handler has
// already been installed, a null pointer will be returned, and we assert that
// this does not happen.
//..
    AssertionCounter *ac_p =
        balb::AssertionTrackerSingleton<AssertionCounter>::singleton();
    ASSERT(ac_p);
//..
// Finally, we will trigger some assertions and verify that we are counting
// them correctly.
//..
    BSLS_ASSERT_ASSERT(0 && "assertion 1");
    BSLS_ASSERT_ASSERT(0 && "assertion 2");
    ASSERT(ac_p->getAssertionCount() == 2);
//..
      } break;
      case 1: {
        // --------------------------------------------------------------------
        // BREATHING TEST
        //   This case exercises (but does not fully test) basic functionality.
        //
        // Concerns:
        //: 1 The class is sufficiently functional to install an assertion
        //:   handler and process assertions.
        //
        // Plan:
        //: 1 Create a singleton 'AssertionTracker' object, trigger some
        //:   assertions, and verify that they are noticed by having the
        //:   assertion handler write them to a string stream and then
        //:   examining the contents of the stream.
        //
        // Testing:
        //   void failTracker(const char *, const char *, int);
        //   TRACKER *singleton(bslma::Allocator * = 0);
        // --------------------------------------------------------------------

        if (verbose)
            cout << "BREATHING TEST\n"
                    "==============\n";
        {
            bsl::ostringstream      os;
            balb::AssertionTracker *at_p = Obj::singleton();

            ASSERT(at_p);
            at_p->setReportingCallback(
                bdlf::BindUtil::bind(&balb::AssertionTracker::reportAssertion,
                                     &os,
                                     bdlf::PlaceHolders::_1,
                                     bdlf::PlaceHolders::_2,
                                     bdlf::PlaceHolders::_3,
                                     bdlf::PlaceHolders::_4,
                                     bdlf::PlaceHolders::_5));

            for (int i = 0; i < 10; ++i) {
                if (veryVeryVerbose) { P_(i) Q("assert 1") }
                BSLS_ASSERT_ASSERT(0 && "assert 1");
                for (int j = 0; j < 10; ++j) {
                    if (veryVeryVerbose) { P_(i) P_(j) Q("assert 2") }
                    BSLS_ASSERT_ASSERT(0 && "assert 2");
                }
            }

            for (int i = 0; i < 2; ++i) {
                if (veryVeryVerbose) { P_(i) Q("assert 3") }
                Obj::failTracker("0 && \"assert 3\"", __FILE__, __LINE__);
            }

            bsl::string s = os.str();

            ASSERTV(s, s.npos != s.find(__FILE__));

            ASSERTV(s, s.npos != s.find(":1:0 && \"assert 1\":"))
            ASSERTV(s, s.npos != s.find(":1:0 && \"assert 2\":"))
            ASSERTV(s, s.npos != s.find(":1:0 && \"assert 3\":"))

            os.str("");
            at_p->reportAllStackTraces();
            s = os.str();

#ifdef BSLS_PLATFORM_OS_WINDOWS
            // In some Windows builds the stack traces appear to be split, with
            // a each assertion appearing twice with different stack traces. I
            // have seen this with cl-18, while cl-19 seems to work properly.
            // For now, just test that the assertions show up at all.
            ASSERTV(s, s.npos != s.find(":0 && \"assert 1\":"))
            ASSERTV(s, s.npos != s.find(":0 && \"assert 2\":"))
            ASSERTV(s, s.npos != s.find(":0 && \"assert 3\":"))
#else
            ASSERTV(s, s.npos != s.find(":10:0 && \"assert 1\":"))
            ASSERTV(s, s.npos != s.find(":100:0 && \"assert 2\":"))
            ASSERTV(s, s.npos != s.find(":2:0 && \"assert 3\":"))
#endif
        }
      } break;
      default: {
        cerr << "WARNING: CASE `" << test << "' NOT FOUND." << endl;
        testStatus = -1;
      }
    }

    if (testStatus > 0) {
        cerr << "Error, non-zero test status = " << testStatus << "." << endl;
    }
    return testStatus;
}

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


<commit_before>//===--- NameBinding.cpp - Name Binding -----------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
//  This file implements name binding for Swift.
//
//===----------------------------------------------------------------------===//

#include "swift/Subsystems.h"
#include "swift/AST/AST.h"
#include "swift/AST/Component.h"
#include "swift/AST/Diagnostics.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/system_error.h"
#include "llvm/Support/Path.h"
using namespace swift;

//===----------------------------------------------------------------------===//
// NameBinder
//===----------------------------------------------------------------------===//

typedef TranslationUnit::ImportedModule ImportedModule;
typedef llvm::PointerUnion<const ImportedModule*, OneOfType*> BoundScope;

namespace {
  class NameBinder {
    llvm::error_code findModule(StringRef Module,
                                SourceLoc ImportLoc,
                                llvm::OwningPtr<llvm::MemoryBuffer> &Buffer);

  public:
    TranslationUnit *TU;
    ASTContext &Context;

    NameBinder(TranslationUnit *TU) : TU(TU), Context(TU->Ctx) {
    }
    ~NameBinder() {
    }

    template<typename ...ArgTypes>
    InFlightDiagnostic diagnose(ArgTypes... Args) {
      return Context.Diags.diagnose(Args...);
    }

    void addImport(ImportDecl *ID, SmallVectorImpl<ImportedModule> &Result);

    BoundScope bindScopeName(TypeAliasDecl *TypeFromScope,
                             Identifier Name, SourceLoc NameLoc);

  private:
    /// getModule - Load a module referenced by an import statement,
    /// emitting an error at the specified location and returning null on
    /// failure.
    Module *getModule(std::pair<Identifier,SourceLoc> ModuleID);
  };
}

llvm::error_code NameBinder::findModule(StringRef Module,
                                        SourceLoc ImportLoc,
                                llvm::OwningPtr<llvm::MemoryBuffer> &Buffer) {
  std::string ModuleFilename = Module.str() + std::string(".swift");

  llvm::SmallString<128> InputFilename;

  // First, search in the directory corresponding to the import location.
  // FIXME: This screams for a proper FileManager abstraction.
  llvm::SourceMgr &SourceMgr = Context.SourceMgr;
  int CurrentBufferID = SourceMgr.FindBufferContainingLoc(ImportLoc.Value);
  if (CurrentBufferID >= 0) {
    const llvm::MemoryBuffer *ImportingBuffer
      = SourceMgr.getBufferInfo(CurrentBufferID).Buffer;
    StringRef CurrentDirectory
      = llvm::sys::path::parent_path(ImportingBuffer->getBufferIdentifier());
    if (!CurrentDirectory.empty()) {
      InputFilename = CurrentDirectory;
      llvm::sys::path::append(InputFilename, ModuleFilename);
      llvm::error_code Err = llvm::MemoryBuffer::getFile(InputFilename, Buffer);
      if (!Err)
        return Err;
    }
  }

  // Second, search in the current directory.
  llvm::error_code Err = llvm::MemoryBuffer::getFile(ModuleFilename, Buffer);
  if (!Err)
    return Err;

  // If we fail, search each import search path.
  for (auto Path : Context.ImportSearchPaths) {
    InputFilename = Path;
    llvm::sys::path::append(InputFilename, ModuleFilename);
    Err = llvm::MemoryBuffer::getFile(InputFilename, Buffer);
    if (!Err)
      return Err;
  }

  return Err;
}

Module *NameBinder::getModule(std::pair<Identifier, SourceLoc> ModuleID) {
  // TODO: We currently just recursively parse referenced modules.  This works
  // fine for now since they are each a single file.  Ultimately we'll want a
  // compiled form of AST's like clang's that support lazy deserialization.

  // Open the input file.
  llvm::OwningPtr<llvm::MemoryBuffer> InputFile;
  if (llvm::error_code Err = findModule(ModuleID.first.str(), ModuleID.second,
                                        InputFile)) {
    diagnose(ModuleID.second, diag::sema_opening_import,
             ModuleID.first.str(), Err.message());
    return 0;
  }

  unsigned BufferID =
    Context.SourceMgr.AddNewSourceBuffer(InputFile.take(),
                                         ModuleID.second.Value);

  // For now, treat all separate modules as unique components.
  Component *Comp = new (Context.Allocate<Component>(1)) Component();

  // Parse the translation unit, but don't do name binding or type checking.
  // This can produce new errors etc if the input is erroneous.
  TranslationUnit *TU = parseTranslationUnit(BufferID, Comp, Context);
  if (TU == 0)
    return 0;

  // We have to do name binding on it to ensure that types are fully resolved.
  // This should eventually be eliminated by having actual fully resolved binary
  // dumps of the code instead of reparsing though.
  performNameBinding(TU);

  return TU;
}

void NameBinder::addImport(ImportDecl *ID,
                           SmallVectorImpl<ImportedModule> &Result) {
  ArrayRef<ImportDecl::AccessPathElement> Path = ID->getAccessPath();
  Module *M = getModule(Path[0]);
  if (M == 0) return;

  // FIXME: Validate the access path against the module.  Reject things like
  // import swift.aslkdfja
  if (Path.size() > 2) {
    diagnose(Path[2].second, diag::invalid_declaration_imported);
    return;
  }

  Result.push_back(std::make_pair(Path.slice(1), M));
}

/// Try to bind an unqualified name into something usable as a scope.
BoundScope NameBinder::bindScopeName(TypeAliasDecl *TypeFromScope,
                                     Identifier Name, SourceLoc NameLoc) {
  // Check whether the "optimistic" type from scope is still
  // undefined.  If not, use that as the actual type; otherwise we'll
  // need to do a lookup from the imports.
  TypeAliasDecl *Type;
  if (TypeFromScope->hasUnderlyingType()) {
    Type = TypeFromScope;
  } else {
    Type = TU->lookupGlobalType(Name, NLKind::UnqualifiedLookup);
  }

  // If that failed, look for a module name.
  if (!Type) {
    for (const ImportedModule &ImpEntry : TU->ImportedModules)
      if (ImpEntry.second->Name == Name)
        return &ImpEntry;

    diagnose(NameLoc, diag::no_module_or_type);
    return BoundScope();
  }

  // Otherwise, at least cache the type we found.
  assert(Type->hasUnderlyingType());
  if (!TypeFromScope->hasUnderlyingType()) {
    TypeFromScope->setUnderlyingType(Type->getUnderlyingType());
  }

  // Try to convert that to a type scope.
  TypeBase *Ty = Type->getUnderlyingType()->getCanonicalType();

  // Silently fail if we have an error type.
  if (isa<ErrorType>(Ty)) return BoundScope();

  // Reject things like int::x.
  OneOfType *DT = dyn_cast<OneOfType>(Ty);
  if (DT == 0) {
    diagnose(NameLoc, diag::invalid_type_scoped_access, Name);
    return BoundScope();
  }

  if (DT->Elements.empty()) {
    diagnose(NameLoc, diag::incomplete_or_empty_oneof, Name);
    return BoundScope();
  }

  return DT;
}

//===----------------------------------------------------------------------===//
// performNameBinding
//===----------------------------------------------------------------------===//

static Expr *BindNames(Expr *E, WalkOrder Order, NameBinder &Binder) {

  // Ignore the preorder walk.
  if (Order == WalkOrder::PreOrder)
    return E;

  Identifier Name;
  SourceLoc Loc;
  SmallVector<ValueDecl*, 4> Decls;

  // Process UnresolvedDeclRefExpr by doing an unqualified lookup.
  if (UnresolvedDeclRefExpr *UDRE = dyn_cast<UnresolvedDeclRefExpr>(E)) {
    Name = UDRE->getName();
    Loc = UDRE->getLoc();
    Binder.TU->lookupGlobalValue(Name, NLKind::UnqualifiedLookup, Decls);

  // Process UnresolvedScopedIdentifierExpr by doing a qualified lookup.
  } else if (UnresolvedScopedIdentifierExpr *USIE =
               dyn_cast<UnresolvedScopedIdentifierExpr>(E)) {
    Name = USIE->getName();
    Loc = USIE->getNameLoc();

    Identifier BaseName = USIE->getBaseName();
    SourceLoc BaseNameLoc = USIE->getBaseNameLoc();
    BoundScope Scope =
      Binder.bindScopeName(USIE->getBaseTypeFromScope(), BaseName, BaseNameLoc);
    if (!Scope) return nullptr;

    auto Module = Scope.get<const ImportedModule*>();
    Module->second->lookupValue(Module->first, Name,
                                NLKind::QualifiedLookup, Decls);

  // Otherwise, not something that needs name binding.
  } else {
    return E;
  }

  if (Decls.empty()) {
    Binder.diagnose(Loc, diag::use_unresolved_identifier, Name);
    return 0;
  }

  if (Decls.size() == 1)
    return new (Binder.Context) DeclRefExpr(Decls[0], Loc);

  // Copy the overload set into ASTContext memory.
  ArrayRef<ValueDecl*> DeclList = Binder.Context.AllocateCopy(Decls);

  return new (Binder.Context) OverloadSetRefExpr(DeclList, Loc);
}

static void bindNamesInDecl(Decl *D, WalkExprType ^BinderBlock) {
  if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
    if (VD->getInit())
      VD->setInit(VD->getInit()->walk(BinderBlock));
  } else if (ExtensionDecl *ED = dyn_cast<ExtensionDecl>(D)) {
    for (Decl *Member : ED->getMembers()) {
      bindNamesInDecl(Member, BinderBlock);
    }
  }
}

/// performNameBinding - Once parsing is complete, this walks the AST to
/// resolve names and do other top-level validation.
///
/// At this parsing has been performed, but we still have UnresolvedDeclRefExpr
/// nodes for unresolved value names, and we may have unresolved type names as
/// well.  This handles import directives and forward references.
void swift::performNameBinding(TranslationUnit *TU) {
  NameBinder Binder(TU);

  SmallVector<ImportedModule, 8> ImportedModules;

  // Import the builtin library as an implicit import.
  // FIXME: This should only happen for translation units in the standard
  // library.
  ImportedModules.push_back(std::make_pair(Module::AccessPathTy(),
                                           TU->Ctx.TheBuiltinModule));

  // FIXME: For translation units not in the standard library, we should import
  // swift.swift implicitly.  We need a way for swift.swift itself to not
  // recursively import itself though.

  // Do a prepass over the declarations to find and load the imported modules.
  for (auto Elt : TU->Body->getElements())
    if (Decl *D = Elt.dyn_cast<Decl*>()) {
      if (ImportDecl *ID = dyn_cast<ImportDecl>(D))
        Binder.addImport(ID, ImportedModules);
    }

  TU->setImportedModules(TU->Ctx.AllocateCopy(ImportedModules));

  // Type binding.  Loop over all of the unresolved types in the translation
  // unit, resolving them with imports.
  for (TypeAliasDecl *TA : TU->getUnresolvedTypes()) {
    if (TypeAliasDecl *Result =
          Binder.TU->lookupGlobalType(TA->getName(),
                                      NLKind::UnqualifiedLookup)) {
      assert(!TA->hasUnderlyingType() && "Not an unresolved type");
      // Update the decl we already have to be the correct type.
      TA->setTypeAliasLoc(Result->getTypeAliasLoc());
      TA->setUnderlyingType(Result->getUnderlyingType());
      continue;
    }

    Binder.diagnose(TA->getLocStart(), diag::use_undeclared_type,
                    TA->getName());

    TA->setUnderlyingType(ErrorType::get(TU->Ctx));
  }

  // Loop over all the unresolved scoped types in the translation
  // unit, resolving them if possible.
  for (auto BaseAndType : TU->getUnresolvedScopedTypes()) {
    BoundScope Scope = Binder.bindScopeName(BaseAndType.first,
                                            BaseAndType.first->getName(),
                                        BaseAndType.first->getTypeAliasLoc());
    if (!Scope) continue;

    Identifier Name = BaseAndType.second->getName();
    SourceLoc NameLoc = BaseAndType.second->getTypeAliasLoc();

    TypeAliasDecl *Alias = nullptr;
    if (auto Module = Scope.dyn_cast<const ImportedModule*>())
      Alias = Module->second->lookupType(Module->first, Name,
                                         NLKind::QualifiedLookup);

    if (Alias) {
      BaseAndType.second->setUnderlyingType(Alias->getAliasType());
    } else {
      Binder.diagnose(NameLoc, diag::invalid_member_type,
                      Name, BaseAndType.first->getName());
      BaseAndType.second->setUnderlyingType(Binder.Context.TheErrorType);
    }
  }

  NameBinder *NBPtr = &Binder;
  auto BinderBlock = ^(Expr *E, WalkOrder Order, WalkContext const&) {
    return BindNames(E, Order, *NBPtr);
  };

  // Now that we know the top-level value names, go through and resolve any
  // UnresolvedDeclRefExprs that exist.
  for (unsigned i = 0, e = TU->Body->getNumElements(); i != e; ++i) {
    BraceStmt::ExprStmtOrDecl Elt = TU->Body->getElement(i);
    if (Decl *D = Elt.dyn_cast<Decl*>()) {
      bindNamesInDecl(D, BinderBlock);
    } else if (Stmt *S = Elt.dyn_cast<Stmt*>()) {
      Elt = S->walk(BinderBlock);
    } else {
      Elt = Elt.get<Expr*>()->walk(BinderBlock);
    }

    // Fill in null results with a dummy expression.
    if (Elt.isNull())
      Elt = new (TU->Ctx) TupleExpr(SourceLoc(), 0, 0, 0, SourceLoc(),
                                    TypeJudgement(TupleType::getEmpty(TU->Ctx),
                                                  ValueKind::RValue));
    TU->Body->setElement(i, Elt);
  }

  TU->ASTStage = TranslationUnit::NameBound;
  verify(TU);
}

<commit_msg>implement support for normal lookup to find module names, and build a  ModuleExpr of the right  type to represent it.  Not tested yet, because nothing can handle module exprs.<commit_after>//===--- NameBinding.cpp - Name Binding -----------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
//  This file implements name binding for Swift.
//
//===----------------------------------------------------------------------===//

#include "swift/Subsystems.h"
#include "swift/AST/AST.h"
#include "swift/AST/Component.h"
#include "swift/AST/Diagnostics.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/system_error.h"
#include "llvm/Support/Path.h"
using namespace swift;

//===----------------------------------------------------------------------===//
// NameBinder
//===----------------------------------------------------------------------===//

typedef TranslationUnit::ImportedModule ImportedModule;
typedef llvm::PointerUnion<const ImportedModule*, OneOfType*> BoundScope;

namespace {
  class NameBinder {
    llvm::error_code findModule(StringRef Module,
                                SourceLoc ImportLoc,
                                llvm::OwningPtr<llvm::MemoryBuffer> &Buffer);

  public:
    TranslationUnit *TU;
    ASTContext &Context;

    NameBinder(TranslationUnit *TU) : TU(TU), Context(TU->Ctx) {
    }
    ~NameBinder() {
    }

    template<typename ...ArgTypes>
    InFlightDiagnostic diagnose(ArgTypes... Args) {
      return Context.Diags.diagnose(Args...);
    }

    void addImport(ImportDecl *ID, SmallVectorImpl<ImportedModule> &Result);

    BoundScope bindScopeName(TypeAliasDecl *TypeFromScope,
                             Identifier Name, SourceLoc NameLoc);

  private:
    /// getModule - Load a module referenced by an import statement,
    /// emitting an error at the specified location and returning null on
    /// failure.
    Module *getModule(std::pair<Identifier,SourceLoc> ModuleID);
  };
}

llvm::error_code NameBinder::findModule(StringRef Module,
                                        SourceLoc ImportLoc,
                                llvm::OwningPtr<llvm::MemoryBuffer> &Buffer) {
  std::string ModuleFilename = Module.str() + std::string(".swift");

  llvm::SmallString<128> InputFilename;

  // First, search in the directory corresponding to the import location.
  // FIXME: This screams for a proper FileManager abstraction.
  llvm::SourceMgr &SourceMgr = Context.SourceMgr;
  int CurrentBufferID = SourceMgr.FindBufferContainingLoc(ImportLoc.Value);
  if (CurrentBufferID >= 0) {
    const llvm::MemoryBuffer *ImportingBuffer
      = SourceMgr.getBufferInfo(CurrentBufferID).Buffer;
    StringRef CurrentDirectory
      = llvm::sys::path::parent_path(ImportingBuffer->getBufferIdentifier());
    if (!CurrentDirectory.empty()) {
      InputFilename = CurrentDirectory;
      llvm::sys::path::append(InputFilename, ModuleFilename);
      llvm::error_code Err = llvm::MemoryBuffer::getFile(InputFilename, Buffer);
      if (!Err)
        return Err;
    }
  }

  // Second, search in the current directory.
  llvm::error_code Err = llvm::MemoryBuffer::getFile(ModuleFilename, Buffer);
  if (!Err)
    return Err;

  // If we fail, search each import search path.
  for (auto Path : Context.ImportSearchPaths) {
    InputFilename = Path;
    llvm::sys::path::append(InputFilename, ModuleFilename);
    Err = llvm::MemoryBuffer::getFile(InputFilename, Buffer);
    if (!Err)
      return Err;
  }

  return Err;
}

Module *NameBinder::getModule(std::pair<Identifier, SourceLoc> ModuleID) {
  // TODO: We currently just recursively parse referenced modules.  This works
  // fine for now since they are each a single file.  Ultimately we'll want a
  // compiled form of AST's like clang's that support lazy deserialization.

  // Open the input file.
  llvm::OwningPtr<llvm::MemoryBuffer> InputFile;
  if (llvm::error_code Err = findModule(ModuleID.first.str(), ModuleID.second,
                                        InputFile)) {
    diagnose(ModuleID.second, diag::sema_opening_import,
             ModuleID.first.str(), Err.message());
    return 0;
  }

  unsigned BufferID =
    Context.SourceMgr.AddNewSourceBuffer(InputFile.take(),
                                         ModuleID.second.Value);

  // For now, treat all separate modules as unique components.
  Component *Comp = new (Context.Allocate<Component>(1)) Component();

  // Parse the translation unit, but don't do name binding or type checking.
  // This can produce new errors etc if the input is erroneous.
  TranslationUnit *TU = parseTranslationUnit(BufferID, Comp, Context);
  if (TU == 0)
    return 0;

  // We have to do name binding on it to ensure that types are fully resolved.
  // This should eventually be eliminated by having actual fully resolved binary
  // dumps of the code instead of reparsing though.
  performNameBinding(TU);

  return TU;
}

void NameBinder::addImport(ImportDecl *ID,
                           SmallVectorImpl<ImportedModule> &Result) {
  ArrayRef<ImportDecl::AccessPathElement> Path = ID->getAccessPath();
  Module *M = getModule(Path[0]);
  if (M == 0) return;

  // FIXME: Validate the access path against the module.  Reject things like
  // import swift.aslkdfja
  if (Path.size() > 2) {
    diagnose(Path[2].second, diag::invalid_declaration_imported);
    return;
  }

  Result.push_back(std::make_pair(Path.slice(1), M));
}

/// Try to bind an unqualified name into something usable as a scope.
BoundScope NameBinder::bindScopeName(TypeAliasDecl *TypeFromScope,
                                     Identifier Name, SourceLoc NameLoc) {
  // Check whether the "optimistic" type from scope is still
  // undefined.  If not, use that as the actual type; otherwise we'll
  // need to do a lookup from the imports.
  TypeAliasDecl *Type;
  if (TypeFromScope->hasUnderlyingType()) {
    Type = TypeFromScope;
  } else {
    Type = TU->lookupGlobalType(Name, NLKind::UnqualifiedLookup);
  }

  // If that failed, look for a module name.
  if (!Type) {
    for (const ImportedModule &ImpEntry : TU->ImportedModules)
      if (ImpEntry.second->Name == Name)
        return &ImpEntry;

    diagnose(NameLoc, diag::no_module_or_type);
    return BoundScope();
  }

  // Otherwise, at least cache the type we found.
  assert(Type->hasUnderlyingType());
  if (!TypeFromScope->hasUnderlyingType()) {
    TypeFromScope->setUnderlyingType(Type->getUnderlyingType());
  }

  // Try to convert that to a type scope.
  TypeBase *Ty = Type->getUnderlyingType()->getCanonicalType();

  // Silently fail if we have an error type.
  if (isa<ErrorType>(Ty)) return BoundScope();

  // Reject things like int::x.
  OneOfType *DT = dyn_cast<OneOfType>(Ty);
  if (DT == 0) {
    diagnose(NameLoc, diag::invalid_type_scoped_access, Name);
    return BoundScope();
  }

  if (DT->Elements.empty()) {
    diagnose(NameLoc, diag::incomplete_or_empty_oneof, Name);
    return BoundScope();
  }

  return DT;
}

//===----------------------------------------------------------------------===//
// performNameBinding
//===----------------------------------------------------------------------===//

static Expr *BindNames(Expr *E, WalkOrder Order, NameBinder &Binder) {

  // Ignore the preorder walk.
  if (Order == WalkOrder::PreOrder)
    return E;

  Identifier Name;
  SourceLoc Loc;
  SmallVector<ValueDecl*, 4> Decls;

  // Process UnresolvedDeclRefExpr by doing an unqualified lookup.
  if (UnresolvedDeclRefExpr *UDRE = dyn_cast<UnresolvedDeclRefExpr>(E)) {
    Name = UDRE->getName();
    Loc = UDRE->getLoc();
    // Perform standard value name lookup.
    Binder.TU->lookupGlobalValue(Name, NLKind::UnqualifiedLookup, Decls);

    // If that fails, this may be the name of a module, try looking that up.
    if (Decls.empty()) {
      for (const ImportedModule &ImpEntry : Binder.TU->ImportedModules)
        if (ImpEntry.second->Name == Name) {
          ModuleType *MT = ModuleType::get(ImpEntry.second);
          return new (Binder.Context) ModuleExpr(Loc,
                                        TypeJudgement(MT, ValueKind::RValue));
        }
    }

  // Process UnresolvedScopedIdentifierExpr by doing a qualified lookup.
  } else if (UnresolvedScopedIdentifierExpr *USIE =
               dyn_cast<UnresolvedScopedIdentifierExpr>(E)) {
    Name = USIE->getName();
    Loc = USIE->getNameLoc();

    Identifier BaseName = USIE->getBaseName();
    SourceLoc BaseNameLoc = USIE->getBaseNameLoc();
    BoundScope Scope =
      Binder.bindScopeName(USIE->getBaseTypeFromScope(), BaseName, BaseNameLoc);
    if (!Scope) return nullptr;

    auto Module = Scope.get<const ImportedModule*>();
    Module->second->lookupValue(Module->first, Name,
                                NLKind::QualifiedLookup, Decls);

  // Otherwise, not something that needs name binding.
  } else {
    return E;
  }

  if (Decls.empty()) {
    Binder.diagnose(Loc, diag::use_unresolved_identifier, Name);
    return 0;
  }

  if (Decls.size() == 1)
    return new (Binder.Context) DeclRefExpr(Decls[0], Loc);

  // Copy the overload set into ASTContext memory.
  ArrayRef<ValueDecl*> DeclList = Binder.Context.AllocateCopy(Decls);

  return new (Binder.Context) OverloadSetRefExpr(DeclList, Loc);
}

static void bindNamesInDecl(Decl *D, WalkExprType ^BinderBlock) {
  if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
    if (VD->getInit())
      VD->setInit(VD->getInit()->walk(BinderBlock));
  } else if (ExtensionDecl *ED = dyn_cast<ExtensionDecl>(D)) {
    for (Decl *Member : ED->getMembers()) {
      bindNamesInDecl(Member, BinderBlock);
    }
  }
}

/// performNameBinding - Once parsing is complete, this walks the AST to
/// resolve names and do other top-level validation.
///
/// At this parsing has been performed, but we still have UnresolvedDeclRefExpr
/// nodes for unresolved value names, and we may have unresolved type names as
/// well.  This handles import directives and forward references.
void swift::performNameBinding(TranslationUnit *TU) {
  NameBinder Binder(TU);

  SmallVector<ImportedModule, 8> ImportedModules;

  // Import the builtin library as an implicit import.
  // FIXME: This should only happen for translation units in the standard
  // library.
  ImportedModules.push_back(std::make_pair(Module::AccessPathTy(),
                                           TU->Ctx.TheBuiltinModule));

  // FIXME: For translation units not in the standard library, we should import
  // swift.swift implicitly.  We need a way for swift.swift itself to not
  // recursively import itself though.

  // Do a prepass over the declarations to find and load the imported modules.
  for (auto Elt : TU->Body->getElements())
    if (Decl *D = Elt.dyn_cast<Decl*>()) {
      if (ImportDecl *ID = dyn_cast<ImportDecl>(D))
        Binder.addImport(ID, ImportedModules);
    }

  TU->setImportedModules(TU->Ctx.AllocateCopy(ImportedModules));

  // Type binding.  Loop over all of the unresolved types in the translation
  // unit, resolving them with imports.
  for (TypeAliasDecl *TA : TU->getUnresolvedTypes()) {
    if (TypeAliasDecl *Result =
          Binder.TU->lookupGlobalType(TA->getName(),
                                      NLKind::UnqualifiedLookup)) {
      assert(!TA->hasUnderlyingType() && "Not an unresolved type");
      // Update the decl we already have to be the correct type.
      TA->setTypeAliasLoc(Result->getTypeAliasLoc());
      TA->setUnderlyingType(Result->getUnderlyingType());
      continue;
    }

    Binder.diagnose(TA->getLocStart(), diag::use_undeclared_type,
                    TA->getName());

    TA->setUnderlyingType(ErrorType::get(TU->Ctx));
  }

  // Loop over all the unresolved scoped types in the translation
  // unit, resolving them if possible.
  for (auto BaseAndType : TU->getUnresolvedScopedTypes()) {
    BoundScope Scope = Binder.bindScopeName(BaseAndType.first,
                                            BaseAndType.first->getName(),
                                        BaseAndType.first->getTypeAliasLoc());
    if (!Scope) continue;

    Identifier Name = BaseAndType.second->getName();
    SourceLoc NameLoc = BaseAndType.second->getTypeAliasLoc();

    TypeAliasDecl *Alias = nullptr;
    if (auto Module = Scope.dyn_cast<const ImportedModule*>())
      Alias = Module->second->lookupType(Module->first, Name,
                                         NLKind::QualifiedLookup);

    if (Alias) {
      BaseAndType.second->setUnderlyingType(Alias->getAliasType());
    } else {
      Binder.diagnose(NameLoc, diag::invalid_member_type,
                      Name, BaseAndType.first->getName());
      BaseAndType.second->setUnderlyingType(Binder.Context.TheErrorType);
    }
  }

  NameBinder *NBPtr = &Binder;
  auto BinderBlock = ^(Expr *E, WalkOrder Order, WalkContext const&) {
    return BindNames(E, Order, *NBPtr);
  };

  // Now that we know the top-level value names, go through and resolve any
  // UnresolvedDeclRefExprs that exist.
  for (unsigned i = 0, e = TU->Body->getNumElements(); i != e; ++i) {
    BraceStmt::ExprStmtOrDecl Elt = TU->Body->getElement(i);
    if (Decl *D = Elt.dyn_cast<Decl*>()) {
      bindNamesInDecl(D, BinderBlock);
    } else if (Stmt *S = Elt.dyn_cast<Stmt*>()) {
      Elt = S->walk(BinderBlock);
    } else {
      Elt = Elt.get<Expr*>()->walk(BinderBlock);
    }

    // Fill in null results with a dummy expression.
    if (Elt.isNull())
      Elt = new (TU->Ctx) TupleExpr(SourceLoc(), 0, 0, 0, SourceLoc(),
                                    TypeJudgement(TupleType::getEmpty(TU->Ctx),
                                                  ValueKind::RValue));
    TU->Body->setElement(i, Elt);
  }

  TU->ASTStage = TranslationUnit::NameBound;
  verify(TU);
}

<|endoftext|>


<commit_before>//
// $Id$
//

#include "AVGImage.h"
#include "IAVGDisplayEngine.h"
#include "AVGPlayer.h"
#include "AVGLogger.h"
#include "IAVGSurface.h"

#include <paintlib/plbitmap.h>
#include <paintlib/planybmp.h>
#include <paintlib/plpngenc.h>
#include <paintlib/planydec.h>
#include <paintlib/Filter/plfilterresizebilinear.h>
#include <paintlib/Filter/plfilterfliprgb.h>
#include <paintlib/Filter/plfilterfill.h>

#include <nsMemory.h>
#include <xpcom/nsComponentManagerUtils.h>

#include <iostream>
#include <sstream>

using namespace std;

NS_IMPL_ISUPPORTS1_CI(AVGImage, IAVGNode);

AVGImage * AVGImage::create()
{
    return createNode<AVGImage>("@c-base.org/avgimage;1");
}

AVGImage::AVGImage ()
    : m_pSurface(0)
{
    NS_INIT_ISUPPORTS();
}

AVGImage::~AVGImage ()
{
    if (m_pSurface) {
        delete m_pSurface;
    }
}

NS_IMETHODIMP
AVGImage::GetType(PRInt32 *_retval)
{
    *_retval = NT_IMAGE;
    return NS_OK;
}

void AVGImage::init (const std::string& id, const std::string& filename,
        int bpp, IAVGDisplayEngine * pEngine, AVGContainer * pParent,
        AVGPlayer * pPlayer)
{
    AVGNode::init(id, pEngine, pParent, pPlayer);

    m_Filename = filename;
    AVG_TRACE(AVGPlayer::DEBUG_PROFILE, "Loading " << m_Filename);
    m_pSurface = getEngine()->createSurface();

    PLAnyPicDecoder decoder;
    PLAnyBmp TempBmp;
    // TODO: Decode directly to surface using PLPicDec::GetImage();
    decoder.MakeBmpFromFile(m_Filename.c_str(), &TempBmp, 32);
    if (!pEngine->hasRGBOrdering()) {
        TempBmp.ApplyFilter(PLFilterFlipRGB());
    }
    int DestBPP = bpp;
    if (!pEngine->supportsBpp(bpp)) {
        DestBPP = 32;
    }
    m_pSurface->create(TempBmp.GetWidth(), TempBmp.GetHeight(),
            DestBPP, TempBmp.HasAlpha());

    PLPixel32** ppSrcLines = TempBmp.GetLineArray32();
    PLBmpBase * pDestBmp = m_pSurface->getBmp();
    PLPixel32** ppDestLines = pDestBmp->GetLineArray32();
    for (int y=0; y<TempBmp.GetHeight(); y++) {
        memcpy (ppDestLines[y], ppSrcLines[y], TempBmp.GetWidth()*4);
    }

    getEngine()->surfaceChanged(m_pSurface);
}

void AVGImage::render (const AVGDRect& Rect)
{
    getEngine()->blt32(m_pSurface, &getAbsViewport(), getEffectiveOpacity(),
            getAngle(), getPivot());
}

bool AVGImage::obscures (const AVGDRect& Rect, int z)
{
    return (getEffectiveOpacity() > 0.999 && !m_pSurface->getBmp()->HasAlpha()
            && getZ() > z && getVisibleRect().Contains(Rect));
}

string AVGImage::getTypeStr ()
{
    return "AVGImage";
}

AVGDPoint AVGImage::getPreferredMediaSize()
{
    return AVGDPoint(m_pSurface->getBmp()->GetSize());
}

<commit_msg>Refactored to use CopyPixels()<commit_after>//
// $Id$
//

#include "AVGImage.h"
#include "IAVGDisplayEngine.h"
#include "AVGPlayer.h"
#include "AVGLogger.h"
#include "IAVGSurface.h"

#include <paintlib/plbitmap.h>
#include <paintlib/planybmp.h>
#include <paintlib/plpngenc.h>
#include <paintlib/planydec.h>
#include <paintlib/Filter/plfilterresizebilinear.h>
#include <paintlib/Filter/plfilterfliprgb.h>
#include <paintlib/Filter/plfilterfill.h>

#include <nsMemory.h>
#include <xpcom/nsComponentManagerUtils.h>

#include <iostream>
#include <sstream>

using namespace std;

NS_IMPL_ISUPPORTS1_CI(AVGImage, IAVGNode);

AVGImage * AVGImage::create()
{
    return createNode<AVGImage>("@c-base.org/avgimage;1");
}

AVGImage::AVGImage ()
    : m_pSurface(0)
{
    NS_INIT_ISUPPORTS();
}

AVGImage::~AVGImage ()
{
    if (m_pSurface) {
        delete m_pSurface;
    }
}

NS_IMETHODIMP
AVGImage::GetType(PRInt32 *_retval)
{
    *_retval = NT_IMAGE;
    return NS_OK;
}

void AVGImage::init (const std::string& id, const std::string& filename,
        int bpp, IAVGDisplayEngine * pEngine, AVGContainer * pParent,
        AVGPlayer * pPlayer)
{
    AVGNode::init(id, pEngine, pParent, pPlayer);

    m_Filename = filename;
    AVG_TRACE(AVGPlayer::DEBUG_PROFILE, "Loading " << m_Filename);
    m_pSurface = getEngine()->createSurface();

    PLAnyPicDecoder decoder;
    PLAnyBmp TempBmp;
    decoder.MakeBmpFromFile(m_Filename.c_str(), &TempBmp, 32);
    if (!pEngine->hasRGBOrdering()) {
        TempBmp.ApplyFilter(PLFilterFlipRGB());
    }
    int DestBPP = bpp;
    if (!pEngine->supportsBpp(bpp)) {
        DestBPP = 32;
    }
    m_pSurface->create(TempBmp.GetWidth(), TempBmp.GetHeight(),
            DestBPP, TempBmp.HasAlpha());
    m_pSurface->getBmp()->CopyPixels(TempBmp);

    getEngine()->surfaceChanged(m_pSurface);
}

void AVGImage::render (const AVGDRect& Rect)
{
    getEngine()->blt32(m_pSurface, &getAbsViewport(), getEffectiveOpacity(),
            getAngle(), getPivot());
}

bool AVGImage::obscures (const AVGDRect& Rect, int z)
{
    return (getEffectiveOpacity() > 0.999 && !m_pSurface->getBmp()->HasAlpha()
            && getZ() > z && getVisibleRect().Contains(Rect));
}

string AVGImage::getTypeStr ()
{
    return "AVGImage";
}

AVGDPoint AVGImage::getPreferredMediaSize()
{
    return AVGDPoint(m_pSurface->getBmp()->GetSize());
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 SeNDA
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
/**
 * FILE NeighbourTable.cpp
 * AUTHOR Blackcatn13
 * DATE Jun 29, 2015
 * VERSION 1
 * This file contains the implementation of the Neighbour class.
 */

#include "Node/Neighbour/NeighbourTable.h"
#include <string>
#include <cstdint>
#include <map>
#include <mutex>
#include "Node/Neighbour/Neighbour.h"

NeighbourTable *NeighbourTable::m_instance = 0;

NeighbourTable::NeighbourTable() {
}

NeighbourTable::~NeighbourTable() {
}

NeighbourTable* NeighbourTable::getInstance() {
  if (m_instance == 0) {
    m_instance = new NeighbourTable();
  }
  return m_instance;
}

void NeighbourTable::update(const std::string &nodeId,
                            const std::string &nodeAddress,
                            const uint16_t &nodePort) {
  mutex.lock();
  std::map<std::string, std::shared_ptr<Neighbour>>::iterator it = m_neighbours
      .find(nodeId);
  if (it != m_neighbours.end()) {
    if (m_neighbours[nodeId]->m_nodeAddress != nodeAddress)
      m_neighbours[nodeId]->m_nodeAddress = nodeAddress;
    if (m_neighbours[nodeId]->m_nodePort != nodePort)
      m_neighbours[nodeId]->m_nodePort = nodePort;
  } else {
    m_neighbours[nodeId] = std::make_shared<Neighbour>(nodeId, nodeAddress,
                                                       nodePort);
  }
  mutex.unlock();
}

void NeighbourTable::cleanNeighbours(int expirationTime) {
  mutex.lock();
  for (std::map<std::string, std::shared_ptr<Neighbour>>::iterator it =
      m_neighbours.begin(); it != m_neighbours.end(); ++it) {
    if ((*it).second->getElapsedActivityTime() >= expirationTime) {
      m_neighbours.erase(it);
    }
  }
  mutex.unlock();
}

void NeighbourTable::getNeighbours(
    std::map<std::string, std::shared_ptr<Neighbour>> *map) {
  mutex.lock();
  (*map).insert(m_neighbours.begin(), m_neighbours.end());
  mutex.unlock();
}

<commit_msg>Fixes not updating neighbour activity time.<commit_after>/*
 * Copyright (c) 2015 SeNDA
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
/**
 * FILE NeighbourTable.cpp
 * AUTHOR Blackcatn13
 * DATE Jun 29, 2015
 * VERSION 1
 * This file contains the implementation of the Neighbour class.
 */

#include "Node/Neighbour/NeighbourTable.h"
#include <string>
#include <cstdint>
#include <map>
#include <mutex>
#include "Node/Neighbour/Neighbour.h"

NeighbourTable *NeighbourTable::m_instance = 0;

NeighbourTable::NeighbourTable() {
}

NeighbourTable::~NeighbourTable() {
}

NeighbourTable* NeighbourTable::getInstance() {
  if (m_instance == 0) {
    m_instance = new NeighbourTable();
  }
  return m_instance;
}

void NeighbourTable::update(const std::string &nodeId,
                            const std::string &nodeAddress,
                            const uint16_t &nodePort) {
  mutex.lock();
  std::map<std::string, std::shared_ptr<Neighbour>>::iterator it = m_neighbours
      .find(nodeId);
  if (it != m_neighbours.end()) {
    if (m_neighbours[nodeId]->m_nodeAddress != nodeAddress)
      m_neighbours[nodeId]->m_nodeAddress = nodeAddress;
    if (m_neighbours[nodeId]->m_nodePort != nodePort)
      m_neighbours[nodeId]->m_nodePort = nodePort;
    m_neighbours[nodeId]->Update();
  } else {
    m_neighbours[nodeId] = std::make_shared<Neighbour>(nodeId, nodeAddress,
                                                       nodePort);
  }
  mutex.unlock();
}

void NeighbourTable::cleanNeighbours(int expirationTime) {
  mutex.lock();
  for (std::map<std::string, std::shared_ptr<Neighbour>>::iterator it =
      m_neighbours.begin(); it != m_neighbours.end(); ++it) {
    if ((*it).second->getElapsedActivityTime() >= expirationTime) {
      m_neighbours.erase(it);
    }
  }
  mutex.unlock();
}

void NeighbourTable::getNeighbours(
    std::map<std::string, std::shared_ptr<Neighbour>> *map) {
  mutex.lock();
  (*map).insert(m_neighbours.begin(), m_neighbours.end());
  mutex.unlock();
}

<|endoftext|>


<commit_before>// Time:  O(nlogn)
// Space: O(n)

// BIT solution. (281ms)
class Solution {
public:
   /**
     * @param A: An integer array
     * @return: Count the number of element before this element 'ai' is
     *          smaller than it and return count number array
     */
    vector<int> countOfSmallerNumberII(vector<int> &A) {
        vector<int> sorted_A(A), orderings(A.size());
        sort(sorted_A.begin(), sorted_A.end());
        for (int i = 0; i < A.size(); ++i) {
            orderings[i] =
                lower_bound(sorted_A.begin(), sorted_A.end(), A[i]) -
                sorted_A.begin();
        }
        vector<int> bit(A.size() + 1), ans(A.size());
        for (int i = 0; i < A.size(); ++i) {
            ans[i] = query(bit, orderings[i]);
            add(bit, orderings[i] + 1, 1);
        }
        return ans;
    }

private:
    void add(vector<int>& bit, int i, int val) {
        for (; i < bit.size(); i += lower_bit(i)) {
            bit[i] += val;
        }
    }

    int query(const vector<int>& bit, int i) {
        int sum = 0;
        for (; i > 0; i -= lower_bit(i)) {
            sum += bit[i];
        }
        return sum;
    }

    int lower_bit(int i) {
        return i & -i;
    }
};

// Time:  O(nlogn)
// Space: O(n)
// BST solution. (743ms)
class Solution2 {
public:
    class BSTreeNode {
    public:
        int val, count;
        BSTreeNode *left, *right;
        BSTreeNode(int val, int count) {
            this->val = val;
            this->count = count;
            this->left = this->right = nullptr;
        }
    };
    /**
     * @param A: An integer array
     * @return: Count the number of element before this element 'ai' is
     *          smaller than it and return count number array
     */
    vector<int> countOfSmallerNumberII(vector<int> &A) {
        vector<int> res;

        BSTreeNode *root = nullptr;

        // Insert into BST and get left count.
        for (int i = 0; i < A.size(); ++i) {
            int count = 0;
            BSTreeNode *node = new BSTreeNode(A[i], 0);
            root = insertNode(root, node);
            count = query(root, A[i]);
            res.emplace_back(count);
        }

        return res;
    }

    // Insert node into BST.
    BSTreeNode* insertNode(BSTreeNode* root, BSTreeNode* node) {
        if (root == nullptr) {
            return node;
        }
        BSTreeNode* curr = root;
        while (curr) {
            // Insert left if smaller.
            if (node->val < curr->val) {
                ++curr->count; // Increase the number of left children.
                if (curr->left != nullptr) {
                    curr = curr->left;
                } else {
                    curr->left = node;
                    break;
                }
            } else {  // Insert right if larger or equal.
                if (curr->right != nullptr) {
                    curr = curr->right;
                } else {
                    curr->right = node;
                    break;
                }
            }
        }
        return root;
    }

    // Query the smaller count of the value.
    int query(BSTreeNode* root, int val) {
        if (root == nullptr) {
            return 0;
        }
        int count = 0;
        BSTreeNode* curr = root;
        while (curr) {
            // Insert left.
            if (val < curr->val) {
                curr = curr->left;
            } else if (val > curr->val) {
                count += 1 + curr->count; // Count the number of the smaller nodes.
                curr = curr->right;
            } else {  // Equal.
                return count + curr->count;
            }
        }
        return 0;
    }
};
<commit_msg>Update count-of-smaller-number-before-itself.cpp<commit_after>// Time:  O(nlogn)
// Space: O(n)

// BIT solution. (281ms)
class Solution {
public:
   /**
     * @param A: An integer array
     * @return: Count the number of element before this element 'ai' is
     *          smaller than it and return count number array
     */
    vector<int> countOfSmallerNumberII(vector<int> &A) {
        // Get the place (position in the ascending order) of each number.
        vector<int> sorted_A(A), places(A.size());
        sort(sorted_A.begin(), sorted_A.end());
        for (int i = 0; i < A.size(); ++i) {
            places[i] =
                lower_bound(sorted_A.begin(), sorted_A.end(), A[i]) -
                sorted_A.begin();
        }
        // Count the smaller elements before the number.
        vector<int> bit(A.size() + 1), ans(A.size());
        for (int i = 0; i < A.size(); ++i) {
            ans[i] = query(bit, places[i]);
            add(bit, places[i] + 1, 1);
        }
        return ans;
    }

private:
    void add(vector<int>& bit, int i, int val) {
        for (; i < bit.size(); i += lower_bit(i)) {
            bit[i] += val;
        }
    }

    int query(const vector<int>& bit, int i) {
        int sum = 0;
        for (; i > 0; i -= lower_bit(i)) {
            sum += bit[i];
        }
        return sum;
    }

    int lower_bit(int i) {
        return i & -i;
    }
};

// Time:  O(nlogn)
// Space: O(n)
// BST solution. (743ms)
class Solution2 {
public:
    class BSTreeNode {
    public:
        int val, count;
        BSTreeNode *left, *right;
        BSTreeNode(int val, int count) {
            this->val = val;
            this->count = count;
            this->left = this->right = nullptr;
        }
    };
    /**
     * @param A: An integer array
     * @return: Count the number of element before this element 'ai' is
     *          smaller than it and return count number array
     */
    vector<int> countOfSmallerNumberII(vector<int> &A) {
        vector<int> res;

        BSTreeNode *root = nullptr;

        // Insert into BST and get left count.
        for (int i = 0; i < A.size(); ++i) {
            int count = 0;
            BSTreeNode *node = new BSTreeNode(A[i], 0);
            root = insertNode(root, node);
            count = query(root, A[i]);
            res.emplace_back(count);
        }

        return res;
    }

    // Insert node into BST.
    BSTreeNode* insertNode(BSTreeNode* root, BSTreeNode* node) {
        if (root == nullptr) {
            return node;
        }
        BSTreeNode* curr = root;
        while (curr) {
            // Insert left if smaller.
            if (node->val < curr->val) {
                ++curr->count; // Increase the number of left children.
                if (curr->left != nullptr) {
                    curr = curr->left;
                } else {
                    curr->left = node;
                    break;
                }
            } else {  // Insert right if larger or equal.
                if (curr->right != nullptr) {
                    curr = curr->right;
                } else {
                    curr->right = node;
                    break;
                }
            }
        }
        return root;
    }

    // Query the smaller count of the value.
    int query(BSTreeNode* root, int val) {
        if (root == nullptr) {
            return 0;
        }
        int count = 0;
        BSTreeNode* curr = root;
        while (curr) {
            // Insert left.
            if (val < curr->val) {
                curr = curr->left;
            } else if (val > curr->val) {
                count += 1 + curr->count; // Count the number of the smaller nodes.
                curr = curr->right;
            } else {  // Equal.
                return count + curr->count;
            }
        }
        return 0;
    }
};
<|endoftext|>