There is only one Value() function. It returns a proxy object.
The proxy class implements one conversion operator for each return type.
It all just works.
If you are still using SourceSafe today then you should move away from it as soon as possible.
SourceSafe is buggy, slow, and tends to corrupt its database.
Microsoft stopped supporting it years ago.
Mercurial is nice and friendly. It works well on Windows, and is open source.
With vss2hg you can convert a SourceSafe project to a Mercurial repository.
The perl script was written by Andy Duplain. I made a bunch of small fixes to it.
You can download it here.
I used the vss2hg script to convert a bunch of SourceSafe projects with more than
ten years of history. The largest took 24 hours to convert. It is slow, but it works.
After you have installed ActivePerl,
you can run it from the command line.
123
set ssuser=MyName
set sspwd=MyPassword
vss2hg.pl --ssrepo="\\MyServer\VSS" --sshome="C:\Program Files (x86)\Microsoft Visual SourceSafe" $/MyProject
You need to set the OS to the US date format, otherwise the script does not work.
It is possible to make updates after the initial conversion by using the command
line options --migrate-latest and --resume.
This works pretty well when no files have been deleted or renamed in SourceSafe.
Otherwise you can manually edit the histories.txt file, and then re-run
--resume. I use kdiff3 to check that there are only changes at the bottom.
Here is another trick that I learned for Stephan Lavavej’s
posts on reddit.
How can you work around those evil lowercase min and max macros that Microsoft
defines, so that you can use the std::min and std::max template functions?
Well, it turns out that you can put parentheses around them. Not beautiful, but it works.
I learned this trick from Stephan Lavavej’s proposal
for ISO C++.
Using auto for range-based for loops is inefficient. It will copy each
element out of the container.
1
for(autoelem:range)// inefficient
Using auto&is efficient, and works with both const and non-const containers.
1
for(auto&elem:range)// efficient
Alas, it does not work with iterators that return proxy objects, such as the
infamous std::vector<bool>. You cannot bind a temporary object to a non-const reference.
The trick is to use auto&&. It works with both const and non-const containers,
but also works with proxy objects. It is always correct and efficient!
1
for(auto&&elem:range)// efficient, and works with proxy objects
But if you don’t declare the array properly then things go horribly wrong.
Never declare arrays as pointers!
The following C++ template function is much nicer.
It does not compile at all when the array is declared as a pointer.
1234567891011
template<classT,size_tN>size_tcountof(constT(&)[N]){returnN;}constcharstr1[]="Hello";size_tlen1=countof(str1);// -> 6constchar*str2="Hello";// BAD!size_tlen2=countof(str2);// does not compile
The countof function takes a reference to an array and returns
its size. It is a compile-time constant.
The first one returns the actual size of the string, which is 6 characters
including the null terminator.
The second one returns the size of a pointer, 8 bytes or 64 bits.
The second notation throws away information. Strings should always be declared
as arrays so that their size is known.