Merge branch 'master' into dev/neilmac/contracts
diff --git a/include/span.h b/include/span.h
index 96a7901..0c67d22 100644
--- a/include/span.h
+++ b/include/span.h
@@ -1275,7 +1275,7 @@
         && std::is_convertible<DataType (*)[], value_type (*)[]>::value
         && std::is_same<std::decay_t<decltype(std::declval<Cont>().size(), *std::declval<Cont>().data())>, DataType>::value>
     >
-    constexpr span (Cont& cont) : span(static_cast<pointer>(cont.data()), details::newBoundsHelper<bounds_type>(cont.size()))
+    constexpr span (Cont& cont) : span(static_cast<pointer>(cont.data()), details::newBoundsHelper<bounds_type>(static_cast<size_type>(cont.size())))
     {}
 
     constexpr span(const span &) = default;
@@ -1443,7 +1443,7 @@
         return m_pdata;
     }
 
-    constexpr operator bool() const noexcept
+    constexpr explicit operator bool() const noexcept
     {
         return m_pdata != nullptr;
     }
@@ -1577,6 +1577,14 @@
 constexpr auto as_span(Cont &&arr) -> std::enable_if_t<!details::is_span<std::decay_t<Cont>>::value,
     span<std::remove_reference_t<decltype(arr.size(), *arr.data())>, dynamic_range>> = delete;
 
+// from basic_string which doesn't have nonconst .data() member like other contiguous containers
+template <typename CharT, typename Traits, typename Allocator>
+constexpr auto as_span(std::basic_string<CharT, Traits, Allocator> &str) -> span<CharT, dynamic_range>
+{
+    Expects(str.size() < PTRDIFF_MAX);
+    return {&str[0], static_cast<std::ptrdiff_t>(str.size())};
+}
+
 template <typename ValueType, size_t Rank>
 class strided_span
 {
@@ -1621,8 +1629,12 @@
     {}
 
     // from array view
-    template <std::ptrdiff_t... Dimensions, typename Dummy = std::enable_if<sizeof...(Dimensions) == Rank>>
-    constexpr strided_span(span<ValueType, Dimensions...> av, bounds_type bounds) : strided_span(av.data(), av.bounds().total_size(), std::move(bounds))
+    template <typename OtherValueType, std::ptrdiff_t... Dimensions,
+        bool Enabled1 = (sizeof...(Dimensions) == Rank),
+        bool Enabled2 = std::is_convertible<OtherValueType*, ValueType*>::value,
+        typename Dummy = std::enable_if_t<Enabled1 && Enabled2>
+    >
+    constexpr strided_span(span<OtherValueType, Dimensions...> av, bounds_type bounds) : strided_span(av.data(), av.bounds().total_size(), std::move(bounds))
     {}
     
     // convertible
@@ -1688,7 +1700,7 @@
         return m_pdata;
     }
 
-    constexpr operator bool() const noexcept
+    constexpr explicit operator bool() const noexcept
     {
         return m_pdata != nullptr;
     }
diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp
index 8a7c552..e5078af 100644
--- a/tests/span_tests.cpp
+++ b/tests/span_tests.cpp
@@ -204,6 +204,15 @@
 		}
 
 		{
+			string str;
+			span<char> strspan = as_span(str);
+			(void)strspan;
+			const string cstr;
+			span<const char> cstrspan = as_span(cstr);
+			(void)cstrspan;
+		}
+
+		{
 			int a[3][4][5];
 			auto av = as_span(a);
 			const int (*b)[4][5];
@@ -333,7 +342,7 @@
 				CHECK(sav_c[1] == 2);
 
 #if _MSC_VER > 1800
-				strided_span<volatile int, 1> sav_v{ {src}, {2, 1} };
+				strided_span<volatile int, 1> sav_v{ src, {2, 1} };
 #else
 				strided_span<volatile int, 1> sav_v{ span<volatile int>{src}, strided_bounds<1>{2, 1} };
 #endif
@@ -342,7 +351,7 @@
 				CHECK(sav_v[1] == 2);
 
 #if _MSC_VER > 1800
-				strided_span<const volatile int, 1> sav_cv{ {src}, {2, 1} };
+				strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
 #else
 				strided_span<const volatile int, 1> sav_cv{ span<const volatile int>{src}, strided_bounds<1>{2, 1} };
 #endif
@@ -361,7 +370,7 @@
 				CHECK(sav_c[1] == 2);
 
 #if _MSC_VER > 1800
-				strided_span<const volatile int, 1> sav_cv{ {src}, {2, 1} };
+				strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
 #else
 				strided_span<const volatile int, 1> sav_cv{ span<const volatile int>{src}, strided_bounds<1>{2, 1} };
 #endif
@@ -381,7 +390,7 @@
 				CHECK(sav_v[1] == 2);
 
 #if _MSC_VER > 1800
-				strided_span<const volatile int, 1> sav_cv{ {src}, {2, 1} };
+				strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
 #else
 				strided_span<const volatile int, 1> sav_cv{ span<const volatile int>{src}, strided_bounds<1>{2, 1} };
 #endif