Andy Brown's port of the STL
I found a port of the STL for AVR microprocessors here:
http://andybrown.me.uk/ws/2011/01/15/the-standard-template-library-stl-for-avr-with-c-streams/
This is extremely handy if you want to use vectors, maps etc. in the fairly minimalist environment of programming Arduino or similar chips.
Testing indicates that, depending on what features you use, you may consume around another 1000 bytes of program memory (for a simple vector). Using a map adds 2400 bytes or so. Using both adds 2800 bytes (they would share some code).
So that isn't too bad, considering the Atmega328 has 32 Kb of program memory.
In case his site ever goes down I have a copy here:
http://www.gammon.com.au/Arduino/avr-stl-1.1.zip
Maniacbug's port of the STL
I have found some issues with Andy Brown's port in recent versions of the Arduino IDE. An alternative can be found here:
https://github.com/maniacbug/StandardCplusplus
In the case of Maniacbug's port, just download the file from GitHub, remove the word "-master" from the end of it, and install into your libraries directory. No fiddling around with the IDE download is required.
For this port, just include this line at the start of any sketch requiring the STL:
#include <StandardCplusplus.h>
Installation instructions for Andy Brown's port
Quote:
If you want to use the STL from within the popular Arduino IDE then all you need to do is copy all the files in the avr-stl\include directory into the hardware\tools\avr\avr\include subdirectory of the Arduino installation. For example, on my system I would copy all the header files into here: C:\Program Files (x86)\arduino-0021\hardware\tools\avr\avr\include.
Tip:
For Ubuntu, I found the directory structure slightly different, and copied the files from the avr-stl/include directory into:
~/arduino-1.0.6/hardware/tools/avr/lib/avr/include/
Of course, the "~/arduino-1.0.6" part would be wherever you installed your copy of the Arduino IDE.
Configuration (to affect how memory is allocated) is here:
Quote:
All configuration options may be found in avr_config.h.
You need to include <iterator> or you will get compile errors. You also need <new.cpp> in one file of your project to get the 'new' and 'delete' operators.
[EDIT] For Arduino 1.0 onwards you don't need <new.cpp> but you need <pnew.cpp> instead to get "placement new".
Example minimal code
#include <iterator>
#include <vector>
#include <map>
#include <new.cpp>
void setup ()
{
std::vector<byte> v;
v.push_back (1);
std::map<byte, byte> m;
m [1] = 2;
} // end of setup
void loop () {}
Credits
The code was released under the "Attribution-ShareAlike 3.0 Unported" license:
http://creativecommons.org/licenses/by-sa/3.0/
All credit and thanks to Andy Brown for making this port available.
More elaborate example
// stl test
#include <iterator>
#include <string>
#include <vector>
#include <serstream>
#include <pnew.cpp> // placement new implementation
using namespace std;
ohserialstream serial(Serial);
void showv (const string s, const vector<string> & v)
{
serial << s << endl;
copy(v.begin(), v.end(), ostream_iterator<string>(serial, " "));
serial << endl << endl;
} // end of showv
// case-independent (ci) string less_than
// returns true if s1 < s2
struct ci_less : binary_function<string, string, bool>
{
// case-independent (ci) compare_less binary function
struct nocase_compare : public binary_function<unsigned char,unsigned char,bool>
{
bool operator() (const unsigned char& c1, const unsigned char& c2) const
{ return tolower (c1) < tolower (c2); }
};
bool operator() (const string & s1, const string & s2) const
{
return lexicographical_compare
(s1.begin (), s1.end (), // source range
s2.begin (), s2.end (), // dest range
nocase_compare ()); // comparison
}
}; // end of ci_less
void setup() {
Serial.begin (115200);
// vector of strings
vector<string> v;
// make a back insert iterator to safely add to the back of the vector
back_insert_iterator<vector<string> > i(v);
// Insert items into the vector.
// Strictly speaking, the "++" is not needed, as the
// assignment to the iterator is what advances it.
*i++ = "The";
*i++ = "quick";
*i++ = "brown";
*i++ = "fox";
*i++ = "jumped";
*i++ = "over";
*i++ = "the";
*i++ = "lazy";
*i++ = "dog";
showv ("initial vector...", v);
// sort ascending
sort (v.begin (), v.end ());
showv ("after sort (ascending)...", v);
// sort descending by using greater function to compare less
sort (v.begin (), v.end (), greater<string> ());
showv ("after sort (descending)...", v);
// sort case-independent by using our own compare-less
sort (v.begin (), v.end (), ci_less ());
showv ("after case-independent sort (ascending)...", v);
// reverse that by doing a "not" on the result
sort (v.begin (), v.end (), not2 (ci_less ()));
showv ("after case-independent sort (descending)...", v);
// shuffle the words
random_shuffle (v.begin (), v.end ());
showv ("after shuffle...", v);
// rotate them
rotate (v.begin (), v.begin () + 1, v.end ());
showv ("after rotate 1 to the left...", v);
// reverse their order
reverse (v.begin (), v.end ());
showv ("after reverse...", v);
// add "(" to the beginning of each one
transform (v.begin (), v.end (),
v.begin (),
bind1st (plus<string> (), "("));
// add ")" to the end of each one
transform (v.begin (), v.end (),
v.begin (),
bind2nd (plus<string> (), ")"));
showv ("after transforms...", v);
} // end of setup
void loop() { }
Bug in string class
See Andy's notes about modifying line 1107 of the "string" header file to read like this:
= (typename basic_string<_CharT,_Traits,_Alloc>::size_type) -1;
Problems with IDE 1.6.0
In addition to the above change, to compile under IDE 1.6.0 you need to add "this->" in two places as described below:
In file "string" at line 173:
{ this->_M_deallocate(_Base::_M_start, _Base::_M_end_of_storage - _Base::_M_start); }
In file "stl_vector.h" at line 117:
~_Vector_base() { this->_M_deallocate(_Base::_M_start, _Base::_M_end_of_storage - _Base::_M_start); }
|