<commit_before>#include "UCT.h"

#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <time.h>

#include <atomic>
#include <cstdlib>
#include <mutex>
#include <random>
#include <thread>

#include "Common.h"
#include "Patterns.h"

#if _MSC_VER
#define snprintf _snprintf
#endif

// Implemented using http://www.cameronius.com/cv/mcts-survey-master.pdf

std::mutex treePolicyMutex;
std::mutex backUpMutex;
std::atomic<int> simulationCount;

double diffclock(timespec start, timespec finish) {
  double elapsed = static_cast<double>(finish.tv_sec - start.tv_sec);
  elapsed += static_cast<double>(finish.tv_nsec - start.tv_nsec)/1000000000.0;
  return elapsed * (-1000);
}

void printNode(UCTNode* n, char* spaces) {
  printf("%sn(%d %d) V %d R %f\n", spaces, n->move.row, n->move.column,
    n->visits, n->totalRewards);
  // std::cout << spaces << "n (" << n->move.row << " " << n->move.column
    // << ") V " << n->visits << " R " << n->totalRewards << std::endl;

  UCTNode* next = n->child;
  while (next != nullptr) {
    char moreSpaces[100];
    snprintf(moreSpaces, sizeof(spaces), "%s ", spaces);
    printNode(next, moreSpaces);
    next = next->sibling;
  }
}

UCTNode* bestChild(UCTNode* node) {
  node->mutex.lock();
  const double c = 1;  // / sqrt(static_cast<float>(2));
  // const double c = 1;
  UCTNode* bestChild = node->child;
  double bestScore = -100000;
  UCTNode* next = node->child;
  while (next != nullptr) {
    double uctScore = next->totalRewards / next->visits
      + c*sqrt((2*log(static_cast<float>(node->visits))) / next->visits);
    if (bestScore < uctScore) {
      bestChild = next;
      bestScore = uctScore;
    }
    next = next->sibling;
  }
  node->mutex.unlock();
  return bestChild;
}

UCTNode* getNewChild(UCTNode* node, std::default_random_engine& engine) {
  node->mutex.lock();
  if (node->possibleChildren.empty() && node->child == nullptr) {
    node->state->getPossibleMoves();
    for (unsigned short i = 0; i < node->state->numLegalMoves; ++i) {
      UCTNode* child = new UCTNode(*node->state->legalMoves[i], node);
      node->possibleChildren.push_back(child);
    }

    Point pass(BOARD_SIZE, BOARD_SIZE);
    UCTNode* passChild = new UCTNode(pass, node);
    node->possibleChildren.push_back(passChild);
  }

  if (node->possibleChildren.size() == 0) {
    node->mutex.unlock();
    return nullptr;
  }
  // else //Pick random child
  // {
    std::uniform_int_distribution<> dist(0, (int)node->possibleChildren.size()-1);
    unsigned int choice = dist(engine);
    UCTNode* chosenChild = node->possibleChildren[choice];
    // for(unsigned int i = 0; i < possibleChildren.size(); i++)
    //  if(i != choice)
    //    delete possibleChildren[i];
    // node->possibleChildren.erase(&node->possibleChildren.begin()+choice);
    node->possibleChildren[choice] = node->possibleChildren.back();
    node->possibleChildren.pop_back();
    node->mutex.unlock();
    if (chosenChild->visits == 0)
      chosenChild->init();
    return chosenChild;
  //  }
}

UCTNode* TreePolicy(UCTNode* node, std::default_random_engine& engine) {
  GameResult r;
  while (!node->state->isGameOver(&r)) {  // Not terminal
    UCTNode* newChild = getNewChild(node, engine);
    if (newChild != nullptr) {
      node->addChild(newChild);
      return newChild;
    } else {
      node = bestChild(node);
    }
  }
  Point pass(BOARD_SIZE, BOARD_SIZE);
  if (node->move != pass
    && node->move.color != Empty) {
    assert(false);
  }
  return node;
}

int DefaultPolicy(std::default_random_engine& engine, UCTNode* node, Board* clone, Patterns* patterns) {
  for (Group* g : clone->blackGroups)
    delete g;
  clone->blackGroups.clear();
  for (Group* g : clone->whiteGroups)
    delete g;
  clone->whiteGroups.clear();

  node->state->cloneInto(clone);

  GameResult r;
  if (patterns != nullptr && patterns->initialized)
    r = clone->playGame(patterns, engine);
  else
    r = clone->playRandomGame(engine);

  if ((node->state->turn == Black ? White : Black) == static_cast<int>(r))
    return 1;
  else if (r != Draw)
    return -1;
  else if (r == Draw)
    return 0;
  else
    assert(false);
}

void backup(UCTNode* v, int reward) {
  // If not me, then its updating opponent
  bool me = true;
  while (v != nullptr) {
    v->mutex.lock();
    v->visits++;
    if (me)
      v->totalRewards += reward;
    else
      v->totalRewards -= reward;
    v->mutex.unlock();
    v = v->parent;
    me = !me;
  }
}

UCTNode* UCTSearch(UCTNode* root, int numSimulations, Patterns* patterns) {
  Board* clone = new Board();
  clone->init();
  std::default_random_engine engine(time(nullptr));
  for (int i = 0; i < numSimulations; i++) {
    UCTNode* v = TreePolicy(root, engine);
    int reward = DefaultPolicy(engine, v, clone, patterns);
    backup(v, reward);

    if (i % 1000 == 0 && i != 0)
      printf("%d\n", i);
  }
  delete clone;

  UCTNode* best = root->child;
  UCTNode* next = root->child;
  while (next != nullptr) {
    if (next->visits > best->visits)
      best = next;
    next = next->sibling;
  }

  Point pass(BOARD_SIZE, BOARD_SIZE);
  if (!(best->move == pass)
    && best->move.color != Empty) {
    assert(false);
  }
  if (!(best->move == pass)
    && best->move.color != Empty) {
    assert(false);
  }
  return best;
}

void runSimulationThread(UCTNode* root, int millaSecondsToThink, Patterns* patterns) {
  struct timespec start, end;
  clock_gettime(CLOCK_MONOTONIC, &start);
  clock_gettime(CLOCK_MONOTONIC, &end);

  int i = 0;

  std::default_random_engine engine(time(nullptr));
  Board* clone = new Board();
  clone->init();

  while (diffclock(end, start) < millaSecondsToThink) {
    simulationCount++;
    i++;

    UCTNode* v = TreePolicy(root, engine);

    int reward = DefaultPolicy(engine, v, clone, patterns);

    backup(v, reward);

    /*if (i % 100 == 0 && i != 0) {
      char buffer[100];
      sprintf(buffer, "#%d - %d", getpid(), i);
      Log(buffer);
      sprintf(buffer, "  %f %d", diffclock(end, start), millaSecondsToThink);
      Log(buffer);
    }*/
    // end = clock();
    clock_gettime(CLOCK_MONOTONIC, &end);
  }
  delete clone;
  Log(std::to_string(i).c_str());
}

UCTNode* UCTSearch(UCTNode* root, float millaSecondsToThink, Patterns* patterns) {
  simulationCount = 0;

  int numThreads = 4;
  std::thread* threads = new std::thread[numThreads];
  for (int threadNum = 0; threadNum < numThreads; threadNum++) {
    threads[threadNum] = std::thread(runSimulationThread, root,
      millaSecondsToThink, patterns);
  }

  for (int threadNum = 0; threadNum < numThreads; threadNum++)
    threads[threadNum].join();
  delete[] threads;

  UCTNode* best = root->child;
  UCTNode* next = root->child;
  while (next != nullptr) {
    if (next->visits > best->visits)
      best = next;
    next = next->sibling;
  }

  Point pass(BOARD_SIZE, BOARD_SIZE);
  if (!(best->move == pass)
    && best->move.color != Empty) {
    assert(false);
  }
  if (!(best->move == pass)
    && best->move.color != Empty) {
    assert(false);
  }

  char buffer[100];
  snprintf(buffer, sizeof(buffer),
    "Thought for %d simulations.\nR: %f V: %d\nR/V: %f\t%d %d",
    static_cast<int>(simulationCount), best->totalRewards, best->visits,
    static_cast<double>(best->totalRewards/best->visits), best->move.row, best->move.column);
  Log(buffer);
  if (patterns != nullptr) {
    snprintf(buffer, sizeof(buffer), "Called\t\t%d times", patterns->numCalled);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Not Legal\t%d times", patterns->numNotLegal);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Null\t\t%d times", patterns->numNull);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Not Called\t%d times", patterns->numNotCalled);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Called2\t\t%d times", patterns->numCalled2);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Not Legal2\t%d times", patterns->numNotLegal2);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Null2\t\t%d times", patterns->numNull2);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Not Called2\t%d times", patterns->numNotCalled2);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Total\t\t%d times\n", patterns->total);
    Log(buffer);
  }
  return best;
}
<commit_msg>Changed UCT::simulationCount to update at the end of each thread instead of incrementing for each simulation<commit_after>#include "UCT.h"

#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <time.h>

#include <atomic>
#include <cstdlib>
#include <mutex>
#include <random>
#include <thread>

#include "Common.h"
#include "Patterns.h"

#if _MSC_VER
#define snprintf _snprintf
#endif

// Implemented using http://www.cameronius.com/cv/mcts-survey-master.pdf

std::mutex treePolicyMutex;
std::mutex backUpMutex;
std::atomic<int> simulationCount;

double diffclock(timespec start, timespec finish) {
  double elapsed = static_cast<double>(finish.tv_sec - start.tv_sec);
  elapsed += static_cast<double>(finish.tv_nsec - start.tv_nsec)/1000000000.0;
  return elapsed * (-1000);
}

void printNode(UCTNode* n, char* spaces) {
  printf("%sn(%d %d) V %d R %f\n", spaces, n->move.row, n->move.column,
    n->visits, n->totalRewards);
  // std::cout << spaces << "n (" << n->move.row << " " << n->move.column
    // << ") V " << n->visits << " R " << n->totalRewards << std::endl;

  UCTNode* next = n->child;
  while (next != nullptr) {
    char moreSpaces[100];
    snprintf(moreSpaces, sizeof(spaces), "%s ", spaces);
    printNode(next, moreSpaces);
    next = next->sibling;
  }
}

UCTNode* bestChild(UCTNode* node) {
  node->mutex.lock();
  const double c = 1;  // / sqrt(static_cast<float>(2));
  // const double c = 1;
  UCTNode* bestChild = node->child;
  double bestScore = -100000;
  UCTNode* next = node->child;
  while (next != nullptr) {
    double uctScore = next->totalRewards / next->visits
      + c*sqrt((2*log(static_cast<float>(node->visits))) / next->visits);
    if (bestScore < uctScore) {
      bestChild = next;
      bestScore = uctScore;
    }
    next = next->sibling;
  }
  node->mutex.unlock();
  return bestChild;
}

UCTNode* getNewChild(UCTNode* node, std::default_random_engine& engine) {
  node->mutex.lock();
  if (node->possibleChildren.empty() && node->child == nullptr) {
    node->state->getPossibleMoves();
    for (unsigned short i = 0; i < node->state->numLegalMoves; ++i) {
      UCTNode* child = new UCTNode(*node->state->legalMoves[i], node);
      node->possibleChildren.push_back(child);
    }

    Point pass(BOARD_SIZE, BOARD_SIZE);
    UCTNode* passChild = new UCTNode(pass, node);
    node->possibleChildren.push_back(passChild);
  }

  if (node->possibleChildren.size() == 0) {
    node->mutex.unlock();
    return nullptr;
  }
  // else //Pick random child
  // {
    std::uniform_int_distribution<> dist(0, (int)node->possibleChildren.size()-1);
    unsigned int choice = dist(engine);
    UCTNode* chosenChild = node->possibleChildren[choice];
    // for(unsigned int i = 0; i < possibleChildren.size(); i++)
    //  if(i != choice)
    //    delete possibleChildren[i];
    // node->possibleChildren.erase(&node->possibleChildren.begin()+choice);
    node->possibleChildren[choice] = node->possibleChildren.back();
    node->possibleChildren.pop_back();
    node->mutex.unlock();
    if (chosenChild->visits == 0)
      chosenChild->init();
    return chosenChild;
  //  }
}

