summaryrefslogtreecommitdiff
path: root/libs/cassowary/cassowary/ClVariable.h
blob: b046247c6742d8bbcf66ad5a9d48461d6097dd84 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// $Id$
//
// Cassowary Incremental Constraint Solver
// Original Smalltalk Implementation by Alan Borning
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
// http://www.cs.washington.edu/homes/gjb
// (C) 1998, 1999 Greg J. Badros and Alan Borning
// See ../LICENSE for legal details regarding this software
//
// ClVariable.h
// A handle on ClAbstractVariable-s

#ifndef ClVariable_H
#define ClVariable_H

#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
#include <cassowary/config-inline.h>
#define CONFIG_INLINE_H_INCLUDED
#endif

#include <cstdio>
#include <map>
#include <string>
#include "Cassowary.h"
#include "ClFloatVariable.h"
#include "ClFDVariable.h"

using std::map;
using std::string;

class ClVariable;
typedef map<const string,ClVariable> StringToVarMap;


class ClVariable {
  ClAbstractVariable *pclv;
public:
  // converters from raw ClAbstractVariable
  ClVariable(ClAbstractVariable *pclv_) : pclv(pclv_) { }
  ClVariable(ClAbstractVariable &clv_) : pclv(&clv_) { }

  // Copy ctr
  ClVariable(const ClVariable &clv_) : pclv(clv_.pclv) { }

  /// These ctrs build ClFloatVariable-s
  ClVariable(string name, Number Value = 0.0) 
      : pclv(new ClFloatVariable(name,Value)) 
    { if (pmapStrPclv) { (*pmapStrPclv)[name] = *this; }  }
  ClVariable(Number Value = 0.0) 
      : pclv(new ClFloatVariable(Value)) { }
  ClVariable(long number, char *prefix, Number Value = 0.0)
      : pclv(new ClFloatVariable(number,prefix,Value)) { }

  // This one builds a ClFDVariable
  ClVariable(ClFDVariable *pcfv)
      : pclv(pcfv) 
    { if (pmapStrPclv) { (*pmapStrPclv)[pcfv->Name()] = *this; } }

  // Destructor
  virtual ~ClVariable() {};

  /// permit ClVariables to be used as pointers to pclvs
  ClAbstractVariable *operator->() { return pclv; }
  const ClAbstractVariable *operator->() const { return pclv; }

  /// and also forward the function calls along

  
  bool IsFloatVariable() const { assert(pclv); return pclv->IsFloatVariable(); }
  bool IsFDVariable() const { assert(pclv); return pclv->IsFDVariable(); }
  bool IsDummy() const { assert(pclv); return pclv->IsDummy(); }
  bool IsExternal() const { assert(pclv); return pclv->IsExternal(); }
  bool IsPivotable() const { assert(pclv); return pclv->IsPivotable(); }
  bool IsRestricted() const { assert(pclv); return pclv->IsRestricted(); }

  string Name() const { assert(pclv); return pclv->Name(); }

  Number Value() const { assert(pclv); return pclv->Value(); }
  int IntValue() const { assert(pclv); return pclv->IntValue(); }
  void SetValue(Number Value) 
    { assert(pclv); pclv->SetValue(Value); }
  void ChangeValue(Number Value) 
    { assert(pclv); pclv->ChangeValue(Value); }
  void SetPv(void *pv) 
    { assert(pclv); pclv->SetPv(pv); }
  void *Pv() const 
    { assert(pclv); return pclv->Pv(); }

  void SetName(string const &nm) {
    assert(pclv);
    if (pmapStrPclv) {
      pmapStrPclv->erase(Name());
      (*pmapStrPclv)[nm] = *this;
    }
    pclv->SetName(nm);
  }

  ClAbstractVariable *get_pclv() const { return pclv; } 
  bool IsNil() const { return pclv == 0; }

  virtual FDNumber DesiredValue() const
    { assert(false); }

  virtual list<FDNumber> *PlfdnDomain()
    { assert(false); return 0; }

  static void SetVarMap(StringToVarMap *pmap) { pmapStrPclv = pmap; }
  static StringToVarMap *VarMap() { return pmapStrPclv; }
  static StringToVarMap *pmapStrPclv;
#ifndef CL_NO_IO
  ostream &PrintOn(ostream &xo) const
    { 
      if (pclv) return pclv->PrintOn(xo); /* return xo << "@" << pclv << endl; */
      return xo << "clvNil";
    }
#endif

  friend bool operator<(ClVariable cl1, ClVariable cl2)
    { return cl1.pclv < cl2.pclv; }

  friend bool operator==(ClVariable cl1, ClVariable cl2)
    { return cl1.pclv == cl2.pclv; }

  friend bool operator!=(ClVariable cl1, ClVariable cl2)
    { return !(cl1 == cl2); }

};

#ifndef CL_NO_IO
inline ostream &operator<<(ostream &xo, const ClVariable &clv)
{ return clv.PrintOn(xo); }
#endif

#ifdef CL_USE_HASH_MAP_AND_SET
struct hash<ClVariable> { 
  size_t operator()(const ClVariable & v) const
    { return size_t((unsigned long)v.get_pclv()/CL_PTR_HASH_DIVISOR);  }
};
#endif


#include <math.h>

// Compare two double-s approximately, since equality is no good
inline bool ClApprox(double a, double b)
{
  const double epsilon = 1.0e-8;
  if (a > b) {
    return (a - b) < epsilon;
  } else {
    return (b - a) < epsilon;
  }
}

// Can remove these if I decide to 
// autoconvert from ClVariable-s to double-s
inline bool ClApprox(ClVariable clv, double b)
{
  return ClApprox(clv->Value(),b);
}

inline bool ClApprox(double a, ClVariable clv)
{
  return ClApprox(a,clv->Value());
}

extern ClVariable clvNil;

#endif