﻿/*
	© 2015 FrankHB.

	This file is part of the YSLib project, and may only be used,
	modified, and distributed under the terms of the YSLib project
	license, LICENSE.TXT.  By continuing to use, modify, or distribute
	this file you indicate that you have read the license and
	understand and accept it fully.
*/

/*!	\file Workflow.Annual2015.txt
\ingroup Documentation
\brief 工作流汇总报告 - 2015 年度。
\version r224
\author FrankHB <frankhb1989@gmail.com>
\since build 564
\par 创建时间:
	2014-01-02 09:40:31 +0800
\par 修改时间:
	2015-05-24 15:08 +0800
\par 文本编码:
	UTF-8
\par 模块名称:
	Documentation::Workflow::Annual2015
*/

// See "Meta.cpp" for meta descriptions.

$import $WORKFLOW;
$LINE-WIDTH-RESTRICT 0;

$WORKFLOW:
// Following lines are only for logging informal project information.
// See Meta.txt for formal project information.
// See ChangeLog.*.txt for accepted contents.

$2015-01:

report.impl:
Note that 'va_args' and 'va_end' cannot be encapulased using RAII/RRID.
	ISO C explicitly specified they shall match in a function.
	Since constructor and destructor are functions, they can not be used.
UAC is annoying for program which aquireing no administrator privilege but containing some patterns in file name e.g. 'patch.exe' or 'install.exe'.
	See https://github.com/bmatzelle/gow/issues/156 .
The function 'std::quick_exit' is mostly a workaround of cleanup when the thread cancellation is not supported in C++.
	See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2440.htm .
	Do not register callbacks through 'std::at_quick_exit' unless the states of threads are all known.
		Note these callbacks shall not raise signals according ISO C11, otherwise the behavior is undefined.
	The similar thing also fit for 'std::exit' and 'std::atexit'.
		However, it is generally more difficult to avoid.
		In fact, current libgcc exploited 'atexit' to make the destructors to be called.
Win32 console would call 'ExitProcess' by default during window close or handling 'Ctrl+C', etc.
	See http://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx .
	This might probable not preferred because this call would mostly make the C/C++ runtime a mess.
	This call can inform the loaded DLLs to be terminated, but also might lead to deadlock when DLLs are not used properly.
	A clean call of 'TerminateProcess' on current process would be better if not all states of each thread are known.
		However, it would not touch the C/C++ runtime states, either.
	So C/C++ standard library functions or other runtime functions are generally preferred for C/C++ applications.
		Use 'SetConsoleCtrlHandler' function to change default behavior for the attached console.
			See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686016(v=vs.85).aspx .
		YSLib now use it to workaround the unexpected behavior.
			The exit code 'STATUS_CONTROL_C_EXIT' is used for 'CTRL_C_EVENT' and 'CTRL_CLOSE_EVENT' to retain old behavior.
			For 'CTRL_BREAK_EVENT', 'CTRL_LOGOFF_EVENT' and 'CTRL_SHUTDOWN_EVENT' the same code is used, but not tested to be the same as original one.
Since 'ystdex::nptr' is exactly a wrapper but not a smart pointer, it is intended in <ystdex/utility.hpp> but not in <ystdex/memory.hpp>.
The function 'isatty' on POSIX compliant environments and '_isatty' is not the same.
	For POSIX compliant environments, '::isatty' returns whether the file descriptor is associated with a terminal.
		See http://pubs.opengroup.org/onlinepubs/009695399/functions/isatty.html .
	For Win32, '::_isatty' returns whether the file descriptor is associated with a character device;  Both cases exclude some uses not fit.
		See http://msdn.microsoft.com/en-us/library/f4s0ddew.aspx.
	Use Win32 APIs to achieve the functionality of POSIX compliant 'isatty'.
		See http://stackoverflow.com/questions/3648711/detect-nul-file-descriptor-isatty-is-bogus .
	However, both function can exclude some cases not fit for terminal output.
Move-only parameter passing counts.
	See the discussion at http://scottmeyers.blogspot.com/2014/07/should-move-only-types-ever-be-passed.html .
	Both 'T&&' or 'T' have cases. The former is probable more efficient and debugger-friendly, while the latter is simpler (both on coding and behavior).
		For 'T&&', the extra move is delayed to the client code. And there is possible to not move (or even not use) the argument at all.
		For 'T', the move operation is mandated by copy-initialization of the parameter.
	The implicit coding rules used by YSLib are not documentated then, so here is the summary.
		To use mandated move on certain move-only types which has predictable and acception perfomance on the move operation (e.g. instances of 'std::unique_ptr' with default deleter), 'T' is preferred.
		Otherwise, 'T&&' should be used.
	These cases was attented at long before.
		At least in September 2014, these rules were adopted.
			This is reflected by the modification on Documentation::CommonRules (Mercurial changeset 406, build 534; now Documentation::LanguageConvention).
			However, no actual code modification was taken (e.g. on 'YSLib::UI::Widget::SetRenderer').
		These rules are now updated to be more explicit in Documentation::LanguageConvention.
		In fact, 'YSLib::UI::Widget::SetRenderer' was modified in May 2013 (Mercurial changeset 278, build 406) for probable the same rules.
		Now 'YSLib::UI::Widget::SetView' is synchronized to be consistent. Both these functions needed the object of 'unique_ptr' instance always being used.
	For non move-only type, see $2014-04.