UCTNode* TreePolicy(UCTNode* node, std::default_random_engine& engine) {
  GameResult r;
  while (!node->state->isGameOver(&r)) {  // Not terminal
    UCTNode* newChild = getNewChild(node, engine);
    if (newChild != nullptr) {
      node->addChild(newChild);
      return newChild;
    } else {
      node = bestChild(node);
    }
  }
  Point pass(BOARD_SIZE, BOARD_SIZE);
  if (node->move != pass
    && node->move.color != Empty) {
    assert(false);
  }
  return node;
}

int DefaultPolicy(std::default_random_engine& engine, UCTNode* node, Board* clone, Patterns* patterns) {
  for (Group* g : clone->blackGroups)
    delete g;
  clone->blackGroups.clear();
  for (Group* g : clone->whiteGroups)
    delete g;
  clone->whiteGroups.clear();

  node->state->cloneInto(clone);

  GameResult r;
  if (patterns != nullptr && patterns->initialized)
    r = clone->playGame(patterns, engine);
  else
    r = clone->playRandomGame(engine);

  if ((node->state->turn == Black ? White : Black) == static_cast<int>(r))
    return 1;
  else if (r != Draw)
    return -1;
  else if (r == Draw)
    return 0;
  else
    assert(false);
}

void backup(UCTNode* v, int reward) {
  // If not me, then its updating opponent
  bool me = true;
  while (v != nullptr) {
    v->mutex.lock();
    v->visits++;
    if (me)
      v->totalRewards += reward;
    else
      v->totalRewards -= reward;
    v->mutex.unlock();
    v = v->parent;
    me = !me;
  }
}

UCTNode* UCTSearch(UCTNode* root, int numSimulations, Patterns* patterns) {
  Board* clone = new Board();
  clone->init();
  std::default_random_engine engine(time(nullptr));
  for (int i = 0; i < numSimulations; i++) {
    UCTNode* v = TreePolicy(root, engine);
    int reward = DefaultPolicy(engine, v, clone, patterns);
    backup(v, reward);

    if (i % 1000 == 0 && i != 0)
      printf("%d\n", i);
  }
  delete clone;

  UCTNode* best = root->child;
  UCTNode* next = root->child;
  while (next != nullptr) {
    if (next->visits > best->visits)
      best = next;
    next = next->sibling;
  }

  Point pass(BOARD_SIZE, BOARD_SIZE);
  if (!(best->move == pass)
    && best->move.color != Empty) {
    assert(false);
  }
  if (!(best->move == pass)
    && best->move.color != Empty) {
    assert(false);
  }
  return best;
}

void runSimulationThread(UCTNode* root, int millaSecondsToThink, Patterns* patterns) {
  struct timespec start, end;
  clock_gettime(CLOCK_MONOTONIC, &start);
  clock_gettime(CLOCK_MONOTONIC, &end);

  int i = 0;

  std::default_random_engine engine(time(nullptr));
  Board* clone = new Board();
  clone->init();

  while (diffclock(end, start) < millaSecondsToThink) {
    i++;

    UCTNode* v = TreePolicy(root, engine);

    int reward = DefaultPolicy(engine, v, clone, patterns);

    backup(v, reward);

    /*if (i % 100 == 0 && i != 0) {
      char buffer[100];
      sprintf(buffer, "#%d - %d", getpid(), i);
      Log(buffer);
      sprintf(buffer, "  %f %d", diffclock(end, start), millaSecondsToThink);
      Log(buffer);
    }*/
    // end = clock();
    clock_gettime(CLOCK_MONOTONIC, &end);
  }
  delete clone;

  simulationCount.fetch_add(i);
  Log(std::to_string(i).c_str());
}

UCTNode* UCTSearch(UCTNode* root, float millaSecondsToThink, Patterns* patterns) {
  simulationCount = 0;

  int numThreads = 4;
  std::thread* threads = new std::thread[numThreads];
  for (int threadNum = 0; threadNum < numThreads; threadNum++) {
    threads[threadNum] = std::thread(runSimulationThread, root,
      millaSecondsToThink, patterns);
  }

  for (int threadNum = 0; threadNum < numThreads; threadNum++)
    threads[threadNum].join();
  delete[] threads;

  UCTNode* best = root->child;
  UCTNode* next = root->child;
  while (next != nullptr) {
    if (next->visits > best->visits)
      best = next;
    next = next->sibling;
  }

  Point pass(BOARD_SIZE, BOARD_SIZE);
  if (!(best->move == pass)
    && best->move.color != Empty) {
    assert(false);
  }
  if (!(best->move == pass)
    && best->move.color != Empty) {
    assert(false);
  }

  char buffer[100];
  snprintf(buffer, sizeof(buffer),
    "Thought for %d simulations.\nR: %f V: %d\nR/V: %f\t%d %d",
    static_cast<int>(simulationCount), best->totalRewards, best->visits,
    static_cast<double>(best->totalRewards/best->visits), best->move.row, best->move.column);
  Log(buffer);
  if (patterns != nullptr) {
    snprintf(buffer, sizeof(buffer), "Called\t\t%d times", patterns->numCalled);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Not Legal\t%d times", patterns->numNotLegal);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Null\t\t%d times", patterns->numNull);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Not Called\t%d times", patterns->numNotCalled);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Called2\t\t%d times", patterns->numCalled2);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Not Legal2\t%d times", patterns->numNotLegal2);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Null2\t\t%d times", patterns->numNull2);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Not Called2\t%d times", patterns->numNotCalled2);
    Log(buffer);
    snprintf(buffer, sizeof(buffer), "Total\t\t%d times\n", patterns->total);
    Log(buffer);
  }
  return best;
}
<|endoftext|>


<commit_before>#include <cmath>
#include <cassert>
#include <cstdlib>
#include <iostream>
#include "World.H"
#include "Unit.H"

#define PI 3.14159

using namespace std;

/* helper that you need to implement

 - move unit by current_speed * heading

 - units only collide with the map border

 - when units hit a wall they stop at the collision point (current_speed=0)
   and collision_hook is called with the previous speed and a vector of bools
   encoding the walls that were hit. This vector is used in collision_hook to
   implement bouncing by only changing the unit's heading, i.e. even when
   bouncing the unit stays at the collision location for the remainder of the
   simulation frame and only starts moving again in the following frame.

 - it is essential that units are located inside the map at all times. There
   can be no overlap. Ensure this property by clipping coordinates after
   moving.

*/

void startShowdownMode(Unit &u, Unit &v, World const &w);

void World::move_unit(Unit &u)
{
  //Take unit speed multiply by heading to get new position
  double futureX = u.pos.x + (u.current_speed*u.heading.x);
  double futureY = u.pos.y + (u.current_speed*u.heading.y);
  //Extra space to leave for a collision. Compensates for rounding errors.
  double buffer = 0.1;
  //Collision occured flag
  bool collision = false;
  bool collisions[4] = {false, false, false, false};
  double prev_speed = u.current_speed;

  //Check to see if movement would result in a collision
  if(futureX+u.radius+buffer >= width) {
    //Collision with Right wall
    futureX = width - u.radius - buffer;
    collision = true;
    collisions[1] = true;
  }
  if(futureX-u.radius-buffer <= 0) {
    //Collision with Left wall
    futureX = u.radius + buffer;
    collision = true;
    collisions[3] = true;
  }
  if(futureY+u.radius+buffer >= height) {
    //Collision with Bottom wall
    futureY = height - u.radius - buffer;
    collision = true;
    collisions[2] = true;
  }
  if(futureY-u.radius-buffer <= 0) {
    //Collision with Top wall
    futureY = u.radius + buffer;
    collision = true;
    collisions[0] = true;
  }

  if(collision) {
	u.current_speed = 0;
    u.collision_hook(prev_speed, collisions);
  }

  //Update unit's position to new position
  u.pos = Vec2(futureX, futureY);

}

// returns policy name
const char *apol2str(AttackPolicy pol)
{
  switch (pol) {
    case ATTACK_WEAKEST:
      return "attack-weakest";
    case ATTACK_CLOSEST:
      return "attack-closest";
    case ATTACK_MOST_DANGEROUS:
      return "attack-most-dangerous";
  }
  return "?";
}

//Clean up
World::~World()
{
  //Delete each unit in units vector
  for(auto &dude : units){
    delete dude;
  }
}

// deducts hit points and calls attack_hook
void World::attack(Unit &attacker, Unit &attacked)
{
  //Reduce attacked unit's health by attack strength of attacker
  attacked.hp -= (int)attacker.damage;
  attack_hook(attacker, attacked);
  //Remove dead is handled by step in World2.C
}

// return a random position at which a circle of that radius fits

Vec2 World::rnd_pos(double radius) const
{
  double slack = radius * 2;

  Vec2 p((width  - 2*slack) * rnd01() + slack,
         (height - 2*slack) * rnd01() + slack);

  // assert circle in rectangle
  assert(p.x > radius && p.x < width - radius);
  assert(p.y > radius && p.y < height - radius);
  return p;
}

// return uniform random heading
// length of vector = 1
Vec2 World::rnd_heading() const
{
  // Generate random value between (0 and 2)*pi radians
  // This should preserve a uniform distribution as the 2*rnd01
  // transforms from an infinite set of points
  double angle = ((this->rnd01())*2)*PI;

  // create Vec2 object with x = cos(angle), y = sin(angle)
  return Vec2(cos(angle), sin(angle));
}

// mirror position with respect to map mid-point
Vec2 World::mirror(const Vec2 &pos) const
{
  //Create Mid-point coordinates
  double midX = width/2;
  double midY = height/2;
  double newX;
  double newY;
  double diff;

  //Set new coordinate to position same distance from midpoint
  //but on the other side of said midpoint
  if(pos.x >= midX) {
    diff = pos.x - midX;
    newX = midX - diff;
  } else {
    diff = midX - pos.x;
    newX = midX + diff;
  }
  if(pos.y >= midY){
    diff = pos.y - midY;
    newY = midY - diff;
  } else {
    diff = midY - pos.y;
    newY = midY + diff;
  }
  return Vec2(newX, newY);

}

// return squared distance between two unit centers
double World::distance2(const Unit &u, const Unit &v)
{
  return pow((v.pos.x - u.pos.x), 2) + pow((v.pos.y - u.pos.y), 2);
}

// return true iff u can attack v, i.e. distance of u's and v's centers is
// less than u's attack distance plus v's radius
bool World::can_attack(const Unit &u, const Unit &v)
{
  double dist = sqrt(distance2(u, v));

  if(dist <= u.attack_radius + v.radius){
    return true;
  } else {
    return false;
  }
}

// populate a vector with enemy units that can be attacked by u;
// clears vector first
void World::enemies_within_attack_range(const Unit &u,
                                        vector<Unit*> &targets) const
{
  targets.clear();

  //Append all units to vector
  for(auto &unit : units) {
    if(can_attack(u, *unit)) {
      if(unit->team != u.team){
        targets.push_back(unit);
      }
    }
  }
}

// return a random unit that can be attacked by u with minimal hp_old value,
// or 0 if none exists
Unit *World::random_weakest_target(Unit &u) const
{
  //Create list of possible targets
  vector<Unit*> targets;
  enemies_within_attack_range(u, targets);

  //If there are no available targets
  if(targets.size() ==0) {return 0;}

  //Search for unit with lowest hp
  Unit * lowest = targets[0];
  for(auto &unit: targets) {
    if(unit->hp_old < lowest->hp_old){
      lowest = unit;
    }
  }
  return lowest;
}

// return a random unit that can be attacked by u with minimal distance to
// u, or 0 if none exists
Unit *World::random_closest_target(Unit &u) const
{
  //Create list of possible targets
  vector<Unit*> targets;
  enemies_within_attack_range(u, targets);

  //If there are no available targets
  if(targets.size() == 0) {return 0;}

  //Search for unit with lowest distance
  Unit * closest = targets[0];
  for(auto &unit: targets) {
    if(distance2(u, *unit) < distance2(u, *closest)){
      closest = unit;
    }
  }

  return closest;
}

