Checking in to continue working elsewhere.
diff --git a/include/span.h b/include/span.h
index 38cf9f5..4983295 100644
--- a/include/span.h
+++ b/include/span.h
@@ -94,20 +94,22 @@
     constexpr static const index_type extent = Extent;
 
     // [span.cons], span constructors, copy, assignment, and destructor 
-    constexpr span() noexcept : data_(nullptr), size_(0)
-    { static_assert(extent == dynamic_extent || extent == 0, "Cannot default initialize a fixed-length span."); }
+    constexpr span() noexcept : storage_(nullptr, extent_type<0>())
+    {}
 
     constexpr span(nullptr_t) noexcept : span()
     {}
 
-    constexpr span(pointer ptr, index_type count) : data_(ptr), size_(count)
-    { Expects(((!ptr && count == 0) || (ptr && count >= 0)) && (extent == dynamic_extent || extent == count)); }
+    constexpr span(pointer ptr, index_type count) : storage_(ptr, count)
+    { Expects(((!ptr && count == 0) || (ptr && count >= 0))); }
 
-    constexpr span(pointer firstElem, pointer lastElem) : data_(firstElem), size_(std::distance(firstElem, lastElem))
-    { Expects(size_ >= 0 && (extent == dynamic_extent || extent == size_)); }
+    constexpr span(pointer firstElem, pointer lastElem)
+        : storage_(firstElem, std::distance(firstElem, lastElem))
+    {}
     
     template <size_t N>
-    constexpr span(element_type(&arr)[N]) {}
+    constexpr span(element_type(&arr)[N]) : storage_(&arr[0], extent_type<N>())
+    {}
 
 #if 0 // TODO
     template <size_t N>
@@ -141,7 +143,7 @@
 #endif
     // [span.obs], span observers 
     constexpr index_type length() const noexcept { return size(); }
-    constexpr index_type size() const noexcept { return size_;  }
+    constexpr index_type size() const noexcept { return storage_.size();  }
     constexpr index_type length_bytes() const noexcept { return size_bytes(); }
     constexpr index_type size_bytes() const noexcept { return size() * sizeof(element_type); }
     constexpr bool empty() const noexcept { return size() == 0; }
@@ -149,11 +151,11 @@
     // [span.elem], span element access 
     constexpr reference operator[](index_type idx) const
     {
-        Expects(idx >= 0 && idx < size_);
-        return data_[idx];
+        Expects(idx >= 0 && idx < storage_.size());
+        return storage_.data()[idx];
     }
     constexpr reference operator()(index_type idx) const { return this->operator[](idx); }
-    constexpr pointer data() const noexcept { return data_; }
+    constexpr pointer data() const noexcept { return storage_.data(); }
 #if 0 // TODO
     // [span.iter], span iterator support 
     iterator begin() const noexcept;
@@ -169,8 +171,70 @@
     const_reverse_iterator crend() const noexcept;
 #endif
 private:
-    pointer data_;
-    index_type size_;
+    template <index_type Extent>
+    class extent_type;
+    
+    template <index_type Extent>
+    class extent_type
+    {
+    public:
+        static_assert(Extent >= 0, "A fixed-size span must be >= 0 in size.");
+
+        constexpr extent_type() noexcept {}
+
+        template <index_type Other>
+        constexpr extent_type(extent_type<Other>) noexcept
+        {
+            static_assert(Other == Extent,
+                "Mismatch between fixed-size extent and size of initializing data.");
+        }
+
+        constexpr extent_type(index_type size)
+        { Expects(size == Extent); }
+
+        constexpr inline index_type size() const noexcept { return Extent; }
+    };
+
+    template <>
+    class extent_type<dynamic_extent>
+    {
+    public:
+        template <index_type Other>
+        explicit constexpr extent_type(extent_type<Other> ext) : size_(ext.size())
+        {}
+
+        explicit constexpr extent_type(index_type size) : size_(size)
+        { Expects(size >= 0); } 
+
+        constexpr inline index_type size() const noexcept
+        { return size_; }
+
+    private:
+        index_type size_;
+    };
+
+    // this implementation detail class lets us take advantage of the 
+    // empty base class optimization to pay for only storage of a single
+    // pointer in the case of fixed-size spans
+    template <class ExtentType>
+    class storage_type : public ExtentType
+    {
+    public:
+        template <class OtherExtentType>
+        storage_type(pointer data, OtherExtentType ext)
+            : ExtentType(ext), data_(data) {}
+
+        //storage_type(pointer data, ExtentType ext)
+        //    : ExtentType(ext), data_(data) {}
+        
+        constexpr inline pointer data() const noexcept
+        { return data_; }
+
+    private:
+        pointer data_;
+    };
+
+    storage_type<extent_type<Extent>> storage_;
 };