Useful code snippets thread

Whenever you come up with a useful code snippet, or you find one on the web, pleas post it.

The complexity can be varied, however if someone is going to give us a template meta-meta programming gem, it may be wise to add some comments from which we can learn from.

I will be posting any snippet I create which other people may find useful, if someone would like to make "versions" of the snippet, i.e. better method, better optimizations etc etc, please document the changes, and why.

It would be great as a community, if we could have a solid, well-made snippet thread we can reference when answering posts (I have seen many post over the years that get repeated almost every week).

I'm looking forward to what tomorrow may bring.

Snippet: Read file

This snippet takes a filename(std::string), whether to keep empty lines(bool) default is 0, and a delimiter(char) which is defaulted to a new line. The function returns a std::vector<std::string> and each element is of course the line(or up to delimiter) from the file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <string>
#include <vector>
#include <fstream>

std::vector<std::string> ReadFile(const std::string& filename, const bool& KeepEmpty = 0, const char& delimiter = '\n')
{
	std::vector<std::string> result;

	std::ifstream ifs(filename.c_str());
	if(!ifs) return result;

	while(ifs.good())
	{
		static std::string line;
		std::getline(ifs,line, delimiter);
		if(line.empty() && !KeepEmpty);
		else result.push_back(line);
	}

	return result;
}


USAGE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
#include <vector>

#include "read_file.h"

int main()
{
	auto file = ReadFile("main.cpp",0); // file = main.cpp | Don't keep empty lines, delimiter is default as new line
	for(auto f : file)
	{
		std::cout << f << std::endl;
	}
	return 0;
}

Snippet: A2B

This little function I found to be useful, it uses the stringstream class for type conversion.

1
2
3
4
5
6
7
8
9
10
#include <sstream>

template<typename A, typename B>
bool A2B(A& a, B& b)
{
	std::stringstream ss;
	ss << a;
	if(ss >> b) return 1;
	else return 0;
}


USAGE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>

#include "a2b.h"

int main()
{
	std::string s = "1.1";
	double d;
	if(A2B(s,d)) std::cout << "Type conversion successful\n";
	else std::cout << "Could not convert\n";
	std::string s2;
	if(A2B(d,s2)) std::cout << "Type conversion successful\n";
	else std::cout << "Could not convert\n";
	return 0;
}
Last edited on
This is the only one I can think of that's general enough to be used frequently:

Snippet: arraysize
1
2
template <typename T, std::size_t S>
inline constexpr std::size_t arraysize(T (&)[S]) { return S; }


USAGE
1
2
3
4
5
    const int foo[] = {1,2,3,4,5};
    int* bar = new int[100];

    cout << arraysize(foo) << endl; // prints 5
    cout << arraysize(bar) << endl; // compiler error - not an array 



Better than the typical sizeof approach because it will generate a compiler error when used incorrectly -- whereas sizeof will compile but just quietly give you incorrect sizes.

EDIT: added constexpr
Last edited on
Nice one Disch, I could use that in a project actually.

How does it actually work though? It's the (T (&)[S] ) that is throwing me.

EDIT: Could you answer this in your OP, so I can delete this a keep getting a 1 post - 1 snippet thing going here


Snippet: FindPositions

I created this little function when I experimented with parsing/tokenizing. It returns a std::vector of type size_t with the start positions of all occurrences of a delimiter or string in a given line of text. I will post the second part of this ( The bracket matcher ) another time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <string>
#include <vector>

std::vector<size_t> FindPositions(const std::string& line, const std::string& to_find)
{
	std::vector<size_t> result;
	size_t pos = 0;
	pos = line.find(to_find);
	while(pos != std::string::npos)
	{
		result.push_back(pos);
		pos = line.find(to_find, pos+1);
	}
	return result;
}


USAGE

1
2
3
4
5
6
7
8
9
10
11
12
#include <string>
#include <vector>

#include "find_position.h"