// return a random unit that can be attacked by u with maximal damage/hp_old
// ratio, or 0 if none exists
Unit *World::random_most_dangerous_target(Unit &u) const
{
  //Create list of possible targets
  vector<Unit*> targets;
  enemies_within_attack_range(u, targets);

  //If there are no available targets
  if(targets.size() ==0) {return 0;}

  //Search for unit with highest damage/hp remaining ratio
  Unit * baddest = targets[0];
  for(auto &unit: targets) {
    if(unit->damage/unit->hp_old < baddest->damage/baddest->hp_old){
      baddest = unit;
    }
  }

  return baddest;
}

// return score for red: 2 for win, 0 for loss, 1 for draw, -1 for game not
// over yet
int World::red_score() const
{
  //Flags for if red or blue units still exist
  bool red = false;
  bool blue = false;

  if (units.empty()) {
    return 1;
  }

  //Check all remaining units for team affiliations
  for(auto &unit : units){
    if(unit->team == Team::BLUE){
      blue = true;
    }
    if(unit->team == Team::RED){
      red = true;
    }
    //If there are at least one unit of each team game continues
    if(red && blue){
      //If there are is only one unit remaining on each side game enters showdown mode
      if(units.size() == 2){
        startShowdownMode(*units[0], *units[1], *this); //Last two units moved and thrown towards eachother
      }
      return -1;
    }
  }

  //If in all the remaining units, none are red loss
  if(!red) {
    return 0;
  } else {
    return 2; //Otherwise return win!
  }
}

//Place two units above and below midpoint of map and change headings towards eachother.
void startShowdownMode(Unit &u, Unit &v, World const &w) {
  u.pos.x = w.width/2;
  u.pos.y = w.height*3/4;
  v.pos = w.mirror(u.pos);
  u.heading = Vec2(0,-1.0);
  v.heading = Vec2(0,1.0);
}<commit_msg>Added random choice among ties in enemy targeting selection<commit_after>#include <cmath>
#include <cassert>
#include <cstdlib>
#include <iostream>
#include "World.H"
#include "Unit.H"

#define PI 3.14159

using namespace std;

/* helper that you need to implement

 - move unit by current_speed * heading

 - units only collide with the map border

 - when units hit a wall they stop at the collision point (current_speed=0)
   and collision_hook is called with the previous speed and a vector of bools
   encoding the walls that were hit. This vector is used in collision_hook to
   implement bouncing by only changing the unit's heading, i.e. even when
   bouncing the unit stays at the collision location for the remainder of the
   simulation frame and only starts moving again in the following frame.

 - it is essential that units are located inside the map at all times. There
   can be no overlap. Ensure this property by clipping coordinates after
   moving.

*/

void startShowdownMode(Unit &u, Unit &v, World const &w);

void World::move_unit(Unit &u)
{
  //Take unit speed multiply by heading to get new position
  double futureX = u.pos.x + (u.current_speed*u.heading.x);
  double futureY = u.pos.y + (u.current_speed*u.heading.y);
  //Extra space to leave for a collision. Compensates for rounding errors.
  double buffer = 0.1;
  //Collision occured flag
  bool collision = false;
  bool collisions[4] = {false, false, false, false};
  double prev_speed = u.current_speed;

  //Check to see if movement would result in a collision
  if(futureX+u.radius+buffer >= width) {
    //Collision with Right wall
    futureX = width - u.radius - buffer;
    collision = true;
    collisions[1] = true;
  }
  if(futureX-u.radius-buffer <= 0) {
    //Collision with Left wall
    futureX = u.radius + buffer;
    collision = true;
    collisions[3] = true;
  }
  if(futureY+u.radius+buffer >= height) {
    //Collision with Bottom wall
    futureY = height - u.radius - buffer;
    collision = true;
    collisions[2] = true;
  }
  if(futureY-u.radius-buffer <= 0) {
    //Collision with Top wall
    futureY = u.radius + buffer;
    collision = true;
    collisions[0] = true;
  }

  if(collision) {
	u.current_speed = 0;
    u.collision_hook(prev_speed, collisions);
  }

  //Update unit's position to new position
  u.pos = Vec2(futureX, futureY);

}

// returns policy name
const char *apol2str(AttackPolicy pol)
{
  switch (pol) {
    case ATTACK_WEAKEST:
      return "attack-weakest";
    case ATTACK_CLOSEST:
      return "attack-closest";
    case ATTACK_MOST_DANGEROUS:
      return "attack-most-dangerous";
  }
  return "?";
}

//Clean up
World::~World()
{
  //Delete each unit in units vector
  for(auto &dude : units){
    delete dude;
  }
}

// deducts hit points and calls attack_hook
void World::attack(Unit &attacker, Unit &attacked)
{
  //Reduce attacked unit's health by attack strength of attacker
  attacked.hp -= (int)attacker.damage;
  attack_hook(attacker, attacked);
  //Remove dead is handled by step in World2.C
}

// return a random position at which a circle of that radius fits

Vec2 World::rnd_pos(double radius) const
{
  double slack = radius * 2;

  Vec2 p((width  - 2*slack) * rnd01() + slack,
         (height - 2*slack) * rnd01() + slack);

  // assert circle in rectangle
  assert(p.x > radius && p.x < width - radius);
  assert(p.y > radius && p.y < height - radius);
  return p;
}

// return uniform random heading
// length of vector = 1
Vec2 World::rnd_heading() const
{
  // Generate random value between (0 and 2)*pi radians
  // This should preserve a uniform distribution as the 2*rnd01
  // transforms from an infinite set of points
  double angle = ((this->rnd01())*2)*PI;

  // create Vec2 object with x = cos(angle), y = sin(angle)
  return Vec2(cos(angle), sin(angle));
}

// mirror position with respect to map mid-point
Vec2 World::mirror(const Vec2 &pos) const
{
  //Create Mid-point coordinates
  double midX = width/2;
  double midY = height/2;
  double newX;
  double newY;
  double diff;

  //Set new coordinate to position same distance from midpoint
  //but on the other side of said midpoint
  if(pos.x >= midX) {
    diff = pos.x - midX;
    newX = midX - diff;
  } else {
    diff = midX - pos.x;
    newX = midX + diff;
  }
  if(pos.y >= midY){
    diff = pos.y - midY;
    newY = midY - diff;
  } else {
    diff = midY - pos.y;
    newY = midY + diff;
  }
  return Vec2(newX, newY);

}

// return squared distance between two unit centers
double World::distance2(const Unit &u, const Unit &v)
{
  return pow((v.pos.x - u.pos.x), 2) + pow((v.pos.y - u.pos.y), 2);
}

// return true iff u can attack v, i.e. distance of u's and v's centers is
// less than u's attack distance plus v's radius
bool World::can_attack(const Unit &u, const Unit &v)
{
  double dist = sqrt(distance2(u, v));

  if(dist <= u.attack_radius + v.radius){
    return true;
  } else {
    return false;
  }
}

// populate a vector with enemy units that can be attacked by u;
// clears vector first
void World::enemies_within_attack_range(const Unit &u,
                                        vector<Unit*> &targets) const
{
  targets.clear();

  //Append all units to vector
  for(auto &unit : units) {
    if(can_attack(u, *unit)) {
      if(unit->team != u.team){
        targets.push_back(unit);
      }
    }
  }
}

// return a random unit that can be attacked by u with minimal hp_old value,
// or 0 if none exists
Unit *World::random_weakest_target(Unit &u) const
{
  //Create list of possible targets
  vector<Unit*> targets;
  enemies_within_attack_range(u, targets);

  //If there are no available targets
  if(targets.size() ==0) {return 0;}

  //Search for unit with lowest hp
  Unit * lowest = targets[0];
  for(auto &unit: targets) {
    if(unit->hp_old < lowest->hp_old){
      lowest = unit;
    }
  }

  std::vector<Unit*> ties;
  for(auto &unit : targets) {
    if(unit->hp_old == lowest->hp_old){
      ties.push_back(unit);
    }
  }

  lowest = ties[rnd_int(ties.size())];
  return lowest;
}

// return a random unit that can be attacked by u with minimal distance to
// u, or 0 if none exists
Unit *World::random_closest_target(Unit &u) const
{
  //Create list of possible targets
  vector<Unit*> targets;
  enemies_within_attack_range(u, targets);

  //If there are no available targets
  if(targets.size() == 0) {return 0;}

  //Search for unit with lowest distance
  Unit * closest = targets[0];
  for(auto &unit: targets) {
    if(distance2(u, *unit) < distance2(u, *closest)){
      closest = unit;
    }
  }

  std::vector<Unit*> ties;
  for(auto &unit : targets) {
    if(distance2(u, *unit) == distance2(u, *closest)){
      ties.push_back(unit);
    }
  }

  closest = ties[rnd_int(ties.size())];

  return closest;
}

// return a random unit that can be attacked by u with maximal damage/hp_old
// ratio, or 0 if none exists
Unit *World::random_most_dangerous_target(Unit &u) const
{
  //Create list of possible targets
  vector<Unit*> targets;
  enemies_within_attack_range(u, targets);

  //If there are no available targets
  if(targets.size() ==0) {return 0;}

  //Search for unit with highest damage/hp remaining ratio
  Unit * baddest = targets[0];
  for(auto &unit: targets) {
    if(unit->damage/unit->hp_old < baddest->damage/baddest->hp_old){
      baddest = unit;
    }
  }

  std::vector<Unit*> ties;
  for(auto &unit : targets) {
    if(unit->damage/unit->hp_old == baddest->damage/baddest->hp_old){
      ties.push_back(unit);
    }
  }

  baddest = ties[rnd_int(ties.size())];

  return baddest;
}

// return score for red: 2 for win, 0 for loss, 1 for draw, -1 for game not
// over yet
int World::red_score() const
{
  //Flags for if red or blue units still exist
  bool red = false;
  bool blue = false;

  if (units.empty()) {
    return 1;
  }

  //Check all remaining units for team affiliations
  for(auto &unit : units){
    if(unit->team == Team::BLUE){
      blue = true;
    }
    if(unit->team == Team::RED){
      red = true;
    }
    //If there are at least one unit of each team game continues
    if(red && blue){
      //If there are is only one unit remaining on each side game enters showdown mode
      if(units.size() == 2){
        startShowdownMode(*units[0], *units[1], *this); //Last two units moved and thrown towards eachother
      }
      return -1;
    }
  }

  //If in all the remaining units, none are red loss
  if(!red) {
    return 0;
  } else {
    return 2; //Otherwise return win!
  }
}

//Place two units above and below midpoint of map and change headings towards eachother.
void startShowdownMode(Unit &u, Unit &v, World const &w) {
  u.pos.x = w.width/2;
  u.pos.y = w.height*3/4;
  v.pos = w.mirror(u.pos);
  u.heading = Vec2(0,-1.0);
  v.heading = Vec2(0,1.0);
}<|endoftext|>


<commit_before>#include <stdexcept>
#include <iostream>