The duration (and potentially other instances of 'std::chrono' time types e.g. time points) parameters are now passed by value rather than by reference.
	In general, The default argument binding to reference type of parameter causes odr-used of the argument.
		If the argument is a static data member of class, either declared with const, constexpr or not, an extra definition out of class definition is required to obey ODR, otherwise the program is ill-formed.
		This is necessary by intention. Only value is actually used so lvalue-to-rvalue is expected, and odr-use is not required.
	To elimination the requirement of extra definition, parameter of object type can be used directly instead of parameter reference type.
	However, the static data member of literal types designated with constexpr are used (rather than integral or enumeration types) it might not work.
		To be a constant-expression it should be a non-volatile glvalue performed lvalue-to-rvalue conversion.
			This is required "immediately" by ISO C++11.
			The requirement is relaxted by new working draft, but not all issues are resoved now.
			See http://stackoverflow.com/questions/23491781/when-is-a-variable-odr-used-in-c14 .
		Implementations like MinGW G++ 4.9.1 or Clang++ 3.5.1 with both '-std=c++11' and '-std=c++14' are actually not treated them as constant expressions for such use, so the definition are not removed tentatively now.
		See WG21/N4296 5.20/2.7.1 about use for integral or enumeration types.
	For instance of duration used directly in YFramework, the underlying arithmetic types are predicatable, so the costs are generally known and acceptable.
		This may differ in the standard library or other cases (e.g. YBase), which use const lvalue reference of templated object types.
	To be consistently, all parameters use the same form.
	This is not necessary the case of 'YSLib::Drawing::Point' and other types of geometry in YFramework (esp. the cost of copy an object of 'YSLib::Drawing::Rect', for consistency in style), so they are not touched.

$2015-02:

