1

I need to merge and edit multiple Motorolla S-Record (MOT/SREC) files that each consist of memory addresses and the associated contents, and are therefore generally ordered by the memory address (unless someone hand-edits it or something), and then write the result back out (in order) to a single S-Rec file.

To allow easy ordering and processing of the addresses, I decided to use a map with the memory address as an integer key and the full SREC line (including the address) as a string value, e.g. std::map<int,std::string> mymap;

Since the files may have overlapping regions, the 'merge' will have to allow subsequent values to overwrite any existing ones. Since std::insert will not replace an existing value, my thought was to use operator[], but then two things piqued my interest:

  1. std::insert also has a form that takes an iterator position 'hint' and returns an iterator, which seems especially suited for the type of mostly-ordered insert I'll be doing - the data following an insert is very likely to follow it in order, so why not give the last position as a hint (i.e. just pass the iterator the last insert call returned to the next insert call)?
  2. From the SGI STL reference, "m[k] is equivalent to (*((m.insert(value_type(k, data_type()))).first)).second", which made me wonder if I could combine the hint form and the operator (w/ replacement) form... After all, complexity for both is logarithmic unless a good hint is provided for the insert, in which case it becomes an 'amortized constant'...

Which all comes down to: Is there an issue with combining insert-with-hint and operator[] by inserting a 'hint' into the operator[] syntax? e.g. (*(m.insert(hint, value_type(k, data_type())))).second = value; (This does still create a value using the default constructor before assigning the new value, which may be avoided somehow, but I'm not too worried about it right now for string values...)


Bonus: is there a reason why this isn't written as (m.insert(hint, value_type(k, data_type())))->second, or in the original example (*((m.insert(value_type(k, data_type()))).first)).second? Is there something special about the iterator or something?


(For what it's worth, "In STL maps, is it better to use map::insert than []?" deals with the choice between insert and operator[], and answers there tend to argue for readability in general, which is fine and is good practice in general, but this question deals especially with ordered (or mostly-ordered) data that may make some level of optimization worth it.)

Community
  • 1
  • 1
johnny
  • 4,024
  • 2
  • 24
  • 38
  • 4
    Given the sizes of most S-record files I've seen, and the fact that you're (presumably) doing this mixed with I/O, I'd be fairly surprised if any of this made any real difference -- the I/O time will typically dominate. – Jerry Coffin Jun 19 '13 at 14:49
  • About the combine insert-with-hint and operator[], what do you mean? Create your own operator[] to admit a hint (deriving from map, for example)? Or just using the code you sample to insert the element? – Gonmator Jun 19 '13 at 15:07
  • 1
    About the bonus: I don't think are any special reason, since map impose bidirectional iterator requirements, where both codes are equivalent. In C++98 operator[] is defined as in SGI documentation, but not in C++11: "_Effects: If there is no key equivalent to `x` in the map, inserts `value_type(x, T())` into the map._" – Gonmator Jun 19 '13 at 15:11
  • @Gonmator, I was just planning to use the code sample to insert the element, not creating my own operator[]... – johnny Jun 19 '13 at 15:29
  • @JerryCoffin, that's pretty much what I expected to hear, but I was still curious whether the construct would be useful at all... – johnny Jun 19 '13 at 15:31
  • @johnny: I don't see any issue by using the sample code with the hint. Because is just a hint, in the worst case (STL implementation, or bad hint used) you get the same complexity time. – Gonmator Jun 19 '13 at 15:52

0 Answers0