aboutsummaryrefslogtreecommitdiff
path: root/build2/name
diff options
context:
space:
mode:
Diffstat (limited to 'build2/name')
-rw-r--r--build2/name113
1 files changed, 113 insertions, 0 deletions
diff --git a/build2/name b/build2/name
new file mode 100644
index 0000000..a0672c7
--- /dev/null
+++ b/build2/name
@@ -0,0 +1,113 @@
+// file : build2/name -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BUILD2_NAME
+#define BUILD2_NAME
+
+#include <string>
+#include <vector>
+#include <iosfwd>
+#include <utility> // move()
+
+#include <butl/path>
+
+// Note: include <build2/types> instead of this file directly.
+//
+namespace build2
+{
+ using butl::dir_path;
+
+ // A name is what we operate on by default. Depending on the context,
+ // it can be interpreted as a target or prerequisite name. A name
+ // without a type and directory can be used to represent any text.
+ // A name with directory and empty value represents a directory.
+ // A name may also be project-qualified. If the project name is
+ // empty, then it means the name is in a project other than our
+ // own (e.g., it is installed).
+ //
+ // If pair is not '\0', then this name and the next in the list
+ // form a pair.
+ //
+ struct name
+ {
+ name () = default;
+
+ explicit name (std::string v): value (std::move (v)) {}
+ name& operator= (std::string v) {return *this = name (std::move (v));}
+
+ explicit name (dir_path d): dir (std::move (d)) {}
+ name& operator= (dir_path d) {return *this = name (std::move (d));}
+
+ name (std::string t, std::string v)
+ : type (std::move (t)), value (std::move (v)) {}
+
+ name (dir_path d, std::string t, std::string v)
+ : dir (std::move (d)), type (std::move (t)), value (std::move (v)) {}
+
+ // The first argument should be from project_name_pool.
+ //
+ name (const std::string* p, dir_path d, std::string t, std::string v)
+ : proj (p),
+ dir (std::move (d)),
+ type (std::move (t)),
+ value (std::move (v)) {}
+
+ bool
+ qualified () const {return proj != nullptr;}
+
+ bool
+ unqualified () const {return proj == nullptr;}
+
+ bool
+ typed () const {return !type.empty ();}
+
+ bool
+ untyped () const {return type.empty ();}
+
+ bool
+ empty () const {return dir.empty () && value.empty ();}
+
+ // Note that strictly speaking the following tests should be
+ // orthogonal to qualification. However, the vast majority of
+ // cases where we expect a simple or directory name, we also
+ // expect it to be unqualified.
+ //
+ // Note also that empty name is simple but not a directory.
+ //
+ bool
+ simple () const {return unqualified () && untyped () && dir.empty ();}
+
+ bool
+ directory () const
+ {return unqualified () && untyped () && !dir.empty () && value.empty ();}
+
+ const std::string* proj = nullptr; // Points to project_name_pool.
+ dir_path dir;
+ std::string type;
+ std::string value;
+ char pair = '\0'; // Pair symbol, if any.
+ };
+
+ inline bool
+ operator== (const name& x, const name& y)
+ {
+ return x.proj == y.proj && // Pooled, so can just compare pointers.
+ x.type == y.type &&
+ x.dir == y.dir &&
+ x.value == y.value;
+ }
+
+ inline bool
+ operator!= (const name& x, const name& y) {return !(x == y);}
+
+ typedef std::vector<name> names;
+
+ std::ostream&
+ operator<< (std::ostream&, const name&);
+
+ std::ostream&
+ operator<< (std::ostream&, const names&);
+}
+
+#endif // BUILD2_NAME