message: span: add lifetimebound attribute
  See for
  reference.
  This helps to guard against dangling references caused by construction from
  temporaries such as:
  Span<const int> sp(std::vector<int>{1,2,3});
diff: #define ASSERT_IF_DEBUG(x)
  #endif
  +#if defined(__clang__)
  +#if __has_attribute(lifetimebound)
  +#define SPAN_ATTR_LIFETIMEBOUND [[clang::lifetimebound]]
  +#else
  +#define SPAN_ATTR_LIFETIMEBOUND
  +#endif
  +#else
  +#define SPAN_ATTR_LIFETIMEBOUND
  +#endif
  +
  /** A Span is an object that can refer to a contiguous sequence of objects.
  *
  * It implements a subset of C++20's std::span.
  @@ -143,14 +153,14 @@ public:
  * Note that this restriction does not exist when converting arrays or other Spans (see above).
  */
  template <typename V>
  - constexpr Span(V& other,
  + constexpr Span(V& other SPAN_ATTR_LIFETIMEBOUND,
  typename std::enable_if<!is_Span<V>::value &&
  std::is_convertible<typename std::remove_pointer<decltype(std::declval<V&>().data())>::type (*)[], C (*)[]>::value &&
  std::is_convertible<decltype(std::declval<V&>().size()), std::size_t>::value, std::nullptr_t>::type = nullptr)
  : m_data(other.data()), m_size(other.size()){}
  template <typename V>
  - constexpr Span(const V& other,
  + constexpr Span(const V& other SPAN_ATTR_LIFETIMEBOUND,
  typename std::enable_if<!is_Span<V>::value &&
  std::is_convertible<typename std::remove_pointer<decltype(std::declval<const V&>().data())>::type (*)[], C (*)[]>::value &&
  std::is_convertible<decltype(std::declval<const V&>().size()), std::size_t>::value, std::nullptr_t>::type = nullptr)
  @@ -211,9 +221,9 @@ public:
  /** MakeSpan for arrays: */
  template <typename A, int N> Span<A> constexpr MakeSpan(A (&a)[N]) { return Span<A>(a, N); }
  /** MakeSpan for temporaries / rvalue references, only supporting const output. */
  -template <typename V> constexpr auto MakeSpan(V&& v) -> typename std::enable_if<!std::is_lvalue_reference<V>::value, Span<const typename std::remove_pointer<decltype(v.data())>::type>>::type { return std::forward<V>(v); }
  +template <typename V> constexpr auto MakeSpan(V&& v SPAN_ATTR_LIFETIMEBOUND) -> typename std::enable_if<!std::is_lvalue_reference<V>::value, Span<const typename std::remove_pointer<decltype(v.data())>::type>>::type { return std::forward<V>(v); }
  /** MakeSpan for (lvalue) references, supporting mutable output. */
  -template <typename V> constexpr auto MakeSpan(V& v) -> Span<typename std::remove_pointer<decltype(v.data())>::type> { return v; }
  +template <typename V> constexpr auto MakeSpan(V& v SPAN_ATTR_LIFETIMEBOUND) -> Span<typename std::remove_pointer<decltype(v.data())>::type> { return v; }
  /** Pop the last element off a span, and return a reference to that element. */
  template <typename T>
  