From d72e5f95e70976f9b8bc29a7ace3c354e815ca49 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 12 Aug 2020 13:54:21 +0200 Subject: Add int64 and int64s variable types --- doc/manual.cli | 3 +++ libbuild2/parser.cxx | 2 ++ libbuild2/types.hxx | 2 ++ libbuild2/variable.cxx | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ libbuild2/variable.hxx | 36 ++++++++++++++++++++++++++++++++++-- libbuild2/variable.ixx | 28 ++++++++++++++++++++++++++++ 6 files changed, 118 insertions(+), 2 deletions(-) diff --git a/doc/manual.cli b/doc/manual.cli index 03dc180..d3ee659 100644 --- a/doc/manual.cli +++ b/doc/manual.cli @@ -5497,6 +5497,9 @@ The following variable/value types can currently be used in \c{buildfiles}: \ bool +int64 +int64s + uint64 uint64s diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index cda4c69..8ae13a8 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -3797,6 +3797,7 @@ namespace build2 return n == "bool" ? ptr (value_traits::value_type) : + n == "int64" ? ptr (value_traits::value_type) : n == "uint64" ? ptr (value_traits::value_type) : n == "string" ? ptr (value_traits::value_type) : n == "path" ? ptr (value_traits::value_type) : @@ -3807,6 +3808,7 @@ namespace build2 n == "target_triplet" ? ptr (value_traits::value_type) : n == "project_name" ? ptr (value_traits::value_type) : + n == "int64s" ? ptr (value_traits::value_type) : n == "uint64s" ? ptr (value_traits::value_type) : n == "strings" ? ptr (value_traits::value_type) : n == "paths" ? ptr (value_traits::value_type) : diff --git a/libbuild2/types.hxx b/libbuild2/types.hxx index 65e0918..dcf1a30 100644 --- a/libbuild2/types.hxx +++ b/libbuild2/types.hxx @@ -65,9 +65,11 @@ namespace build2 using std::uint8_t; using std::uint16_t; using std::uint32_t; + using std::int64_t; using std::uint64_t; using std::uintptr_t; + using int64s = std::vector; using uint64s = std::vector; using std::size_t; diff --git a/libbuild2/variable.cxx b/libbuild2/variable.cxx index 79d0018..a4c3ef3 100644 --- a/libbuild2/variable.cxx +++ b/libbuild2/variable.cxx @@ -480,6 +480,54 @@ namespace build2 nullptr // Never empty. }; + // int64_t value + // + int64_t value_traits:: + convert (const name& n, const name* r) + { + if (r == nullptr && n.simple ()) + { + try + { + // May throw invalid_argument or out_of_range. + // + size_t i; + int64_t r (stoll (n.value, &i)); + + if (i == n.value.size ()) + return r; + + // Fall through. + } + catch (const std::exception&) + { + // Fall through. + } + } + + throw_invalid_argument (n, r, "int64"); + } + + const char* const value_traits::type_name = "int64"; + + const value_type value_traits::value_type + { + type_name, + sizeof (int64_t), + nullptr, // No base. + nullptr, // No element. + nullptr, // No dtor (POD). + nullptr, // No copy_ctor (POD). + nullptr, // No copy_assign (POD). + &simple_assign, + &simple_append, + &simple_append, // Prepend same as append. + &simple_reverse, + nullptr, // No cast (cast data_ directly). + nullptr, // No compare (compare as POD). + nullptr // Never empty. + }; + // uint64_t value // uint64_t value_traits:: @@ -1759,6 +1807,7 @@ namespace build2 template struct LIBBUILD2_DEFEXPORT value_traits>; template struct LIBBUILD2_DEFEXPORT value_traits; template struct LIBBUILD2_DEFEXPORT value_traits; + template struct LIBBUILD2_DEFEXPORT value_traits; template struct LIBBUILD2_DEFEXPORT value_traits; template struct LIBBUILD2_DEFEXPORT diff --git a/libbuild2/variable.hxx b/libbuild2/variable.hxx index 99eb3aa..6c78c95 100644 --- a/libbuild2/variable.hxx +++ b/libbuild2/variable.hxx @@ -710,6 +710,30 @@ namespace build2 static const build2::value_type value_type; }; + // int64_t + // + template <> + struct LIBBUILD2_SYMEXPORT value_traits + { + static_assert (sizeof (int64_t) <= value::size_, "insufficient space"); + + // Note: in some places we rely on the convert() function not changing + // the passed names thus we make them const. + // + static int64_t convert (const name&, const name*); + static void assign (value&, int64_t); + static void append (value&, int64_t); // ADD. + static name reverse (int64_t x) {return name (to_string (x));} + static int compare (int64_t, int64_t); + static bool empty (bool) {return false;} + + static const bool empty_value = false; + static const char* const type_name; + static const build2::value_type value_type; + }; + + // uint64_t + // template <> struct LIBBUILD2_SYMEXPORT value_traits { @@ -730,13 +754,20 @@ namespace build2 static const build2::value_type value_type; }; - // Treat unsigned integral types as uint64. Note that bool is handled - // differently at an earlier stage. + // Treat signed/unsigned integral types as int64/uint64. Note that bool is + // handled differently at an earlier stage. // template struct value_traits_specialization::value && + std::is_signed::value>::type>: + value_traits {}; + + template + struct value_traits_specialization::value && std::is_unsigned::value>::type>: value_traits {}; @@ -1055,6 +1086,7 @@ namespace build2 extern template struct LIBBUILD2_DECEXPORT value_traits>; extern template struct LIBBUILD2_DECEXPORT value_traits; extern template struct LIBBUILD2_DECEXPORT value_traits; + extern template struct LIBBUILD2_DECEXPORT value_traits; extern template struct LIBBUILD2_DECEXPORT value_traits; extern template struct LIBBUILD2_DECEXPORT diff --git a/libbuild2/variable.ixx b/libbuild2/variable.ixx index 84bf20c..a11ee12 100644 --- a/libbuild2/variable.ixx +++ b/libbuild2/variable.ixx @@ -368,6 +368,34 @@ namespace build2 return l < r ? -1 : (l > r ? 1 : 0); } + // int64_t value + // + inline void value_traits:: + assign (value& v, int64_t x) + { + if (v) + v.as () = x; + else + new (&v.data_) int64_t (x); + } + + inline void value_traits:: + append (value& v, int64_t x) + { + // ADD. + // + if (v) + v.as () += x; + else + new (&v.data_) int64_t (x); + } + + inline int value_traits:: + compare (int64_t l, int64_t r) + { + return l < r ? -1 : (l > r ? 1 : 0); + } + // uint64_t value // inline void value_traits:: -- cgit v1.1