dep.merge:
df.operators(https://github.com/d-frey/operators): partially merged.

report.impl:
The '+' or '+=' expression concerned with random access iterators should be noticed.
	ISO C++ has not required that the preconditions for these operations. However, this check is by original design.
		See http://www.sgi.com/tech/stl/RandomAccessIterator.html#1 .
	Note out-of-bound pointer arithmetic is undefined behavior.
		See http://stackoverflow.com/questions/10473573/why-is-out-of-bounds-pointer-arithmetic-undefined-behaviour .
		Since the algorithms implemented to support random iterators are usually allowing pointers, it should be cautious to use these operations.
		Unless otherwise explicitly specified, YSLib uses the strict strategy, i.e. the code shall not use these operations to perform undefined behavior, unless the pointers are prevented to be instantiated intentionally.
		YBase also uses some strict boundary check (esp. assertions) on these operations in implementation of iterators.

$2015-03:

dep.merge:
OpenImageIO(http://www.openimageio.org/): tentatively rejected.
	This is a library focused on image I/O.
		It actually does more, e.g. provides some ISO C99 math functions and POSIX math macros, implementation of 'array_view', etc.
		It embeds some 3rd party code to support XML, SHA1, etc.
		It also encapsulates some system-dependent operations, e.g. threads.
			The threading operations depend on Boost.Thread.
		Its interface is in C++.
			This is good to avoid name clash.
			However, the quality is not always good.
				Error handling totally bypassed exceptions (except for throwing 'std::out_of_range' from 'array_view', etc), and uses thread-specific state instead.
					This is of generally bad style and can be hard to use.
			Sometimes the interface is necessarily bloated, e.g. 'ParamValueList' can actually be an type alias rather than a class.
		The headers are a bit mess.
			There are multiple headers in the same directory doing different works. Not all of them are aiming to image I/O.
			It is somewhat difficult to use it cleanly directly without referencing some use cases.
	The license is 3-clause BSD-like.
		Though 2-clause would be better, it is good to use.
	The binary code of static library is even slightly larger than that of FreeImage for MSYS2.
		It is in doubt to shrink without giving up some functionality.
	It is lacks of GIF support, which is used by YFramework.
		So at least at current, it can not replace FreeImage.

report.impl:
In general, the key state in the event argument of 'KeyDown' event should not be modified in the handler.
	Call of 'GUIState::UpdateChar' would once modify it.
		The key set was combined of multiple keys, which was modified by checked held state.
		This was wrong for a 'KeyDown' event not called by 'KeyHeld' handler.
		Class 'TextBox' was effected. It would occasionally behave normally if the key of least key index was pressed down at last.
			Since the key was determined by the first key index in the key set through call of 'FindFirstKeyInCategroy'.
			For example, right arrow after left arrow would be treated as left arrow but right arrow after left array would be normal, if the key index of the left arrow key is less than the one of right arrow key, which is the case of Win32 and many other platforms.
Be cautious with revision patcher script. Currently the pattern of reversion is hard coded.
	Only certain version number pattern is supported.
		Some versioned files like makefiles should still going to be maintained manully.
	Be cautious with the lines area counts.
		Most files are with the '\version' in first 20 lines, only 3 files are the exceptions: YBase::YDefinition, YFramework::YCLib::YModules, Tools::PredefinedMacroDetector::Main.
		All of them are not touched since the script was used.
		So nothing had been going wrong.
		Set 'PatchEnd' variable when necessary.
			The default value has been adjusted to '30' instead of '20' to cover all of current source files.
	Now version number pattern is restricted to mandate a prefixed number character in the version number.
		Thus the script it self would not be affected even the 'PatchEnd' is set to 30. It should also work for the readme file.
The Clang++ warning '-Wweak-vtables' is mainly for compiling performance.
	See http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-August/024020.html .
	See also http://stackoverflow.com/questions/23746941/what-is-the-meaning-of-clangs-wweak-vtables .
	G++ behave similarly, but VC++ does not.
		See http://stackoverflow.com/questions/12024642/placing-of-external-virtual-tables .
	It is enabled by '-Weverything'.
	For client code this might be not important, so no problem to disable.
	However, for libraries with a lot of translation units or being depended deeply, it is better to turn it on.
		YSLib libraries should use these flags if possible.
		YFramework interface type now requires out-of-line destructor provided by user.
		Note to avoid '-Wdeprecated' warnings, the copy or move constructor should be defined.
			This might cause some trouble with '-Wextra' from G++ complaining aboud imlicit call of default constructor in devired classes if it is not explicit initialized.
				As a workaround, (a few) copy constructors now explicitly initialize the base interface subobjects.
Note that '__cplusplus' value is significant across different versions of implementations.
	Paticularly, '__cplusplus > 201103L' is not equivalent to '__cplusplus >= 201402L'.
		ISO C++ working draft did not specify any value between '201103L' and '201402L' for 'cplusplus'.
		However, there exists some implementations use these values.
			For example, some G++ versions uses '201300L' for C++1y mode.
				See https://gcc.gnu.org/ml/gcc-patches/2013-04/msg01452.html .
				MinGW G++ 4.9.1 from MSYS2 is tested and confimed the use of this value when specified '-std=c++14'.
			On the other hand, Clang++ 3.5.1 from MSYS2 uses '201402L' for '-std=c++14'.
		This is important for some feature detection conditions.
			As an example, 'constexpr' on C++14 'std::max' is supported differently by similar conditions.
				Libstdc++ only supports it through macro '_GLIBCXX14_CONSTEXPR' after version 4.9 when '__cplusplus >= 201402L'.
				Libc++ supports it with same condition through macro '_LIBCPP_CONSTEXPR_AFTER_CXX11' except for it can be disabled by define '_LIBCPP_HAS_NO_CXX14_CONSTEXPR'.
			As another example, C++14 'std::integer_sequence' is supported similarly.
				Libstdc++ 4.9 supports it when '__cplusplus > 201103L'.
				Libc++ supports it when '_LIBCPP_STD_VER > 11', effectively equivalent with '__cplusplus > 201103L''.
		YSLib uses it carefullly.
			For different senarios, these different conditions are distinguished.
			Currently the non-standard-compliant macros like '_LIBCPP_HAS_NO_CXX14_CONSTEXPR' are ignored.
			There would be some specific macros like libc++ to control it better in future.
			Utilization of '__has_feature' would be preferred. Note it would be supported by G++ 5, and Clang++ has already supported it.

$2015-04:

report.impl:
ISO C++14 does not allowed arbitiary expressions for template non-type arguments.
	Notably, 'std::integral_constant' using '()' converting to a value is not allowed in these context.
		This is too restrict and cause it can be used almost always with 'static_assert' declarations or 'noexcept' specifications.
	WG21/N4198 stated and resolved this problem.
		See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4198.html .
		The resolution has been merged into working draft WG21/N4296.
	Note the use of '::value' are preferred in several contexts.
		Only certain expression related with 'std::integral_constant' should be considered for refactoring.
		For example, those 'seq_size' call in YBase.YStandardEx.Variadic and implementations of 'and_', 'or_', and 'not_' in YBase.YStandardEx.TypeOperation would not be touched even C++1z is accepted.
Copy constructor of exception classes is reviewed.
	See $2014-02 report.impl of basic rules.
	The standard don't restrict the stored subobjets of standard exception classes to allow optimization.
		See http://wg21.cmeerw.net/lwg/issue254.
		However, actual implementations may directly use reference-counted strings.
			See http://stackoverflow.com/questions/29052647/c11-introduced-exception-constructors-taking-const-char-but-why .
			See http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20140428/104370.html .

$2015-05:

report.impl:
Now 'ystdex::nptr' is moved to <ystdex/pointer.hpp> to be specifically categorized as the pointer-related interface.
	Also to implement by using <ystdex/operators.hpp> avoiding too many dependencies introduced to <ystdex/utility.hpp>.
	It is still not ideal to decouple the interface, because now <ystdex/iterator.hpp> is relying on this header. In future, some portion of code in latter would better placed in another new header.

////