class wrapped_int {
public:
  long long val;
  wrapped_int() { val = 0; }
  wrapped_int(long long val) { this->val = val; }
  wrapped_int(long long v1, long long v2) {
    if (v2 == 4) {
      throw std::domain_error("4 isn't good for initialization!");
    }
    this->val = v1;
  }
  wrapped_int operator+(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("tried to add 4");
    }
    return wrapped_int(this->val + other.val);
  }
  wrapped_int operator+() {
    if (this->val == 4) {
      throw std::domain_error("'4' not in valid domain.");
    }
    return *this;
  }
  wrapped_int operator-(wrapped_int &other) {
    if (other.val == 4) {
      throw std::overflow_error("Value '4' is no good.");
    }
    return *this;
  }
  wrapped_int operator-() {
    if (this->val == 4) {
      throw std::range_error("Can't take the negative of 4.");
    }
    return wrapped_int(-this->val);
  }
  wrapped_int operator*(wrapped_int &other) {
    if (other.val == 4) {
      throw std::out_of_range("Multiplying by 4 isn't going to work.");
    }
    return wrapped_int(this->val * other.val);
  }
  wrapped_int operator/(wrapped_int &other) {
    if (other.val == 4) {
      throw std::out_of_range("Multiplying by 4 isn't going to work.");
    }
    return wrapped_int(this->val / other.val);
  }
  wrapped_int operator%(wrapped_int &other) {
    if (other.val == 4) {
      throw std::out_of_range("Multiplying by 4 isn't going to work.");
    }
    return wrapped_int(this->val % other.val);
  }
  long long operator^(wrapped_int &other) {
    if (other.val == 4) {
      throw std::out_of_range("Multiplying by 4 isn't going to work.");
    }
    return this->val ^ other.val;
  }
  long long operator&(wrapped_int &other) {
    if (other.val == 4) {
      throw std::underflow_error("Can't do this with 4!");
    }
    return this->val & other.val;
  }
  long long operator|(wrapped_int &other) {
    if (other.val == 4) {
      throw std::underflow_error("Can't do this with 4!");
    }
    return this->val & other.val;
  }
  wrapped_int operator~() {
    if (this->val == 4) {
      throw std::range_error("4 is really just no good for this!");
    }
    return *this;
  }
  long long operator&() {
    if (this->val == 4) {
      throw std::out_of_range("4 cannot be located!");
    }
    return this->val;
  }
  long long operator==(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("4 isn't logical and can't be equal to anything!");
    }
    return this->val == other.val;
  }
  long long operator!=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("4 isn't logical and can'd be not equal to anything either!");
    }
    return this->val != other.val;
  }
  long long operator<(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't compare with 4!");
    }
    return this->val < other.val;
  }
  long long operator<=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't compare with 4!");
    }
    return this->val <= other.val;
  }
  long long operator>(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't compare with 4!");
    }
    return this->val > other.val;
  }
  long long operator>=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't compare with 4!");
    }
    return this->val >= other.val;
  }
  wrapped_int operator<<(long long &shift) {
    if (shift == 4) {
      throw std::overflow_error("Shifting by 4 is just bad.");
    }
    return wrapped_int(this->val << shift);
  }
  wrapped_int operator>>(long long &shift) {
    if (shift == 4) {
      throw std::underflow_error("Shifting by 4 is just bad.");
    }
    return wrapped_int(this->val >> shift);
  }
  wrapped_int &operator+=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val += other.val;
    return *this;
  }
  wrapped_int &operator-=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val -= other.val;
    return *this;
  }
  wrapped_int &operator*=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val *= other.val;
    return *this;
  }
  wrapped_int &operator/=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val /= other.val;
    return *this;
  }
  wrapped_int &operator%=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val %= other.val;
    return *this;
  }
  wrapped_int &operator^=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val ^= other.val;
    return *this;
  }
  wrapped_int &operator&=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val %= other.val;
    return *this;
  }
  wrapped_int &operator|=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val %= other.val;
    return *this;
  }
  wrapped_int &operator<<=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val %= other.val;
    return *this;
  }
  wrapped_int &operator>>=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val %= other.val;
    return *this;
  }
  wrapped_int &operator++() {
    if (this->val == 4) {
      throw std::out_of_range("Can't increment 4!");
    }
    this->val += 1;
    return *this;
  }
  wrapped_int &operator--() {
    if (this->val == 4) {
      throw std::out_of_range("Can't decrement 4!");
    }
    this->val -= 1;
    return *this;
  }
  wrapped_int operator++(int) {
    if (this->val == 4) {
      throw std::out_of_range("Can't increment 4!");
    }
    wrapped_int t = *this;
    this->val += 1;
    return t;
  }
  wrapped_int operator--(int) {
    if (this->val == 4) {
      throw std::out_of_range("Can't decrement 4!");
    }
    wrapped_int t = *this;
    this->val -= 1;
    return t;
  }
  wrapped_int operator!() {
    if (this->val == 4) {
      throw std::out_of_range("Can't negate 4!");
    }
    return wrapped_int(!this->val);
  }
  operator bool() {
    if (this->val == 4) {
      throw std::invalid_argument("4 can't be cast to a boolean value!");
    }
    return (this->val != 0);
  }
  wrapped_int &operator[](long long &idx) {
    if (idx == 4) {
      throw std::invalid_argument("Index of 4 not allowed.");
    }
    return *this;
  }
  long long &operator()() {
    if (this->val == 4) {
      throw std::range_error("Can't call 4!");
    }
    return this->val;
  }
  wrapped_int &operator=(const wrapped_int &other) {
    if ((other.val == 4) && (this->val == 4)) {
      throw std::overflow_error("Can't assign 4 to 4!");
    }
    this->val = other.val;
    return *this;
  }
  wrapped_int &operator=(const long long &v) {
    if ((v == 4) && (this->val == 4)) {
      throw std::overflow_error("Can't assign 4 to 4!");
    }
    this->val = v;
    return *this;
  }
};
<commit_msg>Removed unnecessary include.<commit_after>#include <stdexcept>

class wrapped_int {
public:
  long long val;
  wrapped_int() { val = 0; }
  wrapped_int(long long val) { this->val = val; }
  wrapped_int(long long v1, long long v2) {
    if (v2 == 4) {
      throw std::domain_error("4 isn't good for initialization!");
    }
    this->val = v1;
  }
  wrapped_int operator+(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("tried to add 4");
    }
    return wrapped_int(this->val + other.val);
  }
  wrapped_int operator+() {
    if (this->val == 4) {
      throw std::domain_error("'4' not in valid domain.");
    }
    return *this;
  }
  wrapped_int operator-(wrapped_int &other) {
    if (other.val == 4) {
      throw std::overflow_error("Value '4' is no good.");
    }
    return *this;
  }
  wrapped_int operator-() {
    if (this->val == 4) {
      throw std::range_error("Can't take the negative of 4.");
    }
    return wrapped_int(-this->val);
  }
  wrapped_int operator*(wrapped_int &other) {
    if (other.val == 4) {
      throw std::out_of_range("Multiplying by 4 isn't going to work.");
    }
    return wrapped_int(this->val * other.val);
  }
  wrapped_int operator/(wrapped_int &other) {
    if (other.val == 4) {
      throw std::out_of_range("Multiplying by 4 isn't going to work.");
    }
    return wrapped_int(this->val / other.val);
  }
  wrapped_int operator%(wrapped_int &other) {
    if (other.val == 4) {
      throw std::out_of_range("Multiplying by 4 isn't going to work.");
    }
    return wrapped_int(this->val % other.val);
  }
  long long operator^(wrapped_int &other) {
    if (other.val == 4) {
      throw std::out_of_range("Multiplying by 4 isn't going to work.");
    }
    return this->val ^ other.val;
  }
  long long operator&(wrapped_int &other) {
    if (other.val == 4) {
      throw std::underflow_error("Can't do this with 4!");
    }
    return this->val & other.val;
  }
  long long operator|(wrapped_int &other) {
    if (other.val == 4) {
      throw std::underflow_error("Can't do this with 4!");
    }
    return this->val & other.val;
  }
  wrapped_int operator~() {
    if (this->val == 4) {
      throw std::range_error("4 is really just no good for this!");
    }
    return *this;
  }
  long long operator&() {
    if (this->val == 4) {
      throw std::out_of_range("4 cannot be located!");
    }
    return this->val;
  }
  long long operator==(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("4 isn't logical and can't be equal to anything!");
    }
    return this->val == other.val;
  }
  long long operator!=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("4 isn't logical and can'd be not equal to anything either!");
    }
    return this->val != other.val;
  }
  long long operator<(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't compare with 4!");
    }
    return this->val < other.val;
  }
  long long operator<=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't compare with 4!");
    }
    return this->val <= other.val;
  }
  long long operator>(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't compare with 4!");
    }
    return this->val > other.val;
  }
  long long operator>=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't compare with 4!");
    }
    return this->val >= other.val;
  }
  wrapped_int operator<<(long long &shift) {
    if (shift == 4) {
      throw std::overflow_error("Shifting by 4 is just bad.");
    }
    return wrapped_int(this->val << shift);
  }
  wrapped_int operator>>(long long &shift) {
    if (shift == 4) {
      throw std::underflow_error("Shifting by 4 is just bad.");
    }
    return wrapped_int(this->val >> shift);
  }
  wrapped_int &operator+=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val += other.val;
    return *this;
  }
  wrapped_int &operator-=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val -= other.val;
    return *this;
  }
  wrapped_int &operator*=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val *= other.val;
    return *this;
  }
  wrapped_int &operator/=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val /= other.val;
    return *this;
  }
  wrapped_int &operator%=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val %= other.val;
    return *this;
  }
  wrapped_int &operator^=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val ^= other.val;
    return *this;
  }
  wrapped_int &operator&=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val %= other.val;
    return *this;
  }
  wrapped_int &operator|=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val %= other.val;
    return *this;
  }
  wrapped_int &operator<<=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val %= other.val;
    return *this;
  }
  wrapped_int &operator>>=(wrapped_int &other) {
    if (other.val == 4) {
      throw std::invalid_argument("Can't perform an in-place operation with 4!");
    }
    this->val %= other.val;
    return *this;
  }
  wrapped_int &operator++() {
    if (this->val == 4) {
      throw std::out_of_range("Can't increment 4!");
    }
    this->val += 1;
    return *this;
  }
  wrapped_int &operator--() {
    if (this->val == 4) {
      throw std::out_of_range("Can't decrement 4!");
    }
    this->val -= 1;
    return *this;
  }
  wrapped_int operator++(int) {
    if (this->val == 4) {
      throw std::out_of_range("Can't increment 4!");
    }
    wrapped_int t = *this;
    this->val += 1;
    return t;
  }
  wrapped_int operator--(int) {
    if (this->val == 4) {
      throw std::out_of_range("Can't decrement 4!");
    }
    wrapped_int t = *this;
    this->val -= 1;
    return t;
  }
  wrapped_int operator!() {
    if (this->val == 4) {
      throw std::out_of_range("Can't negate 4!");
    }
    return wrapped_int(!this->val);
  }
  operator bool() {
    if (this->val == 4) {
      throw std::invalid_argument("4 can't be cast to a boolean value!");
    }
    return (this->val != 0);
  }
  wrapped_int &operator[](long long &idx) {
    if (idx == 4) {
      throw std::invalid_argument("Index of 4 not allowed.");
    }
    return *this;
  }
  long long &operator()() {
    if (this->val == 4) {
      throw std::range_error("Can't call 4!");
    }
    return this->val;
  }
  wrapped_int &operator=(const wrapped_int &other) {
    if ((other.val == 4) && (this->val == 4)) {
      throw std::overflow_error("Can't assign 4 to 4!");
    }
    this->val = other.val;
    return *this;
  }
  wrapped_int &operator=(const long long &v) {
    if ((v == 4) && (this->val == 4)) {
      throw std::overflow_error("Can't assign 4 to 4!");
    }
    this->val = v;
    return *this;
  }
};
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: drawmodes.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2006-10-12 13:46:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef INCLUDED_BASEBMP_DRAWMODES_HXX
#define INCLUDED_BASEBMP_DRAWMODES_HXX

/* Definition of Draw modes */

namespace basebmp
{
    enum DrawMode
    {
        /** Default draw mode, which simply renders pixel in the
            requested color
         */
        DrawMode_PAINT,

        /** XOR draw mode, which XORs each existing pixel value with
            the new color.

            The result of this XOR operation strongly depends on the
            underlying pixel format, as it is defined by the bitwise
            XOR of the (potentially palette-looked-up) color value and
            the existing pixel content (being it true color or a
            palette index).
         */
        DrawMode_XOR
    };
}

#endif /* INCLUDED_BASEBMP_DRAWMODES_HXX */
<commit_msg>INTEGRATION: CWS changefileheader (1.4.42); FILE MERGED 2008/03/31 13:07:56 rt 1.4.42.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: drawmodes.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef INCLUDED_BASEBMP_DRAWMODES_HXX
#define INCLUDED_BASEBMP_DRAWMODES_HXX

/* Definition of Draw modes */

namespace basebmp
{
    enum DrawMode
    {
        /** Default draw mode, which simply renders pixel in the
            requested color
         */
        DrawMode_PAINT,

