parent
cde8002df4
commit
aee0474191
@ -0,0 +1,5 @@ |
|||||||
|
# Copyright 2023 jacqueline <me@jacqueline.id.au> |
||||||
|
# |
||||||
|
# SPDX-License-Identifier: GPL-3.0-only |
||||||
|
|
||||||
|
idf_component_register(INCLUDE_DIRS "include") |
@ -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. |
||||||
|
|
@ -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. |
@ -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_
|
@ -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"); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
@ -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
|
@ -0,0 +1,6 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "targetver.h" |
||||||
|
|
||||||
|
#include "CppUnitTest.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> |
Loading…
Reference in new issue