title: Where exactly does my code not adhere to the specification of the key and value type?
body: <blockquote>
    <p><strong>Task Description</strong></p>
    
    <p><code>interval_map&lt;K,V&gt;</code> is a data structure that efficiently associates intervals of keys of type K with values of type V. Your task is to implement the assign member function of this data structure, which is outlined below.</p>
    
    <p><code>interval_map&lt;K, V&gt;</code> is implemented on top of <code>std::map</code>. In case you are not entirely sure which functions <code>std::map</code> provides, what they do and which guarantees they provide, we provide an excerpt of the C++ standard here. (at the end)</p>
    
    <p>Each key-value-pair (k,v) in the <code>std::map</code> means that the value v is associated with the interval from k (including) to the next key (excluding) in the <code>std::map</code>.</p>
    
    <p>Example: the <code>std::map (0,'A'), (3,'B'), (5,'A')</code> represents the mapping</p>
    
    <ul>
    <li>0 -> 'A'</li>
    <li>1 -> 'A'</li>
    <li>2 -> 'A'</li>
    <li>3 -> 'B'</li>
    <li>4 -> 'B'</li>
    <li>5 -> 'A'</li>
    <li>6 -> 'A'</li>
    <li>7 -> 'A'</li>
    </ul>
    
    <p>... all the way to <code>numeric_limits&lt;int&gt;::max()</code></p>
    
    <p>The representation in the <code>std::map</code> must be canonical, that is, consecutive map entries must not have the same value: <code>..., (0,'A'), (3,'A'), ...</code> is not allowed. Initially, the whole range of K is associated with a given initial value, passed to the constructor of the interval_map data structure.</p>
  </blockquote>
  
  <p>Here's my implementation of <code>assign()</code>: (rest of the code comes by default). </p>
  
  <pre><code>#include &lt;map&gt;
  #include &lt;limits&gt;
  
  template&lt;typename K, typename V&gt;
  class interval_map {
      std::map&lt;K,V&gt; m_map;
  
  public:
    // constructor associates whole range of K with val by inserting (K_min, val)
    // into the map
    interval_map( V const&amp; val) {
        m_map.insert(m_map.end(),std::make_pair(std::numeric_limits&lt;K&gt;::lowest(),val));
    }
  
    // Assign value val to interval [keyBegin, keyEnd).
    // Overwrite previous values in this interval.
    // Conforming to the C++ Standard Library conventions, the interval
    // includes keyBegin, but excludes keyEnd.
    // If !( keyBegin &lt; keyEnd ), this designates an empty interval,
    // and assign must do nothing.
    void assign( K const&amp; keyBegin, K const&amp; keyEnd, V const&amp; val ) {
  
          // insert code here   
          if (!(keyBegin &lt; keyEnd)) return;
  
          std::pair&lt;K,V&gt; beginExtra;
          std::pair&lt;K,V&gt; endExtra;
          bool beginHasExtra = false;
          bool endHasExtra = false;
  
          typename std::map&lt;K,V&gt;::iterator itBegin;
          itBegin = m_map.lower_bound(keyBegin);
          if ( itBegin!=m_map.end() &amp;&amp; keyBegin &lt; itBegin-&gt;first ) {
              if (itBegin != m_map.begin()) {
                  beginHasExtra = true;
                  --itBegin;
                  beginExtra = std::make_pair(itBegin-&gt;first, itBegin-&gt;second);
              }
              // openRange for erase is prevIterator
              // insert (prevIterator-&gt;first, prevIterator-&gt;second) as well!
          }
  
          typename std::map&lt;K,V&gt;::iterator itEnd;
          itEnd = m_map.lower_bound(keyEnd);
          if ( itEnd!=m_map.end() &amp;&amp; keyEnd &lt; itEnd-&gt;first ) {
              endHasExtra = true;
              typename std::map&lt;K,V&gt;::iterator extraIt = itEnd;
              --extraIt;
              endExtra = std::make_pair(keyEnd, extraIt-&gt;second);
              // closeRange for erase is this iterator
              // insert (keyEnd, prevIterator-&gt;second) as well!
          }
  
          // 4 canonical conflicts:
          //   beginExtra w/ mid
          //   before-mid w/ mid (beginHasExtra==false)
          //   mid w/ endExtra
          //   mid w/ after-mid (endHasExtra==false)
  
          bool insertMid = true;
          if (beginHasExtra) {
              if (beginExtra.second == val)
                  insertMid = false;
          } else {
              if (itBegin != m_map.begin()) {
                  typename std::map&lt;K,V&gt;::iterator beforeMid = itBegin;
                  --beforeMid;
                  if (beforeMid-&gt;second == val)
                      insertMid = false;
              }
          }
  
  
          if (endHasExtra) {
              if ( (insertMid &amp;&amp; endExtra.second == val) || (!insertMid &amp;&amp; endExtra.second == beginExtra.second) )
                  endHasExtra = false;
          } else {
              if ( (insertMid &amp;&amp; itEnd!=m_map.end() &amp;&amp; itEnd-&gt;second == val) || (!insertMid &amp;&amp; itEnd!=m_map.end() &amp;&amp; itEnd-&gt;second == beginExtra.second) )
                  itEnd = m_map.erase(itEnd);
          }
  
          itBegin = m_map.erase(itBegin, itEnd);
          if (beginHasExtra)
              itBegin = m_map.insert(itBegin, beginExtra);
          if (insertMid)
              itBegin = m_map.insert(itBegin, std::make_pair(keyBegin, val));
          if (endHasExtra)
              m_map.insert(itBegin, endExtra);
    }
  
    // look-up of the value associated with key
    V const&amp; operator[]( K const&amp; key ) const {
        return ( --m_map.upper_bound(key) )-&gt;second;
    }
  };
  </code></pre>
  
  <blockquote>
    <p><strong>Key type</strong> </p>
    
    <p>K</p>
    
    <ul>
    <li>besides being copyable and assignable, is less-than comparable via operator&lt;</li>
    <li>is bounded below, with the lowest value being std::numeric_limits::lowest()</li>
    <li>does not implement any other operations, in particular no equality comparison or arithmetic operators</li>
    </ul>
    
    <p><strong>Value type</strong></p>
    
    <p>V</p>
    
    <ul>
    <li>besides being copyable and assignable, is equality-comparable via operator==</li>
    <li>does not implement any other operations</li>
    </ul>
  </blockquote>
  
  <p><strong>===========================================================================</strong></p>
  
  <p>This code works perfectly fine on my local machine. However after submitting the code I got <code>You must adhere to the specification of the key and value type given above.</code> Can anyone tell me what I did wrong? I know I should've used <code>const_iterator</code> for my iterators but the error is talking about <code>K, V</code>. </p>
  
  <p><strong>===========================================================================</strong></p>
  
  <pre><code>The following paragraphs from the final draft of the C++1x ISO standard describe the available 
  operations on a std::map container, their effects and their complexity.
  
  23.2.1 General container requirements 
  
  §1 Containers are objects that store other objects. They control allocation and deallocation of 
  these objects through constructors, destructors, insert and erase operations.
  
  §6 begin() returns an iterator referring to the first element in the container. end() returns 
  an iterator which is the past-the-end value for the container. If the container is empty, 
  then begin() == end();
  
  24.2.1 General Iterator Requirements
  
  §1 Iterators are a generalization of pointers that allow a C++ program to work with different 
  data structures.
  
  §2 Since iterators are an abstraction of pointers, their semantics is a generalization of most 
  of the semantics of pointers in C++. This ensures that every function template that takes 
  iterators works as well with regular pointers.
  
  §5 Just as a regular pointer to an array guarantees that there is a pointer value pointing past 
  the last element of the array, so for any iterator type there is an iterator value that points 
  past the last element of a corresponding sequence. These values are called past-the-end values. 
  Values of an iterator i for which the expression *i is defined are called dereferenceable. 
  The library never assumes that past-the-end values are dereferenceable. Iterators can also have 
  singular values that are not associated with any sequence. [ Example: After the declaration of 
  an uninitialized pointer x (as with int* x;), x  must always be assumed to have a singular 
  value of a pointer. -end example ] Results of most expressions are undefined for singular 
  values; the only exceptions are destroying an iterator that holds a singular value, the 
  assignment of a non-singular value to an iterator that holds a singular value, and, for 
  iterators that satisfy the DefaultConstructible requirements, using a value-initialized 
  iterator as the source of a copy or move operation.
  
  §10 An invalid iterator is an iterator that may be singular. (This definition applies to 
  pointers, since pointers are iterators. The effect of dereferencing an iterator that has been 
  invalidated is undefined.)
  
  23.2.4 Associative containers
  
  §1 Associative containers provide fast retrieval of data based on keys. The library provides 
  four basic kinds of associative containers: set, multiset, map and multimap.
  
  §4 An associative container supports unique keys if it may contain at most one element for each 
  key. Otherwise, it supports equivalent keys. The set and map classes support unique keys; the 
  multiset and multimap classes support equivalent keys.
  
  §5 For map and multimap the value type is equal to std::pair&lt;const Key, T&gt;. Keys in an 
  associative container are immutable.
  
  §6 iterator of an associative container is of the bidirectional iterator category.
  (i.e., an iterator i can be incremented and decremented: ++i; --i;)
  
  §9 The insert member functions (see below) shall not affect the validity of iterators and 
  references to the container, and the erase members shall invalidate only iterators and 
  references to the erased elements.
  
  §10 The fundamental property of iterators of associative containers is that they iterate 
  through the containers in the non-descending order of keys where non-descending is defined by 
  the comparison that was used to construct them.
  
  Associative container requirements (in addition to general container requirements):
  
  std::pair&lt;iterator, bool&gt; insert(std::pair&lt;const key_type, T&gt; const" t)
  Effects: Inserts t if and only if there is no element in the container with key equivalent to 
  the key of t. The bool component of the returned pair is true if and only if the insertion 
  takes place, and the iterator component of the pair points to the element with key equivalent 
  to the key of t.
  Complexity: logarithmic
  
  iterator insert(const_iterator p, std::pair&lt;const key_type, T&gt; const" t)
  Effects: Inserts t if and only if there is no element with key equivalent to the key of t in 
  containers with unique keys. Always returns the iterator pointing to the element with key 
  equivalent to the key of t. 
  Complexity: logarithmic in general, but amortized constant if t is inserted right before p.
  
  size_type erase(key_type const" k)  
  Effects: Erases all elements in the container with key equivalent to k. Returns the number of 
  erased elements.
  Complexity: log(size of container) + number of elements with key k
  
  iterator erase(const_iterator q) 
  Effects: Erases the element pointed to by q. Returns an iterator pointing to the element 
  immediately following q prior to the element being erased. If no such element exists, returns 
  end().
  Complexity: Amortized constant
  
  iterator erase(const_iterator q1, const_iterator q2)
  Effects: Erases all the elements in the left-inclusive and right-exclusive range [q1,q2). 
  Returns q2.
  Complexity: Amortized O(N) where N has the value distance(q1, q2).
  
  void clear() 
  Effects: erase(begin(), end())
  Post-Condition: empty() returns true
  Complexity: linear in size().
  
  iterator find(key_type const" k);
  Effects: Returns an iterator pointing to an element with the key equivalent to k, or end() if 
  such an element is not found.
  Complexity: logarithmic
  
  size_type count(key_type constquot;&amp; k) 
  Effects: Returns the number of elements with key equivalent to k
  Complexity: log(size of map) + number of elements with key equivalent to k
  
  iterator lower_bound(key_type const" k)
  Effects: Returns an iterator pointing to the first element with key not less than k, or end() 
  if such an element is not found.
  Complexity: logarithmic
  
  iterator upper_bound(key_type const" k)
  Effects: Returns an iterator pointing to the first element with key greater than k, or end() 
  if such an element is not found.
  Complexity: logarithmic
  
  23.4.1 Class template map
  
  §1 A map is an associative container that supports unique keys (contains at most one of each 
  key value) and provides for fast retrieval of values of another type T based on the keys. The 
  map class supports bidirectional iterators.
  
  23.4.1.2 map element access
  
  T" operator[](const key_type" x);
  Effects: If there is no key equivalent to x in the map, inserts value_type(x, T()) into the map. 
  Returns: A reference to the mapped_type corresponding to x in *this.
  Complexity: logarithmic.
  
  T" at(const key_type" x);
  const T" at(const key_type" x) const;
  Returns: A reference to the element whose key is equivalent to x.
  Throws: An exception object of type out_of_range if no such element is present.
  Complexity: logarithmic.
  </code></pre>