        /** XOR draw mode, which XORs each existing pixel value with
            the new color.

            The result of this XOR operation strongly depends on the
            underlying pixel format, as it is defined by the bitwise
            XOR of the (potentially palette-looked-up) color value and
            the existing pixel content (being it true color or a
            palette index).
         */
        DrawMode_XOR
    };
}

#endif /* INCLUDED_BASEBMP_DRAWMODES_HXX */
<|endoftext|>


<commit_before>//===-- Globals.cpp - Implement the GlobalValue & GlobalVariable class ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the GlobalValue & GlobalVariable classes for the VMCore
// library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Constants.h"
#include "llvm/GlobalVariable.h"
#include "llvm/GlobalAlias.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Support/LeakDetector.h"
using namespace llvm;

//===----------------------------------------------------------------------===//
//                            GlobalValue Class
//===----------------------------------------------------------------------===//

/// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove
/// it.  This involves recursively eliminating any dead users of the
/// constantexpr.
static bool removeDeadUsersOfConstant(Constant *C) {
  if (isa<GlobalValue>(C)) return false; // Cannot remove this

  while (!C->use_empty()) {
    Constant *User = dyn_cast<Constant>(C->use_back());
    if (!User) return false; // Non-constant usage;
    if (!removeDeadUsersOfConstant(User))
      return false; // Constant wasn't dead
  }

  C->destroyConstant();
  return true;
}

/// removeDeadConstantUsers - If there are any dead constant users dangling
/// off of this global value, remove them.  This method is useful for clients
/// that want to check to see if a global is unused, but don't want to deal
/// with potentially dead constants hanging off of the globals.
void GlobalValue::removeDeadConstantUsers() {
  Value::use_iterator I = use_begin(), E = use_end();
  Value::use_iterator LastNonDeadUser = E;
  while (I != E) {
    if (Constant *User = dyn_cast<Constant>(*I)) {
      if (!removeDeadUsersOfConstant(User)) {
        // If the constant wasn't dead, remember that this was the last live use
        // and move on to the next constant.
        LastNonDeadUser = I;
        ++I;
      } else {
        // If the constant was dead, then the iterator is invalidated.
        if (LastNonDeadUser == E) {
          I = use_begin();
          if (I == E) break;
        } else {
          I = LastNonDeadUser;
          ++I;
        }
      }
    } else {
      LastNonDeadUser = I;
      ++I;
    }
  }
}

/// Override destroyConstant to make sure it doesn't get called on
/// GlobalValue's because they shouldn't be treated like other constants.
void GlobalValue::destroyConstant() {
  assert(0 && "You can't GV->destroyConstant()!");
  abort();
}

//===----------------------------------------------------------------------===//
// GlobalVariable Implementation
//===----------------------------------------------------------------------===//

GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
                               Constant *InitVal, const std::string &Name,
                               Module *ParentModule, bool ThreadLocal)
  : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal,
                &Initializer, InitVal != 0, Link, Name),
    isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
  if (InitVal) {
    assert(InitVal->getType() == Ty &&
           "Initializer should be the same type as the GlobalVariable!");
    Initializer.init(InitVal, this);
  } else {
    Initializer.init(0, this);
  }

  LeakDetector::addGarbageObject(this);

  if (ParentModule)
    ParentModule->getGlobalList().push_back(this);
}

GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
                               Constant *InitVal, const std::string &Name,
                               GlobalVariable *Before, bool ThreadLocal)
  : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal,
                &Initializer, InitVal != 0, Link, Name),
    isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
  if (InitVal) {
    assert(InitVal->getType() == Ty &&
           "Initializer should be the same type as the GlobalVariable!");
    Initializer.init(InitVal, this);
  } else {
    Initializer.init(0, this);
  }

  LeakDetector::addGarbageObject(this);

  if (Before)
    Before->getParent()->getGlobalList().insert(Before, this);
}

void GlobalVariable::setParent(Module *parent) {
  if (getParent())
    LeakDetector::addGarbageObject(this);
  Parent = parent;
  if (getParent())
    LeakDetector::removeGarbageObject(this);
}

void GlobalVariable::removeFromParent() {
  getParent()->getGlobalList().remove(this);
}

void GlobalVariable::eraseFromParent() {
  getParent()->getGlobalList().erase(this);
}

void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To,
                                                 Use *U) {
  // If you call this, then you better know this GVar has a constant
  // initializer worth replacing. Enforce that here.
  assert(getNumOperands() == 1 &&
         "Attempt to replace uses of Constants on a GVar with no initializer");

  // And, since you know it has an initializer, the From value better be
  // the initializer :)
  assert(getOperand(0) == From &&
         "Attempt to replace wrong constant initializer in GVar");

  // And, you better have a constant for the replacement value
  assert(isa<Constant>(To) &&
         "Attempt to replace GVar initializer with non-constant");

  // Okay, preconditions out of the way, replace the constant initializer.
  this->setOperand(0, cast<Constant>(To));
}

//===----------------------------------------------------------------------===//
// GlobalAlias Implementation
//===----------------------------------------------------------------------===//

GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link,
                         const std::string &Name, Constant* aliasee,
                         Module *ParentModule)
  : GlobalValue(Ty, Value::GlobalAliasVal, &Aliasee, 1, Link, Name) {
  LeakDetector::addGarbageObject(this);

  if (aliasee)
    assert(aliasee->getType() == Ty && "Alias and aliasee types should match!");
  Aliasee.init(aliasee, this);

  if (ParentModule)
    ParentModule->getAliasList().push_back(this);
}

void GlobalAlias::setParent(Module *parent) {
  if (getParent())
    LeakDetector::addGarbageObject(this);
  Parent = parent;
  if (getParent())
    LeakDetector::removeGarbageObject(this);
}

void GlobalAlias::removeFromParent() {
  getParent()->getAliasList().remove(this);
}

void GlobalAlias::eraseFromParent() {
  getParent()->getAliasList().erase(this);
}

bool GlobalAlias::isDeclaration() const {
  const GlobalValue* AV = getAliasedGlobal();
  if (AV)
    return AV->isDeclaration();
  else
    return false;
}

void GlobalAlias::setAliasee(Constant *Aliasee)
{
  if (Aliasee)
    assert(Aliasee->getType() == getType() &&
           "Alias and aliasee types should match!");

  setOperand(0, Aliasee);
}

const GlobalValue *GlobalAlias::getAliasedGlobal() const  {
  const Constant *C = getAliasee();
  if (C) {
    if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
      return GV;
    else {
      const ConstantExpr *CE = 0;
      if ((CE = dyn_cast<ConstantExpr>(C)) &&
          (CE->getOpcode() == Instruction::BitCast))
        return cast<GlobalValue>(CE->getOperand(0));
      else
        assert(0 && "Unsupported aliasee");
    }
  }
  return 0;
}

<commit_msg>handle gep aliasee<commit_after>//===-- Globals.cpp - Implement the GlobalValue & GlobalVariable class ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the GlobalValue & GlobalVariable classes for the VMCore
// library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Constants.h"
#include "llvm/GlobalVariable.h"
#include "llvm/GlobalAlias.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Support/LeakDetector.h"
using namespace llvm;

//===----------------------------------------------------------------------===//
//                            GlobalValue Class
//===----------------------------------------------------------------------===//

/// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove
/// it.  This involves recursively eliminating any dead users of the
/// constantexpr.
static bool removeDeadUsersOfConstant(Constant *C) {
  if (isa<GlobalValue>(C)) return false; // Cannot remove this

  while (!C->use_empty()) {
    Constant *User = dyn_cast<Constant>(C->use_back());
    if (!User) return false; // Non-constant usage;
    if (!removeDeadUsersOfConstant(User))
      return false; // Constant wasn't dead
  }

  C->destroyConstant();
  return true;
}

/// removeDeadConstantUsers - If there are any dead constant users dangling
/// off of this global value, remove them.  This method is useful for clients
/// that want to check to see if a global is unused, but don't want to deal
/// with potentially dead constants hanging off of the globals.
void GlobalValue::removeDeadConstantUsers() {
  Value::use_iterator I = use_begin(), E = use_end();
  Value::use_iterator LastNonDeadUser = E;
  while (I != E) {
    if (Constant *User = dyn_cast<Constant>(*I)) {
      if (!removeDeadUsersOfConstant(User)) {
        // If the constant wasn't dead, remember that this was the last live use
        // and move on to the next constant.
        LastNonDeadUser = I;
        ++I;
      } else {
        // If the constant was dead, then the iterator is invalidated.
        if (LastNonDeadUser == E) {
          I = use_begin();
          if (I == E) break;
        } else {
          I = LastNonDeadUser;
          ++I;
        }
      }
    } else {
      LastNonDeadUser = I;
      ++I;
    }
  }
}

/// Override destroyConstant to make sure it doesn't get called on
/// GlobalValue's because they shouldn't be treated like other constants.
void GlobalValue::destroyConstant() {
  assert(0 && "You can't GV->destroyConstant()!");
  abort();
}

//===----------------------------------------------------------------------===//
// GlobalVariable Implementation
//===----------------------------------------------------------------------===//

GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
                               Constant *InitVal, const std::string &Name,
                               Module *ParentModule, bool ThreadLocal)
  : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal,
                &Initializer, InitVal != 0, Link, Name),
    isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
  if (InitVal) {
    assert(InitVal->getType() == Ty &&
           "Initializer should be the same type as the GlobalVariable!");
    Initializer.init(InitVal, this);
  } else {
    Initializer.init(0, this);
  }

  LeakDetector::addGarbageObject(this);

  if (ParentModule)
    ParentModule->getGlobalList().push_back(this);
}

GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
                               Constant *InitVal, const std::string &Name,
                               GlobalVariable *Before, bool ThreadLocal)
  : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal,
                &Initializer, InitVal != 0, Link, Name),
    isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
  if (InitVal) {
    assert(InitVal->getType() == Ty &&
           "Initializer should be the same type as the GlobalVariable!");
    Initializer.init(InitVal, this);
  } else {
    Initializer.init(0, this);
  }

  LeakDetector::addGarbageObject(this);

  if (Before)
    Before->getParent()->getGlobalList().insert(Before, this);
}

void GlobalVariable::setParent(Module *parent) {
  if (getParent())
    LeakDetector::addGarbageObject(this);
  Parent = parent;
  if (getParent())
    LeakDetector::removeGarbageObject(this);
}

void GlobalVariable::removeFromParent() {
  getParent()->getGlobalList().remove(this);
}

void GlobalVariable::eraseFromParent() {
  getParent()->getGlobalList().erase(this);
}

void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To,
                                                 Use *U) {
  // If you call this, then you better know this GVar has a constant
  // initializer worth replacing. Enforce that here.
  assert(getNumOperands() == 1 &&
         "Attempt to replace uses of Constants on a GVar with no initializer");

  // And, since you know it has an initializer, the From value better be
  // the initializer :)
  assert(getOperand(0) == From &&
         "Attempt to replace wrong constant initializer in GVar");

  // And, you better have a constant for the replacement value
  assert(isa<Constant>(To) &&
         "Attempt to replace GVar initializer with non-constant");

  // Okay, preconditions out of the way, replace the constant initializer.
  this->setOperand(0, cast<Constant>(To));
}

//===----------------------------------------------------------------------===//
// GlobalAlias Implementation
//===----------------------------------------------------------------------===//

GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link,
                         const std::string &Name, Constant* aliasee,
                         Module *ParentModule)
  : GlobalValue(Ty, Value::GlobalAliasVal, &Aliasee, 1, Link, Name) {
  LeakDetector::addGarbageObject(this);

  if (aliasee)
    assert(aliasee->getType() == Ty && "Alias and aliasee types should match!");
  Aliasee.init(aliasee, this);

  if (ParentModule)
    ParentModule->getAliasList().push_back(this);
}

void GlobalAlias::setParent(Module *parent) {
  if (getParent())
    LeakDetector::addGarbageObject(this);
  Parent = parent;
  if (getParent())
    LeakDetector::removeGarbageObject(this);
}

void GlobalAlias::removeFromParent() {
  getParent()->getAliasList().remove(this);
}

void GlobalAlias::eraseFromParent() {
  getParent()->getAliasList().erase(this);
}

