GLSL 'include' support
This commit is contained in:
parent
e6ecd558a9
commit
a60cc70246
@ -1,5 +1,3 @@
|
|||||||
#version 330 core
|
|
||||||
|
|
||||||
in vec3 v_coord;
|
in vec3 v_coord;
|
||||||
out vec4 f_color;
|
out vec4 f_color;
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#version 330 core
|
|
||||||
|
|
||||||
layout (location = 0) in vec2 v_position;
|
layout (location = 0) in vec2 v_position;
|
||||||
|
|
||||||
out vec3 v_coord;
|
out vec3 v_coord;
|
||||||
|
|||||||
11
res/shaders/lib/commons.glsl
Normal file
11
res/shaders/lib/commons.glsl
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Example of a GLSL library
|
||||||
|
|
||||||
|
vec4 decompress_light(float compressed_light) {
|
||||||
|
vec4 result;
|
||||||
|
int compressed = floatBitsToInt(compressed_light);
|
||||||
|
result.r = ((compressed >> 24) & 0xFF) / 255.f;
|
||||||
|
result.g = ((compressed >> 16) & 0xFF) / 255.f;
|
||||||
|
result.b = ((compressed >> 8) & 0xFF) / 255.f;
|
||||||
|
result.a = (compressed & 0xFF) / 255.f;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@ -1,5 +1,3 @@
|
|||||||
#version 330 core
|
|
||||||
|
|
||||||
in vec4 v_color;
|
in vec4 v_color;
|
||||||
out vec4 f_color;
|
out vec4 f_color;
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#version 330 core
|
|
||||||
|
|
||||||
layout (location = 0) in vec3 a_position;
|
layout (location = 0) in vec3 a_position;
|
||||||
layout (location = 1) in vec4 a_color;
|
layout (location = 1) in vec4 a_color;
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#version 330 core
|
|
||||||
|
|
||||||
in vec4 a_color;
|
in vec4 a_color;
|
||||||
in vec2 a_texCoord;
|
in vec2 a_texCoord;
|
||||||
in float a_distance;
|
in float a_distance;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#version 330 core
|
#include <commons>
|
||||||
|
|
||||||
layout (location = 0) in vec3 v_position;
|
layout (location = 0) in vec3 v_position;
|
||||||
layout (location = 1) in vec2 v_texCoord;
|
layout (location = 1) in vec2 v_texCoord;
|
||||||
@ -22,15 +22,6 @@ uniform float u_torchlightDistance;
|
|||||||
|
|
||||||
#define SKY_LIGHT_MUL 2.5
|
#define SKY_LIGHT_MUL 2.5
|
||||||
|
|
||||||
vec4 decompress_light(float compressed_light) {
|
|
||||||
vec4 result;
|
|
||||||
int compressed = floatBitsToInt(compressed_light);
|
|
||||||
result.r = ((compressed >> 24) & 0xFF) / 255.f;
|
|
||||||
result.g = ((compressed >> 16) & 0xFF) / 255.f;
|
|
||||||
result.b = ((compressed >> 8) & 0xFF) / 255.f;
|
|
||||||
result.a = (compressed & 0xFF) / 255.f;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
vec2 pos2d = (u_model * vec4(v_position, 1.0)).xz-u_cameraPos.xz;
|
vec2 pos2d = (u_model * vec4(v_position, 1.0)).xz-u_cameraPos.xz;
|
||||||
|
|||||||
@ -22,8 +22,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 330 core
|
|
||||||
|
|
||||||
// first, lets define some constants to use (planet radius, position, and scattering coefficients)
|
// first, lets define some constants to use (planet radius, position, and scattering coefficients)
|
||||||
#define PLANET_POS vec3(0.0) /* the position of the planet */
|
#define PLANET_POS vec3(0.0) /* the position of the planet */
|
||||||
#define PLANET_RADIUS 6371e3 /* radius of the planet */
|
#define PLANET_RADIUS 6371e3 /* radius of the planet */
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#version 330 core
|
|
||||||
|
|
||||||
layout (location = 0) in vec2 v_position;
|
layout (location = 0) in vec2 v_position;
|
||||||
|
|
||||||
out vec2 v_coord;
|
out vec2 v_coord;
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#version 330 core
|
|
||||||
|
|
||||||
in vec2 a_textureCoord;
|
in vec2 a_textureCoord;
|
||||||
in vec4 a_color;
|
in vec4 a_color;
|
||||||
out vec4 f_color;
|
out vec4 f_color;
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#version 330 core
|
|
||||||
|
|
||||||
layout (location = 0) in vec2 v_position;
|
layout (location = 0) in vec2 v_position;
|
||||||
layout (location = 1) in vec2 v_textureCoord;
|
layout (location = 1) in vec2 v_textureCoord;
|
||||||
layout (location = 2) in vec4 v_color;
|
layout (location = 2) in vec4 v_color;
|
||||||
|
|||||||
@ -48,7 +48,7 @@ bool AssetsLoader::loadNext() {
|
|||||||
#include "../graphics/Font.h"
|
#include "../graphics/Font.h"
|
||||||
|
|
||||||
bool _load_shader(Assets* assets, const path& filename, const std::string& name) {
|
bool _load_shader(Assets* assets, const path& filename, const std::string& name) {
|
||||||
Shader* shader = load_shader(filename.string() + ".glslv", filename.string() + ".glslf");
|
Shader* shader = Shader::loadShader(filename.string() + ".glslv", filename.string() + ".glslf");
|
||||||
if (shader == nullptr) {
|
if (shader == nullptr) {
|
||||||
std::cerr << "failed to load shader '" << name << "'" << std::endl;
|
std::cerr << "failed to load shader '" << name << "'" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
145
src/coders/GLSLExtension.cpp
Normal file
145
src/coders/GLSLExtension.cpp
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
#include "GLSLExtension.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include "../util/stringutil.h"
|
||||||
|
#include "../typedefs.h"
|
||||||
|
#include "../files/files.h"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::filesystem::path;
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
path GLSLExtension::getHeaderPath(string name) {
|
||||||
|
return libFolder/path(name+".glsl");
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLSLExtension::setLibFolder(path folder) {
|
||||||
|
this->libFolder = folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLSLExtension::setVersion(string version) {
|
||||||
|
this->version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLSLExtension::loadHeader(string name) {
|
||||||
|
path file = getHeaderPath(name);
|
||||||
|
string source = files::read_string(file);
|
||||||
|
addHeader(name, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLSLExtension::addHeader(string name, string source) {
|
||||||
|
headers[name] = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLSLExtension::define(string name, string value) {
|
||||||
|
defines[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const string& GLSLExtension::getHeader(const string name) const {
|
||||||
|
auto found = headers.find(name);
|
||||||
|
if (found == headers.end()) {
|
||||||
|
throw std::runtime_error("no header '"+name+"' loaded");
|
||||||
|
}
|
||||||
|
return found->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const string GLSLExtension::getDefine(const string name) const {
|
||||||
|
auto found = defines.find(name);
|
||||||
|
if (found == defines.end()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return found->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLSLExtension::hasDefine(const string name) const {
|
||||||
|
return defines.find(name) != defines.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLSLExtension::hasHeader(const string name) const {
|
||||||
|
return headers.find(name) != headers.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLSLExtension::undefine(string name) {
|
||||||
|
if (hasDefine(name)) {
|
||||||
|
defines.erase(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::runtime_error parsing_error(
|
||||||
|
const path& file,
|
||||||
|
uint linenum,
|
||||||
|
const string message) {
|
||||||
|
return std::runtime_error("file "+file.string()+": "+message+
|
||||||
|
" at line "+std::to_string(linenum));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void parsing_warning(
|
||||||
|
const path& file,
|
||||||
|
uint linenum, const
|
||||||
|
string message) {
|
||||||
|
std::cerr << "file "+file.string()+": warning: "+message+
|
||||||
|
" at line "+std::to_string(linenum) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void source_line(std::stringstream& ss, const path& file, uint linenum) {
|
||||||
|
ss << "#line " << linenum << " " << file << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
const string GLSLExtension::process(const path file, const string& source) {
|
||||||
|
std::stringstream ss;
|
||||||
|
size_t pos = 0;
|
||||||
|
uint linenum = 1;
|
||||||
|
ss << "#version " << version << '\n';
|
||||||
|
for (auto& entry : defines) {
|
||||||
|
ss << "#define " << entry.first << " " << entry.second << '\n';
|
||||||
|
}
|
||||||
|
source_line(ss, file, linenum);
|
||||||
|
while (pos < source.length()) {
|
||||||
|
size_t endline = source.find('\n', pos);
|
||||||
|
if (endline == string::npos) {
|
||||||
|
endline = source.length();
|
||||||
|
}
|
||||||
|
// parsing preprocessor directives
|
||||||
|
if (source[pos] == '#') {
|
||||||
|
string line = source.substr(pos+1, endline-pos);
|
||||||
|
util::trim(line);
|
||||||
|
// parsing 'include' directive
|
||||||
|
if (line.find("include") != string::npos) {
|
||||||
|
line = line.substr(7);
|
||||||
|
util::trim(line);
|
||||||
|
if (line.length() < 3) {
|
||||||
|
throw parsing_error(file, linenum,
|
||||||
|
"invalid 'include' syntax");
|
||||||
|
}
|
||||||
|
if (line[0] != '<' || line[line.length()-1] != '>') {
|
||||||
|
throw parsing_error(file, linenum,
|
||||||
|
"expected '#include <filename>' syntax");
|
||||||
|
}
|
||||||
|
string name = line.substr(1, line.length()-2);
|
||||||
|
path hfile = getHeaderPath(name);
|
||||||
|
if (!hasHeader(name)) {
|
||||||
|
loadHeader(name);
|
||||||
|
}
|
||||||
|
source_line(ss, hfile, 1);
|
||||||
|
ss << getHeader(name) << '\n';
|
||||||
|
pos = endline+1;
|
||||||
|
linenum++;
|
||||||
|
source_line(ss, file, linenum);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// removing extra 'include' directives
|
||||||
|
else if (line.find("version") != string::npos) {
|
||||||
|
parsing_warning(file, linenum, "removed #version directive");
|
||||||
|
pos = endline+1;
|
||||||
|
linenum++;
|
||||||
|
source_line(ss, file, linenum);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
linenum++;
|
||||||
|
ss << source.substr(pos, endline+1-pos);
|
||||||
|
pos = endline+1;
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
33
src/coders/GLSLExtension.h
Normal file
33
src/coders/GLSLExtension.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef CODERS_GLSL_EXTESION_H_
|
||||||
|
#define CODERS_GLSL_EXTESION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
class GLSLExtension {
|
||||||
|
std::unordered_map<std::string, std::string> headers;
|
||||||
|
std::unordered_map<std::string, std::string> defines;
|
||||||
|
std::filesystem::path libFolder;
|
||||||
|
std::string version = "330 core";
|
||||||
|
|
||||||
|
void loadHeader(std::string name);
|
||||||
|
std::filesystem::path getHeaderPath(std::string name);
|
||||||
|
public:
|
||||||
|
void setLibFolder(std::filesystem::path folder);
|
||||||
|
void setVersion(std::string version);
|
||||||
|
|
||||||
|
void define(std::string name, std::string value);
|
||||||
|
void undefine(std::string name);
|
||||||
|
void addHeader(std::string name, std::string source);
|
||||||
|
|
||||||
|
const std::string& getHeader(const std::string name) const;
|
||||||
|
const std::string getDefine(const std::string name) const;
|
||||||
|
|
||||||
|
bool hasHeader(const std::string name) const;
|
||||||
|
bool hasDefine(const std::string name) const;
|
||||||
|
|
||||||
|
const std::string process(const std::filesystem::path file, const std::string& source);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CODERS_GLSL_EXTESION_H_
|
||||||
@ -15,6 +15,7 @@
|
|||||||
#include "window/Camera.h"
|
#include "window/Camera.h"
|
||||||
#include "window/input.h"
|
#include "window/input.h"
|
||||||
#include "graphics/Batch2D.h"
|
#include "graphics/Batch2D.h"
|
||||||
|
#include "graphics/Shader.h"
|
||||||
#include "graphics/ImageData.h"
|
#include "graphics/ImageData.h"
|
||||||
#include "frontend/gui/GUI.h"
|
#include "frontend/gui/GUI.h"
|
||||||
#include "frontend/screens.h"
|
#include "frontend/screens.h"
|
||||||
@ -22,6 +23,7 @@
|
|||||||
|
|
||||||
#include "coders/json.h"
|
#include "coders/json.h"
|
||||||
#include "coders/png.h"
|
#include "coders/png.h"
|
||||||
|
#include "coders/GLSLExtension.h"
|
||||||
#include "files/files.h"
|
#include "files/files.h"
|
||||||
#include "files/engine_paths.h"
|
#include "files/engine_paths.h"
|
||||||
|
|
||||||
@ -35,6 +37,7 @@ using gui::GUI;
|
|||||||
Engine::Engine(EngineSettings& settings, EnginePaths* paths, Content* content)
|
Engine::Engine(EngineSettings& settings, EnginePaths* paths, Content* content)
|
||||||
: settings(settings), content(content), paths(paths) {
|
: settings(settings), content(content), paths(paths) {
|
||||||
Window::initialize(settings.display);
|
Window::initialize(settings.display);
|
||||||
|
Shader::preprocessor->setLibFolder(paths->getResources()/path("shaders/lib"));
|
||||||
|
|
||||||
assets = new Assets();
|
assets = new Assets();
|
||||||
std::cout << "-- loading assets" << std::endl;
|
std::cout << "-- loading assets" << std::endl;
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
using std::ios;
|
using std::ios;
|
||||||
using std::string;
|
using std::string;
|
||||||
@ -57,6 +58,9 @@ char* files::read_bytes(path filename, size_t& length) {
|
|||||||
std::string files::read_string(path filename) {
|
std::string files::read_string(path filename) {
|
||||||
size_t size;
|
size_t size;
|
||||||
unique_ptr<char> chars (read_bytes(filename, size));
|
unique_ptr<char> chars (read_bytes(filename, size));
|
||||||
|
if (chars == nullptr) {
|
||||||
|
throw std::runtime_error("could not to load file '"+filename.string()+"'");
|
||||||
|
}
|
||||||
return string(chars.get(), size);
|
return string(chars.get(), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,12 @@
|
|||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include "../coders/GLSLExtension.h"
|
||||||
|
|
||||||
|
using std::filesystem::path;
|
||||||
|
|
||||||
|
GLSLExtension* Shader::preprocessor = new GLSLExtension();
|
||||||
|
|
||||||
Shader::Shader(unsigned int id) : id(id){
|
Shader::Shader(unsigned int id) : id(id){
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +63,7 @@ void Shader::uniform3f(std::string name, glm::vec3 xyz){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Shader* load_shader(std::string vertexFile, std::string fragmentFile) {
|
Shader* Shader::loadShader(std::string vertexFile, std::string fragmentFile) {
|
||||||
// Reading Files
|
// Reading Files
|
||||||
std::string vertexCode;
|
std::string vertexCode;
|
||||||
std::string fragmentCode;
|
std::string fragmentCode;
|
||||||
@ -84,6 +90,9 @@ Shader* load_shader(std::string vertexFile, std::string fragmentFile) {
|
|||||||
std::cerr << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
|
std::cerr << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
vertexCode = preprocessor->process(path(vertexFile), vertexCode);
|
||||||
|
fragmentCode = preprocessor->process(path(fragmentFile), fragmentCode);
|
||||||
|
|
||||||
const GLchar* vShaderCode = vertexCode.c_str();
|
const GLchar* vShaderCode = vertexCode.c_str();
|
||||||
const GLchar* fShaderCode = fragmentCode.c_str();
|
const GLchar* fShaderCode = fragmentCode.c_str();
|
||||||
|
|
||||||
@ -98,7 +107,7 @@ Shader* load_shader(std::string vertexFile, std::string fragmentFile) {
|
|||||||
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
|
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
|
||||||
if (!success){
|
if (!success){
|
||||||
glGetShaderInfoLog(vertex, 512, nullptr, infoLog);
|
glGetShaderInfoLog(vertex, 512, nullptr, infoLog);
|
||||||
std::cerr << "SHADER::VERTEX: compilation failed" << std::endl;
|
std::cerr << "SHADER::VERTEX: compilation failed: " << vertexFile << std::endl;
|
||||||
std::cerr << infoLog << std::endl;
|
std::cerr << infoLog << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -110,7 +119,7 @@ Shader* load_shader(std::string vertexFile, std::string fragmentFile) {
|
|||||||
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
|
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
|
||||||
if (!success){
|
if (!success){
|
||||||
glGetShaderInfoLog(fragment, 512, nullptr, infoLog);
|
glGetShaderInfoLog(fragment, 512, nullptr, infoLog);
|
||||||
std::cerr << "SHADER::FRAGMENT: compilation failed" << std::endl;
|
std::cerr << "SHADER::FRAGMENT: compilation failed: " << vertexFile << std::endl;
|
||||||
std::cerr << infoLog << std::endl;
|
std::cerr << infoLog << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,11 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class GLSLExtension;
|
||||||
|
|
||||||
class Shader {
|
class Shader {
|
||||||
public:
|
public:
|
||||||
|
static GLSLExtension* preprocessor;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
|
||||||
Shader(unsigned int id);
|
Shader(unsigned int id);
|
||||||
@ -19,8 +22,8 @@ public:
|
|||||||
void uniform2f(std::string name, glm::vec2 xy);
|
void uniform2f(std::string name, glm::vec2 xy);
|
||||||
void uniform3f(std::string name, float x, float y, float z);
|
void uniform3f(std::string name, float x, float y, float z);
|
||||||
void uniform3f(std::string name, glm::vec3 xyz);
|
void uniform3f(std::string name, glm::vec3 xyz);
|
||||||
|
|
||||||
|
static Shader* loadShader(std::string vertexFile, std::string fragmentFile);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Shader* load_shader(std::string vertexFile, std::string fragmentFile);
|
|
||||||
|
|
||||||
#endif /* GRAPHICS_SHADER_H_ */
|
#endif /* GRAPHICS_SHADER_H_ */
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include <locale>
|
#include <locale>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using std::string;
|
using std::string;
|
||||||
@ -149,4 +150,21 @@ bool util::is_valid_filename(std::wstring name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void util::ltrim(std::string &s) {
|
||||||
|
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
|
||||||
|
return !std::isspace(ch);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void util::rtrim(std::string &s) {
|
||||||
|
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
|
||||||
|
return !std::isspace(ch);
|
||||||
|
}).base(), s.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void util::trim(std::string &s) {
|
||||||
|
rtrim(s);
|
||||||
|
ltrim(s);
|
||||||
|
}
|
||||||
|
|||||||
@ -15,6 +15,10 @@ namespace util {
|
|||||||
extern bool is_integer(std::string text);
|
extern bool is_integer(std::string text);
|
||||||
extern bool is_integer(std::wstring text);
|
extern bool is_integer(std::wstring text);
|
||||||
extern bool is_valid_filename(std::wstring name);
|
extern bool is_valid_filename(std::wstring name);
|
||||||
|
|
||||||
|
extern void ltrim(std::string &s);
|
||||||
|
extern void rtrim(std::string &s);
|
||||||
|
extern void trim(std::string &s);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // UTIL_STRINGUTIL_H_
|
#endif // UTIL_STRINGUTIL_H_
|
||||||
Loading…
x
Reference in New Issue
Block a user