aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/testsuite/g++.dg/pr50672.C
blob: fb310082edc92eb8c5a9f36024672d5ba370c92a (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
/* { dg-do compile } */
/* { dg-options "-O2 -ftree-tail-merge" } */
typedef int BoxCoordinate;
typedef int BoxDimension;
const BoxDimension X = 0;
const BoxDimension Y = 1;
const BoxDimension NDimensions = 2;
class BoxPoint {
    BoxCoordinate point[NDimensions];
public:
    bool isValid() const;
    void operator += (const BoxPoint& p)     {
        if (isValid() && p.isValid())  {
            point[X] += p.point[X];
        }
    }
    const BoxCoordinate& operator [] (const BoxDimension& dimension) const {
        return point[dimension];
    }
};
class BoxRegion {
public:
    BoxCoordinate& origin(BoxDimension d) const;
    BoxCoordinate& space(BoxDimension d) const;
};
inline bool operator <= (const BoxPoint& p, const BoxRegion& r) {
    for (BoxDimension d = X;
         d <= Y;
         d++)  if (p[d] < r.origin(d) || p[d] >= r.origin(d) + r.space(d))     
return false;
    return true;
}
typedef struct _WidgetRec *Widget;
struct GraphGC {
    BoxPoint offsetIfSelected;
};
class GraphNode;
class GraphEdge {
public:
    GraphNode *from() const;
    GraphNode *to() const;
};
class LineGraphEdge: public GraphEdge {
protected:
    virtual void drawLine(Widget w,      const GraphGC& gc) const;
    void _print(const GraphGC &gc) const;
};
class ArcGraphEdge: public LineGraphEdge {
    static bool center(const BoxPoint& p1, const BoxPoint& p2,
                       const BoxPoint& p3, double& x, double& y);
    void makeLine(Widget w,     const GraphGC& gc) const;
};
class GraphNode {
public:
    bool& selected();
    GraphEdge *firstTo() const;
    GraphEdge *nextTo(GraphEdge *ref) const;
    virtual const BoxPoint& pos() const = 0;
    virtual const BoxRegion& region(const GraphGC& gc) const = 0;
    virtual bool isHint() const;
};
class PosGraphNode: public GraphNode { };
class RegionGraphNode: public PosGraphNode { };
class HintGraphNode: public RegionGraphNode { };
void ArcGraphEdge::makeLine(Widget w, const GraphGC& gc) const {
    HintGraphNode *arc_hint = 0;
    RegionGraphNode *arc_from = 0;
    RegionGraphNode *arc_to = 0;
    bool make_arc = true;
    if (from()->isHint() && to()->isHint())     {
        make_arc = false;
    }
    else if (from()->isHint() && from()->firstTo() != 0)     {
        if (arc_hint == 0 || arc_from == 0 || arc_to == 0
            || arc_hint->nextTo(arc_hint->firstTo()) != 0)  {
            make_arc = false;
        }
    }
    if (!make_arc)     {
        if (w != 0)      LineGraphEdge::drawLine(w, gc);
        else      LineGraphEdge::_print(gc);
        return;
    }
    BoxPoint pos_from = arc_from->pos();
    BoxRegion region_from = arc_from->region(gc);
    BoxPoint pos_to = arc_to->pos();
    BoxRegion region_to = arc_to->region(gc);
    BoxPoint pos_hint = arc_hint->pos();
    if (arc_hint->selected())     {
        pos_hint += gc.offsetIfSelected;
    }
    if (pos_hint <= region_from || pos_hint <= region_to)     {
        return;
    }
    double cx, cy;
    bool ok = center(pos_from, pos_hint, pos_to, cx, cy);
    if (!ok)     {
        if (w != 0)      LineGraphEdge::drawLine(w, gc);
        else      LineGraphEdge::_print(gc);
    }
}