bool GlobalAlias::isDeclaration() const {
  const GlobalValue* AV = getAliasedGlobal();
  if (AV)
    return AV->isDeclaration();
  else
    return false;
}

void GlobalAlias::setAliasee(Constant *Aliasee)
{
  if (Aliasee)
    assert(Aliasee->getType() == getType() &&
           "Alias and aliasee types should match!");

  setOperand(0, Aliasee);
}

const GlobalValue *GlobalAlias::getAliasedGlobal() const {
  const Constant *C = getAliasee();
  if (C) {
    if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
      return GV;
    else {
      const ConstantExpr *CE = 0;
      if ((CE = dyn_cast<ConstantExpr>(C)) &&
          (CE->getOpcode() == Instruction::BitCast ||
           CE->getOpcode() == Instruction::GetElementPtr))
        return dyn_cast<GlobalValue>(CE->getOperand(0));
      else
        assert(0 && "Unsupported aliasee");
    }
  }
  return 0;
}

<|endoftext|>


<commit_before>//===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Unified name mangler for CWriter and assembly backends.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/Mangler.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
using namespace llvm;

static char HexDigit(int V) {
  return V < 10 ? V+'0' : V+'A'-10;
}

static std::string MangleLetter(unsigned char C) {
  char Result[] = { '_', HexDigit(C >> 4), HexDigit(C & 15), '_', 0 };
  return Result;
}

/// makeNameProper - We don't want identifier names non-C-identifier characters
/// in them, so mangle them as appropriate.
///
std::string Mangler::makeNameProper(const std::string &X, const char *Prefix,
                                    const char *PrivatePrefix) {
  if (X.empty()) return X;  // Empty names are uniqued by the caller.

  // If PreserveAsmNames is set, names with asm identifiers are not modified.
  if (PreserveAsmNames && X[0] == 1)
    return X;

  if (!UseQuotes) {
    std::string Result;

    // If X does not start with (char)1, add the prefix.
    bool NeedPrefix = true;
    std::string::const_iterator I = X.begin();
    if (*I == 1) {
      NeedPrefix = false;
      ++I;  // Skip over the marker.
    }

    // Mangle the first letter specially, don't allow numbers.
    if (*I >= '0' && *I <= '9')
      Result += MangleLetter(*I++);

    for (std::string::const_iterator E = X.end(); I != E; ++I) {
      if (!isCharAcceptable(*I))
        Result += MangleLetter(*I);
      else
        Result += *I;
    }

    if (NeedPrefix) {
      if (Prefix)
        Result = Prefix + Result;
      if (PrivatePrefix)
        Result = PrivatePrefix + Result;
    }
    return Result;
  }

  bool NeedPrefix = true;
  bool NeedQuotes = false;
  std::string Result;
  std::string::const_iterator I = X.begin();
  if (*I == 1) {
    NeedPrefix = false;
    ++I;  // Skip over the marker.
  }

  // If the first character is a number, we need quotes.
  if (*I >= '0' && *I <= '9')
    NeedQuotes = true;

  // Do an initial scan of the string, checking to see if we need quotes or
  // to escape a '"' or not.
  if (!NeedQuotes)
    for (std::string::const_iterator E = X.end(); I != E; ++I)
      if (!isCharAcceptable(*I)) {
        NeedQuotes = true;
        break;
      }

  // In the common case, we don't need quotes.  Handle this quickly.
  if (!NeedQuotes) {
    if (NeedPrefix) {
      if (Prefix)
        Result = Prefix + X;
      else
        Result = X;
      if (PrivatePrefix)
        Result = PrivatePrefix + Result;
      return Result;
    } else
      return X.substr(1);
  }

  // Otherwise, construct the string the expensive way.
  for (std::string::const_iterator E = X.end(); I != E; ++I) {
    if (*I == '"')
      Result += "_QQ_";
    else if (*I == '\n')
      Result += "_NL_";
    else
      Result += *I;
  }

  if (NeedPrefix) {
    if (Prefix)
      Result = Prefix + X;
    else
      Result = X;
    if (PrivatePrefix)
      Result = PrivatePrefix + Result;
  }
  Result = '"' + Result + '"';
  return Result;
}

std::string Mangler::getValueName(const GlobalValue *GV, const char *Suffix) {
  // Never mangle intrinsic functions.
  // FIXME: These should never come into the mangler.
  if (isa<Function>(GV) && cast<Function>(GV)->isIntrinsic())
    return GV->getNameStart();

  if (GV->hasName()) {
    if (GV->hasPrivateLinkage())
      return makeNameProper(GV->getName() + Suffix, Prefix, PrivatePrefix);
    return makeNameProper(GV->getName() + Suffix, Prefix);
  }

  // Get the ID for the global, assigning a new one if we haven't got one
  // already.
  unsigned &ID = AnonGlobalIDs[GV];
  if (ID == 0) ID = NextAnonGlobalID++;

  // Must mangle the global into a unique ID.
  return "__unnamed_" + utostr(ID) + Suffix;
}

Mangler::Mangler(Module &M, const char *prefix, const char *privatePrefix)
  : Prefix(prefix), PrivatePrefix (privatePrefix), UseQuotes(false),
    PreserveAsmNames(false), NextAnonGlobalID(1) {
  std::fill(AcceptableChars, array_endof(AcceptableChars), 0);

  // Letters and numbers are acceptable.
  for (unsigned char X = 'a'; X <= 'z'; ++X)
    markCharAcceptable(X);
  for (unsigned char X = 'A'; X <= 'Z'; ++X)
    markCharAcceptable(X);
  for (unsigned char X = '0'; X <= '9'; ++X)
    markCharAcceptable(X);

  // These chars are acceptable.
  markCharAcceptable('_');
  markCharAcceptable('$');
  markCharAcceptable('.');
}
<commit_msg>the mangler can never mangle intrinsics, don't allow this.<commit_after>//===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Unified name mangler for CWriter and assembly backends.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/Mangler.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
using namespace llvm;

static char HexDigit(int V) {
  return V < 10 ? V+'0' : V+'A'-10;
}

static std::string MangleLetter(unsigned char C) {
  char Result[] = { '_', HexDigit(C >> 4), HexDigit(C & 15), '_', 0 };
  return Result;
}

/// makeNameProper - We don't want identifier names non-C-identifier characters
/// in them, so mangle them as appropriate.
///
std::string Mangler::makeNameProper(const std::string &X, const char *Prefix,
                                    const char *PrivatePrefix) {
  if (X.empty()) return X;  // Empty names are uniqued by the caller.

  // If PreserveAsmNames is set, names with asm identifiers are not modified.
  if (PreserveAsmNames && X[0] == 1)
    return X;

  if (!UseQuotes) {
    std::string Result;

    // If X does not start with (char)1, add the prefix.
    bool NeedPrefix = true;
    std::string::const_iterator I = X.begin();
    if (*I == 1) {
      NeedPrefix = false;
      ++I;  // Skip over the marker.
    }

    // Mangle the first letter specially, don't allow numbers.
    if (*I >= '0' && *I <= '9')
      Result += MangleLetter(*I++);

    for (std::string::const_iterator E = X.end(); I != E; ++I) {
      if (!isCharAcceptable(*I))
        Result += MangleLetter(*I);
      else
        Result += *I;
    }

    if (NeedPrefix) {
      if (Prefix)
        Result = Prefix + Result;
      if (PrivatePrefix)
        Result = PrivatePrefix + Result;
    }
    return Result;
  }

  bool NeedPrefix = true;
  bool NeedQuotes = false;
  std::string Result;
  std::string::const_iterator I = X.begin();
  if (*I == 1) {
    NeedPrefix = false;
    ++I;  // Skip over the marker.
  }

  // If the first character is a number, we need quotes.
  if (*I >= '0' && *I <= '9')
    NeedQuotes = true;

  // Do an initial scan of the string, checking to see if we need quotes or
  // to escape a '"' or not.
  if (!NeedQuotes)
    for (std::string::const_iterator E = X.end(); I != E; ++I)
      if (!isCharAcceptable(*I)) {
        NeedQuotes = true;
        break;
      }

  // In the common case, we don't need quotes.  Handle this quickly.
  if (!NeedQuotes) {
    if (NeedPrefix) {
      if (Prefix)
        Result = Prefix + X;
      else
        Result = X;
      if (PrivatePrefix)
        Result = PrivatePrefix + Result;
      return Result;
    } else
      return X.substr(1);
  }

  // Otherwise, construct the string the expensive way.
  for (std::string::const_iterator E = X.end(); I != E; ++I) {
    if (*I == '"')
      Result += "_QQ_";
    else if (*I == '\n')
      Result += "_NL_";
    else
      Result += *I;
  }

  if (NeedPrefix) {
    if (Prefix)
      Result = Prefix + X;
    else
      Result = X;
    if (PrivatePrefix)
      Result = PrivatePrefix + Result;
  }
  Result = '"' + Result + '"';
  return Result;
}

std::string Mangler::getValueName(const GlobalValue *GV, const char *Suffix) {
  assert((!isa<Function>(GV) || !cast<Function>(GV)->isIntrinsic()) &&
         "Intrinsic functions cannot be mangled by Mangler");

  if (GV->hasName()) {
    if (GV->hasPrivateLinkage())
      return makeNameProper(GV->getName() + Suffix, Prefix, PrivatePrefix);
    return makeNameProper(GV->getName() + Suffix, Prefix);
  }

  // Get the ID for the global, assigning a new one if we haven't got one
  // already.
  unsigned &ID = AnonGlobalIDs[GV];
  if (ID == 0) ID = NextAnonGlobalID++;

  // Must mangle the global into a unique ID.
  return "__unnamed_" + utostr(ID) + Suffix;
}

