/* * This file is a part of EZC -- Easy templating in C++ library * and is distributed under the BSD 3-Clause licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * 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. * * * Neither the name Tomasz Sowa nor the names of contributors to this * project 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 OWNER 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. */ #ifndef headerfile_ezc_var #define headerfile_ezc_var #include "spacewrapper.h" #include "date/date.h" #include "modelcontainerwrapper.h" #include "textstream/textstream.h" namespace Ezc { template struct Env; /* a variable */ template class Var { public: typedef void (*UserFunction)(Env &); enum Type { // string or wstring from space_local TYPE_VOID, // or change maybe to something like TYPE_LOCAL_SPACE? TYPE_BOOL, TYPE_LONG, TYPE_DOUBLE, TYPE_STRING, TYPE_STREAM, TYPE_FUNCTION, TYPE_MODEL, TYPE_MODEL_CONTAINER_WRAPPER, TYPE_SPACE_WRAPPER, // or just type_space }; Type type; Var(); void clear(); bool to_bool() const; void set(const char * str); void set(const wchar_t * str); void set(const std::string & str); void set(const std::wstring & str); // void set(char val); // void set(unsigned char val); // void set(wchar_t val); void set(bool val); void set(short val); void set(int val); void set(long val); void set(long long val); void set(unsigned short val); void set(unsigned int val); void set(unsigned long val); void set(unsigned long long val); void set(float val); void set(double val); void set(long double val); // this str object is copied void set(const pt::Stream & str); void set(UserFunction user_function); // this model is not copied, is it a correct interface? void set(morm::Model & model); bool is_equal(const char * str) const; bool is_equal(const wchar_t * str) const; bool is_equal(const std::string & str) const; bool is_equal(const std::wstring & str) const; void serialize_to(pt::WTextStream & str); Var & operator<<(const char * str); Var & operator<<(const wchar_t * str); Var & operator<<(const std::string & str); Var & operator<<(const std::wstring & str); Var & operator<<(char val); Var & operator<<(unsigned char val); Var & operator<<(wchar_t val); Var & operator<<(bool val); Var & operator<<(short val); Var & operator<<(int val); Var & operator<<(long val); Var & operator<<(long long val); Var & operator<<(unsigned short val); Var & operator<<(unsigned int val); Var & operator<<(unsigned long val); Var & operator<<(unsigned long long val); Var & operator<<(float val); Var & operator<<(double val); Var & operator<<(long double val); Var & operator<<(const pt::Stream & str); UserFunction user_function; morm::Model * model; morm::ModelContainerWrapper * model_container_wrapper; pt::Date * date; morm::SpaceWrapper * space_wrapper; pt::Space space_local; StreamType stream; private: bool is_equal_bool(const char * str) const; bool is_equal_string(const char * str) const; bool is_equal_bool(const wchar_t * str) const; bool is_equal_string(const wchar_t * str) const; /* * old */ /* * if true then means 'str' is a function name and should be called (res is ignored) * * if false then means 'str' is a string value and res is a boolean value */ //bool is_function; //std::wstring str; // a string value //bool res; // a boolean value }; template Var::Var() { clear(); } template void Var::clear() { //res = false; //is_function = false; type = TYPE_VOID; user_function = nullptr; model = nullptr; model_container_wrapper = nullptr; date = nullptr; space_wrapper = nullptr; space_local.clear(); stream.clear(); } template bool Var::to_bool() const { switch(type) { case TYPE_VOID: return false; case TYPE_BOOL: case TYPE_LONG: case TYPE_DOUBLE: case TYPE_STRING: return space_local.to_bool(); case TYPE_STREAM: case TYPE_FUNCTION: case TYPE_MODEL: case TYPE_MODEL_CONTAINER_WRAPPER: case TYPE_SPACE_WRAPPER: break; } return false; } template void Var::set(const char * str) { type = TYPE_STRING; space_local.set(str); } template void Var::set(const wchar_t * str) { type = TYPE_STRING; space_local.set(str); } template void Var::set(const std::string & str) { type = TYPE_STRING; space_local.set(str); } template void Var::set(const std::wstring & str) { type = TYPE_STRING; space_local.set(str); } /* template void Var::set(char val) { type = TYPE_STRING; space_local.set(str); } template void Var::set(unsigned char val) { type = TYPE_STRING; space_local.set(str); } template void Var::set(wchar_t val) { type = TYPE_STRING; space_local.set(str); } */ template void Var::set(bool val) { type = TYPE_BOOL; space_local.set(val); } template void Var::set(short val) { type = TYPE_LONG; space_local.set(val); } template void Var::set(int val) { type = TYPE_LONG; space_local.set(val); } template void Var::set(long val) { type = TYPE_LONG; space_local.set(val); } template void Var::set(long long val) { type = TYPE_LONG; space_local.set(val); } template void Var::set(unsigned short val) { type = TYPE_LONG; space_local.set(val); } template void Var::set(unsigned int val) { type = TYPE_LONG; space_local.set(val); } template void Var::set(unsigned long val) { type = TYPE_LONG; space_local.set(val); } template void Var::set(unsigned long long val) { type = TYPE_LONG; space_local.set(val); } template void Var::set(float val) { type = TYPE_DOUBLE; space_local.set(val); } template void Var::set(double val) { type = TYPE_DOUBLE; space_local.set(val); } template void Var::set(long double val) { type = TYPE_DOUBLE; space_local.set(val); } template void Var::set(const pt::Stream & str) { type = TYPE_STREAM; stream.clear(); stream << str; } template void Var::set(UserFunction user_function) { type = TYPE_FUNCTION; this->user_function = user_function; } template void Var::set(morm::Model & model) { type = TYPE_MODEL; this->model = &model; } template bool Var::is_equal(const char * str) const { switch(type) { case TYPE_BOOL: return is_equal_bool(str); case TYPE_STRING: return is_equal_string(str); case TYPE_VOID: case TYPE_LONG: case TYPE_DOUBLE: case TYPE_STREAM: case TYPE_FUNCTION: case TYPE_MODEL: case TYPE_MODEL_CONTAINER_WRAPPER: case TYPE_SPACE_WRAPPER: break; } return false; } template bool Var::is_equal(const wchar_t * str) const { switch(type) { case TYPE_BOOL: return is_equal_bool(str); case TYPE_STRING: return is_equal_string(str); case TYPE_VOID: case TYPE_LONG: case TYPE_DOUBLE: case TYPE_STREAM: case TYPE_FUNCTION: case TYPE_MODEL: case TYPE_MODEL_CONTAINER_WRAPPER: case TYPE_SPACE_WRAPPER: break; } return false; } template bool Var::is_equal(const std::string & str) const { return is_equal(str.c_str()); } template bool Var::is_equal(const std::wstring & str) const { return is_equal(str.c_str()); } template bool Var::is_equal_bool(const char * str) const { if( space_local.to_bool() ) { return str[0] != 0; } else { return str[0] == 0; } } template bool Var::is_equal_string(const char * str) const { if( space_local.is_str() ) { return space_local.is_equal(str); } else if( space_local.is_wstr() ) { std::string space_str_utf8; pt::wide_to_utf8(*space_local.get_wstr(), space_str_utf8); return space_str_utf8 == str; } return false; } template bool Var::is_equal_bool(const wchar_t * str) const { if( space_local.to_bool() ) { return str[0] != 0; } else { return str[0] == 0; } } template bool Var::is_equal_string(const wchar_t * str) const { if( space_local.is_wstr() ) { return space_local.is_equal(str); } else if( space_local.is_str() ) { std::string str_utf8; pt::wide_to_utf8(str, str_utf8); return space_local.is_equal(str_utf8); } return false; } template void Var::serialize_to(pt::WTextStream & str) { switch(type) { case TYPE_BOOL: case TYPE_LONG: case TYPE_DOUBLE: case TYPE_STRING: space_local.serialize_to_string(str); break; case TYPE_STREAM: str = stream; break; case TYPE_VOID: case TYPE_FUNCTION: case TYPE_MODEL: case TYPE_MODEL_CONTAINER_WRAPPER: case TYPE_SPACE_WRAPPER: break; } } template Var & Var::operator<<(const char * str) { type = TYPE_STREAM; stream << str; return *this; } template Var & Var::operator<<(const wchar_t * str) { type = TYPE_STREAM; stream << str; return *this; } template Var & Var::operator<<(const std::string & str) { type = TYPE_STREAM; stream << str; return *this; } template Var & Var::operator<<(const std::wstring & str) { type = TYPE_STREAM; stream << str; return *this; } template Var & Var::operator<<(char val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(unsigned char val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(wchar_t val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(bool val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(short val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(int val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(long val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(long long val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(unsigned short val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(unsigned int val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(unsigned long val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(unsigned long long val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(float val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(double val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(long double val) { type = TYPE_STREAM; stream << val; return *this; } template Var & Var::operator<<(const pt::Stream & str) { type = TYPE_STREAM; stream << str; return *this; } } #endif