summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-06-23 15:31:45 +1000
committerjacqueline <me@jacqueline.id.au>2023-06-23 15:31:45 +1000
commitaee0474191aa6b4e4505e3f5a74b4ac8cc48063b (patch)
treef899ca369fa64975dc4c8f6d005d7aa1842045cd
parentcde8002df4a86a2a6efd4aa0b5c174b2f39f7bf7 (diff)
downloadtangara-fw-aee0474191aa6b4e4505e3f5a74b4ac8cc48063b.tar.gz
Add a shared string library
-rw-r--r--lib/shared_string/CMakeLists.txt5
-rwxr-xr-xlib/shared_string/LICENSE22
-rwxr-xr-xlib/shared_string/README.md31
-rwxr-xr-xlib/shared_string/include/shared_string.h586
-rwxr-xr-xlib/shared_string/shared_string_test/SharedStringTest.cpp24
-rwxr-xr-xlib/shared_string/shared_string_test/shared_string_test.sln22
-rwxr-xr-xlib/shared_string/shared_string_test/shared_string_test.vcxproj99
-rwxr-xr-xlib/shared_string/shared_string_test/shared_string_test.vcxproj.filters36
-rwxr-xr-xlib/shared_string/shared_string_test/stdafx.cpp8
-rwxr-xr-xlib/shared_string/shared_string_test/stdafx.h6
-rwxr-xr-xlib/shared_string/shared_string_test/targetver.h8
-rw-r--r--tools/cmake/common.cmake1
12 files changed, 848 insertions, 0 deletions
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 <me@jacqueline.id.au>
+#
+# 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<const std::basic_string<CharT>> 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<shared_string, MyType>’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 <string>
+#include <memory>
+#include <functional>
+
+template <typename CharT,
+ class Traits = std::char_traits<CharT>,
+ class Allocator = std::allocator < CharT >
+>
+class basic_shared_string {
+
+public:
+ typedef std::basic_string<CharT, Traits, Allocator> 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<const string_type> string_;
+
+ void replace_contents(string_type&& newString) {
+ string_ = std::make_shared<const string_type>(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<CharT> 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<CharT> 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<CharT, Traits, Alloc>& lhs,
+ const basic_shared_string<CharT, Traits, Alloc>& rhs) {
+ return lhs.str() == rhs.str();
+}
+
+template< class CharT, class Traits, class Alloc >
+bool operator!=(
+ const basic_shared_string<CharT, Traits, Alloc>& lhs,
+ const basic_shared_string<CharT, Traits, Alloc>& rhs) {
+ return lhs.str() != rhs.str();
+}
+
+template< class CharT, class Traits, class Alloc >
+bool operator<(
+ const basic_shared_string<CharT, Traits, Alloc>& lhs,
+ const basic_shared_string<CharT, Traits, Alloc>& rhs) {
+ return lhs.str() < rhs.str();
+}
+
+template< class CharT, class Traits, class Alloc >
+bool operator<=(
+ const basic_shared_string<CharT, Traits, Alloc>& lhs,
+ const basic_shared_string<CharT, Traits, Alloc>& rhs) {
+ return lhs.str() <= rhs.str();
+}
+
+template< class CharT, class Traits, class Alloc >
+bool operator>(
+ const basic_shared_string<CharT, Traits, Alloc>& lhs,
+ const basic_shared_string<CharT, Traits, Alloc>& rhs) {
+
+ return lhs.str() > rhs.str();
+}
+
+template< class CharT, class Traits, class Alloc >
+bool operator>=(
+ const basic_shared_string<CharT, Traits, Alloc>& lhs,
+ const basic_shared_string<CharT, Traits, Alloc>& rhs) {
+
+ return lhs.str() >= rhs.str();
+}
+
+template< class CharT, class Traits, class Alloc >
+bool operator==(
+ const CharT* lhs,
+ const basic_shared_string<CharT, Traits, Alloc>& rhs) {
+ return operator==(lhs, rhs.str());
+}
+
+template< class CharT, class Traits, class Alloc >
+bool operator==(
+ const basic_shared_string<CharT, Traits, Alloc>& 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<CharT, Traits, Alloc>& rhs) {
+ return operator!=(lhs, rhs.str());
+}
+
+template< class CharT, class Traits, class Alloc >
+bool operator!=(const basic_shared_string<CharT, Traits, Alloc>& 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<CharT, Traits, Alloc>& rhs) {
+ return operator<(lhs, rhs.str());
+}
+
+template< class CharT, class Traits, class Alloc >
+bool operator<(const basic_shared_string<CharT, Traits, Alloc>& 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<CharT, Traits, Alloc>& rhs) {
+ return operator<=(lhs, rhs.str());
+}
+
+template< class CharT, class Traits, class Alloc >
+bool operator<=(const basic_shared_string<CharT, Traits, Alloc>& 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<CharT, Traits, Alloc>& rhs) {
+ return operator>(lhs, rhs.str());
+}
+
+template< class CharT, class Traits, class Alloc >
+bool operator>(const basic_shared_string<CharT, Traits, Alloc>& 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<CharT, Traits, Alloc>& rhs) {
+ return operator>=(lhs, rhs.str());
+}
+
+template< class CharT, class Traits, class Alloc >
+bool operator>=(const basic_shared_string<CharT, Traits, Alloc>& lhs, const CharT* rhs) {
+ return operator>=(lhs.str(), rhs);
+}
+
+
+template <class CharT, class Traits, class Allocator>
+std::basic_ostream<CharT, Traits>& operator<<(
+ std::basic_ostream<CharT, Traits>& os,
+ const basic_shared_string<CharT, Traits, Allocator>& str) {
+ return operator<<(os, str.str());
+}
+
+template <class CharT, class Traits, class Allocator>
+std::basic_istream<CharT, Traits>& operator>>(
+ std::basic_istream<CharT, Traits>& is,
+ basic_shared_string<CharT, Traits, Allocator>& str) {
+
+ std::basic_string<CharT, Traits, Allocator> temp;
+ operator>>(is, temp);
+ str = temp;
+ return is;
+}
+
+template< class CharT, class Traits, class Alloc >
+basic_shared_string<CharT, Traits, Alloc> operator+(
+ const basic_shared_string<CharT, Traits, Alloc>& lhs,
+ const basic_shared_string<CharT, Traits, Alloc>& rhs) {
+ return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs.str(), rhs.str()));
+}
+
+template< class CharT, class Traits, class Alloc >
+basic_shared_string<CharT, Traits, Alloc> operator+(
+ const basic_shared_string<CharT, Traits, Alloc>& lhs,
+ const std::basic_string<CharT, Traits, Alloc>& rhs) {
+ return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs.str(), rhs));
+}
+
+template< class CharT, class Traits, class Alloc >
+basic_shared_string<CharT, Traits, Alloc> operator+(
+ const std::basic_string<CharT, Traits, Alloc>& lhs,
+ const basic_shared_string<CharT, Traits, Alloc>& rhs) {
+ return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs, rhs.str()));
+}
+
+template< class CharT, class Traits, class Alloc >
+basic_shared_string<CharT, Traits, Alloc> operator+(
+ const CharT* lhs,
+ const basic_shared_string<CharT, Traits, Alloc>& rhs) {
+
+ return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs, rhs.str()));
+}
+
+template< class CharT, class Traits, class Alloc >
+basic_shared_string<CharT, Traits, Alloc> operator+(
+ CharT lhs,
+ const basic_shared_string<CharT, Traits, Alloc>& rhs) {
+
+ return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs, rhs.str()));
+}
+
+template< class CharT, class Traits, class Alloc >
+basic_shared_string<CharT, Traits, Alloc> operator+(
+ const basic_shared_string<CharT, Traits, Alloc>& lhs,
+ const CharT* rhs) {
+
+ return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs.str(), rhs));
+}
+
+template<class CharT, class Traits, class Alloc>
+basic_shared_string<CharT, Traits, Alloc> operator+(
+ const basic_shared_string<CharT, Traits, Alloc>& lhs,
+ CharT rhs) {
+
+ return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs.str(), rhs));
+}
+
+namespace std {
+
+ template <class CharT, class Traits, class Alloc>
+ int stoi(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0, int base = 10) {
+ return stoi(str.str(), pos, base);
+ }
+
+ template <class CharT, class Traits, class Alloc>
+ long stol(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0, int base = 10) {
+ return stol(str.str(), pos, base);
+ }
+
+ template <class CharT, class Traits, class Alloc>
+ long long stoll(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0, int base = 10) {
+ return stoll(str.str(), pos, base);
+ }
+
+ template <class CharT, class Traits, class Alloc>
+ unsigned long stoul(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0, int base = 10) {
+ return stoul(str.str(), pos, base);
+ }
+
+ template <class CharT, class Traits, class Alloc>
+ unsigned long long stoull(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0, int base = 10) {
+ return stoull(str.str(), pos, base);
+ }
+
+ template <class CharT, class Traits, class Alloc>
+ float stof(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0) {
+ return stof(str.str(), pos);
+ }
+
+ template <class CharT, class Traits, class Alloc>
+ double stod(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0) {
+ return stod(str.str(), pos);
+ }
+
+ template <class CharT, class Traits, class Alloc>
+ double stold(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0) {
+ return stold(str.str(), pos);
+ }
+
+ template <class CharT>
+ struct hash < basic_shared_string<CharT> > {
+ size_t operator()(const basic_shared_string<CharT>& key) {
+ return hash<std::string>()(key.str());
+ }
+ };
+}
+
+typedef basic_shared_string<char> shared_string;
+typedef basic_shared_string<wchar_t> 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{79A93E93-50A8-46A3-A592-604F74C3BBEB}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>shared_string_test</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v120</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v120</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <UseFullPaths>true</UseFullPaths>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <UseFullPaths>true</UseFullPaths>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\shared_string.h" />
+ <ClInclude Include="stdafx.h" />
+ <ClInclude Include="targetver.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="stdafx.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="SharedStringTest.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="stdafx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="targetver.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\shared_string.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="stdafx.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="SharedStringTest.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ 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 <SDKDDKVer.h>
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)