1. C++ / Говнокод #20706

    +319

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    template<typename OpeningBracketRange,
    	typename ClosingBracketRange,
    	typename StopTokenRange,
    	typename CommentBlockRangePairRange,
    	typename RecursiveCommentBlockRangePairRange>
    
    Meta::EnableIf<
    	IsFiniteForwardRange<OpeningBracketRange>::_ &&
    	IsFiniteForwardRange<ClosingBracketRange>::_ &&
    	IsFiniteForwardRange<StopTokenRange>::_ &&
    	IsFiniteForwardRange<CommentBlockRangePairRange>::_ &&
    	IsFiniteForwardRange<RecursiveCommentBlockRangePairRange>::_,
    
    decltype(Meta::Val<R>().Take(0))> ReadRecursiveBlock(int& counter, size_t* ioIndex,
    	OpeningBracketRange openingBracket, ClosingBracketRange closingBracket, StopTokenRange stopToken,
    	CommentBlockRangePairRange commentBlocks, RecursiveCommentBlockRangePairRange recursiveCommentBlocks)
    {
    	R start = me();
    	size_t index = 0;
    	const size_t openingBracketLen = openingBracket.Count();
    	const size_t closingBracketLen = closingBracket.Count();
    	const size_t stopTokenLen = stopToken.Count();
    	while(!me().Empty() && counter!=0)
    	{
    		if(openingBracketLen!=0 && me().StartsWith(openingBracket))
    		{
    			counter++;
    			me().PopFrontExactly(openingBracketLen);
    			index += openingBracketLen;
    			continue;
    		}
    
    		if(closingBracketLen!=0 && me().StartsWith(closingBracket))
    		{
    			counter--;
    			me().PopFrontExactly(closingBracketLen);
    			index += closingBracketLen;
    			continue;
    		}
    
    		if(stopTokenLen!=0 && me().StartsWith(stopToken))
    		{
    			me().PopFrontExactly(stopTokenLen);
    			index += stopTokenLen;
    			break;
    		}
    
    		bool commentFound = false;
    		for(auto& commentBlock: commentBlocks)
    		{
    			commentFound = me().StartsWith(commentBlock.Get<0>());
    			if(!commentFound) continue;
    
    			const size_t commentBlockOpeningLen = commentBlock.Get<0>().Count();
    			const size_t commentBlockClosingLen = commentBlock.Get<1>().Count();
    			me().PopFrontN(commentBlockOpeningLen);
    			index += commentBlockOpeningLen;
    			me().FindAdvance(commentBlock.Get<1>(), &index);
    			me().PopFrontN(commentBlockClosingLen);
    			index += commentBlockClosingLen;
    			break;
    		}
    		if(commentFound) continue;
    
    		for(auto& commentBlock: recursiveCommentBlocks)
    		{
    			commentFound = me().StartsWith(commentBlock.Get<0>());
    			if(!commentFound) continue;
    
    			int commentCounter = 1;
    			ReadRecursiveBlock(commentCounter, &index, commentBlock.Get<0>(), commentBlock.Get<1>(), null, null);
    			break;
    		}
    		if(commentFound) continue;
    
    		me().PopFront();
    	}
    	if(ioIndex!=null) (*ioIndex) += index;
    	return start.Take(index);
    }

    Это мои последние достижения в написании сверх универсального обобщённого кода.
    Начиналось всё с функции, которая парсила блок кода до закрывающей фигурной скобки, учитывая встречающиеся открывающие скобки. Затем появилась поддержка комментариев и строк. Позже я решил, что нечего привязываться к какому-то конкретному языку, ведь можно же таким же образом парсить другой язык, где вместо скобок begin end и комментарии по-другому оформляются.
    А потом я подумал, зачем вообще привязывать типы параметров к строкам и массивам строк? И почему код, который парсится, вообще должен быть строкой, хранящейся в памяти непрерывно? В итоге мои размышления привели к такой реализации, которая способна парсить всё подряд, в том числе и связные списки, причём необязательно состоящие из символов. При этом открывающуюся скобку можно передать связным списком, закрывающуюся - массивом, а блоки комментариев передавать как массивом кортежей, так и хеш-таблицей.

    При этом эта функция относится к классу примеси и наследованием её можно подмешать к любому классу, имеющему нужные методы.

    gammaker, 15 Августа 2016

    Комментарии (39)
  2. C++ / Говнокод #20503

    +8

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    #include <vector>
    #include <iostream>
    
    template<class T>
    struct reverse_view_impl {
    	const T& cont;
    	reverse_view_impl(const T& cont): cont(cont) {}
    	using iterator = typename T::const_reverse_iterator;
    };
    template<class T>
    reverse_view_impl<T> reverse_view(const T& cont) {
    	return reverse_view_impl<T>(cont);
    }
    
    template<class T>
    typename reverse_view_impl<T>::iterator begin(const reverse_view_impl<T>& view) {
    	return view.cont.crbegin();
    }
    template<class T>
    typename reverse_view_impl<T>::iterator end(const reverse_view_impl<T>& view) {
    	return view.cont.crend();
    }
    
    std::vector<int> one_two_three() { return { 1, 2, 3 }; }
    
    int main() {
    	for (auto i : reverse_view(one_two_three())) {
    		std::cout << i << std::endl;
    	}
    }

    // Surprise, motherfucker

    Bobik, 10 Августа 2016

    Комментарии (22)
  3. C++ / Говнокод #20485

    +2

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    template<typename V>
            constexpr Vector(V&& x, V&& y, V&& z) noexcept(std::is_lvalue_reference<V>::value ?
                    std::is_nothrow_move_constructible<V>::value  :
                    std::is_nothrow_copy_constructible<V>::value) :
                data{std::forward<V>(x), std::forward<V>(y), std::forward<V>(z)} {}

    jangolare, 07 Августа 2016

    Комментарии (17)
  4. C++ / Говнокод #20477

    +9

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    template<typename T> struct OBB
    {
    	vector3<T> position;
    	matrix3<T> transform;
    
    	vector3<T> GetPoint(bool positiveX, bool positiveY, bool positiveZ) const
    	{
    		const vector3<T> localUnitPoint = {T(positiveX)-T(0.5), T(positiveY)-T(0.5), T(positiveZ)-T(0.5)};
    		return vector3<T>(GetFullTransform()*vector4<T>(localUnitPoint, 1));
    	}
    
    	AABB<T> BoundingAABB() const
    	{
    		AABB<T> result;
    		result.max = result.min = position;
    		for(bool b1: {false, true})
    			for(bool b2: {false, true})
    				for(bool b3: {false, true}) //Перебираем все точки параллелепипеда
    					result.AddPoint(GetPoint(b1, b2, b3));
    		return result;
    	}
    };

    Что-то даже не могу вспомнить, когда я такое написал. Случайно наткнулся и решил, что это должно быть здесь.

    gammaker, 05 Августа 2016

    Комментарии (15)
  5. C++ / Говнокод #20474

    +20

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    std::vector<D3D11_INPUT_ELEMENT_DESC> desc;
    for (auto it = descStrings.begin(); it != descStrings.end(); it++)
    {
    	auto strIt = it->begin();
     
    	std::string SemanticName;
    	while ((*strIt) != ',' || strIt != it->end())
    	{
    		if ((*strIt) != ' ')
    			SemanticName += (*strIt);
    		strIt++;
    	}
    	strIt++;
     
    	std::string SemanticIndex;
    	while ((*strIt) != ',' || strIt != it->end())
    	{
    		if ((*strIt) != ' ')
    		 SemanticIndex += (*strIt);
    		strIt++;
    	}
    	strIt++;
     
    	std::string Format;
    	while ((*strIt) != ',' || strIt != it->end())
    	{
    		if ((*strIt) != ' ')
    		 Format += (*strIt);
    		strIt++;
    	}
    	strIt++;
     
    	std::string InputSlot;
    	while ((*strIt) != ',' || strIt != it->end())
    	{
    		if ((*strIt) != ' ')
    		 InputSlot += (*strIt);
    		strIt++;
    	}
    	strIt++;
     
    	std::string AlignedByteOffset;
    	while ((*strIt) != ',' || strIt != it->end())
    	{
    		if ((*strIt) != ' ')
    		 AlignedByteOffset += (*strIt);
    		strIt++;
    	}
    	strIt++;
     
    	std::string InputSlotClass;
    	while ((*strIt) != ',' || strIt != it->end())
    	{
    		if ((*strIt) != ' ')
    			InputSlotClass += (*strIt);
    		strIt++;
    	}
    	strIt++;
     
    	std::string InstanceDataStepRate;
    	while ((*strIt) != '}' || strIt != it->end())
    	{
    		if((*strIt) != ' ')
    			InstanceDataStepRate += (*strIt);
    		strIt++;
    	}
    	strIt++;
     
    	D3D11_INPUT_ELEMENT_DESC element = {
    		SemanticName.c_str(), 
    		atoi(SemanticIndex.c_str()), 
    		(DXGI_FORMAT)atoi(Format.c_str()),
    		atoi(InputSlot.c_str()), 
    		atoi(AlignedByteOffset.c_str()), 
    		(D3D11_INPUT_CLASSIFICATION)atoi(InputSlotClass.c_str()),
    		atoi(InstanceDataStepRate.c_str())
    	};
     
    	desc.push_back(element);
    }

    Где-то в мире сдох от зависти один индус

    ptr2ptr, 05 Августа 2016

    Комментарии (1)
  6. C++ / Говнокод #20472

    +10

    1. 1
    2. 2
    3. 3
    4. 4
    #ifdef _MSC_VER
    template<typename> using void_t = void;
    __if_exists(void_t<int>) {}
    #endif

    Эти строчки превратят Visual Studio 2015 в блокнот с подсветкой синтаксиса.
    Для максимального эффекта их следует поместить в stdafx.h или любой другой повсеместно используемый заголовок.
    Предположительно, на более старых студиях будет тот же эффект, но я не проверял.

    gammaker, 05 Августа 2016

    Комментарии (124)
  7. C++ / Говнокод #20466

    +7

    1. 1
    value = *((const char*)(*it).second.value);

    void* -> const char* -> char

    ptr2ptr, 04 Августа 2016

    Комментарии (21)
  8. C++ / Говнокод #20449

    +1

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    91. 91
    92. 92
    93. 93
    94. 94
    95. 95
    96. 96
    struct Test
    {
    	Array<int> intArray;
    	int fixedIntArray[3];
    	bool booleanVal;
    	float flt;
    	Array<string> stringArray;
    
    	ADD_REFLECTION(Test, intArray, fixedIntArray, booleanVal, flt, stringArray);
    };
    
    struct SuperTest
    {
    	Array<string> strArr;
    	int foo;
    	string str;
    	Array<short> vals;
    	double dbl;
    	Test tests[3];
    	ushort bar;
    
    	ADD_REFLECTION(SuperTest, strArr, foo, str, vals, dbl, tests, bar);
    };
    
    int main()
    {
    	StringView structText = R"({
    		.strArr = {"str1", "ergvwr", "brt"},
    		.foo = 5,
    		.str = "gammaker",
    		.vals = {-4, 66, 432, -95},
    		.dbl = 3.1415926535897932384626433832795,
    		{
    			{
    				.fixedIntArray = {9, 4, 85},
    				.stringArray = {"test 0 A", "test 0 B", "test 0 C"},
    				.booleanVal = true,
    				.intArray = {43, 54, 36, 76},
    				.flt = 1.23456,
    				.flt = 2.34567
    			},
    			{
    				.intArray = {},
    				.fixedIntArray = {3655456, 234, 3},
    				.booleanVal = false,
    				.flt = 2.718281828,
    				.stringArray = {"test 1 A", "test 1 B"}
    			},
    			{
    				.intArray = {1531, 1253, 16, 634, 236462363},
    				.fixedIntArray = {9435, 435, 8355},
    				.booleanVal = false,
    				.flt = 123.65,
    				.stringArray = {"test 2 A", "test 2 B", "test 2 C", "test 2 D"}
    			}
    		},
    		.bar = 1025
    	})";
    
    	Data::TextDeserializer deserializer(Data::DataLanguageParams::CStructInitializer, structText);
    	SuperTest test = deserializer.Deserialize<SuperTest>();
    
    	char charBuf[5000];
    	Data::TextSerializer serializer(Data::DataLanguageParams::Json, Data::TextSerializerParams::Verbose, ArrayRange<char>(charBuf, 5000));
    	serializer.NestingLevel=-1;
    	serializer.Serialize(test);
    	Console.PrintLine(serializer.GetString());
    
    	Data::DataLanguageParams rusML;
    	rusML.RequireFieldAssignments = false;
    	rusML.AddFieldNameAfterAssignment = false;
    	rusML.LeftAssignmentOperator = "равно";
    	rusML.FieldSeparator = " следующее поле";
    	rusML.LeftFieldNameBeginQuote = null;
    	rusML.LeftFieldNameEndQuote = null;
    	rusML.RightFieldNameBeginQuote = null;
    	rusML.RightFieldNameEndQuote = null;
    	rusML.StructInstanceOpen = "начало структуры";
    	rusML.StructInstanceClose = " структура кончилась";
    	rusML.OneLineCommentBegin = "комментарий:";
    	rusML.StringQuote="\"";
    	rusML.CharQuotes = "";
    	rusML.ArrayOpen = " массив начался ";
    	rusML.ArrayClose = " кончился массив ";
    	rusML.ArrayElementSeparator = " дальше";
    	rusML.FalseTrueNames[0] = "нет";
    	rusML.FalseTrueNames[0] = "да";
    	rusML.DecimalSeparator = ',';
    
    	serializer = Data::TextSerializer(rusML, Data::TextSerializerParams::Verbose, ArrayRange<char>(charBuf, 5000));
    	serializer.NestingLevel=-1;
    	serializer.Serialize(test);
    	Console.PrintLine(serializer.GetString());
    
    	return 0;
    }

    Сделал автоматический сериализатор с кучей параметров, используя которые можно описать JSON, инициализаторы C'шных и D'шных структур, подмножество XML или какой-нибудь свой кастомный формат. Здесь показана десериализация сишного инициализатора с designated initializers, который почему-то не добавили в C++. Затем полученная структура сериализуется в JSON (его описание в моём хидере, и здесь не приведено), а затем в придуманный мной ради прикола язык разметки rusML, описание которого можно видеть в коде.

    Выводит (табы порезались):

    {
    "strArr" : ["str1", "ergvwr", "brt"],
    "foo" : 5,
    "str" : "gammaker",
    "vals" : [-4, 66, 432, -95],
    "dbl" : 3.141592653589789,
    "tests" : [
    {
    "intArray" : [43, 54, 36, 76],
    "fixedIntArray" : [9, 4, 85],
    "booleanVal" : true,
    "flt" : 2.3456699,
    "stringArray" : ["test 0 A", "test 0 B", "test 0 C"]
    },
    {
    "intArray" : [],
    "fixedIntArray" : [3655456, 234, 3],
    "booleanVal" : false,
    "flt" : 2.7182817,
    "stringArray" : ["test 1 A", "test 1 B"]
    },
    {
    "intArray" : [1531, 1253, 16, 634, 236462363],
    "fixedIntArray" : [9435, 435, 8355],
    "booleanVal" : false,
    "flt" : 123.6499938,
    "stringArray" : ["test 2 A", "test 2 B", "test 2 C", "test 2 D"]
    }
    ],
    "bar" : 1025
    }

    начало структуры
    strArr равно массив начался "str1" дальше "ergvwr" дальше "brt" кончился массив следующее поле
    foo равно 5 следующее поле
    str равно "gammaker" следующее поле
    vals равно массив начался -4 дальше 66 дальше 432 дальше -95 кончился массив следующее поле
    ...

    gammaker, 30 Июля 2016

    Комментарии (173)
  9. C++ / Говнокод #20440

    +1

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    #include <iostream>
    #include <tuple>
    using namespace std;
    
    template<typename T, typename T0, typename T1, typename ...Args>
    void PrintStruct(const tuple<T0 T::*, T1 T::*, Args T::*...>& members, const T& val)
    {
    	cout << val.*std::get<0>(members) << endl;
    	PrintStruct(members._Get_rest(), val);
    }
    
    template<typename T, typename T0>
    void PrintStruct(const tuple<T0 T::*>& members, const T& val)
    {
    	cout << val.*std::get<0>(members) << endl;
    }
    
    struct MyStruct
    {
    	int x;
    	float y;
    
    	static const tuple<decltype(&MyStruct::x), decltype(&MyStruct::y)> Members;
    };
    
    const tuple<int MyStruct::*, float MyStruct::*> MyStruct::Members = std::make_tuple(&MyStruct::x, &MyStruct::y);
    
    int main()
    {
    	MyStruct str = {123, 3.14159f};
    	PrintStruct(MyStruct::Members, str);
    	return 0;
    }

    Пытался понять, почему мой код не компилится в 2013 студии, и быстренько накатал этот минимальный пример. Но вышел облом - он почему-то компилится, в отличие от моей реальной либы со схожими шаблонными крестоконструкциями.

    gammaker, 27 Июля 2016

    Комментарии (99)
  10. C++ / Говнокод #20438

    +8

    1. 1
    2. 2
    const
    #include "file.xpm"

    У чувака в файле file.xpm объявлен массив static char * icon_xpm [] = { "..", "..", ... } и он не может заинклудить его в плюсовый код. Вот такой воркараунд ему предложили.
    https://www.linux.org.ru/forum/development/10400992?cid=10406949

    kurwa-nextgen, 27 Июля 2016

    Комментарии (13)