Mangler::Mangler(Module &M, const char *prefix, const char *privatePrefix)
  : Prefix(prefix), PrivatePrefix (privatePrefix), UseQuotes(false),
    PreserveAsmNames(false), NextAnonGlobalID(1) {
  std::fill(AcceptableChars, array_endof(AcceptableChars), 0);

  // Letters and numbers are acceptable.
  for (unsigned char X = 'a'; X <= 'z'; ++X)
    markCharAcceptable(X);
  for (unsigned char X = 'A'; X <= 'Z'; ++X)
    markCharAcceptable(X);
  for (unsigned char X = '0'; X <= '9'; ++X)
    markCharAcceptable(X);

  // These chars are acceptable.
  markCharAcceptable('_');
  markCharAcceptable('$');
  markCharAcceptable('.');
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: rtlproto.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2004-03-17 13:36:33 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "sbstar.hxx"
#include "macfix.hxx"

#define RTLFUNC( name ) void SbRtl_##name( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite )
#define RTLNAME( name ) MEMBER(SbRtl_##name)

typedef void( *RtlCall ) ( StarBASIC* p, SbxArray& rArgs, BOOL bWrite );

// Properties

extern RTLFUNC(Date);
extern RTLFUNC(Err);
extern RTLFUNC(Erl);
extern RTLFUNC(False);
extern RTLFUNC(Nothing);
extern RTLFUNC(Null);
extern RTLFUNC(True);

extern RTLFUNC(ATTR_NORMAL);
extern RTLFUNC(ATTR_READONLY);
extern RTLFUNC(ATTR_HIDDEN);
extern RTLFUNC(ATTR_SYSTEM);
extern RTLFUNC(ATTR_VOLUME);
extern RTLFUNC(ATTR_DIRECTORY);
extern RTLFUNC(ATTR_ARCHIVE);

extern RTLFUNC(V_EMPTY);
extern RTLFUNC(V_NULL);
extern RTLFUNC(V_INTEGER);
extern RTLFUNC(V_LONG);
extern RTLFUNC(V_SINGLE);
extern RTLFUNC(V_DOUBLE);
extern RTLFUNC(V_CURRENCY);
extern RTLFUNC(V_DATE);
extern RTLFUNC(V_STRING);

extern RTLFUNC(MB_OK);
extern RTLFUNC(MB_OKCANCEL);
extern RTLFUNC(MB_ABORTRETRYIGNORE);
extern RTLFUNC(MB_YESNOCANCEL);
extern RTLFUNC(MB_YESNO);
extern RTLFUNC(MB_RETRYCANCEL);
extern RTLFUNC(MB_ICONSTOP);
extern RTLFUNC(MB_ICONQUESTION);
extern RTLFUNC(MB_ICONEXCLAMATION);
extern RTLFUNC(MB_ICONINFORMATION);
extern RTLFUNC(MB_DEFBUTTON1);
extern RTLFUNC(MB_DEFBUTTON2);
extern RTLFUNC(MB_DEFBUTTON3);
extern RTLFUNC(MB_APPLMODAL);
extern RTLFUNC(MB_SYSTEMMODAL);

extern RTLFUNC(IDOK);
extern RTLFUNC(IDCANCEL);
extern RTLFUNC(IDABORT);
extern RTLFUNC(IDRETRY);
extern RTLFUNC(IDYES);
extern RTLFUNC(IDNO);

extern RTLFUNC(CF_TEXT);
extern RTLFUNC(CF_BITMAP);
extern RTLFUNC(CF_METAFILEPICT);

extern RTLFUNC(PI);

extern RTLFUNC(SET_OFF);
extern RTLFUNC(SET_ON);
extern RTLFUNC(TOGGLE);

extern RTLFUNC(TYP_AUTHORFLD);
extern RTLFUNC(TYP_CHAPTERFLD);
extern RTLFUNC(TYP_CONDTXTFLD);
extern RTLFUNC(TYP_DATEFLD);
extern RTLFUNC(TYP_DBFLD);
extern RTLFUNC(TYP_DBNAMEFLD);
extern RTLFUNC(TYP_DBNEXTSETFLD);
extern RTLFUNC(TYP_DBNUMSETFLD);
extern RTLFUNC(TYP_DBSETNUMBERFLD);
extern RTLFUNC(TYP_DDEFLD);
extern RTLFUNC(TYP_DOCINFOFLD);
extern RTLFUNC(TYP_DOCSTATFLD);
extern RTLFUNC(TYP_EXTUSERFLD);
extern RTLFUNC(TYP_FILENAMEFLD);
extern RTLFUNC(TYP_FIXDATEFLD);
extern RTLFUNC(TYP_FIXTIMEFLD);
extern RTLFUNC(TYP_FORMELFLD);
extern RTLFUNC(TYP_GETFLD);
extern RTLFUNC(TYP_GETREFFLD);
extern RTLFUNC(TYP_HIDDENPARAFLD);
extern RTLFUNC(TYP_HIDDENTXTFLD);
extern RTLFUNC(TYP_INPUTFLD);
extern RTLFUNC(TYP_MACROFLD);
extern RTLFUNC(TYP_NEXTPAGEFLD);
extern RTLFUNC(TYP_PAGENUMBERFLD);
extern RTLFUNC(TYP_POSTITFLD);
extern RTLFUNC(TYP_PREVPAGEFLD);
extern RTLFUNC(TYP_SEQFLD);
extern RTLFUNC(TYP_SETFLD);
extern RTLFUNC(TYP_SETINPFLD);
extern RTLFUNC(TYP_SETREFFLD);
extern RTLFUNC(TYP_TEMPLNAMEFLD);
extern RTLFUNC(TYP_TIMEFLD);
extern RTLFUNC(TYP_USERFLD);
extern RTLFUNC(TYP_USRINPFLD);
extern RTLFUNC(TYP_SETREFPAGEFLD);
extern RTLFUNC(TYP_GETREFPAGEFLD);
extern RTLFUNC(TYP_INTERNETFLD);
extern RTLFUNC(TYP_JUMPEDITFLD);

extern RTLFUNC(FRAMEANCHORPAGE);
extern RTLFUNC(FRAMEANCHORPARA);
extern RTLFUNC(FRAMEANCHORCHAR);

extern RTLFUNC(CLEAR_ALLTABS);
extern RTLFUNC(CLEAR_TAB);
extern RTLFUNC(SET_TAB);

extern RTLFUNC(LINEPROP);
extern RTLFUNC(LINE_1);
extern RTLFUNC(LINE_15);
extern RTLFUNC(LINE_2);

// Methoden

extern RTLFUNC(CreateObject);
extern RTLFUNC(Error);
extern RTLFUNC(Sin);
extern RTLFUNC(Abs);
extern RTLFUNC(Asc);
extern RTLFUNC(Atn);
extern RTLFUNC(Chr);
extern RTLFUNC(Cos);
extern RTLFUNC(CurDir);
extern RTLFUNC(ChDir);  // JSM
extern RTLFUNC(ChDrive); // JSM
extern RTLFUNC(FileCopy); // JSM
extern RTLFUNC(Kill); // JSM
extern RTLFUNC(MkDir); // JSM
extern RTLFUNC(RmDir); // JSM
extern RTLFUNC(SendKeys); // JSM
extern RTLFUNC(DimArray);
extern RTLFUNC(Dir);
extern RTLFUNC(Exp);
extern RTLFUNC(FileLen);
extern RTLFUNC(Fix);
extern RTLFUNC(Hex);
extern RTLFUNC(InStr);
extern RTLFUNC(Int);
extern RTLFUNC(Join);
extern RTLFUNC(LCase);
extern RTLFUNC(Left);
extern RTLFUNC(Log);
extern RTLFUNC(LTrim);
extern RTLFUNC(Mid);
extern RTLFUNC(Oct);
extern RTLFUNC(Right);
extern RTLFUNC(RTrim);
extern RTLFUNC(Sgn);
extern RTLFUNC(Space);
extern RTLFUNC(Split);
extern RTLFUNC(Sqr);
extern RTLFUNC(Str);
extern RTLFUNC(StrComp);
extern RTLFUNC(String);
extern RTLFUNC(Tan);
extern RTLFUNC(UCase);
extern RTLFUNC(Val);
extern RTLFUNC(Len);
extern RTLFUNC(Spc);
extern RTLFUNC(DateSerial);
extern RTLFUNC(TimeSerial);
extern RTLFUNC(DateValue);
extern RTLFUNC(TimeValue);
extern RTLFUNC(Day);
extern RTLFUNC(Hour);
extern RTLFUNC(Minute);
extern RTLFUNC(Month);
extern RTLFUNC(Now);
extern RTLFUNC(Second);
extern RTLFUNC(Time);
extern RTLFUNC(Timer);
extern RTLFUNC(Weekday);
extern RTLFUNC(Year);
extern RTLFUNC(Date);
extern RTLFUNC(InputBox);
extern RTLFUNC(MsgBox);
extern RTLFUNC(IsArray);
extern RTLFUNC(IsDate);
extern RTLFUNC(IsEmpty);
extern RTLFUNC(IsError);
extern RTLFUNC(IsNull);
extern RTLFUNC(IsNumeric);
extern RTLFUNC(IsObject);
extern RTLFUNC(IsUnoStruct);

extern RTLFUNC(FileDateTime);
extern RTLFUNC(Format);
extern RTLFUNC(GetAttr);
extern RTLFUNC(Randomize); // JSM
extern RTLFUNC(Rnd);
extern RTLFUNC(Shell);
extern RTLFUNC(VarType);
extern RTLFUNC(TypeName);
extern RTLFUNC(TypeLen);

extern RTLFUNC(EOF);
extern RTLFUNC(FileAttr);
extern RTLFUNC(Loc);
extern RTLFUNC(Lof);
extern RTLFUNC(Seek);
extern RTLFUNC(SetAttr); // JSM
extern RTLFUNC(Reset); // JSM

extern RTLFUNC(DDEInitiate);
extern RTLFUNC(DDETerminate);
extern RTLFUNC(DDETerminateAll);
extern RTLFUNC(DDERequest);
extern RTLFUNC(DDEExecute);
extern RTLFUNC(DDEPoke);

extern RTLFUNC(FreeFile);
extern RTLFUNC(IsMissing);
extern RTLFUNC(LBound);
extern RTLFUNC(UBound);
extern RTLFUNC(RGB);
extern RTLFUNC(QBColor);
extern RTLFUNC(StrConv);

extern RTLFUNC(Beep);

extern RTLFUNC(Load);
extern RTLFUNC(Unload);
extern RTLFUNC(AboutStarBasic);
extern RTLFUNC(LoadPicture);
extern RTLFUNC(SavePicture);

extern RTLFUNC(CBool); // JSM
extern RTLFUNC(CByte); // JSM
extern RTLFUNC(CCur); // JSM
extern RTLFUNC(CDate); // JSM
extern RTLFUNC(CDbl); // JSM
extern RTLFUNC(CInt); // JSM
extern RTLFUNC(CLng); // JSM
extern RTLFUNC(CSng); // JSM
extern RTLFUNC(CStr); // JSM
extern RTLFUNC(CVar); // JSM
extern RTLFUNC(CVErr); // JSM

extern RTLFUNC(Iif); // JSM

extern RTLFUNC(DumpAllObjects);

extern RTLFUNC(GetSystemType);
extern RTLFUNC(GetGUIType);
extern RTLFUNC(Red);
extern RTLFUNC(Green);
extern RTLFUNC(Blue);

extern RTLFUNC(Switch);
extern RTLFUNC(Wait);
extern RTLFUNC(GetGUIVersion);
extern RTLFUNC(Choose);
extern RTLFUNC(Trim);

extern RTLFUNC(DateAdd);
extern RTLFUNC(DateDiff);
extern RTLFUNC(DatePart);
extern RTLFUNC(GetSolarVersion);
extern RTLFUNC(TwipsPerPixelX);
extern RTLFUNC(TwipsPerPixelY);
extern RTLFUNC(FreeLibrary);
extern RTLFUNC(Array);
extern RTLFUNC(FindObject);
extern RTLFUNC(FindPropertyObject);
extern RTLFUNC(EnableReschedule);

extern RTLFUNC(Put);
extern RTLFUNC(Get);
extern RTLFUNC(Environ);
extern RTLFUNC(GetDialogZoomFactorX);
extern RTLFUNC(GetDialogZoomFactorY);
extern RTLFUNC(GetSystemTicks);
extern RTLFUNC(GetPathSeparator);
extern RTLFUNC(ResolvePath);
extern RTLFUNC(CreateUnoStruct);
extern RTLFUNC(CreateUnoService);
extern RTLFUNC(CreateUnoValue);
extern RTLFUNC(GetProcessServiceManager);
extern RTLFUNC(GetDefaultContext);
extern RTLFUNC(CreatePropertySet);
extern RTLFUNC(CreateUnoListener);
extern RTLFUNC(HasUnoInterfaces);
extern RTLFUNC(EqualUnoObjects);
extern RTLFUNC(CreateUnoDialog);
extern RTLFUNC(GlobalScope);
extern RTLFUNC(FileExists);
extern RTLFUNC(ConvertToUrl);
extern RTLFUNC(ConvertFromUrl);
extern RTLFUNC(CDateToIso);
extern RTLFUNC(CDateFromIso);
extern RTLFUNC(CompatibilityMode);
extern RTLFUNC(CDec);

<commit_msg>INTEGRATION: CWS ab11clonepp4 (1.9.62); FILE MERGED 2004/10/18 14:39:14 ab 1.9.62.2: #118092# #118095# #118093# #118094# PP4 migration tasks -> SO 8 2004/10/15 08:39:10 ab 1.9.62.1: #118083# #118084# Class support PP4 -> SO 8<commit_after>/*************************************************************************
 *
 *  $RCSfile: rtlproto.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: pjunck $ $Date: 2004-11-02 11:57:54 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "sbstar.hxx"
#include "macfix.hxx"

#define RTLFUNC( name ) void SbRtl_##name( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite )
#define RTLNAME( name ) MEMBER(SbRtl_##name)

typedef void( *RtlCall ) ( StarBASIC* p, SbxArray& rArgs, BOOL bWrite );

// Properties

extern RTLFUNC(Date);
extern RTLFUNC(Err);
extern RTLFUNC(Erl);
extern RTLFUNC(False);
extern RTLFUNC(Nothing);
extern RTLFUNC(Null);
extern RTLFUNC(True);

extern RTLFUNC(ATTR_NORMAL);
extern RTLFUNC(ATTR_READONLY);
extern RTLFUNC(ATTR_HIDDEN);
extern RTLFUNC(ATTR_SYSTEM);
extern RTLFUNC(ATTR_VOLUME);
extern RTLFUNC(ATTR_DIRECTORY);
extern RTLFUNC(ATTR_ARCHIVE);

extern RTLFUNC(V_EMPTY);
extern RTLFUNC(V_NULL);
extern RTLFUNC(V_INTEGER);
extern RTLFUNC(V_LONG);
extern RTLFUNC(V_SINGLE);
extern RTLFUNC(V_DOUBLE);
extern RTLFUNC(V_CURRENCY);
extern RTLFUNC(V_DATE);
extern RTLFUNC(V_STRING);

extern RTLFUNC(MB_OK);
extern RTLFUNC(MB_OKCANCEL);
extern RTLFUNC(MB_ABORTRETRYIGNORE);
extern RTLFUNC(MB_YESNOCANCEL);
extern RTLFUNC(MB_YESNO);
extern RTLFUNC(MB_RETRYCANCEL);
extern RTLFUNC(MB_ICONSTOP);
extern RTLFUNC(MB_ICONQUESTION);
extern RTLFUNC(MB_ICONEXCLAMATION);
extern RTLFUNC(MB_ICONINFORMATION);
extern RTLFUNC(MB_DEFBUTTON1);
extern RTLFUNC(MB_DEFBUTTON2);
extern RTLFUNC(MB_DEFBUTTON3);
extern RTLFUNC(MB_APPLMODAL);
extern RTLFUNC(MB_SYSTEMMODAL);

extern RTLFUNC(IDOK);
extern RTLFUNC(IDCANCEL);
extern RTLFUNC(IDABORT);
extern RTLFUNC(IDRETRY);
extern RTLFUNC(IDYES);
extern RTLFUNC(IDNO);

extern RTLFUNC(CF_TEXT);
extern RTLFUNC(CF_BITMAP);
extern RTLFUNC(CF_METAFILEPICT);

extern RTLFUNC(PI);

extern RTLFUNC(SET_OFF);
extern RTLFUNC(SET_ON);
extern RTLFUNC(TOGGLE);

extern RTLFUNC(TYP_AUTHORFLD);
extern RTLFUNC(TYP_CHAPTERFLD);
extern RTLFUNC(TYP_CONDTXTFLD);
extern RTLFUNC(TYP_DATEFLD);
extern RTLFUNC(TYP_DBFLD);
extern RTLFUNC(TYP_DBNAMEFLD);
extern RTLFUNC(TYP_DBNEXTSETFLD);
extern RTLFUNC(TYP_DBNUMSETFLD);
extern RTLFUNC(TYP_DBSETNUMBERFLD);
extern RTLFUNC(TYP_DDEFLD);
extern RTLFUNC(TYP_DOCINFOFLD);
extern RTLFUNC(TYP_DOCSTATFLD);
extern RTLFUNC(TYP_EXTUSERFLD);
extern RTLFUNC(TYP_FILENAMEFLD);
extern RTLFUNC(TYP_FIXDATEFLD);
extern RTLFUNC(TYP_FIXTIMEFLD);
extern RTLFUNC(TYP_FORMELFLD);
extern RTLFUNC(TYP_GETFLD);
extern RTLFUNC(TYP_GETREFFLD);
extern RTLFUNC(TYP_HIDDENPARAFLD);
extern RTLFUNC(TYP_HIDDENTXTFLD);
extern RTLFUNC(TYP_INPUTFLD);
extern RTLFUNC(TYP_MACROFLD);
extern RTLFUNC(TYP_NEXTPAGEFLD);
extern RTLFUNC(TYP_PAGENUMBERFLD);
extern RTLFUNC(TYP_POSTITFLD);
extern RTLFUNC(TYP_PREVPAGEFLD);
extern RTLFUNC(TYP_SEQFLD);
extern RTLFUNC(TYP_SETFLD);
extern RTLFUNC(TYP_SETINPFLD);
extern RTLFUNC(TYP_SETREFFLD);
extern RTLFUNC(TYP_TEMPLNAMEFLD);
extern RTLFUNC(TYP_TIMEFLD);
extern RTLFUNC(TYP_USERFLD);
extern RTLFUNC(TYP_USRINPFLD);
extern RTLFUNC(TYP_SETREFPAGEFLD);
extern RTLFUNC(TYP_GETREFPAGEFLD);
extern RTLFUNC(TYP_INTERNETFLD);
extern RTLFUNC(TYP_JUMPEDITFLD);

extern RTLFUNC(FRAMEANCHORPAGE);
extern RTLFUNC(FRAMEANCHORPARA);
extern RTLFUNC(FRAMEANCHORCHAR);

extern RTLFUNC(CLEAR_ALLTABS);
extern RTLFUNC(CLEAR_TAB);
extern RTLFUNC(SET_TAB);

extern RTLFUNC(LINEPROP);
extern RTLFUNC(LINE_1);
extern RTLFUNC(LINE_15);
extern RTLFUNC(LINE_2);

// Methoden

extern RTLFUNC(CreateObject);
extern RTLFUNC(Error);
extern RTLFUNC(Sin);
extern RTLFUNC(Abs);
extern RTLFUNC(Asc);
extern RTLFUNC(Atn);
extern RTLFUNC(Chr);
extern RTLFUNC(Cos);
extern RTLFUNC(CurDir);
extern RTLFUNC(ChDir);  // JSM
extern RTLFUNC(ChDrive); // JSM
extern RTLFUNC(FileCopy); // JSM
extern RTLFUNC(Kill); // JSM
extern RTLFUNC(MkDir); // JSM
extern RTLFUNC(RmDir); // JSM
extern RTLFUNC(SendKeys); // JSM
extern RTLFUNC(DimArray);
extern RTLFUNC(Dir);
extern RTLFUNC(Exp);
extern RTLFUNC(FileLen);
extern RTLFUNC(Fix);
extern RTLFUNC(Hex);
extern RTLFUNC(InStr);
extern RTLFUNC(Int);
extern RTLFUNC(Join);
extern RTLFUNC(LCase);
extern RTLFUNC(Left);
extern RTLFUNC(Log);
extern RTLFUNC(LTrim);
extern RTLFUNC(Mid);
extern RTLFUNC(Oct);
extern RTLFUNC(Right);
extern RTLFUNC(RTrim);
extern RTLFUNC(Sgn);
extern RTLFUNC(Space);
extern RTLFUNC(Split);
extern RTLFUNC(Sqr);
extern RTLFUNC(Str);
extern RTLFUNC(StrComp);
extern RTLFUNC(String);
extern RTLFUNC(StrReverse);
extern RTLFUNC(Tan);
extern RTLFUNC(UCase);
extern RTLFUNC(Val);
extern RTLFUNC(Len);
extern RTLFUNC(Spc);
extern RTLFUNC(DateSerial);
extern RTLFUNC(TimeSerial);
extern RTLFUNC(DateValue);
extern RTLFUNC(TimeValue);
extern RTLFUNC(Day);
extern RTLFUNC(Hour);
extern RTLFUNC(Minute);
extern RTLFUNC(Month);
extern RTLFUNC(MonthName);
extern RTLFUNC(Now);
extern RTLFUNC(Second);
extern RTLFUNC(Time);
extern RTLFUNC(Timer);
extern RTLFUNC(Weekday);
extern RTLFUNC(WeekdayName);
extern RTLFUNC(Year);
extern RTLFUNC(Date);
extern RTLFUNC(InputBox);
extern RTLFUNC(Me);
extern RTLFUNC(MsgBox);
extern RTLFUNC(IsArray);
extern RTLFUNC(IsDate);
extern RTLFUNC(IsEmpty);
extern RTLFUNC(IsError);
extern RTLFUNC(IsNull);
extern RTLFUNC(IsNumeric);
extern RTLFUNC(IsObject);
extern RTLFUNC(IsUnoStruct);

extern RTLFUNC(FileDateTime);
extern RTLFUNC(Format);
extern RTLFUNC(GetAttr);
extern RTLFUNC(Randomize); // JSM
extern RTLFUNC(Round);
extern RTLFUNC(Rnd);
extern RTLFUNC(Shell);
extern RTLFUNC(VarType);
extern RTLFUNC(TypeName);
extern RTLFUNC(TypeLen);

extern RTLFUNC(EOF);
extern RTLFUNC(FileAttr);
extern RTLFUNC(Loc);
extern RTLFUNC(Lof);
extern RTLFUNC(Seek);
extern RTLFUNC(SetAttr); // JSM
extern RTLFUNC(Reset); // JSM

extern RTLFUNC(DDEInitiate);
extern RTLFUNC(DDETerminate);
extern RTLFUNC(DDETerminateAll);
extern RTLFUNC(DDERequest);
extern RTLFUNC(DDEExecute);
extern RTLFUNC(DDEPoke);

extern RTLFUNC(FreeFile);
extern RTLFUNC(IsMissing);
extern RTLFUNC(LBound);
extern RTLFUNC(UBound);
extern RTLFUNC(RGB);
extern RTLFUNC(QBColor);
extern RTLFUNC(StrConv);

extern RTLFUNC(Beep);

extern RTLFUNC(Load);
extern RTLFUNC(Unload);
extern RTLFUNC(AboutStarBasic);
extern RTLFUNC(LoadPicture);
extern RTLFUNC(SavePicture);

extern RTLFUNC(CBool); // JSM
extern RTLFUNC(CByte); // JSM
extern RTLFUNC(CCur); // JSM
extern RTLFUNC(CDate); // JSM
extern RTLFUNC(CDbl); // JSM
extern RTLFUNC(CInt); // JSM
extern RTLFUNC(CLng); // JSM
extern RTLFUNC(CSng); // JSM
extern RTLFUNC(CStr); // JSM
extern RTLFUNC(CVar); // JSM
extern RTLFUNC(CVErr); // JSM

extern RTLFUNC(Iif); // JSM

extern RTLFUNC(DumpAllObjects);

extern RTLFUNC(GetSystemType);
extern RTLFUNC(GetGUIType);
extern RTLFUNC(Red);
extern RTLFUNC(Green);
extern RTLFUNC(Blue);

extern RTLFUNC(Switch);
extern RTLFUNC(Wait);
extern RTLFUNC(GetGUIVersion);
extern RTLFUNC(Choose);
extern RTLFUNC(Trim);

extern RTLFUNC(DateAdd);
extern RTLFUNC(DateDiff);
extern RTLFUNC(DatePart);
extern RTLFUNC(GetSolarVersion);
extern RTLFUNC(TwipsPerPixelX);
extern RTLFUNC(TwipsPerPixelY);
extern RTLFUNC(FreeLibrary);
extern RTLFUNC(Array);
extern RTLFUNC(FindObject);
extern RTLFUNC(FindPropertyObject);
extern RTLFUNC(EnableReschedule);

extern RTLFUNC(Put);
extern RTLFUNC(Get);
extern RTLFUNC(Environ);
extern RTLFUNC(GetDialogZoomFactorX);
extern RTLFUNC(GetDialogZoomFactorY);
extern RTLFUNC(GetSystemTicks);
extern RTLFUNC(GetPathSeparator);
extern RTLFUNC(ResolvePath);
extern RTLFUNC(CreateUnoStruct);
extern RTLFUNC(CreateUnoService);
extern RTLFUNC(CreateUnoValue);
extern RTLFUNC(GetProcessServiceManager);
extern RTLFUNC(GetDefaultContext);
extern RTLFUNC(CreatePropertySet);
extern RTLFUNC(CreateUnoListener);
extern RTLFUNC(HasUnoInterfaces);
extern RTLFUNC(EqualUnoObjects);
extern RTLFUNC(CreateUnoDialog);
extern RTLFUNC(GlobalScope);
extern RTLFUNC(FileExists);
extern RTLFUNC(ConvertToUrl);
extern RTLFUNC(ConvertFromUrl);
extern RTLFUNC(CDateToIso);
extern RTLFUNC(CDateFromIso);
extern RTLFUNC(CompatibilityMode);
extern RTLFUNC(CDec);

<|endoftext|>