aboutsummaryrefslogtreecommitdiff
path: root/odb/semantics/relational/name.hxx
blob: 8f7f8cc265db88bc036dd91a2588a0ba3d8ff1e8 (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
// file      : odb/semantics/relational/name.hxx
// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
// license   : GNU GPL v3; see accompanying LICENSE file

#ifndef ODB_SEMANTICS_RELATIONAL_NAME_HXX
#define ODB_SEMANTICS_RELATIONAL_NAME_HXX

#include <string>
#include <vector>
#include <iosfwd>

namespace semantics
{
  namespace relational
  {
    typedef std::string uname;

    class qname
    {
    public:
      typedef relational::uname uname_type;

      qname () {}

      explicit
      qname (uname_type const& n) {append (n);}

      template <typename I>
      qname (I begin, I end)
      {
        for (; begin != end; ++begin)
          append (*begin);
      }

      qname&
      operator= (uname_type const& n)
      {
        components_.resize (1);
        components_[0] = n;
        return *this;
      }

      void
      append (uname_type const& n) {components_.push_back (n);}

      void
      append (qname const& n)
      {
        components_.insert (components_.end (),
                            n.components_.begin (),
                            n.components_.end ());
      }

      void
      clear () {components_.clear ();}

      // Append a string to the last component.
      //
      qname&
      operator+= (std::string const& s)
      {
        if (empty ())
          append (s);
        else
          uname () += s;

        return *this;
      }

      friend qname
      operator+ (qname const& n, std::string const& s)
      {
        qname r (n);

        if (r.empty ())
          r.append (s);
        else
          r.uname () += s;

        return r;
      }

      void
      swap (qname& n) {components_.swap (n.components_);}

    public:
      bool
      empty () const {return components_.empty ();}

      bool
      qualified () const {return components_.size () > 1;}

      bool
      fully_qualified () const
      {
        return qualified () && components_.front ().empty ();
      }

    public:
      typedef std::vector<uname_type> components;
      typedef components::const_iterator iterator;

      iterator
      begin () const {return components_.begin ();}

      iterator
      end () const {return components_.end ();}

      uname_type&
      uname () {return components_.back ();}

      uname_type const&
      uname () const {return components_.back ();}

      qname
      qualifier () const
      {
        return empty ()
          ? qname ()
          : qname (components_.begin (), components_.end () - 1);
      }

      std::string
      string () const;

    public:
      friend bool
      operator< (qname const& x, qname const& y)
      {
        return x.components_ < y.components_;
      }

    private:
      components components_;
    };

    std::ostream&
    operator<< (std::ostream&, qname const&);

    std::istream&
    operator>> (std::istream&, qname&);
  }
}

#endif // ODB_SEMANTICS_RELATIONAL_NAME_HXX