Hello, Can you please help me solve a compile error in this Flash library.
Library description:
An Arduino library for smoother, easier access to Flash data. This fork from MikalHart is the 1.5+ compatible version, and officially added to the Arduino library manager.
There are two compile errors:
- no matching function for call to 'print(ostream& (*&)(ostream&))'
- invalid conversion from 'ostream& (*)(ostream&)' to 'long unsigned int' [-fpermissive
Both errors occur on line #240 of Flash.h.
Computer System:
- Windows 10 Pro x64.
- PlatformIO Core
5.2.5
Home3.4.1
. - Arduino IDE 1.8.19 portable.
main.cpp:
#include <Arduino.h>
#include <Flash.h>
I'm struggling to understand exactly why the compiler is giving the invalid conversion error. I'm a little familiar with templates and operator overloading but it's beyond my knowledge to understand how the overload function(s) are defined.
I would really appreciate help in understanding what's going on and how the overload operator calls the correct type to stream.
If needs be I can create a bare minimum test project to illustrate the issue but since it appears to be a library issue I haven't not yet done so.
I would warmly welcome your input.
Flash.h:
/*
Flash.h - An Arduino library for flash-based (ROM) data collections.
Copyright (C) 2009-2012 Mikal Hart
All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __FLASH_H__
#define __FLASH_H__
#include <avr/pgmspace.h>
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#define FLASH_LIBRARY_VERSION 5
// Use these macros to define your flash-based data structures
// Example: FLASH_STRING(str, "Four score and seven years ago");
#define FLASH_STRING(name, value) \
static const char name##_flash[] PROGMEM = value; \
_FLASH_STRING name(name##_flash);
// Example: FLASH_ARRAY(float, temperatures, 98.1, 98.5, 99.1, 102.1);
#define FLASH_ARRAY(type, name, values...) \
static const type name##_flash[] PROGMEM = { values }; \
_FLASH_ARRAY<type> name(name##_flash, sizeof(name##_flash) / sizeof(type));
// Example: FLASH_TABLE(uint8_t, fonts, 7, {ON, OFF, ON, ON, OFF, ON, OFF}, {OFF, ON, OFF, ON, OFF, ON, OFF});
#define FLASH_TABLE(type, name, cols, values...) \
static const type name##_flash[][cols] PROGMEM = { values }; \
_FLASH_TABLE<type> name((const PROGMEM type *)name##_flash, sizeof(name##_flash) / sizeof(name##_flash[0]), cols);
// Example: FLASH_STRING_ARRAY(nums, PSTR("One"), PSTR("Two"), PSTR("Three"), PSTR("Four"), PSTR("Five"));
#define FLASH_STRING_ARRAY(name, values...) \
const char *name##_arr[] PROGMEM = { values }; \
_FLASH_STRING_ARRAY name(name##_arr, sizeof(name##_arr) / sizeof(name##_arr[0]));
#ifndef ARDUINO_CORE_PRINTABLE_SUPPORT
class _Printable
{
public:
virtual void print(Print &stream) const = 0;
};
#endif
#if ARDUINO < 100
// Inline ROM strings. Example: Serial << F("Hello, big world!");
#define F(str) (_FLASH_STRING(PSTR(str)).Printable())
#endif
/* _FLASH_STRING class. Use the FLASH_STRING() macro to create these, or use inline F() macro. */
class _FLASH_STRING : public _Printable
{
public:
#if ARDUINO >= 150
_FLASH_STRING(const char *arr PROGMEM);
#else
_FLASH_STRING(const prog_char *arr);
#endif
size_t length() const
{ return strlen_P(_arr); }
char *copy(char *to, size_t size = -1, size_t offset = 0) const
{
#if ARDUINO >= 150
return size == (size_t)-1 ?
#else
return size == -1 ?
#endif
strcpy_P(to, _arr + offset) : strncpy_P(to, _arr + offset, size);
}
#if ARDUINO >= 150
const char *access() const PROGMEM { return _arr; }
#else
const prog_char *access() const { return _arr; }
#endif
const _Printable &Printable() const
{ return *this; }
char operator[](int index) const
{ return static_cast<char>(pgm_read_byte(_arr + index)); }
void print(Print &stream) const;
private:
#if ARDUINO >= 150
const char *_arr PROGMEM;
#else
const prog_char *_arr;
#endif
};
/* _FLASH_ARRAY template class. Use the FLASH_ARRAY() macro to create these. */
template<class T>
class _FLASH_ARRAY : public _Printable
{
#if ARDUINO >= 150
typedef const T PROGMEM _DataType;
#else
typedef T PROGMEM _DataType;
#endif
public:
_FLASH_ARRAY(const _DataType *arr, size_t count) : _arr(arr), _size(count)
{ }
size_t count() const
{ return _size; }
const _DataType *access() const
{ return _arr; }
T operator[](int index) const
{
uint32_t val = 0;
if (sizeof(T) == 1)
val = pgm_read_byte(_arr + index);
else if (sizeof(T) == 2)
val = pgm_read_word(_arr + index);
else if (sizeof(T) == 4)
val = pgm_read_dword(_arr + index);
return *reinterpret_cast<T *>(&val);
}
void print(Print &stream) const
{
for (size_t i=0; i<_size; ++i)
{
stream.print((*this)[i]);
if (i < _size - 1)
stream.print(",");
}
}
private:
const _DataType *_arr;
size_t _size;
};
/* _FLASH_TABLE template class. Use the FLASH_TABLE() macro to create these. */
template<class T>
class _FLASH_TABLE : public _Printable
{
typedef T PROGMEM _DataType;
public:
_FLASH_TABLE(const _DataType *arr, size_t rows, size_t cols) : _arr(arr), _rows(rows), _cols(cols)
{ }
size_t rows() const
{ return _rows; }
size_t cols() const
{ return _cols; }
const _DataType *access()
{ return _arr; }
_FLASH_ARRAY<T> operator[](int index) const
{
_FLASH_ARRAY<T> row(_arr + index * _cols, _cols);
return row;
}
void print(Print &stream) const
{
for (int i=0; i<_rows; ++i)
{
_FLASH_ARRAY<T> row(_arr + i * _cols, _cols);
row.print(stream);
stream.println();
}
}
private:
const _DataType *_arr;
size_t _rows, _cols;
};
/* _FLASH_STRING_ARRAY class. Use the FLASH_STRING_ARRAY() macro to create these. */
class _FLASH_STRING_ARRAY : public _Printable
{
public:
#if ARDUINO >= 150
_FLASH_STRING_ARRAY(const char **arr PROGMEM, size_t count) : _arr(arr), _size(count) {}
#else
_FLASH_STRING_ARRAY(const prog_char **arr, size_t count) : _arr(arr), _size(count) {}
#endif
size_t count() const
{ return _size; }
_FLASH_STRING operator[](int index) const
{ return _FLASH_STRING(_arr[index]); }
void print(Print &stream) const
{
for (size_t i=0; i<_size; ++i)
{
_FLASH_STRING str(_arr[i]);
str.print(stream);
stream.println();
}
}
private:
#if ARDUINO >= 150
const char **_arr PROGMEM;
#else
const prog_char **_arr;
#endif
size_t _size;
};
#ifndef ARDUINO_STREAMING
#define ARDUINO_STREAMING
template<class T>
inline Print &operator <<(Print &stream, T arg)
{ stream.print(arg); return stream; }
#endif
inline Print &operator <<(Print &stream, const _Printable &printable)
{ printable.print(stream); return stream; }
inline Print &operator <<(Print &stream, const _FLASH_STRING &printable)
{ printable.print(stream); return stream; }
template<class T>
inline Print &operator <<(Print &stream, const _FLASH_ARRAY<T> &printable)
{ printable.print(stream); return stream; }
template<class T>
inline Print &operator <<(Print &stream, const _FLASH_TABLE<T> &printable)
{ printable.print(stream); return stream; }
inline Print &operator <<(Print &stream, const _FLASH_STRING_ARRAY &printable)
{ printable.print(stream); return stream; }
#endif // def __FLASH_H__
Flash.cpp:
/*
Flash.cpp - An Arduino library for flash-based (ROM) data collections.
Copyright (C) 2009 Mikal Hart
All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "Flash.h"
#if ARDUINO >= 150
_FLASH_STRING::_FLASH_STRING(const char *arr PROGMEM) : _arr(arr) {}
#else
_FLASH_STRING::_FLASH_STRING(const prog_char *arr) : _arr(arr) {}
#endif
void _FLASH_STRING::print(Print &stream) const
{
for (size_t i=0; ; ++i)
{
char c = (*this)[i];
if (!c) break;
stream.print(c); // print in char form
}
}