safer_string_typedef.hpp
581 lines
| 21.1 KiB
| text/x-c++hdr
|
CppLexer
r4 | #ifndef OPAQUE_EXPERIMENTAL_SAFER_STRING_TYPEDEF_HPP | |||
#define OPAQUE_EXPERIMENTAL_SAFER_STRING_TYPEDEF_HPP | ||||
// | ||||
// Copyright (c) 2016 | ||||
// Kyle Markley. All rights reserved. | ||||
// | ||||
// Redistribution and use in source and binary forms, with or without | ||||
// modification, are permitted provided that the following conditions are met: | ||||
// | ||||
// 1. Redistributions of source code must retain the above copyright notice, | ||||
// this list of conditions and the following disclaimer. | ||||
// 2. Redistributions in binary form must reproduce the above copyright notice, | ||||
// this list of conditions and the following disclaimer in the documentation | ||||
// and/or other materials provided with the distribution. | ||||
// 3. Neither the name of the author nor the names of any contributors may be | ||||
// used to endorse or promote products derived from this software without | ||||
// specific prior written permission. | ||||
// | ||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
// POSSIBILITY OF SUCH DAMAGE. | ||||
// | ||||
#include "../data.hpp" | ||||
#include <memory> | ||||
#include <string> | ||||
namespace opaque { | ||||
namespace experimental { | ||||
/// \addtogroup typedefs | ||||
/// @{ | ||||
/// | ||||
/// Safer string opaque typedef base type | ||||
/// | ||||
/// This is an opaque typedef base class for standard strings, but without | ||||
/// interoperability with character arrays in ways that would modify the | ||||
/// opaque object or create new opaque object instances. | ||||
/// | ||||
/// Template arguments: | ||||
/// -# S : The string type (e.g. std::string) | ||||
/// -# R : The result type, your subclass | ||||
/// | ||||
template <typename S, typename R> | ||||
struct safer_string_typedef : data<S,R> { | ||||
private: | ||||
using base = opaque::data<S,R>; | ||||
public: | ||||
using typename base::underlying_type; | ||||
using typename base::opaque_type; | ||||
using base::value; | ||||
typedef typename S::traits_type traits_type; | ||||
typedef typename S::value_type value_type; | ||||
typedef typename S::allocator_type allocator_type; | ||||
typedef typename S::size_type size_type; | ||||
typedef typename S::difference_type difference_type; | ||||
typedef typename S::reference reference; | ||||
typedef typename S::const_reference const_reference; | ||||
typedef typename S::pointer pointer; | ||||
typedef typename S::const_pointer const_pointer; | ||||
typedef typename S::iterator iterator; | ||||
typedef typename S::const_iterator const_iterator; | ||||
typedef typename S::reverse_iterator reverse_iterator; | ||||
typedef typename S::const_reverse_iterator const_reverse_iterator; | ||||
static const size_type npos = size_type(0)-size_type(1); | ||||
private: | ||||
typedef allocator_type Allocator; | ||||
typedef typename std::allocator_traits<Allocator>::value_type charT; | ||||
public: | ||||
// | ||||
// Constructor philosophy | ||||
// | ||||
// 1) Provide for explicit construction from an instance of underlying_type. | ||||
// | ||||
// 2) Constructors that have an argument of underlying_type are provided in | ||||
// in two flavors: an explicit one taking underlying_type, and one taking | ||||
// opaque_type that has the explicitness of the original. | ||||
// | ||||
// 3) Constructors that do not have an argument of underlying_type are made | ||||
// explicit. | ||||
// | ||||
explicit safer_string_typedef(const underlying_type& str) noexcept | ||||
: base(str) { } | ||||
explicit safer_string_typedef( underlying_type&& str) noexcept | ||||
: base(std::move(str)) { } | ||||
// | ||||
// The default constructor has the C++14 interface; a zero-argument | ||||
// form (defaulted below) and a single-argument form taking an Allocator. | ||||
// | ||||
explicit safer_string_typedef(const Allocator& a) | ||||
: base(a) { } | ||||
explicit safer_string_typedef(const underlying_type& str, size_type pos, | ||||
size_type n = npos, const Allocator& a = Allocator()) | ||||
: base(str.value, pos, n, a) { } | ||||
safer_string_typedef(const opaque_type& str, size_type pos, | ||||
size_type n = npos, const Allocator& a = Allocator()) | ||||
: base(str.value, pos, n, a) { } | ||||
explicit safer_string_typedef(const charT* s, size_type n, | ||||
const Allocator& a = Allocator()) | ||||
: base(s, n, a) { } | ||||
explicit safer_string_typedef(const charT* s, | ||||
const Allocator& a = Allocator()) | ||||
: base(s, a) { } | ||||
explicit safer_string_typedef(size_type n, charT c, | ||||
const Allocator& a = Allocator()) | ||||
: base(n, c, a) { } | ||||
template <class InputIterator> | ||||
explicit safer_string_typedef(InputIterator Begin, InputIterator End, | ||||
const Allocator& a = Allocator()) | ||||
: base(Begin, End, a) { } | ||||
explicit safer_string_typedef(std::initializer_list<charT> il, | ||||
const Allocator& a = Allocator()) | ||||
: base(il, a) { } | ||||
explicit safer_string_typedef(const underlying_type& str, const Allocator& a) | ||||
: base(str.value, a) { } | ||||
explicit safer_string_typedef(underlying_type&& str, const Allocator& a) | ||||
: base(std::move(str.value), a) { } | ||||
safer_string_typedef(const opaque_type& str, const Allocator& a) | ||||
: base(str.value, a) { } | ||||
safer_string_typedef(opaque_type&& str, const Allocator& a) | ||||
: base(std::move(str.value), a) { } | ||||
// opaque_type& operator=(const charT* s); | ||||
opaque_type& operator=(charT c) { | ||||
value = c; | ||||
return downcast(); | ||||
} | ||||
opaque_type& operator=(std::initializer_list<charT> il) { | ||||
value = il; | ||||
return downcast(); | ||||
} | ||||
iterator begin() noexcept { return value.begin() ; } | ||||
const_iterator begin() const noexcept { return value.begin() ; } | ||||
iterator end() noexcept { return value.end() ; } | ||||
const_iterator end() const noexcept { return value.end() ; } | ||||
reverse_iterator rbegin() noexcept { return value.rbegin() ; } | ||||
const_reverse_iterator rbegin() const noexcept { return value.rbegin() ; } | ||||
reverse_iterator rend() noexcept { return value.rend() ; } | ||||
const_reverse_iterator rend() const noexcept { return value.rend() ; } | ||||
const_iterator cbegin() const noexcept { return value.cbegin() ; } | ||||
const_iterator cend() const noexcept { return value.cend() ; } | ||||
const_reverse_iterator crbegin() const noexcept { return value.crbegin(); } | ||||
const_reverse_iterator crend() const noexcept { return value.crend() ; } | ||||
size_type size() const noexcept { return value.size(); } | ||||
size_type length() const noexcept { return value.length(); } | ||||
size_type max_size() const noexcept { return value.max_size(); } | ||||
void resize(size_type n, charT c) { return value.resize(n, c); } | ||||
void resize(size_type n) { return value.resize(n); } | ||||
size_type capacity() const noexcept { return value.capacity(); } | ||||
void reserve(size_type res_arg = 0) { return value.reserve(res_arg); } | ||||
void shrink_to_fit() { return value.shrink_to_fit(); } | ||||
void clear() noexcept { return value.clear(); } | ||||
bool empty() const noexcept { return value.empty(); } | ||||
const_reference operator[](size_type pos) const { return value[pos]; } | ||||
reference operator[](size_type pos) { return value[pos]; } | ||||
const_reference at(size_type n) const { return value.at(n); } | ||||
reference at(size_type n) { return value.at(n); } | ||||
const charT& front() const { return value.front(); } | ||||
charT& front() { return value.front(); } | ||||
const charT& back() const { return value.back(); } | ||||
charT& back() { return value.back(); } | ||||
opaque_type& operator+=(const opaque_type& str) { | ||||
value += str.value; | ||||
return downcast(); | ||||
} | ||||
// opaque_type& operator+=(const charT* s); | ||||
opaque_type& operator+=(charT c) { | ||||
value += c; | ||||
return downcast(); | ||||
} | ||||
opaque_type& operator+=(std::initializer_list<charT> il) { | ||||
value += il; | ||||
return downcast(); | ||||
} | ||||
opaque_type& append(const opaque_type& str) { | ||||
value.append(str.value); | ||||
return downcast(); | ||||
} | ||||
// C++14 interface | ||||
opaque_type& append(const opaque_type& str, size_type pos, | ||||
size_type n = npos) { | ||||
value.append(str.value, pos, n); | ||||
return downcast(); | ||||
} | ||||
//opaque_type& append(const charT* s, size_type n); | ||||
//opaque_type& append(const charT* s); | ||||
opaque_type& append(size_type n, charT c) { | ||||
value.append(n, c); | ||||
return downcast(); | ||||
} | ||||
template <class InputIterator> | ||||
opaque_type& append(InputIterator first, InputIterator last) { | ||||
value.append(first, last); | ||||
return downcast(); | ||||
} | ||||
opaque_type& append(std::initializer_list<charT> il) { | ||||
value.append(il); | ||||
return downcast(); | ||||
} | ||||
void push_back(charT c) { | ||||
return value.push_back(c); | ||||
} | ||||
opaque_type& assign(const opaque_type& str) { | ||||
value.assign(str.value); | ||||
return downcast(); | ||||
} | ||||
opaque_type& assign(opaque_type&& str) noexcept { | ||||
value.assign(std::move(str.value)); | ||||
return downcast(); | ||||
} | ||||
// C++14 interface | ||||
opaque_type& assign(const opaque_type& str, size_type pos, | ||||
size_type n = npos) { | ||||
value.assign(str.value, pos, n); | ||||
return downcast(); | ||||
} | ||||
// opaque_type& assign(const charT* s, size_type n); | ||||
// opaque_type& assign(const charT* s); | ||||
opaque_type& assign(size_type n, charT c) { | ||||
value.assign(n, c); | ||||
return downcast(); | ||||
} | ||||
template <class InputIterator> | ||||
opaque_type& assign(InputIterator first, InputIterator last) { | ||||
value.assign(first, last); | ||||
return downcast(); | ||||
} | ||||
opaque_type& assign(std::initializer_list<charT> il) { | ||||
value.assign(il); | ||||
return downcast(); | ||||
} | ||||
opaque_type& insert(size_type pos1, const opaque_type& str) { | ||||
value.insert(pos1, str.value); | ||||
return downcast(); | ||||
} | ||||
// C++14 interface | ||||
opaque_type& insert(size_type pos1, const opaque_type& str, | ||||
size_type pos2, size_type n = npos) { | ||||
value.insert(pos1, str.value, pos2, n); | ||||
return downcast(); | ||||
} | ||||
// opaque_type& insert(size_type pos, const charT* s, size_type n); | ||||
// opaque_type& insert(size_type pos, const charT* s); | ||||
opaque_type& insert(size_type pos, size_type n, charT c) { | ||||
value.insert(pos, n, c); | ||||
return downcast(); | ||||
} | ||||
// C++03 interface | ||||
iterator insert(iterator p, charT c) { | ||||
return insert(p, c); | ||||
} | ||||
// C++03 interface | ||||
iterator insert(iterator p, size_type n, charT c) { | ||||
return insert(p, n, c); | ||||
} | ||||
// C++03 interface | ||||
template <class InputIterator> | ||||
iterator insert(iterator p, InputIterator first, InputIterator last) { | ||||
return insert(p, first, last); | ||||
} | ||||
iterator insert(const_iterator p, charT c) { | ||||
return insert(p, c); | ||||
} | ||||
iterator insert(const_iterator p, size_type n, charT c) { | ||||
return insert(p, n, c); | ||||
} | ||||
template <class InputIterator> | ||||
iterator insert(const_iterator p, InputIterator first, InputIterator last) { | ||||
return insert(p, first, last); | ||||
} | ||||
iterator insert(const_iterator p, std::initializer_list<charT> il) { | ||||
return insert(p, il); | ||||
} | ||||
opaque_type& erase(size_type pos = 0, size_type n = npos) { | ||||
value.erase(pos, n); | ||||
return downcast(); | ||||
} | ||||
// C++03 interface | ||||
iterator erase(iterator p) { | ||||
return value.erase(p); | ||||
} | ||||
// C++03 interface | ||||
iterator erase(iterator first, iterator last) { | ||||
return value.erase(first, last); | ||||
} | ||||
iterator erase(const_iterator p) { | ||||
return value.erase(p); | ||||
} | ||||
iterator erase(const_iterator first, const_iterator last) { | ||||
return value.erase(first, last); | ||||
} | ||||
void pop_back() { return value.pop_back(); } | ||||
opaque_type& replace(size_type pos1, size_type n1, const opaque_type& str) { | ||||
value.replace(pos1, n1, str.value); | ||||
return downcast(); | ||||
} | ||||
// C++14 interface | ||||
opaque_type& replace(size_type pos1, size_type n1, const opaque_type& str, | ||||
size_type pos2, size_type n2 = npos) { | ||||
value.replace(pos1, n1, str.value, pos2, n2); | ||||
return downcast(); | ||||
} | ||||
// opaque_type& replace(size_type pos, size_type n1, const charT* s, | ||||
// size_type n2); | ||||
// opaque_type& replace(size_type pos, size_type n1, const charT* s); | ||||
opaque_type& replace(size_type pos, size_type n1, size_type n2, charT c) { | ||||
value.replace(pos, n1, n2, c); | ||||
return downcast(); | ||||
} | ||||
opaque_type& replace(const_iterator i1, const_iterator i2, | ||||
const opaque_type& str) { | ||||
value.replace(i1, i2, str.value); | ||||
return downcast(); | ||||
} | ||||
opaque_type& replace(const_iterator i1, const_iterator i2, | ||||
const charT* s, size_type n) { | ||||
value.replace(i1, i2, s, n); | ||||
return downcast(); | ||||
} | ||||
opaque_type& replace(const_iterator i1, const_iterator i2, | ||||
const charT* s) { | ||||
value.replace(i1, i2, s); | ||||
return downcast(); | ||||
} | ||||
opaque_type& replace(const_iterator i1, const_iterator i2, | ||||
size_type n, charT c) { | ||||
value.replace(i1, i2, n, c); | ||||
return downcast(); | ||||
} | ||||
template <class InputIterator> | ||||
opaque_type& replace(const_iterator i1, const_iterator i2, | ||||
InputIterator j1, InputIterator j2) { | ||||
value.replace(i1, i2, j1, j2); | ||||
return downcast(); | ||||
} | ||||
opaque_type& replace(const_iterator i1, const_iterator i2, | ||||
std::initializer_list<charT> il) { | ||||
value.replace(i1, i2, il); | ||||
return downcast(); | ||||
} | ||||
size_type copy(charT* s, size_type n, size_type pos = 0) const { | ||||
return value.copy(s, n, pos); | ||||
} | ||||
void swap(opaque_type& str) { return value.swap(str.value); } | ||||
const charT* c_str() const noexcept { return value.c_str(); } | ||||
const charT* data() const noexcept { return value.data(); } | ||||
allocator_type get_allocator() const noexcept { | ||||
return value.get_allocator(); | ||||
} | ||||
size_type find (const opaque_type& str, size_type pos = 0) const noexcept { | ||||
return value.find(str.value, pos); | ||||
} | ||||
size_type find (const charT* s, size_type pos, size_type n) const { | ||||
return value.find(s, pos, n); | ||||
} | ||||
size_type find (const charT* s, size_type pos = 0) const { | ||||
return value.find(s, pos); | ||||
} | ||||
size_type find (charT c, size_type pos = 0) const noexcept { | ||||
return value.find(c, pos); | ||||
} | ||||
size_type rfind(const opaque_type& str, size_type pos = npos) const noexcept { | ||||
return value.rfind(str.value, pos); | ||||
} | ||||
size_type rfind(const charT* s, size_type pos, size_type n) const { | ||||
return value.rfind(s, pos, n); | ||||
} | ||||
size_type rfind(const charT* s, size_type pos = npos) const { | ||||
return value.rfind(s, pos); | ||||
} | ||||
size_type rfind(charT c, size_type pos = npos) const noexcept { | ||||
return value.rfind(c, pos); | ||||
} | ||||
size_type find_first_of(const opaque_type& str, size_type pos = 0) const noexcept { | ||||
return value.find_first_of(str.value, pos); | ||||
} | ||||
size_type find_first_of(const charT* s, size_type pos, size_type n) const { | ||||
return value.find_first_of(s, pos, n); | ||||
} | ||||
size_type find_first_of(const charT* s, size_type pos = 0) const { | ||||
return value.find_first_of(s, pos); | ||||
} | ||||
size_type find_first_of(charT c, size_type pos = 0) const noexcept { | ||||
return value.find_first_of(c, pos); | ||||
} | ||||
size_type find_last_of (const opaque_type& str, size_type pos = npos) const noexcept { | ||||
return value.find_last_of(str.value, pos); | ||||
} | ||||
size_type find_last_of (const charT* s, size_type pos, size_type n) const { | ||||
return value.find_last_of(s, pos, n); | ||||
} | ||||
size_type find_last_of (const charT* s, size_type pos = npos) const { | ||||
return value.find_last_of(s, pos); | ||||
} | ||||
size_type find_last_of (charT c, size_type pos = npos) const noexcept { | ||||
return value.find_last_of(c, pos); | ||||
} | ||||
size_type find_first_not_of(const opaque_type& str, size_type pos = 0) const noexcept { | ||||
return value.find_first_not_of(str.value, pos); | ||||
} | ||||
size_type find_first_not_of(const charT* s, size_type pos, size_type n) const { | ||||
return value.find_first_not_of(s, pos, n); | ||||
} | ||||
size_type find_first_not_of(const charT* s, size_type pos = 0) const { | ||||
return value.find_first_not_of(s, pos); | ||||
} | ||||
size_type find_first_not_of(charT c, size_type pos = 0) const noexcept { | ||||
return value.find_first_not_of(c, pos); | ||||
} | ||||
size_type find_last_not_of (const opaque_type& str, size_type pos = npos) const noexcept { | ||||
return value.find_last_not_of(str.value, pos); | ||||
} | ||||
size_type find_last_not_of (const charT* s, size_type pos, size_type n) const { | ||||
return value.find_last_not_of(s, pos, n); | ||||
} | ||||
size_type find_last_not_of (const charT* s, size_type pos = npos) const { | ||||
return value.find_last_not_of(s, pos); | ||||
} | ||||
size_type find_last_not_of (charT c, size_type pos = npos) const noexcept { | ||||
return value.find_last_not_of(c, pos); | ||||
} | ||||
opaque_type substr(size_type pos = 0, size_type n = npos) const { | ||||
return opaque_type(value.substr(pos, n)); | ||||
} | ||||
int compare(const opaque_type& str) const noexcept { | ||||
return value.compare(str.value); | ||||
} | ||||
int compare(size_type pos1, size_type n1, const opaque_type& str) const { | ||||
return value.compare(pos1, n1, str.value); | ||||
} | ||||
// C++14 interface | ||||
int compare(size_type pos1, size_type n1, const opaque_type& str, | ||||
size_type pos2, size_type n2 = npos) const { | ||||
return value.compare(pos1, n1, str.value, pos2, n2); | ||||
} | ||||
int compare(const charT* s) const { | ||||
return value.compare(s); | ||||
} | ||||
int compare(size_type pos1, size_type n1, const charT* s) const { | ||||
return value.compare(pos1, n1, s); | ||||
} | ||||
int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const { | ||||
return value.compare(pos1, n1, s, n2); | ||||
} | ||||
friend opaque_type operator+(const opaque_type& l, const opaque_type& r) { | ||||
return opaque_type( l.value + r.value ); | ||||
} | ||||
friend opaque_type operator+( opaque_type&& l, const opaque_type& r) { | ||||
return opaque_type(std::move(l.value) + r.value ); | ||||
} | ||||
friend opaque_type operator+(const opaque_type& l, opaque_type&& r) { | ||||
return opaque_type( l.value + std::move(r.value)); | ||||
} | ||||
friend opaque_type operator+( opaque_type&& l, opaque_type&& r) { | ||||
return opaque_type(std::move(l.value) + std::move(r.value)); | ||||
} | ||||
// friend opaque_type operator+(const charT* lhs, const opaque_type& rhs); | ||||
// friend opaque_type operator+(const charT* lhs, opaque_type&& rhs); | ||||
friend opaque_type operator+( charT lhs, const opaque_type& rhs) { | ||||
return lhs + rhs.value ; | ||||
} | ||||
friend opaque_type operator+( charT lhs, opaque_type&& rhs) { | ||||
return lhs + std::move(rhs.value); | ||||
} | ||||
// friend opaque_type operator+(const opaque_type& lhs, const charT* rhs); | ||||
// friend opaque_type operator+( opaque_type&& lhs, const charT* rhs); | ||||
friend opaque_type operator+(const opaque_type& lhs, charT rhs) { | ||||
return lhs.value + rhs; | ||||
} | ||||
friend opaque_type operator+( opaque_type&& lhs, charT rhs) { | ||||
return std::move(lhs.value) + rhs; | ||||
} | ||||
friend bool operator==(const opaque_type& lhs, const opaque_type& rhs) { | ||||
return lhs.value == rhs.value; | ||||
} | ||||
friend bool operator==(const charT* lhs, const opaque_type& rhs) { | ||||
return lhs == rhs.value; | ||||
} | ||||
friend bool operator==(const opaque_type& lhs, const charT* rhs) { | ||||
return lhs.value == rhs ; | ||||
} | ||||
friend bool operator!=(const opaque_type& lhs, const opaque_type& rhs) { | ||||
return lhs.value != rhs.value; | ||||
} | ||||
friend bool operator!=(const charT* lhs, const opaque_type& rhs) { | ||||
return lhs != rhs.value; | ||||
} | ||||
friend bool operator!=(const opaque_type& lhs, const charT* rhs) { | ||||
return lhs.value != rhs ; | ||||
} | ||||
friend bool operator< (const opaque_type& lhs, const opaque_type& rhs) { | ||||
return lhs.value < rhs.value; | ||||
} | ||||
friend bool operator< (const charT* lhs, const opaque_type& rhs) { | ||||
return lhs < rhs.value; | ||||
} | ||||
friend bool operator< (const opaque_type& lhs, const charT* rhs) { | ||||
return lhs.value < rhs ; | ||||
} | ||||
friend bool operator> (const opaque_type& lhs, const opaque_type& rhs) { | ||||
return lhs.value > rhs.value; | ||||
} | ||||
friend bool operator> (const charT* lhs, const opaque_type& rhs) { | ||||
return lhs > rhs.value; | ||||
} | ||||
friend bool operator> (const opaque_type& lhs, const charT* rhs) { | ||||
return lhs.value > rhs ; | ||||
} | ||||
friend bool operator<=(const opaque_type& lhs, const opaque_type& rhs) { | ||||
return lhs.value <= rhs.value; | ||||
} | ||||
friend bool operator<=(const charT* lhs, const opaque_type& rhs) { | ||||
return lhs <= rhs.value; | ||||
} | ||||
friend bool operator<=(const opaque_type& lhs, const charT* rhs) { | ||||
return lhs.value <= rhs ; | ||||
} | ||||
friend bool operator>=(const opaque_type& lhs, const opaque_type& rhs) { | ||||
return lhs.value >= rhs.value; | ||||
} | ||||
friend bool operator>=(const charT* lhs, const opaque_type& rhs) { | ||||
return lhs >= rhs.value; | ||||
} | ||||
friend bool operator>=(const opaque_type& lhs, const charT* rhs) { | ||||
return lhs.value >= rhs ; | ||||
} | ||||
friend void swap(opaque_type& lhs, opaque_type& rhs) { | ||||
using std::swap; | ||||
return swap(lhs.value, rhs.value); | ||||
} | ||||
safer_string_typedef() = default; | ||||
safer_string_typedef(const safer_string_typedef& ) = default; | ||||
safer_string_typedef( safer_string_typedef&&) = default; | ||||
safer_string_typedef& operator=(const safer_string_typedef& ) = default; | ||||
safer_string_typedef& operator=( safer_string_typedef&&) = default; | ||||
protected: | ||||
~safer_string_typedef() = default; | ||||
using base::downcast; | ||||
}; | ||||
/// @} | ||||
} | ||||
} | ||||
#endif | ||||