From 9fb791e9fad6c63fc1dac49f4d05ae63b8a3db9b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 5 Jan 2016 11:55:15 +0200 Subject: Rename build directory/namespace to build2 --- build2/variable.ixx | 398 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 build2/variable.ixx (limited to 'build2/variable.ixx') diff --git a/build2/variable.ixx b/build2/variable.ixx new file mode 100644 index 0000000..2933deb --- /dev/null +++ b/build2/variable.ixx @@ -0,0 +1,398 @@ +// file : build2/variable.ixx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +namespace build2 +{ + // value + // + template + inline void + assign (value& v, const variable& var) + { + auto t (&value_traits::value_type); + + if (v.type != t) + assign (v, t, var); + } + + template + inline typename value_traits::type + as (value& v) + { + return value_traits::as (v); + } + + template + inline typename value_traits::const_type + as (const value& v) + { + return value_traits::as (v); + } + + template + inline bool + assign (name& n) + { + return value_traits::assign (n); + } + + template + inline typename value_traits::type + as (name& n) + { + return value_traits::as (n); + } + + template + inline typename value_traits::const_type + as (const name& n) + { + return value_traits::as (n); + } + + template + inline value& value:: + operator= (T v) + { + value_traits::assign (*this, std::move (v)); + return *this; + } + + template + inline value& value:: + operator+= (T v) + { + value_traits::append (*this, std::move (v)); + return *this; + } + + inline void value:: + assign (names v, const variable& var) + { + data_ = std::move (v); + state_ = (type != nullptr && type->assign != nullptr + ? type->assign (data_, var) + : !data_.empty ()) + ? state_type::filled + : state_type::empty; + } + + // bool value + // + inline bool_value value_traits:: + as (value& v) + { + assert (v.type == bool_type); + return bool_value (v.data_.front ()); + } + + inline bool_value value_traits:: + as (const value& v) + { + assert (v.type == bool_type); + return bool_value (v.data_.front ()); + } + + inline void value_traits:: + assign (value& v, bool x) + { + if (v.null ()) + { + if (v.type == nullptr) + v.type = bool_type; + v.data_.emplace_back (name ()); + v.state_ = value::state_type::empty; + } + + as (v) = x; + v.state_ = value::state_type::filled; + } + + inline void value_traits:: + append (value& v, bool x) + { + if (v.null ()) + assign (v, x); + else + as (v) += x; // Cannot be empty. + } + + // string value + // + inline std::string& value_traits:: + as (value& v) + { + assert (v.type == string_type); + return v.data_.front ().value; + } + + inline const std::string& value_traits:: + as (const value& v) + { + assert (v.type == string_type); + return v.data_.front ().value; + } + + inline void value_traits:: + assign (value& v, std::string x) + { + if (v.null ()) + { + if (v.type == nullptr) + v.type = string_type; + v.data_.emplace_back (name ()); + v.state_ = value::state_type::empty; + } + + v.state_ = (as (v) = std::move (x)).empty () + ? value::state_type::empty + : value::state_type::filled; + } + + inline void value_traits:: + append (value& v, std::string x) + { + if (v.null ()) + assign (v, std::move (x)); + else + v.state_ = (as (v) += std::move (x)).empty () + ? value::state_type::empty + : value::state_type::filled; + } + + // dir_path value + // + inline dir_path& value_traits:: + as (value& v) + { + assert (v.type == dir_path_type); + return v.data_.front ().dir; + } + + inline const dir_path& value_traits:: + as (const value& v) + { + assert (v.type == dir_path_type); + return v.data_.front ().dir; + } + + inline void value_traits:: + assign (value& v, dir_path x) + { + if (v.null ()) + { + if (v.type == nullptr) + v.type = dir_path_type; + v.data_.emplace_back (name ()); + v.state_ = value::state_type::empty; + } + + v.state_ = (as (v) = std::move (x)).empty () + ? value::state_type::empty + : value::state_type::filled; + } + + inline void value_traits:: + append (value& v, dir_path x) + { + if (v.null ()) + assign (v, std::move (x)); + else + v.state_ = (as (v) /= std::move (x)).empty () + ? value::state_type::empty + : value::state_type::filled; + } + + // name value + // + inline name& value_traits:: + as (value& v) + { + assert (v.type == name_type); + return v.data_.front (); + } + + inline const name& value_traits:: + as (const value& v) + { + assert (v.type == name_type); + return v.data_.front (); + } + + inline void value_traits:: + assign (value& v, name x) + { + if (v.null ()) + { + if (v.type == nullptr) + v.type = name_type; + v.data_.emplace_back (name ()); + v.state_ = value::state_type::empty; + } + + v.state_ = (as (v) = std::move (x)).empty () + ? value::state_type::empty + : value::state_type::filled; + } + + // vector value + // + template + inline vector_value& vector_value:: + assign (std::vector v) + { + d->clear (); + d->insert (d->end (), + std::make_move_iterator (v.begin ()), + std::make_move_iterator (v.end ())); + return *this; + } + + template + template + inline vector_value& vector_value:: + assign (const vector_value& v) + { + d->clear (); + d->insert (d->end (), v.begin (), v.end ()); + return *this; + } + + template + template + inline vector_value& vector_value:: + append (const vector_value& v) + { + d->insert (d->end (), v.begin (), v.end ()); + return *this; + } + + template + inline vector_value value_traits>:: + as (value& v) + { + assert (v.type == &value_traits>::value_type); + return vector_value (v.data_); + } + + template + inline vector_value value_traits>:: + as (const value& v) + { + assert (v.type == &value_traits>::value_type); + return vector_value (v.data_); + } + + template + template + inline void value_traits>:: + assign (value& v, V x) + { + if (v.null ()) + { + if (v.type == nullptr) + v.type = &value_traits>::value_type; + v.state_ = value::state_type::empty; + } + + v.state_ = (as (v).assign (std::move (x))).empty () + ? value::state_type::empty + : value::state_type::filled; + } + + template + template + inline void value_traits>:: + append (value& v, V x) + { + if (v.null ()) + assign (v, std::move (x)); + else + v.state_ = (as (v).append (std::move (x))).empty () + ? value::state_type::empty + : value::state_type::filled; + } + + // map value + // + template + inline map_value value_traits>:: + as (value& v) + { + assert ((v.type == &value_traits>::value_type)); + return map_value (v.data_); + } + + template + inline map_value value_traits>:: + as (const value& v) + { + assert ((v.type == &value_traits>::value_type)); + return map_value (v.data_); + } + + template + template + inline void value_traits>:: + assign (value& v, M x) + { + if (v.null ()) + { + if (v.type == nullptr) + v.type = &value_traits>::value_type; + v.state_ = value::state_type::empty; + } + + v.state_ = (as (v).assign (std::move (x))).empty () + ? value::state_type::empty + : value::state_type::filled; + } + + template + template + inline void value_traits>:: + append (value& v, M x) + { + if (v.null ()) + assign (v, std::move (x)); + else + v.state_ = (as (v).append (std::move (x))).empty () + ? value::state_type::empty + : value::state_type::filled; + } + + // variable_map::iterator_adapter + // + template + inline typename I::reference variable_map::iterator_adapter:: + operator* () const + { + auto& r (I::operator* ()); + const variable& var (r.first); + auto& val (r.second); + + // First access after being assigned a type? + // + if (var.type != nullptr && val.type != var.type) + build2::assign (const_cast (val), var.type, var); + + return r; + } + + template + inline typename I::pointer variable_map::iterator_adapter:: + operator-> () const + { + auto p (I::operator-> ()); + const variable& var (p->first); + auto& val (p->second); + + // First access after being assigned a type? + // + if (var.type != nullptr && val.type != var.type) + build2::assign (const_cast (val), var.type, var); + + return p; + } +} -- cgit v1.1