From 32d3aee7ef4b14ea443d7ded70de1a17451bd367 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Nov 2019 12:29:27 +0100 Subject: [PATCH 001/254] Moved Stream.flush() to Print.flush() --- api/Print.h | 2 ++ api/Stream.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/api/Print.h b/api/Print.h index 6a06bad6..0cd11667 100644 --- a/api/Print.h +++ b/api/Print.h @@ -82,5 +82,7 @@ class Print size_t println(double, int = 2); size_t println(const Printable&); size_t println(void); + + virtual void flush() { /* Empty implementation for backward compatibility */ } }; diff --git a/api/Stream.h b/api/Stream.h index 0576ba87..4ef5bc27 100644 --- a/api/Stream.h +++ b/api/Stream.h @@ -58,7 +58,6 @@ class Stream : public Print virtual int available() = 0; virtual int read() = 0; virtual int peek() = 0; - virtual void flush() = 0; Stream() {_timeout=1000;} From 398e70f188e2b861c10d9ffe5e2bfcb6a4a4f489 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Nov 2019 12:31:10 +0100 Subject: [PATCH 002/254] Added Print.availableForWrite() --- api/Print.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/Print.h b/api/Print.h index 0cd11667..0bf79bd5 100644 --- a/api/Print.h +++ b/api/Print.h @@ -54,6 +54,10 @@ class Print return write((const uint8_t *)buffer, size); } + // default to zero, meaning "a single write may block" + // should be overriden by subclasses with buffering + virtual int availableForWrite() { return 0; } + size_t print(const __FlashStringHelper *); size_t print(const String &); size_t print(const char[]); From fc0c12d7faf43782fd44d2e1384abfef6109da21 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Mon, 12 Nov 2018 12:10:13 +0100 Subject: [PATCH 003/254] Encapsulate everything in namespace arduino This will help integrating with other C++ frameworks declaring the same classes (String/Serial/...) --- api/Client.h | 3 +++ api/HardwareI2C.h | 4 ++++ api/HardwareSerial.h | 3 +++ api/IPAddress.cpp | 2 ++ api/IPAddress.h | 4 +++- api/Interrupts.h | 3 +++ api/PluggableUSB.cpp | 2 ++ api/PluggableUSB.h | 4 ++++ api/Print.cpp | 2 ++ api/Print.h | 3 +++ api/Printable.h | 3 +++ api/RingBuffer.h | 5 ++++- api/Server.h | 3 +++ api/Stream.cpp | 2 ++ api/Stream.h | 4 ++++ api/String.cpp | 24 +++++++++++++----------- api/String.h | 29 +++++++++++++++++------------ api/USBAPI.h | 2 ++ api/Udp.h | 3 +++ api/WCharacter.h | 3 +++ 20 files changed, 83 insertions(+), 25 deletions(-) diff --git a/api/Client.h b/api/Client.h index c8ebc9fe..5a1d99fe 100644 --- a/api/Client.h +++ b/api/Client.h @@ -22,6 +22,8 @@ #include "Stream.h" #include "IPAddress.h" +namespace arduino { + class Client : public Stream { public: @@ -41,3 +43,4 @@ class Client : public Stream { uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; }; +} \ No newline at end of file diff --git a/api/HardwareI2C.h b/api/HardwareI2C.h index 25bf40e5..c107d1a6 100644 --- a/api/HardwareI2C.h +++ b/api/HardwareI2C.h @@ -21,6 +21,8 @@ #include #include "Stream.h" +namespace arduino { + class HardwareI2C : public Stream { public: @@ -41,3 +43,5 @@ class HardwareI2C : public Stream virtual void onRequest(void(*)(void)) = 0; }; +} + diff --git a/api/HardwareSerial.h b/api/HardwareSerial.h index e3b0b278..e8f0657a 100644 --- a/api/HardwareSerial.h +++ b/api/HardwareSerial.h @@ -21,6 +21,8 @@ #include #include "Stream.h" +namespace arduino { + // XXX: Those constants should be defined as const int / enums? // XXX: shall we use namespaces too? #define SERIAL_PARITY_EVEN (0x1ul) @@ -100,3 +102,4 @@ class HardwareSerial : public Stream // XXX: Are we keeping the serialEvent API? extern void serialEventRun(void) __attribute__((weak)); +} \ No newline at end of file diff --git a/api/IPAddress.cpp b/api/IPAddress.cpp index 62244d6b..0590fd10 100644 --- a/api/IPAddress.cpp +++ b/api/IPAddress.cpp @@ -20,6 +20,8 @@ #include "IPAddress.h" #include "Print.h" +using namespace arduino; + IPAddress::IPAddress() { _address.dword = 0; diff --git a/api/IPAddress.h b/api/IPAddress.h index c8df92d7..7302b24a 100644 --- a/api/IPAddress.h +++ b/api/IPAddress.h @@ -23,6 +23,8 @@ #include "Printable.h" #include "String.h" +namespace arduino { + // A class to make it easier to handle and pass around IP addresses class IPAddress : public Printable { @@ -74,4 +76,4 @@ class IPAddress : public Printable { }; extern const IPAddress INADDR_NONE; - +} diff --git a/api/Interrupts.h b/api/Interrupts.h index fad8c801..e306fc79 100644 --- a/api/Interrupts.h +++ b/api/Interrupts.h @@ -7,6 +7,8 @@ #include #include "Common.h" +namespace arduino { + template using voidTemplateFuncPtrParam = void (*)(T param); @@ -37,5 +39,6 @@ template void attachInterrupt(pin_size_t interruptNum, voidTemplateF attachInterruptParam(interruptNum, (voidFuncPtrParam)userFunc, mode, (void*)param); } +} #endif #endif diff --git a/api/PluggableUSB.cpp b/api/PluggableUSB.cpp index f0c45f01..ca19d65d 100644 --- a/api/PluggableUSB.cpp +++ b/api/PluggableUSB.cpp @@ -20,6 +20,8 @@ #include "USBAPI.h" #include "PluggableUSB.h" +using namespace arduino; + int PluggableUSB_::getInterface(uint8_t* interfaceCount) { int sent = 0; diff --git a/api/PluggableUSB.h b/api/PluggableUSB.h index 09b5fed5..1d735bc4 100644 --- a/api/PluggableUSB.h +++ b/api/PluggableUSB.h @@ -24,6 +24,8 @@ #include #include +namespace arduino { + // core need to define void* epBuffer(unsigned int n); // -> returns a poointer to the Nth element of the EP buffer structure @@ -72,4 +74,6 @@ class PluggableUSB_ { // https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use PluggableUSB_& PluggableUSB(); +} + #endif \ No newline at end of file diff --git a/api/Print.cpp b/api/Print.cpp index 4f0016c4..01ff7bee 100644 --- a/api/Print.cpp +++ b/api/Print.cpp @@ -23,6 +23,8 @@ #include "Print.h" +using namespace arduino; + // Public Methods ////////////////////////////////////////////////////////////// /* default implementation: may be overridden */ diff --git a/api/Print.h b/api/Print.h index 0bf79bd5..f8664123 100644 --- a/api/Print.h +++ b/api/Print.h @@ -29,6 +29,8 @@ #define OCT 8 #define BIN 2 +namespace arduino { + class Print { private: @@ -90,3 +92,4 @@ class Print virtual void flush() { /* Empty implementation for backward compatibility */ } }; +} \ No newline at end of file diff --git a/api/Printable.h b/api/Printable.h index de45907d..972866e8 100644 --- a/api/Printable.h +++ b/api/Printable.h @@ -20,6 +20,8 @@ #include +namespace arduino { + class Print; /** The Printable class provides a way for new classes to allow themselves to be printed. @@ -34,3 +36,4 @@ class Printable virtual size_t printTo(Print& p) const = 0; }; +} \ No newline at end of file diff --git a/api/RingBuffer.h b/api/RingBuffer.h index 2d58dca5..af552e77 100644 --- a/api/RingBuffer.h +++ b/api/RingBuffer.h @@ -23,6 +23,8 @@ #include +namespace arduino { + // Define constants and variables for buffering incoming serial data. We're // using a ring buffer (I think), in which head is the index of the location // to which to write the next incoming character and tail is the index of the @@ -137,6 +139,7 @@ bool RingBufferN::isFull() return (nextIndex(_iHead) == _iTail); } -#endif /* _RING_BUFFER_ */ +} +#endif /* _RING_BUFFER_ */ #endif /* __cplusplus */ \ No newline at end of file diff --git a/api/Server.h b/api/Server.h index 86756825..83d0cd3b 100644 --- a/api/Server.h +++ b/api/Server.h @@ -21,8 +21,11 @@ #include "Print.h" +namespace arduino { + class Server : public Print { public: virtual void begin() = 0; }; +} \ No newline at end of file diff --git a/api/Stream.cpp b/api/Stream.cpp index b3f366f5..18af5a82 100644 --- a/api/Stream.cpp +++ b/api/Stream.cpp @@ -27,6 +27,8 @@ #define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait +using namespace arduino; + // private method to read stream with timeout int Stream::timedRead() { diff --git a/api/Stream.h b/api/Stream.h index 4ef5bc27..bf4261a5 100644 --- a/api/Stream.h +++ b/api/Stream.h @@ -34,6 +34,8 @@ readBytesBetween( pre_string, terminator, buffer, length) */ +namespace arduino { + // This enumeration provides the lookahead options for parseInt(), parseFloat() // The rules set out here are used until either the first valid character is found // or a time out occurs due to lack of input. @@ -125,3 +127,5 @@ class Stream : public Print }; #undef NO_IGNORE_CHAR + +} \ No newline at end of file diff --git a/api/String.cpp b/api/String.cpp index b27a5013..97d0a5f6 100644 --- a/api/String.cpp +++ b/api/String.cpp @@ -27,6 +27,8 @@ /* Constructors */ /*********************************************/ +using namespace arduino; + String::String(const char *cstr) { init(); @@ -352,77 +354,77 @@ unsigned char String::concat(const __FlashStringHelper * str) /* Concatenate */ /*********************************************/ -StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) +StringSumHelper & arduino::operator + (const StringSumHelper &lhs, const String &rhs) { StringSumHelper &a = const_cast(lhs); if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); return a; } -StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) +StringSumHelper & arduino::operator + (const StringSumHelper &lhs, const char *cstr) { StringSumHelper &a = const_cast(lhs); if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); return a; } -StringSumHelper & operator + (const StringSumHelper &lhs, char c) +StringSumHelper & arduino::operator + (const StringSumHelper &lhs, char c) { StringSumHelper &a = const_cast(lhs); if (!a.concat(c)) a.invalidate(); return a; } -StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) +StringSumHelper & arduino::operator + (const StringSumHelper &lhs, unsigned char num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & operator + (const StringSumHelper &lhs, int num) +StringSumHelper & arduino::operator + (const StringSumHelper &lhs, int num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) +StringSumHelper & arduino::operator + (const StringSumHelper &lhs, unsigned int num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & operator + (const StringSumHelper &lhs, long num) +StringSumHelper & arduino::operator + (const StringSumHelper &lhs, long num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) +StringSumHelper & arduino::operator + (const StringSumHelper &lhs, unsigned long num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & operator + (const StringSumHelper &lhs, float num) +StringSumHelper & arduino::operator + (const StringSumHelper &lhs, float num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & operator + (const StringSumHelper &lhs, double num) +StringSumHelper & arduino::operator + (const StringSumHelper &lhs, double num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) +StringSumHelper & arduino::operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) { StringSumHelper &a = const_cast(lhs); if (!a.concat(rhs)) a.invalidate(); diff --git a/api/String.h b/api/String.h index 8c6d2d39..56ba7ba3 100644 --- a/api/String.h +++ b/api/String.h @@ -19,10 +19,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#pragma once - #ifdef __cplusplus +#ifndef __ARDUINO_STRINGS__ +#define __ARDUINO_STRINGS__ + #include #include #include @@ -32,6 +33,7 @@ #include "deprecated-avr-comp/avr/pgmspace.h" #endif +namespace arduino { // When compiling programs with this class, the following gcc parameters // dramatically increase performance and memory (RAM) efficiency, typically // with little or no increase in code size. @@ -48,6 +50,7 @@ class StringSumHelper; // The string class class String { + friend class StringSumHelper; // use a function pointer to allow for "if (s)" without the // complications of an operator bool(). for more information, see: // http://www.artima.com/cppsource/safebool.html @@ -231,16 +234,18 @@ class String class StringSumHelper : public String { public: - StringSumHelper(const String &s) : String(s) {} - StringSumHelper(const char *p) : String(p) {} - StringSumHelper(char c) : String(c) {} - StringSumHelper(unsigned char num) : String(num) {} - StringSumHelper(int num) : String(num) {} - StringSumHelper(unsigned int num) : String(num) {} - StringSumHelper(long num) : String(num) {} - StringSumHelper(unsigned long num) : String(num) {} - StringSumHelper(float num) : String(num) {} - StringSumHelper(double num) : String(num) {} + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} }; +} #endif // __cplusplus +#endif // __ARDUINO_STRINGS__ diff --git a/api/USBAPI.h b/api/USBAPI.h index 8743ab4b..7b14762c 100644 --- a/api/USBAPI.h +++ b/api/USBAPI.h @@ -22,6 +22,7 @@ #include +namespace arduino { //================================================================================ //================================================================================ // Low level API @@ -57,4 +58,5 @@ int USB_Recv(uint8_t ep, void* data, int len); // non-blocking int USB_Recv(uint8_t ep); // non-blocking void USB_Flush(uint8_t ep); +} #endif \ No newline at end of file diff --git a/api/Udp.h b/api/Udp.h index 90581653..b6950024 100644 --- a/api/Udp.h +++ b/api/Udp.h @@ -37,6 +37,8 @@ #include "Stream.h" #include "IPAddress.h" +namespace arduino { + class UDP : public Stream { public: @@ -84,3 +86,4 @@ class UDP : public Stream { uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; }; +} \ No newline at end of file diff --git a/api/WCharacter.h b/api/WCharacter.h index 4ce89ee8..68c0e793 100644 --- a/api/WCharacter.h +++ b/api/WCharacter.h @@ -22,6 +22,8 @@ #include +namespace arduino { + // WCharacter.h prototypes inline bool isAlphaNumeric(int c) __attribute__((always_inline)); inline bool isAlpha(int c) __attribute__((always_inline)); @@ -165,4 +167,5 @@ inline int toUpperCase(int c) return toupper (c); } +} #endif \ No newline at end of file From 9c2dbe25139cb68446b581ab505c0a4ab1b4bcdc Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 29 Nov 2018 09:46:31 +0100 Subject: [PATCH 004/254] Add header with digital* APIs compatible with legacy code TODO: mark as deprecated --- api/Compat.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 api/Compat.h diff --git a/api/Compat.h b/api/Compat.h new file mode 100644 index 00000000..725ccd66 --- /dev/null +++ b/api/Compat.h @@ -0,0 +1,16 @@ +#ifndef __COMPAT_H__ +#define __COMPAT_H__ + +namespace arduino { + +inline void pinMode(pin_size_t pinNumber, int mode) { + pinMode(pinNumber, (PinMode)mode); +}; + +inline void digitalWrite(pin_size_t pinNumber, int status) { + digitalWrite(pinNumber, (PinStatus)status); +}; + +} + +#endif \ No newline at end of file From 3a701f4543065680e7cbb3ed89fe3cfe32009c63 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 29 Nov 2018 09:47:14 +0100 Subject: [PATCH 005/254] Add SPI class abstraction --- api/HardwareSPI.h | 126 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 api/HardwareSPI.h diff --git a/api/HardwareSPI.h b/api/HardwareSPI.h new file mode 100644 index 00000000..64377472 --- /dev/null +++ b/api/HardwareSPI.h @@ -0,0 +1,126 @@ +/* + Copyright (c) 2018 Arduino LLC. All right 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 +*/ + +#pragma once + +#include "Common.h" +#include +#include "Stream.h" + +namespace arduino { + +typedef enum { + SPI_MODE0 = 0, + SPI_MODE1 = 1, + SPI_MODE2 = 2, + SPI_MODE3 = 3, +} SPIMode; + + +class SPISettings { + public: + SPISettings(uint32_t clock, BitOrder bitOrder, SPIMode dataMode) { + if (__builtin_constant_p(clock)) { + init_AlwaysInline(clock, bitOrder, dataMode); + } else { + init_MightInline(clock, bitOrder, dataMode); + } + } + + SPISettings(uint32_t clock, BitOrder bitOrder, int dataMode) { + if (__builtin_constant_p(clock)) { + init_AlwaysInline(clock, bitOrder, (SPIMode)dataMode); + } else { + init_MightInline(clock, bitOrder, (SPIMode)dataMode); + } + } + + // Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first. + SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); } + + bool operator==(const SPISettings& rhs) const + { + if ((this->clockFreq == rhs.clockFreq) && + (this->bitOrder == rhs.bitOrder) && + (this->dataMode == rhs.dataMode)) { + return true; + } + return false; + } + + bool operator!=(const SPISettings& rhs) const + { + return !(*this == rhs); + } + + uint32_t getClockFreq() const { + return clockFreq; + } + SPIMode getDataMode() const { + return dataMode; + } + BitOrder getBitOrder() const { + return (bitOrder); + } + + private: + void init_MightInline(uint32_t clock, BitOrder bitOrder, SPIMode dataMode) { + init_AlwaysInline(clock, bitOrder, dataMode); + } + + // Core developer MUST use an helper function in beginTransaction() to use this data + void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, SPIMode dataMode) __attribute__((__always_inline__)) { + this->clockFreq = clock; + this->dataMode = dataMode; + this->bitOrder = bitOrder; + } + + uint32_t clockFreq; + SPIMode dataMode; + BitOrder bitOrder; + + friend class HardwareSPI; +}; + +const SPISettings DEFAULT_SPI_SETTINGS = SPISettings(); + +class HardwareSPI +{ + public: + virtual uint8_t transfer(uint8_t data); + virtual uint16_t transfer16(uint16_t data); + virtual void transfer(void *buf, size_t count); + + // Transaction Functions + virtual void usingInterrupt(int interruptNumber); + virtual void notUsingInterrupt(int interruptNumber); + virtual void beginTransaction(SPISettings settings); + virtual void endTransaction(void); + + // SPI Configuration methods + virtual void attachInterrupt(); + virtual void detachInterrupt(); + + virtual void begin(); + virtual void end(); +}; + +// Alias SPIClass to HardwareSPI since it's already the defacto standard for SPI classe name +typedef HardwareSPI SPIClass; + +} From 3eadcebee9bbbb90a1e05ec47f7320a35fbd814a Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 29 Nov 2018 09:48:01 +0100 Subject: [PATCH 006/254] Include Compat and HardwareSPI when including ArduinoAPI.h --- api/ArduinoAPI.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/ArduinoAPI.h b/api/ArduinoAPI.h index c70f2adb..bfb7808c 100644 --- a/api/ArduinoAPI.h +++ b/api/ArduinoAPI.h @@ -28,6 +28,7 @@ #ifdef __cplusplus #include "Client.h" #include "HardwareI2C.h" +#include "HardwareSPI.h" #include "HardwareSerial.h" #include "Interrupts.h" #include "IPAddress.h" @@ -52,4 +53,7 @@ // Misc Arduino core functions #include "Common.h" +// Compatibility layer for older code +#include "Compat.h" + #endif From 334156cff061391b934fb32a41b19cca765e2021 Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Tue, 3 Jan 2017 13:42:24 -0500 Subject: [PATCH 007/254] Add virtual beginMulticast(...) stub to UDP class --- api/Udp.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/Udp.h b/api/Udp.h index b6950024..68a71e85 100644 --- a/api/Udp.h +++ b/api/Udp.h @@ -42,7 +42,8 @@ namespace arduino { class UDP : public Stream { public: - virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual uint8_t beginMulticast(IPAddress, uint16_t) { return 0; } // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure virtual void stop() =0; // Finish with the UDP socket // Sending UDP packets From 8f2672e4234b088bb4740d72fe13d9eebdef54f4 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 4 Jan 2019 13:01:31 +0100 Subject: [PATCH 008/254] Include Compat header only if C++ --- api/ArduinoAPI.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/ArduinoAPI.h b/api/ArduinoAPI.h index bfb7808c..03bd33bb 100644 --- a/api/ArduinoAPI.h +++ b/api/ArduinoAPI.h @@ -53,7 +53,9 @@ // Misc Arduino core functions #include "Common.h" +#ifdef __cplusplus // Compatibility layer for older code #include "Compat.h" +#endif #endif From f4ba11f19bd7356ad93526e924f2bca0589e216e Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 4 Jan 2019 13:02:08 +0100 Subject: [PATCH 009/254] Move USB APIs out of arduino namespace --- api/PluggableUSB.h | 11 +++++------ api/USBAPI.h | 4 +++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/api/PluggableUSB.h b/api/PluggableUSB.h index 1d735bc4..9018f6ce 100644 --- a/api/PluggableUSB.h +++ b/api/PluggableUSB.h @@ -26,9 +26,6 @@ namespace arduino { -// core need to define -void* epBuffer(unsigned int n); // -> returns a poointer to the Nth element of the EP buffer structure - class PluggableUSBModule { public: PluggableUSBModule(uint8_t numEps, uint8_t numIfs, unsigned int *epType) : @@ -68,12 +65,14 @@ class PluggableUSB_ { PluggableUSBModule* rootNode; uint8_t totalEP; }; +} + +// core need to define +void* epBuffer(unsigned int n); // -> returns a pointer to the Nth element of the EP buffer structure // Replacement for global singleton. // This function prevents static-initialization-order-fiasco // https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use -PluggableUSB_& PluggableUSB(); - -} +arduino::PluggableUSB_& PluggableUSB(); #endif \ No newline at end of file diff --git a/api/USBAPI.h b/api/USBAPI.h index 7b14762c..ba5e87ce 100644 --- a/api/USBAPI.h +++ b/api/USBAPI.h @@ -44,7 +44,10 @@ typedef struct __attribute__((packed)) uint16_t wLength; } USBSetup; +} + //================================================================================ +// USB APIs (C scope) //================================================================================ int USB_SendControl(uint8_t flags, const void* d, int len); @@ -58,5 +61,4 @@ int USB_Recv(uint8_t ep, void* data, int len); // non-blocking int USB_Recv(uint8_t ep); // non-blocking void USB_Flush(uint8_t ep); -} #endif \ No newline at end of file From 7c9e4f8abde3ce75234e51c0e5be3083832c3e49 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 4 Jan 2019 14:34:20 +0100 Subject: [PATCH 010/254] Update API revision to 1.0.1 --- api/ArduinoAPI.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/ArduinoAPI.h b/api/ArduinoAPI.h index 03bd33bb..08f1154b 100644 --- a/api/ArduinoAPI.h +++ b/api/ArduinoAPI.h @@ -21,7 +21,7 @@ #define ARDUINO_API_H // version 1.0.0 -#define ARDUINO_API_VERSION 10000 +#define ARDUINO_API_VERSION 10001 #include "Binary.h" From 30e439755e47339d19a835da9cd79cb1791c2e9f Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 21 Jun 2019 13:54:51 +0200 Subject: [PATCH 011/254] Avoid max() and min() clash with c++ stdlib --- api/Common.h | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/api/Common.h b/api/Common.h index e638d3be..19e1307f 100644 --- a/api/Common.h +++ b/api/Common.h @@ -37,20 +37,6 @@ typedef enum { #define SERIAL 0x0 #define DISPLAY 0x1 -#ifndef min -#define min(a,b) \ - ({ __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a < _b ? _a : _b; }) -#endif - -#ifndef max -#define max(a,b) \ - ({ __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a > _b ? _a : _b; }) -#endif - #ifndef constrain #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #endif @@ -130,6 +116,33 @@ void loop(void); } // extern "C" #endif +#ifdef __cplusplus + template + auto min(const T& a, const L& b) -> decltype((b < a) ? b : a) + { + return (b < a) ? b : a; + } + + template + auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) + { + return (a < b) ? b : a; + } +#else +#ifndef min +#define min(a,b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a < _b ? _a : _b; }) +#endif +#ifndef max +#define max(a,b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a > _b ? _a : _b; }) +#endif +#endif + #ifdef __cplusplus /* C++ prototypes */ From 2136fda39e12c4269668142abf92b992d58edfac Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 18 Jun 2019 15:09:30 +0200 Subject: [PATCH 012/254] Fixed warning about namespace --- api/String.cpp | 26 ++++++++++++++------------ api/String.h | 4 +++- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/api/String.cpp b/api/String.cpp index 97d0a5f6..4a6f598d 100644 --- a/api/String.cpp +++ b/api/String.cpp @@ -27,7 +27,7 @@ /* Constructors */ /*********************************************/ -using namespace arduino; +namespace arduino { String::String(const char *cstr) { @@ -354,77 +354,77 @@ unsigned char String::concat(const __FlashStringHelper * str) /* Concatenate */ /*********************************************/ -StringSumHelper & arduino::operator + (const StringSumHelper &lhs, const String &rhs) +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) { StringSumHelper &a = const_cast(lhs); if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); return a; } -StringSumHelper & arduino::operator + (const StringSumHelper &lhs, const char *cstr) +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) { StringSumHelper &a = const_cast(lhs); if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); return a; } -StringSumHelper & arduino::operator + (const StringSumHelper &lhs, char c) +StringSumHelper & operator + (const StringSumHelper &lhs, char c) { StringSumHelper &a = const_cast(lhs); if (!a.concat(c)) a.invalidate(); return a; } -StringSumHelper & arduino::operator + (const StringSumHelper &lhs, unsigned char num) +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & arduino::operator + (const StringSumHelper &lhs, int num) +StringSumHelper & operator + (const StringSumHelper &lhs, int num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & arduino::operator + (const StringSumHelper &lhs, unsigned int num) +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & arduino::operator + (const StringSumHelper &lhs, long num) +StringSumHelper & operator + (const StringSumHelper &lhs, long num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & arduino::operator + (const StringSumHelper &lhs, unsigned long num) +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & arduino::operator + (const StringSumHelper &lhs, float num) +StringSumHelper & operator + (const StringSumHelper &lhs, float num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & arduino::operator + (const StringSumHelper &lhs, double num) +StringSumHelper & operator + (const StringSumHelper &lhs, double num) { StringSumHelper &a = const_cast(lhs); if (!a.concat(num)) a.invalidate(); return a; } -StringSumHelper & arduino::operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) +StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) { StringSumHelper &a = const_cast(lhs); if (!a.concat(rhs)) a.invalidate(); @@ -742,3 +742,5 @@ double String::toDouble(void) const if (buffer) return atof(buffer); return 0; } + +} // namespace arduino diff --git a/api/String.h b/api/String.h index 56ba7ba3..90361d95 100644 --- a/api/String.h +++ b/api/String.h @@ -34,6 +34,7 @@ #endif namespace arduino { + // When compiling programs with this class, the following gcc parameters // dramatically increase performance and memory (RAM) efficiency, typically // with little or no increase in code size. @@ -246,6 +247,7 @@ class StringSumHelper : public String StringSumHelper(double num) : String(num) {} }; -} +} // namespace arduino + #endif // __cplusplus #endif // __ARDUINO_STRINGS__ From ee8bce838f47c1ab92e4f51361808a26173b3bf9 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Mon, 19 Aug 2019 16:12:14 +0200 Subject: [PATCH 013/254] Add SPI_HAS_TRANSACTION define Modern Arduino cores require to implement beginTransaction, so we can always define SPI_HAS_TRANSACTION. Fixes https://github.com/adafruit/Adafruit-GFX-Library/issues/242 --- api/HardwareSPI.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/HardwareSPI.h b/api/HardwareSPI.h index 64377472..a851b937 100644 --- a/api/HardwareSPI.h +++ b/api/HardwareSPI.h @@ -22,6 +22,8 @@ #include #include "Stream.h" +#define SPI_HAS_TRANSACTION + namespace arduino { typedef enum { From a385de906b8a09ebc3ac4ee17449944949e47951 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Mon, 23 Sep 2019 20:17:28 +0200 Subject: [PATCH 014/254] IPAddress - Ethernet library compatibility fixes --- api/IPAddress.cpp | 2 +- api/IPAddress.h | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/api/IPAddress.cpp b/api/IPAddress.cpp index 0590fd10..4be33105 100644 --- a/api/IPAddress.cpp +++ b/api/IPAddress.cpp @@ -116,4 +116,4 @@ size_t IPAddress::printTo(Print& p) const return n; } -const IPAddress INADDR_NONE(0,0,0,0); +const IPAddress arduino::INADDR_NONE(0,0,0,0); diff --git a/api/IPAddress.h b/api/IPAddress.h index 7302b24a..1771f8e1 100644 --- a/api/IPAddress.h +++ b/api/IPAddress.h @@ -23,6 +23,11 @@ #include "Printable.h" #include "String.h" +// forward declartions of global name space friend classes +class EthernetClass; +class DhcpClass; +class DNSClient; + namespace arduino { // A class to make it easier to handle and pass around IP addresses @@ -67,12 +72,13 @@ class IPAddress : public Printable { virtual size_t printTo(Print& p) const; - friend class EthernetClass; friend class UDP; friend class Client; friend class Server; - friend class DhcpClass; - friend class DNSClient; + + friend ::EthernetClass; + friend ::DhcpClass; + friend ::DNSClient; }; extern const IPAddress INADDR_NONE; From 6dec2cbdd4534c0c9aac80bb6bc870c415f8c350 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 7 Apr 2020 10:54:23 +0200 Subject: [PATCH 015/254] Force arduino namespace if UDP.h is included --- api/Udp.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/Udp.h b/api/Udp.h index 68a71e85..53f89f9a 100644 --- a/api/Udp.h +++ b/api/Udp.h @@ -87,4 +87,6 @@ class UDP : public Stream { uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; }; -} \ No newline at end of file +} + +using namespace arduino; From 3daf1893582d3a1cc6f5b56f7e6949009052a05a Mon Sep 17 00:00:00 2001 From: Shriramana Sharma Date: Sat, 11 Aug 2018 11:11:01 +0530 Subject: [PATCH 016/254] Add `bitToggle` macro to complement `bitSet` etc Port of https://github.com/arduino/ArduinoCore-avr/commit/0c5aa78ff40d208a1341b3dae84166e837901070 Reference PR: https://github.com/arduino/ArduinoCore-avr/pull/31 --- api/Common.h | 1 + 1 file changed, 1 insertion(+) diff --git a/api/Common.h b/api/Common.h index 19e1307f..8d288e18 100644 --- a/api/Common.h +++ b/api/Common.h @@ -64,6 +64,7 @@ typedef void (*voidFuncPtrParam)(void*); #define bitRead(value, bit) (((value) >> (bit)) & 0x01) #define bitSet(value, bit) ((value) |= (1UL << (bit))) #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitToggle(value, bit) ((value) ^= (1UL << (bit))) #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) #ifndef bit From 67e43870fcb7f67ada41b08bf68fac63eef60fb5 Mon Sep 17 00:00:00 2001 From: Akihiro YAMAZAKI Date: Wed, 4 Sep 2019 20:04:45 +0900 Subject: [PATCH 017/254] remove unnecessary if branch checking `length` in below while statement Porting of https://github.com/arduino/ArduinoCore-avr/pull/103 --- api/Stream.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/api/Stream.cpp b/api/Stream.cpp index 18af5a82..a5d8b076 100644 --- a/api/Stream.cpp +++ b/api/Stream.cpp @@ -220,7 +220,6 @@ size_t Stream::readBytes(char *buffer, size_t length) size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) { - if (length < 1) return 0; size_t index = 0; while (index < length) { int c = timedRead(); From 7f8de5869ee3de7a915bf1db64313c08595b3ac3 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 10 Apr 2020 16:35:50 +0200 Subject: [PATCH 018/254] Print: add namespace arduino Fixes https://github.com/arduino/Arduino/issues/10025 --- api/Print.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/Print.h b/api/Print.h index f8664123..1357e108 100644 --- a/api/Print.h +++ b/api/Print.h @@ -92,4 +92,5 @@ class Print virtual void flush() { /* Empty implementation for backward compatibility */ } }; -} \ No newline at end of file +} +using namespace arduino; \ No newline at end of file From 932c7c7d4d4d334b10484284cc846672ad59607c Mon Sep 17 00:00:00 2001 From: oclyke Date: Wed, 22 Jul 2020 11:47:57 -0600 Subject: [PATCH 019/254] change declared shiftIn return type to uint8_t --- api/Common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/Common.h b/api/Common.h index 8d288e18..3f4df062 100644 --- a/api/Common.h +++ b/api/Common.h @@ -104,7 +104,7 @@ unsigned long pulseIn(pin_size_t pin, uint8_t state, unsigned long timeout); unsigned long pulseInLong(pin_size_t pin, uint8_t state, unsigned long timeout); void shiftOut(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder, uint8_t val); -pin_size_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder); +uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder); void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode); void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void* param); From cd4ba4ca9ebc3421c65d3b19abe60820b8c4cf25 Mon Sep 17 00:00:00 2001 From: tttapa Date: Mon, 27 Jul 2020 17:33:33 +0200 Subject: [PATCH 020/254] Fix pgm_read_ptr in AVR pgmspace.h Originally, `pgm_read_ptr` used to cast its argument to `const void *`, i.e. a pointer to read-only data. This is incorrect, because the argument is a pointer to a pointer in "flash memory". You cannot cast it to `const void *` and then dereference it, because `void` is not an object type. Also, the pointer itself is read-only, but the data could in theory be mutable. The correct type should be `void *const *`, i.e. a pointer to a read-only pointer to any data. --- api/deprecated-avr-comp/avr/pgmspace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/deprecated-avr-comp/avr/pgmspace.h b/api/deprecated-avr-comp/avr/pgmspace.h index 0f732bba..95897d75 100644 --- a/api/deprecated-avr-comp/avr/pgmspace.h +++ b/api/deprecated-avr-comp/avr/pgmspace.h @@ -103,7 +103,7 @@ typedef const void* uint_farptr_t; #define pgm_read_word(addr) (*(const unsigned short *)(addr)) #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) #define pgm_read_float(addr) (*(const float *)(addr)) -#define pgm_read_ptr(addr) (*(const void *)(addr)) +#define pgm_read_ptr(addr) (*(void *const *)(addr)) #define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_word_near(addr) pgm_read_word(addr) From ffd26512e2891c12b4b095b61599f6faa85c017a Mon Sep 17 00:00:00 2001 From: giulcioffi Date: Tue, 1 Sep 2020 18:21:17 +0200 Subject: [PATCH 021/254] Remove include of Hardware*.h from ArduinoAPI.h --- api/ArduinoAPI.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/api/ArduinoAPI.h b/api/ArduinoAPI.h index 08f1154b..986b006e 100644 --- a/api/ArduinoAPI.h +++ b/api/ArduinoAPI.h @@ -27,9 +27,6 @@ #ifdef __cplusplus #include "Client.h" -#include "HardwareI2C.h" -#include "HardwareSPI.h" -#include "HardwareSerial.h" #include "Interrupts.h" #include "IPAddress.h" #include "Print.h" From 36b6f53a9b0eb287f4e7911c730d99f53ee66821 Mon Sep 17 00:00:00 2001 From: giulcioffi Date: Mon, 28 Sep 2020 17:17:58 +0200 Subject: [PATCH 022/254] Remove include to Client.h from ArduinoAPI.h --- api/ArduinoAPI.h | 1 - 1 file changed, 1 deletion(-) diff --git a/api/ArduinoAPI.h b/api/ArduinoAPI.h index 986b006e..2029617e 100644 --- a/api/ArduinoAPI.h +++ b/api/ArduinoAPI.h @@ -26,7 +26,6 @@ #include "Binary.h" #ifdef __cplusplus -#include "Client.h" #include "Interrupts.h" #include "IPAddress.h" #include "Print.h" From 95a146fa1aa67ff29c4238b3a2d73a12e8bb1fd1 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Tue, 8 Sep 2020 06:43:08 +0200 Subject: [PATCH 023/254] Initial minimal commit to compile a host-run test binary --- test/.gitignore | 1 + test/CMakeLists.txt | 58 + test/external/catch/v2.13.1/include/catch.hpp | 17802 ++++++++++++++++ test/src/main.cpp | 10 + 4 files changed, 17871 insertions(+) create mode 100644 test/.gitignore create mode 100644 test/CMakeLists.txt create mode 100644 test/external/catch/v2.13.1/include/catch.hpp create mode 100644 test/src/main.cpp diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 00000000..c795b054 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1 @@ +build \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 00000000..b2a6c9a1 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,58 @@ +########################################################################## + +cmake_minimum_required(VERSION 2.8) + +########################################################################## + +project(test-ArduinoCore-API) + +########################################################################## + +include_directories(../api) +include_directories(external/catch/v2.13.1/include) + +########################################################################## + +set(CMAKE_CXX_STANDARD 11) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +########################################################################## + +set(TEST_TARGET ${CMAKE_PROJECT_NAME}) + +########################################################################## + +set(TEST_SRCS +) + +set(TEST_DUT_SRCS +) + +########################################################################## + +set(TEST_TARGET_SRCS + src/main.cpp + ${TEST_SRCS} + ${TEST_UTIL_SRCS} + ${TEST_DUT_SRCS} +) + +########################################################################## + +add_compile_definitions(HOST) +add_compile_options(-Wall -Wextra -Wpedantic -Werror) +add_compile_options(-Wno-cast-function-type) + +set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} "--coverage") +set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "--coverage -Wno-deprecated-copy") + +########################################################################## + +add_executable( + ${TEST_TARGET} + ${TEST_TARGET_SRCS} +) + +########################################################################## + diff --git a/test/external/catch/v2.13.1/include/catch.hpp b/test/external/catch/v2.13.1/include/catch.hpp new file mode 100644 index 00000000..94e20c21 --- /dev/null +++ b/test/external/catch/v2.13.1/include/catch.hpp @@ -0,0 +1,17802 @@ +/* + * Catch v2.13.1 + * Generated: 2020-09-07 12:12:38.090364 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +// start catch.hpp + + +#define CATCH_VERSION_MAJOR 2 +#define CATCH_VERSION_MINOR 13 +#define CATCH_VERSION_PATCH 1 + +#ifdef __clang__ +# pragma clang system_header +#elif defined __GNUC__ +# pragma GCC system_header +#endif + +// start catch_suppress_warnings.h + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(push) +# pragma warning(disable: 161 1682) +# else // __ICC +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# endif +#elif defined __GNUC__ + // Because REQUIREs trigger GCC's -Wparentheses, and because still + // supported version of g++ have only buggy support for _Pragmas, + // Wparentheses have to be suppressed globally. +# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details + +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-variable" +# pragma GCC diagnostic ignored "-Wpadded" +#endif +// end catch_suppress_warnings.h +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +# define CATCH_IMPL +# define CATCH_CONFIG_ALL_PARTS +#endif + +// In the impl file, we want to have access to all parts of the headers +// Can also be used to sanely support PCHs +#if defined(CATCH_CONFIG_ALL_PARTS) +# define CATCH_CONFIG_EXTERNAL_INTERFACES +# if defined(CATCH_CONFIG_DISABLE_MATCHERS) +# undef CATCH_CONFIG_DISABLE_MATCHERS +# endif +# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +# endif +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) +// start catch_platform.h + +#ifdef __APPLE__ +# include +# if TARGET_OS_OSX == 1 +# define CATCH_PLATFORM_MAC +# elif TARGET_OS_IPHONE == 1 +# define CATCH_PLATFORM_IPHONE +# endif + +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define CATCH_PLATFORM_LINUX + +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) +# define CATCH_PLATFORM_WINDOWS +#endif + +// end catch_platform.h + +#ifdef CATCH_IMPL +# ifndef CLARA_CONFIG_MAIN +# define CLARA_CONFIG_MAIN_NOT_DEFINED +# define CLARA_CONFIG_MAIN +# endif +#endif + +// start catch_user_interfaces.h + +namespace Catch { + unsigned int rngSeed(); +} + +// end catch_user_interfaces.h +// start catch_tag_alias_autoregistrar.h + +// start catch_common.h + +// start catch_compiler_capabilities.h + +// Detect a number of compiler features - by compiler +// The following features are defined: +// +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_ form +// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +#ifdef __cplusplus + +# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) +# define CATCH_CPP14_OR_GREATER +# endif + +# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +# define CATCH_CPP17_OR_GREATER +# endif + +#endif + +#if defined(__cpp_lib_uncaught_exceptions) +# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#endif + +// We have to avoid both ICC and Clang, because they try to mask themselves +// as gcc, and we want only GCC in this block +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) + +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) + +#endif + +#if defined(__clang__) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) + +// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug +// which results in calls to destructors being emitted for each temporary, +// without a matching initialization. In practice, this can result in something +// like `std::string::~string` being called on an uninitialized value. +// +// For example, this code will likely segfault under IBM XL: +// ``` +// REQUIRE(std::string("12") + "34" == "1234") +// ``` +// +// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. +# if !defined(__ibmxl__) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ +# endif + +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) + +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// Assume that non-Windows platforms support posix signals by default +#if !defined(CATCH_PLATFORM_WINDOWS) + #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS +#endif + +//////////////////////////////////////////////////////////////////////////////// +// We know some environments not to support full POSIX signals +#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) + #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +#endif + +#ifdef __OS400__ +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# define CATCH_CONFIG_COLOUR_NONE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Not all Windows environments support SEH properly +#if defined(__MINGW32__) +# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#endif + +//////////////////////////////////////////////////////////////////////////////// +// PS4 +#if defined(__ORBIS__) +# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Cygwin +#ifdef __CYGWIN__ + +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +# define _BSD_SOURCE +// some versions of cygwin (most) do not support std::to_string. Use the libstd check. +// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 +# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ + && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) + +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING + +# endif +#endif // __CYGWIN__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#if defined(_MSC_VER) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) + +# if _MSC_VER >= 1900 // Visual Studio 2015 or newer +# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +# endif + +// Universal Windows platform does not support SEH +// Or console colours (or console at all...) +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +# define CATCH_CONFIG_COLOUR_NONE +# else +# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH +# endif + +// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ +// _MSVC_TRADITIONAL == 0 means new conformant preprocessor +// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor +# if !defined(__clang__) // Handle Clang masquerading for msvc +# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) +# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +# endif // MSVC_TRADITIONAL +# endif // __clang__ + +#endif // _MSC_VER + +#if defined(_REENTRANT) || defined(_MSC_VER) +// Enable async processing, as -pthread is specified or no additional linking is required +# define CATCH_INTERNAL_CONFIG_USE_ASYNC +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// +// Check if we are compiled with -fno-exceptions or equivalent +#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) +# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED +#endif + +//////////////////////////////////////////////////////////////////////////////// +// DJGPP +#ifdef __DJGPP__ +# define CATCH_INTERNAL_CONFIG_NO_WCHAR +#endif // __DJGPP__ + +//////////////////////////////////////////////////////////////////////////////// +// Embarcadero C++Build +#if defined(__BORLANDC__) + #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// Use of __COUNTER__ is suppressed during code analysis in +// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly +// handled by it. +// Otherwise all supported compilers support COUNTER macro, +// but user still might want to turn it off +#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) + #define CATCH_INTERNAL_CONFIG_COUNTER +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// RTX is a special version of Windows that is real time. +// This means that it is detected as Windows, but does not provide +// the same set of capabilities as real Windows does. +#if defined(UNDER_RTSS) || defined(RTX64_BUILD) + #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH + #define CATCH_INTERNAL_CONFIG_NO_ASYNC + #define CATCH_CONFIG_COLOUR_NONE +#endif + +#if !defined(_GLIBCXX_USE_C99_MATH_TR1) +#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Various stdlib support checks that require __has_include +#if defined(__has_include) + // Check if string_view is available and usable + #if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW + #endif + + // Check if optional is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if byte is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # include + # if __cpp_lib_byte > 0 + # define CATCH_INTERNAL_CONFIG_CPP17_BYTE + # endif + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if variant is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # if defined(__clang__) && (__clang_major__ < 8) + // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 + // fix should be in clang 8, workaround in libstdc++ 8.2 + # include + # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # define CATCH_CONFIG_NO_CPP17_VARIANT + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__clang__) && (__clang_major__ < 8) + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) +#endif // defined(__has_include) + +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) +# define CATCH_CONFIG_COUNTER +#endif +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) +# define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_CONFIG_POSIX_SIGNALS +#endif +// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. +#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) +# define CATCH_CONFIG_WCHAR +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) +# define CATCH_CONFIG_CPP11_TO_STRING +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) +# define CATCH_CONFIG_CPP17_OPTIONAL +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) +# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) +# define CATCH_CONFIG_CPP17_STRING_VIEW +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) +# define CATCH_CONFIG_CPP17_VARIANT +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) +# define CATCH_CONFIG_CPP17_BYTE +#endif + +#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) +# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) +# define CATCH_CONFIG_NEW_CAPTURE +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +# define CATCH_CONFIG_DISABLE_EXCEPTIONS +#endif + +#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) +# define CATCH_CONFIG_POLYFILL_ISNAN +#endif + +#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) +# define CATCH_CONFIG_USE_ASYNC +#endif + +#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) +# define CATCH_CONFIG_ANDROID_LOGWRITE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) +# define CATCH_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Even if we do not think the compiler has that warning, we still have +// to provide a macro that can be used by the code. +#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS +#endif + +// The goal of this macro is to avoid evaluation of the arguments, but +// still have the compiler warn on problems inside... +#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) +#endif + +#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#elif defined(__clang__) && (__clang_major__ < 5) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +#define CATCH_TRY if ((true)) +#define CATCH_CATCH_ALL if ((false)) +#define CATCH_CATCH_ANON(type) if ((false)) +#else +#define CATCH_TRY try +#define CATCH_CATCH_ALL catch (...) +#define CATCH_CATCH_ANON(type) catch (type) +#endif + +#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) +#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#endif + +// end catch_compiler_capabilities.h +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#ifdef CATCH_CONFIG_COUNTER +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#else +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#endif + +#include +#include +#include + +// We need a dummy global operator<< so we can bring it into Catch namespace later +struct Catch_global_namespace_dummy {}; +std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); + +namespace Catch { + + struct CaseSensitive { enum Choice { + Yes, + No + }; }; + + class NonCopyable { + NonCopyable( NonCopyable const& ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable& operator = ( NonCopyable const& ) = delete; + NonCopyable& operator = ( NonCopyable && ) = delete; + + protected: + NonCopyable(); + virtual ~NonCopyable(); + }; + + struct SourceLineInfo { + + SourceLineInfo() = delete; + SourceLineInfo( char const* _file, std::size_t _line ) noexcept + : file( _file ), + line( _line ) + {} + + SourceLineInfo( SourceLineInfo const& other ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo( SourceLineInfo&& ) noexcept = default; + SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; + + bool empty() const noexcept { return file[0] == '\0'; } + bool operator == ( SourceLineInfo const& other ) const noexcept; + bool operator < ( SourceLineInfo const& other ) const noexcept; + + char const* file; + std::size_t line; + }; + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + + // Bring in operator<< from global namespace into Catch namespace + // This is necessary because the overload of operator<< above makes + // lookup stop at namespace Catch + using ::operator<<; + + // Use this in variadic streaming macros to allow + // >> +StreamEndStop + // as well as + // >> stuff +StreamEndStop + struct StreamEndStop { + std::string operator+() const; + }; + template + T const& operator + ( T const& value, StreamEndStop ) { + return value; + } +} + +#define CATCH_INTERNAL_LINEINFO \ + ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) + +// end catch_common.h +namespace Catch { + + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + }; + +} // end namespace Catch + +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + +// end catch_tag_alias_autoregistrar.h +// start catch_test_registry.h + +// start catch_interfaces_testcase.h + +#include + +namespace Catch { + + class TestSpec; + + struct ITestInvoker { + virtual void invoke () const = 0; + virtual ~ITestInvoker(); + }; + + class TestCase; + struct IConfig; + + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + + bool isThrowSafe( TestCase const& testCase, IConfig const& config ); + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector const& getAllTestCasesSorted( IConfig const& config ); + +} + +// end catch_interfaces_testcase.h +// start catch_stringref.h + +#include +#include +#include +#include + +namespace Catch { + + /// A non-owning string class (similar to the forthcoming std::string_view) + /// Note that, because a StringRef may be a substring of another string, + /// it may not be null terminated. + class StringRef { + public: + using size_type = std::size_t; + using const_iterator = const char*; + + private: + static constexpr char const* const s_empty = ""; + + char const* m_start = s_empty; + size_type m_size = 0; + + public: // construction + constexpr StringRef() noexcept = default; + + StringRef( char const* rawChars ) noexcept; + + constexpr StringRef( char const* rawChars, size_type size ) noexcept + : m_start( rawChars ), + m_size( size ) + {} + + StringRef( std::string const& stdString ) noexcept + : m_start( stdString.c_str() ), + m_size( stdString.size() ) + {} + + explicit operator std::string() const { + return std::string(m_start, m_size); + } + + public: // operators + auto operator == ( StringRef const& other ) const noexcept -> bool; + auto operator != (StringRef const& other) const noexcept -> bool { + return !(*this == other); + } + + auto operator[] ( size_type index ) const noexcept -> char { + assert(index < m_size); + return m_start[index]; + } + + public: // named queries + constexpr auto empty() const noexcept -> bool { + return m_size == 0; + } + constexpr auto size() const noexcept -> size_type { + return m_size; + } + + // Returns the current start pointer. If the StringRef is not + // null-terminated, throws std::domain_exception + auto c_str() const -> char const*; + + public: // substrings and searches + // Returns a substring of [start, start + length). + // If start + length > size(), then the substring is [start, size()). + // If start > size(), then the substring is empty. + auto substr( size_type start, size_type length ) const noexcept -> StringRef; + + // Returns the current start pointer. May not be null-terminated. + auto data() const noexcept -> char const*; + + constexpr auto isNullTerminated() const noexcept -> bool { + return m_start[m_size] == '\0'; + } + + public: // iterators + constexpr const_iterator begin() const { return m_start; } + constexpr const_iterator end() const { return m_start + m_size; } + }; + + auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; + auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; + + constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { + return StringRef( rawChars, size ); + } +} // namespace Catch + +constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { + return Catch::StringRef( rawChars, size ); +} + +// end catch_stringref.h +// start catch_preprocessor.hpp + + +#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ +#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) + +#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ +// MSVC needs more evaluations +#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) +#else +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) +#endif + +#define CATCH_REC_END(...) +#define CATCH_REC_OUT + +#define CATCH_EMPTY() +#define CATCH_DEFER(id) id CATCH_EMPTY() + +#define CATCH_REC_GET_END2() 0, CATCH_REC_END +#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 +#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 +#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT +#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) +#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) + +#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) + +#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) + +// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, +// and passes userdata as the first parameter to each invocation, +// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) +#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) +#else +// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) +#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) +#endif + +#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ +#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) + +#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) +#else +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) +#endif + +#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ + CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) + +#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) +#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) +#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) +#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) +#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) +#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) +#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) +#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) +#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) +#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) +#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) + +#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N + +#define INTERNAL_CATCH_TYPE_GEN\ + template struct TypeList {};\ + template\ + constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ + template class...> struct TemplateTypeList{};\ + template class...Cs>\ + constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ + template\ + struct append;\ + template\ + struct rewrap;\ + template class, typename...>\ + struct create;\ + template class, typename>\ + struct convert;\ + \ + template \ + struct append { using type = T; };\ + template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ + struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ + template< template class L1, typename...E1, typename...Rest>\ + struct append, TypeList, Rest...> { using type = L1; };\ + \ + template< template class Container, template class List, typename...elems>\ + struct rewrap, List> { using type = TypeList>; };\ + template< template class Container, template class List, class...Elems, typename...Elements>\ + struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ + \ + template