Using C++0x features in Teensy code

Status
Not open for further replies.

christoph

Well-known member
Argh... can a mod please correct the thread title to C++0x?

Hi,

I need your opinion and, if any, experience here.

I have a piece of code that is supposed to be portable between avr-gcc and arm-none-eabi-gcc (for AVR Teensys and Teensy 3, respectively), and it relies on a templated array-like type that is used to store small structs, bytes or bits. I can use std::array for the first two, and std::bitset (in a template specialization) for the latter, but is there any library for AVRs that provides those and results in reasonably small/fast code?

I found the standard template library stl for avr with c streams, but has anyone tried its std::bitset?

Regards

Christoph
 
Last edited:
I just gave it a shot and compiled the following code for atmega32u4, optimization -Os, using the library mentioned above:
Code:
#include <iterator>
#include <bitset>
#include <stdint.h>
#include <avr/io.h>

#define LENGTH 11

int main(void)
{
  std::bitset<LENGTH> b;
  b[3] = true;
  PORTC |= (b[3] << 1);
  while(1)
  {
  }

  return 0;
}
The list file contains some cryptic code needed for the bitset, but the main seems to be well optmized:
Code:
000001c8 <main>:
 1c8:	41 9a       	sbi	0x08, 1	; 8
 1ca:	ff cf       	rjmp	.-2      	; 0x1ca <main+0x2>
The next thing I saw was some feature I might need popping up at the horizon (writing 8 bits starting at a non-aligned position, not implemented yet), so I rolled my own:
Code:
#include <avr/io.h>
#include <stdint.h>

template <unsigned int N>
class BitArray
{
  public:
    BitArray()
    {
      for (uint8_t i = 0; i < ((N+7)/8); i++)
      {
        m_data[i] = 0;
      }
    }
    struct proxy
    {
      BitArray& m_a;
      const uint16_t m_i;
      const uint8_t m_bit;
      proxy(BitArray& a, const uint16_t& i) : m_a(a), m_i(i >> 3), m_bit(i & 0x07) {}
      operator bool() const
      {
        return m_a.m_data[m_i] & (1<<m_bit);
      }
      const proxy& operator=(const bool& rhs) const
      {
        m_a.m_data[m_i] = (m_a.m_data[m_i] & ~(1<<m_bit)) | (rhs<<m_bit);
        return *this;
      }
    };
    const proxy operator[](const uint16_t& i)
    {
      return proxy(*this, i);
    }
//  private:
    uint8_t m_data[(N+7)/8];
};

#define LENGTH 11

int main(void)
{
  BitArray<LENGTH> b;
  b[3] = true;
  PORTC |= (b[3] << 1);
  while(1)
  {
  }

  return 0;
}
The BitArray class provides an operator[] which returns a proxy object. This in turn manipulates the actual data. Any C++ experts please point out pitfalls or errors... Anyway this class is not meant as a real replacement for std::bitset, but provides similar functionality according to my needs. Again, this seems to be well optimizable:
Code:
000000c4 <main>:
  c4:	41 9a       	sbi	0x08, 1	; 8
  c6:	ff cf       	rjmp	.-2      	; 0xc6 <main+0x2>
I'll need to do some more testing and profiling, but this one was fun! Plus: No C++0x needed.

Regards

Christoph
 
Status
Not open for further replies.
Back
Top