int main()
{
        std:;string text = "An englishman, a german, a pole and a russian were sitting at a bar...";
        auto positions = FindPositions(text,"man");
        positions = FindPositions(text,"a");
        return 0;
}
Last edited on
It is a nameless reference to an array of Ts, of size S.
closed account (3hM2Nwbp)
I'll just throw this out there...there are probably better solutions available, but this served my diagnostic purposes when designing a certain API. Basically, this gives clear, concise compile-time error messages when a class fails a concept test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#ifndef CONCEPTS_HPP
#define CONCEPTS_HPP
#include <type_traits>
#include <utility>
/**
* A macro that generates a field concept check. The check that is generated shall have the following
* naming format: "[CONCEPT_NAME]_[FIELD_NAME]_concept_check", so for example...
*
* @code
* GENERATE_CONCEPT_FIELD_CHECK(Example, test_field, bool);
* // generates...
* template<typename T> class Example_test_field_concept_check { ... };
*
* The check will ensure an easy to understand compile-time error if the specified field is missing from the
* template parameter or if the type of the field of the template parameter does not match the expected type.
*
* For example:
*
* @code
* GENERATE_CONCEPT_FIELD_CHECK(Example, test_field, const bool);
* struct W { };
* struct X { int test_field; };
* struct Y { bool test_field; };
* struct Z { const bool test_field; };
*
* Example_test_field_concept_check<W>::value; // Compile-time error - missing field 'test_field'
* Example_test_field_concept_check<X>::value; // Compile-time error - incorrect type 'int', expected 'const bool'
* Example_test_field_concept_check<Y>::value; // Compile-time error - incorrect type 'bool', expected 'const bool'
* Example_test_field_concept_check<Z>::value; // Works - Z has a field 'test_field' of type 'const bool'
*
* @param CONCEPT_NAME - the name of the concept that the check is being generated for
*
* @param FIELD_NAME - the name of the field that is being checked
*
* @param EXPECTED_TYPE - the type that the field is expected to be
*
*/
#define GENERATE_CONCEPT_FIELD_CHECK(CONCEPT_NAME, FIELD_NAME, EXPECTED_TYPE)\
template<typename Symbology>\
class CONCEPT_NAME ##_##FIELD_NAME ##_concept_check\
{\
template<typename T>\
static constexpr decltype(std::declval<T>(). FIELD_NAME, void(), std::true_type()) test(int);\
\
template<typename T>\
static constexpr std::false_type test(...);\
\
static_assert(decltype(test<Symbology>(0))::value, \
#CONCEPT_NAME " CONCEPT CHECK FAILED: [missing field: " #FIELD_NAME "] " \
"Hint: Did you forget to add the field '" #FIELD_NAME "' to your " #CONCEPT_NAME "template class?");\
\
using ACTUAL_TYPE = decltype(Symbology::FIELD_NAME);\
static_assert(std::is_same<EXPECTED_TYPE, ACTUAL_TYPE>::value, \
#CONCEPT_NAME " CONCEPT CHECK FAILED: [type mismatch: " #FIELD_NAME "] " \
"Hint: Check the type of the '" #FIELD_NAME "' field in your " #CONCEPT_NAME " template class; \
it should be of type '" #EXPECTED_TYPE "'.");\
public: \
\
static constexpr bool value = decltype(test<Symbology>(0))::value && \
std::is_same<EXPECTED_TYPE, ACTUAL_TYPE>::value;\
}
#define GENERATE_CONCEPT_STATIC_METHOD_CHECK(CONCEPT_NAME, METHOD_NAME, EXPECTED_RETURN_TYPE, ARGUMENT_TYPE)\
template<typename Symbology>\
class CONCEPT_NAME ##_##METHOD_NAME ##_concept_check\
{\
template<typename T>\
static constexpr decltype(std::declval<T>(). METHOD_NAME, void(), std::true_type()) test(int);\
\
template<typename T>\
static constexpr std::false_type test(...);\
\
static_assert(decltype(test<Symbology>(0))::value, \
#CONCEPT_NAME " CONCEPT CHECK FAILED: [missing method: " #METHOD_NAME "] " \
"Hint: Did you forget to add the method '" #METHOD_NAME "' to your " #CONCEPT_NAME " class?");\
\
using STRIPPED_ARGUMENT_TYPE = typename std::remove_reference<ARGUMENT_TYPE>::type;\
using ACTUAL_RETURN_TYPE = decltype(Symbology::METHOD_NAME((STRIPPED_ARGUMENT_TYPE())));\
\
static_assert(std::is_same<EXPECTED_RETURN_TYPE, ACTUAL_RETURN_TYPE>::value, \
#CONCEPT_NAME " CONCEPT CHECK FAILED: [method return type mismatch: " #METHOD_NAME "] " \
"Hint: Check the method signature; it should be \
'" #EXPECTED_RETURN_TYPE " " #METHOD_NAME "(" #ARGUMENT_TYPE ");'");\
public: \
\
static constexpr bool value = decltype(test<Symbology>(0))::value && \
std::is_same<EXPECTED_RETURN_TYPE, ACTUAL_RETURN_TYPE>::value;\
}
#define GENERATE_CONCEPT_OPERATOR_CHECK(CONCEPT_NAME, OPERATOR_NAME, EXPECTED_RETURN_TYPE, ARGUMENT_TYPE)\
template<typename Symbology>\
class CONCEPT_NAME ##_operator_ ##OPERATOR_NAME ##_concept_check\
{\
template<typename T>\
static constexpr decltype(std::declval<T>(). operator ## OPERATOR_NAME, void(), std::true_type()) test(int);\
\
template<typename T>\
static constexpr std::false_type test(...);\
\
static_assert(decltype(test<Symbology>(0))::value, \
#CONCEPT_NAME " CONCEPT CHECK FAILED: [missing method: " #OPERATOR_NAME "] " \
"Hint: Did you forget to add the method '" #OPERATOR_NAME "' to your Symbology class?");\
\
using STRIPPED_ARGUMENT_TYPE = typename std::remove_reference<ARGUMENT_TYPE>::type;\
using ACTUAL_RETURN_TYPE = decltype(Symbology::operator ##OPERATOR_NAME((STRIPPED_ARGUMENT_TYPE())));\
\
static_assert(std::is_same<EXPECTED_RETURN_TYPE, ACTUAL_RETURN_TYPE>::value, \
#CONCEPT_NAME " CONCEPT CHECK FAILED: [method return type mismatch: " #OPERATOR_NAME "] " \
"Hint: Check the method signature; it should be \
'" #EXPECTED_RETURN_TYPE " " #OPERATOR_NAME "(" #ARGUMENT_TYPE ");'");\
public: \
\
static constexpr bool value = decltype(test<Symbology>(0))::value && \
std::is_same<EXPECTED_RETURN_TYPE, ACTUAL_RETURN_TYPE>::value;\
}
#endif 


Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include "Concepts.hpp"
namespace detail
{
#pragma clang diagnostic push
/// clang complains about having a declared, but not defined inline function in our SFINAE tricks
/// This shouldn't be an issue, since we only use this for static-analysis.
#pragma clang diagnostic ignored "-Wundefined-inline"
/// Use our macros to bang out each concept check
GENERATE_CONCEPT_FIELD_CHECK(Symbology, alphanumeric, const bool);
GENERATE_CONCEPT_FIELD_CHECK(Symbology, numeric, const bool);
GENERATE_CONCEPT_FIELD_CHECK(Symbology, discrete, const bool);
GENERATE_CONCEPT_FIELD_CHECK(Symbology, continuous, const bool);
GENERATE_CONCEPT_FIELD_CHECK(Symbology, multi_width, const bool);
GENERATE_CONCEPT_FIELD_CHECK(Symbology, dual_width, const bool);
GENERATE_CONCEPT_FIELD_CHECK(Symbology, fixed_length, const bool);
GENERATE_CONCEPT_FIELD_CHECK(Symbology, variable_length, const bool);
GENERATE_CONCEPT_FIELD_CHECK(Symbology, self_checking, const bool);
GENERATE_CONCEPT_FIELD_CHECK(Symbology, uses_checksum, const bool);
GENERATE_CONCEPT_FIELD_CHECK(Symbology, charset, const std::string);
GENERATE_CONCEPT_FIELD_CHECK(Symbology, start_sequence, const typename Symbology::SequenceType);
GENERATE_CONCEPT_FIELD_CHECK(Symbology, stop_sequence, const typename Symbology::SequenceType);
GENERATE_CONCEPT_STATIC_METHOD_CHECK(Symbology, checksum, unsigned char, const std::string&);
GENERATE_CONCEPT_STATIC_METHOD_CHECK(Symbology, encode, typename Symbology::SequenceType, const std::string&);
GENERATE_CONCEPT_STATIC_METHOD_CHECK(Symbology, decode, std::string, const typename Symbology::SequenceType&);
}

template<typename Symbology>
struct symbology_concept_check
{
static constexpr bool value =
detail::Symbology_encode_concept_check<Symbology>::value &&
detail::Symbology_decode_concept_check<Symbology>::value &&
detail::Symbology_checksum_concept_check<Symbology>::value &&
detail::Symbology_alphanumeric_concept_check<Symbology>::value &&
detail::Symbology_discrete_concept_check<Symbology>::value &&
detail::Symbology_continuous_concept_check<Symbology>::value &&
detail::Symbology_multi_width_concept_check<Symbology>::value &&
detail::Symbology_dual_width_concept_check<Symbology>::value &&
detail::Symbology_fixed_length_concept_check<Symbology>::value &&
detail::Symbology_variable_length_concept_check<Symbology>::value &&
detail::Symbology_self_checking_concept_check<Symbology>::value &&
detail::Symbology_uses_checksum_concept_check<Symbology>::value &&
detail::Symbology_charset_concept_check<Symbology>::value &&
detail::Symbology_numeric_concept_check<Symbology>::value &&
detail::Symbology_start_sequence_concept_check<Symbology>::value;
};
#pragma clang diagnostic pop 
Last edited on
closed account (3hM2Nwbp)
I tried to edit my post to link to the organization, but alas did not have enough characters in the post remaining...
> while(ifs.good())
loop on the reading operation instead. As it is, the last time you'll process invalid input
while( std::getline(ifs,line, delimiter) )


1
2
		if(line.empty() && !KeepEmpty);
		else result.push_back(line);
¿an empty body for the if? ¿why don't simply negate the condition?
1
2
if( not line.empty() or KeepEmpty )
   result.push_back(line);



Unless your function is inline or template, don't put its definition in a header file, it will cause you multiple definition errors at linking time.
Last edited on
@Luke

Wow that is something, I'm not sure how that works but I've only glanced through it. I'm going to read it in depth later on, thank you for your snippet!


@LB

Thanks for the link, I'll add my snippets to it but I will try to keep this thread going.


@ne555

I kept the empty if in case I would like to extend the functionality.

Does the while loop change make any difference?

Also my function doesn't have linker errors, the snippets were part of a .h file that had header guards.

Thanks for the suggestions.
Does the while loop change make any difference?

Functionally, no. It does, however, make your code more efficient.

Also, what's with the references for KeepEmpty and delimiter in your ReadFile function? (And what's with the inconsistent naming convention for variables?)


Also my function doesn't have linker errors, the snippets were part of a .h file that had header guards.

Header guards do not guard against multiple definitions. Just because you haven't included your header in more than one source file doesn't mean the problem won't bite you in the arse somewhere down the road. If a function is defined in a header file it should be inline (or, put another way, have internal linkage.)
There is a change in functionality, suppose that you do accept empty lines and that the input is
foo\n

your result vector would have size = 2, instead of just 1.

that's because you process the string even if the reading in line 15 had failed.


> I kept the empty if in case I would like to extend the functionality.
then you could add an else
closed account (2LzbRXSz)
I have two snippets. I didn't come up with them on my own, but I don't have sources for where they came from. I've modified them a little (added comments, different variable names, etc... I've done the most change to the typewriter one). They're also pretty simplistic.

Go to a specific part of a text file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void fileRead(string &key)
{
    string text;
    
    ifstream myfile ("test.txt");
    if (myfile.is_open())
    {
        while(getline(myfile, text))
        {
            if (text.find(key) != string::npos) // Reads the entire line that the "key" is on, including the key itself, and anything behind it that's also on the same line.
            {
                cout << text;
            }
        }
    }
}


Usage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

void fileRead(string &key)
{
    string text;
    
    ifstream myfile ("test.txt");
    if (myfile.is_open())
    {
        while(getline(myfile, text))
        {
            if (text.find(key) != string::npos)
            {
                cout << text;
            }
        }
    }
}

int main()
{
    string userinput;
    cout << "Enter pass key" << endl;
    getline(cin, userinput);
    fileRead(userinput);
    return 0;
}


Typewriter effect
1
2
3
4
5
6
7
8
9
10
11
12
void typewriter(string &s)
{
    int length = s.length();
    for (int i = 0; i < length; i++)
    {
        cout << s[i]; // Prints each letter one at a time
        cout.flush(); // Flushes the stream
        this_thread::sleep_for(chrono::milliseconds(60)); // Pauses the stream
        // You can change 60 to whatever you want. I just think that speed looks the most natural. 
        // You also don't have to use milliseconds.
    }
}


Usage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <thread>
#include <chrono>

using namespace std;

void typewriter(string &s)
{
    int length = s.length();
    for (int i = 0; i < length; i++)
    {
        cout << s[i]; // Prints each letter one at a time
        cout.flush(); // Flushes the stream
        this_thread::sleep_for(chrono::milliseconds(60)); 
    }
}

int main()
{
    string str = "Hello, world!";
    typewriter(str);
}


You could even combine it with the fileRead function and do something like this...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <fstream>
#include <string>
#include <thread>
#include <chrono>

using namespace std;

void typewriter(string &s)
{
    int length = s.length();
    for (int i = 0; i < length; i++)
    {
        cout << s[i];
        cout.flush();
        this_thread::sleep_for(chrono::milliseconds(60));
    }
}

void fileRead(string &key)
{
    string text;
    
    ifstream myfile ("test.txt");
    if (myfile.is_open())
    {
        while(getline(myfile, text))
        {
            if (text.find(key) != string::npos)
            {
                typewriter(text);
            }
        }
    }
}

int main()
{
    string userinput;
    cout << "Enter pass key" << endl;
    getline(cin, userinput);
    fileRead(userinput);
    return 0;
}
Topic archived. No new replies allowed.