diff --git a/lib/shared_string/CMakeLists.txt b/lib/shared_string/CMakeLists.txt new file mode 100644 index 00000000..57871f57 --- /dev/null +++ b/lib/shared_string/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright 2023 jacqueline +# +# SPDX-License-Identifier: GPL-3.0-only + +idf_component_register(INCLUDE_DIRS "include") diff --git a/lib/shared_string/LICENSE b/lib/shared_string/LICENSE new file mode 100755 index 00000000..e7e640ee --- /dev/null +++ b/lib/shared_string/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 sschanel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/lib/shared_string/README.md b/lib/shared_string/README.md new file mode 100755 index 00000000..daa7ce45 --- /dev/null +++ b/lib/shared_string/README.md @@ -0,0 +1,31 @@ +# shared_string + +Simple implementation of a shared string in C++ (C++11). + +All it does is wrap up a std::shared_ptr> and give it std::basic_string interface, so it's feels like you're using a regular ol' std::string. Almost all of the implemented methods are thin wrappers around the actual shared string. + +### Methods missing that exist in std::basic_string + +- reserve() +- capacity() +- shrink_to_fit() +- append() +- assign() +- insert() +- erase() +- replace() +- push_front() +- push_back() +- all methods that return a non-const iterator + +It's not meant for manipulating the string underneath. If you need those methods, you should just use std::string. + +Note that you still get operator=() and clear(). + +### Couldn’t I just use const std::string&? + +Sure. But it doesn’t help you if, for instance, you want to use those strings as keys in maps. shared_string allows you to create lots of std::map’s and not incur a penalty for repeating the keys over and over again. + +### Couldn’t I use boost::const_string? + +You bet! And you should. But this has different semantics - if you initialize a shared_string with a const char *, a copy is made, and the shared_string takes ownership of that copy - just like std::string. Just like std::string except that copying a shared_string doesn’t allocate new buffers. diff --git a/lib/shared_string/include/shared_string.h b/lib/shared_string/include/shared_string.h new file mode 100755 index 00000000..f3cbc7ca --- /dev/null +++ b/lib/shared_string/include/shared_string.h @@ -0,0 +1,586 @@ +#pragma once + +#ifndef _SHARED_STRING_H_INCLUDED_ +#define _SHARED_STRING_H_INCLUDED_ + +/** + * basic_shared_string + * + * Copyright (c) 2015 Scott Schanel http://github.com/sschanel/shared_string + * + * License: MIT License + * + * Uses std::shared_ptr internally to keep memory allocation to a minimum. + * This is a boost-less implementation that does not use boost::flyweights. + * That means that if you try hard enough you can outsmart it and do + * things very ineffeciently. + * + * But! If you embrace it, you get all the same methods that basic_string + * has (as of C++11), and you get a true shared string and it's thread-safe. + * Missing methods from basic_string: reserve(), capacity(), shrink_to_fit(). + * append(), assign(), insert(), erase(), replace(), push_front(), push_back(), + * all methods that return a non-const iterator. Almost all of the implemented + * methods are thin wrappers around the shared string. + * + * If you need those methods, make a copy of the internal string by calling + * str() and work on that temporary string. + * + * You still get operator=(). And clear(). + * + * + * + */ + +#include +#include +#include + +template , + class Allocator = std::allocator < CharT > +> +class basic_shared_string { + +public: + typedef std::basic_string string_type; + + typedef typename string_type::const_iterator const_iterator; + typedef typename string_type::const_reverse_iterator const_reverse_iterator; + typedef typename string_type::size_type size_type; + +private: + std::shared_ptr string_; + + void replace_contents(string_type&& newString) { + string_ = std::make_shared(std::move(newString)); + } + +public: + static const size_type npos = (size_t)-1; + + const string_type& str() const { + static const string_type empty; + if (string_.get() != nullptr) { + return *(string_.get()); + } + return empty; + } + + operator const string_type&() { + return str(); + } + + basic_shared_string() { + } + + basic_shared_string(const CharT * s) { + replace_contents(string_type(s)); + } + + basic_shared_string(const string_type& s) { + replace_contents(string_type(s)); + } + + basic_shared_string(string_type&& s) { + replace_contents(std::move(s)); + } + + basic_shared_string(const basic_shared_string& s) { + string_ = s.string_; + } + + void clear() { + string_ = nullptr; + } + + basic_shared_string& operator=(const basic_shared_string& s) { + string_ = s.string_; + return *this; + } + + basic_shared_string& operator=(const string_type& str) { + replace_contents(string_type(str)); + return *this; + } + + basic_shared_string& operator=(string_type&& str) { + replace_contents(std::move(str)); + return *this; + } + + basic_shared_string& operator=(const CharT* s) { + replace_contents(string_type(s)); + return *this; + } + + basic_shared_string& operator=(CharT ch) { + replace_contents(string_type(ch)); + return *this; + } + + basic_shared_string& operator=(std::initializer_list ilist) { + replace_contents(string_type(ilist)); + return *this; + } + + void swap(basic_shared_string& rhs) { + this->string_.swap(rhs.string_); + } + + + CharT at(size_type pos) const { + return str().at(pos); + } + + CharT operator[](size_type pos) const { + return str()[pos]; + } + + CharT front() const { + return str().front(); + } + + CharT back() const { + return str().back(); + } + + const CharT * c_str() const { + return str().c_str(); + } + + const_iterator begin() const { + return str().begin(); + } + + const_iterator cbegin() const { + return str().cbegin(); + } + + const_iterator end() const { + return str().end(); + } + + const_iterator cend() const { + return str().end(); + } + + const_reverse_iterator rbegin() const { + return str().rbegin(); + } + + const_reverse_iterator crbegin() const { + return str().crbegin(); + } + + const_reverse_iterator rend() const { + return str().rend(); + } + + const_reverse_iterator crend() const { + return str().crend(); + } + + + + bool empty() const { + return str().empty(); + } + + size_t size() const { + return str().size(); + } + + size_t length() const { + return str().length(); + } + + size_t max_size() const { + return str().max_size(); + } + + size_t capacity() const { + return str().capacity(); + } + + int compare(const string_type& rhs) const { + return str().compare(rhs); + } + + int compare(const basic_shared_string& rhs) const { + return str().compare(rhs.str()); + } + + int compare(size_type pos1, size_type count1, + const string_type& str) const { + return str().compare(pos1, count1, str); + } + + int compare(const CharT* s) const { + return str().compare(s); + } + + int compare(size_type pos1, size_type count1, + const CharT* s) const { + + return str().compare(pos1, count1, s); + } + + int compare( + size_type pos1, + size_type count1, + const CharT* s, + size_type count2) const { + + return str().compare(pos1, count1, s, count2); + } + + basic_shared_string substr( + size_type pos = 0, + size_type count = npos) const { + + if (pos == 0) { + if (count == npos) { + return *this; + } + else if (count >= str().size()) { + return *this; + } + } + return basic_shared_string(str().substr(pos, count)); + } + + size_type copy( + CharT* dest, + size_type count, + size_type pos = 0) const { + return str().copy(dest, count, pos); + } + + size_type find(const string_type& str, size_type pos = 0) const { + return str().find(str, pos); + } + + size_type find(const CharT* s, size_type pos, size_type count) const { + return str().find(s, pos, count); + } + + size_type find(const CharT* s, size_type pos = 0) const { + return str().find(s, pos); + } + + size_type find(CharT ch, size_type pos = 0) const { + return str().find(ch, pos); + } + + size_type rfind(const string_type& str, size_type pos = npos) const { + return str().rfind(str, pos); + } + + size_type rfind(const CharT* s, size_type pos, size_type count) const { + return str().rfind(s, pos, count); + } + + size_type rfind(const CharT* s, size_type pos = npos) const { + return str().rfind(s, pos); + } + + size_type rfind(CharT ch, size_type pos = npos) const { + return str().rfind(ch, pos); + } + + size_type find_first_of(const string_type& str, size_type pos = 0) const { + return str().find_first_of(str, pos); + } + + size_type find_first_of(const CharT* s, size_type pos, size_type count) const { + return str().find_first_of(s, pos, count); + } + + size_type find_first_of(const CharT* s, size_type pos = 0) const { + return str().find_first_of(s, pos); + } + + size_type find_first_of(CharT ch, size_type pos = 0) const { + return str().find_first_of(ch, pos); + } + + size_type find_first_not_of(const string_type& str, size_type pos = 0) const { + return str().find_first_not_of(str, pos); + } + + size_type find_first_not_of(const CharT* s, size_type pos, size_type count) const { + return str().find_first_not_of(s, pos, count); + } + + size_type find_first_not_of(const CharT* s, size_type pos = 0) const { + return str().find_first_not_of(s, pos); + } + + size_type find_first_not_of(CharT ch, size_type pos = 0) const { + return str().find_first_not_of(ch, pos); + } + + size_type find_last_of(const string_type& str, size_type pos = npos) const { + return str().find_last_of(str, pos); + } + + size_type find_last_of(const CharT* s, size_type pos, size_type count) const { + return str().find_last_of(s, pos, count); + } + + size_type find_last_of(const CharT* s, size_type pos = npos) const { + return str().find_last_of(s, pos); + } + size_type find_last_of(CharT ch, size_type pos = npos) const { + return str().find_last_of(ch, pos); + } + size_type find_last_not_of(const string_type& str, size_type pos = npos) const { + return str().find_last_not_of(str, pos); + } + size_type find_last_not_of(const CharT* s, size_type pos, size_type count) const { + return str().find_last_not_of(s, pos, count); + } + size_type find_last_not_of(const CharT* s, size_type pos = npos) const { + return str().find_last_not_of(s, pos); + } + size_type find_last_not_of(CharT ch, size_type pos = npos) const { + return str().find_last_not_of(ch, pos); + } +}; + +template< class CharT, class Traits, class Alloc > +bool operator==( + const basic_shared_string& lhs, + const basic_shared_string& rhs) { + return lhs.str() == rhs.str(); +} + +template< class CharT, class Traits, class Alloc > +bool operator!=( + const basic_shared_string& lhs, + const basic_shared_string& rhs) { + return lhs.str() != rhs.str(); +} + +template< class CharT, class Traits, class Alloc > +bool operator<( + const basic_shared_string& lhs, + const basic_shared_string& rhs) { + return lhs.str() < rhs.str(); +} + +template< class CharT, class Traits, class Alloc > +bool operator<=( + const basic_shared_string& lhs, + const basic_shared_string& rhs) { + return lhs.str() <= rhs.str(); +} + +template< class CharT, class Traits, class Alloc > +bool operator>( + const basic_shared_string& lhs, + const basic_shared_string& rhs) { + + return lhs.str() > rhs.str(); +} + +template< class CharT, class Traits, class Alloc > +bool operator>=( + const basic_shared_string& lhs, + const basic_shared_string& rhs) { + + return lhs.str() >= rhs.str(); +} + +template< class CharT, class Traits, class Alloc > +bool operator==( + const CharT* lhs, + const basic_shared_string& rhs) { + return operator==(lhs, rhs.str()); +} + +template< class CharT, class Traits, class Alloc > +bool operator==( + const basic_shared_string& lhs, + const CharT* rhs) { + + return operator==(lhs.str(), rhs); +} + +template< class CharT, class Traits, class Alloc > +bool operator!=(const CharT* lhs, const basic_shared_string& rhs) { + return operator!=(lhs, rhs.str()); +} + +template< class CharT, class Traits, class Alloc > +bool operator!=(const basic_shared_string& lhs, const CharT* rhs) { + return operator!=(lhs.str(), rhs); +} + +template< class CharT, class Traits, class Alloc > +bool operator<(const CharT* lhs, const basic_shared_string& rhs) { + return operator<(lhs, rhs.str()); +} + +template< class CharT, class Traits, class Alloc > +bool operator<(const basic_shared_string& lhs, const CharT* rhs) { + return operator<(lhs.str(), rhs); +} + +template< class CharT, class Traits, class Alloc > +bool operator<=(const CharT* lhs, const basic_shared_string& rhs) { + return operator<=(lhs, rhs.str()); +} + +template< class CharT, class Traits, class Alloc > +bool operator<=(const basic_shared_string& lhs, const CharT* rhs) { + return operator<=(lhs.str(), rhs); +} + +template< class CharT, class Traits, class Alloc > +bool operator>(const CharT* lhs, const basic_shared_string& rhs) { + return operator>(lhs, rhs.str()); +} + +template< class CharT, class Traits, class Alloc > +bool operator>(const basic_shared_string& lhs, const CharT* rhs) { + return operator>(lhs.str(), rhs); +} + +template< class CharT, class Traits, class Alloc > +bool operator>=(const CharT* lhs, const basic_shared_string& rhs) { + return operator>=(lhs, rhs.str()); +} + +template< class CharT, class Traits, class Alloc > +bool operator>=(const basic_shared_string& lhs, const CharT* rhs) { + return operator>=(lhs.str(), rhs); +} + + +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const basic_shared_string& str) { + return operator<<(os, str.str()); +} + +template +std::basic_istream& operator>>( + std::basic_istream& is, + basic_shared_string& str) { + + std::basic_string temp; + operator>>(is, temp); + str = temp; + return is; +} + +template< class CharT, class Traits, class Alloc > +basic_shared_string operator+( + const basic_shared_string& lhs, + const basic_shared_string& rhs) { + return basic_shared_string(operator+(lhs.str(), rhs.str())); +} + +template< class CharT, class Traits, class Alloc > +basic_shared_string operator+( + const basic_shared_string& lhs, + const std::basic_string& rhs) { + return basic_shared_string(operator+(lhs.str(), rhs)); +} + +template< class CharT, class Traits, class Alloc > +basic_shared_string operator+( + const std::basic_string& lhs, + const basic_shared_string& rhs) { + return basic_shared_string(operator+(lhs, rhs.str())); +} + +template< class CharT, class Traits, class Alloc > +basic_shared_string operator+( + const CharT* lhs, + const basic_shared_string& rhs) { + + return basic_shared_string(operator+(lhs, rhs.str())); +} + +template< class CharT, class Traits, class Alloc > +basic_shared_string operator+( + CharT lhs, + const basic_shared_string& rhs) { + + return basic_shared_string(operator+(lhs, rhs.str())); +} + +template< class CharT, class Traits, class Alloc > +basic_shared_string operator+( + const basic_shared_string& lhs, + const CharT* rhs) { + + return basic_shared_string(operator+(lhs.str(), rhs)); +} + +template +basic_shared_string operator+( + const basic_shared_string& lhs, + CharT rhs) { + + return basic_shared_string(operator+(lhs.str(), rhs)); +} + +namespace std { + + template + int stoi(const basic_shared_string& str, std::size_t* pos = 0, int base = 10) { + return stoi(str.str(), pos, base); + } + + template + long stol(const basic_shared_string& str, std::size_t* pos = 0, int base = 10) { + return stol(str.str(), pos, base); + } + + template + long long stoll(const basic_shared_string& str, std::size_t* pos = 0, int base = 10) { + return stoll(str.str(), pos, base); + } + + template + unsigned long stoul(const basic_shared_string& str, std::size_t* pos = 0, int base = 10) { + return stoul(str.str(), pos, base); + } + + template + unsigned long long stoull(const basic_shared_string& str, std::size_t* pos = 0, int base = 10) { + return stoull(str.str(), pos, base); + } + + template + float stof(const basic_shared_string& str, std::size_t* pos = 0) { + return stof(str.str(), pos); + } + + template + double stod(const basic_shared_string& str, std::size_t* pos = 0) { + return stod(str.str(), pos); + } + + template + double stold(const basic_shared_string& str, std::size_t* pos = 0) { + return stold(str.str(), pos); + } + + template + struct hash < basic_shared_string > { + size_t operator()(const basic_shared_string& key) { + return hash()(key.str()); + } + }; +} + +typedef basic_shared_string shared_string; +typedef basic_shared_string shared_wstring; + + +#endif // _STRING_REF_H_INCLUDED_ diff --git a/lib/shared_string/shared_string_test/SharedStringTest.cpp b/lib/shared_string/shared_string_test/SharedStringTest.cpp new file mode 100755 index 00000000..3bccf103 --- /dev/null +++ b/lib/shared_string/shared_string_test/SharedStringTest.cpp @@ -0,0 +1,24 @@ +#include "stdafx.h" +#include "CppUnitTest.h" +#include "../shared_string.h" + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +namespace shared_string_test +{ + TEST_CLASS(SharedStringTest) + { + public: + + TEST_METHOD(Assign) { + + shared_string s = "Test"; + + Assert::IsTrue(s == "Test"); + + s = "NO"; + + Assert::IsTrue(s == "NO"); + } + }; +} \ No newline at end of file diff --git a/lib/shared_string/shared_string_test/shared_string_test.sln b/lib/shared_string/shared_string_test/shared_string_test.sln new file mode 100755 index 00000000..2fac5c56 --- /dev/null +++ b/lib/shared_string/shared_string_test/shared_string_test.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared_string_test", "shared_string_test.vcxproj", "{79A93E93-50A8-46A3-A592-604F74C3BBEB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {79A93E93-50A8-46A3-A592-604F74C3BBEB}.Debug|Win32.ActiveCfg = Debug|Win32 + {79A93E93-50A8-46A3-A592-604F74C3BBEB}.Debug|Win32.Build.0 = Debug|Win32 + {79A93E93-50A8-46A3-A592-604F74C3BBEB}.Release|Win32.ActiveCfg = Release|Win32 + {79A93E93-50A8-46A3-A592-604F74C3BBEB}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/lib/shared_string/shared_string_test/shared_string_test.vcxproj b/lib/shared_string/shared_string_test/shared_string_test.vcxproj new file mode 100755 index 00000000..d2423735 --- /dev/null +++ b/lib/shared_string/shared_string_test/shared_string_test.vcxproj @@ -0,0 +1,99 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {79A93E93-50A8-46A3-A592-604F74C3BBEB} + Win32Proj + shared_string_test + + + + DynamicLibrary + true + v120 + Unicode + false + + + DynamicLibrary + false + v120 + true + Unicode + false + + + + + + + + + + + + + true + + + true + + + + Use + Level3 + Disabled + $(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;%(PreprocessorDefinitions) + true + + + Windows + true + $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + Level3 + Use + MaxSpeed + true + true + $(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + + + + + + Create + Create + + + + + + + \ No newline at end of file diff --git a/lib/shared_string/shared_string_test/shared_string_test.vcxproj.filters b/lib/shared_string/shared_string_test/shared_string_test.vcxproj.filters new file mode 100755 index 00000000..1ee25f1b --- /dev/null +++ b/lib/shared_string/shared_string_test/shared_string_test.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/lib/shared_string/shared_string_test/stdafx.cpp b/lib/shared_string/shared_string_test/stdafx.cpp new file mode 100755 index 00000000..539b4668 --- /dev/null +++ b/lib/shared_string/shared_string_test/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// shared_string_test.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/lib/shared_string/shared_string_test/stdafx.h b/lib/shared_string/shared_string_test/stdafx.h new file mode 100755 index 00000000..fde457b1 --- /dev/null +++ b/lib/shared_string/shared_string_test/stdafx.h @@ -0,0 +1,6 @@ +#pragma once + +#include "targetver.h" + +#include "CppUnitTest.h" + diff --git a/lib/shared_string/shared_string_test/targetver.h b/lib/shared_string/shared_string_test/targetver.h new file mode 100755 index 00000000..87c0086d --- /dev/null +++ b/lib/shared_string/shared_string_test/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/tools/cmake/common.cmake b/tools/cmake/common.cmake index b2e6de48..a94f498f 100644 --- a/tools/cmake/common.cmake +++ b/tools/cmake/common.cmake @@ -19,6 +19,7 @@ list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/lvgl") list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/result") list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/span") list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/stb_vorbis") +list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/shared_string") list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/tinyfsm") include($ENV{IDF_PATH}/tools/cmake/project.cmake)