{"id":13420197,"url":"https://github.com/theypsilon/concat","last_synced_at":"2025-08-22T02:08:22.433Z","repository":{"id":18759428,"uuid":"21971922","full_name":"theypsilon/concat","owner":"theypsilon","description":"A string concatenation utility in a single header file for C++11.","archived":false,"fork":false,"pushed_at":"2014-08-10T04:50:16.000Z","size":607,"stargazers_count":67,"open_issues_count":4,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-08-01T09:59:52.588Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/theypsilon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE_1_0.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-18T07:33:23.000Z","updated_at":"2025-01-22T20:06:20.000Z","dependencies_parsed_at":"2022-07-12T22:00:37.743Z","dependency_job_id":null,"html_url":"https://github.com/theypsilon/concat","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/theypsilon/concat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theypsilon%2Fconcat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theypsilon%2Fconcat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theypsilon%2Fconcat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theypsilon%2Fconcat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/theypsilon","download_url":"https://codeload.github.com/theypsilon/concat/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theypsilon%2Fconcat/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271574431,"owners_count":24783319,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-22T02:00:08.480Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T22:01:28.491Z","updated_at":"2025-08-22T02:08:22.408Z","avatar_url":"https://github.com/theypsilon.png","language":"C++","funding_links":[],"categories":["C++","TODO scan for Android support in followings"],"sub_categories":[],"readme":"concat.hpp [![Build Status](https://travis-ci.org/theypsilon/concat.svg?branch=master)](https://travis-ci.org/theypsilon/concat)\n======\n\nBecause string concatenation deserves one-liners in C++11 too.\n\n```cpp\nstd::cout \u003c\u003c concat(\"aa\", \"bb\") \u003c\u003c std::endl;\n/* output: \"aabb\" */\n```\n    \n    \nThat simple. **concat** also works with containers and other scalar types.\n\n```cpp\nstd::vector\u003cint\u003e v{1,2,3,4,5};\nstd::cout \u003c\u003c concat(v) \u003c\u003c std::endl;\n/* output: \"12345\" */\n```\n\n    \nYou may use separators in two ways:\n\n```cpp\nstd::cout \u003c\u003c concat(separator(\" + \"), 1,2,3,4,5) \u003c\u003c std::endl;\n/* output: \"1 + 2 + 3 + 4 + 5\" */\n\nstd::cout \u003c\u003c concat\u003c' '\u003e('a','b','c') \u003c\u003c std::endl;\n/* output: \"a b c\" */\n```\n\n\n\nIt is possible to mix between different parameter types, because under the hood we are using a ``std::ostringstream``.\n\n```cpp\nstd::cout \u003c\u003c concat\u003c' '\u003e(\"hello\", \"world\", std::make_tuple(1,2,3), '!', v) \u003c\u003c std::endl;\n/* output: \"hello world 1 2 3 ! 1 2 3 4 5\" */\n```\n\n\n\nYeah, it also accepts tuples (even nested ones). You may also introduce manipulators.\n\n```cpp\nstd::cout \u003c\u003c concat\u003c' '\u003e(std::setprecision(2), 4.0/3.0, std::setprecision(3), 1.0/3.0) \u003c\u003c std::endl;\n/* output: \"1.3 0.333\" */\n```\n\n\n\nAnd if you want fine-grained control of the underlying ``std::stringstream``, you may also supply it. Just make sure that you pass it as the first parameter (second, if there is also a separator parameter).\n\n```cpp\nstd::stringstream s;\nconcat\u003c' '\u003e(s, \"it\", \"just\", \"works!\");\nstd::cout \u003c\u003c s.str() \u003c\u003c endl;\n/* output: \"it just works!\" */\n```\n\n\n\nIf you supply the std:stringstream as the second or any other parameter, it just gonna be converted to ``std::string``, so you are not writing on it.\n\nSupplying the ``std::stringstream`` can be useful.\n\n```cpp\nstd::ostringstream s1, s2;\n\nread_file(s2, \"test.txt\"); // this might cause s2.setstate(std::ios::failbit);\n\ntry {\n    s1.exceptions(std::ios::failbit);\n    concat(s1, s2); // s1 gets the output of reading s2\n} catch(std::ios::failure\u0026 e) {\n    std::cout \u003c\u003c e.what() \u003c\u003c std::endl;\n}\n\n/* output could be like this: \"ios_base::clear: unspecified iostream_category error\" */\n```\n\n\n    \nYou can work with unicode, by specifing the char type as template parameter.\n\n```cpp\nassert((concat\u003cchar16_t\u003e(                u\"uni\", u\"code\") == u\"unicode\") \u0026\u0026\n       (concat\u003cchar32_t\u003e(separator(U\"\"), U\"Uni\", U\"code\") == U\"Unicode\"));\n           \n/* that's true! */\n```\n    \n\nBy the way, the only way to specify a separator with UTF parameters is that one.\n\nString type conversion between different UTF charsets is not yet implemented, so when you choose an encoding format, you have to stick to it for all the supplied parameters.\n\nKnow more\n------\n\nIf you want to read more about the power of **concat**, you can learn all you need to know just by reading [tests/unit.cpp](tests/unit.cpp).\n\nWhy not just use std::stringstream?\n------\n\nOf course you can, and I'm sure it is gonna be good enough for many situations. But sometimes I wish it could cover some other common use cases that right now require special (and often tedious) handling. Unfortunately, with ``std::stringstream`` you can not print **arrays**, **containers**, **tuples**, **pairs** or other **stringstreams** in a uniform and concise manner. \n\nFurthemore there are some tricky things about streams, that can make them feel a little unsafe. I.e.: when you attempt to add a ```(const char*)nullptr``` to a stream, it silently fails (unless you configured exceptions), and following operations with ``\u003c\u003c`` would totally be ignored. This would never happen with **concat** even if you decide to inject your own ``std::stringstream`` as shown above.\n\nSeparators, and the function syntax, are also some nice additions that could help to produce a more terse and readable code. It is convenient to remember that in most of the code we write, we are not doing performance critical operations, and therefore we should always consider the chance of trading off a little performance penalty for a better readability.\n\nBuild\n------\nIt is just a header file! Just copy ``concat.hpp`` to your include path, maybe rename the namespace to something more convenient than my nickname, and start using it. \n\nOf course, also make sure your compiler is set to C++11 and that you are linking a standard library implementation in your project, because there is no other dependency. \n\n----\n\nPlease **\"Star\"** the project on GitHub to help it to survive! Thanks!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheypsilon%2Fconcat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftheypsilon%2Fconcat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheypsilon%2Fconcat/lists"}